[Zope-Checkins] SVN: Zope/branches/2.12/ LP #642728: Fixed TypeError on nested multi part messages in MailHost. Thanks to Mail Derstappen for the patch!

Hanno Schlichting hannosch at hannosch.eu
Sat Sep 25 16:51:33 EDT 2010


Log message for revision 116939:
  LP #642728: Fixed TypeError on nested multi part messages in MailHost. Thanks to Mail Derstappen for the patch!
  

Changed:
  U   Zope/branches/2.12/doc/CHANGES.rst
  U   Zope/branches/2.12/src/Products/MailHost/MailHost.py
  U   Zope/branches/2.12/src/Products/MailHost/tests/testMailHost.py

-=-
Modified: Zope/branches/2.12/doc/CHANGES.rst
===================================================================
--- Zope/branches/2.12/doc/CHANGES.rst	2010-09-25 20:45:28 UTC (rev 116938)
+++ Zope/branches/2.12/doc/CHANGES.rst	2010-09-25 20:51:32 UTC (rev 116939)
@@ -11,6 +11,8 @@
 Bugs Fixed
 ++++++++++
 
+- LP #642728: Fixed TypeError on nested multi part messages in MailHost.
+
 Features Added
 ++++++++++++++
 

Modified: Zope/branches/2.12/src/Products/MailHost/MailHost.py
===================================================================
--- Zope/branches/2.12/src/Products/MailHost/MailHost.py	2010-09-25 20:45:28 UTC (rev 116938)
+++ Zope/branches/2.12/src/Products/MailHost/MailHost.py	2010-09-25 20:51:32 UTC (rev 116939)
@@ -420,32 +420,9 @@
         # we don't use get_content_type because that has a default
         # value of 'text/plain'
         mo.set_type(msg_type)
-    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
 
+    charset = _set_recursive_charset(mo, charset=charset)
+
     # Parameters given will *always* override headers in the messageText.
     # This is so that you can't override or add to subscribers by adding
     # them to # the message text.
@@ -492,6 +469,40 @@
 
     return mo.as_string(), mto, mfrom
 
+
+def _set_recursive_charset(payload, charset=None):
+    """Set charset for all parts of an multipart message."""
+    def _set_payload_charset(payload, charset=None, index=None):
+        payload_from_string = False
+        if not isinstance(payload, Message):
+            payload = message_from_string(payload)
+            payload_from_string = True
+        charset_match = CHARSET_RE.search(payload['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
+            if payload_from_string:
+                payload.get_payload()[index] = payload
+            else:
+                payload.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]
+        return charset
+    if payload.is_multipart():
+        for index, payload in enumerate(payload.get_payload()):
+            if payload.get_filename() is None:
+                if not payload.is_multipart():
+                    charset = _set_payload_charset(payload, charset=charset, index=index)
+                else:
+                    _set_recursive_charset(payload, charset=charset)
+    else:
+        charset = _set_payload_charset(payload, charset=charset)
+    return charset
+
+
 def _try_encode(text, charset):
     """Attempt to encode using the default charset if none is
     provided.  Should we permit encoding errors?"""

Modified: Zope/branches/2.12/src/Products/MailHost/tests/testMailHost.py
===================================================================
--- Zope/branches/2.12/src/Products/MailHost/tests/testMailHost.py	2010-09-25 20:45:28 UTC (rev 116938)
+++ Zope/branches/2.12/src/Products/MailHost/tests/testMailHost.py	2010-09-25 20:51:32 UTC (rev 116939)
@@ -541,12 +541,18 @@
 Content-Transfer-Encoding: quoted-printable
 
 This is plain text.
+
 --===============0490954888==
+Content-Type: multipart/related; boundary="===============2078950065=="
+MIME-Version: 1.0
+
+--===============2078950065==
 Content-Type: text/html; charset="utf-8"
 MIME-Version: 1.0
 Content-Transfer-Encoding: quoted-printable
 
 <p>This is html.</p>
+--===============2078950065==--
 --===============0490954888==--
 """)
 



More information about the Zope-Checkins mailing list