document.write('
Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. #python2.7
  2. from bz2 import BZ2File
  3. import argparse
  4. import csv
  5. import datetime
  6. import email
  7. import email.utils
  8. import imaplib
  9. import logging
  10. import parsedatetime
  11. import os
  12. import re
  13. import time
  14. import titlecase
  15.  
  16. LOGFILE=\'procmail.py.log\'
  17. rows = []
  18.  
  19. def add_paypal(data_in):
  20.     spot_re = re.compile(\'Merchant:.*\\n(.*)\\n\')
  21.     amt_re = re.compile(\'Payment: =24([^ ]+)\')
  22.     date_re = re.compile(\'Date: (.*)\')
  23.     logging.fatal(\'Paypal found!\')
  24.     spot = spot_re.search(data_in)
  25.     amt = amt_re.search(data_in)
  26.     datematch = date_re.search(data_in)
  27.     date_ = email.utils.parsedate(datematch.group(1))
  28.     date = datetime.datetime(*date_[:6]).isoformat()
  29.     data = [spot.group(1).strip(), amt.group(1).strip(), date]
  30.     rows.append([data[0], data[1], data[2]])
  31.  
  32. def add_amazon(data_in):
  33.     logging.debug(\'Amazon found!\')
  34.     amt_re = re.compile(r\'Grand Total:[^$]+\\$([0-9.]+)\')
  35.     date_re = re.compile(\'Date: (.*) -0[87]00\')
  36.     spot = \'Amazon\'
  37.     amt = amt_re.search(data_in)
  38.     date = date_re.search(data_in)
  39.     date = datetime.datetime.strptime(date.group(1),\'%a, %d %b %Y %H:%M:%S\')
  40.     date = date.isoformat()
  41.     data = [spot, amt.group(1), date]
  42.     rows.append([data[0], data[1], data[2]])
  43.  
  44. def add_lyft(data_in):
  45.     logging.debug(\'Lyft found!\')
  46.     date = amt = None
  47.     date_reg = \'Date: (.*).{7}\'
  48.     date_re = re.compile(date_reg)
  49.     date_fmt = \'%d %B %Y %H:%M\'
  50.     amt_fmt = \'Total charged to[^$]+\\$+([0-9.]+)\'
  51.     amt_re = re.compile(amt_fmt)
  52.     if date_re.search(data_in):
  53.         logging.debug(\'date match!\')
  54.         date_match = date_re.findall(data_in)[2]
  55.         date_match = date_match[:date_match.rindex(\'<br>\')]
  56.         date_line = date_match
  57.         logging.debug(\'dateline found: {}\'.format(date_line))
  58.         try:
  59.             date = datetime.datetime.strptime(date_line, date_fmt).isoformat()
  60.             logging.debug(\'Date is {}\'.format(date))
  61.         except ValueError:
  62.             pass
  63.     if amt_re.search(data_in) is not None:
  64.         amt = amt_re.search(data_in).group(1)
  65.         logging.debug(\'Amount: {}\'.format(amt))
  66.  
  67.     logging.debug(\'Date: {0}, Amount: {1}, Location: Lyft\'.format(date,amt))
  68.     if date is not None and amt is not None:
  69.         rows.append([\'Lyft\', amt, date])
  70.  
  71. # TODO add calendar events requests
  72. """
  73. If on the event day, popup event
  74. """
  75. def google_event_alert(data_in):
  76.     p = parsedatetime.Calendar()
  77.     try:
  78.         event_time_struct = p.parse(data_in)
  79.     except Exception, e:
  80.         return
  81.     logging.debug(event_time_struct)
  82.     event_epoch_time = time.mktime(event_time_struct[0])
  83.     event_time = datetime.datetime.fromtimestamp(event_epoch_time)
  84.     logging.debug(\'date is {}\'.format(event_time.date()))
  85.     if event_time.date() == datetime.datetime.now().date():
  86.         if event_time > datetime.datetime.now():
  87.             logging.debug(\'event is today, but in the future\')
  88.            
  89. def add_rcpt(contents):
  90.     msg = email.message_from_string(contents)
  91.     logging.debug(msg._headers)
  92.     for h in msg._headers:
  93.         if h[0] == \'Subject\':
  94.             if h[1].startswith(\'Rcpt: \'):
  95.                 parts = h[1].split(\' \')
  96.                 amount = parts[-1]
  97.                 spot = h[1][6:h[1].rindex(amount)].strip()
  98.         if h[0] == \'Date\':
  99.             date = email.utils.parsedate(h[1])
  100.     logging.debug(\'Date: "{0}"; Location: "{1}"; Amount: "{2}"\'.format(date, spot, amount))
  101.     rows.append([titlecase.titlecase(spot), amount, datetime.datetime.fromtimestamp(time.mktime(date)).isoformat()])
  102.  
  103. def receipts(FILE):
  104.     with BZ2File(FILE,\'w\') as rcptOut:
  105.         writer = csv.writer(rcptOut, quoting=csv.QUOTE_ALL)
  106.         writer.writerow([\'Store\',\'Amount\',\'Timestamp\'])
  107.         writer.writerows(rows)
  108.  
  109. if __name__ == \'__main__\':
  110.     try:
  111.         os.unlink(LOGFILE)
  112.     except OSError:
  113.         pass
  114.     parser = argparse.ArgumentParser(description=\'Process mail\')
  115.     parser.add_argument(\'-u\', \'--username\', type=str, help=\'IMAP Username\', default=\'hd1@jsc.d8u.us\')
  116.     parser.add_argument(\'-p\', \'--password\', type=str, help=\'IMAP Password\')
  117.     parser.add_argument(\'-s\', \'--server\', type=str, help=\'IMAP server\', default=\'imap.gmail.com\')
  118.     parser.add_argument(\'--out\', type=str, help=\'Receipts logging file\', default=\'/home/hdiwan/rcpts.bz2\')
  119.     parser.add_argument(\'--ssl\', action=\'store_true\', help=\'SSL IMAP server?\', default=True)
  120.     args = parser.parse_args()
  121.  
  122.     logging.basicConfig(level=logging.DEBUG, filemode=\'w\', filename=LOGFILE, format=\'"%(asctime)s","%(message)s"\')
  123.     logging.debug(\'{}\'.format(sorted(dir(args))))
  124.     logging.debug(\'Username: {0}; Password: {1}; Server: {2}\'.format(args.username, args.password, args.server))
  125.     if args.ssl:
  126.         mail = imaplib.IMAP4_SSL(\'{}\'.format(args.server))
  127.         logging.debug(\'ssl!\')
  128.     else:
  129.         mail = imaplib.IMAP4(\'{}\'.format(args.server))
  130.         logging.debug(\'no ssl!\')
  131.     mail.login(u\'{}\'.format(args.username),\'{}\'.format(args.password))
  132.     logging.debug(\'logged in!\')
  133.     mail.select(u\'inbox\', readonly=True)
  134.     logging.debug(\'inbox selected\')
  135.     result,data = mail.search(None, \'ALL\')
  136.     logging.debug(\'iterating through messages\')
  137.  
  138.     for id_ in data[0].split(\' \'):
  139.         contents = mail.fetch(id_, \'(RFC822)\')[1][0][1]
  140.         if contents.find(\'Amazon.com\') != -1:
  141.             add_amazon(contents)
  142.         elif contents.find(\'@paypal.com\') != -1:
  143.             add_paypal(contents)
  144.         elif contents.find(\'<no-reply@lyftmail.com>\') != -1:
  145.             add_lyft(contents)
  146.         elif contents.find(\'Subject: Rcpt\') != -1:
  147.             add_rcpt(contents)
  148.  
  149.         #elif contents.find(\'www.google.com/calendar/event\'):
  150.         #   google_event_alert(contents)
  151.     receipts(args.out)
  152.     messages = len(data[0].split(\' \'))
  153.     print(\'Processed {0} messages\'.format(messages))
');