1 |
# Credit Cards |
2 |
# |
3 |
# Douglas Thrift |
4 |
# |
5 |
# $Id$ |
6 |
|
7 |
import atom |
8 |
from datetime import date, datetime, timedelta |
9 |
import email |
10 |
import gdata.calendar |
11 |
import re |
12 |
|
13 |
def creditcard(name): |
14 |
class CreditCard(object): |
15 |
def __init__(self, function): |
16 |
self.function = function |
17 |
creditcards[function.__name__] = self |
18 |
|
19 |
def __call__(self, *args, **kwargs): |
20 |
return name, self.function(*args, **kwargs) |
21 |
|
22 |
return CreditCard |
23 |
|
24 |
creditcards = {} |
25 |
|
26 |
@creditcard('Wells Fargo MasterCard') |
27 |
def wellsfargo(imap): |
28 |
subject = re.compile(r'Wells Fargo Credit Card Payment Due on ([0-9]{2}/[0-9]{2}/[0-9]{4})') |
29 |
|
30 |
for message in map(int, imap.search(None, |
31 |
'FROM', 'alerts@notify.wellsfargo.com', |
32 |
'SUBJECT', 'Wells Fargo Credit Card Payment Due on ', |
33 |
'SINCE', date.today().replace(day = 1).strftime('%d-%b-%Y'), |
34 |
)[1][0].split()): |
35 |
match = subject.search(email.message_from_string(imap.fetch(message, '(BODY.PEEK[HEADER.FIELDS (SUBJECT)])')[1][0][1])['subject']) |
36 |
|
37 |
if match is not None: |
38 |
return datetime.strptime(match.group(1), '%m/%d/%Y').date() |
39 |
|
40 |
@creditcard('Shell MasterCard') |
41 |
def shellmc(imap): |
42 |
due = re.compile(r'Payment Due Date: ([0-9]{2}/[0-9]{2}/[0-9]{2})') |
43 |
|
44 |
for message in map(int, imap.search(None, |
45 |
'FROM', 'alert@shellcreditcard.com', |
46 |
'SUBJECT', 'Credit Card - Minimum Payment Due', |
47 |
'SINCE', date.today().replace(day = 1).strftime('%d-%b-%Y'), |
48 |
)[1][0].split()): |
49 |
match = due.search(imap.fetch(message, '(BODY.PEEK[1])')[1][0][1]) |
50 |
|
51 |
if match is not None: |
52 |
return datetime.strptime(match.group(1), '%m/%d/%y').date() |
53 |
|
54 |
def main(calendar, imap, config, debug): |
55 |
reminder = gdata.calendar.Reminder(hours = 2) |
56 |
|
57 |
imap.select(readonly = True) |
58 |
|
59 |
for name, due in map(lambda creditcard: creditcards[creditcard](imap), config.getlist('creditcards')): |
60 |
if due is None: |
61 |
continue |
62 |
|
63 |
today = date.today() |
64 |
|
65 |
if due <= today: |
66 |
continue |
67 |
|
68 |
title = '%s Due' % name |
69 |
query = gdata.calendar.service.CalendarEventQuery('default', 'private', 'full', '"%s"' % title) |
70 |
query.start_min = str(today) |
71 |
events = calendar.CalendarQuery(query).entry |
72 |
|
73 |
if not events: |
74 |
event = gdata.calendar.CalendarEventEntry() |
75 |
event.title = atom.Title(text = title) |
76 |
event.transparency = gdata.calendar.Transparency() |
77 |
event.transparency.value = 'TRANSPARENT' |
78 |
event.visibility = gdata.calendar.Visibility() |
79 |
event.visibility.value = 'PRIVATE' |
80 |
|
81 |
event.when.append(gdata.calendar.When(start_time = str(due), end_time = str(due + timedelta(1)))) |
82 |
event.when[0].reminder.append(reminder) |
83 |
calendar.InsertEvent(event, '/calendar/feeds/default/private/full') |
84 |
else: |
85 |
for index, event in enumerate(filter(lambda event: event.title.text == title, events)): |
86 |
if index == 0: |
87 |
event.transparency.value = 'TRANSPARENT' |
88 |
event.visibility.value = 'PRIVATE' |
89 |
event.when[0].start_time = str(due) |
90 |
event.when[0].end_time = str(due + timedelta(1)) |
91 |
|
92 |
if event.when[0].reminder: |
93 |
event.when[0].reminder[0] = reminder |
94 |
else: |
95 |
event.when[0].reminder.append(reminder) |
96 |
|
97 |
calendar.UpdateEvent(event.GetEditLink().href, event) |
98 |
else: |
99 |
calendar.DeleteEvent(event.GetEditLink().href) |