summaryrefslogtreecommitdiff
path: root/src/mailman/email
diff options
context:
space:
mode:
authorBarry Warsaw2014-12-22 13:40:30 -0500
committerBarry Warsaw2014-12-22 13:40:30 -0500
commit7d996dfa54e35053fb3518f29cd5368f88c085b8 (patch)
treeb4111954c2cd95578f92240686b8b23cd243a1a7 /src/mailman/email
parent10b4557d9b0de2cb0ce40032e5b633165d6b9139 (diff)
parent4173e7219271fa6ffc336c6a6d16b041cc62df12 (diff)
downloadmailman-7d996dfa54e35053fb3518f29cd5368f88c085b8.tar.gz
mailman-7d996dfa54e35053fb3518f29cd5368f88c085b8.tar.zst
mailman-7d996dfa54e35053fb3518f29cd5368f88c085b8.zip
Trunk merge.
Diffstat (limited to 'src/mailman/email')
-rw-r--r--src/mailman/email/message.py49
-rw-r--r--src/mailman/email/tests/test_message.py37
2 files changed, 50 insertions, 36 deletions
diff --git a/src/mailman/email/message.py b/src/mailman/email/message.py
index 92f5ff846..d77afcbe0 100644
--- a/src/mailman/email/message.py
+++ b/src/mailman/email/message.py
@@ -28,6 +28,7 @@ from __future__ import absolute_import, print_function, unicode_literals
__metaclass__ = type
__all__ = [
'Message',
+ 'MultipartDigestMessage',
'OwnerNotification',
'UserNotification',
]
@@ -38,6 +39,7 @@ import email.message
import email.utils
from email.header import Header
+from email.mime.multipart import MIMEMultipart
from mailman.config import config
@@ -53,29 +55,6 @@ class Message(email.message.Message):
self.__version__ = VERSION
email.message.Message.__init__(self)
- def __getitem__(self, key):
- # Ensure that header values are unicodes.
- value = email.message.Message.__getitem__(self, key)
- if isinstance(value, bytes):
- return value.decode('ascii')
- return value
-
- def get(self, name, failobj=None):
- # Ensure that header values are unicodes.
- value = email.message.Message.get(self, name, failobj)
- if isinstance(value, bytes):
- return value.decode('ascii')
- return value
-
- def get_all(self, name, failobj=None):
- # Ensure all header values are unicodes.
- missing = object()
- all_values = email.message.Message.get_all(self, name, missing)
- if all_values is missing:
- return failobj
- return [(value.decode('ascii') if isinstance(value, bytes) else value)
- for value in all_values]
-
# BAW: For debugging w/ bin/dumpdb. Apparently pprint uses repr.
def __repr__(self):
return self.__str__()
@@ -144,18 +123,20 @@ class Message(email.message.Message):
field_values = self.get_all(header, [])
senders.extend(address.lower() for (display_name, address)
in email.utils.getaddresses(field_values))
- # Filter out None and the empty string.
- return [sender for sender in senders if sender]
+ # Filter out None and the empty string, and convert to unicode.
+ clean_senders = []
+ for sender in senders:
+ if not sender:
+ continue
+ if isinstance(sender, bytes):
+ sender = sender.decode('ascii')
+ clean_senders.append(sender)
+ return clean_senders
- def get_filename(self, failobj=None):
- """Some MUA have bugs in RFC2231 filename encoding and cause
- Mailman to stop delivery in Scrubber.py (called from ToDigest.py).
- """
- try:
- filename = email.message.Message.get_filename(self, failobj)
- return filename
- except (UnicodeError, LookupError, ValueError):
- return failobj
+
+
+class MultipartDigestMessage(MIMEMultipart, Message):
+ """Mix-in class for MIME digest messages."""
diff --git a/src/mailman/email/tests/test_message.py b/src/mailman/email/tests/test_message.py
index e281c0d06..280a86477 100644
--- a/src/mailman/email/tests/test_message.py
+++ b/src/mailman/email/tests/test_message.py
@@ -22,13 +22,15 @@ from __future__ import absolute_import, print_function, unicode_literals
__metaclass__ = type
__all__ = [
'TestMessage',
+ 'TestMessageSubclass',
]
import unittest
+from email.parser import FeedParser
from mailman.app.lifecycle import create_list
-from mailman.email.message import UserNotification
+from mailman.email.message import Message, UserNotification
from mailman.testing.helpers import get_queue_messages
from mailman.testing.layers import ConfigLayer
@@ -56,5 +58,36 @@ class TestMessage(unittest.TestCase):
self._msg.send(self._mlist)
messages = get_queue_messages('virgin')
self.assertEqual(len(messages), 1)
- self.assertEqual(messages[0].msg.get_all('precedence'),
+ self.assertEqual(messages[0].msg.get_all('precedence'),
['omg wtf bbq'])
+
+
+
+class TestMessageSubclass(unittest.TestCase):
+ def test_i18n_filenames(self):
+ parser = FeedParser(_factory=Message)
+ parser.feed("""\
+Message-ID: <blah@example.com>
+Content-Type: multipart/mixed; boundary="------------050607040206050605060208"
+
+This is a multi-part message in MIME format.
+--------------050607040206050605060208
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: quoted-printable
+
+Test message containing an attachment with an accented filename
+
+--------------050607040206050605060208
+Content-Disposition: attachment;
+ filename*=UTF-8''d%C3%A9jeuner.txt
+
+Test content
+--------------050607040206050605060208--
+""")
+ msg = parser.close()
+ attachment = msg.get_payload(1)
+ try:
+ filename = attachment.get_filename()
+ except TypeError as e:
+ self.fail(e)
+ self.assertEqual(filename, u'd\xe9jeuner.txt')