cragr: add support for credit cards

This commit is contained in:
Noé Rubinstein 2013-07-26 20:54:24 +02:00 committed by Romain Bignon
commit f1d3f03a92
2 changed files with 116 additions and 8 deletions

View file

@ -24,7 +24,8 @@ import re
from weboob.tools.browser import BaseBrowser, BrowserIncorrectPassword from weboob.tools.browser import BaseBrowser, BrowserIncorrectPassword
from weboob.tools.date import LinearDateGuesser from weboob.tools.date import LinearDateGuesser
from .pages import HomePage, LoginPage, LoginErrorPage, AccountsPage, SavingsPage, TransactionsPage, UselessPage from .pages import HomePage, LoginPage, LoginErrorPage, AccountsPage, \
SavingsPage, TransactionsPage, UselessPage, CardsPage
__all__ = ['Cragr'] __all__ = ['Cragr']
@ -43,6 +44,8 @@ class Cragr(BaseBrowser):
'https?://[^/]+/stb/collecteNI\?.*sessionAPP=Releves.*': TransactionsPage, 'https?://[^/]+/stb/collecteNI\?.*sessionAPP=Releves.*': TransactionsPage,
'https?://[^/]+/stb/.*/erreur/.*': LoginErrorPage, 'https?://[^/]+/stb/.*/erreur/.*': LoginErrorPage,
'https?://[^/]+/stb/entreeBam\?.*act=Messagesprioritaires': UselessPage, 'https?://[^/]+/stb/entreeBam\?.*act=Messagesprioritaires': UselessPage,
'https?://[^/]+/stb/collecteNI\?.*fwkaction=Cartes.*': CardsPage,
'https?://[^/]+/stb/collecteNI\?.*fwkaction=Detail.*sessionAPP=Cartes.*': CardsPage,
} }
class WebsiteNotSupported(Exception): class WebsiteNotSupported(Exception):
@ -127,6 +130,14 @@ class Cragr(BaseBrowser):
if not self.is_on_page(AccountsPage): if not self.is_on_page(AccountsPage):
self.location(self.accounts_url) self.location(self.accounts_url)
accounts_list.extend(self.page.get_list()) accounts_list.extend(self.page.get_list())
# credit cards
cards_page = self.page.cards_page()
if cards_page:
self.location(cards_page)
assert self.is_on_page(CardsPage)
accounts_list.extend(self.page.get_list())
# savings accounts # savings accounts
self.location(self.savings_url) self.location(self.savings_url)
if self.is_on_page(SavingsPage): if self.is_on_page(SavingsPage):
@ -150,15 +161,20 @@ class Cragr(BaseBrowser):
if account._link is None: if account._link is None:
return return
self.location(account._link)
url = account._link
date_guesser = LinearDateGuesser() date_guesser = LinearDateGuesser()
self.location(account._link)
while url: if self.is_on_page(CardsPage):
self.location(url)
assert self.is_on_page(TransactionsPage)
for tr in self.page.get_history(date_guesser): for tr in self.page.get_history(date_guesser):
yield tr yield tr
else:
url = account._link
url = self.page.get_next_url() while url:
self.location(url)
assert self.is_on_page(TransactionsPage)
for tr in self.page.get_history(date_guesser):
yield tr
url = self.page.get_next_url()

View file

@ -20,6 +20,7 @@
import re import re
from decimal import Decimal from decimal import Decimal
from weboob.tools.date import parse_french_date
from weboob.capabilities.bank import Account from weboob.capabilities.bank import Account
from weboob.tools.browser import BasePage from weboob.tools.browser import BasePage
from weboob.tools.capabilities.bank.transactions import FrenchTransaction as Transaction from weboob.tools.capabilities.bank.transactions import FrenchTransaction as Transaction
@ -101,6 +102,97 @@ class _AccountsPage(BasePage):
yield account yield account
def cards_page(self):
try:
return self.document.xpath('//table[@class="ca-table"]' +
'/tr[@class="ligne-connexe"]' +
'//a/@href')[0]
except IndexError:
pass
class CardsPage(BasePage):
def get_list(self):
TABLE_XPATH = '//table[caption[@class="caption tdb-cartes-caption"]]'
cards_tables = self.document.xpath(TABLE_XPATH)
if cards_tables:
# There are several cards
xpaths = {
'_id': './caption/span[@class="tdb-cartes-num"]',
'label1': './caption/span[@class="tdb-cartes-carte l30"]',
'label2': './caption/span[@class="tdb-cartes-prop"]',
'balance': './/tr[last()]/td[@class="cel-num"]',
'currency': '//table/caption//span/text()[starts-with(.,"Montants en ")]',
'link': './/tr//a/@href',
}
else:
xpaths = {
'_id': './/tr/td[@class="cel-texte"]',
'label1': './/tr[@class="ligne-impaire ligne-bleu"]/th',
'label2': './caption/span[@class="tdb-cartes-prop"]/b',
'balance': './/tr[last()-1]/td[@class="cel-num"]',
'currency': '//table/caption//span/text()[starts-with(.,"Montants en ")]',
}
TABLE_XPATH = '(//table[@class="ca-table"])[1]'
cards_tables = self.document.xpath(TABLE_XPATH)
for table in cards_tables:
get = lambda name: self.parser.tocleanstring(table.xpath(xpaths[name])[0])
account = Account()
account.id = ''.join(get('_id').split()[1:])
account.label = '%s - %s' % (get('label1'),
re.sub('\s*-\s*$', '', get('label2')))
account.balance = Decimal(Transaction.clean_amount(get('balance')))
account.currency = account.get_currency(self.document
.xpath(xpaths['currency'])[0].replace("Montants en ", ""))
if 'link' in xpaths:
account._link = table.xpath(xpaths['link'])[-1]
else:
account._link = self.url
yield account
def get_history(self, date_guesser):
seen = set()
lines = self.document.xpath('(//table[@class="ca-table"])[2]/tr')
for line in lines[1:]: # first line is balance
is_balance = line.xpath('./td/@class="cel-texte cel-neg"')
[date, label, _, amount] = [self.parser.tocleanstring(td)
for td in line.xpath('./td')]
clean_amount = Decimal(Transaction.clean_amount(amount))
t = Transaction(0)
if is_balance:
date_str = label.replace( u"Opérations débitées le ", "") \
.replace(" :","")
t.date = parse_french_date(date_str)
t.label = u"Débit"
t.amount = -clean_amount
else:
day, month = map(int, date.split('/', 1))
t.date = date_guesser.guess_date(day, month)
t.label = t.raw = label
t.amount = clean_amount
t.type = t.TYPE_CARD
t.rdate = t.date
try:
t.id = t.unique_id(seen)
except UnicodeEncodeError:
print t
print t.label
raise
yield t
class AccountsPage(_AccountsPage): class AccountsPage(_AccountsPage):
pass pass