1 |
douglas |
1179 |
# Credit Cards |
2 |
douglas |
1131 |
# |
3 |
|
|
# Douglas Thrift |
4 |
|
|
# |
5 |
|
|
# $Id$ |
6 |
|
|
|
7 |
|
|
import atom |
8 |
douglas |
1424 |
from datetime import date, datetime, timedelta |
9 |
|
|
import email |
10 |
douglas |
1131 |
import gdata.calendar |
11 |
douglas |
1424 |
import re |
12 |
douglas |
1131 |
|
13 |
douglas |
1424 |
def creditcard(name): |
14 |
|
|
class CreditCard(object): |
15 |
|
|
def __init__(self, function): |
16 |
|
|
self.function = function |
17 |
|
|
creditcards[function.__name__] = self |
18 |
douglas |
1181 |
|
19 |
douglas |
1424 |
def __call__(self, *args, **kwargs): |
20 |
|
|
return name, self.function(*args, **kwargs) |
21 |
douglas |
1145 |
|
22 |
douglas |
1424 |
return CreditCard |
23 |
douglas |
1131 |
|
24 |
douglas |
1424 |
creditcards = {} |
25 |
douglas |
1131 |
|
26 |
douglas |
1424 |
@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 |
douglas |
1131 |
|
30 |
douglas |
1424 |
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 |
douglas |
1131 |
|
37 |
douglas |
1424 |
if match is not None: |
38 |
|
|
return datetime.strptime(match.group(1), '%m/%d/%Y').date() |
39 |
douglas |
1131 |
|
40 |
douglas |
1424 |
@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 |
douglas |
1131 |
|
44 |
douglas |
1424 |
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 |
douglas |
1131 |
else: |
95 |
douglas |
1424 |
event.when[0].reminder.append(reminder) |
96 |
|
|
|
97 |
|
|
calendar.UpdateEvent(event.GetEditLink().href, event) |
98 |
|
|
else: |
99 |
|
|
calendar.DeleteEvent(event.GetEditLink().href) |