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.
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
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.
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'])
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 "/".
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.
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
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.
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'])
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 "/".