Ticket #1541: mail_attachment_as_str.diff

File mail_attachment_as_str.diff, 5.3 KB (added by mssnlayam@…, 8 years ago)

Similar to mail_attachment.diff, but accepts str objects instread of file objects

  • django/core/mail.py

     
    11# Use this module for e-mailing.
    22
    33from django.conf import settings
     4from email import Encoders
     5from email.MIMEBase import MIMEBase
     6from email.MIMEMultipart import MIMEMultipart
    47from email.MIMEText import MIMEText
    58from email.Header import Header
    69import smtplib, rfc822
     
    2225            val = Header(val, settings.DEFAULT_CHARSET)
    2326        MIMEText.__setitem__(self, name, val)
    2427
    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):
     28class SafeMIMEMultipart(MIMEMultipart):
     29    def __setitem__(self, name, val):
     30        "Forbids multi-line headers, to prevent header injection."
     31        if '\n' in val or '\r' in val:
     32            raise BadHeaderError, "Header values can't contain newlines (got %r for header %r)" % (val, name)
     33        if name == "Subject":
     34            val = Header(val, settings.DEFAULT_CHARSET)
     35        MIMEMultipart.__setitem__(self, name, val)
     36
     37    def attachFile(self, filename, content, mimetype):
     38        maintype, subtype = mimetype.split('/', 1)
     39        msg = MIMEBase(maintype, subtype)
     40        msg.set_payload(content)
     41        Encoders.encode_base64(msg)
     42        msg.add_header('Content-Disposition', 'attachment', filename=filename)
     43        MIMEMultipart.attach(self, msg)
     44
     45def send_mail(subject, message, from_email, recipient_list, fail_silently=False, auth_user=settings.EMAIL_HOST_USER, auth_password=settings.EMAIL_HOST_PASSWORD, attachments=None):
    2646    """
    2747    Easy wrapper for sending a single message to a recipient list. All members
    2848    of the recipient list will see the other recipients in the 'To' field.
    2949    """
    30     return send_mass_mail([[subject, message, from_email, recipient_list]], fail_silently, auth_user, auth_password)
     50    return send_mass_mail([[subject, message, from_email, recipient_list, attachments]], fail_silently, auth_user, auth_password)
    3151
    3252def send_mass_mail(datatuple, fail_silently=False, auth_user=settings.EMAIL_HOST_USER, auth_password=settings.EMAIL_HOST_PASSWORD):
    3353    """
     
    4666            return
    4767        raise
    4868    num_sent = 0
    49     for subject, message, from_email, recipient_list in datatuple:
     69    for i in datatuple:
     70        try:
     71            subject, message, from_email, recipient_list, attachments = i
     72        except ValueError:
     73            subject, message, from_email, recipient_list = i
     74            attachments = None
    5075        if not recipient_list:
    5176            continue
    5277        from_email = from_email or settings.DEFAULT_FROM_EMAIL
    53         msg = SafeMIMEText(message, 'plain', settings.DEFAULT_CHARSET)
     78        body = SafeMIMEText(message, 'plain', settings.DEFAULT_CHARSET)
     79        if attachments:
     80            # This is a multipart mail
     81            msg = SafeMIMEMultipart()
     82            # First the body
     83            msg.attach(body)
     84            # Then the various files to be attached.
     85            for (filename, content, mimetype) in attachments:
     86                msg.attachFile(filename, content, mimetype)
     87        else:
     88            msg = body
    5489        msg['Subject'] = subject
    5590        msg['From'] = from_email
    5691        msg['To'] = ', '.join(recipient_list)
  • docs/email.txt

     
    3535
    3636    send_mail(subject, message, from_email, recipient_list,
    3737        fail_silently=False, auth_user=EMAIL_HOST_USER,
    38         auth_password=EMAIL_HOST_PASSWORD)
     38        auth_password=EMAIL_HOST_PASSWORD, attachments=None)
    3939
    4040The ``subject``, ``message``, ``from_email`` and ``recipient_list`` parameters
    4141are required.
     
    5555    * ``auth_password``: The optional password to use to authenticate to the
    5656      SMTP server. If this isn't provided, Django will use the value of the
    5757      ``EMAIL_HOST_PASSWORD`` setting.
     58    * ``attachments``: A list of ``(filename, content, mimetype)`` tuples
     59      specifying attachements.
    5860
    5961.. _smtplib docs: http://www.python.org/doc/current/lib/module-smtplib.html
    6062
     63Sending mail with attachments
     64-----------------------------
     65
     66``attachments`` is a list of ``(filename, content, mimetype)`` tuples.
     67``filename`` specifes the name of the file to be attached, ``content`` is the
     68contents of a file as a ``str`` object, and finally, ``mimetype`` is the mime
     69type of the attachment. To attach an image and an audio file pass
     70
     71    attachments = [
     72        ('image.png', open('/home/user/image.png', 'rb').read(), 'image/png'),
     73        ('audio.mp3', open('/home/user/audio.mp3', 'rb').read(), 'audio/mpeg'),
     74    ]
     75
     76to the ``send_mail`` function.
     77
    6178send_mass_mail()
    6279================
    6380
     
    6784    send_mass_mail(datatuple, fail_silently=False,
    6885        auth_user=EMAIL_HOST_USER, auth_password=EMAIL_HOST_PASSWORD):
    6986
    70 ``datatuple`` is a tuple in which each element is in this format::
     87``datatuple`` is a tuple in which each element is either in the format::
    7188
    7289    (subject, message, from_email, recipient_list)
    7390
     91or::
     92
     93    (subject, message, from_email, recipient_list, attachments)
     94
    7495``fail_silently``, ``auth_user`` and ``auth_password`` have the same functions
    7596as in ``send_mail()``.
    7697
Back to Top