Code

Opened 6 years ago

Closed 5 years ago

Last modified 5 years ago

#9367 closed (fixed)

EmailMultiAlternatives does not properly handle attachments

Reported by: loekje Owned by: lukeplant
Component: Core (Mail) Version: 1.0
Severity: Keywords:
Cc: patrys@…, walter+django@… Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

EmailMultiAlternatives does not properly attach (PDF) files. The generated email only contains a multipart/alternative part, whereas in order to additionally support attachments the multipart/alternative part should be wrapped in a multipart/mixed part. This allows for the inclusion of attachments in addition to different alternative views.

I would like to suggest to add this functionality to either the EmailMessage class or to update the EmailMultiAlternatives class to have proper support of both alternative views AND attachments. I have included an example on how to support this behavior. It has been tested to work with Outlook and Thunderbird mail clients.

Attachments (2)

mail.py (2.8 KB) - added by loekje 6 years ago.
Example of EmailAlternativesMessage with support of including, next to alternative views, attachments
mail.py.patch (5.7 KB) - added by loekje 6 years ago.

Download all attachments as: .zip

Change History (15)

Changed 6 years ago by loekje

Example of EmailAlternativesMessage with support of including, next to alternative views, attachments

comment:1 Changed 6 years ago by loekje

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

Just to be clear on what the result is of the following code for the EmailMultiAlternatives implementation in Django 1.0 when invoking the following code:

subject, from_email, to = 'hello', 'from@example.com', 'to@example.com'
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])
msg.attach_alternative(html_content, "text/html")
msg.attach_file('/tmp/file.pdf')
msg.send()

A message will be sent, with the two views (typically the HTML view will show up in the email client) and the file.pdf attachment is included in the email. However, it cannot be opened in email client because it does not show any attachments (and why should the email client, it is supposed to be an alternative view...)

comment:2 follow-up: Changed 6 years ago by mtredinnick

  • Summary changed from EmailMultiAlternatives does not properly attach (PDF) files. to EmailMultiAlternatives does not properly handle attachments
  • Triage Stage changed from Unreviewed to Accepted

We should make sure that attach_file() works correctly and actually attaches the file even in the subclass. That should be all that's needed here.

I can't work out what your attachment here is trying to do, since it's a whole file. Can you attach a proper patch if you're trying to fix attach_file()?

comment:3 in reply to: ↑ 2 Changed 6 years ago by anonymous

Replying to mtredinnick:

We should make sure that attach_file() works correctly and actually attaches the file even in the subclass. That should be all that's needed here.

I can't work out what your attachment here is trying to do, since it's a whole file. Can you attach a proper patch if you're trying to fix attach_file()?

Ok. I will submit a patch in the coming days.

Changed 6 years ago by loekje

comment:4 Changed 6 years ago by loekje

  • Has patch set

Patch has been attached. In the patch the EmailMultiAlternatives wraps the multipart/alternative views in a multipart/mixed message that also includes the attachments. The changes made to EmailMessage are merely for reusing code in the derived EmailMutliAlternatives class. In the original EmailMultiAlternatives all attachments (including the alternative views) would be attached as multipart/alternative. As a result of this the alternative views are correctly presented in the browser, however the attachments are also considered to be an alternative view (instead of the real attachment they are).

comment:5 Changed 5 years ago by loekje

  • Owner changed from nobody to mtredinnick

comment:6 Changed 5 years ago by patrys

  • Cc patrys@… added

comment:7 Changed 5 years ago by mtredinnick

  • Owner mtredinnick deleted

Not sure why this is assigned to me. I'm not going to have time to look at it just yet.

comment:8 Changed 5 years ago by thejaswi_puthraya

  • Component changed from Uncategorized to django.core.mail

comment:9 Changed 5 years ago by wdoekes

  • Cc walter+django@… added

comment:10 Changed 5 years ago by lukeplant

  • Owner set to lukeplant

comment:11 Changed 5 years ago by lukeplant

It's still quite difficult to see what the patch does, due to the way diff interprets things, but I've had a proper look. attach_file() doesn't work correctly in the subclass because the subclass works by overriding the value of multipart_subtype, which is used by the base class to build the message. So the fundamental way EmailMultiAlternatives works is broken for normal attachments, hence the need for quite a big patch. But it looks like a good patch.

I've added a test, I'll commit shortly. I'm taking it on trust that this is necessary to fix behaviour in Outlook (the previous format of email worked OK in my mail client, but Outlook's behaviour seems sensible as loekje argues).

comment:12 Changed 5 years ago by lukeplant

  • Resolution set to fixed
  • Status changed from new to closed

(In [10983]) Fixed #9367 - EmailMultiAlternatives does not properly handle attachments.

Thanks to Loek Engels for the bulk of the patch.

comment:13 Changed 5 years ago by lukeplant

(In [10984]) [1.0.X] Fixed #9367 - EmailMultiAlternatives does not properly handle attachments.

Thanks to Loek Engels for the bulk of the patch.

Backport of r10983 from trunk

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.