Commit 4c8901e8 authored by Andreas Jung's avatar Andreas Jung

- smarter upload

- enforcing UTF-8 in the ZMI
- enforcing unicode as internal  representation
- added some assertions to check for unicode
parent c95e8411
...@@ -20,6 +20,7 @@ from urllib import quote ...@@ -20,6 +20,7 @@ from urllib import quote
import os, AccessControl, Acquisition import os, AccessControl, Acquisition
from Globals import ImageFile, package_home, InitializeClass from Globals import ImageFile, package_home, InitializeClass
from OFS.SimpleItem import SimpleItem from OFS.SimpleItem import SimpleItem
from OFS.content_types import guess_content_type
from DateTime.DateTime import DateTime from DateTime.DateTime import DateTime
from Shared.DC.Scripts.Script import Script from Shared.DC.Scripts.Script import Script
from Shared.DC.Scripts.Signature import FuncCode from Shared.DC.Scripts.Signature import FuncCode
...@@ -63,6 +64,7 @@ class ZPT(Script, PageTemplate, Historical, Cacheable, ...@@ -63,6 +64,7 @@ class ZPT(Script, PageTemplate, Historical, Cacheable,
__implements__ = (WriteLockInterface,) __implements__ = (WriteLockInterface,)
meta_type = 'ZPT' meta_type = 'ZPT'
management_page_charset = 'utf-8'
func_defaults = None func_defaults = None
func_code = FuncCode((), 0) func_code = FuncCode((), 0)
...@@ -90,12 +92,12 @@ class ZPT(Script, PageTemplate, Historical, Cacheable, ...@@ -90,12 +92,12 @@ class ZPT(Script, PageTemplate, Historical, Cacheable,
security.declareObjectProtected(view) security.declareObjectProtected(view)
security.declareProtected(view, '__call__') security.declareProtected(view, '__call__')
def __init__(self, id, text=None, content_type=None): def __init__(self, id, text=None, content_type=None, encoding='utf-8'):
self.id = str(id) self.id = str(id)
self.ZBindings_edit(self._default_bindings) self.ZBindings_edit(self._default_bindings)
if text is None: if text is None:
text = open(self._default_content_fn).read() text = open(self._default_content_fn).read()
self.pt_edit(text, content_type) self.pt_edit(text, content_type, encoding)
def _setPropValue(self, id, value): def _setPropValue(self, id, value):
PropertyManager._setPropValue(self, id, value) PropertyManager._setPropValue(self, id, value)
...@@ -104,7 +106,11 @@ class ZPT(Script, PageTemplate, Historical, Cacheable, ...@@ -104,7 +106,11 @@ class ZPT(Script, PageTemplate, Historical, Cacheable,
security.declareProtected(change_page_templates, 'pt_edit') security.declareProtected(change_page_templates, 'pt_edit')
def pt_edit(self, text, content_type): def pt_edit(self, text, content_type, encoding='utf-8'):
if not isinstance(text, unicode):
text = unicode(text, encoding, 'strict')
assert isinstance(text, unicode)
self.ZCacheable_invalidate()
PageTemplate.pt_edit(self, text, content_type) PageTemplate.pt_edit(self, text, content_type)
security.declareProtected(change_page_templates, 'pt_editAction') security.declareProtected(change_page_templates, 'pt_editAction')
...@@ -143,16 +149,22 @@ class ZPT(Script, PageTemplate, Historical, Cacheable, ...@@ -143,16 +149,22 @@ class ZPT(Script, PageTemplate, Historical, Cacheable,
if self.wl_isLocked(): if self.wl_isLocked():
raise ResourceLockedError("File is locked via WebDAV") raise ResourceLockedError("File is locked via WebDAV")
filename = None
if not isinstance(file, str): if not isinstance(file, str):
if not file: raise ValueError('File not specified') if not file: raise ValueError('File not specified')
filename = file.filename
file = file.read() file = file.read()
if charset:
try: ct, dummy = guess_content_type(filename, file)
unicode(file, 'us-ascii') if not ct in ('text/html', 'text/xml'):
file = str(file) raise ValueError('Unsupported mimetype: %s' % ct)
except UnicodeDecodeError:
file = unicode(file, charset) if not isinstance(file, unicode):
self.write(file) if not charset:
raise ValueError('No encoding specified for non-unicode content')
file = unicode(file, charset)
self.pt_edit(file, ct)
message = 'Saved changes.' message = 'Saved changes.'
return self.pt_editForm(manage_tabs_message=message) return self.pt_editForm(manage_tabs_message=message)
...@@ -205,10 +217,9 @@ class ZPT(Script, PageTemplate, Historical, Cacheable, ...@@ -205,10 +217,9 @@ class ZPT(Script, PageTemplate, Historical, Cacheable,
} }
return c return c
security.declareProtected(change_page_templates, 'write') # security.declareProtected(change_page_templates, 'write')
def write(self, text): # def write(self, text):
self.ZCacheable_invalidate() # PageTemplate.write(self, text)
PageTemplate.write(self, text)
security.declareProtected(view_management_screens, 'manage_main', 'read', security.declareProtected(view_management_screens, 'manage_main', 'read',
'ZScriptHTML_tryForm') 'ZScriptHTML_tryForm')
...@@ -248,6 +259,7 @@ class ZPT(Script, PageTemplate, Historical, Cacheable, ...@@ -248,6 +259,7 @@ class ZPT(Script, PageTemplate, Historical, Cacheable,
try: try:
# XXX: check the parameters for pt_render()! (aj) # XXX: check the parameters for pt_render()! (aj)
result = self.pt_render(self.pt_getContext()) result = self.pt_render(self.pt_getContext())
assert isinstance(result, unicode)
# result = self.pt_render(extra_context=bound_names) # result = self.pt_render(extra_context=bound_names)
if keyset is not None: if keyset is not None:
...@@ -266,7 +278,8 @@ class ZPT(Script, PageTemplate, Historical, Cacheable, ...@@ -266,7 +278,8 @@ class ZPT(Script, PageTemplate, Historical, Cacheable,
""" Handle HTTP PUT requests """ """ Handle HTTP PUT requests """
self.dav__init(REQUEST, RESPONSE) self.dav__init(REQUEST, RESPONSE)
self.dav__simpleifhandler(REQUEST, RESPONSE, refresh=1) self.dav__simpleifhandler(REQUEST, RESPONSE, refresh=1)
self.write(REQUEST.get('BODY', '')) ## XXX:this should be unicode or we must pass an encoding
self.pt_edit(REQUEST.get('BODY', ''))
RESPONSE.setStatus(204) RESPONSE.setStatus(204)
return RESPONSE return RESPONSE
...@@ -281,7 +294,7 @@ class ZPT(Script, PageTemplate, Historical, Cacheable, ...@@ -281,7 +294,7 @@ class ZPT(Script, PageTemplate, Historical, Cacheable,
self.REQUEST.RESPONSE.setHeader('Content-Type', self.content_type) self.REQUEST.RESPONSE.setHeader('Content-Type', self.content_type)
return self.read() return self.read()
security.declareProtected(view_manage_screens, 'html') security.declareProtected(view_management_screens, 'html')
def html(self): def html(self):
return self.content_type == 'text/html' return self.content_type == 'text/html'
......
...@@ -123,15 +123,14 @@ to view or download the current text. ...@@ -123,15 +123,14 @@ to view or download the current text.
<input type="file" name="file" size="25" value=""> <input type="file" name="file" size="25" value="">
</td> </td>
</tr> </tr>
<tr tal:condition="context/management_page_charset|nothing"> <tr>
<td align="left" valign="top"> <td align="left" valign="top">
<div class="form-label"> <div class="form-label">
Encoding &nbsp; Encoding &nbsp;
</div> </div>
</td> </td>
<td align="left" valign="top"> <td align="left" valign="top">
<input name="charset" value="" <input name="charset" value="utf-8"/>
tal:attributes="value context/management_page_charset|default" />
</td> </td>
</tr> </tr>
<tr> <tr>
......
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