I had issues getting snippet 285 working when using a MIMEBase subclass (ie.. MIMEImage).
This modification to snippet 285.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | from __future__ import absolute_import
import os.path
import re
from email.MIMEBase import MIMEBase
from django.conf import settings
from django.core.mail import EmailMultiAlternatives, SafeMIMEMultipart
class EmailMultiRelated(EmailMultiAlternatives):
"""
A version of EmailMessage that makes it easy to send multipart/related
messages. For example, including text and HTML versions with inline images.
@see https://djangosnippets.org/snippets/2215/
"""
related_subtype = 'related'
def __init__(self, *args, **kwargs):
# self.related_ids = []
self.related_attachments = []
return super(EmailMultiRelated, self).__init__(*args, **kwargs)
def attach_related(self, filename=None, content=None, mimetype=None):
"""
Attaches a file with the given filename and content. The filename can
be omitted and the mimetype is guessed, if not provided.
If the first parameter is a MIMEBase subclass it is inserted directly
into the resulting message attachments.
"""
if isinstance(filename, MIMEBase):
assert content == mimetype == None
self.related_attachments.append(filename)
else:
assert content is not None
self.related_attachments.append((filename, content, mimetype))
def attach_related_file(self, path, mimetype=None):
"""Attaches a file from the filesystem."""
filename = os.path.basename(path)
content = open(path, 'rb').read()
self.attach_related(filename, content, mimetype)
def _create_message(self, msg):
return self._create_attachments(self._create_related_attachments(self._create_alternatives(msg)))
def _create_alternatives(self, msg):
for i, (content, mimetype) in enumerate(self.alternatives):
if mimetype == 'text/html':
for related_attachment in self.related_attachments:
if isinstance(related_attachment, MIMEBase):
content_id = related_attachment.get('Content-ID')
content = re.sub(r'(?<!cid:)%s' % re.escape(content_id), 'cid:%s' % content_id, content)
else:
filename, _, _ = related_attachment
content = re.sub(r'(?<!cid:)%s' % re.escape(filename), 'cid:%s' % filename, content)
self.alternatives[i] = (content, mimetype)
return super(EmailMultiRelated, self)._create_alternatives(msg)
def _create_related_attachments(self, msg):
encoding = self.encoding or settings.DEFAULT_CHARSET
if self.related_attachments:
body_msg = msg
msg = SafeMIMEMultipart(_subtype=self.related_subtype, encoding=encoding)
if self.body:
msg.attach(body_msg)
for related_attachment in self.related_attachments:
if isinstance(related_attachment, MIMEBase):
msg.attach(related_attachment)
else:
msg.attach(self._create_related_attachment(*related_attachment))
return msg
def _create_related_attachment(self, filename, content, mimetype=None):
"""
Convert the filename, content, mimetype triple into a MIME attachment
object. Adjust headers to use Content-ID where applicable.
Taken from http://code.djangoproject.com/ticket/4771
"""
attachment = super(EmailMultiRelated, self)._create_attachment(filename, content, mimetype)
if filename:
mimetype = attachment['Content-Type']
del(attachment['Content-Type'])
del(attachment['Content-Disposition'])
attachment.add_header('Content-Disposition', 'inline', filename=filename)
attachment.add_header('Content-Type', mimetype, name=filename)
attachment.add_header('Content-ID', '<%s>' % filename)
return attachment
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 1 week ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 2 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 6 months ago
Comments
Please login first before commenting.