Opened 18 years ago
Closed 18 years ago
#4771 closed (wontfix)
EmailHTML - EmailMessage with HTML and related/inline images support
| Reported by: | Owned by: | nobody | |
|---|---|---|---|
| Component: | Core (Mail) | Version: | dev |
| Severity: | Keywords: | EmailMessage multipart mail html attachments Content-ID | |
| Cc: | nick.lane.au@… | Triage Stage: | Design decision needed |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
Seems we need the ability to specify Content-Type 'name' header for attachments, when using the new mail objects. I'm trying to send an HTML mail with images, using EmailMultiAlternatives, attach_alternative, and attach_file, but the resulting message isn't readable. It's attaching everything OK, but not with the right headers.
Change History (4)
comment:1 by , 18 years ago
comment:2 by , 18 years ago
| Cc: | added |
|---|---|
| Summary: | EmailMultiAlternatives doesn't support named image/media attachments → EmailHTML - EmailMessage with HTML and related/inline images support |
| Triage Stage: | Unreviewed → Design decision needed |
Here is a derivative of EmailMessage that allows nice easy HTML with inline images. It also provides a multipart/related-safe way of attaching HTML and automatically fixes file references in your HTML to point to inline attachments.
class EmailHTML(EmailMessage):
multipart_subtype = 'related'
html = None
related_ids = []
def message(self):
if self.html:
for id in self.related_ids:
self.html = self.html.replace(id, 'cid:' + id)
encoding = self.encoding or settings.DEFAULT_CHARSET
ha = SafeMIMEText(self.html, 'html', encoding)
if self.body:
a = SafeMIMEMultipart(_subtype='alternative')
a.attach(SafeMIMEText(smart_str(self.body, encoding), self.content_subtype, encoding))
a.attach(ha)
else:
a = ha
self.attachments.insert(0, a)
self.body = None
self.html = None
return super(EmailHTML, self).message()
def attach_html(self, html):
"""
Specify HTML to include in the message.
"""
self.html = html
def attach_related(self, path, mimetype=None):
"""
Attaches a file from the filesystem, with a Content-ID.
For use with multipart/related messages.
"""
filename = os.path.basename(path)
content = open(path, 'rb').read()
self.attachments.append((filename, content, mimetype, True))
self.related_ids += [ filename ]
def _create_attachment(self, filename, content, mimetype=None, with_id=False):
"""
Convert the filename, content, mimetype triple into a MIME attachment
object. Adjust headers to use Content-ID where applicable.
"""
attachment = super(EmailHTML, self)._create_attachment(filename, content, mimetype)
if filename and with_id:
# change headers to suit
del(attachment['Content-Disposition'])
mimetype = attachment['Content-Type']
del(attachment['Content-Type'])
attachment.add_header('Content-Type', mimetype, name=filename)
attachment.add_header('Content-ID', '<%s>' % filename)
return attachment
comment:3 by , 18 years ago
If we're including multipart and attachment support in core.mail, then I think this (or similar) should be included also.
See also ticket #4781 a typo fix required to make this class work.
comment:4 by , 18 years ago
| Resolution: | → wontfix |
|---|---|
| Status: | new → closed |
I think this doesn't make much sense as a built-in: HTML email is so weird that pretty much everyone wants to do things differently (my HTMLEmail class is similar to the above, but different in a few ways). Since there really isn't a one-size-fits-all (or even a one-size-fits-most) solution, I'm going to close this wontfix.
I haven't looked into this yet, but you might need to use the Content-ID header for the image.
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/473810