Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fails when attaching HTML file #18

Open
anentropic opened this issue Dec 11, 2013 · 2 comments · May be fixed by #19
Open

Fails when attaching HTML file #18

anentropic opened this issue Dec 11, 2013 · 2 comments · May be fixed by #19

Comments

@anentropic
Copy link

I am trying to attach an HTML file to an email.

I get the following error:

/usr/local/lib/python2.7/email/message.pyc in get(self, name, failobj)
    358         is missing.
    359         """
--> 360         name = name.lower()
    361         for k, v in self._headers:
    362             if k.lower() == name:

AttributeError: 'slice' object has no attribute 'lower'

Stepping into the code with ipython debugger it seems that it detects the MIME type of the file, correctly, as text/html but this causes it to follow a different codepath which is where it fails: https://github.com/tomekwojcik/envelopes/blob/master/envelopes/envelope.py#L292

If I force it to use a generic mime type instead:
envelope.add_attachment("myfile.html", mimetype="application/octet-stream")

...then I can send the message but something weird happens - Gmail shows the message as having the file attached twice, even though if I go back and check the envelope object it seems I have only one attachment:

In [18]: envelope._parts
Out[18]:
[('text/plain', 'my body text', 'utf-8'),
 ('application/octet-stream',
  <email.mime.base.MIMEBase instance at 0x270cd40>)]
@anentropic
Copy link
Author

the 'double' attachments showing up in Gmail seems to be a bug in Gmail ... the message source appears to be correct :)

@thakkarparth007
Copy link

The problem is that the code makes a wrong assumption in line 291 of envelope.py (https://github.com/tomekwojcik/envelopes/blob/master/envelopes/envelope.py#L291).

    for part in self._parts:
        type_maj, type_min = part[0].split('/')
        # Small correction. See thakkarparth007's comment on:
        # https://github.com/tomekwojcik/envelopes/issues/18
        if type_maj == 'text' and type_min in ('html', 'plain'):
            msg.attach(MIMEText(part[1], type_min, self._charset))
        else:
            msg.attach(part[1])

self._parts contains the (mimetype, part, charset) tuples for the "main"
content - the text/html part and the text/plain part. Here, part is a
(unicode?) string. But, it also contains the attachments - the (mimetype, part)
tuples which are added in the add_attachment() function. Here, the part
is a MIMEBase object. Now, consider what happens when you attach a text/html
or text/plain file - you'll be appending a ('text/html',MIMEBase) tuple
to the self._parts list. Now, in the above loop, the condition is satisfied
by this text-ish file. So, you try to create a MIMEText object with the first
argument being a MIMEBase instead of a (unicode?) string. This causes all the
trouble.

A simple (but maybe hackish) solution is to add another condition and make that
if statement look something like this:

       if type_maj == 'text' and type_min in ('html', 'plain') and\
            (isinstance(part[1], str) or isinstance(part[1], unicode)):
            msg.attach(MIMEText(part[1], type_min, self._charset))
        else:
            msg.attach(part[1])

This will work (at least for now).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants