From a32776787a094be1c10cf6e586764e91e916f039 Mon Sep 17 00:00:00 2001 From: Romain Bignon Date: Tue, 21 Oct 2014 17:58:48 +0200 Subject: [PATCH] support professional accounts --- modules/bp/browser.py | 37 +++++++++++++++++++++++++++++-------- modules/bp/module.py | 12 ++++++++---- modules/bp/pages/login.py | 27 ++++++++++++--------------- 3 files changed, 49 insertions(+), 27 deletions(-) diff --git a/modules/bp/browser.py b/modules/bp/browser.py index 2b853d68..35b2a558 100644 --- a/modules/bp/browser.py +++ b/modules/bp/browser.py @@ -26,11 +26,12 @@ from weboob.deprecated.browser import Browser, BrowserIncorrectPassword, Browser from .pages import LoginPage, Initident, CheckPassword, repositionnerCheminCourant, BadLoginPage, AccountDesactivate, \ AccountList, AccountHistory, CardsList, UnavailablePage, \ TransferChooseAccounts, CompleteTransfer, TransferConfirm, TransferSummary +from .pages.pro import RedirectPage, ProAccountsList, ProAccountHistory, ProAccountHistoryDownload, ProAccountHistoryCSV, HistoryParser from weboob.capabilities.bank import Transfer -__all__ = ['BPBrowser'] +__all__ = ['BPBrowser', 'BProBrowser'] class BPBrowser(Browser): @@ -43,9 +44,16 @@ class BPBrowser(Browser): r'.*authentification/initialiser-identif.ea' : Initident, r'.*authentification/verifierMotDePasse-identif.ea' : CheckPassword, + r'.*voscomptes/identification/identification.ea.*' : RedirectPage, + r'.*synthese_assurancesEtComptes/afficheSynthese-synthese\.ea' : AccountList, r'.*synthese_assurancesEtComptes/rechercheContratAssurance-synthese.ea' : AccountList, + r'.*voscomptes/synthese/synthese.ea' : ProAccountsList, + r'.*voscomptes/historiqueccp/historiqueccp.ea.*' : ProAccountHistory, + r'.*voscomptes/telechargercomptes/telechargercomptes.ea.*' : ProAccountHistoryDownload, + r'.*voscomptes/telechargercomptes/1-telechargercomptes.ea' : (ProAccountHistoryCSV, HistoryParser()), + r'.*CCP/releves_ccp/releveCPP-releve_ccp\.ea' : AccountHistory, r'.*CNE/releveCNE/releveCNE-releve_cne\.ea' : AccountHistory, r'.*CB/releveCB/preparerRecherche-mouvementsCarteDD.ea.*' : AccountHistory, @@ -61,22 +69,23 @@ class BPBrowser(Browser): r'https?://.*.labanquepostale.fr/delestage.html' : UnavailablePage, } + login_url = 'https://voscomptesenligne.labanquepostale.fr/wsost/OstBrokerWeb/loginform?TAM_OP=login&' \ + 'ERROR_CODE=0x00000000&URL=%2Fvoscomptes%2FcanalXHTML%2Fidentif.ea%3Forigin%3Dparticuliers' + accounts_url = "https://voscomptesenligne.labanquepostale.fr/voscomptes/canalXHTML/comptesCommun/synthese_assurancesEtComptes/rechercheContratAssurance-synthese.ea" + def __init__(self, *args, **kwargs): kwargs['parser'] = ('lxml',) Browser.__init__(self, *args, **kwargs) def home(self): - self.location('https://voscomptesenligne.labanquepostale.fr/wsost/OstBrokerWeb/loginform?TAM_OP=login&' - 'ERROR_CODE=0x00000000&URL=%2Fvoscomptes%2FcanalXHTML%2Fidentif.ea%3Forigin%3Dparticuliers') + self.login() def is_logged(self): return not self.is_on_page(LoginPage) def login(self): if not self.is_on_page(LoginPage): - self.location('https://voscomptesenligne.labanquepostale.fr/wsost/OstBrokerWeb/loginform?TAM_OP=login&' - 'ERROR_CODE=0x00000000&URL=%2Fvoscomptes%2FcanalXHTML%2Fidentif.ea%3Forigin%3Dparticuliers', - no_login=True) + self.location(self.login_url, no_login=True) self.page.login(self.username, self.password) @@ -86,12 +95,12 @@ class BPBrowser(Browser): raise BrowserBanned() def get_accounts_list(self): - self.location("https://voscomptesenligne.labanquepostale.fr/voscomptes/canalXHTML/comptesCommun/synthese_assurancesEtComptes/rechercheContratAssurance-synthese.ea") + self.location(self.accounts_url) return self.page.get_accounts_list() def get_account(self, id): if not self.is_on_page(AccountList): - self.location("https://voscomptesenligne.labanquepostale.fr/voscomptes/canalXHTML/comptesCommun/synthese_assurancesEtComptes/rechercheContratAssurance-synthese.ea") + self.location(self.accounts_url) return self.page.get_account(id) def get_history(self, account): @@ -155,3 +164,15 @@ class BPBrowser(Browser): transfer.recipient = to_account.label transfer.date = datetime.now() return transfer + +class BProBrowser(BPBrowser): + login_url = "https://banqueenligne.entreprises.labanquepostale.fr/wsost/OstBrokerWeb/loginform?TAM_OP=login&ERROR_CODE=0x00000000&URL=%2Fws_q47%2Fvoscomptes%2Fidentification%2Fidentification.ea%3Forigin%3Dprofessionnels" + + def login(self): + BPBrowser.login(self) + + v = urlsplit(self.page.url) + version = v.path.split('/')[1] + + self.base_url = 'https://banqueenligne.entreprises.labanquepostale.fr/%s' % version + self.accounts_url = self.base_url + '/voscomptes/synthese/synthese.ea' diff --git a/modules/bp/module.py b/modules/bp/module.py index 05f20ff8..9b65ed76 100644 --- a/modules/bp/module.py +++ b/modules/bp/module.py @@ -20,9 +20,9 @@ from weboob.capabilities.bank import CapBank, Account from weboob.tools.backend import Module, BackendConfig -from weboob.tools.value import ValueBackendPassword +from weboob.tools.value import ValueBackendPassword, Value -from .browser import BPBrowser +from .browser import BPBrowser, BProBrowser __all__ = ['BPModule'] @@ -36,10 +36,14 @@ class BPModule(Module, CapBank): LICENSE = 'AGPLv3+' DESCRIPTION = u'La Banque Postale' CONFIG = BackendConfig(ValueBackendPassword('login', label='Identifiant', masked=False), - ValueBackendPassword('password', label='Mot de passe', regexp='^(\d{6}|)$')) - BROWSER = BPBrowser + ValueBackendPassword('password', label='Mot de passe', regexp='^(\d{6}|)$'), + Value('website', label='Type de compte', default='par', + choices={'par': 'Particuliers', 'pro': 'Professionnels'})) def create_default_browser(self): + b = {'par': BPBrowser, 'pro': BProBrowser} + self.BROWSER = b[self.config['website'].get()] + return self.create_browser(self.config['login'].get(), self.config['password'].get()) def iter_accounts(self): diff --git a/modules/bp/pages/login.py b/modules/bp/pages/login.py index 6224caf6..9ceb7d5a 100644 --- a/modules/bp/pages/login.py +++ b/modules/bp/pages/login.py @@ -18,8 +18,6 @@ # along with weboob. If not, see . -import hashlib - import re import lxml.etree as etree @@ -27,12 +25,6 @@ from weboob.deprecated.browser import Page, BrowserUnavailable from weboob.tools.captcha.virtkeyboard import VirtKeyboard -def md5(f): - md5 = hashlib.md5() - md5.update(f.read()) - return md5.hexdigest() - - class UnavailablePage(Page): def on_loaded(self): raise BrowserUnavailable() @@ -48,25 +40,30 @@ class Keyboard(VirtKeyboard): '6':'7fedfd9e57007f2985c3a1f44fb38ea1', '7':'389b8ef432ae996ac0141a2fcc7b540f', '8':'bf357ff09cc29ea544991642cd97d453', - '9':'b744015eb89c1b950e13a81364112cd6' + '9':'b744015eb89c1b950e13a81364112cd6', } color=(0xff, 0xff, 0xff) def __init__(self, page): - img_url = re.search('background:url\((.*?)\)',etree.tostring(page.document)).group(1) + m = re.search(r'background:url\((.*?)\)',etree.tostring(page.document)) + if m: + img_url = m.group(1) + size = 252 + else: + img_url = page.document.xpath('//img[@id="imageCVS"]')[0].attrib['src'] + size = 146 coords = {} - size = 252 x, y, width, height = (0, 0, size/4, size/4) - for i,a in enumerate(page.document.xpath('//div[@id="imageclavier"]//button')): + for i, _ in enumerate(page.document.xpath('//div[@id="imageclavier"]//button')): code = '%02d' % i - coords[code] = (x+8, y+8, x+height-8, y+height-8) + coords[code] = (x+4, y+4, x+width-8, y+height-8) if (x + width + 1) >= size: - y += height + y += height + 1 x = 0 else: - x += width + x += width + 1 VirtKeyboard.__init__(self, page.browser.openurl(img_url), coords, self.color)