forked from peopledoc/django-mail-factory
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmessages.py
93 lines (79 loc) · 3.77 KB
/
messages.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# -*- coding: utf-8 -*-
import re
from email.mime.base import MIMEBase
from os.path import basename
from django.conf import settings
from django.core.mail import EmailMultiAlternatives, SafeMIMEMultipart
# http://djangosnippets.org/snippets/2215/
class EmailMultiRelated(EmailMultiAlternatives):
"""
A version of EmailMessage that makes it easy to send multipart/related
messages. For example, including text and HTML versions with inline images.
"""
related_subtype = 'related'
def __init__(self, subject='', body='', from_email=None, to=None, bcc=None,
connection=None, attachments=None, headers=None,
alternatives=None):
self.related_attachments = []
super(EmailMultiRelated, self).__init__(
subject, body, from_email, to, bcc, connection,
attachments, headers, alternatives)
def attach_related(self, filename=None, content=None, mimetype=None):
"""
Attaches a file with the given filename and content. The filename can
be omitted and the mimetype is guessed, if not provided.
If the first parameter is a MIMEBase subclass it is inserted directly
into the resulting message attachments.
"""
if isinstance(filename, MIMEBase):
assert content is None and mimetype is None
self.related_attachments.append(filename)
else:
assert content is not None
self.related_attachments.append((filename, content, mimetype))
def attach_related_file(self, path, mimetype=None, filename=None):
"""Attaches a file from the filesystem."""
if not filename:
filename = basename(path)
with open(path, 'rb') as fd:
content = fd.read()
self.attach_related(filename, content, mimetype)
def _create_message(self, msg):
return self._create_attachments(
self._create_related_attachments(self._create_alternatives(msg)))
def _create_alternatives(self, msg):
for i, (content, mimetype) in enumerate(self.alternatives):
if mimetype == 'text/html':
for filename, _, _ in self.related_attachments:
content = re.sub(r'(?<!cid:)%s' % re.escape(filename),
'cid:%s' % filename, content)
self.alternatives[i] = (content, mimetype)
return super(EmailMultiRelated, self)._create_alternatives(msg)
def _create_related_attachments(self, msg):
encoding = self.encoding or settings.DEFAULT_CHARSET
if self.related_attachments:
body_msg = msg
msg = SafeMIMEMultipart(_subtype=self.related_subtype,
encoding=encoding)
if self.body:
msg.attach(body_msg)
for related in self.related_attachments:
msg.attach(self._create_related_attachment(*related))
return msg
def _create_related_attachment(self, filename, content, mimetype=None):
"""
Convert the filename, content, mimetype triple into a MIME attachment
object. Adjust headers to use Content-ID where applicable.
Taken from http://code.djangoproject.com/ticket/4771
"""
attachment = super(EmailMultiRelated, self)._create_attachment(
filename, content, mimetype)
if filename:
mimetype = attachment['Content-Type']
del(attachment['Content-Type'])
del(attachment['Content-Disposition'])
attachment.add_header('Content-Disposition', 'inline',
filename=filename)
attachment.add_header('Content-Type', mimetype, name=filename)
attachment.add_header('Content-ID', '<%s>' % filename)
return attachment