Django

Code

Ticket #3366: 3366.diff

File 3366.diff, 6.9 kB (added by Gary Wilson <gary.wilson@gmail.com>, 2 years ago)
  • django/core/mail.py

    old new  
    1 # Use this module for e-mailing. 
     1""" 
     2Tools for sending emails. 
     3""" 
    24 
    35from django.conf import settings 
    46from email.MIMEText import MIMEText 
     
    2224            val = Header(val, settings.DEFAULT_CHARSET) 
    2325        MIMEText.__setitem__(self, name, val) 
    2426 
    25 def send_mail(subject, message, from_email, recipient_list, fail_silently=False, auth_user=settings.EMAIL_HOST_USER, auth_password=settings.EMAIL_HOST_PASSWORD): 
    26     """ 
    27     Easy wrapper for sending a single message to a recipient list. All members 
    28     of the recipient list will see the other recipients in the 'To' field. 
    29     """ 
    30     return send_mass_mail([[subject, message, from_email, recipient_list]], fail_silently, auth_user, auth_password) 
    31  
    32 def send_mass_mail(datatuple, fail_silently=False, auth_user=settings.EMAIL_HOST_USER, auth_password=settings.EMAIL_HOST_PASSWORD): 
    33     """ 
    34     Given a datatuple of (subject, message, from_email, recipient_list), sends 
    35     each message to each recipient list. Returns the number of e-mails sent. 
    36  
    37     If from_email is None, the DEFAULT_FROM_EMAIL setting is used. 
    38     If auth_user and auth_password are set, they're used to log in. 
    39     """ 
    40     try: 
    41         server = smtplib.SMTP(settings.EMAIL_HOST, settings.EMAIL_PORT) 
    42         if auth_user and auth_password: 
    43             server.login(auth_user, auth_password) 
    44     except: 
    45         if fail_silently: 
    46             return 
    47         raise 
    48     num_sent = 0 
    49     for subject, message, from_email, recipient_list in datatuple: 
    50         if not recipient_list: 
    51             continue 
    52         from_email = from_email or settings.DEFAULT_FROM_EMAIL 
    53         msg = SafeMIMEText(message, 'plain', settings.DEFAULT_CHARSET) 
    54         msg['Subject'] = subject 
    55         msg['From'] = from_email 
    56         msg['To'] = ', '.join(recipient_list) 
     27class EmailConnection(object): 
     28    """An SMTP connection.""" 
     29 
     30    def __init__(self, host=settings.EMAIL_HOST, port=settings.EMAIL_PORT, 
     31                 username=settings.EMAIL_HOST_USER, 
     32                 password=settings.EMAIL_HOST_PASSWORD, fail_silently=False): 
     33        self.host = host 
     34        self.port = port 
     35        self.username = username 
     36        self.password = password 
     37        self.fail_silently = fail_silently 
     38        self.connection = None 
     39 
     40    def open(self): 
     41        """Open the connection to the email server.""" 
     42 
     43        # Nothing to do if the connection is already open. 
     44        if self.connection: 
     45            return 
     46        try: 
     47            self.connection = smtplib.SMTP(self.host, self.port) 
     48            if self.username and self.password: 
     49                self.connection.login(self.username, self.password) 
     50        except: 
     51            if self.fail_silently: 
     52                return 
     53            raise 
     54 
     55    def close(self): 
     56        """Close the connection to the email server.""" 
     57 
     58        # Python versions < 2.5 do not allow try...except...finally, 
     59        # so we nest a try...except in a try...finally here for backwards 
     60        # compatibility. 
     61        try: 
     62            try: 
     63                self.connection.quit() 
     64            except: 
     65                if self.fail_silently: 
     66                    return 
     67                raise 
     68        finally: 
     69            self.connection = None 
     70 
     71    def send_messages(self, email_messages): 
     72        """ 
     73        Send one or more EmailMessage objects and return the number of email 
     74        messages sent. 
     75        """ 
     76 
     77        if not email_messages: 
     78            return 
     79        self.open() 
     80        num_sent = 0 
     81        for message in email_messages: 
     82            sent = self._send(message) 
     83            if sent: 
     84                num_sent += 1 
     85        self.close() 
     86        return num_sent 
     87 
     88    def _send(self, email_message): 
     89        """A helper method that does the actual sending.""" 
     90 
     91        if not email_message.to: 
     92            return False 
     93        msg = SafeMIMEText(email_message.body, 'plain', 
     94                           settings.DEFAULT_CHARSET) 
     95        msg['Subject'] = email_message.subject 
     96        msg['From'] = email_message.from_email 
     97        msg['To'] = ', '.join(email_message.to) 
    5798        msg['Date'] = rfc822.formatdate() 
     99        msg['Message-ID'] = self._message_id() 
     100        try: 
     101            self.connection.sendmail(email_message.from_email, 
     102                                     email_message.to, msg.as_string()) 
     103        except: 
     104            if not self.fail_silently: 
     105                raise 
     106        return True 
     107 
     108    def _message_id(self): 
     109        """Generate a message ID.""" 
     110 
     111        # Python 2.3 doesn't have random.getrandbits(). 
    58112        try: 
    59113            random_bits = str(random.getrandbits(64)) 
    60         except AttributeError: # Python 2.3 doesn't have random.getrandbits(). 
     114        except AttributeError: 
    61115            random_bits = ''.join([random.choice('1234567890') for i in range(19)]) 
    62         msg['Message-ID'] = "<%d.%s@%s>" % (time.time(), random_bits, DNS_NAME) 
    63         try: 
    64             server.sendmail(from_email, recipient_list, msg.as_string()) 
    65             num_sent += 1 
    66         except: 
    67             if not fail_silently: 
    68                 raise 
    69     try: 
    70         server.quit() 
    71     except: 
    72         if fail_silently: 
    73             return 
    74         raise 
    75     return num_sent 
     116        return "<%d.%s@%s>" % (time.time(), random_bits, DNS_NAME) 
     117 
     118class EmailMessage(object): 
     119    """ 
     120    A container for email information. 
     121    """ 
     122 
     123    def __init__(self, to=None, from_email=settings.DEFAULT_FROM_EMAIL, 
     124                 subject="", body="", connection=None): 
     125        self.to = to or [] 
     126        self.from_email = from_email 
     127        self.subject = subject 
     128        self.body = body 
     129 
     130    def send(self, connection=None, fail_silently=False): 
     131        """Send the email message.""" 
     132 
     133        connection = connection or EmailConnection(fail_silently=fail_silently) 
     134        connection.send_messages([self]) 
    76135 
    77136def mail_admins(subject, message, fail_silently=False): 
    78137    "Sends a message to the admins, as defined by the ADMINS setting." 
    79     send_mail(settings.EMAIL_SUBJECT_PREFIX + subject, message, settings.SERVER_EMAIL, [a[1] for a in settings.ADMINS], fail_silently) 
     138 
     139    EmailMessage( 
     140        subject=settings.EMAIL_SUBJECT_PREFIX + subject, 
     141        body=message, 
     142        from_email=settings.SERVER_EMAIL, 
     143        to=[a[1] for a in settings.ADMINS], 
     144    ).send(fail_silently=fail_silently) 
    80145 
    81146def mail_managers(subject, message, fail_silently=False): 
    82147    "Sends a message to the managers, as defined by the MANAGERS setting." 
    83     send_mail(settings.EMAIL_SUBJECT_PREFIX + subject, message, settings.SERVER_EMAIL, [a[1] for a in settings.MANAGERS], fail_silently) 
     148 
     149    EmailMessage( 
     150        subject=settings.EMAIL_SUBJECT_PREFIX + subject, 
     151        body=message, 
     152        from_email=settings.SERVER_EMAIL, 
     153        to=[a[1] for a in settings.MANAGERS], 
     154    ).send(fail_silently=fail_silently)