Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions flask_mail.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ class Message(object):
:param extra_headers: A dictionary of additional headers for the message
:param mail_options: A list of ESMTP options to be used in MAIL FROM command
:param rcpt_options: A list of ESMTP options to be used in RCPT commands
:param subtype: Media subtype name for a message
"""

def __init__(self, subject='',
Expand All @@ -270,7 +271,8 @@ def __init__(self, subject='',
charset=None,
extra_headers=None,
mail_options=None,
rcpt_options=None):
rcpt_options=None,
subtype=None):

sender = sender or current_app.extensions['mail'].default_sender

Expand All @@ -290,6 +292,7 @@ def __init__(self, subject='',
self.msgId = make_msgid()
self.charset = charset
self.extra_headers = extra_headers
self.subtype = subtype
self.mail_options = mail_options or []
self.rcpt_options = rcpt_options or []
self.attachments = attachments or []
Expand All @@ -309,10 +312,11 @@ def html(self, value):
else:
self.alts['html'] = value

def _mimetext(self, text, subtype='plain'):
def _mimetext(self, text, subtype=None):
"""Creates a MIMEText object with the given subtype (default: 'plain')
If the text is unicode, the utf-8 charset is used.
"""
subtype = subtype or 'plain'
charset = self.charset or 'utf-8'
return MIMEText(text, _subtype=subtype, _charset=charset)

Expand All @@ -325,16 +329,18 @@ def _message(self):

if len(attachments) == 0 and not self.alts:
# No html content and zero attachments means plain text
msg = self._mimetext(self.body)
msg = self._mimetext(self.body, self.subtype)
elif len(attachments) > 0 and not self.alts:
# No html and at least one attachment means multipart
msg = MIMEMultipart()
subtype = self.subtype or 'mixed'
msg = MIMEMultipart(_subtype=subtype)
msg.attach(self._mimetext(self.body))
else:
# Anything else
msg = MIMEMultipart()
alternative = MIMEMultipart('alternative')
alternative.attach(self._mimetext(self.body, 'plain'))
subtype = self.subtype or 'mixed'
msg = MIMEMultipart(_subtype=subtype)
alternative = MIMEMultipart(_subtype='alternative')
alternative.attach(self._mimetext(self.body))
for mimetype, content in self.alts.items():
alternative.attach(self._mimetext(content, mimetype))
msg.attach(alternative)
Expand Down
19 changes: 19 additions & 0 deletions tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ def test_html_message(self):

self.assertEqual(html_text, msg.html)
self.assertIn('Content-Type: multipart/alternative', msg.as_string())
self.assertIn('Content-Type: text/html', msg.as_string())

def test_json_message(self):
json_text = '{"msg": "Hello World!}'
Expand All @@ -361,6 +362,8 @@ def test_html_message_with_attachments(self):

self.assertEqual(html_text, msg.html)
self.assertIn('Content-Type: multipart/alternative', msg.as_string())
self.assertIn('Content-Type: text/html', msg.as_string())
self.assertIn('Content-Type: text/plain', msg.as_string())

parsed = email.message_from_string(msg.as_string())
self.assertEqual(len(parsed.get_payload()), 2)
Expand Down Expand Up @@ -547,6 +550,22 @@ def test_empty_subject_header(self):
self.mail.send(msg)
self.assertNotIn('Subject:', msg.as_string())

def test_custom_subtype_without_attachment(self):
msg = Message(sender="[email protected]",
subject="testing",
recipients=["[email protected]"],
subtype="html")
self.assertIn('Content-Type: text/html', msg.as_string())

def test_custom_subtype_with_attachment(self):
msg = Message(sender="[email protected]",
subject="testing",
recipients=["[email protected]"],
subtype="related")
msg.attach(data=b"this is a test",
content_type="text/plain")
self.assertIn('Content-Type: multipart/related', msg.as_string())

class TestMail(TestCase):

def test_send(self):
Expand Down