cragr: add support for credit cards
This commit is contained in:
parent
4502b9b015
commit
f1d3f03a92
2 changed files with 116 additions and 8 deletions
|
|
@ -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,9 +161,14 @@ 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)
|
||||||
|
|
||||||
|
if self.is_on_page(CardsPage):
|
||||||
|
for tr in self.page.get_history(date_guesser):
|
||||||
|
yield tr
|
||||||
|
else:
|
||||||
|
url = account._link
|
||||||
|
|
||||||
while url:
|
while url:
|
||||||
self.location(url)
|
self.location(url)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue