mirror of
https://github.com/pacnpal/django-anymail.git
synced 2025-12-20 03:41:05 -05:00
Docs: update tooling and outdated/broken content
* Update docs build config
* Specify Sphinx and theme versions in docs/requirements.txt
(tox had been using latest; RTD had pinned older versions)
* Update docs builds for Python 3 and recent Sphinx
* Remove obsolete sphinx-rtd-theme patches
* Add .readthedocs.yml
* Move some JS to async (now that Sphinx supports that)
* Fix version-alert.js for async loading
* Remove docs versionadded/changed info older than v3.0
* Fix broken GitHub issue links in changelog (never worked?)
* Add setup long_description_content_type
* Drop poorly maintained AUTHORS.txt
(just point to GitHub contributors page)
This commit is contained in:
@@ -1,20 +1,25 @@
|
||||
%(head_prefix)s
|
||||
<!--
|
||||
This approximates PyPI.org project page styling as of 8/2019
|
||||
(and relies on their compiled CSS that was available at that time).
|
||||
This approximates PyPI.org project page styling as of 8/2020,
|
||||
and loads their compiled CSS that was in use at that time.
|
||||
|
||||
Base template is ${SITE_PACKAGES}/docutils/writers/html5_polyglot/template.txt
|
||||
(Styling seems to change more often than basic page structure,
|
||||
so to update, it may be sufficient to copy in the current
|
||||
<link rel="stylesheet" ...> tags from any live package page.)
|
||||
|
||||
This extends the docutils base template found at
|
||||
${SITE_PACKAGES}/docutils/writers/html5_polyglot/template.txt
|
||||
-->
|
||||
|
||||
<base href="https://pypi.org/">
|
||||
%(head)s
|
||||
<!-- template (stylesheet) omitted -->
|
||||
|
||||
<link rel="stylesheet" href="/static/css/warehouse.a1809af1.css">
|
||||
<link rel="stylesheet" href="/static/css/fontawesome.4b73fd92.css">
|
||||
<link rel="stylesheet" href="/static/css/regular.19624371.css">
|
||||
<link rel="stylesheet" href="/static/css/solid.f478cfb1.css">
|
||||
<link rel="stylesheet" href="/static/css/brands.1ea560bf.css">
|
||||
<link rel="stylesheet" href="/static/css/warehouse-ltr.f2d4f304.css">
|
||||
<link rel="stylesheet" href="/static/css/fontawesome.6002a161.css">
|
||||
<link rel="stylesheet" href="/static/css/regular.98fbf39a.css">
|
||||
<link rel="stylesheet" href="/static/css/solid.c3b5f0b5.css">
|
||||
<link rel="stylesheet" href="/static/css/brands.2c303be1.css">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,400italic,600,600italic,700,700italic|Source+Code+Pro:500">
|
||||
<link rel="icon" href="/static/images/favicon.6a76275d.ico" type="image/x-icon">
|
||||
|
||||
@@ -22,16 +27,16 @@
|
||||
|
||||
<main id="#content">
|
||||
|
||||
<section class="banner">
|
||||
<div class="banner">
|
||||
<div class="package-header">
|
||||
<div class="package-header__left">
|
||||
%(body_pre_docinfo)s
|
||||
%(docinfo)s
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<section>
|
||||
<div>
|
||||
<div class="tabs-container">
|
||||
<div class="vertical-tabs">
|
||||
<div class="vertical-tabs__panel">
|
||||
@@ -45,7 +50,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
%(body_suffix)s
|
||||
|
||||
31
docs/_static/anymail-theme.css
vendored
31
docs/_static/anymail-theme.css
vendored
@@ -1,31 +1,9 @@
|
||||
/* Anymail modifications to sphinx-rtd-theme styles */
|
||||
|
||||
/* List item spacing: https://github.com/rtfd/sphinx_rtd_theme/issues/590 */
|
||||
/* Regression: https://github.com/rtfd/sphinx_rtd_theme/issues/705 */
|
||||
.rst-content .section ol li p:last-child,
|
||||
.rst-content .section ul li p:last-child {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
|
||||
/* Pygments shell/console prompt: */
|
||||
.highlight .gp {
|
||||
/* The RTD theme shows prompts the same color as other code.
|
||||
We want to distinguish them (like most Pygments themes do). */
|
||||
color: #d14;
|
||||
|
||||
/* Exclude prompt characters when copying from highlighted code. */
|
||||
user-select: none;
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
|
||||
|
||||
/* Sticky table first column (used for ESP feature matrix) */
|
||||
table.sticky-left td:first-of-type,
|
||||
table.sticky-left th:first-of-type {
|
||||
position: -webkit-sticky; /* Safari */
|
||||
position: sticky;
|
||||
left: 0;
|
||||
background-color: #fcfcfc; /* override transparent from .wy-table td */
|
||||
@@ -36,7 +14,6 @@ table.sticky-left th:first-of-type[colspan] > p {
|
||||
since those always wrap a rubric <p> (in the specific table that uses this),
|
||||
just make the <p> sticky within the <td>. */
|
||||
display: inline-block;
|
||||
position: -webkit-sticky; /* Safari */
|
||||
position: sticky;
|
||||
left: 17px; /* (.wy-table $table-padding-size) + (docutils border="1" in html) */
|
||||
}
|
||||
@@ -57,12 +34,12 @@ table.sticky-left th:first-of-type[colspan] > p {
|
||||
https://github.com/rtfd/sphinx_rtd_theme/issues/92
|
||||
*/
|
||||
.rst-content a code.xref {
|
||||
color: #2980B9;
|
||||
font-weight: inherit;
|
||||
color: inherit;
|
||||
/*font-weight: inherit;*/
|
||||
}
|
||||
.rst-content a:hover code.xref {
|
||||
color: #3091d1;
|
||||
color: inherit;
|
||||
}
|
||||
.rst-content a:visited code.xref {
|
||||
color: #9B59B6;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
6
docs/_static/version-alert.js
vendored
6
docs/_static/version-alert.js
vendored
@@ -27,4 +27,8 @@ function warnOnLatestVersion() {
|
||||
parent.insertBefore(warning, parent.firstChild);
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', warnOnLatestVersion);
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', warnOnLatestVersion);
|
||||
} else {
|
||||
warnOnLatestVersion();
|
||||
}
|
||||
|
||||
38
docs/conf.py
38
docs/conf.py
@@ -11,20 +11,25 @@
|
||||
|
||||
import os
|
||||
import sys
|
||||
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
|
||||
from pathlib import Path
|
||||
|
||||
ON_READTHEDOCS = os.environ.get('READTHEDOCS', None) == 'True'
|
||||
DOCS_PATH = Path(__file__).parent
|
||||
PROJECT_ROOT_PATH = DOCS_PATH.parent
|
||||
|
||||
# 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('..'))
|
||||
sys.path.insert(0, PROJECT_ROOT_PATH.resolve())
|
||||
|
||||
# define __version__ and __minor_version__ from ../anymail/_version.py,
|
||||
# but without importing from anymail (which would make docs dependent on Django, etc.)
|
||||
__version__ = "UNSET"
|
||||
__minor_version__ = "UNSET"
|
||||
with open("../anymail/_version.py") as f:
|
||||
code = compile(f.read(), "../anymail/_version.py", 'exec')
|
||||
exec(code)
|
||||
version_path = PROJECT_ROOT_PATH / "anymail/_version.py"
|
||||
code = compile(version_path.read_text(), version_path, 'exec')
|
||||
exec(code)
|
||||
|
||||
|
||||
# -- General configuration -----------------------------------------------------
|
||||
|
||||
@@ -50,7 +55,7 @@ master_doc = 'index'
|
||||
# General information about the project.
|
||||
project = 'Anymail'
|
||||
# noinspection PyShadowingBuiltins
|
||||
copyright = 'Anymail contributors (see AUTHORS.txt)'
|
||||
copyright = 'Anymail contributors'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
@@ -100,11 +105,11 @@ pygments_style = 'sphinx'
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
if not on_rtd: # only import and set the theme if we're building docs locally
|
||||
if not ON_READTHEDOCS: # only import and set the theme if we're building docs locally
|
||||
import sphinx_rtd_theme # this seems to come with sphinx; if not, pip install it
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
|
||||
# if on_rtd, readthedocs.org uses their theme by default (and specifying it here breaks them)
|
||||
# else readthedocs.org uses their theme by default (and specifying it here breaks them)
|
||||
|
||||
# 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
|
||||
@@ -202,7 +207,7 @@ latex_elements = {
|
||||
# (source start file, target name, title, author, documentclass [howto/manual]).
|
||||
latex_documents = [
|
||||
('index', 'Anymail.tex', 'Anymail Documentation',
|
||||
'Anymail contributors (see AUTHORS.txt)', 'manual'),
|
||||
'Anymail contributors', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
@@ -232,7 +237,7 @@ latex_documents = [
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('index', 'anymail', 'Anymail Documentation',
|
||||
['Anymail contributors (see AUTHORS.txt)'], 1)
|
||||
['Anymail contributors'], 1)
|
||||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
@@ -246,7 +251,7 @@ man_pages = [
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
('index', 'Anymail', 'Anymail Documentation',
|
||||
'Anymail contributors (see AUTHORS.txt)', 'Anymail', 'Multi-ESP transactional email for Django.',
|
||||
'Anymail contributors', 'Anymail', 'Multi-ESP transactional email for Django.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
@@ -275,10 +280,13 @@ intersphinx_mapping = {
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.add_stylesheet("anymail-theme.css")
|
||||
app.add_javascript("anymail-config.js")
|
||||
app.add_javascript("version-alert.js")
|
||||
app.add_javascript("https://unpkg.com/rate-the-docs")
|
||||
app.add_css_file("anymail-theme.css")
|
||||
# Inline <script> for anymail-config.js to avoid non-async JS load:
|
||||
# app.add_js_file("anymail-config.js")
|
||||
anymail_config_js = (DOCS_PATH / "_static/anymail-config.js").read_text()
|
||||
app.add_js_file(None, body=anymail_config_js)
|
||||
app.add_js_file("version-alert.js", **{"async": "async"})
|
||||
app.add_js_file("https://unpkg.com/rate-the-docs", **{"async": "async"})
|
||||
|
||||
# Django-specific roles, from https://github.com/django/django/blob/master/docs/_ext/djangodocs.py:
|
||||
app.add_crossref_type(
|
||||
|
||||
@@ -13,8 +13,6 @@ AWS SDK for Python, and includes sending, tracking, and inbound receiving capabi
|
||||
Depending on your needs, one of them may be more appropriate than Anymail.
|
||||
|
||||
|
||||
.. versionadded:: 2.1
|
||||
|
||||
.. _Amazon Simple Email Service: https://aws.amazon.com/ses/
|
||||
.. _Boto 3: https://boto3.readthedocs.io/en/stable/
|
||||
|
||||
|
||||
@@ -137,13 +137,6 @@ use Anymail's :attr:`~anymail.message.AnymailMessage.envelope_sender`
|
||||
message.envelope_sender = "anything@mail2.example.com" # the "anything@" is ignored
|
||||
|
||||
|
||||
.. versionchanged:: 2.0
|
||||
|
||||
Earlier Anymail versions looked for a special `sender_domain` key in the message's
|
||||
:attr:`~anymail.message.AnymailMessage.esp_extra` to override Mailgun's sender domain.
|
||||
This is still supported, but may be deprecated in a future release. Using
|
||||
:attr:`~anymail.message.AnymailMessage.envelope_sender` as shown above is now preferred.
|
||||
|
||||
.. _Mailgun sender domain:
|
||||
https://help.mailgun.com/hc/en-us/articles/202256730-How-do-I-pick-a-domain-name-for-my-Mailgun-account-
|
||||
|
||||
|
||||
@@ -5,8 +5,6 @@ Mailjet
|
||||
|
||||
Anymail integrates with the `Mailjet`_ email service, using their transactional `Send API`_ (v3).
|
||||
|
||||
.. versionadded:: 0.11
|
||||
|
||||
.. _mailjet-v31-api:
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -257,14 +257,6 @@ for each event in the batch.)
|
||||
https://mandrill.zendesk.com/hc/en-us/articles/205583197-Inbound-Email-Processing-Overview
|
||||
|
||||
|
||||
.. versionchanged:: 1.3
|
||||
Earlier Anymail releases used :samp:`.../anymail/mandrill/{tracking}/` as the tracking
|
||||
webhook url. With the addition of inbound handling, Anymail has dropped "tracking"
|
||||
from the recommended url for new installations. But the older url is still
|
||||
supported. Existing installations can continue to use it---and can even install it
|
||||
on a Mandrill *inbound* route to avoid issuing a new webhook key.
|
||||
|
||||
|
||||
.. _migrating-from-djrill:
|
||||
|
||||
Migrating from Djrill
|
||||
@@ -380,8 +372,6 @@ Changes to EmailMessage attributes
|
||||
instead. You'll need to pass a valid email address (not just a domain),
|
||||
but Anymail will use only the domain, and will ignore anything before the @.
|
||||
|
||||
.. versionchanged:: 2.0
|
||||
|
||||
**Other Mandrill-specific attributes**
|
||||
Djrill allowed nearly all Mandrill API parameters to be set
|
||||
as attributes directly on an EmailMessage. With Anymail, you
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
Receiving mail
|
||||
==============
|
||||
|
||||
.. versionadded:: 1.3
|
||||
|
||||
For ESPs that support receiving inbound email, Anymail offers normalized handling
|
||||
of inbound events.
|
||||
|
||||
@@ -168,7 +166,7 @@ Normalized inbound message
|
||||
:class:`~anymail.utils.EmailAddress` object, which makes it easier to access
|
||||
the parsed address fields:
|
||||
|
||||
.. code-block:: python
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> str(message.from_email) # the fully-formatted address
|
||||
'"Dr. Justin Customer, CPA" <jcustomer@example.com>'
|
||||
@@ -367,11 +365,6 @@ have these methods:
|
||||
The errors param is as in :meth:`~bytes.decode`. The default "replace" substitutes the
|
||||
Unicode "replacement character" for any illegal characters in the text.
|
||||
|
||||
.. versionchanged:: 2.1
|
||||
|
||||
Changed to use attachment's declared charset by default,
|
||||
and added errors option defaulting to replace.
|
||||
|
||||
.. method:: get_content_bytes()
|
||||
|
||||
Returns the raw content of the attachment as bytes. (This will automatically decode
|
||||
|
||||
@@ -282,20 +282,11 @@ This is actually implemented using HTTP basic authentication, and the string is
|
||||
technically a "username:password" format. But you should *not* use any real
|
||||
username or password for this shared secret.
|
||||
|
||||
.. versionchanged:: 1.4
|
||||
|
||||
The earlier WEBHOOK_AUTHORIZATION setting was renamed WEBHOOK_SECRET, so that
|
||||
Django error reporting sanitizes it. Support for the old name was dropped in
|
||||
Anymail 2.0, and if you have not yet updated your settings.py, all webhook calls
|
||||
will fail with a "missing or invalid basic auth" error.
|
||||
|
||||
|
||||
.. setting:: ANYMAIL_REQUESTS_TIMEOUT
|
||||
|
||||
.. rubric:: REQUESTS_TIMEOUT
|
||||
|
||||
.. versionadded:: 1.3
|
||||
|
||||
For Requests-based Anymail backends, the timeout value used for all API calls to your ESP.
|
||||
The default is 30 seconds. You can set to a single float, a 2-tuple of floats for
|
||||
separate connection and read timeouts, or `None` to disable timeouts (not recommended).
|
||||
|
||||
4
docs/requirements.txt
Normal file
4
docs/requirements.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
# (Pygments defaulted "python" to Python 2 before v2.5.0; it doesn't use semver)
|
||||
Pygments~=2.6.1
|
||||
sphinx~=3.1
|
||||
sphinx-rtd-theme~=0.5.0
|
||||
@@ -76,8 +76,6 @@ an :ref:`unsupported feature <unsupported-features>` error.
|
||||
|
||||
.. attribute:: envelope_sender
|
||||
|
||||
.. versionadded:: 2.0
|
||||
|
||||
Set this to a `str` email address that should be used as the message's
|
||||
envelope sender. If supported by your ESP, this will become the Return-Path
|
||||
in the recipient's mailbox.
|
||||
|
||||
@@ -145,10 +145,6 @@ has special handling for certain headers. Anymail replicates its behavior for co
|
||||
:class:`to <django.core.mail.EmailMessage>` list. Spoofing the :mailheader:`To` header like this
|
||||
is popular with spammers, and almost none of Anymail's supported ESPs allow it.
|
||||
|
||||
.. versionchanged:: 2.0
|
||||
|
||||
Improved header-handling compatibility with Django's SMTP EmailBackend.
|
||||
|
||||
|
||||
.. _unsupported-features:
|
||||
|
||||
|
||||
@@ -43,8 +43,6 @@ Exceptions
|
||||
|
||||
.. exception:: AnymailInvalidAddress
|
||||
|
||||
.. versionadded:: 0.7
|
||||
|
||||
The send call will raise a :exc:`!AnymailInvalidAddress` error if you
|
||||
attempt to send a message with invalidly-formatted email addresses in
|
||||
the :attr:`from_email` or recipient lists.
|
||||
|
||||
Reference in New Issue
Block a user