fix detection on login failed, and support deferred debit cards

This commit is contained in:
Romain Bignon 2013-04-01 16:25:46 +02:00
commit fc78b3c9b7
3 changed files with 55 additions and 22 deletions

View file

@ -59,3 +59,7 @@ class CaisseEpargneBackend(BaseBackend, ICapBank):
def iter_history(self, account): def iter_history(self, account):
with self.browser: with self.browser:
return self.browser.get_history(account) return self.browser.get_history(account)
def iter_coming(self, account):
with self.browser:
return self.browser.get_coming(account)

View file

@ -39,10 +39,13 @@ class CaisseEpargne(BaseBrowser):
} }
def is_logged(self): 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): def home(self):
self.location('https://www.caisse-epargne.fr/particuliers/ind_pauthpopup.aspx?mar=101&reg=&fctpopup=auth&cv=0') if self.is_logged():
self.location(self.buildurl('/Portail.aspx'))
else:
self.login()
def login(self): def login(self):
""" """
@ -56,7 +59,7 @@ class CaisseEpargne(BaseBrowser):
return return
if not self.is_on_page(LoginPage): if not self.is_on_page(LoginPage):
self.home() 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() self.page.login2()
@ -64,8 +67,6 @@ class CaisseEpargne(BaseBrowser):
if not self.is_logged(): if not self.is_logged():
raise BrowserIncorrectPassword() raise BrowserIncorrectPassword()
if self.is_on_page(ErrorPage):
raise BrowserIncorrectPassword(self.page.get_error())
v = urlsplit(self.page.url) v = urlsplit(self.page.url)
self.DOMAIN = v.netloc self.DOMAIN = v.netloc
@ -85,10 +86,10 @@ class CaisseEpargne(BaseBrowser):
return None return None
def get_history(self, account): def _get_history(self, link_type, id):
self.location(self.buildurl('/Portail.aspx')) self.location(self.buildurl('/Portail.aspx'))
self.page.go_history(account.id) self.page.go_history(link_type, id)
while 1: while 1:
assert self.is_on_page(IndexPage) assert self.is_on_page(IndexPage)
@ -98,3 +99,11 @@ class CaisseEpargne(BaseBrowser):
if not self.page.go_next(): if not self.page.go_next():
return 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

View file

@ -22,7 +22,9 @@ from decimal import Decimal
import re import re
from weboob.tools.mech import ClientForm 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.capabilities.bank import Account
from weboob.tools.capabilities.bank.transactions import FrenchTransaction from weboob.tools.capabilities.bank.transactions import FrenchTransaction
@ -31,6 +33,12 @@ __all__ = ['LoginPage', 'ErrorPage', 'IndexPage', 'UnavailablePage']
class LoginPage(BasePage): 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): def login(self, login):
self.browser.select_form(name='Main') self.browser.select_form(name='Main')
self.browser.set_all_readonly(False) self.browser.set_all_readonly(False)
@ -55,13 +63,8 @@ class LoginPage(BasePage):
self.browser.submit(nologin=True) self.browser.submit(nologin=True)
class ErrorPage(BasePage): class ErrorPage(LoginPage):
def get_error(self): pass
try:
return self.parser.select(self.document.getroot(), 'div.messErreur', 1).text.strip()
except BrokenPageError:
return None
class UnavailablePage(BasePage): class UnavailablePage(BasePage):
def on_loaded(self): def on_loaded(self):
@ -97,6 +100,8 @@ class IndexPage(BasePage):
} }
def get_list(self): def get_list(self):
accounts = OrderedDict()
for table in self.document.xpath('//table[@cellpadding="1"]'): for table in self.document.xpath('//table[@cellpadding="1"]'):
account_type = Account.TYPE_UNKNOWN account_type = Account.TYPE_UNKNOWN
for tr in table.xpath('./tr'): 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) account_type = self.ACCOUNT_TYPES.get(tds[1].text.strip(), Account.TYPE_UNKNOWN)
else: else:
a = tds[1].find('a') 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: 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 continue
account = Account() account = Account()
account.id = m.group(1) account.id = m.group(2)
account.label = unicode(a.text.strip()) account._link_type = m.group(1)
account.label = self.parser.tocleanstring(a)
account.type = account_type account.type = account_type
amount = u''.join([txt.strip() for txt in tds[-1].itertext()]) amount = u''.join([txt.strip() for txt in tds[-1].itertext()])
account.balance = Decimal(FrenchTransaction.clean_amount(amount)) account.balance = Decimal(FrenchTransaction.clean_amount(amount))
account.currency = account.get_currency(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.select_form(name='main')
self.browser.set_all_readonly(False) self.browser.set_all_readonly(False)
self.browser['__EVENTTARGET'] = 'MM$SYNTHESE' 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['MM$m_CH$IsMsgInit'] = '0'
self.browser.controls.append(ClientForm.TextControl('text', 'm_ScriptManager', {'value': ''})) self.browser.controls.append(ClientForm.TextControl('text', 'm_ScriptManager', {'value': ''}))
self.browser['m_ScriptManager'] = 'MM$m_UpdatePanel|MM$SYNTHESE' 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()]) credit = u''.join([txt.strip() for txt in tds[-1].itertext()])
t.parse(date, re.sub(r'[ ]+', ' ', raw)) t.parse(date, re.sub(r'[ ]+', ' ', raw))
if t.date is NotAvailable:
continue
t.set_amount(credit, debit) t.set_amount(credit, debit)
yield t yield t