Commit Graph

24 Commits

Author SHA1 Message Date
Mike Edmunds
85cec5e9dc Drop Python 2 and Django 1.11 support
Minimum supported versions are now Django 2.0, Python 3.5.

This touches a lot of code, to:
* Remove obsolete portability code and workarounds
  (six, backports of email parsers, test utils, etc.)
* Use Python 3 syntax (class defs, raise ... from, etc.)
* Correct inheritance for mixin classes
* Fix outdated docs content and links
* Suppress Python 3 "unclosed SSLSocket" ResourceWarnings
  that are beyond our control (in integration tests due to boto3, 
  python-sparkpost)
2020-08-01 14:53:10 -07:00
Mike Edmunds
75d7671056 Add merge_metadata for other ESPs
Support merge_metadata in Mailgun, Mailjet, Mandrill, Postmark, 
SparkPost, and Test backends. (SendGrid covered in earlier PR.)

Also:
* Add `merge_metadata` to AnymailMessage, AnymailMessageMixin
* Add `is_batch()` logic to BasePayload, for consistent handling
* Docs

Note: Mailjet implementation switches *all* batch sending from their 
"Recipients" field to to the "Messages" array bulk sending option.
This allows an independent payload for each batch recipient.
In addition to supporting merge_metadata, this also removes the
prior limitation on mixing Cc/Bcc with merge_data.

Closes #141.
2019-02-23 13:32:28 -08:00
medmunds
07fbeac6bd Feature: Add envelope_sender
New EmailMessage attribute `envelope_sender` controls ESP's sender,
sending domain, or return path where supported:

* Mailgun: overrides SENDER_DOMAIN on individual message
  (domain portion only)
* Mailjet: becomes `Sender` API param
* Mandrill: becomes `return_path_domain` API param
  (domain portion only)
* SparkPost: becomes `return_path` API param
* Other ESPs: not believed to be supported

Also support undocumented Django SMTP backend behavior, where envelope
sender is given by `message.from_email` when
`message.extra_headers["From"]` is set. Fixes #91.
2018-02-26 18:42:19 -08:00
medmunds
ec0ee336a2 Cleanup: Avoid Python 3.7 deprecation warning on 'async' keyword
Fixes #92
2018-02-26 10:24:08 -08:00
medmunds
9acf6501b5 Utils: Finish ParsedEmail --> EmailAddress conversion
Within an EmailAddress (previously ParsedEmail object), properties
now match Python 3.6 email.headerregistry.Address naming:

* .email --> .addr_spec
* .name --> .display_name
* .localpart --> .username

(Completes work started in 386668908423d1d4eade90cf7a21a546a1e96514;
this updates remaining uses of old names and removes them.)
2017-10-27 17:53:13 -07:00
medmunds
a67e174f38 Remove deprecated <ESP>Backend names
(Deprecated with warnings since v0.8)
2017-09-08 16:42:28 -07:00
medmunds
8bdc67939a Flake8 clean 2017-04-16 11:43:13 -07:00
medmunds
56d2b53c2b Use specific ESP name in error messages.
Change  (e.g.,) "ESP API response 400"
to "Mailgun API response 400".
2017-01-22 10:21:19 -08:00
medmunds
79288603fb Rename EmailBackends for Django consistency
* **Future breaking change:**
  Rename all Anymail backends to just `EmailBackend`,
  matching Django's naming convention.
  (E.g., switch to "anymail.backends.mailgun.EmailBackend"
  rather than "anymail.backends.mailgun.MailgunBackend".)

  The old names still work, but will issue a DeprecationWarning
  and will be removed in some future release.

  (Apologies for this change; the old naming convention was
  a holdover from Djrill, and I wanted consistency with
  other Django EmailBackends before hitting 1.0.)

Fixes #49.
2017-01-20 15:47:37 -08:00
medmunds
a0b92bee7a Mandrill: support esp_extra
* Merge esp_extra with Mandrill send payload
* Handle pythonic forms of `recipient_metadata`
  and `template_content` in esp_extra
* DeprecationWarning for Mandrill EmailMessage
  attributes inherited from Djrill
2016-05-11 15:08:57 -07:00
medmunds
75730e8219 Add ESP templates, batch send and merge
* message.template_id to use ESP stored templates
* message.merge_data and merge_global_data
  to supply per-recipient/global merge variables
  (with or without an ESP stored template)
* When using per-recipient merge_data, tell ESP to use
  batch send: individual message per "to" address.
  (Mailgun does this automatically; SendGrid requires
  using a different "to" field; Mandrill requires
  `preserve_recipients=False`; Postmark doesn't
  support *this type* of batch sending with merge data.)
* Allow message.from_email=None (must be set after
  init) and message.subject=None to suppress those
  fields in API calls (for ESPs that allow "From" and
  "Subject" in their template definitions).

Mailgun:
* Emulate merge_global_data by copying to
  recipient-variables for each recipient.

SendGrid:
* Add delimiters to merge field names via
  esp_extra['merge_field_format'] or
  ANYMAIL_SENDGRID_MERGE_FIELD_FORMAT setting.

Mandrill:
* Remove Djrill versions of these features;
  update migration notes.

Closes #5.
2016-05-06 12:27:11 -07:00
medmunds
df881fdb75 Allow kwargs overrides for (nearly) all settings
* Update utils.get_anymail_setting to support
  kwargs override of django.conf.settings values
* Use the updated version everywhere
* Switch from ImproperlyConfigured to
  AnymailConfigurationError exception
  (anticipates feature_wehooks change)

Closes #12
2016-04-29 14:34:34 -07:00
medmunds
b407e9f452 Preserve filename of inline attachments
For ESPs that support both content-id and filename,
don't drop the filename.
2016-03-11 10:07:13 -08:00
medmunds
d1d41badc8 Add Mailgun backend 2016-03-07 18:07:48 -08:00
medmunds
3a93648481 Normalize ESP response and recipient status 2016-03-05 17:22:27 -08:00
medmunds
518e6e86f8 Normalize text/html alternative handling in BasePayload 2016-03-05 15:16:49 -08:00
medmunds
a6c0eb5974 Normalize send_at date/datetime/timestamp in BasePayload.
Interpret dates and naive datetimes as Django's
current_timezone (rather than UTC like Djrill did).
This should be more likely to behave as expected
when running with a non-UTC TIME_ZONE setting.
2016-03-05 11:23:18 -08:00
medmunds
0a5bca1426 Make requests optional for backends that don't need it
(Prep for installing backends as package extras)

* Extract AnymailRequestsBackend and RequestsPayload
  to base_requests.py
* Don't define/require requests exceptions when requests
  not available
2016-03-04 17:39:43 -08:00
medmunds
38729df93c Uniform settings handling
For MANDRILL_API_KEY (e.g.,), look for these settings:
* ANYMAIL = { 'MANDRILL_API_KEY': '...' }
* ANYMAIL_MANDRILL_API_KEY = "..."
* MANDRILL_API_KEY = "..."

(the "bare" third version is used only for settings that
might be reasonably shared with other apps, like api keys)
2016-03-04 17:02:43 -08:00
medmunds
3b414a9619 Move all the payload construction into Payload classes 2016-03-04 15:55:19 -08:00
medmunds
dbf57d8a33 Move common message attrs into base backend 2016-03-03 16:52:10 -08:00
medmunds
ef971489cd Start factoring out common backend functionality 2016-02-29 11:52:35 -08:00
medmunds
1c7fe8a759 Rename exceptions
* Change Djrill -> Mandrill in exception names
* Don't re-export at package level
  (import from anymail.exceptions, not from anymail)
2016-02-27 12:03:45 -08:00
medmunds
921dd5d0d6 Fork from Djrill and rename to "anymail" 2016-02-27 11:16:04 -08:00