Ticket #1541: 1541_multipart_unified.diff

File 1541_multipart_unified.diff, 3.5 KB (added by sime <simon@…>, 8 years ago)

unified #1541 and #3366 - needs improvement to handle other mimetypes

  • django/core/mail.py

     
    44
    55from django.conf import settings
    66from email.MIMEText import MIMEText
     7from email.MIMEMultipart import MIMEMultipart
    78from email.Header import Header
    89from email.Utils import formatdate
    910from email import Charset
     
    6465            val = Header(val, settings.DEFAULT_CHARSET)
    6566        MIMEText.__setitem__(self, name, val)
    6667
     68class SafeMIMEMultipart(MIMEMultipart):
     69    def __setitem__(self, name, val):
     70        "Forbids multi-line headers, to prevent header injection."
     71        if '\n' in val or '\r' in val:
     72            raise BadHeaderError, "Header values can't contain newlines (got %r for header %r)" % (val, name)
     73        MIMEMultipart.__setitem__(self, name, val)
     74
    6775class SMTPConnection(object):
    6876    """
    6977    A wrapper that manages the SMTP network connection.
     
    154162    """
    155163    A container for email information.
    156164    """
    157     def __init__(self, subject='', body='', from_email=None, to=None, bcc=None, connection=None):
     165    def __init__(self, subject='', body='',
     166                 from_email=None, to=None, bcc=None,
     167                 attachments=None, body_html=None,
     168                 connection=None):
    158169        self.to = to or []
    159170        self.bcc = bcc or []
    160171        self.from_email = from_email or settings.DEFAULT_FROM_EMAIL
    161172        self.subject = subject
    162173        self.body = body
    163174        self.connection = connection
     175        self.attachments = attachments or []
     176        if body_html:
     177            self.attach(SafeMIMEText(body_html, 'html', settings.DEFAULT_CHARSET))
    164178
    165179    def get_connection(self, fail_silently=False):
    166180        if not self.connection:
    167181            self.connection = SMTPConnection(fail_silently=fail_silently)
    168182        return self.connection
    169183
     184    def attach(self, attachment):
     185        self.attachments += [attachment]
     186       
    170187    def message(self):
    171         msg = SafeMIMEText(self.body, 'plain', settings.DEFAULT_CHARSET)
     188        if self.attachments is not []:
     189            msg = SafeMIMEMultipart('alternative', settings.DEFAULT_CHARSET)
     190            for attachment in self.attachments:
     191                msg.attach(attachment)
     192        else:
     193            msg = SafeMIMEText(self.body, 'plain', settings.DEFAULT_CHARSET)
    172194        msg['Subject'] = self.subject
    173195        msg['From'] = self.from_email
    174196        msg['To'] = ', '.join(self.to)
     
    189211        """Send the email message."""
    190212        return self.get_connection(fail_silently).send_messages([self])
    191213
    192 def send_mail(subject, message, from_email, recipient_list, fail_silently=False, auth_user=None, auth_password=None):
     214def send_mail(subject, message, from_email, recipient_list, fail_silently=False,
     215              message_html=None, auth_user=None, auth_password=None):
    193216    """
    194217    Easy wrapper for sending a single message to a recipient list. All members
    195218    of the recipient list will see the other recipients in the 'To' field.
     
    202225    """
    203226    connection = SMTPConnection(username=auth_user, password=auth_password,
    204227                                 fail_silently=fail_silently)
    205     return EmailMessage(subject, message, from_email, recipient_list, connection=connection).send()
     228    return EmailMessage(subject, message, from_email, recipient_list,
     229                        body_html=message_html, connection=connection).send()
    206230
    207231def send_mass_mail(datatuple, fail_silently=False, auth_user=None, auth_password=None):
    208232    """
Back to Top