Code

Ticket #9367: mail.py.patch

File mail.py.patch, 5.7 KB (added by loekje, 5 years ago)
  • mail.py

    old new  
    190190            return False 
    191191        return True 
    192192 
     193""" http://code.djangoproject.com/ticket/9367 by Loek Engels """ 
    193194class EmailMessage(object): 
    194195    """ 
    195196    A container for email information. 
    196197    """ 
    197198    content_subtype = 'plain' 
    198     multipart_subtype = 'mixed' 
     199    mixed_subtype = 'mixed' 
    199200    encoding = None     # None => use settings default 
    200201 
    201202    def __init__(self, subject='', body='', from_email=None, to=None, bcc=None, 
     
    234235        encoding = self.encoding or settings.DEFAULT_CHARSET 
    235236        msg = SafeMIMEText(smart_str(self.body, settings.DEFAULT_CHARSET), 
    236237                           self.content_subtype, encoding) 
    237         if self.attachments: 
    238             body_msg = msg 
    239             msg = SafeMIMEMultipart(_subtype=self.multipart_subtype) 
    240             if self.body: 
    241                 msg.attach(body_msg) 
    242             for attachment in self.attachments: 
    243                 if isinstance(attachment, MIMEBase): 
    244                     msg.attach(attachment) 
    245                 else: 
    246                     msg.attach(self._create_attachment(*attachment)) 
     238        msg = self._create_message(msg) 
    247239        msg['Subject'] = self.subject 
    248240        msg['From'] = self.from_email 
    249241        msg['To'] = ', '.join(self.to) 
     
    267259    def attach(self, filename=None, content=None, mimetype=None): 
    268260        """ 
    269261        Attaches a file with the given filename and content. The filename can 
    270         be omitted (useful for multipart/alternative messages) and the mimetype 
    271         is guessed, if not provided. 
     262        be omitted and the mimetype is guessed, if not provided. 
    272263 
    273264        If the first parameter is a MIMEBase subclass it is inserted directly 
    274265        into the resulting message attachments. 
     
    286277        content = open(path, 'rb').read() 
    287278        self.attach(filename, content, mimetype) 
    288279 
    289     def _create_attachment(self, filename, content, mimetype=None): 
    290         """ 
    291         Converts the filename, content, mimetype triple into a MIME attachment 
    292         object. 
     280    def _create_message(self, msg): 
     281        return self._create_attachments(msg) 
     282 
     283    def _create_attachments(self, msg): 
     284        if self.attachments: 
     285            body_msg = msg 
     286            msg = SafeMIMEMultipart(_subtype=self.mixed_subtype) 
     287            if self.body: 
     288                msg.attach(body_msg) 
     289            for attachment in self.attachments: 
     290                if isinstance(attachment, MIMEBase): 
     291                    msg.attach(attachment) 
     292                else: 
     293                    msg.attach(self._create_attachment(*attachment)) 
     294        return msg 
     295 
     296    def _create_mime_attachment(self, content, mimetype): 
     297        """  
     298        Converts the content, mimetype pair into a MIME attachment object.  
    293299        """ 
    294         if mimetype is None: 
    295             mimetype, _ = mimetypes.guess_type(filename) 
    296             if mimetype is None: 
    297                 mimetype = DEFAULT_ATTACHMENT_MIME_TYPE 
    298300        basetype, subtype = mimetype.split('/', 1) 
    299301        if basetype == 'text': 
    300302            attachment = SafeMIMEText(smart_str(content, 
     
    304306            attachment = MIMEBase(basetype, subtype) 
    305307            attachment.set_payload(content) 
    306308            Encoders.encode_base64(attachment) 
     309        return attachment 
     310 
     311    def _create_attachment(self, filename, content, mimetype=None): 
     312        """ 
     313        Converts the filename, content, mimetype triple into a MIME attachment 
     314        object. 
     315        """ 
     316        if mimetype is None: 
     317            mimetype, _ = mimetypes.guess_type(filename) 
     318            if mimetype is None: 
     319                mimetype = DEFAULT_ATTACHMENT_MIME_TYPE 
     320        attachment = self._create_mime_attachment(content, mimetype) 
    307321        if filename: 
    308322            attachment.add_header('Content-Disposition', 'attachment', 
    309323                                  filename=filename) 
     
    315329    messages. For example, including text and HTML versions of the text is 
    316330    made easier. 
    317331    """ 
    318     multipart_subtype = 'alternative' 
     332    alternative_subtype = 'alternative' 
     333 
     334    def __init__(self, subject='', body='', from_email=None, to=None, bcc=None, 
     335            connection=None, attachments=None, headers=None, alternatives=None): 
     336        """ 
     337        Initialize a single email message (which can be sent to multiple 
     338        recipients). 
     339 
     340        All strings used to create the message can be unicode strings (or UTF-8 
     341        bytestrings). The SafeMIMEText class will handle any necessary encoding 
     342        conversions. 
     343        """ 
     344        super(EmailMultiAlternatives, self).__init__(subject, body, from_email, to, bcc, connection, attachments, headers) 
     345        self.alternatives=alternatives or [] 
    319346 
    320     def attach_alternative(self, content, mimetype=None): 
     347    def attach_alternative(self, content, mimetype): 
    321348        """Attach an alternative content representation.""" 
    322         self.attach(content=content, mimetype=mimetype) 
     349        assert content is not None 
     350        assert mimetype is not None 
     351        self.alternatives.append((content, mimetype)) 
     352 
     353    def _create_message(self, msg): 
     354        return self._create_attachments(self._create_alternatives(msg)) 
     355 
     356    def _create_alternatives(self, msg): 
     357        if self.alternatives: 
     358            body_msg = msg 
     359            msg = SafeMIMEMultipart(_subtype=self.alternative_subtype) 
     360            if self.body: 
     361                msg.attach(body_msg) 
     362            for alternative in self.alternatives: 
     363                msg.attach(self._create_mime_attachment(*alternative)) 
     364        return msg 
    323365 
    324366def send_mail(subject, message, from_email, recipient_list, 
    325367              fail_silently=False, auth_user=None, auth_password=None):