caissedepargne: support pro accounts

This commit is contained in:
Romain Bignon 2013-07-23 22:11:06 +02:00
commit 9e33711227
3 changed files with 44 additions and 14 deletions

View file

@ -20,7 +20,7 @@
from weboob.capabilities.bank import ICapBank, AccountNotFound from weboob.capabilities.bank import ICapBank, AccountNotFound
from weboob.tools.backend import BaseBackend, BackendConfig from weboob.tools.backend import BaseBackend, BackendConfig
from weboob.tools.value import ValueBackendPassword from weboob.tools.value import Value, ValueBackendPassword
from .browser import CaisseEpargne from .browser import CaisseEpargne
@ -36,11 +36,13 @@ class CaisseEpargneBackend(BaseBackend, ICapBank):
DESCRIPTION = u'Caisse d\'Épargne French bank website' DESCRIPTION = u'Caisse d\'Épargne French bank website'
LICENSE = 'AGPLv3+' LICENSE = 'AGPLv3+'
CONFIG = BackendConfig(ValueBackendPassword('login', label='Account ID', masked=False), CONFIG = BackendConfig(ValueBackendPassword('login', label='Account ID', masked=False),
ValueBackendPassword('password', label='Password', regexp='\d+')) ValueBackendPassword('password', label='Password', regexp='\d+'),
Value('nuser', label='User ID (optional)', default=''))
BROWSER = CaisseEpargne BROWSER = CaisseEpargne
def create_default_browser(self): def create_default_browser(self):
return self.create_browser(self.config['login'].get(), return self.create_browser(self.config['nuser'].get(),
self.config['login'].get(),
self.config['password'].get()) self.config['password'].get())
def iter_accounts(self): def iter_accounts(self):

View file

@ -39,6 +39,10 @@ class CaisseEpargne(BaseBrowser):
'https://[^/]+.caisse-epargne.fr/page_hs_dei_.*.aspx': UnavailablePage, 'https://[^/]+.caisse-epargne.fr/page_hs_dei_.*.aspx': UnavailablePage,
} }
def __init__(self, nuser, *args, **kwargs):
self.nuser = nuser
BaseBrowser.__init__(self, *args, **kwargs)
def is_logged(self): def is_logged(self):
return self.page is not None and not self.is_on_page((LoginPage,ErrorPage)) return self.page is not None and not self.is_on_page((LoginPage,ErrorPage))
@ -64,8 +68,9 @@ class CaisseEpargne(BaseBrowser):
self.location('https://www.caisse-epargne.fr/particuliers/ind_pauthpopup.aspx?mar=101&reg=&fctpopup=auth&cv=0', no_login=True) self.location('https://www.caisse-epargne.fr/particuliers/ind_pauthpopup.aspx?mar=101&reg=&fctpopup=auth&cv=0', no_login=True)
self.page.login(self.username) self.page.login(self.username)
self.page.login2() if not self.page.login2(self.nuser, self.password):
self.page.login3(self.password) # perso
self.page.login3(self.password)
if not self.is_logged(): if not self.is_logged():
raise BrowserIncorrectPassword() raise BrowserIncorrectPassword()

View file

@ -50,13 +50,23 @@ class LoginPage(_LogoutPage):
self.browser['__EVENTTARGET'] = 'ctl01$CC_ind_pauthpopup$ctl01$CC_ind_ident$ctl01$CC_ind_inputuserid_sup$btnValider' self.browser['__EVENTTARGET'] = 'ctl01$CC_ind_pauthpopup$ctl01$CC_ind_ident$ctl01$CC_ind_inputuserid_sup$btnValider'
self.browser.submit(nologin=True) self.browser.submit(nologin=True)
def login2(self): def login2(self, nuser, passwd):
self.browser.select_form(name='Main') self.browser.select_form(name='Main')
self.browser.set_all_readonly(False) self.browser.set_all_readonly(False)
self.browser['__EVENTARGUMENT'] = 'idsrv=WE' self.browser['__EVENTARGUMENT'] = 'idsrv=WE'
a = self.document.xpath('//a[@title="Valider"]')[0]
m = re.match("javascript:RedirectToDeiPro\('([^']+)', \d+\);", a.attrib['href'])
if m:
self.browser['nuusager'] = nuser.encode('utf-8')
self.browser['codconf'] = passwd.encode('utf-8')
self.browser.form.action = m.group(1)
self.browser.submit(nologin=True) self.browser.submit(nologin=True)
def login3(self, passwd): return m is not None
def login3(self, nuser, passwd):
self.browser.select_form(name='Main') self.browser.select_form(name='Main')
self.browser['codconf'] = passwd.encode('utf-8') self.browser['codconf'] = passwd.encode('utf-8')
a = self.document.xpath('//a[@title="Valider"]')[0] a = self.document.xpath('//a[@title="Valider"]')[0]
@ -124,7 +134,7 @@ class IndexPage(BasePage):
def _add_account(self, accounts, link, label, account_type, balance): def _add_account(self, accounts, link, label, account_type, balance):
info = self._get_account_info(link) info = self._get_account_info(link)
if info is None: if info is None:
self.logger.warning('Unable to parse account %r' % label) self.logger.warning('Unable to parse account %r: %r' % (label, link))
return return
account = Account() account = Account()
@ -157,12 +167,25 @@ class IndexPage(BasePage):
if tr.attrib.get('class', '') == 'DataGridHeader': if tr.attrib.get('class', '') == 'DataGridHeader':
account_type = self.ACCOUNT_TYPES.get(tds[1].text.strip(), Account.TYPE_UNKNOWN) account_type = self.ACCOUNT_TYPES.get(tds[1].text.strip(), Account.TYPE_UNKNOWN)
else: else:
a = tds[1].find('a') label = ''
if a is None: i = 1
continue a = None
while label == '' and i < len(tds):
a = tds[i].find('a')
if a is None:
continue
label = self.parser.tocleanstring(a) label = self.parser.tocleanstring(a)
balance = u''.join([txt.strip() for txt in tds[-1].itertext()]) i += 1
balance = ''
i = -1
while balance == '' and i > -len(tds):
try:
balance = self.parser.tocleanstring(tds[i].xpath('./a')[0])
except KeyError:
balance = u''.join([txt.strip() for txt in tds[i].itertext()])
i -= 1
self._add_account(accounts, a, label, account_type, balance) self._add_account(accounts, a, label, account_type, balance)
if len(accounts) == 0: if len(accounts) == 0: