mirror of
https://github.com/pacnpal/django-anymail.git
synced 2025-12-20 11:51:05 -05:00
Merge pull request #30 from brack3t/docs
Break up readme into docs; add to readthedocs.org
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,5 +3,6 @@
|
||||
*.pyc
|
||||
*.egg-info
|
||||
dist/
|
||||
docs/_build/
|
||||
TODO.txt
|
||||
local.py
|
||||
|
||||
352
README.rst
352
README.rst
@@ -1,327 +1,121 @@
|
||||
Djrill, for Mandrill
|
||||
====================
|
||||
.. This README is reused in multiple places:
|
||||
* Github: project page, exactly as it appears here
|
||||
* Docs: shared-intro section gets included in docs/index.rst
|
||||
quickstart section gets included in docs/quickstart.rst
|
||||
* PyPI: project page (via setup.py long_description),
|
||||
with several edits to freeze it to the specific PyPI release
|
||||
(see long_description_from_readme in setup.py)
|
||||
You can use docutils 1.0 markup, but *not* any Sphinx additions.
|
||||
|
||||
.. image:: https://secure.travis-ci.org/brack3t/Djrill.png?branch=master
|
||||
.. These substitution definitions apply in the readme (github) only;
|
||||
they're altered by setup.py for the long_description,
|
||||
and defined differently for the docs includes
|
||||
|
||||
.. |release| replace:: (source)
|
||||
|
||||
.. |version| replace:: |release|
|
||||
|
||||
.. |buildstatus| image:: https://secure.travis-ci.org/brack3t/Djrill.png?branch=master
|
||||
:target: https://travis-ci.org/brack3t/Djrill
|
||||
|
||||
Djrill is an email backend for Django users who want to take advantage of the
|
||||
Mandrill_ transactional email service from MailChimp_.
|
||||
.. default-role:: literal
|
||||
|
||||
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. The admin interface allows you to:
|
||||
.. _shared-intro:
|
||||
.. This shared-intro section is also included in docs/index.rst
|
||||
|
||||
* Check the status of your Mandrill API connection.
|
||||
* See stats on email senders, tags and urls.
|
||||
Djrill: Mandrill Transactional Email for Django
|
||||
===============================================
|
||||
|
||||
Djrill is made available under the BSD license.
|
||||
Release |release|
|
||||
|
||||
Installation
|
||||
Djrill integrates the `Mandrill <http://mandrill.com>`_ transactional
|
||||
email service into Django.
|
||||
|
||||
In general, Djrill "just works" with Django's built-in `django.core.mail`
|
||||
package. It includes:
|
||||
|
||||
* Support for HTML, attachments, extra headers, and other features of
|
||||
`Django's built-in email <https://docs.djangoproject.com/en/dev/topics/email/>`_
|
||||
* Mandrill-specific extensions like tags, metadata, tracking, and MailChimp templates
|
||||
* An optional Django admin interface
|
||||
|
||||
Djrill is released under the BSD license. It is tested against Django 1.3, 1.4, and 1.5
|
||||
(including Python 3 support with Django 1.5). |buildstatus|
|
||||
|
||||
.. END shared-intro
|
||||
|
||||
Resources:
|
||||
|
||||
* Full documentation: https://djrill.readthedocs.org/en/latest/
|
||||
* Package on PyPI: https://pypi.python.org/pypi/djrill
|
||||
* Project on Github: https://github.com/brack3t/Djrill
|
||||
|
||||
|
||||
Djrill 1-2-3
|
||||
------------
|
||||
|
||||
Install from PyPI::
|
||||
.. _quickstart:
|
||||
.. This quickstart section is also included in docs/quickstart.rst
|
||||
|
||||
pip install djrill
|
||||
1. Install Djrill from PyPI:
|
||||
|
||||
The only dependency other than Django is the requests_ library from Kenneth
|
||||
Reitz. (If you do not install Djrill using pip or setuptools, you will also
|
||||
need to ``pip install requests``.)
|
||||
.. code-block:: console
|
||||
|
||||
$ pip install djrill
|
||||
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
2. Edit your project's ``settings.py``:
|
||||
|
||||
In ``settings.py``:
|
||||
|
||||
1. Add ``djrill`` to your ``INSTALLED_APPS``:
|
||||
|
||||
.. code:: python
|
||||
.. code-block:: python
|
||||
|
||||
INSTALLED_APPS = (
|
||||
...
|
||||
"djrill"
|
||||
)
|
||||
|
||||
2. Add the following line, substituting your own ``MANDRILL_API_KEY``:
|
||||
|
||||
.. code:: python
|
||||
|
||||
MANDRILL_API_KEY = "brack3t-is-awesome"
|
||||
|
||||
3. Override your existing email backend with the following line:
|
||||
|
||||
.. code:: python
|
||||
|
||||
MANDRILL_API_KEY = "<your Mandrill key>"
|
||||
EMAIL_BACKEND = "djrill.mail.backends.djrill.DjrillBackend"
|
||||
|
||||
4. (optional) If you want to be able to add senders through Django's admin or
|
||||
view stats about your messages, do the following in your base ``urls.py``:
|
||||
|
||||
.. code:: python
|
||||
3. Now the regular `Django email functions <https://docs.djangoproject.com/en/dev/topics/email/>`_
|
||||
will send through Mandrill:
|
||||
|
||||
...
|
||||
from django.contrib import admin
|
||||
.. code-block:: python
|
||||
|
||||
from djrill import DjrillAdminSite
|
||||
from django.core.mail import send_mail
|
||||
|
||||
admin.site = DjrillAdminSite()
|
||||
admin.autodiscover()
|
||||
...
|
||||
send_mail("It works!", "This will get sent through Mandrill",
|
||||
"Djrill Sender <djrill@example.com>", ["to@example.com"])
|
||||
|
||||
urlpatterns = patterns('',
|
||||
...
|
||||
url(r'^admin/', include(admin.site.urls)),
|
||||
)
|
||||
|
||||
Usage
|
||||
-----
|
||||
You could send an HTML message, complete with custom Mandrill tags and metadata:
|
||||
|
||||
Since you are replacing the global ``EMAIL_BACKEND``, **all** emails are sent
|
||||
through Mandrill's service. (To selectively use Mandrill for some messages, see
|
||||
`Using Multiple Email Backends`_ below.)
|
||||
|
||||
In general, Djrill "just works" with Django's built-in `django.core.mail`_
|
||||
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 EmailMessage_ (or for HTML,
|
||||
EmailMultiAlternatives_) object and setting Mandrill-specific
|
||||
properties on it before calling its ``send`` method. (See
|
||||
`Mandrill Message Options`_ below.)
|
||||
|
||||
Example, sending HTML email with Mandrill tags and metadata:
|
||||
|
||||
.. code:: python
|
||||
.. code-block:: python
|
||||
|
||||
from django.core.mail import EmailMultiAlternatives
|
||||
|
||||
msg = EmailMultiAlternatives(
|
||||
subject="Djrill Message",
|
||||
body="This is the text version of your email",
|
||||
body="This is the text email body",
|
||||
from_email="Djrill Sender <djrill@example.com>",
|
||||
to=["Djrill Receiver <djrill.receiver@example.com>", "another.person@example.com"],
|
||||
to=["Recipient One <someone@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.attach_alternative("<p>This is the HTML email body</p>", "text/html")
|
||||
|
||||
# Optional Mandrill-specific extensions (see full list below):
|
||||
# Optional Mandrill-specific extensions:
|
||||
msg.tags = ["one tag", "two tag", "red tag", "blue tag"]
|
||||
msg.metadata = {'user_id': "8675309"}
|
||||
|
||||
# Send it:
|
||||
msg.send()
|
||||
|
||||
If the email tries to use features that aren't supported by Mandrill, the send
|
||||
call will raise a ``djrill.NotSupportedByMandrillError`` exception (a subclass
|
||||
of ValueError).
|
||||
(Be sure to use a ``from_email`` that's in one of your Mandrill approved sending
|
||||
domains, or the message won't get sent.)
|
||||
|
||||
If the Mandrill API fails or returns an error response, the send call will
|
||||
raise a ``djrill.MandrillAPIError`` exception (a subclass of
|
||||
requests.HTTPError).
|
||||
.. END quickstart
|
||||
|
||||
|
||||
Django EmailMessage Support
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Djrill supports most of the functionality of Django's `EmailMessage`_ and
|
||||
`EmailMultiAlternatives`_ classes. Some notes and limitations:
|
||||
|
||||
* **Display Names:** All email addresses (from, to, cc) can be simple
|
||||
("email@example.com") or can include a display name
|
||||
("Real Name <email@example.com>").
|
||||
* **From Address:** The ``from_email`` must be in one of the approved sending
|
||||
domains in your Mandrill account.
|
||||
* **CC Recipients:** Djrill treats all "cc" recipients as if they were
|
||||
additional "to" addresses. (Mandrill does not distinguish "cc" from "to".)
|
||||
Note that you will also need to set ``preserve_recipients`` True if you want
|
||||
each recipient to see the other recipients listed in the email headers.
|
||||
* **BCC Recipients:** Mandrill does not permit more than one "bcc" address.
|
||||
Djrill raises ``djrill.NotSupportedByMandrillError`` if you attempt to send a
|
||||
message with multiple bcc's. (Mandrill's bcc option seems intended primarily
|
||||
for logging. To send a single message to multiple recipients without exposing
|
||||
their email addresses to each other, simply include them all in the "to" list
|
||||
and leave ``preserve_recipients`` set to False.)
|
||||
* **Attachments:** Djrill includes a message's attachments. Also, if an image
|
||||
attachment has a Content-ID header, Djrill will tell Mandrill to treat that
|
||||
as an embedded image rather than an ordinary attachment. (For an example,
|
||||
see ``test_embedded_images`` in tests/test_mandrill_send.py.)
|
||||
* **Headers:** Djrill accepts additional headers, but only ``Reply-To`` and
|
||||
``X-*`` (since that is all that Mandrill accepts). Any other extra headers
|
||||
will raise ``djrill.NotSupportedByMandrillError`` when you attempt to send the
|
||||
message.
|
||||
* **Alternative Parts:** Djrill requires that if you ``attach_alternative`` to a
|
||||
message, there must be only one alternative part, and it must be text/html.
|
||||
Otherwise, Djrill will raise ``djrill.NotSupportedByMandrillError`` when you
|
||||
attempt to send the message. (Mandrill doesn't support sending multiple html
|
||||
alternative parts, or any non-html alternatives.)
|
||||
|
||||
Mandrill Message Options
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Many of the options from the Mandrill `messages/send API`_ ``message``
|
||||
struct can be set directly on an ``EmailMessage`` (or subclass) object:
|
||||
|
||||
* ``track_opens`` - Boolean
|
||||
* ``track_clicks`` - Boolean (If you want to track clicks in HTML only, not
|
||||
plaintext mail, you must *not* set this property, and instead just set the
|
||||
default in your Mandrill account sending options.)
|
||||
* ``auto_text`` - Boolean
|
||||
* ``url_strip_qs`` - Boolean
|
||||
* ``preserve_recipients`` - Boolean
|
||||
* ``global_merge_vars`` - a dict -- e.g.,
|
||||
``{ 'company': "ACME", 'offer': "10% off" }``
|
||||
* ``recipient_merge_vars`` - a dict whose keys are the recipient email addresses
|
||||
and whose values are dicts of merge vars for each recipient -- e.g.,
|
||||
``{ 'wiley@example.com': { 'offer': "15% off anvils" } }``
|
||||
* ``tags`` - a list of strings
|
||||
* ``google_analytics_domains`` - a list of string domain names
|
||||
* ``google_analytics_campaign`` - a string or list of strings
|
||||
* ``metadata`` - a dict
|
||||
* ``recipient_metadata`` - a dict whose keys are the recipient email addresses,
|
||||
and whose values are dicts of metadata for each recipient (similar to
|
||||
``recipient_merge_vars``)
|
||||
|
||||
These Mandrill-specific properties work with *any* ``EmailMessage``-derived
|
||||
object, so you can use them with many other apps that add Django mail
|
||||
functionality (such as Django template-based messages).
|
||||
|
||||
If you have any questions about the python syntax for any of these properties,
|
||||
see ``DjrillMandrillFeatureTests`` in tests/test_mandrill_send.py for examples.
|
||||
|
||||
Mandrill Templates
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To use a Mandrill (MailChimp) template, set a ``template_name`` and (optionally)
|
||||
``template_content`` on your ``EmailMessage`` object:
|
||||
|
||||
.. code:: python
|
||||
|
||||
msg = EmailMessage(subject="Shipped!", from_email="store@example.com",
|
||||
to=["customer@example.com", "accounting@example.com"])
|
||||
msg.template_name = "SHIPPING_NOTICE" # A Mandrill template name
|
||||
msg.template_content = { # Content blocks to fill in
|
||||
'TRACKING_BLOCK': "<a href='.../\*\|TRACKINGNO\|\*'>track it</a>" }
|
||||
msg.global_merge_vars = { # Merge tags in your template
|
||||
'ORDERNO': "12345", 'TRACKINGNO': "1Z987" }
|
||||
msg.merge_vars = { # Per-recipient merge tags
|
||||
'accounting@example.com': { 'NAME': "Pat" },
|
||||
'customer@example.com': { 'NAME': "Kim" } }
|
||||
msg.send()
|
||||
|
||||
If template_name is set, Djrill will use Mandrill's `messages/send-template API`_,
|
||||
rather than messages/send. All of the other options listed above can be used.
|
||||
|
||||
(This is for *MailChimp* templates stored in your Mandrill account. If you
|
||||
want to use a *Django* template, you can use Django's render_to_string_ template
|
||||
shortcut to build the body and html, and send using EmailMultiAlternatives as
|
||||
in the earlier examples.)
|
||||
|
||||
Using Multiple Email Backends
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You can use Django mail's optional ``connection`` argument to send some mail
|
||||
through Mandrill and others through a different system. This can be useful to
|
||||
send customer emails with Mandrill, but admin emails directly through an SMTP
|
||||
server. Example:
|
||||
|
||||
.. code:: python
|
||||
|
||||
from django.core.mail import send_mail, get_connection
|
||||
|
||||
# send_mail connection defaults to the settings EMAIL_BACKEND, which
|
||||
# we've set to DjrillBackend. This will be sent using Mandrill:
|
||||
send_mail("Subject", "Body", "support@example.com", ["user@example.com"])
|
||||
|
||||
# Get a connection to an SMTP backend, and send using that instead:
|
||||
smtp_backend = get_connection('django.core.mail.backends.smtp.EmailBackend')
|
||||
send_mail("Subject", "Body", "admin@example.com", ["alert@example.com"],
|
||||
connection=smtp_backend)
|
||||
|
||||
You can supply a different connection to Django's `django.core.mail`_
|
||||
``send_mail`` and ``send_mass_mail`` helpers, and in the constructor for an
|
||||
EmailMessage_ or EmailMultiAlternatives_.
|
||||
|
||||
|
||||
Testing
|
||||
-------
|
||||
|
||||
Djrill is tested against Django 1.3 and 1.4 on Python 2.6 and 2.7, and
|
||||
Django 1.5RC on Python 2.7 and 3.2.
|
||||
(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?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
|
||||
don't require a Mandrill API key, but they *do* require mock_
|
||||
(``pip install mock``). To run the tests, either::
|
||||
|
||||
python -Wall setup.py test
|
||||
|
||||
or::
|
||||
|
||||
python -Wall runtests.py
|
||||
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
Djrill is maintained by its users -- it's not managed by the folks at MailChimp.
|
||||
Pull requests are always welcome to improve support for Mandrill and Django
|
||||
features.
|
||||
|
||||
Please include test cases with pull requests. (And by submitting a pull request,
|
||||
you're agreeing to release your changes under under the same BSD license as the
|
||||
rest of this project.)
|
||||
|
||||
|
||||
Release Notes
|
||||
-------------
|
||||
|
||||
Version 0.3.0:
|
||||
|
||||
* Attachments are now supported
|
||||
* Mandrill templates are now supported
|
||||
* A bcc address is now passed to Mandrill as bcc, rather than being lumped in
|
||||
with the "to" recipients. Multiple bcc recipients will now raise an exception,
|
||||
as Mandrill only allows one.
|
||||
* Python 3 support (with Django 1.5)
|
||||
* Exceptions should be more useful: ``djrill.NotSupportedByMandrillError``
|
||||
replaces generic ValueError; ``djrill.MandrillAPIError`` replaces
|
||||
DjrillBackendHTTPError, and is now derived from requests.HTTPError. (New
|
||||
exceptions are backwards compatible with old ones for existing code.)
|
||||
|
||||
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
|
||||
------
|
||||
|
||||
Thanks to the MailChimp team for asking us to build this nifty little app. Also thanks to James Socol on Github for his
|
||||
django-adminplus_ library that got us off on the right foot for the custom admin views. Oh, and, of course, Kenneth Reitz for
|
||||
the awesome ``requests`` library.
|
||||
|
||||
|
||||
.. _Mandrill: http://mandrill.com
|
||||
.. _MailChimp: http://mailchimp.com
|
||||
.. _requests: http://docs.python-requests.org
|
||||
.. _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
|
||||
.. _render_to_string: https://docs.djangoproject.com/en/dev/ref/templates/api/#the-render-to-string-shortcut
|
||||
.. _messages/send API: https://mandrillapp.com/api/docs/messages.html#method=send
|
||||
.. _messages/send-template API: https://mandrillapp.com/api/docs/messages.html#method=send-template
|
||||
|
||||
See the `full documentation <https://djrill.readthedocs.org/en/latest/>`_
|
||||
for more features and options.
|
||||
|
||||
@@ -4,8 +4,7 @@ from django.utils.text import capfirst
|
||||
|
||||
from djrill.exceptions import MandrillAPIError, NotSupportedByMandrillError
|
||||
|
||||
VERSION = (0, 3, 1)
|
||||
__version__ = '.'.join([str(x) for x in VERSION])
|
||||
from ._version import *
|
||||
|
||||
# This backend was developed against this API endpoint.
|
||||
# You can override in settings.py, if desired.
|
||||
|
||||
3
djrill/_version.py
Normal file
3
djrill/_version.py
Normal file
@@ -0,0 +1,3 @@
|
||||
VERSION = (0, 3, 9)
|
||||
__version__ = '.'.join([str(x) for x in VERSION])
|
||||
__minor_version__ = '.'.join([str(x) for x in VERSION[:2]]) # Sphinx's X.Y "version"
|
||||
153
docs/Makefile
Normal file
153
docs/Makefile
Normal file
@@ -0,0 +1,153 @@
|
||||
# Makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
PAPER =
|
||||
BUILDDIR = _build
|
||||
|
||||
# Internal variables.
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
# the i18n builder cannot share the environment and doctrees with the others
|
||||
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
|
||||
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
|
||||
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " html to make standalone HTML files"
|
||||
@echo " dirhtml to make HTML files named index.html in directories"
|
||||
@echo " singlehtml to make a single large HTML file"
|
||||
@echo " pickle to make pickle files"
|
||||
@echo " json to make JSON files"
|
||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
||||
@echo " qthelp to make HTML files and a qthelp project"
|
||||
@echo " devhelp to make HTML files and a Devhelp project"
|
||||
@echo " epub to make an epub"
|
||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||
@echo " latexpdf to make LaTeX files and run them through pdflatex"
|
||||
@echo " text to make text files"
|
||||
@echo " man to make manual pages"
|
||||
@echo " texinfo to make Texinfo files"
|
||||
@echo " info to make Texinfo files and run them through makeinfo"
|
||||
@echo " gettext to make PO message catalogs"
|
||||
@echo " changes to make an overview of all changed/added/deprecated items"
|
||||
@echo " linkcheck to check all external links for integrity"
|
||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
||||
|
||||
clean:
|
||||
-rm -rf $(BUILDDIR)/*
|
||||
|
||||
html:
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
|
||||
dirhtml:
|
||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
||||
|
||||
singlehtml:
|
||||
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
|
||||
|
||||
pickle:
|
||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
||||
@echo
|
||||
@echo "Build finished; now you can process the pickle files."
|
||||
|
||||
json:
|
||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
||||
@echo
|
||||
@echo "Build finished; now you can process the JSON files."
|
||||
|
||||
htmlhelp:
|
||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||
".hhp project file in $(BUILDDIR)/htmlhelp."
|
||||
|
||||
qthelp:
|
||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
||||
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
|
||||
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Djrill.qhcp"
|
||||
@echo "To view the help file:"
|
||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Djrill.qhc"
|
||||
|
||||
devhelp:
|
||||
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
|
||||
@echo
|
||||
@echo "Build finished."
|
||||
@echo "To view the help file:"
|
||||
@echo "# mkdir -p $$HOME/.local/share/devhelp/Djrill"
|
||||
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Djrill"
|
||||
@echo "# devhelp"
|
||||
|
||||
epub:
|
||||
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
|
||||
@echo
|
||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
||||
|
||||
latex:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo
|
||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
||||
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
||||
"(use \`make latexpdf' here to do that automatically)."
|
||||
|
||||
latexpdf:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through pdflatex..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
text:
|
||||
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
||||
@echo
|
||||
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
||||
|
||||
man:
|
||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
||||
@echo
|
||||
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
||||
|
||||
texinfo:
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo
|
||||
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
|
||||
@echo "Run \`make' in that directory to run these through makeinfo" \
|
||||
"(use \`make info' here to do that automatically)."
|
||||
|
||||
info:
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo "Running Texinfo files through makeinfo..."
|
||||
make -C $(BUILDDIR)/texinfo info
|
||||
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
|
||||
|
||||
gettext:
|
||||
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
|
||||
@echo
|
||||
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
|
||||
|
||||
changes:
|
||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
||||
@echo
|
||||
@echo "The overview file is in $(BUILDDIR)/changes."
|
||||
|
||||
linkcheck:
|
||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
||||
@echo
|
||||
@echo "Link check complete; look for any errors in the above output " \
|
||||
"or in $(BUILDDIR)/linkcheck/output.txt."
|
||||
|
||||
doctest:
|
||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
||||
@echo "Testing of doctests in the sources finished, look at the " \
|
||||
"results in $(BUILDDIR)/doctest/output.txt."
|
||||
282
docs/conf.py
Normal file
282
docs/conf.py
Normal file
@@ -0,0 +1,282 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Djrill documentation build configuration file, created by
|
||||
# sphinx-quickstart on Sat Mar 2 13:07:34 2013.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
import sys, os
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
sys.path.insert(0, os.path.abspath('..'))
|
||||
|
||||
# define __version__ and __minor_version__ from ../djrill/_version.py,
|
||||
# but without importing from djrill (which would make docs dependent on Django, etc.)
|
||||
with open("../djrill/_version.py") as f:
|
||||
code = compile(f.read(), "../djrill/_version.py", 'exec')
|
||||
exec(code)
|
||||
|
||||
# -- General configuration -----------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions = ['sphinx.ext.intersphinx']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'Djrill'
|
||||
# noinspection PyShadowingBuiltins
|
||||
copyright = u'2013, Djrill contributors (see AUTHORS.txt)'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = __minor_version__
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = __version__
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ['_build']
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all documents.
|
||||
default_role = "py:obj"
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
|
||||
|
||||
# -- Options for HTML output ---------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = 'default'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
#html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
#html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = None
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'Djrilldoc'
|
||||
|
||||
|
||||
# -- Options for LaTeX output --------------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#'preamble': '',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass [howto/manual]).
|
||||
latex_documents = [
|
||||
('index', 'Djrill.tex', u'Djrill Documentation',
|
||||
u'Djrill contributors (see AUTHORS.txt)', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
#latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output --------------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('index', 'djrill', u'Djrill Documentation',
|
||||
[u'Djrill contributors (see AUTHORS.txt)'], 1)
|
||||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#man_show_urls = False
|
||||
|
||||
|
||||
# -- Options for Texinfo output ------------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
('index', 'Djrill', u'Djrill Documentation',
|
||||
u'Djrill contributors (see AUTHORS.txt)', 'Djrill', 'Mandrill integration for Django.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#texinfo_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#texinfo_domain_indices = True
|
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||
#texinfo_show_urls = 'footnote'
|
||||
|
||||
|
||||
# -- Options for Intersphinx ------------------------------------------------
|
||||
|
||||
intersphinx_mapping = {
|
||||
'python': ('http://docs.python.org/2.7', None),
|
||||
'django': ('http://docs.djangoproject.com/en/dev/', 'http://docs.djangoproject.com/en/dev/_objects/'),
|
||||
'requests': ('http://docs.python-requests.org/en/latest/', None),
|
||||
}
|
||||
|
||||
|
||||
def setup(app):
|
||||
# Django-specific roles, from https://github.com/django/django/blob/master/docs/_ext/djangodocs.py:
|
||||
app.add_crossref_type(
|
||||
directivename = "setting",
|
||||
rolename = "setting",
|
||||
indextemplate = "pair: %s; setting",
|
||||
)
|
||||
app.add_crossref_type(
|
||||
directivename = "templatetag",
|
||||
rolename = "ttag",
|
||||
indextemplate = "pair: %s; template tag"
|
||||
)
|
||||
app.add_crossref_type(
|
||||
directivename = "templatefilter",
|
||||
rolename = "tfilter",
|
||||
indextemplate = "pair: %s; template filter"
|
||||
)
|
||||
app.add_crossref_type(
|
||||
directivename = "fieldlookup",
|
||||
rolename = "lookup",
|
||||
indextemplate = "pair: %s; field lookup type",
|
||||
)
|
||||
54
docs/contributing.rst
Normal file
54
docs/contributing.rst
Normal file
@@ -0,0 +1,54 @@
|
||||
Contributing
|
||||
============
|
||||
|
||||
Djrill is maintained by its users. Your contributions are encouraged!
|
||||
|
||||
The `Djrill source code`_ is on github. See `AUTHORS.txt`_ for a list
|
||||
of some of the people who have helped improve Djrill.
|
||||
|
||||
.. _Djrill source code: https://github.com/brack3t/Djrill:
|
||||
.. _AUTHORS.txt: https://github.com/brack3t/Djrill/blob/master/AUTHORS.txt
|
||||
|
||||
|
||||
Bugs
|
||||
----
|
||||
|
||||
You can report problems or request features in
|
||||
`Djrill's github issue tracker <https://github.com/brack3t/Djrill/issues>`_.
|
||||
|
||||
|
||||
Pull Requests
|
||||
-------------
|
||||
|
||||
Pull requests are always welcome to fix bugs and improve support for Mandrill and Django features.
|
||||
|
||||
* Please include test cases.
|
||||
* We try to follow the `Django coding style`_ (basically, PEP 8 with longer lines OK).
|
||||
* By submitting a pull request, you're agreeing to release your changes under under
|
||||
the same BSD license as the rest of this project.
|
||||
|
||||
.. _Django coding style: https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/coding-style/
|
||||
|
||||
|
||||
Testing
|
||||
-------
|
||||
|
||||
Djrill is `tested on Travis <https://travis-ci.org/brack3t/Djrill>`_ against:
|
||||
|
||||
* Django 1.3 on Python 2.6 and 2.7
|
||||
* Django 1.4 on Python 2.6 and 2.7
|
||||
* Django 1.5 on Python 2.7 and 3.2
|
||||
|
||||
The included tests verify that Djrill constructs the expected Mandrill API
|
||||
calls, without actually calling Mandrill or sending any email. So the tests
|
||||
don't require a Mandrill API key, but they *do* require
|
||||
`mock <http://www.voidspace.org.uk/python/mock/index.html>`_ (``pip install mock``).
|
||||
|
||||
To run the tests, either::
|
||||
|
||||
python -Wall setup.py test
|
||||
|
||||
or::
|
||||
|
||||
python -Wall runtests.py
|
||||
|
||||
25
docs/history.rst
Normal file
25
docs/history.rst
Normal file
@@ -0,0 +1,25 @@
|
||||
Release Notes
|
||||
=============
|
||||
|
||||
Version 0.3.0:
|
||||
|
||||
* :ref:`Attachments <sending-attachments>` are now supported
|
||||
* :ref:`Mandrill templates <mandrill-templates>` are now supported
|
||||
* A bcc address is now passed to Mandrill as bcc, rather than being lumped in
|
||||
with the "to" recipients. Multiple bcc recipients will now raise an exception,
|
||||
as Mandrill only allows one.
|
||||
* Python 3 support (with Django 1.5)
|
||||
* Exceptions should be more useful:
|
||||
:exc:`djrill.NotSupportedByMandrillError` replaces generic ValueError;
|
||||
:exc:`djrill.MandrillAPIError` replaces DjrillBackendHTTPError, and is now
|
||||
derived from requests.HTTPError.
|
||||
(New exceptions are backwards compatible with old ones for existing code.)
|
||||
|
||||
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``.)
|
||||
|
||||
45
docs/index.rst
Normal file
45
docs/index.rst
Normal file
@@ -0,0 +1,45 @@
|
||||
.. Djrill documentation master file, created by
|
||||
sphinx-quickstart on Sat Mar 2 13:07:34 2013.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
.. Incorporate the shared-intro section from the root README:
|
||||
|
||||
.. include:: ../README.rst
|
||||
:start-after: _shared-intro:
|
||||
:end-before: END shared-intro
|
||||
|
||||
.. Eliminate the README's Travis build status indicator.
|
||||
(Is there some way we could link to Travis status for the
|
||||
specific |VERSION| of the app being documented here???)
|
||||
|
||||
.. |buildstatus| replace:: \
|
||||
|
||||
|
||||
.. _toc:
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
quickstart
|
||||
installation
|
||||
usage/sending_mail
|
||||
usage/templates
|
||||
usage/multiple_backends
|
||||
contributing
|
||||
history
|
||||
|
||||
|
||||
Thanks
|
||||
------
|
||||
|
||||
Thanks to the MailChimp team for asking us to build this nifty little app, and to all of Djrill's
|
||||
:doc:`contributors <contributing>`. Also thanks to James Socol on Github for his django-adminplus_
|
||||
library that got us off on the right foot for the custom admin views.
|
||||
Oh, and, of course, Kenneth Reitz for the awesome requests_ library.
|
||||
|
||||
.. _requests: http://docs.python-requests.org
|
||||
.. _django-adminplus: https://github.com/jsocol/django-adminplus
|
||||
61
docs/installation.rst
Normal file
61
docs/installation.rst
Normal file
@@ -0,0 +1,61 @@
|
||||
Installation
|
||||
============
|
||||
|
||||
It's easiest to install Djrill from `PyPI <https://pypi.python.org/pypi/djrill>`_:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ pip install djrill
|
||||
|
||||
If you decide to install Djrill some other way, you'll also need to install its
|
||||
one dependency (other than Django, of course): the `requests <http://docs.python-requests.org>`_
|
||||
library from Kenneth Reitz.
|
||||
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
In your project's :file:`settings.py`:
|
||||
|
||||
1. Add :mod:`djrill` to your :setting:`INSTALLED_APPS`::
|
||||
|
||||
INSTALLED_APPS = (
|
||||
...
|
||||
"djrill"
|
||||
)
|
||||
|
||||
2. Add the following line, substituting your own :setting:`MANDRILL_API_KEY`::
|
||||
|
||||
MANDRILL_API_KEY = "brack3t-is-awesome"
|
||||
|
||||
3. Override your existing :setting:`EMAIL_BACKEND` with the following line::
|
||||
|
||||
EMAIL_BACKEND = "djrill.mail.backends.djrill.DjrillBackend"
|
||||
|
||||
|
||||
Admin (Optional)
|
||||
----------------
|
||||
|
||||
Djrill includes an optional Django admin interface, which allows you to:
|
||||
|
||||
* Check the status of your Mandrill API connection
|
||||
* See stats on email senders, tags and urls
|
||||
|
||||
If you want to enable the Djrill admin interface, edit your base :file:`urls.py`:
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 4,6
|
||||
|
||||
...
|
||||
from django.contrib import admin
|
||||
|
||||
from djrill import DjrillAdminSite
|
||||
|
||||
admin.site = DjrillAdminSite()
|
||||
admin.autodiscover()
|
||||
...
|
||||
|
||||
urlpatterns = patterns('',
|
||||
...
|
||||
url(r'^admin/', include(admin.site.urls)),
|
||||
)
|
||||
190
docs/make.bat
Normal file
190
docs/make.bat
Normal file
@@ -0,0 +1,190 @@
|
||||
@ECHO OFF
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
if "%SPHINXBUILD%" == "" (
|
||||
set SPHINXBUILD=sphinx-build
|
||||
)
|
||||
set BUILDDIR=_build
|
||||
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
|
||||
set I18NSPHINXOPTS=%SPHINXOPTS% .
|
||||
if NOT "%PAPER%" == "" (
|
||||
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
|
||||
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
|
||||
)
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
if "%1" == "help" (
|
||||
:help
|
||||
echo.Please use `make ^<target^>` where ^<target^> is one of
|
||||
echo. html to make standalone HTML files
|
||||
echo. dirhtml to make HTML files named index.html in directories
|
||||
echo. singlehtml to make a single large HTML file
|
||||
echo. pickle to make pickle files
|
||||
echo. json to make JSON files
|
||||
echo. htmlhelp to make HTML files and a HTML help project
|
||||
echo. qthelp to make HTML files and a qthelp project
|
||||
echo. devhelp to make HTML files and a Devhelp project
|
||||
echo. epub to make an epub
|
||||
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
|
||||
echo. text to make text files
|
||||
echo. man to make manual pages
|
||||
echo. texinfo to make Texinfo files
|
||||
echo. gettext to make PO message catalogs
|
||||
echo. changes to make an overview over all changed/added/deprecated items
|
||||
echo. linkcheck to check all external links for integrity
|
||||
echo. doctest to run all doctests embedded in the documentation if enabled
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "clean" (
|
||||
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
|
||||
del /q /s %BUILDDIR%\*
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "html" (
|
||||
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "dirhtml" (
|
||||
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "singlehtml" (
|
||||
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "pickle" (
|
||||
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can process the pickle files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "json" (
|
||||
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can process the JSON files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "htmlhelp" (
|
||||
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can run HTML Help Workshop with the ^
|
||||
.hhp project file in %BUILDDIR%/htmlhelp.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "qthelp" (
|
||||
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can run "qcollectiongenerator" with the ^
|
||||
.qhcp project file in %BUILDDIR%/qthelp, like this:
|
||||
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Djrill.qhcp
|
||||
echo.To view the help file:
|
||||
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Djrill.ghc
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "devhelp" (
|
||||
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "epub" (
|
||||
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The epub file is in %BUILDDIR%/epub.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latex" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "text" (
|
||||
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The text files are in %BUILDDIR%/text.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "man" (
|
||||
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The manual pages are in %BUILDDIR%/man.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "texinfo" (
|
||||
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "gettext" (
|
||||
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "changes" (
|
||||
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.The overview file is in %BUILDDIR%/changes.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "linkcheck" (
|
||||
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Link check complete; look for any errors in the above output ^
|
||||
or in %BUILDDIR%/linkcheck/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "doctest" (
|
||||
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Testing of doctests in the sources finished, look at the ^
|
||||
results in %BUILDDIR%/doctest/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
:end
|
||||
9
docs/quickstart.rst
Normal file
9
docs/quickstart.rst
Normal file
@@ -0,0 +1,9 @@
|
||||
Djrill 1-2-3
|
||||
============
|
||||
|
||||
.. Quickstart is maintained in README.rst at the source root.
|
||||
(Docs can include from the readme; the readme can't include anything.)
|
||||
|
||||
.. include:: ../README.rst
|
||||
:start-after: _quickstart:
|
||||
:end-before: END quickstart
|
||||
32
docs/usage/multiple_backends.rst
Normal file
32
docs/usage/multiple_backends.rst
Normal file
@@ -0,0 +1,32 @@
|
||||
.. _multiple-backends:
|
||||
|
||||
Mixing Email Backends
|
||||
=====================
|
||||
|
||||
Since you are replacing Django's global :setting:`EMAIL_BACKEND`, by default
|
||||
Djrill will handle all outgoing mail, sending everything through Mandrill.
|
||||
|
||||
You can use Django mail's optional :func:`connection <django.core.mail.get_connection>`
|
||||
argument to send some mail through Mandrill and others through a different system.
|
||||
|
||||
This could be useful, for example, to deliver customer emails with Mandrill,
|
||||
but send admin emails directly through an SMTP server:
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 8,10
|
||||
|
||||
from django.core.mail import send_mail, get_connection
|
||||
|
||||
# send_mail connection defaults to the settings EMAIL_BACKEND, which
|
||||
# we've set to DjrillBackend. This will be sent using Mandrill:
|
||||
send_mail("Thanks", "We sent your order", "sales@example.com", ["customer@example.com"])
|
||||
|
||||
# Get a connection to an SMTP backend, and send using that instead:
|
||||
smtp_backend = get_connection('django.core.mail.backends.smtp.EmailBackend')
|
||||
send_mail("Uh-Oh", "Need your attention", "admin@example.com", ["alert@example.com"],
|
||||
connection=smtp_backend)
|
||||
|
||||
You can supply a different connection to Django's
|
||||
:func:`~django.core.mail.send_mail` and :func:`~django.core.mail.send_mass_mail` helpers,
|
||||
and in the constructor for an
|
||||
:class:`~django.core.mail.EmailMessage` or :class:`~django.core.mail.EmailMultiAlternatives`.
|
||||
225
docs/usage/sending_mail.rst
Normal file
225
docs/usage/sending_mail.rst
Normal file
@@ -0,0 +1,225 @@
|
||||
Sending Mail
|
||||
============
|
||||
|
||||
Djrill handles **all** outgoing email sent through Django's standard
|
||||
:mod:`django.core.mail` package, including :func:`~django.core.mail.send_mail`,
|
||||
:func:`~django.core.mail.send_mass_mail`, the :class:`~django.core.mail.EmailMessage` class,
|
||||
and even :func:`~django.core.mail.mail_admins`.
|
||||
|
||||
If you'd like to selectively send only some messages through Mandrill,
|
||||
there is a way to :ref:`use multiple email backends <multiple-backends>`.
|
||||
|
||||
|
||||
.. _django-send-support:
|
||||
|
||||
Django Email Support
|
||||
--------------------
|
||||
|
||||
Djrill supports most of the functionality of Django's :class:`~django.core.mail.EmailMessage`
|
||||
and :class:`~django.core.mail.EmailMultiAlternatives` classes.
|
||||
|
||||
Some notes and limitations:
|
||||
|
||||
**Display Names**
|
||||
All email addresses (from, to, cc) can be simple
|
||||
("email\@example.com") or can include a display name
|
||||
("Real Name <email\@example.com>").
|
||||
|
||||
**From Address**
|
||||
The ``from_email`` must be in one of the approved sending
|
||||
domains in your Mandrill account, or Mandrill will refuse to send the message.
|
||||
|
||||
**CC Recipients**
|
||||
Djrill treats all "cc" recipients as if they were
|
||||
additional "to" addresses. (Mandrill does not distinguish "cc" from "to".)
|
||||
|
||||
.. note::
|
||||
|
||||
By default, Mandrill hides all recipients from each other. If you want the
|
||||
headers to list everyone who was sent the message, you'll also need to set the
|
||||
Mandrill option :attr:`preserve_recipients` to `!True`
|
||||
|
||||
**BCC Recipients**
|
||||
Mandrill does not permit more than one "bcc" address.
|
||||
Djrill raises :exc:`~djrill.NotSupportedByMandrillError` if you attempt to send a
|
||||
message with multiple bcc's.
|
||||
|
||||
(Mandrill's bcc option seems intended primarily
|
||||
for logging. To send a single message to multiple recipients without exposing
|
||||
their email addresses to each other, simply include them all in the "to" list
|
||||
and leave Mandrill's :attr:`preserve_recipients` set to `!False`.)
|
||||
|
||||
.. versionadded:: 0.3
|
||||
Previously "bcc" was treated as "cc"
|
||||
|
||||
|
||||
.. _sending-html:
|
||||
|
||||
**HTML/Alternative Parts**
|
||||
To include an HTML version of a message, use
|
||||
:meth:`~django.core.mail.EmailMultiAlternatives.attach_alternative`:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from django.core.mail import EmailMultiAlternatives
|
||||
|
||||
msg = EmailMultiAlternatives("Subject", "text body",
|
||||
"from@example.com", ["to@example.com"])
|
||||
msg.attach_alternative("<html>html body</html>", "text/html")
|
||||
|
||||
Djrill allows a maximum of one
|
||||
:meth:`~django.core.mail.EmailMultiAlternatives.attach_alternative`
|
||||
on a message, and it must be ``mimetype="text/html"``.
|
||||
Otherwise, Djrill will raise :exc:`~djrill.NotSupportedByMandrillError` when you
|
||||
attempt to send the message. (Mandrill doesn't support sending multiple html
|
||||
alternative parts, or any non-html alternatives.)
|
||||
|
||||
|
||||
.. _sending-attachments:
|
||||
|
||||
**Attachments**
|
||||
Djrill will send a message's attachments. (Note that Mandrill may impose limits
|
||||
on size and type of attachments.)
|
||||
|
||||
Also, if an image attachment has a Content-ID header, Djrill will tell Mandrill
|
||||
to treat that as an embedded image rather than an ordinary attachment.
|
||||
(For an example, see :meth:`~DjrillBackendTests.test_embedded_images`
|
||||
in :file:`tests/test_mandrill_send.py`.)
|
||||
|
||||
.. versionadded:: 0.3
|
||||
Attachments
|
||||
|
||||
.. versionchanged:: 0.4
|
||||
Special handling for embedded images
|
||||
|
||||
**Headers**
|
||||
Djrill accepts additional headers, but only ``Reply-To`` and
|
||||
``X-*`` (since that is all that Mandrill accepts). Any other extra headers
|
||||
will raise :exc:`~djrill.NotSupportedByMandrillError` when you attempt to send the
|
||||
message.
|
||||
|
||||
|
||||
.. _mandrill-send-support:
|
||||
|
||||
Mandrill-Specific Options
|
||||
-------------------------
|
||||
|
||||
Most of the options from the Mandrill
|
||||
`messages/send API <https://mandrillapp.com/api/docs/messages.html#method=send>`_
|
||||
`message` struct can be set directly on an :class:`~django.core.mail.EmailMessage`
|
||||
(or subclass) object:
|
||||
|
||||
.. attribute:: track_opens
|
||||
|
||||
``Boolean``: whether Mandrill should enable open-tracking for this message.
|
||||
Default from your Mandrill account settings. ::
|
||||
|
||||
message.track_opens = True
|
||||
|
||||
.. attribute:: track_clicks
|
||||
|
||||
``Boolean``: whether Mandrill should enable click-tracking for this message.
|
||||
Default from your Mandrill account settings.
|
||||
|
||||
.. note::
|
||||
|
||||
Mandrill has an option to track clicks in HTML email but not plaintext, but
|
||||
it's *only* available in your Mandrill account settings. If you want to use that
|
||||
option, set it at Mandrill, and *don't* set the ``track_clicks`` attribute here.
|
||||
|
||||
.. attribute:: auto_text
|
||||
|
||||
``Boolean``: whether Mandrill should automatically generate a text body from the HTML.
|
||||
Default from your Mandrill account settings.
|
||||
|
||||
.. attribute:: url_strip_qs
|
||||
|
||||
``Boolean``: whether Mandrill should ignore any query parameters when aggregating
|
||||
URL tracking data. Default from your Mandrill account settings.
|
||||
|
||||
.. attribute:: preserve_recipients
|
||||
|
||||
``Boolean``: whether Mandrill should include all recipients in the "to" message header.
|
||||
Default from your Mandrill account settings.
|
||||
|
||||
.. attribute:: global_merge_vars
|
||||
|
||||
``dict``: merge variables to use for all recipients (most useful with :ref:`mandrill-templates`). ::
|
||||
|
||||
message.global_merge_vars = {'company': "ACME", 'offer': "10% off"}
|
||||
|
||||
.. attribute:: recipient_merge_vars
|
||||
|
||||
``dict``: per-recipient merge variables (most useful with :ref:`mandrill-templates`). The keys
|
||||
in the dict are the recipient email addresses, and the values are dicts of merge vars for
|
||||
each recipient::
|
||||
|
||||
message.recipient_merge_vars = {
|
||||
'wiley@example.com': {'offer': "15% off anvils"},
|
||||
'rr@example.com': {'offer': "instant tunnel paint"}
|
||||
}
|
||||
|
||||
.. attribute:: tags
|
||||
|
||||
``list`` of ``str``: tags to apply to the message, for filtering reports in the Mandrill
|
||||
dashboard. (Note that Mandrill prohibits tags longer than 50 characters or starting with
|
||||
underscores.) ::
|
||||
|
||||
message.tags = ["Order Confirmation", "Test Variant A"]
|
||||
|
||||
.. attribute:: google_analytics_domains
|
||||
|
||||
``list`` of ``str``: domain names for links where Mandrill should add Google Analytics
|
||||
tracking parameters. ::
|
||||
|
||||
message.google_analytics_domains = ["example.com"]
|
||||
|
||||
.. attribute:: google_analytics_campaign
|
||||
|
||||
``str`` or ``list`` of ``str``: the utm_campaign tracking parameter to attach to links
|
||||
when adding Google Analytics tracking. (Mandrill defaults to the message's from_email as
|
||||
the campaign name.)
|
||||
|
||||
.. attribute:: metadata
|
||||
|
||||
``dict``: metadata values Mandrill should store with the message for later search and
|
||||
retrieval. ::
|
||||
|
||||
message.metadata = {'customer': customer.id, 'order': order.reference_number}
|
||||
|
||||
.. attribute:: recipient_metadata
|
||||
|
||||
``dict``: per-recipient metadata values. Keys are the recipient email addresses,
|
||||
and values are dicts of metadata for each recipient (similar to
|
||||
:attr:`recipient_merge_vars`)
|
||||
|
||||
|
||||
These Mandrill-specific properties work with *any*
|
||||
:class:`~django.core.mail.EmailMessage`-derived object, so you can use them with
|
||||
many other apps that add Django mail functionality.
|
||||
|
||||
If you have questions about the python syntax for any of these properties,
|
||||
see :class:`DjrillMandrillFeatureTests` in :file:`tests/test_mandrill_send.py` for examples.
|
||||
|
||||
|
||||
.. _djrill-exceptions:
|
||||
|
||||
Exceptions
|
||||
----------
|
||||
|
||||
.. versionadded:: 0.3
|
||||
Djrill-specific exceptions
|
||||
|
||||
.. exception:: djrill.NotSupportedByMandrillError
|
||||
|
||||
If the email tries to use features that aren't supported by Mandrill, the send
|
||||
call will raise a :exc:`~!djrill.NotSupportedByMandrillError` exception (a subclass
|
||||
of :exc:`ValueError`).
|
||||
|
||||
|
||||
.. exception:: djrill.MandrillAPIError
|
||||
|
||||
If the Mandrill API fails or returns an error response, the send call will
|
||||
raise a :exc:`~!djrill.MandrillAPIError` exception (a subclass of :exc:`requests.HTTPError`).
|
||||
The exception's :attr:`status_code` and :attr:`response` attributes may
|
||||
help explain what went wrong.
|
||||
70
docs/usage/templates.rst
Normal file
70
docs/usage/templates.rst
Normal file
@@ -0,0 +1,70 @@
|
||||
Sending Template Mail
|
||||
=====================
|
||||
|
||||
.. _mandrill-templates:
|
||||
|
||||
Mandrill Templates
|
||||
------------------
|
||||
|
||||
.. versionadded:: 0.3
|
||||
Mandrill template support
|
||||
|
||||
To use a *Mandrill* (MailChimp) template stored in your Mandrill account,
|
||||
set a :attr:`template_name` and (optionally) :attr:`template_content`
|
||||
on your :class:`~django.core.mail.EmailMessage` object::
|
||||
|
||||
from django.core.mail import EmailMessage
|
||||
|
||||
msg = EmailMessage(subject="Shipped!", from_email="store@example.com",
|
||||
to=["customer@example.com", "accounting@example.com"])
|
||||
msg.template_name = "SHIPPING_NOTICE" # A Mandrill template name
|
||||
msg.template_content = { # Content blocks to fill in
|
||||
'TRACKING_BLOCK': "<a href='.../*|TRACKINGNO|*'>track it</a>"
|
||||
}
|
||||
msg.global_merge_vars = { # Merge tags in your template
|
||||
'ORDERNO': "12345", 'TRACKINGNO': "1Z987"
|
||||
}
|
||||
msg.merge_vars = { # Per-recipient merge tags
|
||||
'accounting@example.com': {'NAME': "Pat"},
|
||||
'customer@example.com': {'NAME': "Kim"}
|
||||
}
|
||||
msg.send()
|
||||
|
||||
If :attr:`template_name` is set, Djrill will use Mandrill's
|
||||
`messages/send-template API <https://mandrillapp.com/api/docs/messages.html#method=send-template>`_,
|
||||
and will ignore any `body` text set on the `EmailMessage`.
|
||||
|
||||
All of Djrill's other :ref:`Mandrill-specific options <mandrill-send-support>`
|
||||
can be used with templates.
|
||||
|
||||
|
||||
.. _django-templates:
|
||||
|
||||
Django Templates
|
||||
----------------
|
||||
|
||||
To compose email using *Django* templates, you can use Django's
|
||||
:func:`~django.template.loaders.django.template.loader.render_to_string`
|
||||
template shortcut to build the body and html.
|
||||
|
||||
Example that builds an email from the templates ``message_subject.txt``,
|
||||
``message_body.txt`` and ``message_body.html``::
|
||||
|
||||
from django.core.mail import EmailMultiAlternatives
|
||||
from django.template import Context
|
||||
from django.template.loader import render_to_string
|
||||
|
||||
template_data = {
|
||||
'ORDERNO': "12345", 'TRACKINGNO': "1Z987"
|
||||
}
|
||||
|
||||
plaintext_context = Context(autoescape=False) # HTML escaping not appropriate in plaintext
|
||||
subject = render_to_string("message_subject.txt", template_data, plaintext_context)
|
||||
text_body = render_to_string("message_body.txt", template_data, plaintext_context)
|
||||
html_body = render_to_string("message_body.html", template_data)
|
||||
|
||||
msg = EmailMessage(subject=subject, from_email="store@example.com",
|
||||
to=["customer@example.com"], body=text_body)
|
||||
msg.attach_alternative(html_body, "text/html")
|
||||
msg.send()
|
||||
|
||||
29
setup.py
29
setup.py
@@ -1,14 +1,31 @@
|
||||
from setuptools import setup
|
||||
import re
|
||||
|
||||
with open('LICENSE') as file:
|
||||
license_text = file.read()
|
||||
with open('README.rst') as file:
|
||||
long_description = file.read()
|
||||
# define __version__ and __minor_version__ from djrill/_version.py,
|
||||
# but without importing from djrill (which would break setup)
|
||||
with open("djrill/_version.py") as f:
|
||||
code = compile(f.read(), "djrill/_version.py", 'exec')
|
||||
exec(code)
|
||||
|
||||
|
||||
def long_description_from_readme(rst):
|
||||
# Patch up some rest substitution variables (references only - not definitions):
|
||||
rst = re.sub(r'(?<!\.\. )\|release\|', __version__, rst)
|
||||
rst = re.sub(r'(?<!\.\. )\|version\|', __minor_version__, rst)
|
||||
rst = re.sub(r'(?<!\.\. )\|buildstatus\|', "", rst) # hide latest-code Travis status indicator
|
||||
rst = re.sub(r'(djrill\.readthedocs\.org/\w+)/latest',
|
||||
r'\1/' + __version__, rst) # freeze docs link to this version
|
||||
return rst
|
||||
|
||||
with open('LICENSE') as f:
|
||||
license_text = f.read()
|
||||
with open('README.rst') as f:
|
||||
long_description = long_description_from_readme(f.read())
|
||||
|
||||
setup(
|
||||
name="djrill",
|
||||
version="0.3.1",
|
||||
description='Django email backend for Mandrill.',
|
||||
version=__version__,
|
||||
description='Mandrill transactional email for Django',
|
||||
keywords="django, mailchimp, mandrill, email, email backend",
|
||||
author="Kenneth Love <kenneth@brack3t.com>, Chris Jones <chris@brack3t.com>",
|
||||
author_email="kenneth@brack3t.com",
|
||||
|
||||
Reference in New Issue
Block a user