Ticket #3366: 3366.2.diff

File 3366.2.diff, 8.2 KB (added by Gary Wilson <gary.wilson@…>, 13 years ago)

updated patch

  • django/core/mail.py

    === modified file 'django/core/mail.py'
     
    1 # Use this module for e-mailing.
     1"""
     2Tools for sending emails.
     3"""
    24
    35from django.conf import settings
    46from email.MIMEText import MIMEText
     
    3436            val = Header(val, settings.DEFAULT_CHARSET)
    3537        MIMEText.__setitem__(self, name, val)
    3638
     39class EmailConnection(object):
     40    """An SMTP connection."""
     41
     42    def __init__(self, host=None, port=None, username=None, password=None,
     43                 fail_silently=False):
     44        if host is None:
     45            self.host = settings.EMAIL_HOST
     46        if port is None:
     47            self.port = settings.EMAIL_PORT
     48        if username is None:
     49                self.username = settings.EMAIL_HOST_USER
     50        if password is None:
     51                self.password = settings.EMAIL_HOST_PASSWORD
     52        self.fail_silently = fail_silently
     53        self.connection = None
     54
     55    def open(self):
     56        """Open the connection to the email server."""
     57
     58        # Nothing to do if the connection is already open.
     59        if self.connection:
     60            return
     61        try:
     62            self.connection = smtplib.SMTP(self.host, self.port)
     63            if self.username and self.password:
     64                self.connection.login(self.username, self.password)
     65        except:
     66            if self.fail_silently:
     67                return
     68            raise
     69
     70    def close(self):
     71        """Close the connection to the email server."""
     72
     73        # Python versions < 2.5 do not allow try...except...finally,
     74        # so we nest a try...except in a try...finally here for backwards
     75        # compatibility.
     76        try:
     77            try:
     78                self.connection.quit()
     79            except:
     80                if self.fail_silently:
     81                    return
     82                raise
     83        finally:
     84            self.connection = None
     85
     86    def send_messages(self, email_messages):
     87        """
     88        Send one or more EmailMessage objects and return the number of email
     89        messages sent.
     90        """
     91
     92        if not email_messages:
     93            return
     94        self.open()
     95        num_sent = 0
     96        for message in email_messages:
     97            sent = self._send(message)
     98            if sent:
     99                num_sent += 1
     100        self.close()
     101        return num_sent
     102
     103    def _send(self, email_message):
     104        """A helper method that does the actual sending."""
     105
     106        if not email_message.to:
     107            return False
     108        msg = SafeMIMEText(email_message.body, 'plain',
     109                           settings.DEFAULT_CHARSET)
     110        msg['Subject'] = email_message.subject
     111        msg['From'] = email_message.from_email
     112        msg['To'] = ', '.join(email_message.to)
     113        msg['Date'] = formatdate()
     114        msg['Message-ID'] = self._message_id()
     115        try:
     116            self.connection.sendmail(email_message.from_email,
     117                                     email_message.to, msg.as_string())
     118        except:
     119            if not self.fail_silently:
     120                raise
     121        return True
     122
     123    def _message_id(self):
     124        """Generate a message ID."""
     125
     126        # Python 2.3 doesn't have random.getrandbits().
     127        try:
     128            random_bits = str(random.getrandbits(64))
     129        except AttributeError:
     130            random_bits = ''.join([random.choice('1234567890') for i in range(19)])
     131        return "<%d.%s@%s>" % (time.time(), random_bits, DNS_NAME)
     132
     133class EmailMessage(object):
     134    """
     135    A container for email information.
     136    """
     137
     138    def __init__(self, to=None, from_email=None, subject="", body="",
     139                 connection=None):
     140        self.to = to or []
     141        if from_email is None:
     142            self.from_email = settings.DEFAULT_FROM_EMAIL
     143        self.subject = subject
     144        self.body = body
     145
     146    def send(self, connection=None, fail_silently=False):
     147        """Send the email message."""
     148
     149        connection = connection or EmailConnection(fail_silently=fail_silently)
     150        return connection.send_messages([self])
     151
    37152def send_mail(subject, message, from_email, recipient_list, fail_silently=False, auth_user=None, auth_password=None):
    38153    """
    39154    Easy wrapper for sending a single message to a recipient list. All members
     
    42157    If auth_user is None, the EMAIL_HOST_USER setting is used.
    43158    If auth_password is None, the EMAIL_HOST_PASSWORD setting is used.
    44159    """
    45     if auth_user is None:
    46         auth_user = settings.EMAIL_HOST_USER
    47     if auth_password is None:
    48         auth_password = settings.EMAIL_HOST_PASSWORD
    49     return send_mass_mail([[subject, message, from_email, recipient_list]], fail_silently, auth_user, auth_password)
     160    connection = EmailConnection(username=auth_user, password=auth_password,
     161                                 fail_silently=fail_silently)
     162    return EmailMessage(
     163        subject=subject,
     164        body=message,
     165        from_email=from_email,
     166        to=recipient_list,
     167    ).send(connection=connection)
    50168
    51169def send_mass_mail(datatuple, fail_silently=False, auth_user=None, auth_password=None):
    52170    """
     
    58176    If auth_user is None, the EMAIL_HOST_USER setting is used.
    59177    If auth_password is None, the EMAIL_HOST_PASSWORD setting is used.
    60178    """
    61     if auth_user is None:
    62         auth_user = settings.EMAIL_HOST_USER
    63     if auth_password is None:
    64         auth_password = settings.EMAIL_HOST_PASSWORD
    65     try:
    66         server = smtplib.SMTP(settings.EMAIL_HOST, settings.EMAIL_PORT)
    67         if auth_user and auth_password:
    68             server.login(auth_user, auth_password)
    69     except:
    70         if fail_silently:
    71             return
    72         raise
    73     num_sent = 0
    74     for subject, message, from_email, recipient_list in datatuple:
    75         if not recipient_list:
    76             continue
    77         from_email = from_email or settings.DEFAULT_FROM_EMAIL
    78         msg = SafeMIMEText(message, 'plain', settings.DEFAULT_CHARSET)
    79         msg['Subject'] = subject
    80         msg['From'] = from_email
    81         msg['To'] = ', '.join(recipient_list)
    82         msg['Date'] = formatdate()
    83         try:
    84             random_bits = str(random.getrandbits(64))
    85         except AttributeError: # Python 2.3 doesn't have random.getrandbits().
    86             random_bits = ''.join([random.choice('1234567890') for i in range(19)])
    87         msg['Message-ID'] = "<%d.%s@%s>" % (time.time(), random_bits, DNS_NAME)
    88         try:
    89             server.sendmail(from_email, recipient_list, msg.as_string())
    90             num_sent += 1
    91         except:
    92             if not fail_silently:
    93                 raise
    94     try:
    95         server.quit()
    96     except:
    97         if fail_silently:
    98             return
    99         raise
    100     return num_sent
     179    connection = EmailConnection(username=auth_user, password=auth_password,
     180                                 fail_silently=fail_silently)
     181    messages = [EmailMessage(
     182                   subject=subject,
     183                   body=message,
     184                   from_email=from_email,
     185                   to=recipient_list,
     186                   ) for subject, message, from_email, recipient_list \
     187                     in datatuple]
     188    return connection.send_messages(messages)
    101189
    102190def mail_admins(subject, message, fail_silently=False):
    103191    "Sends a message to the admins, as defined by the ADMINS setting."
    104     send_mail(settings.EMAIL_SUBJECT_PREFIX + subject, message, settings.SERVER_EMAIL, [a[1] for a in settings.ADMINS], fail_silently)
     192
     193    EmailMessage(
     194        subject=settings.EMAIL_SUBJECT_PREFIX + subject,
     195        body=message,
     196        from_email=settings.SERVER_EMAIL,
     197        to=[a[1] for a in settings.ADMINS],
     198    ).send(fail_silently=fail_silently)
    105199
    106200def mail_managers(subject, message, fail_silently=False):
    107201    "Sends a message to the managers, as defined by the MANAGERS setting."
    108     send_mail(settings.EMAIL_SUBJECT_PREFIX + subject, message, settings.SERVER_EMAIL, [a[1] for a in settings.MANAGERS], fail_silently)
     202
     203    EmailMessage(
     204        subject=settings.EMAIL_SUBJECT_PREFIX + subject,
     205        body=message,
     206        from_email=settings.SERVER_EMAIL,
     207        to=[a[1] for a in settings.MANAGERS],
     208    ).send(fail_silently=fail_silently)
Back to Top