ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/repos/FreeBSDAdmin/Reminder/dtwesabe.py
Revision: 1180
Committed: 2009-05-19T21:16:13-07:00 (16 years, 1 month ago) by douglas
Content type: text/x-python
File size: 3538 byte(s)
Log Message:
Working Wesabe upload.

File Contents

# User Rev Content
1 douglas 1180 # DT Wesabe
2 douglas 1178 #
3     # Douglas Thrift
4     #
5     # $Id$
6    
7 douglas 1180 from datetime import datetime
8     import decimal
9 douglas 1178 from M2Crypto import m2urllib2, SSL
10 douglas 1180 import urllib2
11     from xml.etree import ElementTree
12 douglas 1178
13 douglas 1180 EPOCH = datetime.utcfromtimestamp(0)
14     ISO_8601 = '%Y-%m-%dT%H:%M:%SZ'
15    
16     class Account(object):
17     def __init__(self, account):
18     self.id = int(account.find('id').text)
19     self.guid = account.find('guid').text
20     account_number = account.find('account-number')
21     self.account_number = int(account_number.text) if account_number is not None else None
22     self.name = account.find('name').text
23     financial_institution = account.find('financial-institution')
24     self.financial_institution = FinancialInstitution(financial_institution) if financial_institution is not None else None
25     self.account_type = account.find('account-type').text
26     self.currency = Currency(account.find('currency'))
27     current_balance = account.find('current-balance')
28    
29     assert current_balance.get('type') == 'float'
30    
31     self.current_balance = decimal.Decimal(current_balance.text)
32     last_uploaded_at = account.find('last-uploaded-at')
33    
34     if last_uploaded_at is not None:
35     assert last_uploaded_at.get('type') == 'datetime'
36    
37     self.last_uploaded_at = datetime.strptime(last_uploaded_at.text, ISO_8601)
38     else:
39     self.last_uploaded_at = EPOCH
40    
41     self.txaction_count = int(account.find('txaction-count').text)
42     oldest_txaction = account.find('oldest-txaction')
43    
44     if oldest_txaction is not None:
45     assert oldest_txaction.get('type') == 'datetime'
46    
47     self.oldest_txaction = datetime.strptime(oldest_txaction.text, ISO_8601)
48     else:
49     self.oldest_txaction = EPOCH
50    
51     newest_txaction = account.find('newest-txaction')
52    
53     if newest_txaction is not None:
54     assert newest_txaction.get('type') == 'datetime'
55    
56     self.newest_txaction = datetime.strptime(newest_txaction.text, ISO_8601)
57     else:
58     self.newest_txaction = EPOCH
59    
60     class Currency(object):
61     def __init__(self, currency):
62     self.symbol = currency.get('symbol')
63     self.separator = currency.get('separator')
64     self.delimiter = currency.get('delimiter')
65     self.decimal_places = int(currency.get('decimal_places'))
66     self.name = currency.text
67    
68     class FinancialInstitution(object):
69     def __init__(self, financial_institution):
70     self.id = financial_institution.find('id').text
71     self.name = financial_institution.find('name').text
72    
73 douglas 1178 class Wesabe(object):
74 douglas 1180 def __init__(self, email, password):
75 douglas 1178 context = SSL.Context()
76    
77     context.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, depth = 9)
78     context.load_verify_locations('/etc/ssl/cert.pem')
79    
80 douglas 1180 handler = urllib2.HTTPBasicAuthHandler()
81 douglas 1178
82 douglas 1180 handler.add_password('RESTRICTED', 'https://www.wesabe.com/', email, password)
83     handler.add_password('Wesabe Upload API', 'https://api.wesabe.com/rest/upload/statement', email, password)
84 douglas 1178
85 douglas 1180 self.opener = m2urllib2.build_opener(context, handler)
86    
87     def accounts(self):
88     accounts = ElementTree.parse(self.opener.open('https://www.wesabe.com/accounts.xml')).getroot()
89 douglas 1178
90 douglas 1180 return map(lambda account: Account(account), accounts.getchildren())
91 douglas 1178
92 douglas 1180 def upload(self, account_number, account_type, wesabe_id, data, balance = None):
93     upload = ElementTree.Element('upload')
94     statement = ElementTree.SubElement(upload, 'statement')
95    
96     statement.set('acctid', str(account_number))
97     statement.set('accttype', account_type)
98     statement.set('wesabe_id', wesabe_id)
99    
100     if balance is not None:
101     statement.set('balance', str(balance))
102    
103     statement.text = data
104    
105     self.opener.open('https://api.wesabe.com/rest/upload/statement', ElementTree.tostring(upload, 'UTF-8'))

Properties

Name Value
svn:keywords Id