Python – Searching different imap inboxes based on conditions

Question:

Is there a way to search different Inboxes based on a condition with the python imap4-library?
I simply can’t wrap my head around a way to check certain subfolders based on a condition.
Until now I’m selecting the subfolders from “Inbox” like this:

imap = imaplib.IMAP4_SSL(host=imap_host)
imap.login(imap_user, imap_pass)

unseen_mails = imap.select('Inbox.Private.folder1')

# this is the second subfolder within "Private"
# unseen_mails = imap.select('Inbox.Private.folder2')

unseen_mails = imap.search(None, '(UNSEEN)')
unseen_mails = unseen_mails[1]
print(unseen_mails)

Would be glad if someone could figure out where my brain stopped functioning.

Asked By: Fullbringa

||

Answers:

imap.list() lists all folders and sub-folders, and imap.list(directory = 'Inbox') lists all of Inbox’s children. You can then extract the folder names and search for all that have a / in the name to find the sub-folders.

for folder in (imap.list()[1]):
    folder = folder.decode()                        # folder = '(Marked HasNoChildren) "/" "Inbox/Privare/Subfolder1"'
    flags, name = folder.split(' "/" ')             # name = 'Inbox/Private/Subfolder1'

    if '/' in name:
        split_val = name.split('/')
        folderName = split_val[-1]                  # folderName = 'Subfolder1'
        parents = split_val[0:-1]                   # parents = ['Inbox', 'Private']

    flags = flags.split('\')
    flags.remove(flags[0])
    flags = [each.strip(' )') for each in flags]    # flags = ['Marked', 'HasChildren']


name = 'Inbox'    # Example of fetching list for directory
typ, data = imap.list(directory = name) 

# [ b'(\Marked \HasChildren) "/" "Inbox"',
#   b'(\HasNoChildren) "/" "Inbox/Subfolder"' ]

Hope this helps

Answered By: gandhiv

Thank you guys for your help. I sort of figured it out myself. When you fetch the status of an inbox you get an dict and the dict[1] is the number of the unread message. If this is empty it simply returns “[b”]” so I wrote a if clause which compares my output to that of an empty inbox no_mails = [b”] and told the code to run this across all subfolders.

Answered By: Fullbringa
from imap_tools import MailBox
with MailBox('imap.mail.com').login('[email protected]', 'password') as mailbox:
    # get all folders
    for f in mailbox.folder.list():
        print(f['name'])
    # get INBOX subfolders
    for f in mailbox.folder.list('INBOX'):
        print(f['name'])

https://github.com/ikvk/imap_tools

Answered By: Vladimir

I came across this answer trying to make it so it will only list sub folders within the INBOX rather than all folders. So for example if the folder setup was;

-INBOX
--folder1
---folder1-1
---folder1-2
--folder2

I only wanted folder1 and folder2, not folder1-1 and folder1-2 as well.
Doing;

for folder in imap.list(pattern="/%")[1]:
    print(folder.decode().split(' "/" ')[1])

prints

INBOX/folder1
INBOX/folder2

From https://readthedocs.org/projects/imapclient/downloads/pdf/master/

"% matches 0 or more characters except the folder delimiter" which is a "/".

Answered By: Destroyer467
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.