Skip to content

Commit c680b1e

Browse files
author
Nikolay Blokhin
committed
Add support for attachments (tuples and MIMEBase instances)
1 parent 94cacfe commit c680b1e

File tree

3 files changed

+60
-1
lines changed

3 files changed

+60
-1
lines changed

djcelery_email/utils.py

+21-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import copy
2+
import base64
3+
from email.mime.base import MIMEBase
24

35
from django.conf import settings
46
from django.core.mail import EmailMultiAlternatives, EmailMessage
@@ -31,7 +33,7 @@ def email_to_dict(message):
3133
'to': message.to,
3234
'bcc': message.bcc,
3335
# ignore connection
34-
'attachments': message.attachments,
36+
'attachments': [],
3537
'headers': message.extra_headers,
3638
'cc': message.cc}
3739

@@ -47,6 +49,17 @@ def email_to_dict(message):
4749
if message.mixed_subtype != EmailMessage.mixed_subtype:
4850
message_dict["mixed_subtype"] = message.mixed_subtype
4951

52+
attachments = message.attachments
53+
for attachment in attachments:
54+
if isinstance(attachment, MIMEBase):
55+
filename = attachment.get_filename('')
56+
binary_contents = attachment.get_payload(decode=True)
57+
mimetype = attachment.get_content_type()
58+
else:
59+
filename, binary_contents, mimetype = attachment
60+
contents = base64.b64encode(binary_contents).decode('ascii')
61+
message_dict['attachments'].append((filename, contents, mimetype))
62+
5063
if settings.CELERY_EMAIL_MESSAGE_EXTRA_ATTRIBUTES:
5164
for attr in settings.CELERY_EMAIL_MESSAGE_EXTRA_ATTRIBUTES:
5265
if hasattr(message, attr):
@@ -62,6 +75,13 @@ def dict_to_email(messagedict):
6275
for attr in settings.CELERY_EMAIL_MESSAGE_EXTRA_ATTRIBUTES:
6376
if attr in messagedict:
6477
extra_attrs[attr] = messagedict.pop(attr)
78+
attachments = messagedict.pop('attachments')
79+
messagedict['attachments'] = []
80+
for attachment in attachments:
81+
filename, contents, mimetype = attachment
82+
binary_contents = base64.b64decode(contents.encode('ascii'))
83+
messagedict['attachments'].append(
84+
(filename, binary_contents, mimetype))
6585
if isinstance(messagedict, dict) and "content_subtype" in messagedict:
6686
content_subtype = messagedict["content_subtype"]
6787
del messagedict["content_subtype"]

tests/image.png

78 Bytes
Loading

tests/tests.py

+39
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
import json
2+
import os.path
3+
from email.mime.image import MIMEImage
4+
15
from django.core import mail
26
from django.core.mail.backends.base import BaseEmailBackend
37
from django.core.mail.backends import locmem
@@ -44,6 +48,41 @@ def test_dict_to_email_extra_attrs(self):
4448

4549
self.assertEquals(email_to_dict(dict_to_email(msg_dict)), msg_dict)
4650

51+
def check_json_of_msg(self, msg):
52+
serialized = json.dumps(email_to_dict(msg))
53+
self.assertEqual(
54+
email_to_dict(dict_to_email(json.loads(serialized))),
55+
email_to_dict(msg))
56+
57+
def test_email_with_attachment(self):
58+
file_path = os.path.join(os.path.dirname(__file__), 'image.png')
59+
with open(file_path, 'rb') as file:
60+
file_contents = file.read()
61+
msg = mail.EmailMessage(
62+
'test', 'Testing with Celery! w00t!!', '[email protected]',
63+
64+
msg.attach('image.png', file_contents)
65+
self.check_json_of_msg(msg)
66+
67+
def test_email_with_mime_attachment(self):
68+
file_path = os.path.join(os.path.dirname(__file__), 'image.png')
69+
with open(file_path, 'rb') as file:
70+
file_contents = file.read()
71+
mimg = MIMEImage(file_contents)
72+
msg = mail.EmailMessage(
73+
'test', 'Testing with Celery! w00t!!', '[email protected]',
74+
75+
msg.attach(mimg)
76+
self.check_json_of_msg(msg)
77+
78+
def test_email_with_attachment_from_file(self):
79+
file_path = os.path.join(os.path.dirname(__file__), 'image.png')
80+
msg = mail.EmailMessage(
81+
'test', 'Testing with Celery! w00t!!', '[email protected]',
82+
83+
msg.attach_file(file_path)
84+
self.check_json_of_msg(msg)
85+
4786

4887
class TaskTests(TestCase):
4988
"""

0 commit comments

Comments
 (0)