Merge pull request #18 from medmunds/v020

v0.2.0
This commit is contained in:
Mike Edmunds
2012-12-11 13:51:17 -08:00
8 changed files with 93 additions and 38 deletions

2
.gitignore vendored
View File

@@ -2,4 +2,6 @@
._*
*.pyc
*.egg-info
dist/
TODO.txt
local.py

View File

@@ -6,3 +6,5 @@ Chris Jones
Mike Edmunds
ArnaudF
Théo Crevon
Rafael E. Belliard
Jared Morse

View File

@@ -1,16 +1,16 @@
Djrill, for Mandrill
====================
.. image:: https://secure.travis-ci.org/brack3t/Djrill.png
:target: https://secure.travis-ci.org/brack3t/Djrill
.. image:: https://secure.travis-ci.org/brack3t/Djrill.png?branch=master
:target: https://travis-ci.org/brack3t/Djrill
Djrill is an email backend and new message class for Django users that want to take advantage of the Mandrill_ transactional
email service from MailChimp_.
Djrill is an email backend for Django users who want to take advantage of the
Mandrill_ transactional email service from MailChimp_.
An optional Django admin interface is included. The admin interface allows you to:
* Check the status of your Mandrill API connection.
* See stats on email tags and urls.
* See stats on email senders, tags and urls.
Djrill is made available under the BSD license.
@@ -81,35 +81,38 @@ package, including ``send_mail``, ``send_mass_mail``, ``EmailMessage`` and
``EmailMultiAlternatives``.
You can also take advantage of Mandrill-specific features like tags, metadata,
and tracking by creating a ``django.mail.EmailMessage`` (or for HTML,
``django.mail.EmailMultiAlternatives``) object and setting Mandrill-specific
and tracking by creating a Django EmailMessage_ (or for HTML,
EmailMultiAlternatives_) object and setting Mandrill-specific
properties on it before calling its ``send`` method.
Example:
Example, sending HTML email with Mandrill tags and metadata:
.. code:: python
from django.core.mail import EmailMultiAlternatives # or just EmailMessage if you don't need HTML
from django.core.mail import EmailMultiAlternatives
subject = "Djrill Message"
from_email = "Djrill Sender <djrill@example.com>" # this has to be in your Mandrill account's sending domains
to = ["Djrill Receiver <djrill.receiver@example.com>", "djrill.two@example.com"]
reply_email = "Customer Service <support@example.com>" # optional
text_content = "This is the text version of your email"
html_content = "<p>This is the HTML version of your email</p>" # optional, use with ``attach_alternative`` below
msg = EmailMultiAlternatives(
subject="Djrill Message",
body="This is the text version of your email",
from_email="Djrill Sender <djrill@example.com>",
to=["Djrill Receiver <djrill.receiver@example.com>", "another.person@example.com"],
headers={'Reply-To': "Service <support@example.com>"} # optional extra headers
)
msg.attach_alternative("<p>This is the HTML version of your email</p>", "text/html")
msg = EmailMultiAlternatives(subject, text_content, from_email, to, headers={'Reply-To': reply_email})
msg.tags = ["one tag", "two tag", "red tag", "blue tag"] # optional, Mandrill-specific message extension
msg.metadata = {'user_id': "8675309"} # optional, Mandrill-specific message extension
msg.attach_alternative(html_content, "text/html")
# Optional Mandrill-specific extensions (see full list below):
msg.tags = ["one tag", "two tag", "red tag", "blue tag"]
msg.metadata = {'user_id': "8675309"}
# Send it:
msg.send()
If the Mandrill API returns an error response for any reason, the send call will
raise a ``djrill.mail.backends.djrill.DjrillBackendHTTPError`` exception
(unless called with fail_silently=True).
Djrill supports most of the functionality of Django's ``EmailMessage`` and
``EmailMultiAlternatives``. Some limitations:
Djrill supports most of the functionality of Django's `EmailMessage`_ and
`EmailMultiAlternatives`_ classes. Some limitations:
* Djrill accepts additional headers, but only ``Reply-To`` and ``X-*`` (since
that is all that Mandrill accepts). Any other extra headers will raise a
@@ -125,6 +128,10 @@ Djrill supports most of the functionality of Django's ``EmailMessage`` and
which Djrill doesn't use. *Caution:* depending on the ``preserve_recipients``
setting, this could result in exposing bcc addresses to all recipients. It's
probably best to just avoid bcc.)
* All email addresses (from, to, cc) can be simple ("email@example.com") or
can include a display name ("Real Name <email@example.com>").
* The ``from_email`` must be in one of the approved sending domains in your
Mandrill account.
Many of the options from the Mandrill `messages/send.json API`_ ``message``
struct can be set directly on an ``EmailMessage`` (or subclass) object:
@@ -160,12 +167,13 @@ see ``DjrillMandrillFeatureTests`` in tests.py for examples.
Testing
-------
Djrill is tested against Django 1.3 and 1.4 on Python 2.6 and 2.7.
Djrill is tested against Django 1.3 and 1.4 on Python 2.6 and 2.7, and
Django 1.5beta on Python 2.7.
(It may also work with Django 1.2 and Python 2.5, if you use an older
version of requests compatible with that code.)
.. image:: https://secure.travis-ci.org/brack3t/Djrill.png
:target: https://secure.travis-ci.org/brack3t/Djrill
.. image:: https://secure.travis-ci.org/brack3t/Djrill.png?branch=master
:target: https://travis-ci.org/brack3t/Djrill
The included tests verify that Djrill constructs the expected Mandrill API
calls, without actually calling Mandrill or sending any email. So the tests
@@ -179,6 +187,18 @@ or::
python runtests.py
Release Notes
-------------
Version 0.2.0:
* ``MANDRILL_API_URL`` is no longer required in settings.py
* Earlier versions of Djrill required use of a ``DjrillMessage`` class to
specify Mandrill-specific options. This is no longer needed -- Mandrill
options can now be set directly on a Django EmailMessage_ object or any
subclass. (Existing code can continue to use ``DjrillMessage``.)
Thanks
------
@@ -193,5 +213,7 @@ the awesome ``requests`` library.
.. _django-adminplus: https://github.com/jsocol/django-adminplus
.. _mock: http://www.voidspace.org.uk/python/mock/index.html
.. _django.core.mail: https://docs.djangoproject.com/en/dev/topics/email/
.. _EmailMessage: https://docs.djangoproject.com/en/dev/topics/email/#django.core.mail.EmailMessage
.. _EmailMultiAlternatives: https://docs.djangoproject.com/en/dev/topics/email/#sending-alternative-content-types
.. _messages/send.json API: https://mandrillapp.com/api/docs/messages.html#method=send

View File

@@ -1,7 +1,7 @@
from django.contrib.admin.sites import AdminSite
from django.utils.text import capfirst
VERSION = (0, 1, 2)
VERSION = (0, 2, 0)
__version__ = '.'.join([str(x) for x in VERSION])

View File

@@ -1,30 +1,37 @@
from django.core.exceptions import ImproperlyConfigured
from django.core.mail import EmailMultiAlternatives
# DjrillMessage class is deprecated as of 0.2.0, but retained for
# compatibility with existing code. (New code can just set Mandrill-specific
# options directly on an EmailMessage or EmailMultiAlternatives object.)
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, from_name=None, tags=None, track_opens=True,
track_clicks=True, preserve_recipients=False):
track_clicks=True, preserve_recipients=None):
super(DjrillMessage, self).__init__(subject, body, from_email, to, bcc,
connection, attachments, headers, alternatives, cc)
self.from_name = from_name
self.tags = self._set_mandrill_tags(tags)
self.track_opens = track_opens
self.track_clicks = track_clicks
self.preserve_recipients = preserve_recipients
if from_name:
self.from_name = from_name
if tags:
self.tags = self._set_mandrill_tags(tags)
if track_opens is not None:
self.track_opens = track_opens
if track_clicks is not None:
self.track_clicks = track_clicks
if preserve_recipients is not None:
self.preserve_recipients = preserve_recipients
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
Raise ValueError if an underscore tag is passed in to
alert the user. Any tag over 50 chars is left out of the list.
"""
tag_list = []
@@ -33,8 +40,8 @@ class DjrillMessage(EmailMultiAlternatives):
if len(tag) <= 50 and not tag.startswith("_"):
tag_list.append(tag)
elif tag.startswith("_"):
raise ImproperlyConfigured(
raise ValueError(
"Tags starting with an underscore are reserved for "
"internal use and will cause errors with Mandill's API")
"internal use and will cause errors with Mandrill's API")
return tag_list

View File

@@ -61,6 +61,7 @@
<dt>{{ term|capfirst }}</dt>
<dd>{{ value }}</dd>
{% endfor %}
</dl>
</div>
</div>
{% endblock %}

View File

@@ -392,7 +392,7 @@ class DjrillMessageTests(TestCase):
self.assertEqual(msg.alternatives[0][0], self.html_content)
def test_djrill_message_tag_failure(self):
with self.assertRaises(ImproperlyConfigured):
with self.assertRaises(ValueError):
DjrillMessage(self.subject, self.text_content, self.from_email,
self.to, tags=["_fail"])
@@ -409,3 +409,15 @@ class DjrillMessageTests(TestCase):
self.assertIn(tags[0], msg.tags)
self.assertIn(tags[1], msg.tags)
self.assertNotIn(tags[2], msg.tags)
def test_djrill_message_no_options(self):
"""DjrillMessage with only basic EmailMessage options should work"""
msg = DjrillMessage(self.subject, self.text_content,
self.from_email, self.to) # no Mandrill-specific options
self.assertIsInstance(msg, DjrillMessage)
self.assertEqual(msg.body, self.text_content)
self.assertEqual(msg.recipients(), self.to)
self.assertFalse(hasattr(msg, 'tags'))
self.assertFalse(hasattr(msg, 'from_name'))
self.assertFalse(hasattr(msg, 'preserve_recipients'))

View File

@@ -2,9 +2,8 @@ from setuptools import setup
setup(
name="djrill",
version="0.1.4.1",
version="0.2.0",
description='Django email backend for Mandrill.',
long_description='Email backend and new message class to send emails through the Mandrill email service.',
keywords="django, mailchimp, mandrill, email, email backend",
author="Kenneth Love <kenneth@brack3t.com>, Chris Jones <chris@brack3t.com>",
author_email="kenneth@brack3t.com",
@@ -23,4 +22,14 @@ setup(
"Framework :: Django",
"Environment :: Web Environment",
],
long_description="""\
Djrill is an email backend for Django users who want to take advantage of the
`Mandrill <http://mandrill.com>`_ transactional email service from MailChimp.
In general, Djrill "just works" with Django's built-in ``django.core.mail``
package. You can also take advantage of Mandrill-specific features like tags,
metadata, and tracking. An optional Django admin interface is included.
Full details are on the `project page <https://github.com/brack3t/Djrill>`_.
""",
)