Commit 992f73e2 authored by Hanno Schlichting's avatar Hanno Schlichting

flake8

parent bcaeb4ae
......@@ -17,19 +17,20 @@ from cgi import escape
from cStringIO import StringIO
from mimetools import choose_boundary
import struct
import sys
from AccessControl.class_init import InitializeClass
from AccessControl.Permissions import change_images_and_files
from AccessControl.Permissions import view_management_screens
from AccessControl.Permissions import view as View
from AccessControl.Permissions import view as View # NOQA
from AccessControl.Permissions import ftp_access
from AccessControl.Permissions import delete_objects
from AccessControl.SecurityInfo import ClassSecurityInfo
from Acquisition import Implicit
from App.Common import rfc1123_date
from App.special_dtml import DTMLFile
from DateTime.DateTime import DateTime
from Persistence import Persistent
from webdav.common import rfc1123_date
from webdav.interfaces import IWriteLock
from ZPublisher import HTTPRangeSupport
from ZPublisher.HTTPRequest import FileUpload
......@@ -47,11 +48,13 @@ from zope.event import notify
from zope.lifecycleevent import ObjectModifiedEvent
from zope.lifecycleevent import ObjectCreatedEvent
manage_addFileForm = DTMLFile('dtml/imageAdd',
globals(),
Kind='File',
kind='file',
)
if sys.version_info >= (3, 0):
unicode = str
manage_addFileForm = DTMLFile(
'dtml/imageAdd', globals(), Kind='File', kind='file')
def manage_addFile(self, id, file='', title='', precondition='',
content_type='', REQUEST=None):
"""Add a new File object.
......@@ -65,10 +68,10 @@ def manage_addFile(self, id, file='', title='', precondition='',
id, title = cookId(id, title, file)
self=self.this()
self = self.this()
# First, we create the file without data:
self._setObject(id, File(id,title,'',content_type, precondition))
self._setObject(id, File(id, title, '', content_type, precondition))
newFile = self._getOb(id)
......@@ -77,12 +80,12 @@ def manage_addFile(self, id, file='', title='', precondition='',
if file:
newFile.manage_upload(file)
if content_type:
newFile.content_type=content_type
newFile.content_type = content_type
notify(ObjectCreatedEvent(newFile))
if REQUEST is not None:
REQUEST['RESPONSE'].redirect(self.absolute_url()+'/manage_main')
REQUEST['RESPONSE'].redirect(self.absolute_url() + '/manage_main')
class File(Persistent, Implicit, PropertyManager,
......@@ -96,55 +99,56 @@ class File(Persistent, Implicit, PropertyManager,
implementedBy(Item_w__name__),
implementedBy(Cacheable),
IWriteLock,
HTTPRangeSupport.HTTPRangeInterface,
)
meta_type='File'
HTTPRangeSupport.HTTPRangeInterface)
meta_type = 'File'
security = ClassSecurityInfo()
security.declareObjectProtected(View)
precondition=''
size=None
precondition = ''
size = None
manage_editForm =DTMLFile('dtml/fileEdit',globals(),
Kind='File',kind='file')
manage_editForm = DTMLFile('dtml/fileEdit', globals(),
Kind='File', kind='file')
manage_editForm._setName('manage_editForm')
security.declareProtected(view_management_screens, 'manage')
security.declareProtected(view_management_screens, 'manage_main')
manage=manage_main=manage_editForm
manage_uploadForm=manage_editForm
manage = manage_main = manage_editForm
manage_uploadForm = manage_editForm
manage_options=(
manage_options = (
(
{'label': 'Edit', 'action': 'manage_main'},
{'label': 'View', 'action': ''},
)
+ PropertyManager.manage_options
+ RoleManager.manage_options
+ Item_w__name__.manage_options
+ Cacheable.manage_options
) +
PropertyManager.manage_options +
RoleManager.manage_options +
Item_w__name__.manage_options +
Cacheable.manage_options
)
_properties=({'id':'title', 'type': 'string'},
{'id':'content_type', 'type':'string'},
_properties = (
{'id': 'title', 'type': 'string'},
{'id': 'content_type', 'type': 'string'},
)
def __init__(self, id, title, file, content_type='', precondition=''):
self.__name__=id
self.title=title
self.precondition=precondition
self.__name__ = id
self.title = title
self.precondition = precondition
data, size = self._read_data(file)
content_type=self._get_content_type(file, data, id, content_type)
content_type = self._get_content_type(file, data, id, content_type)
self.update_data(data, content_type, size)
def _if_modified_since_request_handler(self, REQUEST, RESPONSE):
# HTTP If-Modified-Since header handling: return True if
# we can handle this request by returning a 304 response
header=REQUEST.get_header('If-Modified-Since', None)
header = REQUEST.get_header('If-Modified-Since', None)
if header is not None:
header=header.split( ';')[0]
header = header.split(';')[0]
# Some proxies seem to send invalid date strings for this
# header. If the date string is not valid, we ignore it
# rather than raise an error to be generally consistent
......@@ -153,13 +157,15 @@ class File(Persistent, Implicit, PropertyManager,
# of the way they parse it).
# This happens to be what RFC2616 tells us to do in the face of an
# invalid date.
try: mod_since=long(DateTime(header).timeTime())
except: mod_since=None
try:
mod_since = int(DateTime(header).timeTime())
except Exception:
mod_since = None
if mod_since is not None:
if self._p_mtime:
last_mod = long(self._p_mtime)
last_mod = int(self._p_mtime)
else:
last_mod = long(0)
last_mod = 0
if last_mod > 0 and last_mod <= mod_since:
RESPONSE.setHeader('Last-Modified',
rfc1123_date(self._p_mtime))
......@@ -193,14 +199,16 @@ class File(Persistent, Implicit, PropertyManager,
ranges = None
else:
# Date
date = if_range.split( ';')[0]
try: mod_since=long(DateTime(date).timeTime())
except: mod_since=None
date = if_range.split(';')[0]
try:
mod_since = int(DateTime(date).timeTime())
except Exception:
mod_since = None
if mod_since is not None:
if self._p_mtime:
last_mod = long(self._p_mtime)
last_mod = int(self._p_mtime)
else:
last_mod = long(0)
last_mod = 0
if last_mod > mod_since:
# Modified, so send a normal response. We delete
# the ranges, which causes us to skip to the 200
......@@ -216,11 +224,11 @@ class File(Persistent, Implicit, PropertyManager,
break
if not satisfiable:
RESPONSE.setHeader('Content-Range',
'bytes */%d' % self.size)
RESPONSE.setHeader(
'Content-Range', 'bytes */%d' % self.size)
RESPONSE.setHeader('Accept-Ranges', 'bytes')
RESPONSE.setHeader('Last-Modified',
rfc1123_date(self._p_mtime))
RESPONSE.setHeader(
'Last-Modified', rfc1123_date(self._p_mtime))
RESPONSE.setHeader('Content-Type', self.content_type)
RESPONSE.setHeader('Content-Length', self.size)
RESPONSE.setStatus(416)
......@@ -233,12 +241,13 @@ class File(Persistent, Implicit, PropertyManager,
start, end = ranges[0]
size = end - start
RESPONSE.setHeader('Last-Modified',
rfc1123_date(self._p_mtime))
RESPONSE.setHeader(
'Last-Modified', rfc1123_date(self._p_mtime))
RESPONSE.setHeader('Content-Type', self.content_type)
RESPONSE.setHeader('Content-Length', size)
RESPONSE.setHeader('Accept-Ranges', 'bytes')
RESPONSE.setHeader('Content-Range',
RESPONSE.setHeader(
'Content-Range',
'bytes %d-%d/%d' % (start, end - 1, self.size))
RESPONSE.setStatus(206) # Partial content
......@@ -256,7 +265,8 @@ class File(Persistent, Implicit, PropertyManager,
# We are within the range
lstart = l - (pos - start)
if lstart < 0: lstart = 0
if lstart < 0:
lstart = 0
# find the endpoint
if end <= pos:
......@@ -286,16 +296,16 @@ class File(Persistent, Implicit, PropertyManager,
size = (size + len('%d%d' % (start, end - 1)) +
end - start)
# Some clients implement an earlier draft of the spec, they
# will only accept x-byteranges.
draftprefix = (request_range is not None) and 'x-' or ''
RESPONSE.setHeader('Content-Length', size)
RESPONSE.setHeader('Accept-Ranges', 'bytes')
RESPONSE.setHeader('Last-Modified',
rfc1123_date(self._p_mtime))
RESPONSE.setHeader('Content-Type',
RESPONSE.setHeader(
'Last-Modified', rfc1123_date(self._p_mtime))
RESPONSE.setHeader(
'Content-Type',
'multipart/%sbyteranges; boundary=%s' % (
draftprefix, boundary))
RESPONSE.setStatus(206) # Partial content
......@@ -308,8 +318,8 @@ class File(Persistent, Implicit, PropertyManager,
for start, end in ranges:
RESPONSE.write('\r\n--%s\r\n' % boundary)
RESPONSE.write('Content-Type: %s\r\n' %
self.content_type)
RESPONSE.write(
'Content-Type: %s\r\n' % self.content_type)
RESPONSE.write(
'Content-Range: bytes %d-%d/%d\r\n\r\n' % (
start, end - 1, self.size))
......@@ -339,7 +349,8 @@ class File(Persistent, Implicit, PropertyManager,
# We are within the range
lstart = l - (pos - start)
if lstart < 0: lstart = 0
if lstart < 0:
lstart = 0
# find the endpoint
if end <= pos:
......@@ -349,12 +360,14 @@ class File(Persistent, Implicit, PropertyManager,
RESPONSE.write(data[lstart:lend])
break
# Not yet at the end, transmit what we have.
# Not yet at the end,
# transmit what we have.
RESPONSE.write(data[lstart:])
data = data.next
# Store a reference to a Pdata chain link so we
# don't have to deref during this request again.
# Store a reference to a Pdata chain link
# so we don't have to deref during
# this request again.
pdata_map[pos] = data
# Do not keep the link references around.
......@@ -386,9 +399,9 @@ class File(Persistent, Implicit, PropertyManager,
# Grab whatever precondition was defined and then
# execute it. The precondition will raise an exception
# if something violates its terms.
c=getattr(self, str(self.precondition))
if hasattr(c,'isDocTemp') and c.isDocTemp:
c(REQUEST['PARENTS'][1],REQUEST)
c = getattr(self, str(self.precondition))
if hasattr(c, 'isDocTemp') and c.isDocTemp:
c(REQUEST['PARENTS'][1], REQUEST)
else:
c()
......@@ -412,14 +425,14 @@ class File(Persistent, Implicit, PropertyManager,
self.ZCacheable_set(None)
data=self.data
data = self.data
if isinstance(data, str):
RESPONSE.setBase(None)
return data
while data is not None:
RESPONSE.write(data.data)
data=data.next
data = data.next
return ''
......@@ -428,7 +441,7 @@ class File(Persistent, Implicit, PropertyManager,
"""
The default view of the contents of the File or Image.
"""
raise Redirect, URL1
raise Redirect(URL1)
security.declareProtected(View, 'PrincipiaSearchSource')
def PrincipiaSearchSource(self):
......@@ -443,10 +456,12 @@ class File(Persistent, Implicit, PropertyManager,
raise TypeError('Data can only be str or file-like. '
'Unicode objects are expressly forbidden.')
if content_type is not None: self.content_type=content_type
if size is None: size=len(data)
self.size=size
self.data=data
if content_type is not None:
self.content_type = content_type
if size is None:
size = len(data)
self.size = size
self.data = data
self.ZCacheable_invalidate()
self.ZCacheable_set(None)
self.http__refreshEtag()
......@@ -460,10 +475,12 @@ class File(Persistent, Implicit, PropertyManager,
if self.wl_isLocked():
raise ResourceLockedError("File is locked.")
self.title=str(title)
self.content_type=str(content_type)
if precondition: self.precondition=str(precondition)
elif self.precondition: del self.precondition
self.title = str(title)
self.content_type = str(content_type)
if precondition:
self.precondition = str(precondition)
elif self.precondition:
del self.precondition
if filedata is not None:
self.update_data(filedata, content_type, len(filedata))
else:
......@@ -472,11 +489,12 @@ class File(Persistent, Implicit, PropertyManager,
notify(ObjectModifiedEvent(self))
if REQUEST:
message="Saved changes."
return self.manage_main(self,REQUEST,manage_tabs_message=message)
message = "Saved changes."
return self.manage_main(
self, REQUEST, manage_tabs_message=message)
security.declareProtected(change_images_and_files, 'manage_upload')
def manage_upload(self,file='',REQUEST=None):
def manage_upload(self, file='', REQUEST=None):
"""
Replaces the current contents of the File or Image object with file.
......@@ -486,53 +504,57 @@ class File(Persistent, Implicit, PropertyManager,
raise ResourceLockedError("File is locked.")
data, size = self._read_data(file)
content_type=self._get_content_type(file, data, self.__name__,
content_type = self._get_content_type(file, data, self.__name__,
'application/octet-stream')
self.update_data(data, content_type, size)
notify(ObjectModifiedEvent(self))
if REQUEST:
message="Saved changes."
return self.manage_main(self,REQUEST,manage_tabs_message=message)
message = "Saved changes."
return self.manage_main(
self, REQUEST, manage_tabs_message=message)
def _get_content_type(self, file, body, id, content_type=None):
headers=getattr(file, 'headers', None)
headers = getattr(file, 'headers', None)
if headers and 'content-type' in headers:
content_type=headers['content-type']
content_type = headers['content-type']
else:
if not isinstance(body, str): body=body.data
content_type, enc=guess_content_type(
getattr(file, 'filename',id), body, content_type)
if not isinstance(body, str):
body = body.data
content_type, enc = guess_content_type(
getattr(file, 'filename', id), body, content_type)
return content_type
def _read_data(self, file):
import transaction
n=1 << 16
n = 1 << 16
if isinstance(file, str):
size=len(file)
if size < n: return file, size
size = len(file)
if size < n:
return (file, size)
# Big string: cut it into smaller chunks
file = StringIO(file)
if isinstance(file, FileUpload) and not file:
raise ValueError, 'File not specified'
raise ValueError('File not specified')
if hasattr(file, '__class__') and file.__class__ is Pdata:
size=len(file)
return file, size
size = len(file)
return (file, size)
seek=file.seek
read=file.read
seek = file.seek
read = file.read
seek(0,2)
size=end=file.tell()
seek(0, 2)
size = end = file.tell()
if size <= 2*n:
if size <= 2 * n:
seek(0)
if size < n: return read(size), size
if size < n:
return read(size), size
return Pdata(read(size)), size
# Make sure we have an _p_jar, even if we are a new object, by
......@@ -550,7 +572,7 @@ class File(Persistent, Implicit, PropertyManager,
# possible.
next = None
while end > 0:
pos = end-n
pos = end - n
if pos < n:
pos = 0 # we always want at least n bytes
seek(pos)
......@@ -558,7 +580,7 @@ class File(Persistent, Implicit, PropertyManager,
# Create the object and assign it a next pointer
# in the same transaction, so that there is only
# a single database update for it.
data = Pdata(read(end-pos))
data = Pdata(read(end - pos))
self._p_jar.add(data)
data.next = next
......@@ -581,12 +603,12 @@ class File(Persistent, Implicit, PropertyManager,
"""Handle HTTP PUT requests"""
self.dav__init(REQUEST, RESPONSE)
self.dav__simpleifhandler(REQUEST, RESPONSE, refresh=1)
type=REQUEST.get_header('content-type', None)
type = REQUEST.get_header('content-type', None)
file=REQUEST['BODYFILE']
file = REQUEST['BODYFILE']
data, size = self._read_data(file)
content_type=self._get_content_type(file, data, self.__name__,
content_type = self._get_content_type(file, data, self.__name__,
type or self.content_type)
self.update_data(data, content_type, size)
......@@ -597,12 +619,13 @@ class File(Persistent, Implicit, PropertyManager,
def get_size(self):
# Get the size of a file or image.
# Returns the size of the file or image.
size=self.size
if size is None: size=len(self.data)
size = self.size
if size is None:
size = len(self.data)
return size
# deprecated; use get_size!
getSize=get_size
getSize = get_size
security.declareProtected(View, 'getContentType')
def getContentType(self):
......@@ -610,9 +633,11 @@ class File(Persistent, Implicit, PropertyManager,
# Returns the content type (MIME type) of a file or image.
return self.content_type
def __str__(self):
return str(self.data)
def __str__(self): return str(self.data)
def __len__(self): return 1
def __len__(self):
return 1
security.declareProtected(ftp_access, 'manage_FTPstat')
security.declareProtected(ftp_access, 'manage_FTPlist')
......@@ -647,8 +672,10 @@ class File(Persistent, Implicit, PropertyManager,
InitializeClass(File)
manage_addImageForm=DTMLFile('dtml/imageAdd',globals(),
Kind='Image',kind='image')
manage_addImageForm = DTMLFile(
'dtml/imageAdd', globals(), Kind='Image', kind='image')
def manage_addImage(self, id, file, title='', precondition='', content_type='',
REQUEST=None):
"""
......@@ -657,17 +684,17 @@ def manage_addImage(self, id, file, title='', precondition='', content_type='',
Creates a new Image object 'id' with the contents of 'file'.
"""
id=str(id)
title=str(title)
content_type=str(content_type)
precondition=str(precondition)
id = str(id)
title = str(title)
content_type = str(content_type)
precondition = str(precondition)
id, title = cookId(id, title, file)
self=self.this()
self = self.this()
# First, we create the image without data:
self._setObject(id, Image(id,title,'',content_type, precondition))
self._setObject(id, Image(id, title, '', content_type, precondition))
newFile = self._getOb(id)
......@@ -676,13 +703,15 @@ def manage_addImage(self, id, file, title='', precondition='', content_type='',
if file:
newFile.manage_upload(file)
if content_type:
newFile.content_type=content_type
newFile.content_type = content_type
notify(ObjectCreatedEvent(newFile))
if REQUEST is not None:
try: url=self.DestinationURL()
except: url=REQUEST['URL1']
try:
url = self.DestinationURL()
except Exception:
url = REQUEST['URL1']
REQUEST.RESPONSE.redirect('%s/manage_main' % url)
return id
......@@ -705,8 +734,8 @@ def getImageInfo(data):
# See PNG v1.2 spec (http://www.cdrom.com/pub/png/spec/)
# Bytes 0-7 are below, 4-byte chunk length, then 'IHDR'
# and finally the 4-byte width, height
elif ((size >= 24) and (data[:8] == '\211PNG\r\n\032\n')
and (data[12:16] == 'IHDR')):
elif ((size >= 24) and (data[:8] == '\211PNG\r\n\032\n') and
(data[12:16] == 'IHDR')):
content_type = 'image/png'
w, h = struct.unpack(">LL", data[16:24])
width = int(w)
......@@ -728,18 +757,21 @@ def getImageInfo(data):
b = jpeg.read(1)
try:
while (b and ord(b) != 0xDA):
while (ord(b) != 0xFF): b = jpeg.read(1)
while (ord(b) == 0xFF): b = jpeg.read(1)
while (ord(b) != 0xFF):
b = jpeg.read(1)
while (ord(b) == 0xFF):
b = jpeg.read(1)
if (ord(b) >= 0xC0 and ord(b) <= 0xC3):
jpeg.read(3)
h, w = struct.unpack(">HH", jpeg.read(4))
break
else:
jpeg.read(int(struct.unpack(">H", jpeg.read(2))[0])-2)
jpeg.read(int(struct.unpack(">H", jpeg.read(2))[0]) - 2)
b = jpeg.read(1)
width = int(w)
height = int(h)
except: pass
except Exception:
pass
return content_type, width, height
......@@ -749,14 +781,14 @@ class Image(File):
as File objects. Images also have a string representation that
renders an HTML 'IMG' tag.
"""
meta_type='Image'
meta_type = 'Image'
security = ClassSecurityInfo()
security.declareObjectProtected(View)
alt=''
height=''
width=''
alt = ''
height = ''
width = ''
# FIXME: Redundant, already in base class
security.declareProtected(change_images_and_files, 'manage_edit')
......@@ -770,33 +802,34 @@ class Image(File):
security.declareProtected(ftp_access, 'manage_FTPget')
security.declareProtected(delete_objects, 'DELETE')
_properties=({'id':'title', 'type': 'string'},
{'id':'alt', 'type':'string'},
{'id':'content_type', 'type':'string','mode':'w'},
{'id':'height', 'type':'string'},
{'id':'width', 'type':'string'},
_properties = (
{'id': 'title', 'type': 'string'},
{'id': 'alt', 'type': 'string'},
{'id': 'content_type', 'type': 'string', 'mode': 'w'},
{'id': 'height', 'type': 'string'},
{'id': 'width', 'type': 'string'},
)
manage_options=(
({'label':'Edit', 'action':'manage_main'},
{'label':'View', 'action':'view_image_or_file'}, )
+ PropertyManager.manage_options
+ RoleManager.manage_options
+ Item_w__name__.manage_options
+ Cacheable.manage_options
manage_options = (
({'label': 'Edit', 'action': 'manage_main'},
{'label': 'View', 'action': 'view_image_or_file'}) +
PropertyManager.manage_options +
RoleManager.manage_options +
Item_w__name__.manage_options +
Cacheable.manage_options
)
manage_editForm =DTMLFile('dtml/imageEdit',globals(),
Kind='Image',kind='image')
manage_editForm = DTMLFile('dtml/imageEdit', globals(),
Kind='Image', kind='image')
manage_editForm._setName('manage_editForm')
security.declareProtected(View, 'view_image_or_file')
view_image_or_file =DTMLFile('dtml/imageView',globals())
view_image_or_file = DTMLFile('dtml/imageView', globals())
security.declareProtected(view_management_screens, 'manage')
security.declareProtected(view_management_screens, 'manage_main')
manage=manage_main=manage_editForm
manage_uploadForm=manage_editForm
manage = manage_main = manage_editForm
manage_uploadForm = manage_editForm
security.declarePrivate('update_data')
def update_data(self, data, content_type=None, size=None):
......@@ -804,10 +837,11 @@ class Image(File):
raise TypeError('Data can only be str or file-like. '
'Unicode objects are expressly forbidden.')
if size is None: size=len(data)
if size is None:
size = len(data)
self.size=size
self.data=data
self.size = size
self.data = data
ct, width, height = getImageInfo(data)
if ct:
......@@ -817,7 +851,8 @@ class Image(File):
self.height = height
# Now we should have the correct content type, or still None
if content_type is not None: self.content_type = content_type
if content_type is not None:
self.content_type = content_type
self.ZCacheable_invalidate()
self.ZCacheable_set(None)
......@@ -842,8 +877,10 @@ class Image(File):
# trying to use 'tag()' to include a CSS class. The tag() method
# will accept a 'css_class' argument that will be converted to
# 'class' in the output tag to work around this.
if height is None: height=self.height
if width is None: width=self.width
if height is None:
height = self.height
if width is None:
width = self.width
# Auto-scaling support
xdelta = xscale or scale
......@@ -854,14 +891,14 @@ class Image(File):
if ydelta and height:
height = str(int(round(int(height) * ydelta)))
result='<img src="%s"' % (self.absolute_url())
result = '<img src="%s"' % (self.absolute_url())
if alt is None:
alt=getattr(self, 'alt', '')
alt = getattr(self, 'alt', '')
result = '%s alt="%s"' % (result, escape(alt, 1))
if title is None:
title=getattr(self, 'title', '')
title = getattr(self, 'title', '')
result = '%s title="%s"' % (result, escape(title, 1))
if height:
......@@ -870,10 +907,6 @@ class Image(File):
if width:
result = '%s width="%s"' % (result, width)
# Omitting 'border' attribute (Collector #1557)
# if not 'border' in [ x.lower() for x in args.keys()]:
# result = '%s border="0"' % result
if css_class is not None:
result = '%s class="%s"' % (result, css_class)
......@@ -888,22 +921,23 @@ InitializeClass(Image)
def cookId(id, title, file):
if not id and hasattr(file,'filename'):
filename=file.filename
title=title or filename
id=filename[max(filename.rfind('/'),
if not id and hasattr(file, 'filename'):
filename = file.filename
title = title or filename
id = filename[max(filename.rfind('/'),
filename.rfind('\\'),
filename.rfind(':'),
)+1:]
) + 1:]
return id, title
class Pdata(Persistent, Implicit):
# Wrapper for possibly large data
next=None
next = None
def __init__(self, data):
self.data=data
self.data = data
def __getslice__(self, i, j):
return self.data[i:j]
......@@ -913,13 +947,14 @@ class Pdata(Persistent, Implicit):
return len(data)
def __str__(self):
next=self.next
if next is None: return self.data
next = self.next
if next is None:
return self.data
r=[self.data]
r = [self.data]
while next is not None:
self=next
self = next
r.append(self.data)
next=self.next
next = self.next
return ''.join(r)
......@@ -773,7 +773,7 @@ class ObjectManager(CopyContainer,
if (request.maybe_webdav_client and
method not in ('GET', 'POST')):
return NullResource(self, key, request).__of__(self)
raise KeyError, key
raise KeyError(key)
def __setitem__(self, key, value):
return self._setObject(key, value)
......
......@@ -51,49 +51,54 @@ class View(Tabs, Base):
def manage_workspace(self, URL1, RESPONSE):
'''Implement a "management" interface
'''
RESPONSE.redirect(URL1+'/manage')
RESPONSE.redirect(URL1 + '/manage')
def tpURL(self): return self.getId()
def tpURL(self):
return self.getId()
def manage_options(self):
"""Return a manage option data structure for me instance
"""
try: r=self.REQUEST
except: r=None
try:
r = self.REQUEST
except Exception:
r = None
if r is None:
pre='../../'
pre = '../../'
else:
pre=r['URL']
for i in (1,2,3):
l=pre.rfind('/')
pre = r['URL']
for i in (1, 2, 3):
l = pre.rfind('/')
if l >= 0:
pre=pre[:l]
pre=pre+'/'
pre = pre[:l]
pre = pre + '/'
r=[]
r = []
for d in aq_parent(aq_parent(self)).manage_options:
path=d['action']
option={'label': d['label'],
'action': pre+path,
'path': '../../'+path}
help=d.get('help')
path = d['action']
option = {'label': d['label'],
'action': pre + path,
'path': '../../' + path}
help = d.get('help')
if help is not None:
option['help']=help
option['help'] = help
r.append(option)
return r
def tabs_path_info(self, script, path):
l=path.rfind('/')
l = path.rfind('/')
if l >= 0:
path=path[:l]
l=path.rfind('/')
if l >= 0: path=path[:l]
return View.inheritedAttribute('tabs_path_info')(
self, script, path)
path = path[:l]
l = path.rfind('/')
if l >= 0:
path = path[:l]
return View.inheritedAttribute('tabs_path_info')(self, script, path)
def meta_type(self):
try: return aq_parent(aq_parent(self)).meta_type
except: return ''
try:
return aq_parent(aq_parent(self)).meta_type
except Exception:
return ''
class PropertySheet(Traversable, Persistent, Implicit):
......@@ -101,15 +106,15 @@ class PropertySheet(Traversable, Persistent, Implicit):
metadata describing those properties. PropertySheets may or may not
provide a web interface for managing its properties."""
_properties=()
_extensible=1
_properties = ()
_extensible = 1
security = ClassSecurityInfo()
security.declareObjectProtected(access_contents_information)
security.setPermissionDefault(access_contents_information,
('Anonymous', 'Manager'))
__reserved_ids= ('values','items')
__reserved_ids = ('values', 'items')
def property_extensible_schema__(self):
# Return a flag indicating whether new properties may be
......@@ -124,11 +129,10 @@ class PropertySheet(Traversable, Persistent, Implicit):
if id in self.__reserved_ids:
raise ValueError(
"'%s' is a reserved Id (forbidden Ids are: %s) " % (
id, self.__reserved_ids
))
id, self.__reserved_ids))
self.id=id
self._md=md or {}
self.id = id
self._md = md or {}
def getId(self):
return self.id
......@@ -146,7 +150,7 @@ class PropertySheet(Traversable, Persistent, Implicit):
return self.v_self()
def valid_property_id(self, id):
if not id or id[:1]=='_' or (id[:3]=='aq_') \
if not id or id[:1] == '_' or (id[:3] == 'aq_') \
or (' ' in id) or escape(id) != id:
return 0
return 1
......@@ -155,7 +159,7 @@ class PropertySheet(Traversable, Persistent, Implicit):
def hasProperty(self, id):
# Return a true value if a property exists with the given id.
for prop in self._propertyMap():
if id==prop['id']:
if id == prop['id']:
return 1
return 0
......@@ -171,16 +175,16 @@ class PropertySheet(Traversable, Persistent, Implicit):
def getPropertyType(self, id):
# Get the type of property 'id', returning None if no
# such property exists.
pself=self.p_self()
pself = self.p_self()
for md in pself._properties:
if md['id']==id:
if md['id'] == id:
return md.get('type', 'string')
return None
def _wrapperCheck(self, object):
# Raise an error if an object is wrapped.
if hasattr(object, 'aq_base'):
raise ValueError, 'Invalid property value: wrapped object'
raise ValueError('Invalid property value: wrapped object')
return
def _setProperty(self, id, value, type='string', meta=None):
......@@ -189,29 +193,32 @@ class PropertySheet(Traversable, Persistent, Implicit):
# systems.
self._wrapperCheck(value)
if not self.valid_property_id(id):
raise BadRequest, 'Invalid property id, %s.' % escape(id)
raise BadRequest('Invalid property id, %s.' % escape(id))
if not self.property_extensible_schema__():
raise BadRequest, (
raise BadRequest(
'Properties cannot be added to this property sheet')
pself=self.p_self()
self=self.v_self()
if hasattr(aq_base(self),id):
if not (id=='title' and not id in self.__dict__):
raise BadRequest, (
pself = self.p_self()
self = self.v_self()
if hasattr(aq_base(self), id):
if not (id == 'title' and id not in self.__dict__):
raise BadRequest(
'Invalid property id, <em>%s</em>. It is in use.' %
escape(id))
if meta is None: meta={}
prop={'id':id, 'type':type, 'meta':meta}
pself._properties=pself._properties+(prop,)
if meta is None:
meta = {}
prop = {'id': id, 'type': type, 'meta': meta}
pself._properties = pself._properties + (prop,)
if type in ('selection', 'multiple selection'):
if not value:
raise BadRequest, (
raise BadRequest(
'The value given for a new selection property '
'must be a variable name<p>')
prop['select_variable']=value
if type=='selection': value=None
else: value=[]
prop['select_variable'] = value
if type == 'selection':
value = None
else:
value = []
# bleah - can't change kw name in api, so use ugly workaround.
if sys.modules['__builtin__'].type(value) == list:
......@@ -225,21 +232,22 @@ class PropertySheet(Traversable, Persistent, Implicit):
# it will used to _replace_ the properties meta data.
self._wrapperCheck(value)
if not self.hasProperty(id):
raise BadRequest, 'The property %s does not exist.' % escape(id)
propinfo=self.propertyInfo(id)
if not 'w' in propinfo.get('mode', 'wd'):
raise BadRequest, '%s cannot be changed.' % escape(id)
if type(value)==type(''):
proptype=propinfo.get('type', 'string')
raise BadRequest('The property %s does not exist.' % escape(id))
propinfo = self.propertyInfo(id)
if 'w' not in propinfo.get('mode', 'wd'):
raise BadRequest('%s cannot be changed.' % escape(id))
if isinstance(value, str):
proptype = propinfo.get('type', 'string')
if proptype in type_converters:
value=type_converters[proptype](value)
value = type_converters[proptype](value)
if meta is not None:
props=[]
pself=self.p_self()
props = []
pself = self.p_self()
for prop in pself._properties:
if prop['id']==id: prop['meta']=meta
if prop['id'] == id:
prop['meta'] = meta
props.append(prop)
pself._properties=tuple(props)
pself._properties = tuple(props)
if type(value) == list:
value = tuple(value)
......@@ -249,16 +257,18 @@ class PropertySheet(Traversable, Persistent, Implicit):
# Delete the property with the given id. If a property with the
# given id does not exist, a ValueError is raised.
if not self.hasProperty(id):
raise BadRequest, 'The property %s does not exist.' % escape(id)
vself=self.v_self()
raise BadRequest('The property %s does not exist.' % escape(id))
vself = self.v_self()
if hasattr(vself, '_reserved_names'):
nd=vself._reserved_names
else: nd=()
if (not 'd' in self.propertyInfo(id).get('mode', 'wd')) or (id in nd):
raise BadRequest, '%s cannot be deleted.' % escape(id)
nd = vself._reserved_names
else:
nd = ()
if ('d' not in self.propertyInfo(id).get('mode', 'wd')) or (id in nd):
raise BadRequest('%s cannot be deleted.' % escape(id))
delattr(vself, id)
pself=self.p_self()
pself._properties=tuple(i for i in pself._properties if i['id'] != id)
pself = self.p_self()
pself._properties = tuple(
[i for i in pself._properties if i['id'] != id])
security.declareProtected(access_contents_information, 'propertyIds')
def propertyIds(self):
......@@ -273,14 +283,16 @@ class PropertySheet(Traversable, Persistent, Implicit):
security.declareProtected(access_contents_information, 'propertyItems')
def propertyItems(self):
# Return a list of (id, property) tuples.
return [(i['id'], self.getProperty(i['id'])) for i in self._propertyMap()]
return [(i['id'], self.getProperty(i['id']))
for i in self._propertyMap()]
security.declareProtected(access_contents_information, 'propertyInfo')
def propertyInfo(self, id):
# Return a mapping containing property meta-data
for p in self._propertyMap():
if p['id']==id: return p
raise ValueError, 'The property %s does not exist.' % escape(id)
if p['id'] == id:
return p
raise ValueError('The property %s does not exist.' % escape(id))
def _propertyMap(self):
# Return a tuple of mappings, giving meta-data for properties.
......@@ -292,9 +304,9 @@ class PropertySheet(Traversable, Persistent, Implicit):
return tuple(dict.copy() for dict in self._propertyMap())
def _propdict(self):
dict={}
dict = {}
for p in self._propertyMap():
dict[p['id']]=p
dict[p['id']] = p
return dict
propstat='<d:propstat xmlns:n="%s">\n' \
......@@ -406,14 +418,14 @@ class PropertySheet(Traversable, Persistent, Implicit):
security.declareProtected(manage_properties, 'manage_propertiesForm')
def manage_propertiesForm(self, URL1):
" "
raise Redirect, URL1+'/manage'
raise Redirect(URL1 + '/manage')
security.declareProtected(manage_properties, 'manage_addProperty')
def manage_addProperty(self, id, value, type, REQUEST=None):
"""Add a new property via the web. Sets a new property with
the given id, type, and value."""
if type in type_converters:
value=type_converters[type](value)
value = type_converters[type](value)
self._setProperty(id, value, type)
if REQUEST is not None:
return self.manage(self, REQUEST)
......@@ -422,14 +434,14 @@ class PropertySheet(Traversable, Persistent, Implicit):
def manage_editProperties(self, REQUEST):
"""Edit object properties via the web."""
for prop in self._propertyMap():
name=prop['id']
name = prop['id']
if 'w' in prop.get('mode', 'wd'):
value=REQUEST.get(name, '')
value = REQUEST.get(name, '')
self._updateProperty(name, value)
return MessageDialog(
title ='Success!',
title='Success!',
message='Your changes have been saved',
action ='manage')
action='manage')
security.declareProtected(manage_properties, 'manage_changeProperties')
def manage_changeProperties(self, REQUEST=None, **kw):
......@@ -439,35 +451,37 @@ class PropertySheet(Traversable, Persistent, Implicit):
name=value parameters
"""
if REQUEST is None:
props={}
else: props=REQUEST
props = {}
else:
props = REQUEST
if kw:
for name, value in kw.items():
props[name]=value
propdict=self._propdict()
props[name] = value
propdict = self._propdict()
for name, value in props.items():
if self.hasProperty(name):
if not 'w' in propdict[name].get('mode', 'wd'):
raise BadRequest, '%s cannot be changed' % escape(name)
if 'w' not in propdict[name].get('mode', 'wd'):
raise BadRequest('%s cannot be changed' % escape(name))
self._updateProperty(name, value)
if REQUEST is not None:
return MessageDialog(
title ='Success!',
title='Success!',
message='Your changes have been saved.',
action ='manage')
action='manage')
security.declareProtected(manage_properties, 'manage_delProperties')
def manage_delProperties(self, ids=None, REQUEST=None):
"""Delete one or more properties specified by 'ids'."""
if REQUEST:
# Bugfix for properties named "ids" (casey)
if ids == self.getProperty('ids', None): ids = None
if ids == self.getProperty('ids', None):
ids = None
ids = REQUEST.get('_ids', ids)
if ids is None:
return MessageDialog(
title='No property specified',
message='No properties were specified!',
action ='./manage',)
action='./manage',)
for id in ids:
self._delProperty(id)
if REQUEST is not None:
......@@ -491,8 +505,8 @@ class DefaultProperties(Virtual, PropertySheet, View):
properties -- it stores its property values in the instance of
its owner."""
id='default'
_md={'xmlns': 'http://www.zope.org/propsets/default'}
id = 'default'
_md = {'xmlns': 'http://www.zope.org/propsets/default'}
InitializeClass(DefaultProperties)
......@@ -612,7 +626,7 @@ class PropertySheets(Traversable, Implicit, Tabs):
"""A tricky container to keep property sets from polluting
an object's direct attribute namespace."""
id='propertysheets'
id = 'propertysheets'
security = ClassSecurityInfo()
security.declareObjectProtected(access_contents_information)
......@@ -620,20 +634,21 @@ class PropertySheets(Traversable, Implicit, Tabs):
('Anonymous', 'Manager'))
# optionally to be overridden by derived classes
PropertySheetClass= PropertySheet
PropertySheetClass = PropertySheet
webdav = DAVProperties()
webdav =DAVProperties()
def _get_defaults(self):
return (self.webdav,)
def __propsets__(self):
propsets = aq_parent(self).__propsets__
__traceback_info__= propsets, type(propsets)
__traceback_info__ = propsets, type(propsets)
return self._get_defaults() + propsets
def __bobo_traverse__(self, REQUEST, name=None):
for propset in self.__propsets__():
if propset.getId()==name:
if propset.getId() == name:
return propset.__of__(self)
return getattr(self, name)
......@@ -642,16 +657,18 @@ class PropertySheets(Traversable, Implicit, Tabs):
security.declareProtected(access_contents_information, 'values')
def values(self):
propsets=self.__propsets__()
propsets = self.__propsets__()
return [n.__of__(self) for n in propsets]
security.declareProtected(access_contents_information, 'items')
def items(self):
propsets=self.__propsets__()
r=[]
propsets = self.__propsets__()
r = []
for n in propsets:
if hasattr(n,'id'): id=n.id
else: id=''
if hasattr(n, 'id'):
id = n.id
else:
id = ''
r.append((id, n.__of__(self)))
return r
......@@ -659,43 +676,45 @@ class PropertySheets(Traversable, Implicit, Tabs):
security.declareProtected(access_contents_information, 'get')
def get(self, name, default=None):
for propset in self.__propsets__():
if propset.id==name or (hasattr(propset, 'xml_namespace') and \
propset.xml_namespace()==name):
if propset.id == name or (hasattr(propset, 'xml_namespace') and
propset.xml_namespace() == name):
return propset.__of__(self)
return default
security.declareProtected(manage_properties, 'manage_addPropertySheet')
def manage_addPropertySheet(self, id, ns, REQUEST=None):
""" """
md={'xmlns':ns}
ps= self.PropertySheetClass(id, md)
md = {'xmlns': ns}
ps = self.PropertySheetClass(id, md)
self.addPropertySheet(ps)
if REQUEST is None: return ps
ps= self.get(id)
if REQUEST is None:
return ps
ps = self.get(id)
REQUEST.RESPONSE.redirect('%s/manage' % ps.absolute_url())
security.declareProtected(manage_properties, 'addPropertySheet')
def addPropertySheet(self, propset):
propsets = aq_parent(self).__propsets__
propsets = propsets+(propset,)
propsets = propsets + (propset,)
aq_parent(self).__propsets__ = propsets
security.declareProtected(manage_properties, 'delPropertySheet')
def delPropertySheet(self, name):
result=[]
result = []
for propset in aq_parent(self).__propsets__:
if propset.getId() != name and propset.xml_namespace() != name:
result.append(propset)
aq_parent(self).__propsets__=tuple(result)
aq_parent(self).__propsets__ = tuple(result)
## DM: deletion support
def isDeletable(self,name):
def isDeletable(self, name):
'''currently, we say that *name* is deletable when it is not a
default sheet. Later, we may further restrict deletability
based on an instance attribute.'''
ps= self.get(name)
if ps is None: return 0
if ps in self._get_defaults(): return 0
ps = self.get(name)
if ps is None:
return 0
if ps in self._get_defaults():
return 0
return 1
def manage_delPropertySheets(self, ids=(), REQUEST=None):
......@@ -714,35 +733,35 @@ class PropertySheets(Traversable, Implicit, Tabs):
def getId(self):
return self.id
# Management interface:
security.declareProtected(view_management_screens, 'manage')
manage = DTMLFile('dtml/propertysheets', globals())
def manage_options(self):
"""Return a manage option data structure for me instance
"""
try: r=self.REQUEST
except: r=None
try:
r = self.REQUEST
except Exception:
r = None
if r is None:
pre='../'
pre = '../'
else:
pre=r['URLPATH0']
for i in (1,2):
l=pre.rfind('/')
pre = r['URLPATH0']
for i in (1, 2):
l = pre.rfind('/')
if l >= 0:
pre=pre[:l]
pre=pre+'/'
pre = pre[:l]
pre = pre + '/'
r=[]
r = []
for d in aq_parent(self).manage_options:
r.append({'label': d['label'], 'action': pre+d['action']})
r.append({'label': d['label'], 'action': pre + d['action']})
return r
def tabs_path_info(self, script, path):
l=path.rfind('/')
if l >= 0: path=path[:l]
l = path.rfind('/')
if l >= 0:
path = path[:l]
return PropertySheets.inheritedAttribute('tabs_path_info')(
self, script, path)
......@@ -753,8 +772,9 @@ class DefaultPropertySheets(PropertySheets):
"""A PropertySheets container that contains a default property
sheet for compatibility with the arbitrary property mgmt
design of Zope PropertyManagers."""
default=DefaultProperties()
webdav =DAVProperties()
default = DefaultProperties()
webdav = DAVProperties()
def _get_defaults(self):
return (self.default, self.webdav)
......@@ -769,7 +789,7 @@ class vps(Base):
attribute of a PropertyManager is accessed.
"""
def __init__(self, c=PropertySheets):
self.c=c
self.c = c
def __of__(self, parent):
return self.c().__of__(parent)
......
......@@ -18,6 +18,7 @@ This module can also be used as a simple template for implementing new
item types.
"""
import logging
import marshal
import re
import sys
......@@ -59,9 +60,9 @@ from OFS.CopySupport import CopySource
from OFS.role import RoleManager
from OFS.Traversable import Traversable
import logging
logger = logging.getLogger()
class Item(Base,
Resource,
CopySource,
......
......@@ -204,7 +204,7 @@ class Traversable:
if name[0] == '_':
# Never allowed in a URL.
raise NotFound, name
raise NotFound(name)
if name == '..':
next = aq_parent(obj)
......
......@@ -42,7 +42,7 @@ the <em>browse</em> button to select a local file to upload.
<td align="left" valign="top" colspan="2">
<div class="form-element">
<dtml-if wl_isLocked>
<em>Locked by WebDAV</em>
<em>Locked</em>
<dtml-else>
<input class="form-element" type="submit" name="SUBMIT" value="Save Changes">
</dtml-if>
......@@ -74,7 +74,7 @@ the <em>browse</em> button to select a local file to upload.
<td align="left" valign="top">
<div class="form-element">
<dtml-if wl_isLocked>
<em>Locked by WebDAV</em>
<em>Locked</em>
<dtml-else>
<input class="form-element" type="submit" value="Upload File">
</dtml-if>
......
......@@ -87,7 +87,7 @@ text type and small enough to be edited in a text area.
<td align="left" valign="top">
<div class="form-element">
<dtml-if wl_isLocked>
<em>Locked by WebDAV</em>
<em>Locked</em>
<dtml-else>
<input class="form-element" type="submit" name="manage_edit:method"
value="Save Changes">
......@@ -114,7 +114,7 @@ text type and small enough to be edited in a text area.
<td align="left" valign="top">
<div class="form-element">
<dtml-if wl_isLocked>
<em>Locked by WebDAV</em>
<em>Locked</em>
<dtml-else>
<input class="form-element" type="submit" name="manage_upload:method"
value="Upload">
......
......@@ -70,7 +70,7 @@ button and click <em>upload</em> to update the contents of the &dtml-kind;.
<td align="left" valign="top">
<div class="form-element">
<dtml-if wl_isLocked>
<em>Locked by WebDAV</em>
<em>Locked</em>
<dtml-else>
<input class="form-element" type="submit" name="submit"
value="Save Changes">
......@@ -103,7 +103,7 @@ button and click <em>upload</em> to update the contents of the &dtml-kind;.
<td align="left" valign="top">
<div class="form-element">
<dtml-if wl_isLocked>
<em>Locked by WebDAV</em>
<em>Locked</em>
<dtml-else>
<input class="form-element" type="submit" name="submit"
value="Upload">
......
......@@ -105,8 +105,3 @@ class ApplicationTests(unittest.TestCase):
def _noWay(self, key, default=None):
raise KeyError(key)
def test_suite():
return unittest.TestSuite((
unittest.makeSuite(ApplicationTests),
))
......@@ -150,7 +150,7 @@ class TestCopySupport(EventTest):
)
def test_5_COPY(self):
# Test webdav COPY
# Test COPY
req = self.app.REQUEST
req.environ['HTTP_DEPTH'] = 'infinity'
req.environ['HTTP_DESTINATION'] = ('%s/subfolder/mydoc'
......@@ -165,7 +165,7 @@ class TestCopySupport(EventTest):
)
def test_6_MOVE(self):
# Test webdav MOVE
# Test MOVE
req = self.app.REQUEST
req.environ['HTTP_DEPTH'] = 'infinity'
req.environ['HTTP_DESTINATION'] = ('%s/subfolder/mydoc'
......@@ -179,7 +179,7 @@ class TestCopySupport(EventTest):
)
def test_7_DELETE(self):
# Test webdav DELETE
# Test DELETE
req = self.app.REQUEST
req['URL'] = '%s/mydoc' % self.folder.absolute_url()
self.folder.mydoc.DELETE(req, req.RESPONSE)
......@@ -274,7 +274,7 @@ class TestCopySupportSublocation(EventTest):
)
def test_5_COPY(self):
# Test webdav COPY
# Test COPY
req = self.app.REQUEST
req.environ['HTTP_DEPTH'] = 'infinity'
req.environ['HTTP_DESTINATION'] = ('%s/subfolder/myfolder'
......@@ -293,7 +293,7 @@ class TestCopySupportSublocation(EventTest):
)
def test_6_MOVE(self):
# Test webdav MOVE
# Test MOVE
req = self.app.REQUEST
req.environ['HTTP_DEPTH'] = 'infinity'
req.environ['HTTP_DESTINATION'] = ('%s/subfolder/myfolder'
......@@ -309,7 +309,7 @@ class TestCopySupportSublocation(EventTest):
)
def test_7_DELETE(self):
# Test webdav DELETE
# Test DELETE
req = self.app.REQUEST
req['URL'] = '%s/myfolder' % self.folder.absolute_url()
self.folder.myfolder.DELETE(req, req.RESPONSE)
......
......@@ -148,7 +148,7 @@ class TestCopySupport(HookTest):
)
def test_5_COPY(self):
# Test webdav COPY
# Test COPY
req = self.app.REQUEST
req.environ['HTTP_DEPTH'] = 'infinity'
req.environ['HTTP_DESTINATION'] = '%s/subfolder/mydoc' % self.folder.absolute_url()
......@@ -159,7 +159,7 @@ class TestCopySupport(HookTest):
)
def test_6_MOVE(self):
# Test webdav MOVE
# Test MOVE
req = self.app.REQUEST
req.environ['HTTP_DEPTH'] = 'infinity'
req.environ['HTTP_DESTINATION'] = '%s/subfolder/mydoc' % self.folder.absolute_url()
......@@ -170,7 +170,7 @@ class TestCopySupport(HookTest):
)
def test_7_DELETE(self):
# Test webdav DELETE
# Test DELETE
req = self.app.REQUEST
req['URL'] = '%s/mydoc' % self.folder.absolute_url()
self.folder.mydoc.DELETE(req, req.RESPONSE)
......@@ -243,7 +243,7 @@ class TestCopySupportSublocation(HookTest):
)
def test_5_COPY(self):
# Test webdav COPY
# Test COPY
req = self.app.REQUEST
req.environ['HTTP_DEPTH'] = 'infinity'
req.environ['HTTP_DESTINATION'] = '%s/subfolder/myfolder' % self.folder.absolute_url()
......@@ -256,7 +256,7 @@ class TestCopySupportSublocation(HookTest):
)
def test_6_MOVE(self):
# Test webdav MOVE
# Test MOVE
req = self.app.REQUEST
req.environ['HTTP_DEPTH'] = 'infinity'
req.environ['HTTP_DESTINATION'] = '%s/subfolder/myfolder' % self.folder.absolute_url()
......@@ -269,7 +269,7 @@ class TestCopySupportSublocation(HookTest):
)
def test_7_DELETE(self):
# Test webdav DELETE
# Test DELETE
req = self.app.REQUEST
req['URL'] = '%s/myfolder' % self.folder.absolute_url()
self.folder.myfolder.DELETE(req, req.RESPONSE)
......
......@@ -2,9 +2,9 @@ import unittest
import Testing
import Zope2
Zope2.startup()
import os, sys
import os
import sys
import time
from cStringIO import StringIO
......@@ -35,24 +35,28 @@ except:
imagedata = os.path.join(here, 'test.gif')
filedata = os.path.join(here, 'test.gif')
Zope2.startup()
def makeConnection():
import ZODB
from ZODB.DemoStorage import DemoStorage
s = DemoStorage()
return ZODB.DB( s ).open()
return ZODB.DB(s).open()
def aputrequest(file, content_type):
resp = HTTPResponse(stdout=sys.stdout)
environ = {}
environ['SERVER_NAME']='foo'
environ['SERVER_PORT']='80'
environ['SERVER_NAME'] = 'foo'
environ['SERVER_PORT'] = '80'
environ['REQUEST_METHOD'] = 'PUT'
environ['CONTENT_TYPE'] = content_type
req = HTTPRequest(stdin=file, environ=environ, response=resp)
return req
class DummyCache:
def __init__(self):
self.clear()
......@@ -71,8 +75,8 @@ class DummyCache:
self.invalidated = ob
def clear(self):
self.set=None
self.get=None
self.set = None
self.get = None
self.invalidated = None
self.si = None
......@@ -80,18 +84,19 @@ class DummyCache:
self.si = si
ADummyCache=DummyCache()
ADummyCache = DummyCache()
class DummyCacheManager(SimpleItem):
def ZCacheManager_getCache(self):
return ADummyCache
class EventCatcher(object):
def __init__(self):
self.created = []
self.modified = []
self.setUp()
def setUp(self):
......@@ -118,22 +123,22 @@ class EventCatcher(object):
if isinstance(event.object, OFS.Image.File):
self.modified.append(event)
class FileTests(unittest.TestCase):
data = open(filedata, 'rb').read()
content_type = 'application/octet-stream'
factory = 'manage_addFile'
def setUp( self ):
def setUp(self):
self.connection = makeConnection()
self.eventCatcher = EventCatcher()
try:
r = self.connection.root()
a = Application()
r['Application'] = a
self.root = a
responseOut = self.responseOut = StringIO()
self.app = makerequest( self.root, stdout=responseOut )
self.app = makerequest(self.root, stdout=responseOut)
self.app.dcm = DummyCacheManager()
factory = getattr(self.app, self.factory)
factory('file',
......@@ -148,18 +153,20 @@ class FileTests(unittest.TestCase):
self.connection.close()
raise
transaction.begin()
self.file = getattr( self.app, 'file' )
self.file = getattr(self.app, 'file')
# Since we do the create here, let's test the events here too
self.assertEquals(1, len(self.eventCatcher.created))
self.assertTrue(aq_base(self.eventCatcher.created[0].object) is aq_base(self.file))
self.assertTrue(
aq_base(self.eventCatcher.created[0].object) is aq_base(self.file))
self.assertEquals(1, len(self.eventCatcher.modified))
self.assertTrue(aq_base(self.eventCatcher.created[0].object) is aq_base(self.file))
self.assertTrue(
aq_base(self.eventCatcher.created[0].object) is aq_base(self.file))
self.eventCatcher.reset()
def tearDown( self ):
def tearDown(self):
del self.file
transaction.abort()
self.connection.close()
......@@ -168,7 +175,6 @@ class FileTests(unittest.TestCase):
del self.root
del self.connection
ADummyCache.clear()
self.eventCatcher.tearDown()
def testViewImageOrFile(self):
......@@ -227,7 +233,9 @@ class FileTests(unittest.TestCase):
def testIfModSince(self):
now = time.time()
e = {'SERVER_NAME':'foo', 'SERVER_PORT':'80', 'REQUEST_METHOD':'GET'}
e = {'SERVER_NAME': 'foo',
'SERVER_PORT': '80',
'REQUEST_METHOD': 'GET'}
# not modified since
t_notmod = rfc1123_date(now)
......@@ -235,7 +243,7 @@ class FileTests(unittest.TestCase):
out = StringIO()
resp = HTTPResponse(stdout=out)
req = HTTPRequest(sys.stdin, e, resp)
data = self.file.index_html(req,resp)
data = self.file.index_html(req, resp)
self.assertEqual(resp.getStatus(), 304)
self.assertEqual(data, '')
......@@ -245,7 +253,7 @@ class FileTests(unittest.TestCase):
out = StringIO()
resp = HTTPResponse(stdout=out)
req = HTTPRequest(sys.stdin, e, resp)
data = self.file.index_html(req,resp)
data = self.file.index_html(req, resp)
self.assertEqual(resp.getStatus(), 200)
self.assertEqual(data, str(self.file.data))
......@@ -317,6 +325,7 @@ class FileTests(unittest.TestCase):
self.assertRaises(TypeError, self.file.manage_edit,
'foobar', 'text/plain', filedata=val)
class ImageTests(FileTests):
data = open(filedata, 'rb').read()
content_type = 'image/gif'
......@@ -332,16 +341,19 @@ class ImageTests(FileTests):
self.assertTrue(ADummyCache.set)
def testStr(self):
self.assertEqual(str(self.file),
('<img src="http://foo/file" alt="" title="" height="16" width="16" />'))
self.assertEqual(
str(self.file),
('<img src="http://foo/file" '
'alt="" title="" height="16" width="16" />'))
def testTag(self):
tag_fmt = '<img src="http://foo/file" alt="%s" title="%s" height="16" width="16" />'
self.assertEqual(self.file.tag(), (tag_fmt % ('','')))
tag_fmt = ('<img src="http://foo/file" '
'alt="%s" title="%s" height="16" width="16" />')
self.assertEqual(self.file.tag(), (tag_fmt % ('', '')))
self.file.manage_changeProperties(title='foo')
self.assertEqual(self.file.tag(), (tag_fmt % ('','foo')))
self.assertEqual(self.file.tag(), (tag_fmt % ('', 'foo')))
self.file.manage_changeProperties(alt='bar')
self.assertEqual(self.file.tag(), (tag_fmt % ('bar','foo')))
self.assertEqual(self.file.tag(), (tag_fmt % ('bar', 'foo')))
def testViewImageOrFile(self):
pass # dtml method,screw it
......@@ -355,6 +367,7 @@ class ImageTests(FileTests):
class ImagePublishTests(Testing.ZopeTestCase.FunctionalTestCase):
def testTagSafe(self):
self.app.manage_addImage("image", "")
res = self.publish(
......@@ -364,11 +377,3 @@ class ImagePublishTests(Testing.ZopeTestCase.FunctionalTestCase):
self.assertFalse(
'<script type="text/javascript">alert(\'evil\');</script>'
in res.getBody())
def test_suite():
return unittest.TestSuite((
unittest.makeSuite(FileTests),
unittest.makeSuite(ImageTests),
unittest.makeSuite(ImagePublishTests)
))
......@@ -11,9 +11,3 @@ class TestFolder(unittest.TestCase):
verifyClass(IFolder, Folder)
verifyClass(IWriteLock, Folder)
def test_suite():
return unittest.TestSuite((
unittest.makeSuite(TestFolder),
))
......@@ -13,9 +13,3 @@ class TestOrderedFolder(unittest.TestCase):
verifyClass(IOrderedContainer, OrderedFolder)
verifyClass(IOrderedFolder, OrderedFolder)
verifyClass(IWriteLock, OrderedFolder)
def test_suite():
return unittest.TestSuite((
unittest.makeSuite(TestOrderedFolder),
))
......@@ -17,7 +17,6 @@ import unittest
class TestPropertyManager(unittest.TestCase):
"""Property management tests."""
def _getTargetClass(self):
from OFS.PropertyManager import PropertyManager
......@@ -33,24 +32,24 @@ class TestPropertyManager(unittest.TestCase):
verifyClass(IPropertyManager, PropertyManager)
def testLinesPropertyIsTuple( self ):
def testLinesPropertyIsTuple(self):
inst = self._makeOne()
inst._setProperty('prop', ['xxx', 'yyy'], 'lines')
self.assertTrue(type(inst.getProperty('prop')) == type(()))
self.assertTrue(type(inst.prop) == type(()))
self.assertTrue(isinstance(inst.getProperty('prop'), tuple))
self.assertTrue(isinstance(inst.prop, tuple))
inst._setPropValue('prop', ['xxx', 'yyy'])
self.assertTrue(type(inst.getProperty('prop')) == type(()))
self.assertTrue(type(inst.prop) == type(()))
self.assertTrue(isinstance(inst.getProperty('prop'), tuple))
self.assertTrue(isinstance(inst.prop, tuple))
inst._updateProperty('prop', ['xxx', 'yyy'])
self.assertTrue(type(inst.getProperty('prop')) == type(()))
self.assertTrue(type(inst.prop) == type(()))
self.assertTrue(isinstance(inst.getProperty('prop'), tuple))
self.assertTrue(isinstance(inst.prop, tuple))
inst.manage_addProperty('prop2', ['xxx', 'yyy'], 'lines')
self.assertTrue(type(inst.getProperty('prop2')) == type(()))
self.assertTrue(type(inst.prop2) == type(()))
self.assertTrue(isinstance(inst.getProperty('prop2'), tuple))
self.assertTrue(isinstance(inst.prop2, tuple))
def test_propertyLabel_no_label_falls_back_to_id(self):
class NoLabel(self._getTargetClass()):
......@@ -88,23 +87,21 @@ class TestPropertyManager(unittest.TestCase):
class TestPropertySheet(unittest.TestCase):
"""Property management tests."""
def _makeOne(self, *args, **kw):
from OFS.PropertySheets import PropertySheet
return PropertySheet(*args, **kw)
def testPropertySheetLinesPropertyIsTuple(self):
inst = self._makeOne('foo')
inst._setProperty('prop', ['xxx', 'yyy'], 'lines')
self.assertTrue(type(inst.getProperty('prop')) == type(()))
self.assertTrue(type(inst.prop) == type(()))
self.assertTrue(isinstance(inst.getProperty('prop'), tuple))
self.assertTrue(isinstance(inst.prop, tuple))
inst._updateProperty('prop', ['xxx', 'yyy'])
self.assertTrue(type(inst.getProperty('prop')) == type(()))
self.assertTrue(type(inst.prop) == type(()))
self.assertTrue(isinstance(inst.getProperty('prop'), tuple))
self.assertTrue(isinstance(inst.prop, tuple))
inst.manage_addProperty('prop2', ['xxx', 'yyy'], 'lines')
self.assertTrue(type(inst.getProperty('prop2')) == type(()))
......
......@@ -109,7 +109,7 @@ class TestRequestRange(unittest.TestCase):
return body + rv
def createLastModifiedDate(self, offset=0):
from webdav.common import rfc1123_date
from App.Common import rfc1123_date
return rfc1123_date(self.file._p_mtime + offset)
def expectUnsatisfiable(self, range):
......
import unittest
class DTMLDocumentTests(unittest.TestCase):
def _getTargetClass(self):
......@@ -36,9 +37,3 @@ class DummyDispatcher:
def _setObject(self, key, value):
self._set[key] = value
def test_suite():
return unittest.TestSuite((
unittest.makeSuite(DTMLDocumentTests),
unittest.makeSuite(FactoryTests),
))
import unittest
class DTMLMethodTests(unittest.TestCase):
def _getTargetClass(self):
......@@ -45,10 +46,3 @@ class DummyDispatcher:
def _setObject(self, key, value):
self._set[key] = value
def test_suite():
return unittest.TestSuite((
unittest.makeSuite(DTMLMethodTests),
unittest.makeSuite(FactoryTests),
))
# -*- encoding: iso-8859-15 -*-
"""ZopePageTemplate regression tests.
"""
ZopePageTemplate regression tests.
Ensures that adding a page template works correctly.
Note: Tests require Zope >= 2.7
"""
import sys
import unittest
import Zope2
import transaction
import zope.component.testing
......@@ -26,7 +23,10 @@ from zope.component import provideUtility
from Products.PageTemplates.interfaces import IUnicodeEncodingConflictResolver
from Products.PageTemplates.unicodeconflictresolver \
import PreferredCharsetResolver
import Zope2
if sys.version_info >= (3, 0):
unicode = str
ascii_str = '<html><body>hello world</body></html>'
iso885915_str = '<html><body></body></html>'
......@@ -81,9 +81,9 @@ html_with_upper_attr = '''<html><body>
</body></html>
'''
installProduct('PageTemplates')
class ZPTUtilsTests(unittest.TestCase):
def testExtractEncodingFromXMLPreamble(self):
......@@ -161,8 +161,8 @@ class ZPTUnicodeEncodingConflictResolution(ZopeTestCase):
self.app.REQUEST.set('data',
unicode('', 'iso-8859-15').encode('utf-8'))
result = zpt.pt_render()
self.assertFalse(result.startswith(unicode('<div></div>',
'iso-8859-15')))
self.assertFalse(
result.startswith(unicode('<div></div>', 'iso-8859-15')))
def testStructureWithAccentedChars(self):
manage_addPageTemplate(self.app, 'test',
......@@ -197,8 +197,7 @@ class ZPTUnicodeEncodingConflictResolution(ZopeTestCase):
import cPickle
empty = ZopePageTemplate(id='empty', text=' ',
content_type='text/html',
output_encoding='ascii',
)
output_encoding='ascii')
state = cPickle.dumps(empty, protocol=1)
cPickle.loads(state)
......@@ -237,6 +236,7 @@ class ZPTUnicodeEncodingConflictResolution(ZopeTestCase):
self.app.REQUEST.debug.sourceAnnotations = True
self.assertEqual(zpt.pt_render().startswith(unicode('<!--')), True)
class ZopePageTemplateFileTests(ZopeTestCase):
def test_class_conforms_to_IWriteLock(self):
......@@ -269,8 +269,7 @@ class ZopePageTemplateFileTests(ZopeTestCase):
zpt = self.app['test']
result = zpt.pt_render()
# use startswith() because the renderer appends a trailing \n
self.assertTrue(result.encode('iso-8859-15'
).startswith(iso885915_str))
self.assertTrue(result.encode('iso-8859-15').startswith(iso885915_str))
self.assertEqual(zpt.output_encoding, 'utf-8')
def testPT_RenderWithUTF8(self):
......@@ -305,7 +304,7 @@ class ZopePageTemplateFileTests(ZopeTestCase):
return zpt
def _makePUTRequest(self, body):
return {'BODY' : body}
return {'BODY': body}
def _put(self, text):
zpt = self._createZPT()
......@@ -355,6 +354,7 @@ class ZopePageTemplateFileTests(ZopeTestCase):
result = zpt.pt_render()
self.assertEqual('ATTR' in result, False)
class PreferredCharsetUnicodeResolverTests(unittest.TestCase):
def testPreferredCharsetResolverWithoutRequestAndWithoutEncoding(self):
......@@ -479,6 +479,7 @@ class ZPTMacros(zope.component.testing.PlacelessSetup, unittest.TestCase):
pt.pt_render(source=True)
self.assertEqual(pt.pt_errors(), None)
class SrcTests(unittest.TestCase):
def _getTargetClass(self):
......
......@@ -64,7 +64,7 @@
<tr>
<td align="left" valign="top" colspan="4">
<div class="form-element">
<em tal:condition="context/wl_isLocked">Locked by WebDAV</em>
<em tal:condition="context/wl_isLocked">Locked</em>
<input tal:condition="not:context/wl_isLocked"
class="form-element" type="submit"
name="pt_editAction:method" value="Save Changes"/>
......@@ -110,7 +110,7 @@ context</a> to view or download the current text.</p>
<td></td>
<td align="left" valign="top">
<div class="form-element">
<em tal:condition="context/wl_isLocked">Locked by WebDAV</em>
<em tal:condition="context/wl_isLocked">Locked</em>
<input tal:condition="not:context/wl_isLocked"
class="form-element" type="submit" value="Upload File" />
</div>
......
......@@ -40,7 +40,7 @@ probably need to manage Zope using its raw IP address to fix things.
<td align="left" valign="top" colspan="2">
<div class="form-element">
<dtml-if wl_isLocked>
<em>Locked by WebDAV</em>
<em>Locked</em>
<dtml-else>
<input class="form-element" type="submit" name="SUBMIT" value="Save Changes">
</dtml-if>
......
......@@ -132,7 +132,7 @@ class TestFunctional(ZopeTestCase.FunctionalTestCase):
self.assertEqual(self.folder.index_html(), 'foo')
def testPUTNew(self):
# Create a new object via FTP or WebDAV
# Create a new object via PUT
self.setPermissions([add_documents_images_and_files])
put_data = StringIO('foo')
......
......@@ -34,7 +34,8 @@ from zope.publisher.interfaces.browser import IBrowserPublisher
from zope.traversing.namespace import namespaceLookup
from zope.traversing.namespace import nsParse
UNSPECIFIED_ROLES=''
UNSPECIFIED_ROLES = ''
def quote(text):
# quote url path segments, but leave + and @ intact
......
import base64
import unittest
import Zope2
Zope2.startup()
import transaction
from Products.SiteAccess.VirtualHostMonster import VirtualHostMonster
from Testing.makerequest import makerequest
import transaction
import base64
import Zope2
auth_info = 'Basic %s' % base64.encodestring('manager:secret').rstrip()
Zope2.startup()
class TestPUTFactory(unittest.TestCase):
......@@ -46,25 +48,29 @@ class TestPUTFactory(unittest.TestCase):
def testSimpleVirtualHosting(self):
request = self.app.REQUEST
put = request.traverse('/VirtualHostBase/http/foo.com:80/VirtualHostRoot/folder/doc')
put = request.traverse('/VirtualHostBase/http/foo.com:80/'
'VirtualHostRoot/folder/doc')
put(request, request.RESPONSE)
self.assertTrue('doc' in self.folder.objectIds())
def testSubfolderVirtualHosting(self):
request = self.app.REQUEST
put = request.traverse('/VirtualHostBase/http/foo.com:80/folder/VirtualHostRoot/doc')
put = request.traverse('/VirtualHostBase/http/foo.com:80/'
'folder/VirtualHostRoot/doc')
put(request, request.RESPONSE)
self.assertTrue('doc' in self.folder.objectIds())
def testInsideOutVirtualHosting(self):
request = self.app.REQUEST
put = request.traverse('/VirtualHostBase/http/foo.com:80/VirtualHostRoot/_vh_foo/folder/doc')
put = request.traverse('/VirtualHostBase/http/foo.com:80/'
'VirtualHostRoot/_vh_foo/folder/doc')
put(request, request.RESPONSE)
self.assertTrue('doc' in self.folder.objectIds())
def testSubfolderInsideOutVirtualHosting(self):
request = self.app.REQUEST
put = request.traverse('/VirtualHostBase/http/foo.com:80/folder/VirtualHostRoot/_vh_foo/doc')
put = request.traverse('/VirtualHostBase/http/foo.com:80/'
'folder/VirtualHostRoot/_vh_foo/doc')
put(request, request.RESPONSE)
self.assertTrue('doc' in self.folder.objectIds())
......@@ -79,13 +85,7 @@ class TestPUTFactory(unittest.TestCase):
put = request.traverse('/A/B/a')
put(request, request.RESPONSE)
# PUT should no acquire A.a
self.assertEqual(str(self.app.A.a), 'I am file a', 'PUT factory should not acquire content')
self.assertEqual(str(self.app.A.a), 'I am file a',
'PUT factory should not acquire content')
# check for the newly created file
self.assertEqual(str(self.app.A.B.a), 'bar')
def test_suite():
return unittest.TestSuite((
unittest.makeSuite(TestPUTFactory),
))
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment