feat: add minimal attachments support for email messages
as of now, caller must provide a fully proper MIME attachment. later we will add some magic normalization logic so caller can just provide attachment file paths
This commit is contained in:
parent
763dd510f6
commit
22d3ba97c9
2 changed files with 36 additions and 2 deletions
|
@ -166,6 +166,10 @@ class Message:
|
||||||
.. attribute:: html_body
|
.. attribute:: html_body
|
||||||
|
|
||||||
String with the ``text/html`` body content.
|
String with the ``text/html`` body content.
|
||||||
|
|
||||||
|
.. attribute:: attachments
|
||||||
|
|
||||||
|
List of file attachments for the message.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
@ -179,6 +183,7 @@ class Message:
|
||||||
replyto=None,
|
replyto=None,
|
||||||
txt_body=None,
|
txt_body=None,
|
||||||
html_body=None,
|
html_body=None,
|
||||||
|
attachments=None,
|
||||||
):
|
):
|
||||||
self.key = key
|
self.key = key
|
||||||
self.sender = sender
|
self.sender = sender
|
||||||
|
@ -189,6 +194,7 @@ class Message:
|
||||||
self.replyto = replyto
|
self.replyto = replyto
|
||||||
self.txt_body = txt_body
|
self.txt_body = txt_body
|
||||||
self.html_body = html_body
|
self.html_body = html_body
|
||||||
|
self.attachments = attachments or []
|
||||||
|
|
||||||
def set_recips(self, name, value):
|
def set_recips(self, name, value):
|
||||||
""" """
|
""" """
|
||||||
|
@ -224,6 +230,13 @@ class Message:
|
||||||
if not msg:
|
if not msg:
|
||||||
raise ValueError("message has no body parts")
|
raise ValueError("message has no body parts")
|
||||||
|
|
||||||
|
if self.attachments:
|
||||||
|
for attachment in self.attachments:
|
||||||
|
if isinstance(attachment, str):
|
||||||
|
raise ValueError("must specify valid MIME attachments; this class cannot "
|
||||||
|
"auto-create them from file path etc.")
|
||||||
|
msg = MIMEMultipart(_subtype='mixed', _subparts=[msg] + self.attachments)
|
||||||
|
|
||||||
msg['Subject'] = self.subject
|
msg['Subject'] = self.subject
|
||||||
msg['From'] = self.sender
|
msg['From'] = self.sender
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# -*- coding: utf-8; -*-
|
# -*- coding: utf-8; -*-
|
||||||
|
|
||||||
|
from email.mime.text import MIMEText
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
from unittest.mock import patch, MagicMock
|
from unittest.mock import patch, MagicMock
|
||||||
|
|
||||||
|
@ -8,7 +9,7 @@ import pytest
|
||||||
from wuttjamaican import email as mod
|
from wuttjamaican import email as mod
|
||||||
from wuttjamaican.util import resource_path
|
from wuttjamaican.util import resource_path
|
||||||
from wuttjamaican.exc import ConfigurationError
|
from wuttjamaican.exc import ConfigurationError
|
||||||
from wuttjamaican.testing import ConfigTestCase
|
from wuttjamaican.testing import ConfigTestCase, FileTestCase
|
||||||
|
|
||||||
|
|
||||||
class TestEmailSetting(ConfigTestCase):
|
class TestEmailSetting(ConfigTestCase):
|
||||||
|
@ -24,7 +25,7 @@ class TestEmailSetting(ConfigTestCase):
|
||||||
self.assertEqual(setting.sample_data(), {})
|
self.assertEqual(setting.sample_data(), {})
|
||||||
|
|
||||||
|
|
||||||
class TestMessage(TestCase):
|
class TestMessage(FileTestCase):
|
||||||
|
|
||||||
def make_message(self, **kwargs):
|
def make_message(self, **kwargs):
|
||||||
return mod.Message(**kwargs)
|
return mod.Message(**kwargs)
|
||||||
|
@ -77,6 +78,26 @@ class TestMessage(TestCase):
|
||||||
complete = msg.as_string()
|
complete = msg.as_string()
|
||||||
self.assertIn('From: bob@example.com', complete)
|
self.assertIn('From: bob@example.com', complete)
|
||||||
|
|
||||||
|
# html + attachment
|
||||||
|
csv_part = MIMEText("foo,bar\n1,2", 'csv', 'utf_8')
|
||||||
|
msg = self.make_message(sender='bob@example.com',
|
||||||
|
html_body="<p>hello world</p>",
|
||||||
|
attachments=[csv_part])
|
||||||
|
complete = msg.as_string()
|
||||||
|
self.assertIn('Content-Type: multipart/mixed; boundary=', complete)
|
||||||
|
self.assertIn('Content-Type: text/csv; charset="utf_8"', complete)
|
||||||
|
|
||||||
|
# error if improper attachment
|
||||||
|
csv_path = self.write_file('data.csv', "foo,bar\n1,2")
|
||||||
|
msg = self.make_message(sender='bob@example.com',
|
||||||
|
html_body="<p>hello world</p>",
|
||||||
|
attachments=[csv_path])
|
||||||
|
self.assertRaises(ValueError, msg.as_string)
|
||||||
|
try:
|
||||||
|
msg.as_string()
|
||||||
|
except ValueError as err:
|
||||||
|
self.assertIn("must specify valid MIME attachments", str(err))
|
||||||
|
|
||||||
# everything
|
# everything
|
||||||
msg = self.make_message(sender='bob@example.com',
|
msg = self.make_message(sender='bob@example.com',
|
||||||
subject='meeting follow-up',
|
subject='meeting follow-up',
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue