I am using exchangelib to connect to my exchange mailbox. Currently the code is scanning through all folders since the target email message can be in any of the folders for my task.
Is there a more efficient way for looping/scanning the folders here? (Looking for emails greater than a target start date)
all_folders = account.root.glob('**/*') for folder in all_folders: # Messages can only exist in 'IPF.Note' folder classes if folder.folder_class == 'IPF.Note': # For all emails that are newer than the target date for email in folder.filter(datetime_received__gt=ews_bfr): # Do something
Edit: Thanks for the help, Erik. This worked and made the run time decrease dramatically:
target_folders = (f for f in account.root.walk() if f.name in ['xxxxxx']) folder_coll = FolderCollection(account=account, folders=target_folders) for email in folder_coll.filter(datetime_received__gt=ews_bfr): # Do something
Advertisement
Answer
A normal .filter()
works on just the folder you call it on. EWS does not support searching items within all folders, but only the folders explicitly mentioned in the FindItems
service call.
In exchangelib, the way to filter on multiple folders in one go is to use a FolderCollection
:
from exchangelib import FolderCollection FolderCollection(account=account, folders=[...]).filter(some_field='foo')
The folders
argument can be any iterable of folders, e.g. [account.inbox, account.sent]
, account.root.walk()
or (f for f in account.root.walk() if f.CONTAINER_CLASS == 'IPF.Note')
.glob()
, .walk()
, .children
and other subfolder access methods also support calling .filter()
on them:
account.root.glob('**/*').filter(datetime_received__gt=ews_bfr) account.root.walk().filter(datetime_received__gt=ews_bfr)