DjrillMessage which wraps Django's EmailMultiAlternatives. Mail backend now works with standard email and multipart through the DjrillMessage object.

This commit is contained in:
Chris Jones
2012-02-28 13:03:26 -08:00
parent d6ff089060
commit 91b846fea3
2 changed files with 81 additions and 10 deletions

View File

@@ -0,0 +1,37 @@
from django.core.exceptions import ImproperlyConfigured
from django.core.mail import EmailMultiAlternatives
class DjrillMessage(EmailMultiAlternatives):
alternative_subtype = "mandrill"
def __init__(self, subject='', body='', from_email=None, to=None, bcc=None,
connection=None, attachments=None, headers=None, alternatives=None,
cc=None, tags=None, track_opens=True, track_clicks=True):
super(DjrillMessage, self).__init__(subject, body, from_email, to, bcc,
connection, attachments, headers, alternatives, cc)
self.tags = self._set_mandrill_tags(tags)
self.track_opens = track_opens
self.track_clicks = track_clicks
def _set_mandrill_tags(self, tags):
"""
Check that all tags are below 50 chars and that they do not start
with an underscore.
Raise ImproperlyConfigured if an underscore tag is passed in to
alert the user. Any tag over 50 chars is left out of the list.
"""
tag_list = []
for tag in tags:
if len(tag) <= 50 and not tag.startswith("_"):
tag_list.append(tag)
elif tag.startswith("_"):
raise ImproperlyConfigured(
"Tags starting with an underscore are reserved for "
"internal use and will cause errors with Mandill's API")
return tag_list

View File

@@ -69,23 +69,21 @@ class DjrillBackend(BaseEmailBackend):
if not message.recipients():
return False
sender = sanitize_address(message.from_email, message.encoding)
self.sender = sanitize_address(message.from_email, message.encoding)
recipients_list = [sanitize_address(addr, message.encoding)
for addr in message.recipients()]
from email.utils import parseaddr
recipients = [{"email": e, "name": n} for n,e in [
self.recipients = [{"email": e, "name": n} for n,e in [
parseaddr(r) for r in recipients_list]]
self.msg_dict = self._build_standard_message_dict(message)
if message.alternative_subtype == "mandrill" and message.alternatives:
self._add_alternatives(message)
djrill_it = requests.post(self.api_action, data=json.dumps({
"key": self.api_key,
"message": {
"html": message.body,
"text": message.body,
"subject": message.subject,
"from_email": sender,
"from_name": "Devs",
"to": recipients
}
"message": self.msg_dict
}))
if djrill_it.status_code != 200:
@@ -93,3 +91,39 @@ class DjrillBackend(BaseEmailBackend):
raise
return False
return True
def _build_standard_message_dict(self, message):
"""
Build standard message dict.
Builds the standard dict that Django's send_mail and send_mass_mail
use by default. Standard text email messages sent through Django will
still work through Mandrill.
"""
return {
"text": message.body,
"subject": message.subject,
"from_email": self.sender,
"from_name": "Devs - FIX ME",
"to": self.recipients
}
def _add_alternatives(self, message):
"""
There can be only one! ... alternative attachment.
Since mandrill does not accept image attachments or anything other
than HTML, the assumption is the only thing you are attaching is
the HTML output for your email.
"""
if len(message.alternatives) > 1:
raise ImproperlyConfigured(
"Mandrill only accepts plain text and html emails. Please "
"check the alternatives you have attached to your message.")
self.msg_dict.update({
"html": message.alternatives[0][0],
"tags": message.tags,
"track_opens": message.track_opens,
"track_clicks": message.track_clicks
})