Django

Code

Ticket #1541: mail_attachment.diff

File mail_attachment.diff, 5.8 kB (added by mssnlayam@yahoo.com, 2 years ago)
  • django/core/mail.py

    old new  
    11# Use this module for e-mailing. 
    22 
    33from django.conf import settings 
     4import mimetypes 
     5from email import Encoders 
     6from email.Message import Message 
     7from email.MIMEAudio import MIMEAudio 
     8from email.MIMEBase import MIMEBase 
     9from email.MIMEMultipart import MIMEMultipart 
     10from email.MIMEImage import MIMEImage 
    411from email.MIMEText import MIMEText 
    512from email.Header import Header 
    613import smtplib, rfc822 
     
    2229            val = Header(val, settings.DEFAULT_CHARSET) 
    2330        MIMEText.__setitem__(self, name, val) 
    2431 
    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): 
     32class SafeMIMEMultipart(MIMEMultipart): 
     33    def __setitem__(self, name, val): 
     34        "Forbids multi-line headers, to prevent header injection." 
     35        if '\n' in val or '\r' in val: 
     36            raise BadHeaderError, "Header values can't contain newlines (got %r for header %r)" % (val, name) 
     37        if name == "Subject": 
     38            val = Header(val, settings.DEFAULT_CHARSET) 
     39        MIMEMultipart.__setitem__(self, name, val) 
     40 
     41    def attachFile(self, filename, fp): 
     42        ctype, encoding = mimetypes.guess_type(filename) 
     43        if ctype is None or encoding is not None: 
     44            ctype = 'application/octet-stream' 
     45        maintype, subtype = ctype.split('/', 1) 
     46        if maintype == 'text': 
     47            msg = SafeMIMEText(fp.read(), _subtype=subtype, _charset=settings.DEFAULT_CHARSET) 
     48        elif maintype == 'image': 
     49            msg = MIMEImage(fp.read(), _subtype=subtype) 
     50        elif maintype == 'audio': 
     51            msg = MIMEAudio(fp.read(), _subtype=subtype) 
     52        else: 
     53            msg = MIMEBase(maintype, subtype) 
     54            msg.set_payload(fp.read()) 
     55            # Encode the payload using Base64 
     56            Encoders.encode_base64(msg) 
     57        # Set the filename parameter 
     58        msg.add_header('Content-Disposition', 'attachment', filename=filename) 
     59        MIMEMultipart.attach(self, msg) 
     60 
     61def 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): 
    2662    """ 
    2763    Easy wrapper for sending a single message to a recipient list. All members 
    2864    of the recipient list will see the other recipients in the 'To' field. 
    2965    """ 
    30     return send_mass_mail([[subject, message, from_email, recipient_list]], fail_silently, auth_user, auth_password) 
     66    return send_mass_mail([[subject, message, from_email, recipient_list, attachments]], fail_silently, auth_user, auth_password) 
    3167 
    3268def send_mass_mail(datatuple, fail_silently=False, auth_user=settings.EMAIL_HOST_USER, auth_password=settings.EMAIL_HOST_PASSWORD): 
    3369    """ 
     
    4682            return 
    4783        raise 
    4884    num_sent = 0 
    49     for subject, message, from_email, recipient_list in datatuple: 
     85    for i in datatuple: 
     86        try: 
     87            subject, message, from_email, recipient_list, attachments = i 
     88        except ValueError: 
     89            subject, message, from_email, recipient_list = i 
     90            attachments = None 
    5091        if not recipient_list: 
    5192            continue 
    5293        from_email = from_email or settings.DEFAULT_FROM_EMAIL 
    53         msg = SafeMIMEText(message, 'plain', settings.DEFAULT_CHARSET) 
     94        body = SafeMIMEText(message, 'plain', settings.DEFAULT_CHARSET) 
     95        if attachments: 
     96            # This is a multipart mail 
     97            msg = SafeMIMEMultipart() 
     98            # First the body 
     99            msg.attach(body) 
     100            # Then the various files to be attached. 
     101            for (filename, fp) in attachments: 
     102                msg.attachFile(filename, fp) 
     103        else: 
     104            msg = body 
    54105        msg['Subject'] = subject 
    55106        msg['From'] = from_email 
    56107        msg['To'] = ', '.join(recipient_list) 
  • docs/email.txt

    old new  
    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, fp)`` tuples specifying 
     59      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, fp)`` tuples. ``filename`` specifes 
     67the name of the file to be attached, and ``fp`` is the file stream. To attach 
     68an image and an audio file pass 
     69 
     70    attachments = [ 
     71        ('image.png', open('/home/user/image.png', 'rb')), 
     72        ('audio.mp3', open('/home/user/audio.mp3', 'rb')), 
     73    ] 
     74 
     75to the ``send_mail`` function. 
     76 
    6177send_mass_mail() 
    6278================ 
    6379 
     
    6783    send_mass_mail(datatuple, fail_silently=False, 
    6884        auth_user=EMAIL_HOST_USER, auth_password=EMAIL_HOST_PASSWORD): 
    6985 
    70 ``datatuple`` is a tuple in which each element is in this format:: 
     86``datatuple`` is a tuple in which each element is either in the format:: 
    7187 
    7288    (subject, message, from_email, recipient_list) 
    7389 
     90or:: 
     91 
     92    (subject, message, from_email, recipient_list, attachments) 
     93 
    7494``fail_silently``, ``auth_user`` and ``auth_password`` have the same functions 
    7595as in ``send_mail()``. 
    7696