sgpe: support credit cards

This commit is contained in:
Romain Bignon 2013-07-28 20:45:12 +02:00
commit 0ab9da2fc6
2 changed files with 142 additions and 19 deletions

View file

@ -21,7 +21,7 @@
from weboob.tools.browser import BaseBrowser, BrowserIncorrectPassword from weboob.tools.browser import BaseBrowser, BrowserIncorrectPassword
from weboob.tools.ordereddict import OrderedDict from weboob.tools.ordereddict import OrderedDict
from .pages import LoginPage, ErrorPage, AccountsPage, HistoryPage from .pages import LoginPage, ErrorPage, AccountsPage, CardsPage, HistoryPage, CardHistoryPage
__all__ = ['SGProfessionalBrowser', 'SGEnterpriseBrowser'] __all__ = ['SGProfessionalBrowser', 'SGEnterpriseBrowser']
@ -34,7 +34,9 @@ class SGPEBrowser(BaseBrowser):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.PAGES = OrderedDict(( self.PAGES = OrderedDict((
('%s://%s/Pgn/.+PageID=SoldeV3&.+' % (self.PROTOCOL, self.DOMAIN), AccountsPage), ('%s://%s/Pgn/.+PageID=SoldeV3&.+' % (self.PROTOCOL, self.DOMAIN), AccountsPage),
('%s://%s/Pgn/.+PageID=Cartes&.+' % (self.PROTOCOL, self.DOMAIN), CardsPage),
('%s://%s/Pgn/.+PageID=ReleveCompteV3&.+' % (self.PROTOCOL, self.DOMAIN), HistoryPage), ('%s://%s/Pgn/.+PageID=ReleveCompteV3&.+' % (self.PROTOCOL, self.DOMAIN), HistoryPage),
('%s://%s/Pgn/.+PageID=ReleveCarte&.+' % (self.PROTOCOL, self.DOMAIN), CardHistoryPage),
('%s://%s/authent\.html' % (self.PROTOCOL, self.DOMAIN), ErrorPage), ('%s://%s/authent\.html' % (self.PROTOCOL, self.DOMAIN), ErrorPage),
('%s://%s/' % (self.PROTOCOL, self.DOMAIN), LoginPage), ('%s://%s/' % (self.PROTOCOL, self.DOMAIN), LoginPage),
)) ))
@ -67,20 +69,36 @@ class SGPEBrowser(BaseBrowser):
raise BrowserIncorrectPassword() raise BrowserIncorrectPassword()
def accounts(self, no_login=False): def accounts(self, no_login=False):
self.location('/Pgn/NavigationServlet?PageID=SoldeV3&MenuID=%s&Classeur=1&NumeroPage=1' % self.MENUID, no_login=no_login) self.location('/Pgn/NavigationServlet?PageID=SoldeV3&MenuID=%sCPT&Classeur=1&NumeroPage=1' % self.MENUID, no_login=no_login)
def cards(self):
doc = self.get_document(self.openurl('/Pgn/NavigationServlet?PageID=CartesFutures&MenuID=%sOPF&Classeur=1&NumeroPage=1&PageDetail=1' % self.MENUID))
url = doc.xpath('//iframe[@name="cartes"]')[0].attrib['src']
self.location(url)
def history(self, _id, page=1): def history(self, _id, page=1):
if page > 1: if page > 1:
pgadd = '&page_numero_page_courante=%s' % page pgadd = '&page_numero_page_courante=%s' % page
else: else:
pgadd = '' pgadd = ''
self.location('/Pgn/NavigationServlet?PageID=ReleveCompteV3&MenuID=%s&Classeur=1&Rib=%s&NumeroPage=1%s' % (self.MENUID, _id, pgadd)) self.location('/Pgn/NavigationServlet?PageID=ReleveCompteV3&MenuID=%sCPT&Classeur=1&Rib=%s&NumeroPage=1%s' % (self.MENUID, _id, pgadd))
def card_history(self, rib, _id, date, currency, page=1):
self.location('/Pgn/NavigationServlet?PageID=ReleveCarte&MenuID=%sOPF&Classeur=1&Rib=%s&Carte=%s&Date=%s&PageDetail=%s&Devise=%s' % (self.MENUID, rib, _id, date, page, currency))
def get_accounts_list(self): def get_accounts_list(self):
if not self.is_on_page(AccountsPage): if not self.is_on_page(AccountsPage):
self.accounts() self.accounts()
assert self.is_on_page(AccountsPage) assert self.is_on_page(AccountsPage)
return self.page.get_list() for acc in self.page.get_list():
yield acc
self.cards()
assert self.is_on_page(CardsPage)
for acc in self.page.get_list():
yield acc
def get_account(self, _id): def get_account(self, _id):
for a in self.get_accounts_list(): for a in self.get_accounts_list():
@ -88,6 +106,18 @@ class SGPEBrowser(BaseBrowser):
yield a yield a
def iter_history(self, account): def iter_history(self, account):
if account._is_card:
page = 1
while page:
self.card_history(account._link_rib, account.id, account._link_date, account._link_currency, page)
assert self.is_on_page(CardHistoryPage)
for tr in self.page.iter_transactions():
yield tr
if self.page.has_next():
page += 1
else:
page = False
else:
page = 1 page = 1
basecount = 0 basecount = 0
while page: while page:
@ -105,12 +135,12 @@ class SGPEBrowser(BaseBrowser):
class SGProfessionalBrowser(SGPEBrowser): class SGProfessionalBrowser(SGPEBrowser):
DOMAIN = 'professionnels.secure.societegenerale.fr' DOMAIN = 'professionnels.secure.societegenerale.fr'
LOGIN_FORM = 'auth_reco' LOGIN_FORM = 'auth_reco'
MENUID = 'SBORELCPT' MENUID = 'SBOREL'
CERTHASH = 'd369315d357ba0018c2bd4d3394645669d99106c797d7390fded516b098a933e' CERTHASH = 'd369315d357ba0018c2bd4d3394645669d99106c797d7390fded516b098a933e'
class SGEnterpriseBrowser(SGPEBrowser): class SGEnterpriseBrowser(SGPEBrowser):
DOMAIN = 'entreprises.secure.societegenerale.fr' DOMAIN = 'entreprises.secure.societegenerale.fr'
LOGIN_FORM = 'auth' LOGIN_FORM = 'auth'
MENUID = 'BANRELCPT' MENUID = 'BANREL'
CERTHASH = 'd5c21d47c7d5a300b40856be49d0b36b42eaae409c8891184652b888d16a05f5' CERTHASH = 'd5c21d47c7d5a300b40856be49d0b36b42eaae409c8891184652b888d16a05f5'

View file

@ -33,7 +33,7 @@ from weboob.tools.capabilities.bank.transactions import FrenchTransaction
from ..captcha import Captcha, TileError from ..captcha import Captcha, TileError
__all__ = ['LoginPage', 'AccountsPage'] __all__ = ['LoginPage', 'AccountsPage', 'CardsPage', 'HistoryPage', 'CardHistoryPage']
class Transaction(FrenchTransaction): class Transaction(FrenchTransaction):
@ -107,10 +107,64 @@ class AccountsPage(SGPEPage):
account.label = to_unicode(tdname) account.label = to_unicode(tdname)
account.id = to_unicode(tdid.replace(u'\xa0', '').replace(' ', '')) account.id = to_unicode(tdid.replace(u'\xa0', '').replace(' ', ''))
account._agency = to_unicode(tdagency) account._agency = to_unicode(tdagency)
account._is_card = False
account.balance = Decimal(Transaction.clean_amount(tdbalance)) account.balance = Decimal(Transaction.clean_amount(tdbalance))
account.currency = account.get_currency(tdbalance) account.currency = account.get_currency(tdbalance)
yield account yield account
class CardsPage(SGPEPage):
COL_ID = 0
COL_LABEL = 1
COL_BALANCE = 2
def get_list(self):
rib = None
currency = None
for script in self.document.xpath('//script'):
if script.text is None:
continue
m = re.search('var rib = "(\d+)"', script.text)
if m:
rib = m.group(1)
m = re.search("var devise='(\w+)'", script.text)
if m:
currency = m.group(1)
if all((rib, currency)):
break
if not all((rib, currency)):
self.logger.error('Unable to find rib or currency')
for tr in self.document.xpath('//table[@id="tab-corps"]//tr'):
tds = tr.findall('td')
if len(tds) != 3:
continue
account = Account()
account.label = self.parser.tocleanstring(tds[self.COL_LABEL])
if len(account.label) == 0:
continue
link = tds[self.COL_ID].xpath('.//a')[0]
m = re.match(r"changeCarte\('(\d+)','(\d+)','([\d/]+)'\);.*", link.attrib['onclick'])
if not m:
self.logger.error('Unable to parse link %r' % link.attrib['onclick'])
continue
account.id = m.group(2)
account._link_num = m.group(1) #useless
account._link_date = m.group(3)
account._link_rib = rib
account._link_currency = currency
account._is_card = True
tdbalance = self.parser.tocleanstring(tds[self.COL_BALANCE])
account.balance = - Decimal(Transaction.clean_amount(tdbalance))
account.currency = account.get_currency(tdbalance)
yield account
class HistoryPage(SGPEPage): class HistoryPage(SGPEPage):
def iter_transactions(self, account, basecount): def iter_transactions(self, account, basecount):
@ -144,3 +198,42 @@ class HistoryPage(SGPEPage):
for end in self.parser.select(n, '.contenu3-lien'): for end in self.parser.select(n, '.contenu3-lien'):
return int(end.text.replace('/', '')) > cur return int(end.text.replace('/', '')) > cur
return False return False
class CardHistoryPage(SGPEPage):
COL_DATE = 0
COL_LABEL = 1
COL_AMOUNT = -1
def iter_transactions(self):
table = self.parser.select(self.document.getroot(), '#tab-corps', 1)
for i, tr in enumerate(self.parser.select(table, 'tr', 'many')):
tds = tr.findall('td')
date = self.parser.tocleanstring(tds[self.COL_DATE])
raw = self.parser.tocleanstring(tds[self.COL_LABEL])
amount = self.parser.tocleanstring(tds[self.COL_AMOUNT])
t = Transaction(i)
t.parse(date, raw)
t.set_amount(amount)
yield t
def has_next(self):
current = None
total = None
for script in self.document.xpath('//script'):
if script.text is None:
continue
m = re.search('var pageActive\s+= (\d+)', script.text)
if m:
current = int(m.group(1))
m = re.search("var nombrePage\s+= (\d+)", script.text)
if m:
total = int(m.group(1))
if all((current, total)) and current < total:
return True
return False