From fc78b3c9b7b4a88b43b6c554127e502711f2dcfd Mon Sep 17 00:00:00 2001 From: Romain Bignon Date: Mon, 1 Apr 2013 16:25:46 +0200 Subject: [PATCH] fix detection on login failed, and support deferred debit cards --- modules/caissedepargne/backend.py | 4 +++ modules/caissedepargne/browser.py | 23 +++++++++----- modules/caissedepargne/pages.py | 50 +++++++++++++++++++++---------- 3 files changed, 55 insertions(+), 22 deletions(-) diff --git a/modules/caissedepargne/backend.py b/modules/caissedepargne/backend.py index f4e8449a..5f79e800 100644 --- a/modules/caissedepargne/backend.py +++ b/modules/caissedepargne/backend.py @@ -59,3 +59,7 @@ class CaisseEpargneBackend(BaseBackend, ICapBank): def iter_history(self, account): with self.browser: return self.browser.get_history(account) + + def iter_coming(self, account): + with self.browser: + return self.browser.get_coming(account) diff --git a/modules/caissedepargne/browser.py b/modules/caissedepargne/browser.py index 824bfcaa..324fa6de 100644 --- a/modules/caissedepargne/browser.py +++ b/modules/caissedepargne/browser.py @@ -39,10 +39,13 @@ class CaisseEpargne(BaseBrowser): } def is_logged(self): - return not self.is_on_page(LoginPage) + return self.page is not None and not self.is_on_page(LoginPage) def home(self): - self.location('https://www.caisse-epargne.fr/particuliers/ind_pauthpopup.aspx?mar=101®=&fctpopup=auth&cv=0') + if self.is_logged(): + self.location(self.buildurl('/Portail.aspx')) + else: + self.login() def login(self): """ @@ -56,7 +59,7 @@ class CaisseEpargne(BaseBrowser): return if not self.is_on_page(LoginPage): - self.home() + self.location('https://www.caisse-epargne.fr/particuliers/ind_pauthpopup.aspx?mar=101®=&fctpopup=auth&cv=0', no_login=True) self.page.login(self.username) self.page.login2() @@ -64,8 +67,6 @@ class CaisseEpargne(BaseBrowser): if not self.is_logged(): raise BrowserIncorrectPassword() - if self.is_on_page(ErrorPage): - raise BrowserIncorrectPassword(self.page.get_error()) v = urlsplit(self.page.url) self.DOMAIN = v.netloc @@ -85,10 +86,10 @@ class CaisseEpargne(BaseBrowser): return None - def get_history(self, account): + def _get_history(self, link_type, id): self.location(self.buildurl('/Portail.aspx')) - self.page.go_history(account.id) + self.page.go_history(link_type, id) while 1: assert self.is_on_page(IndexPage) @@ -98,3 +99,11 @@ class CaisseEpargne(BaseBrowser): if not self.page.go_next(): return + + def get_history(self, account): + return self._get_history(account._link_type, account.id) + + def get_coming(self, account): + for link_type, id in account._card_links: + for tr in self._get_history(link_type, id): + yield tr diff --git a/modules/caissedepargne/pages.py b/modules/caissedepargne/pages.py index f1fafdff..1334a1cd 100644 --- a/modules/caissedepargne/pages.py +++ b/modules/caissedepargne/pages.py @@ -22,7 +22,9 @@ from decimal import Decimal import re from weboob.tools.mech import ClientForm -from weboob.tools.browser import BasePage, BrokenPageError, BrowserUnavailable +from weboob.tools.ordereddict import OrderedDict +from weboob.tools.browser import BasePage, BrokenPageError, BrowserUnavailable, BrowserIncorrectPassword +from weboob.capabilities import NotAvailable from weboob.capabilities.bank import Account from weboob.tools.capabilities.bank.transactions import FrenchTransaction @@ -31,6 +33,12 @@ __all__ = ['LoginPage', 'ErrorPage', 'IndexPage', 'UnavailablePage'] class LoginPage(BasePage): + def on_loaded(self): + try: + raise BrowserIncorrectPassword(self.parser.tocleanstring(self.parser.select(self.document.getroot(), '.messErreur', 1))) + except BrokenPageError: + pass + def login(self, login): self.browser.select_form(name='Main') self.browser.set_all_readonly(False) @@ -55,13 +63,8 @@ class LoginPage(BasePage): self.browser.submit(nologin=True) -class ErrorPage(BasePage): - def get_error(self): - try: - return self.parser.select(self.document.getroot(), 'div.messErreur', 1).text.strip() - except BrokenPageError: - return None - +class ErrorPage(LoginPage): + pass class UnavailablePage(BasePage): def on_loaded(self): @@ -97,6 +100,8 @@ class IndexPage(BasePage): } def get_list(self): + accounts = OrderedDict() + for table in self.document.xpath('//table[@cellpadding="1"]'): account_type = Account.TYPE_UNKNOWN for tr in table.xpath('./tr'): @@ -105,26 +110,39 @@ class IndexPage(BasePage): account_type = self.ACCOUNT_TYPES.get(tds[1].text.strip(), Account.TYPE_UNKNOWN) else: a = tds[1].find('a') - m = re.match("^javascript:__doPostBack\('.*','HISTORIQUE_COMPTE&(\d+)'\)", a.attrib.get('href', '')) + m = re.match("^javascript:__doPostBack\('.*','HISTORIQUE_(\w+)&(\d+)'\)", a.attrib.get('href', '')) if not m: - self.logger.warning('Unable to parse account %s' % (a.text.strip() if a.text is not None else '')) + self.logger.warning('Unable to parse account %r' % (self.parser.tocleanstring(a))) continue account = Account() - account.id = m.group(1) - account.label = unicode(a.text.strip()) + account.id = m.group(2) + account._link_type = m.group(1) + account.label = self.parser.tocleanstring(a) account.type = account_type amount = u''.join([txt.strip() for txt in tds[-1].itertext()]) account.balance = Decimal(FrenchTransaction.clean_amount(amount)) account.currency = account.get_currency(amount) - yield account + account._card_links = [] - def go_history(self, id): + if account._link_type == 'CB' and account.id in accounts: + a = accounts[account.id] + if not a.coming: + a.coming = Decimal('0.0') + a.coming += account.balance + a._card_links.append((account._link_type, account.id)) + continue + + accounts[account.id] = account + + return accounts.itervalues() + + def go_history(self, link_type, id): self.browser.select_form(name='main') self.browser.set_all_readonly(False) self.browser['__EVENTTARGET'] = 'MM$SYNTHESE' - self.browser['__EVENTARGUMENT'] = 'HISTORIQUE_COMPTE&%s' % id + self.browser['__EVENTARGUMENT'] = 'HISTORIQUE_%s&%s' % (link_type, id) self.browser['MM$m_CH$IsMsgInit'] = '0' self.browser.controls.append(ClientForm.TextControl('text', 'm_ScriptManager', {'value': ''})) self.browser['m_ScriptManager'] = 'MM$m_UpdatePanel|MM$SYNTHESE' @@ -149,6 +167,8 @@ class IndexPage(BasePage): credit = u''.join([txt.strip() for txt in tds[-1].itertext()]) t.parse(date, re.sub(r'[ ]+', ' ', raw)) + if t.date is NotAvailable: + continue t.set_amount(credit, debit) yield t