2

I am trying to download all the attachments from the INBOX.

After 10 to 20 downloaded files, the program throws an error.

, line 62, in
get_attachments(raw,email_id)
,line 31, in get_attachments
fileName = '{} '.format(email_id)+part.get_filename()
TypeError: must be str, not NoneType

Plus, I'm trying to change the code to download received files within 24 hours from INBOX and save in my download folder.

import imaplib, email, os
user = "***"
password = "***"
imap_url = "smtp.outlook.com"
attachment_dir = "/GGG/"
# sets up the auth
def auth(user,password,imap_url):
    con = imaplib.IMAP4_SSL(imap_url)
    con.login(user,password)
    return con
# extracts the body from the email
def get_body(msg):
    if msg.is_multipart():
        return get_body(msg.get_payload(0))
    else:
        return msg.get_payload(None,True)
# allows you to download attachments
def get_attachments(msg,email_id):
    for part in msg.walk():
        if part.get_content_maintype()=='multipart':
            continue
        if part.get('Content-Disposition') is None:
            continue
        fileName = '{} '.format(email_id)+part.get_filename()

        if bool(fileName):
            filePath = os.path.join(attachment_dir, fileName)
            with open(filePath,'wb') as f:
                f.write(part.get_payload(decode=True))
#search for a particular email
def search(key,value,con):
    result, data  = con.search(None,key,'"{}"'.format(value))
    return data
#extracts emails from byte array
def get_emails(result_bytes):
    msgs = []
    for num in result_bytes[0].split():
        typ, data = con.fetch(num, '(RFC822)')
        msgs.append(data)
    return msgs

con = auth(user,password,imap_url)

#All I added is below here
#########################################################
#A method of obtaining inbox size
inbox_size = int(con.select('INBOX')[1][0])

#Here I used a for loop to go through all email ids
for email_id in range(1,inbox_size+1):
    result, data = con.fetch(str(email_id).encode(),'(RFC822)')
    raw = email.message_from_bytes(data[0][1])
    get_attachments(raw,email_id)
Community
  • 1
  • 1
Raj
  • 585
  • 4
  • 16
  • 28
  • Did you check this link: https://stackoverflow.com/questions/39656433/how-to-download-outlook-attachment-from-python-script – Alina Li Nov 05 '18 at 07:10
  • @AlinaLi Thanks for pointing out. I ran the code posted by mahendra prabu. It throws an error "self is not defined". Tried debugging but no luck. No explanation in the code as well, so it was hard to understand. – Raj Nov 05 '18 at 07:21
  • @AlinaLi I'm using Mac, win32.client is not available. Kinda stuck. – Raj Nov 05 '18 at 07:24

1 Answers1

2

According to your describe, you could try the below code:

import win32com.client, datetime

outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder(6).Folders('Paper & CD')
messages = inbox.Items
date_now = datetime.datetime.now().date()
date_before = (datetime.datetime.now() + datetime.timedelta(-1)).date()
messages.Find("[Start] >= """ & date_before & """ and [Start] <= """ & date_now & """")

for msg in messages:        
    for att in msg.Attachments:
        if att.FileName == 'list.csv': 
            att.SaveAsFile('C:\\My\\temp\\' + msg.subject + att.FileName)
        att.SaveAsFile('C:\\My\\temp\\' + att.FileName)
Alina Li
  • 884
  • 1
  • 6
  • 5
  • Thanks for your answer. Could you please tell me whether it works in Linux or mac? – Raj Nov 05 '18 at 11:37
  • You can use this on mac. Please refer to this link: https://stackoverflow.com/questions/29629400/can-i-use-win32com-client-for-macos – Alina Li Nov 06 '18 at 01:28