bnporc: introduce Enterprise option

Not working for now
This commit is contained in:
Laurent Bachelier 2013-07-23 15:35:05 +02:00
commit 6594ec2288
4 changed files with 131 additions and 11 deletions

View file

@ -27,9 +27,10 @@ from datetime import datetime, timedelta
from weboob.capabilities.bank import ICapBank, AccountNotFound, Account, Recipient
from weboob.capabilities.messages import ICapMessages, Thread
from weboob.tools.backend import BaseBackend, BackendConfig
from weboob.tools.value import ValueBackendPassword
from weboob.tools.value import ValueBackendPassword, Value
from .browser import BNPorc
from .enterprise.browser import BNPEnterprise
__all__ = ['BNPorcBackend']
@ -42,12 +43,14 @@ class BNPorcBackend(BaseBackend, ICapBank, ICapMessages):
VERSION = '0.g'
LICENSE = 'AGPLv3+'
DESCRIPTION = 'BNP Paribas French bank website'
CONFIG = BackendConfig(ValueBackendPassword('login', label='Account ID', masked=False),
ValueBackendPassword('password', label='Password', regexp='^(\d{6}|)$'),
ValueBackendPassword('rotating_password', default='',
label='Password to set when the allowed uses are exhausted (6 digits)',
regexp='^(\d{6}|)$'))
BROWSER = BNPorc
CONFIG = BackendConfig(
ValueBackendPassword('login', label='Account ID', masked=False),
ValueBackendPassword('password', label='Password', regexp='^(\d{6}|)$'),
ValueBackendPassword('rotating_password', default='',
label='Password to set when the allowed uses are exhausted (6 digits)',
regexp='^(\d{6}|)$'),
Value('website', label='Website to use', default='pp',
choices={'pp': 'Particuliers/Profesionnels', 'ent': 'Entreprises'}))
STORAGE = {'seen': []}
# Store the messages *list* for this duration
@ -59,14 +62,20 @@ class BNPorcBackend(BaseBackend, ICapBank, ICapMessages):
self._threads_age = datetime.utcnow()
def create_default_browser(self):
b = {'pp': BNPorc, 'ent': BNPEnterprise}
self.BROWSER = b[self.config['website'].get()]
if self.config['rotating_password'].get().isdigit() and len(self.config['rotating_password'].get()) == 6:
rotating_password = self.config['rotating_password'].get()
else:
rotating_password = None
return self.create_browser(self.config['login'].get(),
self.config['password'].get(),
password_changed_cb=self._password_changed_cb,
rotating_password=rotating_password)
if self.config['website'].get() != 'pp':
return self.create_browser(self.config['login'].get(),
self.config['password'].get())
else:
return self.create_browser(self.config['login'].get(),
self.config['password'].get(),
password_changed_cb=self._password_changed_cb,
rotating_password=rotating_password)
def _password_changed_cb(self, old, new):
self.config['password'].set(new)
@ -92,10 +101,16 @@ class BNPorcBackend(BaseBackend, ICapBank, ICapMessages):
return self.browser.iter_history(account)
def iter_coming(self, account):
if self.config['website'].get() != 'pp':
raise NotImplementedError()
with self.browser:
return self.browser.iter_coming_operations(account)
def iter_transfer_recipients(self, ignored):
if self.config['website'].get() != 'pp':
raise NotImplementedError()
for account in self.browser.get_transfer_accounts().itervalues():
recipient = Recipient()
recipient.id = account.id
@ -103,6 +118,9 @@ class BNPorcBackend(BaseBackend, ICapBank, ICapMessages):
yield recipient
def transfer(self, account, to, amount, reason=None):
if self.config['website'].get() != 'pp':
raise NotImplementedError()
if isinstance(account, Account):
account = account.id
@ -141,6 +159,9 @@ class BNPorcBackend(BaseBackend, ICapBank, ICapMessages):
return self.get_thread(thread)
def get_thread(self, _id):
if self.config['website'].get() != 'pp':
raise NotImplementedError()
if isinstance(_id, Thread):
thread = _id
_id = thread.id
@ -151,6 +172,9 @@ class BNPorcBackend(BaseBackend, ICapBank, ICapMessages):
return thread
def iter_unread_messages(self):
if self.config['website'].get() != 'pp':
raise NotImplementedError()
threads = list(self.iter_threads(cache=True))
for thread in threads:
if thread.root.flags & thread.root.IS_UNREAD:

View file

View file

@ -0,0 +1,57 @@
# -*- coding: utf-8 -*-
# Copyright(C) 2013 Laurent Bachelier
#
# This file is part of weboob.
#
# weboob is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# weboob is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from weboob.tools.browser import BaseBrowser, BrowserIncorrectPassword
from .pages import LoginPage, AccountsPage
__all__ = ['BNPEnterprise']
class BNPEnterprise(BaseBrowser):
DOMAIN = 'entreprisesplus.bnpparibas.net'
PROTOCOL = 'https'
CERTHASH = '423f68a8162d1328bacb48269675d8b8577ebcc9d222860de8421792c4d222c1'
PAGES = {'%s://%s/NSAccess.*' % (PROTOCOL, DOMAIN): LoginPage,
'%s://%s/UNE\?Action=DSP_VGLOBALE' % (PROTOCOL, DOMAIN): AccountsPage}
def home(self):
self.location('%s://%s/NSAccess' % (self.PROTOCOL, self.DOMAIN))
def is_logged(self):
if self.page:
if self.page.get_error() is not None:
return False
return not self.is_on_page(LoginPage)
def login(self):
assert isinstance(self.username, basestring)
assert isinstance(self.password, basestring)
assert self.password.isdigit()
if not self.is_on_page(LoginPage):
self.home()
self.page.login(self.username, self.password)
self.location('/UNE?Action=DSP_VGLOBALE', no_login=True)
if not self.is_logged():
raise BrowserIncorrectPassword()

View file

@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
# Copyright(C) 2013 Laurent Bachelier
#
# This file is part of weboob.
#
# weboob is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# weboob is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from weboob.tools.browser import BasePage
__all__ = ['LoginPage', 'AccountsPage']
class BEPage(BasePage):
def get_error(self):
for title in self.document.xpath('/html/head/title'):
if 'erreur' in title.text or 'error' in title.text:
return self.parser.select(self.document.getroot(),
'input[@name="titre_page"]', 1).value
class LoginPage(BEPage):
def login(self, username, password):
raise NotImplementedError()
class AccountsPage(BEPage):
pass