CameronAtkinson
CameronAtkinson

Reputation: 107

Outlook - Search for attatchments from a specific sender

Continuation of this program Reference list index to enumerate value

This program will search a dictionary of senders against various criteria in outlook (msg.sender msg.subject msg.SenderEmailAddress etc), then download attachments from ALL senders matching the dictionary and criteria. This works fine and I've been using it for a while.

#Code before this allows me to select a date range to search

senderDict = {sender email : sender name}
listSender = list(senderDict.values())
listSender.insert(0, "Search Any")

########### Choose option from listSender
while True:     
        try:
            senderNum = int(input("Choose a sender: "))
            senderChoice = listSender[senderNum] #refer senderNum to list index

            #Search all
            if senderNum == 0:
                    print("Searching for any sender")
                    break


            elif senderNum <= len(listSender) and senderNum > 0:
                    print("you chose", senderChoice)
                    break

            elif senderNum < 0:
                    print("Cannot choose a negative number.")
                    continue


############# CODE TO CHECK SENDER ATTACHMENTS
for msg in reversed(itcontents): #reversed() will go from most recent to oldest email based on date

########## Search for ANY sender
    if msg.Class == 43: #only search mail items (class 43)
            try:                        
                    if ( senderNum == 0 and
                            (str(msg.SenderEmailAddress) or str(msg.Subject) or str(msg.Sender) or str(msg.SentOnBehalfOfName)) in senderDict 
                            and
                             #msg.SentOn date is not older than searchDate or newer than startDate
                            (msg.SentOn.date() >= searchDate and msg.SentOn.date() <= startDate.date())
                        ):
                            check += 1
                            print(check, "messages from", msg.SenderEmailAddress, "on", msg.SentOn.date()) #keep count of checked messages

                            #Check attachment file format string, invoices are usually PDFs.
                            #x refers to the attachment. Not every message from a listed sender has an attachment.
                            for x in msg.Attachments: 
                                    if str(".pdf").casefold() in str(x): #casfold() checks possible upper or lower case combinations e.g PdF or pDf
                                            x.SaveAsFile(r"C:\Users\camerona\Desktop\Invoices from Outlook\\" + str(msg.SentOn.date()) + str(msg.SenderEmailAddress) + x.FileName)
                                            print("Saved attachment", x, "from", str(msg.Sender()), "on", str(msg.SentOn.date()))

It works fine up to here.

Now I am trying to add functionality to only save attachments from a SPECIFIC sender chosen from an enumerated list, created from the dictionary. The process as I understand it: I want to check if the chosen sender string matches the criteria and is in the dictionary. I've tried using the same code for searching ANY.

########## Search for SPECIFIC sender
               elif ( str(senderChoice) in ( str(msg.SenderEmailAddress) or str(msg.Subject) or str(msg.Sender) or str(msg.SentOnBehalfOfName)) in senderDict
                        and
                        (msg.SentOn.date() >= searchDate and msg.SentOn.date() <= startDate.date())
                              ):
                                check += 1
                                print(check, "messages from", msg.SenderEmailAddress, "on", msg.SentOn.date()) #keep count of checked messages

                                #Check attachment file format, invoices are usually PDFs
                                #x refers to the attachment. Not every message from a listed sender has an attachment.
                                for x in msg.Attachments: 
                                        if str(".pdf").casefold() in str(x): #casfold() cheks upper or lower case format
                                                x.SaveAsFile(r"C:\Users\camerona\Desktop\Invoices from Outlook\\" + str(msg.SentOn.date()) + str(msg.SenderEmailAddress) + x.FileName)
                                                print("Saved attachment", x, "from", str(msg.Sender()), "on", str(msg.SentOn.date()))

Output (redacted) looks like this for each attachment:

Choose a sender: 0
Searching for any sender
1 messages from xxxxxxx.com on 2019-12-16
Saved attachment Invoice INV-001172.pdf from xxxxxxxxx on 2019-12-16

Then choosing that sender specifically does nothing:

Choose a sender: 1
you chose xxxxxx
(attachment sumamry should appear like above)

I'm not sure why this isn't working. I feel like it must be something to do with the first line of the elif statement for str(senderChoice).

Upvotes: 1

Views: 102

Answers (1)

Nick Cruz
Nick Cruz

Reputation: 66

Try this in your second block instead mate:

########## Search for SPECIFIC sender
               elif ( senderNum != 0 and
                            (str(msg.SenderEmailAddress) or str(msg.Subject) or str(msg.Sender) or str(msg.SentOnBehalfOfName)) in senderDict 
                            and
                             #msg.SentOn date is not older than searchDate or newer than startDate
                            (msg.SentOn.date() >= searchDate and msg.SentOn.date() <= startDate.date())
                            and
                             #NEW CODE TO CHECK IF THIS IS THE CHOSEN SPECIFIC USER
                            any([field for field in [str(msg.SenderEmailAddress), str(msg.Subject), str(msg.Sender), str(msg.SentOnBehalfOfName)] if str(senderChoice) in field])
                        ):
                                check += 1
                                print(check, "messages from", msg.SenderEmailAddress, "on", msg.SentOn.date()) #keep count of checked messages

                                #Check attachment file format, invoices are usually PDFs
                                #x refers to the attachment. Not every message from a listed sender has an attachment.
                                for x in msg.Attachments: 
                                        if str(".pdf").casefold() in str(x): #casfold() cheks upper or lower case format
                                                x.SaveAsFile(r"C:\Users\camerona\Desktop\Invoices from Outlook\\" + str(msg.SentOn.date()) + str(msg.SenderEmailAddress) + x.FileName)
                                                print("Saved attachment", x, "from", str(msg.Sender()), "on", str(msg.SentOn.date()))

Upvotes: 1

Related Questions