Skip to content

Instantly share code, notes, and snippets.

@bpgergo
Created September 12, 2012 12:12
Show Gist options
  • Save bpgergo/3706220 to your computer and use it in GitHub Desktop.
Save bpgergo/3706220 to your computer and use it in GitHub Desktop.
python email checker
'''
Created on Sep 11, 2012
@author: bpgergo
'''
import mail_checker_conf
import poplib
from email import parser
from itertools import imap, ifilter, tee
from email.utils import parsedate
from time import mktime
from datetime import datetime
'''
log into POP3 email account
'''
def init_pop_mail(conf):
mail = poplib.POP3(conf.POP_HOST)
mail.user(conf.POP_USER)
mail.pass_(conf.POP_PASSWORD)
#import logging
#mail.set_debuglevel(logging.DEBUG)
return mail
'''
return a map with the following keys: 'subject', 'date', 'body'
'''
def parse_mail(message):
result = {}
result['date'] = datetime.fromtimestamp(mktime(parsedate(message['Date'])))
result['subject'] = message['subject']
result['body'] = message['body'] #get_message_body(message)
if result['body'] is None:
#from http://stackoverflow.com/questions/4908472/how-to-recieve-mail-using-python
for part in message.walk():
if part.get_content_type():
result['body'] = part.get_payload(decode=True)
break
return result
'''
return an iterator over the emails from an opened POP account
'''
def get_messages(pop_mail):
#Get messages pieces from server:
messages = imap(lambda i : pop_mail.retr(i), range(1, len(pop_mail.list()[1]) + 1))
# Concat message pieces:
messages = imap(lambda mssg : "\n".join(mssg[1]), messages)
#Parse message intom an email object:
messages = imap(lambda mssg : parse_mail(parser.Parser().parsestr(mssg)), messages)
return messages
def subject_rule(subject):
def f(message):
return subject in message['subject']
return f
def body_rule(body_part):
def f(message):
return body_part in message['body']
return f
def filter_messages_for_process_key(key, conf, messages):
print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
print "filter messages that have 1) %s in subject; 2) %s in body" % (conf.PROCESS_KEYS_SUBJECT[key], conf.PROCESS_KEYS_SALUTATION[key])
subject_filter = ifilter(subject_rule(conf.PROCESS_KEYS_SUBJECT[key]), messages)
body_filter = ifilter(body_rule(conf.PROCESS_KEYS_SALUTATION[key]), subject_filter)
return body_filter
def get_extractor(key, conf):
def extract_payload(message_body):
result = {}
for (pattern_name, pattern) in conf.PROCESS_KEY_PATTERNS[key]:
search = pattern.search(message_body)
if search:
result[pattern_name] = search.groups()[0]
return result
return extract_payload
def debug_payload(payload):
print "(((((((((((((((PAYLOAD)))))))))))))))"
print payload
print "((((((((((((((END PAYLOAD)))))))))))"
def get_processor(key, conf):
extractor = get_extractor(key, conf)
def do_process(message):
payload = extractor(message['body'])
debug_payload(payload)
return do_process
def debug_message(message):
print "============MESSAGE START========"
print "==============DATE====="
print type(message['date']), message['date']
print "=========subject======="
print message['subject']
print "=========body=========="
print message['body']
print "============END MESSAGE========="
'''
iterate over an iterator of messages (do the actual iteration!)
and call processor function on all messages
'''
def process_messages_for_key(key, conf, messages, processor):
for message in messages:
debug_message(message)
processor(message)
def main(conf):
pop_mail = init_pop_mail(conf)
try:
#get an iterator of messages with specified subject
messages = get_messages(pop_mail)
#tee: split the iterator because wi'll want to use it as many times, as many keys we have
for (key, messages) in zip(conf.PROCESS_KEYS, tee(messages, len(conf.PROCESS_KEYS))):
process_messages_for_key(key, conf, filter_messages_for_process_key(key, conf, messages), get_processor(key, conf))
finally:
pop_mail.quit()
if __name__ == '__main__':
main(mail_checker_conf)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment