Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
Zope
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
Zope
Commits
992f73e2
Commit
992f73e2
authored
Aug 06, 2016
by
Hanno Schlichting
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
flake8
parent
bcaeb4ae
Changes
24
Show whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
544 additions
and
512 deletions
+544
-512
src/OFS/Image.py
src/OFS/Image.py
+226
-191
src/OFS/ObjectManager.py
src/OFS/ObjectManager.py
+1
-1
src/OFS/PropertySheets.py
src/OFS/PropertySheets.py
+161
-141
src/OFS/SimpleItem.py
src/OFS/SimpleItem.py
+2
-1
src/OFS/Traversable.py
src/OFS/Traversable.py
+1
-1
src/OFS/dtml/documentEdit.dtml
src/OFS/dtml/documentEdit.dtml
+2
-2
src/OFS/dtml/fileEdit.dtml
src/OFS/dtml/fileEdit.dtml
+2
-2
src/OFS/dtml/imageEdit.dtml
src/OFS/dtml/imageEdit.dtml
+2
-2
src/OFS/tests/testApplication.py
src/OFS/tests/testApplication.py
+0
-5
src/OFS/tests/testCopySupportEvents.py
src/OFS/tests/testCopySupportEvents.py
+6
-6
src/OFS/tests/testCopySupportHooks.py
src/OFS/tests/testCopySupportHooks.py
+6
-6
src/OFS/tests/testFileAndImage.py
src/OFS/tests/testFileAndImage.py
+55
-50
src/OFS/tests/testFolder.py
src/OFS/tests/testFolder.py
+0
-6
src/OFS/tests/testOrderedFolder.py
src/OFS/tests/testOrderedFolder.py
+0
-6
src/OFS/tests/testProperties.py
src/OFS/tests/testProperties.py
+13
-16
src/OFS/tests/testRanges.py
src/OFS/tests/testRanges.py
+1
-1
src/OFS/tests/test_DTMLDocument.py
src/OFS/tests/test_DTMLDocument.py
+1
-6
src/OFS/tests/test_DTMLMethod.py
src/OFS/tests/test_DTMLMethod.py
+1
-7
src/Products/PageTemplates/tests/testZopePageTemplate.py
src/Products/PageTemplates/tests/testZopePageTemplate.py
+42
-41
src/Products/PageTemplates/www/ptEdit.zpt
src/Products/PageTemplates/www/ptEdit.zpt
+2
-2
src/Products/SiteAccess/www/manage_edit.dtml
src/Products/SiteAccess/www/manage_edit.dtml
+1
-1
src/Testing/ZopeTestCase/testFunctional.py
src/Testing/ZopeTestCase/testFunctional.py
+1
-1
src/ZPublisher/BaseRequest.py
src/ZPublisher/BaseRequest.py
+2
-1
src/webdav/tests/testPUT_factory.py
src/webdav/tests/testPUT_factory.py
+16
-16
No files found.
src/OFS/Image.py
View file @
992f73e2
...
...
@@ -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
]
==
'
\
211
PNG
\
r
\
n
\
032
\
n
'
)
and
(
data
[
12
:
16
]
==
'IHDR'
)):
elif
((
size
>=
24
)
and
(
data
[:
8
]
==
'
\
211
PNG
\
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
)
src/OFS/ObjectManager.py
View file @
992f73e2
...
...
@@ -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
)
...
...
src/OFS/PropertySheets.py
View file @
992f73e2
...
...
@@ -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
)
...
...
src/OFS/SimpleItem.py
View file @
992f73e2
...
...
@@ -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
,
...
...
src/OFS/Traversable.py
View file @
992f73e2
...
...
@@ -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
)
...
...
src/OFS/dtml/documentEdit.dtml
View file @
992f73e2
...
...
@@ -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>
...
...
src/OFS/dtml/fileEdit.dtml
View file @
992f73e2
...
...
@@ -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">
...
...
src/OFS/dtml/imageEdit.dtml
View file @
992f73e2
...
...
@@ -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">
...
...
src/OFS/tests/testApplication.py
View file @
992f73e2
...
...
@@ -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
),
))
src/OFS/tests/testCopySupportEvents.py
View file @
992f73e2
...
...
@@ -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
)
...
...
src/OFS/tests/testCopySupportHooks.py
View file @
992f73e2
...
...
@@ -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
)
...
...
src/OFS/tests/testFileAndImage.py
View file @
992f73e2
...
...
@@ -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
)
))
src/OFS/tests/testFolder.py
View file @
992f73e2
...
...
@@ -11,9 +11,3 @@ class TestFolder(unittest.TestCase):
verifyClass
(
IFolder
,
Folder
)
verifyClass
(
IWriteLock
,
Folder
)
def
test_suite
():
return
unittest
.
TestSuite
((
unittest
.
makeSuite
(
TestFolder
),
))
src/OFS/tests/testOrderedFolder.py
View file @
992f73e2
...
...
@@ -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
),
))
src/OFS/tests/testProperties.py
View file @
992f73e2
...
...
@@ -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
(()))
...
...
src/OFS/tests/testRanges.py
View file @
992f73e2
...
...
@@ -109,7 +109,7 @@ class TestRequestRange(unittest.TestCase):
return
body
+
rv
def
createLastModifiedDate
(
self
,
offset
=
0
):
from
webdav.c
ommon
import
rfc1123_date
from
App.C
ommon
import
rfc1123_date
return
rfc1123_date
(
self
.
file
.
_p_mtime
+
offset
)
def
expectUnsatisfiable
(
self
,
range
):
...
...
src/OFS/tests/test_DTMLDocument.py
View file @
992f73e2
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
),
))
src/OFS/tests/test_DTMLMethod.py
View file @
992f73e2
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
),
))
src/Products/PageTemplates/tests/testZopePageTemplate.py
View file @
992f73e2
# -*- 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
):
...
...
src/Products/PageTemplates/www/ptEdit.zpt
View file @
992f73e2
...
...
@@ -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>
...
...
src/Products/SiteAccess/www/manage_edit.dtml
View file @
992f73e2
...
...
@@ -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>
...
...
src/Testing/ZopeTestCase/testFunctional.py
View file @
992f73e2
...
...
@@ -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'
)
...
...
src/ZPublisher/BaseRequest.py
View file @
992f73e2
...
...
@@ -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
...
...
src/webdav/tests/testPUT_factory.py
View file @
992f73e2
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
),
))
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment