paypal: History support through CSV download

This commit is contained in:
Laurent Bachelier 2013-02-05 16:25:10 +01:00
commit f5c80141ff
2 changed files with 70 additions and 6 deletions

View file

@ -19,7 +19,7 @@
from weboob.tools.browser import BaseBrowser, BrowserIncorrectPassword from weboob.tools.browser import BaseBrowser, BrowserIncorrectPassword
from .pages import LoginPage, AccountPage, DownloadHistoryPage from .pages import LoginPage, AccountPage, DownloadHistoryPage, SubmitPage, HistoryParser
__all__ = ['Paypal'] __all__ = ['Paypal']
@ -29,12 +29,13 @@ class Paypal(BaseBrowser):
DOMAIN = 'www.paypal.com' DOMAIN = 'www.paypal.com'
PROTOCOL = 'https' PROTOCOL = 'https'
# CERTHASH = '74429081f489cb723a82171a94350913d42727053fc86cf5bf5c3d65d39ec449' # CERTHASH = '74429081f489cb723a82171a94350913d42727053fc86cf5bf5c3d65d39ec449'
ENCODING = None # refer to the HTML encoding ENCODING = 'UTF-8' # useful for CSV
PAGES = { PAGES = {
'/cgi-bin/\?cmd=_login-run$': LoginPage, '/cgi-bin/\?cmd=_login-run$': LoginPage,
'/cgi-bin/\?cmd=_login-submit.+$': LoginPage, # wrong login '/cgi-bin/\?cmd=_login-submit.+$': LoginPage, # wrong login
'/cgi-bin/webscr\?cmd=_account&nav=0.0$': AccountPage, '/cgi-bin/webscr\?cmd=_account&nav=0.0$': AccountPage,
'/cgi-bin/webscr\?cmd=_history-download&nav=0.3.1$': DownloadHistoryPage, '/cgi-bin/webscr\?cmd=_history-download&nav=0.3.1$': DownloadHistoryPage,
'/cgi-bin/webscr\?dispatch=[a-z0-9]+$': (SubmitPage, HistoryParser()),
} }
def home(self): def home(self):
@ -69,12 +70,15 @@ class Paypal(BaseBrowser):
return self.page.get_account(_id) return self.page.get_account(_id)
def get_history(self, account): def get_history(self, account):
raise NotImplementedError() self.download_history()
for transaction in self.page.iter_transactions(account):
yield transaction
def download_history(self): def download_history(self):
self.location('/en/cgi-bin/webscr?cmd=_history-download&nav=0.3.1') self.location('/en/cgi-bin/webscr?cmd=_history-download&nav=0.3.1')
assert self.is_on_page(DownloadHistoryPage) assert self.is_on_page(DownloadHistoryPage)
self.page.download() self.page.download()
return self.page.document
def transfer(self, from_id, to_id, amount, reason=None): def transfer(self, from_id, to_id, amount, reason=None):
raise NotImplementedError() raise NotImplementedError()

View file

@ -22,7 +22,8 @@ import re
import datetime import datetime
from weboob.tools.browser import BasePage, BrokenPageError from weboob.tools.browser import BasePage, BrokenPageError
from weboob.capabilities.bank import Account from weboob.tools.parsers.csvparser import CsvParser
from weboob.capabilities.bank import Account, Transaction
from weboob.tools.capabilities.bank.transactions import FrenchTransaction from weboob.tools.capabilities.bank.transactions import FrenchTransaction
__all__ = ['LoginPage', 'AccountPage'] __all__ = ['LoginPage', 'AccountPage']
@ -128,8 +129,67 @@ class DownloadHistoryPage(BasePage):
self.browser['from_a'] = str(today.month) self.browser['from_a'] = str(today.month)
self.browser['from_b'] = str(today.day) self.browser['from_b'] = str(today.day)
# only "real" stuff, no cancelled payments self.browser['custom_file_type'] = ['comma_allactivity']
self.browser['custom_file_type'] = ['comma_completed']
self.browser['latest_completed_file_type'] = [''] self.browser['latest_completed_file_type'] = ['']
self.browser.submit() self.browser.submit()
class SubmitPage(BasePage):
"""
Any result of form submission
"""
def iter_transactions(self, account):
csv = self.document
for row in csv.drows:
# only "real" stuff, no cancelled payments etc.
if row['Status'] != 'Completed':
continue
# we filter accounts by currency
if account.get_currency(row['Currency']) != account.currency:
continue
# does not seem to be a real transaction; duplicates others
if row['Type'] == u'Authorization':
continue
trans = Transaction(row['Transaction ID'])
# silly American locale
if re.search(r'\d\.\d\d$', row['Net']):
date = datetime.datetime.strptime(row['Date'] + ' ' + row['Time'], "%m/%d/%Y %I:%M:%S %p")
else:
date = datetime.datetime.strptime(row['Date'] + ' ' + row['Time'], "%d/%m/%Y %H:%M:%S")
trans.date = date
trans.rdate = date
line = row['Name']
if row['Item Title']:
line += u' ' + row['Item Title']
if row['Auction Site']:
line += u"(" + row['Auction Site'] + u")"
trans.raw = line
trans.label = row['Name']
if row['Type'].endswith(u'Credit Card'):
trans.type = Transaction.TYPE_CARD
elif row['Type'].endswith(u'Payment Sent'):
trans.type = Transaction.TYPE_ORDER
elif row['Type'] == u'Currency Conversion':
trans.type = Transaction.TYPE_BANK
else:
trans.type = Transaction.TYPE_UNKNOWN
# Net is what happens after the fee (0 for most users), so what is the most "real"
trans.amount = clean_amount(row['Net'])
trans._gross = clean_amount(row['Gross'])
trans._fees = clean_amount(row['Fee'])
trans._to = row['To Email Address'] or None
trans._from = row['From Email Address'] or None
yield trans
class HistoryParser(CsvParser):
HEADER = True
FMTPARAMS = {'skipinitialspace': True}