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")
def iter_accounts(self):
with self.browser:
return self.browser.get_accounts_list()
return self.browser.get_accounts_list()
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):
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)
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
# 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, LoggedPage, AccountsPage, TransactionsPage, TransactionsJSONPage, ComingTransactionsPage
from .pages import LoginPage, CreditLoggedPage, AccountsPage, TransactionsPage, TransactionsJSONPage, ComingTransactionsPage
__all__ = ['CreditCooperatif']
class CreditCooperatif(Browser):
PROTOCOL = 'https'
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,
}
class CreditCooperatif(LoginBrowser):
BASEURL = "https://www.credit-cooperatif.coop"
def home(self):
self.location("/portail/particuliers/mescomptes/synthese.do")
loginpage = URL('/portail//particuliers/login.do', LoginPage)
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):
return not self.is_on_page(LoginPage)
def login(self):
def do_login(self):
"""
Attempt to log in.
Note: this method does nothing if we are already logged in.
"""
assert isinstance(self.username, basestring)
assert isinstance(self.password, basestring)
if self.is_logged():
return
if not self.is_on_page(LoginPage):
self.home()
self.loginpage.stay_or_go()
self.page.login(self.username, self.password)
if self.is_on_page(LoggedPage):
if self.loggedpage.is_here():
error = self.page.get_error()
if error is not None:
raise BrowserIncorrectPassword(error)
if error is None:
return
if not self.is_logged():
raise BrowserIncorrectPassword()
raise BrowserIncorrectPassword(error)
@need_login
def get_accounts_list(self):
if not self.is_on_page(AccountsPage):
self.location('/portail/particuliers/mescomptes/synthese.do')
self.accountspage.stay_or_go()
return self.page.get_list()
@need_login
def get_history(self, account):
data = {'accountExternalNumber': account.id}
self.location('/portail/particuliers/mescomptes/relevedesoperations.do', urllib.urlencode(data))
self.transactionpage.go(data=data)
data = {'iDisplayLength': 400,
'iDisplayStart': 0,
@ -87,15 +72,16 @@ class CreditCooperatif(Browser):
'sColumns': '',
'sEcho': 1,
'sSortDir_0': 'asc',
}
self.location('/portail/particuliers/mescomptes/relevedesoperationsjson.do', urllib.urlencode(data))
}
self.transactjsonpage.go(data=data)
return self.page.get_transactions()
@need_login
def get_coming(self, account):
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()

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright(C) 2012 Kevin Pouget
# Copyright(C) 2012-2014 Kevin Pouget, Florent Fourcot
#
# This file is part of weboob.
#
@ -18,26 +18,27 @@
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from decimal import Decimal
import re
from weboob.tools.json import json
from weboob.deprecated.browser import Page
from weboob.capabilities.bank import Account
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):
self.browser.select_form(predicate=lambda form: form.attrs.get('id', '') == 'AuthForm')
self.browser['j_username'] = login.encode('iso-8859-15')
self.browser['j_password'] = password.encode('iso-8859-15')
self.browser.submit(nologin=True)
form = self.get_form(xpath='//form[@id="AuthForm"]')
form['j_username'] = login.encode('iso-8859-15')
form['j_password'] = password.encode('iso-8859-15')
form.submit()
class LoggedPage(Page):
class CreditLoggedPage(HTMLPage):
def get_error(self):
div = self.document.xpath('//div[@class="errorForm-msg"]')
div = self.doc.xpath('//div[@class="errorForm-msg"]')
if len(div) == 0:
return None
@ -45,24 +46,31 @@ class LoggedPage(Page):
return re.sub('[\r\n\t\xa0]+', ' ', msg)
class AccountsPage(Page):
ACCOUNT_TYPES = {u'COMPTE NEF': Account.TYPE_CHECKING}
class AddType(Filter):
types = {u'COMPTE NEF': Account.TYPE_CHECKING,
u'CPTE A VUE': Account.TYPE_CHECKING,
u'LIVRET AGIR': Account.TYPE_SAVINGS}
def get_list(self):
for table in self.document.getroot().cssselect('table.table-synthese'):
account = Account()
labels = table.xpath('.//ul[@class="nClient"]/li')
account_type_str = table.xpath('.//h2[@class="tt_compte"]')[0].text.strip()
def filter(self, str_type):
for key, acc_type in self.types.items():
if key == str_type:
return acc_type
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
account.balance = Decimal(FrenchTransaction.clean_amount(balance))
account.currency = account.get_currency(balance)
class AccountsPage(LoggedPage, HTMLPage):
@method
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):
@ -79,7 +87,7 @@ class Transaction(FrenchTransaction):
(re.compile('^(PRLV|PRELEVEMENT) (?P<text>.*?)(- .*)?$'),
FrenchTransaction.TYPE_ORDER),
(re.compile('^CHEQUE.*'), FrenchTransaction.TYPE_CHECK),
(re.compile('^(AGIOS /|FRAIS) (?P<text>.*)'),FrenchTransaction.TYPE_BANK),
(re.compile('^(AGIOS /|FRAIS) (?P<text>.*)'), FrenchTransaction.TYPE_BANK),
(re.compile('^ABONNEMENT (?P<text>.*)'), FrenchTransaction.TYPE_BANK),
(re.compile('^REMISE (?P<text>.*)'), FrenchTransaction.TYPE_DEPOSIT),
(re.compile('^(?P<text>.*)( \d+)? QUITTANCE .*'),
@ -89,11 +97,11 @@ class Transaction(FrenchTransaction):
]
class TransactionsPage(Page):
class TransactionsPage(LoggedPage, HTMLPage):
pass
class TransactionsJSONPage(Page):
class TransactionsJSONPage(LoggedPage, JsonPage):
ROW_DATE = 0
ROW_TEXT = 2
ROW_CREDIT = -1
@ -101,7 +109,7 @@ class TransactionsJSONPage(Page):
def get_transactions(self):
seen = set()
for tr in self.document['exportData'][1:]:
for tr in self.doc['exportData'][1:]:
t = Transaction(0)
t.parse(tr[self.ROW_DATE], tr[self.ROW_TEXT])
t.set_amount(tr[self.ROW_CREDIT], tr[self.ROW_DEBIT])
@ -109,7 +117,7 @@ class TransactionsJSONPage(Page):
yield t
class ComingTransactionsPage(Page):
class ComingTransactionsPage(LoggedPage, HTMLPage):
ROW_REF = 0
ROW_TEXT = 1
ROW_DATE = 2
@ -118,7 +126,7 @@ class ComingTransactionsPage(Page):
def get_transactions(self):
data = []
for script in self.document.xpath('//script'):
for script in self.doc.xpath('//script'):
txt = script.text
if txt is None:
continue