def test_attachments(self): """Regression test for Django #9367""" headers = { "Date": "Fri, 09 Nov 2001 01:08:47 -0000", "Message-ID": "foo" } subject, from_email, to = 'hello', '*****@*****.**', '*****@*****.**' text_content = 'This is an important message.' html_content = '<p>This is an <strong>important</strong> message.</p>' msg = EmailMultiAlternatives(subject, text_content, from_email, [to], headers=headers) msg.attach_alternative(html_content, "text/html") msg.attach("an attachment.pdf", "%PDF-1.4.%...", mimetype="application/pdf") msg_str = msg.message().as_string() message = message_from_string(msg_str) self.assertTrue(message.is_multipart()) self.assertEqual(message.get_content_type(), 'multipart/mixed') self.assertEqual(message.get_default_type(), 'text/plain') payload = message.get_payload() self.assertEqual(payload[0].get_content_type(), 'multipart/alternative') self.assertEqual(payload[1].get_content_type(), 'application/pdf')
def test_encoding(self): """ Regression for #12791 - Encode body correctly with other encodings than utf-8 """ email = EmailMessage('Subject', 'Firstname Sürname is a great guy.', '*****@*****.**', ['*****@*****.**']) email.encoding = 'iso-8859-1' message = email.message() self.assertTrue(message.as_string().startswith( 'Content-Type: text/plain; charset="iso-8859-1"\nMIME-Version: 1.0\nContent-Transfer-Encoding: quoted-printable\nSubject: Subject\nFrom: [email protected]\nTo: [email protected]' )) self.assertEqual(message.get_payload(), 'Firstname S=FCrname is a great guy.') # Make sure MIME attachments also works correctly with other encodings than utf-8 text_content = 'Firstname Sürname is a great guy.' html_content = '<p>Firstname Sürname is a <strong>great</strong> guy.</p>' msg = EmailMultiAlternatives('Subject', text_content, '*****@*****.**', ['*****@*****.**']) msg.encoding = 'iso-8859-1' msg.attach_alternative(html_content, "text/html") self.assertEqual( msg.message().get_payload(0).as_string(), 'Content-Type: text/plain; charset="iso-8859-1"\nMIME-Version: 1.0\nContent-Transfer-Encoding: quoted-printable\n\nFirstname S=FCrname is a great guy.' ) self.assertEqual( msg.message().get_payload(1).as_string(), 'Content-Type: text/html; charset="iso-8859-1"\nMIME-Version: 1.0\nContent-Transfer-Encoding: quoted-printable\n\n<p>Firstname S=FCrname is a <strong>great</strong> guy.</p>' )
def test_encoding(self): """ Regression for #12791 - Encode body correctly with other encodings than utf-8 """ email = EmailMessage('Subject', 'Firstname Sürname is a great guy.', '*****@*****.**', ['*****@*****.**']) email.encoding = 'iso-8859-1' message = email.message() self.assertTrue(message.as_string().startswith('Content-Type: text/plain; charset="iso-8859-1"\nMIME-Version: 1.0\nContent-Transfer-Encoding: quoted-printable\nSubject: Subject\nFrom: [email protected]\nTo: [email protected]')) self.assertEqual(message.get_payload(), 'Firstname S=FCrname is a great guy.') # Make sure MIME attachments also works correctly with other encodings than utf-8 text_content = 'Firstname Sürname is a great guy.' html_content = '<p>Firstname Sürname is a <strong>great</strong> guy.</p>' msg = EmailMultiAlternatives('Subject', text_content, '*****@*****.**', ['*****@*****.**']) msg.encoding = 'iso-8859-1' msg.attach_alternative(html_content, "text/html") self.assertEqual(msg.message().get_payload(0).as_string(), 'Content-Type: text/plain; charset="iso-8859-1"\nMIME-Version: 1.0\nContent-Transfer-Encoding: quoted-printable\n\nFirstname S=FCrname is a great guy.') self.assertEqual(msg.message().get_payload(1).as_string(), 'Content-Type: text/html; charset="iso-8859-1"\nMIME-Version: 1.0\nContent-Transfer-Encoding: quoted-printable\n\n<p>Firstname S=FCrname is a <strong>great</strong> guy.</p>')
def test_safe_mime_multipart(self): """ Make sure headers can be set with a different encoding than utf-8 in SafeMIMEMultipart as well """ headers = {"Date": "Fri, 09 Nov 2001 01:08:47 -0000", "Message-ID": "foo"} subject, from_email, to = 'hello', '*****@*****.**', '"Sürname, Firstname" <*****@*****.**>' text_content = 'This is an important message.' html_content = '<p>This is an <strong>important</strong> message.</p>' msg = EmailMultiAlternatives('Message from Firstname Sürname', text_content, from_email, [to], headers=headers) msg.attach_alternative(html_content, "text/html") msg.encoding = 'iso-8859-1' self.assertEqual(msg.message()['To'], '=?iso-8859-1?q?S=FCrname=2C_Firstname?= <*****@*****.**>') self.assertEqual(msg.message()['Subject'].encode(), '=?iso-8859-1?q?Message_from_Firstname_S=FCrname?=')
def test_attachments(self): """Regression test for Django #9367""" headers = {"Date": "Fri, 09 Nov 2001 01:08:47 -0000", "Message-ID": "foo"} subject, from_email, to = 'hello', '*****@*****.**', '*****@*****.**' text_content = 'This is an important message.' html_content = '<p>This is an <strong>important</strong> message.</p>' msg = EmailMultiAlternatives(subject, text_content, from_email, [to], headers=headers) msg.attach_alternative(html_content, "text/html") msg.attach("an attachment.pdf", "%PDF-1.4.%...", mimetype="application/pdf") msg_str = msg.message().as_string() message = message_from_string(msg_str) self.assertTrue(message.is_multipart()) self.assertEqual(message.get_content_type(), 'multipart/mixed') self.assertEqual(message.get_default_type(), 'text/plain') payload = message.get_payload() self.assertEqual(payload[0].get_content_type(), 'multipart/alternative') self.assertEqual(payload[1].get_content_type(), 'application/pdf')
def test_safe_mime_multipart(self): """ Make sure headers can be set with a different encoding than utf-8 in SafeMIMEMultipart as well """ headers = { "Date": "Fri, 09 Nov 2001 01:08:47 -0000", "Message-ID": "foo" } subject, from_email, to = 'hello', '*****@*****.**', '"Sürname, Firstname" <*****@*****.**>' text_content = 'This is an important message.' html_content = '<p>This is an <strong>important</strong> message.</p>' msg = EmailMultiAlternatives('Message from Firstname Sürname', text_content, from_email, [to], headers=headers) msg.attach_alternative(html_content, "text/html") msg.encoding = 'iso-8859-1' self.assertEqual( msg.message()['To'], '=?iso-8859-1?q?S=FCrname=2C_Firstname?= <*****@*****.**>') self.assertEqual(msg.message()['Subject'].encode(), u'=?iso-8859-1?q?Message_from_Firstname_S=FCrname?=')
def forge_email(fromaddr, toaddr, subject, content, html_content='', html_images=None, usebcc=False, header=None, footer=None, html_header=None, html_footer=None, ln=None, charset=None, replytoaddr="", attachments=None, bccaddr=""): """Prepare email. Add header and footer if needed. @param fromaddr: [string] sender @param toaddr: [string or list-of-strings] list of receivers (if string, then receivers are separated by ',') @param usebcc: [bool] True for using Bcc in place of To @param subject: [string] subject of the email @param content: [string] content of the email @param html_content: [string] html version of the email @param html_images: [dict] dictionary of image id, image path @param header: [string] None for the default header @param footer: [string] None for the default footer @param ln: language @charset: [string] the content charset. By default is None which means to try to encode the email as ascii, then latin1 then utf-8. @param replytoaddr: [string or list-of-strings] to be used for the reply-to header of the email (if string, then receivers are separated by ',') @param attachments: list of paths of files to be attached. Alternatively, every element of the list could be a tuple: (filename, mimetype) @param bccaddr: [string or list-of-strings] to be used for BCC header of the email (if string, then receivers are separated by ',') @return: forged email as a string""" ln = default_ln(ln) if html_images is None: html_images = {} content = render_template_to_string('mail_text.tpl', content=unicodifier(content), header=unicodifier(header), footer=unicodifier(footer) ).encode('utf8') if type(toaddr) is list: toaddr = ','.join(toaddr) if type(bccaddr) is list: bccaddr = ','.join(bccaddr) if type(replytoaddr) is list: replytoaddr = ','.join(replytoaddr) toaddr = remove_temporary_emails(toaddr) headers = {} kwargs = {'to': [], 'cc': [], 'bcc': []} if replytoaddr: headers['Reply-To'] = replytoaddr if usebcc: headers['Bcc'] = bccaddr kwargs['bcc'] = toaddr.split(',') + bccaddr.split(',') kwargs['to'] = ['Undisclosed.Recipients:'] else: kwargs['to'] = toaddr.split(',') headers['From'] = fromaddr headers['Date'] = formatdate(localtime=True) headers['User-Agent'] = 'Invenio %s at %s' % (cfg['CFG_VERSION'], cfg['CFG_SITE_URL']) if html_content: html_content = render_template_to_string( 'mail_html.tpl', content=unicodifier(html_content), header=unicodifier(html_header), footer=unicodifier(html_footer) ).encode('utf8') msg_root = EmailMultiAlternatives(subject=subject, body=content, from_email=fromaddr, headers=headers, **kwargs) msg_root.attach_alternative(html_content, "text/html") #if not html_images: # # No image? Attach the HTML to the root # msg_root.attach(msg_text) #else: if html_images: # Image(s)? Attach the HTML and image(s) as children of a # "related" block msg_related = MIMEMultipart('related') #msg_related.attach(msg_text) for image_id, image_path in iteritems(html_images): attach_embed_image(msg_related, image_id, image_path) msg_root.attach(msg_related) else: msg_root = EmailMessage(subject=subject, body=content, from_email=fromaddr, headers=headers, **kwargs) if attachments: from invenio.legacy.bibdocfile.api import _mimes, guess_format_from_url #old_msg_root = msg_root #msg_root = MIMEMultipart() #msg_root.attach(old_msg_root) for attachment in attachments: try: mime = None if type(attachment) in (list, tuple): attachment, mime = attachment if mime is None: ## Automatic guessing of mimetype mime = _mimes.guess_type(attachment)[0] if mime is None: ext = guess_format_from_url(attachment) mime = _mimes.guess_type("foo" + ext)[0] if not mime: mime = 'application/octet-stream' part = MIMEBase(*mime.split('/', 1)) part.set_payload(open(attachment, 'rb').read()) Encoders.encode_base64(part) part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(attachment)) msg_root.attach(part) except: from invenio.ext.logging import register_exception register_exception(alert_admin=True, prefix="Can't attach %s" % attachment) return msg_root
def forge_email(fromaddr, toaddr, subject, content, html_content='', html_images=None, usebcc=False, header=None, footer=None, html_header=None, html_footer=None, ln=CFG_SITE_LANG, charset=None, replytoaddr="", attachments=None): """Prepare email. Add header and footer if needed. @param fromaddr: [string] sender @param toaddr: [string or list-of-strings] list of receivers (if string, then receivers are separated by ',') @param usebcc: [bool] True for using Bcc in place of To @param subject: [string] subject of the email @param content: [string] content of the email @param html_content: [string] html version of the email @param html_images: [dict] dictionary of image id, image path @param header: [string] None for the default header @param footer: [string] None for the default footer @param ln: language @charset: [string] the content charset. By default is None which means to try to encode the email as ascii, then latin1 then utf-8. @param replytoaddr: [string or list-of-strings] to be used for the reply-to header of the email (if string, then receivers are separated by ',') @param attachments: list of paths of files to be attached. Alternatively, every element of the list could be a tuple: (filename, mimetype) @return: forged email as a string""" if html_images is None: html_images = {} content = render_template_to_string('mail_text.tpl', content=content, header=header, footer=footer) if type(toaddr) is not str: toaddr = ','.join(toaddr) if type(replytoaddr) is not str: replytoaddr = ','.join(replytoaddr) toaddr = remove_temporary_emails(toaddr) headers = {} kwargs = {'to': [], 'cc': [], 'bcc': []} if replytoaddr: headers['Reply-To'] = replytoaddr if usebcc: headers['Bcc'] = toaddr kwargs['bcc'] = toaddr.split(',') kwargs['to'] = ['Undisclosed.Recipients:'] else: kwargs['to'] = toaddr.split(',') headers['From'] = fromaddr headers['Date'] = formatdate(localtime=True) headers['User-Agent'] = 'Invenio %s at %s' % (CFG_VERSION, CFG_SITE_URL) if html_content: html_content = render_template_to_string('mail_html.tpl', content=html_content, header=html_header, footer=html_footer) msg_root = EmailMultiAlternatives(subject=subject, body=content, from_email=fromaddr, headers=headers, **kwargs) msg_root.attach_alternative(html_content, "text/html") #if not html_images: # # No image? Attach the HTML to the root # msg_root.attach(msg_text) #else: if html_images: # Image(s)? Attach the HTML and image(s) as children of a # "related" block msg_related = MIMEMultipart('related') #msg_related.attach(msg_text) for image_id, image_path in html_images.iteritems(): attach_embed_image(msg_related, image_id, image_path) msg_root.attach(msg_related) else: msg_root = EmailMessage(subject=subject, body=content, from_email=fromaddr, headers=headers, **kwargs) if attachments: from invenio.bibdocfile import _mimes, guess_format_from_url #old_msg_root = msg_root #msg_root = MIMEMultipart() #msg_root.attach(old_msg_root) for attachment in attachments: try: mime = None if type(attachment) in (list, tuple): attachment, mime = attachment if mime is None: ## Automatic guessing of mimetype mime = _mimes.guess_type(attachment)[0] if mime is None: ext = guess_format_from_url(attachment) mime = _mimes.guess_type("foo" + ext)[0] if not mime: mime = 'application/octet-stream' part = MIMEBase(*mime.split('/', 1)) part.set_payload(open(attachment, 'rb').read()) Encoders.encode_base64(part) part.add_header( 'Content-Disposition', 'attachment; filename="%s"' % os.path.basename(attachment)) msg_root.attach(part) except: register_exception(alert_admin=True, prefix="Can't attach %s" % attachment) return msg_root