mirror of
https://github.com/pacnpal/django-anymail.git
synced 2025-12-20 03:41:05 -05:00
Reformat code with automated tools
Apply standardized code style
This commit is contained in:
@@ -2,9 +2,8 @@ import warnings
|
||||
from datetime import datetime
|
||||
|
||||
from ..exceptions import AnymailRequestsAPIError, AnymailWarning
|
||||
from ..message import AnymailRecipientStatus, ANYMAIL_STATUSES
|
||||
from ..utils import last, combine, get_anymail_setting
|
||||
|
||||
from ..message import ANYMAIL_STATUSES, AnymailRecipientStatus
|
||||
from ..utils import combine, get_anymail_setting, last
|
||||
from .base_requests import AnymailRequestsBackend, RequestsPayload
|
||||
|
||||
|
||||
@@ -18,9 +17,15 @@ class EmailBackend(AnymailRequestsBackend):
|
||||
def __init__(self, **kwargs):
|
||||
"""Init options from Django settings"""
|
||||
esp_name = self.esp_name
|
||||
self.api_key = get_anymail_setting('api_key', esp_name=esp_name, kwargs=kwargs, allow_bare=True)
|
||||
api_url = get_anymail_setting('api_url', esp_name=esp_name, kwargs=kwargs,
|
||||
default="https://mandrillapp.com/api/1.0")
|
||||
self.api_key = get_anymail_setting(
|
||||
"api_key", esp_name=esp_name, kwargs=kwargs, allow_bare=True
|
||||
)
|
||||
api_url = get_anymail_setting(
|
||||
"api_url",
|
||||
esp_name=esp_name,
|
||||
kwargs=kwargs,
|
||||
default="https://mandrillapp.com/api/1.0",
|
||||
)
|
||||
if not api_url.endswith("/"):
|
||||
api_url += "/"
|
||||
super().__init__(api_url, **kwargs)
|
||||
@@ -32,18 +37,26 @@ class EmailBackend(AnymailRequestsBackend):
|
||||
parsed_response = self.deserialize_json_response(response, payload, message)
|
||||
recipient_status = {}
|
||||
try:
|
||||
# Mandrill returns a list of { email, status, _id, reject_reason } for each recipient
|
||||
# Mandrill returns a list of { email, status, _id, reject_reason }
|
||||
# for each recipient
|
||||
for item in parsed_response:
|
||||
email = item['email']
|
||||
status = item['status']
|
||||
email = item["email"]
|
||||
status = item["status"]
|
||||
if status not in ANYMAIL_STATUSES:
|
||||
status = 'unknown'
|
||||
message_id = item.get('_id', None) # can be missing for invalid/rejected recipients
|
||||
recipient_status[email] = AnymailRecipientStatus(message_id=message_id, status=status)
|
||||
status = "unknown"
|
||||
# "_id" can be missing for invalid/rejected recipients:
|
||||
message_id = item.get("_id", None)
|
||||
recipient_status[email] = AnymailRecipientStatus(
|
||||
message_id=message_id, status=status
|
||||
)
|
||||
except (KeyError, TypeError) as err:
|
||||
raise AnymailRequestsAPIError("Invalid Mandrill API response format",
|
||||
email_message=message, payload=payload, response=response,
|
||||
backend=self) from err
|
||||
raise AnymailRequestsAPIError(
|
||||
"Invalid Mandrill API response format",
|
||||
email_message=message,
|
||||
payload=payload,
|
||||
response=response,
|
||||
backend=self,
|
||||
) from err
|
||||
return recipient_status
|
||||
|
||||
|
||||
@@ -60,19 +73,18 @@ def encode_date_for_mandrill(dt):
|
||||
dt = dt.replace(microsecond=0)
|
||||
if dt.utcoffset() is not None:
|
||||
dt = (dt - dt.utcoffset()).replace(tzinfo=None)
|
||||
return dt.isoformat(' ')
|
||||
return dt.isoformat(" ")
|
||||
else:
|
||||
return dt
|
||||
|
||||
|
||||
class MandrillPayload(RequestsPayload):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.esp_extra = {} # late-bound in serialize_data
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def get_api_endpoint(self):
|
||||
if 'template_name' in self.data:
|
||||
if "template_name" in self.data:
|
||||
return "messages/send-template.json"
|
||||
else:
|
||||
return "messages/send.json"
|
||||
@@ -81,7 +93,7 @@ class MandrillPayload(RequestsPayload):
|
||||
self.process_esp_extra()
|
||||
if self.is_batch():
|
||||
# hide recipients from each other
|
||||
self.data['message']['preserve_recipients'] = False
|
||||
self.data["message"]["preserve_recipients"] = False
|
||||
return self.serialize_json(self.data)
|
||||
|
||||
#
|
||||
@@ -96,7 +108,9 @@ class MandrillPayload(RequestsPayload):
|
||||
|
||||
def set_from_email(self, email):
|
||||
if getattr(self.message, "use_template_from", False):
|
||||
self.deprecation_warning('message.use_template_from', 'message.from_email = None')
|
||||
self.deprecation_warning(
|
||||
"message.use_template_from", "message.from_email = None"
|
||||
)
|
||||
else:
|
||||
self.data["message"]["from_email"] = email.addr_spec
|
||||
if email.display_name:
|
||||
@@ -112,7 +126,9 @@ class MandrillPayload(RequestsPayload):
|
||||
|
||||
def set_subject(self, subject):
|
||||
if getattr(self.message, "use_template_subject", False):
|
||||
self.deprecation_warning('message.use_template_subject', 'message.subject = None')
|
||||
self.deprecation_warning(
|
||||
"message.use_template_subject", "message.subject = None"
|
||||
)
|
||||
else:
|
||||
self.data["message"]["subject"] = subject
|
||||
|
||||
@@ -129,7 +145,8 @@ class MandrillPayload(RequestsPayload):
|
||||
|
||||
def set_html_body(self, body):
|
||||
if "html" in self.data["message"]:
|
||||
# second html body could show up through multiple alternatives, or html body + alternative
|
||||
# second html body could show up through multiple alternatives,
|
||||
# or html body + alternative
|
||||
self.unsupported_feature("multiple html parts")
|
||||
self.data["message"]["html"] = body
|
||||
|
||||
@@ -140,11 +157,13 @@ class MandrillPayload(RequestsPayload):
|
||||
else:
|
||||
field = "attachments"
|
||||
name = attachment.name or ""
|
||||
self.data["message"].setdefault(field, []).append({
|
||||
"type": attachment.mimetype,
|
||||
"name": name,
|
||||
"content": attachment.b64content
|
||||
})
|
||||
self.data["message"].setdefault(field, []).append(
|
||||
{
|
||||
"type": attachment.mimetype,
|
||||
"name": name,
|
||||
"content": attachment.b64content,
|
||||
}
|
||||
)
|
||||
|
||||
def set_envelope_sender(self, email):
|
||||
# Only the domain is used
|
||||
@@ -170,22 +189,28 @@ class MandrillPayload(RequestsPayload):
|
||||
self.data.setdefault("template_content", []) # Mandrill requires something here
|
||||
|
||||
def set_merge_data(self, merge_data):
|
||||
self.data['message']['merge_vars'] = [
|
||||
{'rcpt': rcpt, 'vars': [{'name': key, 'content': rcpt_data[key]}
|
||||
for key in sorted(rcpt_data.keys())]} # sort for testing reproducibility
|
||||
self.data["message"]["merge_vars"] = [
|
||||
{
|
||||
"rcpt": rcpt,
|
||||
"vars": [
|
||||
# sort for testing reproducibility:
|
||||
{"name": key, "content": rcpt_data[key]}
|
||||
for key in sorted(rcpt_data.keys())
|
||||
],
|
||||
}
|
||||
for rcpt, rcpt_data in merge_data.items()
|
||||
]
|
||||
|
||||
def set_merge_global_data(self, merge_global_data):
|
||||
self.data['message']['global_merge_vars'] = [
|
||||
{'name': var, 'content': value}
|
||||
for var, value in merge_global_data.items()
|
||||
self.data["message"]["global_merge_vars"] = [
|
||||
{"name": var, "content": value} for var, value in merge_global_data.items()
|
||||
]
|
||||
|
||||
def set_merge_metadata(self, merge_metadata):
|
||||
# recipient_metadata format is similar to, but not quite the same as, merge_vars:
|
||||
self.data['message']['recipient_metadata'] = [
|
||||
{'rcpt': rcpt, 'values': rcpt_data}
|
||||
# recipient_metadata format is similar to, but not quite the same as,
|
||||
# merge_vars:
|
||||
self.data["message"]["recipient_metadata"] = [
|
||||
{"rcpt": rcpt, "values": rcpt_data}
|
||||
for rcpt, rcpt_data in merge_metadata.items()
|
||||
]
|
||||
|
||||
@@ -198,33 +223,40 @@ class MandrillPayload(RequestsPayload):
|
||||
esp_extra = self.esp_extra
|
||||
# Convert pythonic template_content dict to Mandrill name/content list
|
||||
try:
|
||||
template_content = esp_extra['template_content']
|
||||
template_content = esp_extra["template_content"]
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
if hasattr(template_content, 'items'): # if it's dict-like
|
||||
# if it's dict-like:
|
||||
if hasattr(template_content, "items"):
|
||||
if esp_extra is self.esp_extra:
|
||||
esp_extra = self.esp_extra.copy() # don't modify caller's value
|
||||
esp_extra['template_content'] = [
|
||||
{'name': var, 'content': value}
|
||||
for var, value in template_content.items()]
|
||||
# don't modify caller's value
|
||||
esp_extra = self.esp_extra.copy()
|
||||
esp_extra["template_content"] = [
|
||||
{"name": var, "content": value}
|
||||
for var, value in template_content.items()
|
||||
]
|
||||
# Convert pythonic recipient_metadata dict to Mandrill rcpt/values list
|
||||
try:
|
||||
recipient_metadata = esp_extra['message']['recipient_metadata']
|
||||
recipient_metadata = esp_extra["message"]["recipient_metadata"]
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
if hasattr(recipient_metadata, 'keys'): # if it's dict-like
|
||||
if esp_extra['message'] is self.esp_extra['message']:
|
||||
esp_extra['message'] = self.esp_extra['message'].copy() # don't modify caller's value
|
||||
# For testing reproducibility, we sort the recipients
|
||||
esp_extra['message']['recipient_metadata'] = [
|
||||
{'rcpt': rcpt, 'values': recipient_metadata[rcpt]}
|
||||
for rcpt in sorted(recipient_metadata.keys())]
|
||||
# Merge esp_extra with payload data: shallow merge within ['message'] and top-level keys
|
||||
self.data.update({k: v for k, v in esp_extra.items() if k != 'message'})
|
||||
# if it's dict-like:
|
||||
if hasattr(recipient_metadata, "keys"):
|
||||
if esp_extra["message"] is self.esp_extra["message"]:
|
||||
# don't modify caller's value:
|
||||
esp_extra["message"] = self.esp_extra["message"].copy()
|
||||
# For testing reproducibility, sort the recipients
|
||||
esp_extra["message"]["recipient_metadata"] = [
|
||||
{"rcpt": rcpt, "values": recipient_metadata[rcpt]}
|
||||
for rcpt in sorted(recipient_metadata.keys())
|
||||
]
|
||||
# Merge esp_extra with payload data: shallow merge within ['message']
|
||||
# and top-level keys
|
||||
self.data.update({k: v for k, v in esp_extra.items() if k != "message"})
|
||||
try:
|
||||
self.data['message'].update(esp_extra['message'])
|
||||
self.data["message"].update(esp_extra["message"])
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
@@ -245,69 +277,75 @@ class MandrillPayload(RequestsPayload):
|
||||
self.deprecation_warning(feature, replacement)
|
||||
|
||||
esp_message_attrs = (
|
||||
('async', last, None),
|
||||
('ip_pool', last, None),
|
||||
('from_name', last, None), # overrides display name parsed from from_email above
|
||||
('important', last, None),
|
||||
('auto_text', last, None),
|
||||
('auto_html', last, None),
|
||||
('inline_css', last, None),
|
||||
('url_strip_qs', last, None),
|
||||
('tracking_domain', last, None),
|
||||
('signing_domain', last, None),
|
||||
('return_path_domain', last, None),
|
||||
('merge_language', last, None),
|
||||
('preserve_recipients', last, None),
|
||||
('view_content_link', last, None),
|
||||
('subaccount', last, None),
|
||||
('google_analytics_domains', last, None),
|
||||
('google_analytics_campaign', last, None),
|
||||
('global_merge_vars', combine, None),
|
||||
('merge_vars', combine, None),
|
||||
('recipient_metadata', combine, None),
|
||||
('template_name', last, None),
|
||||
('template_content', combine, None),
|
||||
("async", last, None),
|
||||
("ip_pool", last, None),
|
||||
("from_name", last, None), # overrides display name parsed from from_email
|
||||
("important", last, None),
|
||||
("auto_text", last, None),
|
||||
("auto_html", last, None),
|
||||
("inline_css", last, None),
|
||||
("url_strip_qs", last, None),
|
||||
("tracking_domain", last, None),
|
||||
("signing_domain", last, None),
|
||||
("return_path_domain", last, None),
|
||||
("merge_language", last, None),
|
||||
("preserve_recipients", last, None),
|
||||
("view_content_link", last, None),
|
||||
("subaccount", last, None),
|
||||
("google_analytics_domains", last, None),
|
||||
("google_analytics_campaign", last, None),
|
||||
("global_merge_vars", combine, None),
|
||||
("merge_vars", combine, None),
|
||||
("recipient_metadata", combine, None),
|
||||
("template_name", last, None),
|
||||
("template_content", combine, None),
|
||||
)
|
||||
|
||||
def set_async(self, is_async):
|
||||
self.deprecated_to_esp_extra('async')
|
||||
self.esp_extra['async'] = is_async
|
||||
self.deprecated_to_esp_extra("async")
|
||||
self.esp_extra["async"] = is_async
|
||||
|
||||
def set_ip_pool(self, ip_pool):
|
||||
self.deprecated_to_esp_extra('ip_pool')
|
||||
self.esp_extra['ip_pool'] = ip_pool
|
||||
self.deprecated_to_esp_extra("ip_pool")
|
||||
self.esp_extra["ip_pool"] = ip_pool
|
||||
|
||||
def set_global_merge_vars(self, global_merge_vars):
|
||||
self.deprecation_warning('message.global_merge_vars', 'message.merge_global_data')
|
||||
self.deprecation_warning(
|
||||
"message.global_merge_vars", "message.merge_global_data"
|
||||
)
|
||||
self.set_merge_global_data(global_merge_vars)
|
||||
|
||||
def set_merge_vars(self, merge_vars):
|
||||
self.deprecation_warning('message.merge_vars', 'message.merge_data')
|
||||
self.deprecation_warning("message.merge_vars", "message.merge_data")
|
||||
self.set_merge_data(merge_vars)
|
||||
|
||||
def set_return_path_domain(self, domain):
|
||||
self.deprecation_warning('message.return_path_domain', 'message.envelope_sender')
|
||||
self.esp_extra.setdefault('message', {})['return_path_domain'] = domain
|
||||
self.deprecation_warning(
|
||||
"message.return_path_domain", "message.envelope_sender"
|
||||
)
|
||||
self.esp_extra.setdefault("message", {})["return_path_domain"] = domain
|
||||
|
||||
def set_template_name(self, template_name):
|
||||
self.deprecation_warning('message.template_name', 'message.template_id')
|
||||
self.deprecation_warning("message.template_name", "message.template_id")
|
||||
self.set_template_id(template_name)
|
||||
|
||||
def set_template_content(self, template_content):
|
||||
self.deprecated_to_esp_extra('template_content')
|
||||
self.esp_extra['template_content'] = template_content
|
||||
self.deprecated_to_esp_extra("template_content")
|
||||
self.esp_extra["template_content"] = template_content
|
||||
|
||||
def set_recipient_metadata(self, recipient_metadata):
|
||||
self.deprecated_to_esp_extra('recipient_metadata', in_message_dict=True)
|
||||
self.esp_extra.setdefault('message', {})['recipient_metadata'] = recipient_metadata
|
||||
self.deprecated_to_esp_extra("recipient_metadata", in_message_dict=True)
|
||||
self.esp_extra.setdefault("message", {})[
|
||||
"recipient_metadata"
|
||||
] = recipient_metadata
|
||||
|
||||
# Set up simple set_<attr> functions for any missing esp_message_attrs attrs
|
||||
# (avoids dozens of simple `self.data["message"][<attr>] = value` functions)
|
||||
|
||||
@classmethod
|
||||
def define_message_attr_setters(cls):
|
||||
for (attr, _, _) in cls.esp_message_attrs:
|
||||
setter_name = 'set_%s' % attr
|
||||
for attr, _, _ in cls.esp_message_attrs:
|
||||
setter_name = "set_%s" % attr
|
||||
try:
|
||||
getattr(cls, setter_name)
|
||||
except AttributeError:
|
||||
@@ -316,10 +354,12 @@ class MandrillPayload(RequestsPayload):
|
||||
|
||||
@staticmethod
|
||||
def make_setter(attr, setter_name):
|
||||
# sure wish we could use functools.partial to create instance methods (descriptors)
|
||||
# sure wish we could use functools.partial
|
||||
# to create instance methods (descriptors)
|
||||
def setter(self, value):
|
||||
self.deprecated_to_esp_extra(attr, in_message_dict=True)
|
||||
self.esp_extra.setdefault('message', {})[attr] = value
|
||||
self.esp_extra.setdefault("message", {})[attr] = value
|
||||
|
||||
setter.__name__ = setter_name
|
||||
return setter
|
||||
|
||||
|
||||
Reference in New Issue
Block a user