From 4e0a0cca71bd21eed322e13ca8150d940aa13aa5 Mon Sep 17 00:00:00 2001 From: winhamwr Date: Wed, 23 Apr 2014 15:52:05 -0400 Subject: [PATCH 1/3] Added failing test showing that unicode attachments cause an error --- djrill/tests/test_mandrill_send.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/djrill/tests/test_mandrill_send.py b/djrill/tests/test_mandrill_send.py index 583d5b1..af88a0d 100644 --- a/djrill/tests/test_mandrill_send.py +++ b/djrill/tests/test_mandrill_send.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- + from base64 import b64decode from datetime import date, datetime, timedelta, tzinfo from email.mime.base import MIMEBase @@ -177,6 +179,24 @@ class DjrillBackendTests(DjrillBackendMockAPITestCase): # Make sure the image attachment is not treated as embedded: self.assertFalse('images' in data['message']) + def test_unicode_attachment_correctly_decoded(self): + unicode_attachment = [ + ('before_html.html', u'

\u2019

', 'text/html'), + ] + email = mail.EmailMessage( + subject='Subject', + body='Body goes here', + from_email='from@example.com', + to=['to1@example.com'], + attachments=unicode_attachment, + ) + + email.send() + data = self.get_api_call_data() + + attachments = data['message']['attachments'] + self.assertEqual(len(attachments), 1) + def test_embedded_images(self): image_data = self.sample_image_content() # Read from a png file image_cid = make_msgid("img") # Content ID per RFC 2045 section 7 (with <...>) From 70dc022f7709422081c9ba39276a6c06b0dea737 Mon Sep 17 00:00:00 2001 From: winhamwr Date: Wed, 23 Apr 2014 16:59:48 -0400 Subject: [PATCH 2/3] Handle unicode attachment content in both python 2.X and python3. --- djrill/mail/backends/djrill.py | 17 ++++++++++------- djrill/tests/test_mandrill_send.py | 11 +++++------ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/djrill/mail/backends/djrill.py b/djrill/mail/backends/djrill.py index 18ee6a8..6ddc7ce 100644 --- a/djrill/mail/backends/djrill.py +++ b/djrill/mail/backends/djrill.py @@ -294,15 +294,18 @@ class DjrillBackend(BaseEmailBackend): if mimetype is None: mimetype = DEFAULT_ATTACHMENT_MIME_TYPE + # b64encode requires bytes, so let's convert our content. try: - content_b64 = b64encode(content) - except TypeError: - # Python 3 b64encode requires bytes. Convert str attachment: + if isinstance(content, unicode): + # Python 2.X unicode string + content = content.encode(str_encoding) + except NameError: + # Python 3 doesn't differentiate between strings and unicode + # Convert python3 unicode str to bytes attachment: if isinstance(content, str): - content_bytes = content.encode(str_encoding) - content_b64 = b64encode(content_bytes) - else: - raise + content = content.encode(str_encoding) + + content_b64 = b64encode(content) mandrill_attachment = { 'type': mimetype, diff --git a/djrill/tests/test_mandrill_send.py b/djrill/tests/test_mandrill_send.py index af88a0d..772844c 100644 --- a/djrill/tests/test_mandrill_send.py +++ b/djrill/tests/test_mandrill_send.py @@ -180,18 +180,17 @@ class DjrillBackendTests(DjrillBackendMockAPITestCase): self.assertFalse('images' in data['message']) def test_unicode_attachment_correctly_decoded(self): - unicode_attachment = [ - ('before_html.html', u'

\u2019

', 'text/html'), - ] - email = mail.EmailMessage( + msg = mail.EmailMessage( subject='Subject', body='Body goes here', from_email='from@example.com', to=['to1@example.com'], - attachments=unicode_attachment, ) + # Slight modification from the Django unicode docs: + # http://django.readthedocs.org/en/latest/ref/unicode.html#email + msg.attach("Une pièce jointe.html", u'

\u2019

', mimetype='text/html') - email.send() + msg.send() data = self.get_api_call_data() attachments = data['message']['attachments'] From f2a08894fa5d05f4e292d2c45ab7d803d5ad9307 Mon Sep 17 00:00:00 2001 From: winhamwr Date: Wed, 23 Apr 2014 18:37:46 -0400 Subject: [PATCH 3/3] Fixed python 3.2 compatibility. --- djrill/tests/test_mandrill_send.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/djrill/tests/test_mandrill_send.py b/djrill/tests/test_mandrill_send.py index 772844c..403584a 100644 --- a/djrill/tests/test_mandrill_send.py +++ b/djrill/tests/test_mandrill_send.py @@ -1,5 +1,7 @@ # -*- coding: utf-8 -*- +from __future__ import unicode_literals + from base64 import b64decode from datetime import date, datetime, timedelta, tzinfo from email.mime.base import MIMEBase @@ -188,7 +190,7 @@ class DjrillBackendTests(DjrillBackendMockAPITestCase): ) # Slight modification from the Django unicode docs: # http://django.readthedocs.org/en/latest/ref/unicode.html#email - msg.attach("Une pièce jointe.html", u'

\u2019

', mimetype='text/html') + msg.attach("Une pièce jointe.html", '

\u2019

', mimetype='text/html') msg.send() data = self.get_api_call_data()