Plain is headed towards 1.0! Subscribe for development updates →

plain.mail

Everything you need to send email.

  1"""
  2Tools for sending email.
  3"""
  4
  5from plain.runtime import settings
  6from plain.utils.module_loading import import_string
  7
  8# Imported for backwards compatibility and for the sake
  9# of a cleaner namespace. These symbols used to be in
 10# django/core/mail.py before the introduction of email
 11# backends and the subsequent reorganization (See #10355)
 12from .message import (
 13    DEFAULT_ATTACHMENT_MIME_TYPE,
 14    BadHeaderError,
 15    EmailMessage,
 16    EmailMultiAlternatives,
 17    SafeMIMEMultipart,
 18    SafeMIMEText,
 19    TemplateEmail,
 20    forbid_multi_line_headers,
 21    make_msgid,
 22)
 23from .utils import DNS_NAME, CachedDnsName
 24
 25__all__ = [
 26    "CachedDnsName",
 27    "DNS_NAME",
 28    "EmailMessage",
 29    "EmailMultiAlternatives",
 30    "TemplateEmail",
 31    "SafeMIMEText",
 32    "SafeMIMEMultipart",
 33    "DEFAULT_ATTACHMENT_MIME_TYPE",
 34    "make_msgid",
 35    "BadHeaderError",
 36    "forbid_multi_line_headers",
 37    "get_connection",
 38    "send_mail",
 39    "send_mass_mail",
 40]
 41
 42
 43def get_connection(backend=None, fail_silently=False, **kwds):
 44    """Load an email backend and return an instance of it.
 45
 46    If backend is None (default), use settings.EMAIL_BACKEND.
 47
 48    Both fail_silently and other keyword arguments are used in the
 49    constructor of the backend.
 50    """
 51    klass = import_string(backend or settings.EMAIL_BACKEND)
 52    return klass(fail_silently=fail_silently, **kwds)
 53
 54
 55def send_mail(
 56    subject,
 57    message,
 58    from_email,
 59    recipient_list,
 60    fail_silently=False,
 61    auth_user=None,
 62    auth_password=None,
 63    connection=None,
 64    html_message=None,
 65):
 66    """
 67    Easy wrapper for sending a single message to a recipient list. All members
 68    of the recipient list will see the other recipients in the 'To' field.
 69
 70    If from_email is None, use the EMAIL_DEFAULT_FROM setting.
 71    If auth_user is None, use the EMAIL_HOST_USER setting.
 72    If auth_password is None, use the EMAIL_HOST_PASSWORD setting.
 73
 74    Note: The API for this method is frozen. New code wanting to extend the
 75    functionality should use the EmailMessage class directly.
 76    """
 77    connection = connection or get_connection(
 78        username=auth_user,
 79        password=auth_password,
 80        fail_silently=fail_silently,
 81    )
 82    mail = EmailMultiAlternatives(
 83        subject, message, from_email, recipient_list, connection=connection
 84    )
 85    if html_message:
 86        mail.attach_alternative(html_message, "text/html")
 87
 88    return mail.send()
 89
 90
 91def send_mass_mail(
 92    datatuple, fail_silently=False, auth_user=None, auth_password=None, connection=None
 93):
 94    """
 95    Given a datatuple of (subject, message, from_email, recipient_list), send
 96    each message to each recipient list. Return the number of emails sent.
 97
 98    If from_email is None, use the EMAIL_DEFAULT_FROM setting.
 99    If auth_user and auth_password are set, use them to log in.
100    If auth_user is None, use the EMAIL_HOST_USER setting.
101    If auth_password is None, use the EMAIL_HOST_PASSWORD setting.
102
103    Note: The API for this method is frozen. New code wanting to extend the
104    functionality should use the EmailMessage class directly.
105    """
106    connection = connection or get_connection(
107        username=auth_user,
108        password=auth_password,
109        fail_silently=fail_silently,
110    )
111    messages = [
112        EmailMessage(subject, message, sender, recipient, connection=connection)
113        for subject, message, sender, recipient in datatuple
114    ]
115    return connection.send_messages(messages)