fix detection on login failed, and support deferred debit cards
This commit is contained in:
parent
f1309eeb93
commit
fc78b3c9b7
3 changed files with 55 additions and 22 deletions
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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®=&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®=&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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue