Commit 0d97cea7 authored by Andreas Jung's avatar Andreas Jung

merged UnicodeEncodingConflictResolver

parents 42562716 c940b163
...@@ -17,6 +17,10 @@ for Python expressions, string literals, and paths. ...@@ -17,6 +17,10 @@ for Python expressions, string literals, and paths.
$Id$ $Id$
""" """
import logging
from zope.component import getUtility
from zope.interface import implements from zope.interface import implements
from zope.tales.tales import Context, Iterator from zope.tales.tales import Context, Iterator
from zope.tales.expressions import PathExpr, StringExpr, NotExpr from zope.tales.expressions import PathExpr, StringExpr, NotExpr
...@@ -31,13 +35,17 @@ import OFS.interfaces ...@@ -31,13 +35,17 @@ import OFS.interfaces
from MultiMapping import MultiMapping from MultiMapping import MultiMapping
from Acquisition import aq_base from Acquisition import aq_base
from zExceptions import NotFound, Unauthorized from zExceptions import NotFound, Unauthorized
from Products.Five.browser.providerexpression import Z2ProviderExpression from Products.Five.browser.providerexpression import Z2ProviderExpression
from Products.PageTemplates import ZRPythonExpr from Products.PageTemplates import ZRPythonExpr
from Products.PageTemplates.DeferExpr import LazyExpr from Products.PageTemplates.DeferExpr import LazyExpr
from Products.PageTemplates.GlobalTranslationService import getGlobalTranslationService from Products.PageTemplates.GlobalTranslationService import getGlobalTranslationService
from Products.PageTemplates.interfaces import IUnicodeEncodingConflictResolver
SecureModuleImporter = ZRPythonExpr._SecureModuleImporter() SecureModuleImporter = ZRPythonExpr._SecureModuleImporter()
LOG = logging.getLogger('Expressions')
# BBB 2005/05/01 -- remove after 12 months # BBB 2005/05/01 -- remove after 12 months
import zope.deprecation import zope.deprecation
from zope.deprecation import deprecate from zope.deprecation import deprecate
...@@ -173,6 +181,44 @@ class ZopeContext(Context): ...@@ -173,6 +181,44 @@ class ZopeContext(Context):
domain, msgid, mapping=mapping, domain, msgid, mapping=mapping,
context=context, default=default) context=context, default=default)
def evaluateText(self, expr):
""" customized version in order to get rid of unicode
errors for all and ever
"""
text = self.evaluate(expr)
if text is self.getDefault() or text is None:
# XXX: should be unicode???
return text
if isinstance(text, unicode):
# we love unicode, nothing to do
return text
elif isinstance(text, str):
# bahh...non-unicode string..we need to convert it to unicode
resolver = getUtility(IUnicodeEncodingConflictResolver)
try:
return resolver.resolve(self.contexts['context'], text, expr)
except UnicodeDecodeError,e:
LOG.error("""UnicodeDecodeError detected for expression "%s"\n"""
"""Resolver class: %s\n"""
"""Exception text: %s\n"""
"""Template: %s\n"""
"""Rendered text: %r""" % \
(expr, resolver.__class__, e,
self.contexts['template'].absolute_url(1), text))
raise
else:
# This is a weird culprit ...calling unicode() on non-string
# objects
return unicode(text)
class ZopeEngine(zope.app.pagetemplate.engine.ZopeEngine): class ZopeEngine(zope.app.pagetemplate.engine.ZopeEngine):
_create_context = ZopeContext _create_context = ZopeContext
......
...@@ -40,7 +40,8 @@ from Products.PageTemplates.PageTemplateFile import PageTemplateFile ...@@ -40,7 +40,8 @@ from Products.PageTemplates.PageTemplateFile import PageTemplateFile
from Products.PageTemplates.PageTemplateFile import guess_type from Products.PageTemplates.PageTemplateFile import guess_type
from Products.PageTemplates.Expressions import SecureModuleImporter from Products.PageTemplates.Expressions import SecureModuleImporter
from Products.PageTemplates.utils import encodingFromXMLPreamble, charsetFromMetaEquiv, convertToUnicode from Products.PageTemplates.utils import encodingFromXMLPreamble, \
charsetFromMetaEquiv, convertToUnicode
preferred_encodings = ['utf-8', 'iso-8859-15'] preferred_encodings = ['utf-8', 'iso-8859-15']
...@@ -103,7 +104,8 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable, ...@@ -103,7 +104,8 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable,
security.declareProtected(view_management_screens, security.declareProtected(view_management_screens,
'read', 'ZScriptHTML_tryForm') 'read', 'ZScriptHTML_tryForm')
def __init__(self, id, text=None, content_type='text/html', strict=True, output_encoding='utf-8'): def __init__(self, id, text=None, content_type='text/html', strict=True,
output_encoding='utf-8'):
self.id = id self.id = id
self.expand = 0 self.expand = 0
self.ZBindings_edit(self._default_bindings) self.ZBindings_edit(self._default_bindings)
...@@ -139,16 +141,13 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable, ...@@ -139,16 +141,13 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable,
charset = charsetFromMetaEquiv(text) charset = charsetFromMetaEquiv(text)
if is_unicode: if is_unicode:
if charset: if charset:
encoding = None encoding = None
output_encoding = charset output_encoding = charset
else: else:
encoding = None encoding = None
output_encoding = 'iso-8859-15' output_encoding = 'iso-8859-15'
else: else:
if charset: if charset:
encoding = charset encoding = charset
output_encoding = charset output_encoding = charset
...@@ -287,7 +286,9 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable, ...@@ -287,7 +286,9 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable,
def write(self, text): def write(self, text):
if not isinstance(text, unicode): if not isinstance(text, unicode):
text, encoding = convertToUnicode(text, self.content_type, preferred_encodings) text, encoding = convertToUnicode(text,
self.content_type,
preferred_encodings)
self.output_encoding = encoding self.output_encoding = encoding
self.ZCacheable_invalidate() self.ZCacheable_invalidate()
......
<configure xmlns="http://namespaces.zope.org/zope">
<utility
provides="Products.PageTemplates.interfaces.IUnicodeEncodingConflictResolver"
component="Products.PageTemplates.unicodeconflictresolver.DefaultUnicodeEncodingConflictResolver"
/>
</configure>
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
from zope.interface import Interface
class IUnicodeEncodingConflictResolver(Interface):
""" A utility that tries to convert a non-unicode string into
a Python unicode by implementing some policy in order
to figure out a possible encoding - either through the
calling context, the location or the system environment
"""
def resolve(context, text, expression):
""" Returns 'text' as unicode string.
'context' is the current context object.
'expression' is the original expression (can be used for
logging purposes)
"""
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
import sys
from zope.interface import implements
from Products.PageTemplates.interfaces import IUnicodeEncodingConflictResolver
default_encoding = sys.getdefaultencoding()
class DefaultUnicodeEncodingConflictResolver:
""" This resolver implements the old-style behavior and will
raise an exception in case of the string 'text' can't be converted
propertly to unicode.
"""
implements(IUnicodeEncodingConflictResolver)
def resolve(self, context, text, expression):
return unicode(text)
DefaultUnicodeEncodingConflictResolver = DefaultUnicodeEncodingConflictResolver()
class Z2UnicodeEncodingConflictResolver:
""" This resolver tries to lookup the encoding from the
'management_page_charset' property and defaults to
sys.getdefaultencoding().
"""
implements(IUnicodeEncodingConflictResolver)
def __init__(self, mode='strict'):
self.mode = mode
def resolve(self, context, text, expression):
try:
return unicode(text)
except UnicodeDecodeError:
encoding = getattr(context, 'managment_page_charset', default_encoding)
return unicode(text, encoding, self.mode)
StrictUnicodeEncodingConflictResolver = Z2UnicodeEncodingConflictResolver('strict')
ReplacingUnicodeEncodingConflictResolver = Z2UnicodeEncodingConflictResolver('replace')
IgnoringUnicodeEncodingConflictResolver = Z2UnicodeEncodingConflictResolver('ignore')
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