Question

So I tried the code below and it downloads attachments alright. The problem is on my gmail account, there are emails that were sent using MMS mail through mobile phone. Email attachments from mobile network A can be downloaded by the script below , while those that came from mobile network B fails.

Here are the links to the full email details : http://pastie.org/private/ektv7yfa2xwdqzu77ys5a (From Mobile Network A, works) http://pastie.org/private/cljaaad4tz7v5jra20l0q (From Mobile Network B, fails)

Grabbed from : How can I download all emails with attachments from Gmail?

import email, getpass, imaplib, os

detach_dir = '.' # directory where to save attachments (default: current)
user = raw_input("Enter your GMail username:")
pwd = getpass.getpass("Enter your password: ")

# connecting to the gmail imap server
m = imaplib.IMAP4_SSL("imap.gmail.com")
m.login(user,pwd)
m.select("[Gmail]/All Mail") # here you a can choose a mail box like INBOX instead
# use m.list() to get all the mailboxes

resp, items = m.search(None, "ALL") # you could filter using the IMAP rules here (check http://www.example-code.com/csharp/imap-search-critera.asp)
items = items[0].split() # getting the mails id

for emailid in items:
    resp, data = m.fetch(emailid, "(RFC822)") # fetching the mail, "`(RFC822)`" means "get the whole stuff", but you can ask for headers only, etc
    email_body = data[0][1] # getting the mail content
    mail = email.message_from_string(email_body) # parsing the mail content to get a mail object

    #Check if any attachments at all
    if mail.get_content_maintype() != 'multipart':
        continue

    print "["+mail["From"]+"] :" + mail["Subject"]

    # we use walk to create a generator so we can iterate on the parts and forget about the recursive headach
    for part in mail.walk():
        # multipart are just containers, so we skip them
        if part.get_content_maintype() == 'multipart':
            continue

        # is this part an attachment ?
        if part.get('Content-Disposition') is None:
            continue

        filename = part.get_filename()
        counter = 1

        # if there is no filename, we create one with a counter to avoid duplicates
        if not filename:
            filename = 'part-%03d%s' % (counter, 'bin')
            counter += 1

        att_path = os.path.join(detach_dir, filename)

        #Check if its already there
        if not os.path.isfile(att_path) :
            # finally write the stuff
            fp = open(att_path, 'wb')
            fp.write(part.get_payload(decode=True))
            fp.close()
Was it helpful?

Solution

The failing e-mail doesn't have Content-Disposition set in the headers for the attachment, so you're skipping over it. Looks like you're going to have to relax the if statement that checks for Content-Disposition a bit.

Maybe you could just look too see if the Content-Type is image/jpeg and work with that.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top