Creditcoop/perso : upgrade to browser2

This commit is contained in:
Florent 2014-10-10 11:29:41 +02:00
commit 40a8bc0ce1
3 changed files with 68 additions and 78 deletions

View file

@ -56,17 +56,13 @@ class CreditCooperatifModule(Module, CapBank):
strong_auth=self.config['auth_type'].get() == "strong") strong_auth=self.config['auth_type'].get() == "strong")
def iter_accounts(self): def iter_accounts(self):
with self.browser:
return self.browser.get_accounts_list() return self.browser.get_accounts_list()
def get_account(self, _id): def get_account(self, _id):
with self.browser:
return find_object(self.browser.get_accounts_list(), id=_id, error=AccountNotFound) return find_object(self.browser.get_accounts_list(), id=_id, error=AccountNotFound)
def iter_history(self, account): def iter_history(self, account):
with self.browser:
return self.browser.get_history(account) return self.browser.get_history(account)
def iter_coming(self, account): def iter_coming(self, account):
with self.browser:
return self.browser.get_coming(account) return self.browser.get_coming(account)

View file

@ -17,68 +17,53 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with weboob. If not, see <http://www.gnu.org/licenses/>. # along with weboob. If not, see <http://www.gnu.org/licenses/>.
import urllib from weboob.browser import LoginBrowser, URL, need_login
from weboob.exceptions import BrowserIncorrectPassword
from weboob.deprecated.browser import Browser, BrowserIncorrectPassword from .pages import LoginPage, CreditLoggedPage, AccountsPage, TransactionsPage, TransactionsJSONPage, ComingTransactionsPage
from .pages import LoginPage, LoggedPage, AccountsPage, TransactionsPage, TransactionsJSONPage, ComingTransactionsPage
__all__ = ['CreditCooperatif'] __all__ = ['CreditCooperatif']
class CreditCooperatif(Browser): class CreditCooperatif(LoginBrowser):
PROTOCOL = 'https' BASEURL = "https://www.credit-cooperatif.coop"
ENCODING = 'iso-8859-15'
DOMAIN = "www.credit-cooperatif.coop"
PAGES = {'https://www.credit-cooperatif.coop/portail/particuliers/login.do': LoginPage,
'https://www.credit-cooperatif.coop/portail/particuliers/authentification.do': LoggedPage,
'https://www.credit-cooperatif.coop/portail/particuliers/mescomptes/synthese.do': AccountsPage,
'https://www.credit-cooperatif.coop/portail/particuliers/mescomptes/relevedesoperations.do': TransactionsPage,
'https://www.credit-cooperatif.coop/portail/particuliers/mescomptes/relevedesoperationsjson.do': (TransactionsJSONPage, 'json'),
'https://www.credit-cooperatif.coop/portail/particuliers/mescomptes/synthese/operationsencourslien.do': ComingTransactionsPage,
}
def home(self): loginpage = URL('/portail//particuliers/login.do', LoginPage)
self.location("/portail/particuliers/mescomptes/synthese.do") loggedpage = URL('/portail/particuliers/authentification.do', CreditLoggedPage)
accountspage = URL('/portail/particuliers/mescomptes/synthese.do', AccountsPage)
transactionpage = URL('/portail/particuliers/mescomptes/relevedesoperations.do', TransactionsPage)
transactjsonpage = URL('/portail/particuliers/mescomptes/relevedesoperationsjson.do', TransactionsJSONPage)
comingpage = URL('/portail/particuliers/mescomptes/synthese/operationsencourslien.do', ComingTransactionsPage)
def is_logged(self): def do_login(self):
return not self.is_on_page(LoginPage)
def login(self):
""" """
Attempt to log in. Attempt to log in.
Note: this method does nothing if we are already logged in. Note: this method does nothing if we are already logged in.
""" """
assert isinstance(self.username, basestring) assert isinstance(self.username, basestring)
assert isinstance(self.password, basestring) assert isinstance(self.password, basestring)
if self.is_logged(): self.loginpage.stay_or_go()
return
if not self.is_on_page(LoginPage):
self.home()
self.page.login(self.username, self.password) self.page.login(self.username, self.password)
if self.is_on_page(LoggedPage): if self.loggedpage.is_here():
error = self.page.get_error() error = self.page.get_error()
if error is not None: if error is None:
return
raise BrowserIncorrectPassword(error) raise BrowserIncorrectPassword(error)
if not self.is_logged(): @need_login
raise BrowserIncorrectPassword()
def get_accounts_list(self): def get_accounts_list(self):
if not self.is_on_page(AccountsPage): self.accountspage.stay_or_go()
self.location('/portail/particuliers/mescomptes/synthese.do')
return self.page.get_list() return self.page.get_list()
@need_login
def get_history(self, account): def get_history(self, account):
data = {'accountExternalNumber': account.id} data = {'accountExternalNumber': account.id}
self.location('/portail/particuliers/mescomptes/relevedesoperations.do', urllib.urlencode(data)) self.transactionpage.go(data=data)
data = {'iDisplayLength': 400, data = {'iDisplayLength': 400,
'iDisplayStart': 0, 'iDisplayStart': 0,
@ -88,14 +73,15 @@ class CreditCooperatif(Browser):
'sEcho': 1, 'sEcho': 1,
'sSortDir_0': 'asc', 'sSortDir_0': 'asc',
} }
self.location('/portail/particuliers/mescomptes/relevedesoperationsjson.do', urllib.urlencode(data)) self.transactjsonpage.go(data=data)
return self.page.get_transactions() return self.page.get_transactions()
@need_login
def get_coming(self, account): def get_coming(self, account):
data = {'accountExternalNumber': account.id} data = {'accountExternalNumber': account.id}
self.location('/portail/particuliers/mescomptes/synthese/operationsencourslien.do', urllib.urlencode(data)) self.comingpage.go(data=data)
assert self.is_on_page(ComingTransactionsPage) assert self.comingpage.is_here()
return self.page.get_transactions() return self.page.get_transactions()

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright(C) 2012 Kevin Pouget # Copyright(C) 2012-2014 Kevin Pouget, Florent Fourcot
# #
# This file is part of weboob. # This file is part of weboob.
# #
@ -18,26 +18,27 @@
# along with weboob. If not, see <http://www.gnu.org/licenses/>. # along with weboob. If not, see <http://www.gnu.org/licenses/>.
from decimal import Decimal
import re import re
from weboob.tools.json import json from weboob.tools.json import json
from weboob.deprecated.browser import Page
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
from weboob.browser.pages import HTMLPage, JsonPage, LoggedPage
from weboob.browser.filters.standard import Filter, Format, CleanText, CleanDecimal
from weboob.browser.elements import ListElement, ItemElement, method
class LoginPage(Page): class LoginPage(HTMLPage):
def login(self, login, password): def login(self, login, password):
self.browser.select_form(predicate=lambda form: form.attrs.get('id', '') == 'AuthForm') form = self.get_form(xpath='//form[@id="AuthForm"]')
self.browser['j_username'] = login.encode('iso-8859-15') form['j_username'] = login.encode('iso-8859-15')
self.browser['j_password'] = password.encode('iso-8859-15') form['j_password'] = password.encode('iso-8859-15')
self.browser.submit(nologin=True) form.submit()
class LoggedPage(Page): class CreditLoggedPage(HTMLPage):
def get_error(self): def get_error(self):
div = self.document.xpath('//div[@class="errorForm-msg"]') div = self.doc.xpath('//div[@class="errorForm-msg"]')
if len(div) == 0: if len(div) == 0:
return None return None
@ -45,24 +46,31 @@ class LoggedPage(Page):
return re.sub('[\r\n\t\xa0]+', ' ', msg) return re.sub('[\r\n\t\xa0]+', ' ', msg)
class AccountsPage(Page): class AddType(Filter):
ACCOUNT_TYPES = {u'COMPTE NEF': Account.TYPE_CHECKING} types = {u'COMPTE NEF': Account.TYPE_CHECKING,
u'CPTE A VUE': Account.TYPE_CHECKING,
u'LIVRET AGIR': Account.TYPE_SAVINGS}
def get_list(self): def filter(self, str_type):
for table in self.document.getroot().cssselect('table.table-synthese'): for key, acc_type in self.types.items():
account = Account() if key == str_type:
labels = table.xpath('.//ul[@class="nClient"]/li') return acc_type
account_type_str = table.xpath('.//h2[@class="tt_compte"]')[0].text.strip() return Account.TYPE_UNKNOWN
account.id = re.sub(u'[^0-9]', '', labels[-1].text)
account.label = u' '.join([account_type_str, labels[0].text.strip()])
account.type = self.ACCOUNT_TYPES.get(account_type_str, Account.TYPE_UNKNOWN)
balance = table.xpath('.//td[@class="sum_solde"]//span')[-1].text class AccountsPage(LoggedPage, HTMLPage):
account.balance = Decimal(FrenchTransaction.clean_amount(balance)) @method
account.currency = account.get_currency(balance) class get_list(ListElement):
item_xpath = '//table[has-class("table-synthese")]'
yield account class item(ItemElement):
klass = Account
obj_label = Format('%s %s', CleanText('.//h2[@class="tt_compte"][1]'), CleanText('.//ul[@class="nClient"]/li[1]'))
obj_id = CleanText('.//ul[@class="nClient"]/li[last()]', symbols=u'')
obj_type = AddType(CleanText('.//h2[@class="tt_compte"][1]'))
obj_balance = CleanDecimal('.//td[@class="sum_solde"]//span[last()]', replace_dots=True)
obj_currency = u'EUR'
class Transaction(FrenchTransaction): class Transaction(FrenchTransaction):
@ -89,11 +97,11 @@ class Transaction(FrenchTransaction):
] ]
class TransactionsPage(Page): class TransactionsPage(LoggedPage, HTMLPage):
pass pass
class TransactionsJSONPage(Page): class TransactionsJSONPage(LoggedPage, JsonPage):
ROW_DATE = 0 ROW_DATE = 0
ROW_TEXT = 2 ROW_TEXT = 2
ROW_CREDIT = -1 ROW_CREDIT = -1
@ -101,7 +109,7 @@ class TransactionsJSONPage(Page):
def get_transactions(self): def get_transactions(self):
seen = set() seen = set()
for tr in self.document['exportData'][1:]: for tr in self.doc['exportData'][1:]:
t = Transaction(0) t = Transaction(0)
t.parse(tr[self.ROW_DATE], tr[self.ROW_TEXT]) t.parse(tr[self.ROW_DATE], tr[self.ROW_TEXT])
t.set_amount(tr[self.ROW_CREDIT], tr[self.ROW_DEBIT]) t.set_amount(tr[self.ROW_CREDIT], tr[self.ROW_DEBIT])
@ -109,7 +117,7 @@ class TransactionsJSONPage(Page):
yield t yield t
class ComingTransactionsPage(Page): class ComingTransactionsPage(LoggedPage, HTMLPage):
ROW_REF = 0 ROW_REF = 0
ROW_TEXT = 1 ROW_TEXT = 1
ROW_DATE = 2 ROW_DATE = 2
@ -118,7 +126,7 @@ class ComingTransactionsPage(Page):
def get_transactions(self): def get_transactions(self):
data = [] data = []
for script in self.document.xpath('//script'): for script in self.doc.xpath('//script'):
txt = script.text txt = script.text
if txt is None: if txt is None:
continue continue