开发者

imap search for messages from users on whitelist?

Is it possible to run an imap search for messages from users on a whitelist? I have figured out several variations that work with two names, but I can't figure out how to generalize it. Already tried reading RFC3501 and googling for examples. I am using 开发者_运维知识库python's imaplib and gmail, but I believe that doesn't matter since my problem is figuring out the syntax of the search string.

m = imap(...)
m.search(None, '(OR (FROM "andy@gmail.com") (FROM "beth@gmail.com"))') # works

whitelist = ['andy@gmail.com', 'beth@gmail.com']
searchstring = '(OR ' + ' '.join(['(FROM "' + x + '")' for x in whitelist]) + ')'
m.search(None, searchstring) # works, but doesn't generalize.


Through some local testing I found that the OR in the search works in pairs. So when you search on just two addresses everything works as expected. The minute you need a third though, you need to do the following:

'(OR (FROM "andy@gmail.com") (OR (FROM "beth@gmail.com") (FROM "chad@gmail.com")))'

I found that the spacing was important. If I used this similar string (with spaces between the final closing parens) it would throw an error:

'(OR (FROM "andy@gmail.com") (OR (FROM "beth@gmail.com") (FROM "chad@gmail.com") ) )'

This reminds me of my LISP days... anyway, using the following logic on a list should do the trick:

def buildOr(list):
    "Builds a tree structure like (OR (FROM 'term') (OR (FROM 'term') (FROM 'term')))"
    if len(list) < 2:
        raise RuntimeError('buildOr requires a list of at least 2')
    if len(list) == 2:
        return '(OR (FROM "{0}") (FROM "{1}"))'.format(list[0], list[1]) 
    else:
        return '(OR (FROM "{0}") {1})'.format(list[0], buildOr(list[1:]))

Then you can combine that with your whitelist to do your search as follows:

m.search(None, buildOr(whitelist))
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜