tags:

views:

386

answers:

3

I have an email that I'm reading with the Python email lib that I need to modify the attachments of. The email Message class has the "attach" method, but does not have anything like "detach". How can I remove an attachment from a multipart message? If possible, I want to do this without recreating the message from scratch.

Essentially I want to:

  1. Load the email
  2. Remove the mime attachments
  3. Add a new attachment
+1  A: 

Well, from my experience, in the context you are working, everything is a Message object. The message, its parts, attachments, everything. So, to accomplish what you want to do, you need to

  1. parse the message using the Parser API (this will get you the root Message object)
  2. Walk the structure, determining what you need and what you don't (using a method of a Message instance, - .walk()), - remember, that everything is a Message.
  3. Attach whatever you need to attach to the parts you've extracted and you are good to go.

To reiterate, what you are working with is, essentially, a tree, where Message objects with .is_multipart() == True are nodes and Message objects with .is_multipart() == False are end-nodes (their payload is a string, not a bunch of Message objects).

shylent
+1  A: 

The way I've figured out to do it is:

  1. Set the payload to an empty list with set_payload
  2. Create the payload, and attach to the message.
john a macdonald
A: 

set_payload() may help.

set_payload(payload[, charset])

Set the entire message object’s payload to payload. It is the client’s responsibility to ensure the payload invariants.

A quick interactive example:

>>> from email import mime,message
>>> m1 = message.Message()
>>> t1=email.MIMEText.MIMEText('t1\r\n')
>>> print t1.as_string()
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit

t1

>>> m1.attach(t1)
>>> m1.is_multipart()
True
>>> m1.get_payload()
[<email.mime.text.MIMEText instance at 0x00F585A8>]
>>> t2=email.MIMEText.MIMEText('t2\r\n')
>>> m1.set_payload([t2])
>>> print m1.get_payload()[0].as_string()
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit

t2

>>>
gimel