More Python 3.2 fixes - attachment encoding

This commit is contained in:
medmunds
2013-01-12 13:32:57 -08:00
parent b4f2866f0f
commit ac0614a633
2 changed files with 26 additions and 14 deletions

View File

@@ -206,14 +206,15 @@ class DjrillBackend(BaseEmailBackend):
def _add_attachments(self, message, msg_dict): def _add_attachments(self, message, msg_dict):
"""Extend msg_dict to include any attachments in message""" """Extend msg_dict to include any attachments in message"""
if message.attachments: if message.attachments:
str_encoding = message.encoding or settings.DEFAULT_CHARSET
attachments = [ attachments = [
self._make_mandrill_attachment(attachment) self._make_mandrill_attachment(attachment, str_encoding)
for attachment in message.attachments for attachment in message.attachments
] ]
if len(attachments) > 0: if len(attachments) > 0:
msg_dict['attachments'] = attachments msg_dict['attachments'] = attachments
def _make_mandrill_attachment(self, attachment): def _make_mandrill_attachment(self, attachment, str_encoding=None):
"""Return a Mandrill dict for an EmailMessage.attachments item""" """Return a Mandrill dict for an EmailMessage.attachments item"""
# Note that an attachment can be either a tuple of (filename, content, # Note that an attachment can be either a tuple of (filename, content,
# mimetype) or a MIMEBase object. (Also, both filename and mimetype may # mimetype) or a MIMEBase object. (Also, both filename and mimetype may
@@ -244,9 +245,19 @@ class DjrillBackend(BaseEmailBackend):
"text/*, image/*, and application/pdf attachments." "text/*, image/*, and application/pdf attachments."
% mimetype) % mimetype)
try:
content_b64 = b64encode(content)
except TypeError:
# Python 3 b64encode requires bytes. Convert str attachment:
if isinstance(content, str):
content_bytes = content.encode(str_encoding)
content_b64 = b64encode(content_bytes)
else:
raise
return { return {
'type': mimetype, 'type': mimetype,
'name': filename or "", 'name': filename or "",
'content': b64encode(content), 'content': content_b64.decode('ascii'),
} }

View File

@@ -1,4 +1,4 @@
from base64 import b64encode from base64 import b64decode
from email.mime.base import MIMEBase from email.mime.base import MIMEBase
from django.conf import settings from django.conf import settings
@@ -100,18 +100,18 @@ class DjrillBackendTests(DjrillBackendMockAPITestCase):
email = mail.EmailMessage('Subject', 'Body goes here', email = mail.EmailMessage('Subject', 'Body goes here',
'from@example.com', ['to1@example.com']) 'from@example.com', ['to1@example.com'])
content1 = "* Item one\n* Item two\n* Item three" text_content = "* Item one\n* Item two\n* Item three"
email.attach(filename="test.txt", content=content1, email.attach(filename="test.txt", content=text_content,
mimetype="text/plain") mimetype="text/plain")
# Should guess mimetype if not provided... # Should guess mimetype if not provided...
content2 = "PNG* pretend this is the contents of a png file" png_content = b"PNG\xb4 pretend this is the contents of a png file"
email.attach(filename="test.png", content=content2) email.attach(filename="test.png", content=png_content)
# Should work with a MIMEBase object (also tests no filename)... # Should work with a MIMEBase object (also tests no filename)...
content3 = "PDF* pretend this is valid pdf data" pdf_content = b"PDF\xb4 pretend this is valid pdf data"
mimeattachment = MIMEBase('application', 'pdf') mimeattachment = MIMEBase('application', 'pdf')
mimeattachment.set_payload(content3) mimeattachment.set_payload(pdf_content)
email.attach(mimeattachment) email.attach(mimeattachment)
email.send() email.send()
@@ -120,13 +120,14 @@ class DjrillBackendTests(DjrillBackendMockAPITestCase):
self.assertEqual(len(attachments), 3) self.assertEqual(len(attachments), 3)
self.assertEqual(attachments[0]["type"], "text/plain") self.assertEqual(attachments[0]["type"], "text/plain")
self.assertEqual(attachments[0]["name"], "test.txt") self.assertEqual(attachments[0]["name"], "test.txt")
self.assertEqual(attachments[0]["content"], b64encode(content1)) self.assertEqual(b64decode(attachments[0]["content"]).decode('ascii'),
text_content)
self.assertEqual(attachments[1]["type"], "image/png") # inferred self.assertEqual(attachments[1]["type"], "image/png") # inferred
self.assertEqual(attachments[1]["name"], "test.png") self.assertEqual(attachments[1]["name"], "test.png")
self.assertEqual(attachments[1]["content"], b64encode(content2)) self.assertEqual(b64decode(attachments[1]["content"]), png_content)
self.assertEqual(attachments[2]["type"], "application/pdf") self.assertEqual(attachments[2]["type"], "application/pdf")
self.assertEqual(attachments[2]["name"], "") # none self.assertEqual(attachments[2]["name"], "") # none
self.assertEqual(attachments[2]["content"], b64encode(content3)) self.assertEqual(b64decode(attachments[2]["content"]), pdf_content)
def test_extra_header_errors(self): def test_extra_header_errors(self):
email = mail.EmailMessage('Subject', 'Body', 'from@example.com', email = mail.EmailMessage('Subject', 'Body', 'from@example.com',