[Zope-Checkins] SVN: Zope/trunk/src/Products/MailHost/ Products.MailHost: merged r107689 from branches/2.12:

2010-01-05 Thread Maurits van Rees
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

2010-01-05 Thread Leonardo Rochael Almeida
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

2010-01-05 Thread Leonardo Rochael Almeida
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(