[Zope-Checkins] SVN: Zope/trunk/src/Products/MailHost/ Products.MailHost: merged r107689 from branches/2.12:
Log message for revision 107723: Products.MailHost: merged r107689 from branches/2.12: Fixed possible TypeError while sending multipart emails. (Zope 2.11 and 2.10 are not affected.) Changed: U Zope/trunk/src/Products/MailHost/MailHost.py U Zope/trunk/src/Products/MailHost/tests/testMailHost.py -=- Modified: Zope/trunk/src/Products/MailHost/MailHost.py === --- Zope/trunk/src/Products/MailHost/MailHost.py2010-01-05 22:13:36 UTC (rev 107722) +++ Zope/trunk/src/Products/MailHost/MailHost.py2010-01-05 22:25:18 UTC (rev 107723) @@ -417,16 +417,31 @@ # we don't use get_content_type because that has a default # value of 'text/plain' mo.set_type(msg_type) -charset_match = CHARSET_RE.search(mo['Content-Type'] or '') -if charset and not charset_match: -# Don't change the charset if already set -# This encodes the payload automatically based on the default -# encoding for the charset -mo.set_charset(charset) -elif charset_match and not charset: -# If a charset parameter was provided use it for header encoding below, -# Otherwise, try to use the charset provided in the message. -charset = charset_match.groups()[0] +if not mo.is_multipart(): +charset_match = CHARSET_RE.search(mo['Content-Type'] or '') +if charset and not charset_match: +# Don't change the charset if already set +# This encodes the payload automatically based on the default +# encoding for the charset +mo.set_charset(charset) +elif charset_match and not charset: +# If a charset parameter was provided use it for header encoding below, +# Otherwise, try to use the charset provided in the message. +charset = charset_match.groups()[0] +else: +# Do basically the same for each payload as for the complete +# multipart message. +for index, payload in enumerate(mo.get_payload()): +if not isinstance(payload, Message): +payload = message_from_string(payload) +charset_match = CHARSET_RE.search(payload['Content-Type'] or '') +if payload.get_filename() is None: +# No binary file +if charset and not charset_match: +payload.set_charset(charset) +elif charset_match and not charset: +charset = charset_match.groups()[0] +mo.get_payload()[index] = payload # Parameters given will *always* override headers in the messageText. # This is so that you can't override or add to subscribers by adding Modified: Zope/trunk/src/Products/MailHost/tests/testMailHost.py === --- Zope/trunk/src/Products/MailHost/tests/testMailHost.py 2010-01-05 22:13:36 UTC (rev 107722) +++ Zope/trunk/src/Products/MailHost/tests/testMailHost.py 2010-01-05 22:25:18 UTC (rev 107723) @@ -518,7 +518,93 @@ statusTemplate='check_status') self.failUnlessEqual(result, 'Message Sent') +def testSendMultiPartAlternativeMessage(self): +msg = ("""\ +Content-Type: multipart/alternative; boundary="===0490954888==" +MIME-Version: 1.0 +Date: Sun, 27 Aug 2006 17:00:00 +0200 +Subject: My multipart email +To: Foo Bar +From: sen...@domain.com +--===0490954888== +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: quoted-printable + +This is plain text. +--===0490954888== +Content-Type: text/html; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: quoted-printable + +This is html. +--===0490954888==-- +""") + +mailhost = self._makeOne('MailHost') +# Specifying a charset for the header may have unwanted side +# effects in the case of multipart mails. +# (TypeError: expected string or buffer) +mailhost.send(msg, charset='utf-8') +self.assertEqual(mailhost.sent, msg) + +def testSendMultiPartMixedMessage(self): +msg = ("""\ +Content-Type: multipart/mixed; boundary="XOIedfhf+7KOe/yw" +Content-Disposition: inline +MIME-Version: 1.0 +Date: Sun, 27 Aug 2006 17:00:00 +0200 +Subject: My multipart email +To: Foo Bar +From: sen...@domain.com + +--XOIedfhf+7KOe/yw +Content-Type: text/plain; charset=us-ascii +Content-Disposition: inline + +This is a test with as attachment OFS/www/new.gif. + +--XOIedfhf+7KOe/yw +Content-Type: image/gif +Content-Disposition: attachment; filename="new.gif" +Content-Transfer-Encoding: base64 + +R0lGODlhCwAQAPcAAP8A/wAAAFBQUICAgMDAwP8AAIAAQAAAoABAgIAAgEAAQP//AP//gACA +gECAgP///wAA + +AAA
[Zope-Checkins] SVN: Zope/branches/2.12/ LP #246983: Unicode conflict resolution on variables inside 'string:' expressions
Log message for revision 107725: LP #246983: Unicode conflict resolution on variables inside 'string:' expressions Changed: U Zope/branches/2.12/doc/CHANGES.rst U Zope/branches/2.12/src/Products/Five/browser/tests/test_pagetemplatefile.py U Zope/branches/2.12/src/Products/PageTemplates/Expressions.py U Zope/branches/2.12/src/Products/PageTemplates/tests/testExpressions.py U Zope/branches/2.12/src/Products/PageTemplates/tests/testZopePageTemplate.py -=- Modified: Zope/branches/2.12/doc/CHANGES.rst === --- Zope/branches/2.12/doc/CHANGES.rst 2010-01-05 22:37:00 UTC (rev 107724) +++ Zope/branches/2.12/doc/CHANGES.rst 2010-01-06 01:31:21 UTC (rev 107725) @@ -11,6 +11,9 @@ Bugs Fixed ++ +- LP #246983: Enabled unicode conflict resolution on variables inside "string:" + expressions in TALES. + - Fixed possible TypeError while sending multipart emails. - Also look for ZEXP imports within the clienthome directory. This Modified: Zope/branches/2.12/src/Products/Five/browser/tests/test_pagetemplatefile.py === --- Zope/branches/2.12/src/Products/Five/browser/tests/test_pagetemplatefile.py 2010-01-05 22:37:00 UTC (rev 107724) +++ Zope/branches/2.12/src/Products/Five/browser/tests/test_pagetemplatefile.py 2010-01-06 01:31:21 UTC (rev 107725) @@ -37,13 +37,13 @@ from zope.tales.expressions import DeferExpr from zope.tales.expressions import NotExpr from zope.tales.expressions import PathExpr -from zope.tales.expressions import StringExpr from zope.tales.expressions import Undefs from zope.tales.pythonexpr import PythonExpr from zope.contentprovider.tales import TALESProviderExpression from Products.PageTemplates.DeferExpr import LazyExpr from Products.PageTemplates.Expressions import TrustedZopePathExpr from Products.PageTemplates.Expressions import SecureModuleImporter +from Products.PageTemplates.Expressions import UnicodeAwareStringExpr vptf = self._makeOne('seagull.pt') engine = vptf.pt_getEngine() @@ -51,7 +51,7 @@ self.assertEqual(engine.types['path'], TrustedZopePathExpr) self.assertEqual(engine.types['exists'], TrustedZopePathExpr) self.assertEqual(engine.types['nocall'], TrustedZopePathExpr) -self.assertEqual(engine.types['string'], StringExpr) +self.assertEqual(engine.types['string'], UnicodeAwareStringExpr) self.assertEqual(engine.types['python'], PythonExpr) self.assertEqual(engine.types['not'], NotExpr) self.assertEqual(engine.types['defer'], DeferExpr) Modified: Zope/branches/2.12/src/Products/PageTemplates/Expressions.py === --- Zope/branches/2.12/src/Products/PageTemplates/Expressions.py 2010-01-05 22:37:00 UTC (rev 107724) +++ Zope/branches/2.12/src/Products/PageTemplates/Expressions.py 2010-01-06 01:31:21 UTC (rev 107725) @@ -372,12 +372,26 @@ return False return ob1 == ob2 +class UnicodeAwareStringExpr(StringExpr): + +def __call__(self, econtext): +vvals = [] +if isinstance(self._expr, unicode): +# coerce values through the Unicode Conflict Resolver +evaluate = econtext.evaluateText +else: +evaluate = econtext.evaluate +for var in self._vars: +v = evaluate(var) +vvals.append(v) +return self._expr % tuple(vvals) + def createZopeEngine(zpe=ZopePathExpr): e = ZopeEngine() e.iteratorFactory = PathIterator for pt in zpe._default_type_names: e.registerType(pt, zpe) -e.registerType('string', StringExpr) +e.registerType('string', UnicodeAwareStringExpr) e.registerType('python', ZRPythonExpr.PythonExpr) e.registerType('not', NotExpr) e.registerType('defer', DeferExpr) Modified: Zope/branches/2.12/src/Products/PageTemplates/tests/testExpressions.py === --- Zope/branches/2.12/src/Products/PageTemplates/tests/testExpressions.py 2010-01-05 22:37:00 UTC (rev 107724) +++ Zope/branches/2.12/src/Products/PageTemplates/tests/testExpressions.py 2010-01-06 01:31:21 UTC (rev 107725) @@ -25,12 +25,20 @@ __allow_access_to_unprotected_subobjects__ = 1 def __call__(self): return 'dummy' + +management_page_charset = 'iso-8859-15' class DummyDocumentTemplate: __allow_access_to_unprotected_subobjects__ = 1 isDocTemp = True def __call__(self, client=None, REQUEST={}, RESPONSE=None, **kw): return 'dummy' + +def absolute_url(self, relative=0): +url = 'dummy' +if
[Zope-Checkins] SVN: Zope/trunk/ merge 107725 from 2.12: fix for LP #246983
Log message for revision 107726: merge 107725 from 2.12: fix for LP #246983 Changed: U Zope/trunk/doc/CHANGES.rst U Zope/trunk/src/Products/Five/browser/tests/test_pagetemplatefile.py U Zope/trunk/src/Products/PageTemplates/Expressions.py U Zope/trunk/src/Products/PageTemplates/tests/testExpressions.py U Zope/trunk/src/Products/PageTemplates/tests/testZopePageTemplate.py -=- Modified: Zope/trunk/doc/CHANGES.rst === --- Zope/trunk/doc/CHANGES.rst 2010-01-06 01:31:21 UTC (rev 107725) +++ Zope/trunk/doc/CHANGES.rst 2010-01-06 01:50:37 UTC (rev 107726) @@ -125,6 +125,9 @@ Bugs Fixed ++ +- LP #246983: Enabled unicode conflict resolution on variables inside "string:" + expressions in TALES. + - Also look for ZEXP imports within the clienthome directory. This provides a place to put imports that won't be clobbered by buildout in a buildout-based Zope instance. Modified: Zope/trunk/src/Products/Five/browser/tests/test_pagetemplatefile.py === --- Zope/trunk/src/Products/Five/browser/tests/test_pagetemplatefile.py 2010-01-06 01:31:21 UTC (rev 107725) +++ Zope/trunk/src/Products/Five/browser/tests/test_pagetemplatefile.py 2010-01-06 01:50:37 UTC (rev 107726) @@ -37,13 +37,13 @@ from zope.tales.expressions import DeferExpr from zope.tales.expressions import NotExpr from zope.tales.expressions import PathExpr -from zope.tales.expressions import StringExpr from zope.tales.expressions import Undefs from zope.tales.pythonexpr import PythonExpr from zope.contentprovider.tales import TALESProviderExpression from Products.PageTemplates.DeferExpr import LazyExpr from Products.PageTemplates.Expressions import TrustedZopePathExpr from Products.PageTemplates.Expressions import SecureModuleImporter +from Products.PageTemplates.Expressions import UnicodeAwareStringExpr vptf = self._makeOne('seagull.pt') engine = vptf.pt_getEngine() @@ -51,7 +51,7 @@ self.assertEqual(engine.types['path'], TrustedZopePathExpr) self.assertEqual(engine.types['exists'], TrustedZopePathExpr) self.assertEqual(engine.types['nocall'], TrustedZopePathExpr) -self.assertEqual(engine.types['string'], StringExpr) +self.assertEqual(engine.types['string'], UnicodeAwareStringExpr) self.assertEqual(engine.types['python'], PythonExpr) self.assertEqual(engine.types['not'], NotExpr) self.assertEqual(engine.types['defer'], DeferExpr) Modified: Zope/trunk/src/Products/PageTemplates/Expressions.py === --- Zope/trunk/src/Products/PageTemplates/Expressions.py2010-01-06 01:31:21 UTC (rev 107725) +++ Zope/trunk/src/Products/PageTemplates/Expressions.py2010-01-06 01:50:37 UTC (rev 107726) @@ -372,12 +372,26 @@ return False return ob1 == ob2 +class UnicodeAwareStringExpr(StringExpr): + +def __call__(self, econtext): +vvals = [] +if isinstance(self._expr, unicode): +# coerce values through the Unicode Conflict Resolver +evaluate = econtext.evaluateText +else: +evaluate = econtext.evaluate +for var in self._vars: +v = evaluate(var) +vvals.append(v) +return self._expr % tuple(vvals) + def createZopeEngine(zpe=ZopePathExpr): e = ZopeEngine() e.iteratorFactory = PathIterator for pt in zpe._default_type_names: e.registerType(pt, zpe) -e.registerType('string', StringExpr) +e.registerType('string', UnicodeAwareStringExpr) e.registerType('python', ZRPythonExpr.PythonExpr) e.registerType('not', NotExpr) e.registerType('defer', DeferExpr) Modified: Zope/trunk/src/Products/PageTemplates/tests/testExpressions.py === --- Zope/trunk/src/Products/PageTemplates/tests/testExpressions.py 2010-01-06 01:31:21 UTC (rev 107725) +++ Zope/trunk/src/Products/PageTemplates/tests/testExpressions.py 2010-01-06 01:50:37 UTC (rev 107726) @@ -25,12 +25,20 @@ __allow_access_to_unprotected_subobjects__ = 1 def __call__(self): return 'dummy' + +management_page_charset = 'iso-8859-15' class DummyDocumentTemplate: __allow_access_to_unprotected_subobjects__ = 1 isDocTemp = True def __call__(self, client=None, REQUEST={}, RESPONSE=None, **kw): return 'dummy' + +def absolute_url(self, relative=0): +url = 'dummy' +if not relative: +url = "http://server/"; + url +return url _DEFAULT_BINDINGS = dict(