# Credit Cards # # Douglas Thrift # # $Id$ import atom from datetime import date, datetime, timedelta import email import gdata.calendar import re def creditcard(name): class CreditCard(object): def __init__(self, function): self.function = function creditcards[function.__name__] = self def __call__(self, *args, **kwargs): return name, self.function(*args, **kwargs) return CreditCard creditcards = {} @creditcard('Wells Fargo MasterCard') def wellsfargo(imap): subject = re.compile(r'Wells Fargo Credit Card Payment Due on ([0-9]{2}/[0-9]{2}/[0-9]{4})') for message in map(int, imap.search(None, 'FROM', 'alerts@notify.wellsfargo.com', 'SUBJECT', 'Wells Fargo Credit Card Payment Due on ', 'SINCE', date.today().replace(day = 1).strftime('%d-%b-%Y'), )[1][0].split()): match = subject.search(email.message_from_string(imap.fetch(message, '(BODY.PEEK[HEADER.FIELDS (SUBJECT)])')[1][0][1])['subject']) if match is not None: return datetime.strptime(match.group(1), '%m/%d/%Y').date() @creditcard('Shell MasterCard') def shellmc(imap): due = re.compile(r'Payment Due Date: ([0-9]{2}/[0-9]{2}/[0-9]{2})') for message in map(int, imap.search(None, 'FROM', 'alert@shellcreditcard.com', 'SUBJECT', 'Credit Card - Minimum Payment Due', 'SINCE', date.today().replace(day = 1).strftime('%d-%b-%Y'), )[1][0].split()): match = due.search(imap.fetch(message, '(BODY.PEEK[1])')[1][0][1]) if match is not None: return datetime.strptime(match.group(1), '%m/%d/%y').date() def main(calendar, imap, config, debug): reminder = gdata.calendar.Reminder(hours = 2) imap.select(readonly = True) for name, due in map(lambda creditcard: creditcards[creditcard](imap), config.getlist('creditcards')): if due is None: continue today = date.today() if due <= today: continue title = '%s Due' % name query = gdata.calendar.service.CalendarEventQuery('default', 'private', 'full', '"%s"' % title) query.start_min = str(today) events = calendar.CalendarQuery(query).entry if not events: event = gdata.calendar.CalendarEventEntry() event.title = atom.Title(text = title) event.transparency = gdata.calendar.Transparency() event.transparency.value = 'TRANSPARENT' event.visibility = gdata.calendar.Visibility() event.visibility.value = 'PRIVATE' event.when.append(gdata.calendar.When(start_time = str(due), end_time = str(due + timedelta(1)))) event.when[0].reminder.append(reminder) calendar.InsertEvent(event, '/calendar/feeds/default/private/full') else: for index, event in enumerate(filter(lambda event: event.title.text == title, events)): if index == 0: event.transparency.value = 'TRANSPARENT' event.visibility.value = 'PRIVATE' event.when[0].start_time = str(due) event.when[0].end_time = str(due + timedelta(1)) if event.when[0].reminder: event.when[0].reminder[0] = reminder else: event.when[0].reminder.append(reminder) calendar.UpdateEvent(event.GetEditLink().href, event) else: calendar.DeleteEvent(event.GetEditLink().href)