fix carrefourbanque to use new website (and rewrite it with browser2)

This commit is contained in:
Romain Bignon 2014-04-26 12:01:09 +02:00
commit 73cb61fec7
3 changed files with 59 additions and 154 deletions

View file

@ -18,6 +18,7 @@
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from weboob.capabilities.base import find_object
from weboob.capabilities.bank import ICapBank, AccountNotFound
from weboob.tools.backend import BaseBackend, BackendConfig
from weboob.tools.value import ValueBackendPassword
@ -35,8 +36,8 @@ class CarrefourBanqueBackend(BaseBackend, ICapBank):
VERSION = '0.i'
DESCRIPTION = u'Carrefour Banque'
LICENSE = 'AGPLv3+'
CONFIG = BackendConfig(ValueBackendPassword('login', label=u'Référent client', masked=False),
ValueBackendPassword('password', label=u"Code d'accès", regexp='\d+'))
CONFIG = BackendConfig(ValueBackendPassword('login', label=u'Votre Identifiant Internet', masked=False),
ValueBackendPassword('password', label=u"Code d'accès", regexp=u'\d+'))
BROWSER = CarrefourBanque
def create_default_browser(self):
@ -44,26 +45,10 @@ class CarrefourBanqueBackend(BaseBackend, ICapBank):
self.config['password'].get())
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:
account = self.browser.get_account(_id)
if account:
return account
else:
raise AccountNotFound()
return find_object(self.browser.get_accounts_list(), id=_id, error=AccountNotFound)
def iter_history(self, account):
with self.browser:
for tr in self.browser.iter_history(account):
if not tr._coming:
yield tr
def iter_coming(self, account):
with self.browser:
for tr in self.browser.iter_history(account):
if tr._coming:
yield tr
return self.browser.iter_history(account)

View file

@ -18,36 +18,23 @@
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
import urllib
from weboob.tools.browser2 import LoginBrowser, URL, need_login
from weboob.tools.browser import BrowserIncorrectPassword
from weboob.tools.browser import BaseBrowser
from .pages import LoginPage, HomePage, AccountsPage, TransactionsPage
from .pages import LoginPage, HomePage, TransactionsPage
__all__ = ['CarrefourBanque']
class CarrefourBanque(BaseBrowser):
PROTOCOL = 'https'
DOMAIN = 'services.carrefour-banque.fr'
ENCODING = 'iso-8859-15'
PAGES = {'https?://services.carrefour-banque.fr/s2pnet/publ/identification.do': LoginPage,
'https?://services.carrefour-banque.fr/stscripts/run.stn/s2p/SommairePS2P': HomePage,
'https?://services.carrefour-banque.fr/s2pnet/priv/disponible.do': AccountsPage,
'https?://services.carrefour-banque.fr/s2pnet/priv/consult.do\?btnTelechargement': (TransactionsPage, 'raw'),
}
class CarrefourBanque(LoginBrowser):
BASEURL = 'https://www.carrefour-banque.fr'
def is_logged(self):
return self.page is not None and not self.is_on_page(LoginPage)
login = URL('/espace-client/connexion', LoginPage)
home = URL('/espace-client$', HomePage)
transactions = URL('/espace-client/carte-credit/solde-dernieres-operations.*', TransactionsPage)
def home(self):
if self.is_logged():
self.location('/s2pnet/priv/disponible.do')
else:
self.login()
def login(self):
def do_login(self):
"""
Attempt to log in.
Note: this method does nothing if we are already logged in.
@ -55,41 +42,21 @@ class CarrefourBanque(BaseBrowser):
assert isinstance(self.username, basestring)
assert isinstance(self.password, basestring)
if self.is_logged():
return
self.login.go()
self.page.enter_login(self.username)
self.page.enter_password(self.password)
args = {'login': '',
'loginCBPASS': self.username.encode(self.ENCODING),
'motPasse': self.password.encode(self.ENCODING),
'testJS': 'true',
'x': 8,
'y': 4,
}
self.location('https://services.carrefour-banque.fr/s2pnet/publ/identification.do', urllib.urlencode(args), no_login=True)
assert self.is_on_page(LoginPage)
# raises BrowserIncorrectPassword if no redirect form is found
self.page.redirect()
if not self.home.is_here():
raise BrowserIncorrectPassword()
@need_login
def get_accounts_list(self):
if not self.is_on_page(AccountsPage):
self.location('/s2pnet/priv/disponible.do')
self.home.stay_or_go()
return self.page.get_list()
def get_account(self, id):
assert isinstance(id, basestring)
l = self.get_accounts_list()
for a in l:
if a.id == id:
return a
return None
@need_login
def iter_history(self, account):
self.location('/s2pnet/priv/consult.do?btnTelechargement')
self.location(account._link)
assert self.is_on_page(TransactionsPage)
assert self.transactions.is_here()
return self.page.get_history(account)

View file

@ -18,102 +18,55 @@
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
import datetime
from decimal import Decimal
import re
from mechanize import FormNotFoundError
from weboob.tools.browser import BasePage, BrowserIncorrectPassword
from weboob.tools.browser2.page import HTMLPage, ListElement, ItemElement, method, LoggedPage
from weboob.tools.browser2.filters import Regexp, CleanText, CleanDecimal, Format, Link
from weboob.capabilities.bank import Account
from weboob.tools.capabilities.bank.transactions import FrenchTransaction
__all__ = ['LoginPage', 'AccountsPage', 'TransactionsPage']
__all__ = ['LoginPage', 'HomePage', 'TransactionsPage']
class LoginPage(BasePage):
def redirect(self):
try:
self.browser.select_form(name='redirectEpargne')
self.browser.submit(nologin=True)
except FormNotFoundError:
raise BrowserIncorrectPassword()
class LoginPage(HTMLPage):
def enter_login(self, username):
form = self.get_form(nr=0)
form['name'] = username
form.submit()
def enter_password(self, password):
form = self.get_form(nr=0)
form['pass'] = password
form.submit()
class HomePage(BasePage):
pass
class HomePage(LoggedPage, HTMLPage):
@method
class get_list(ListElement):
item_xpath = '//div[@class="three_contenu_table"]'
class item(ItemElement):
klass = Account
obj_id = Regexp(CleanText('./div[@class="carte_col_leftcol"]/p'), r'(\d+)')
obj_label = CleanText('./div[@class="carte_col_leftcol"]/h2')
obj_balance = CleanDecimal(Format('-%s', CleanText('.//div[@class="catre_col_one"]/h2')))
obj_currency = FrenchTransaction.Currency('.//div[@class="catre_col_one"]/h2')
obj__link = Link('.//a[contains(@href, "solde-dernieres-operations")]')
class AccountsPage(BasePage):
def get_list(self):
div = self.document.xpath('//div[@id="descriptifdroite"]')[0]
account = Account()
account.id = re.search(u'(\d+)', div.xpath('.//div[@class="credithauttexte"]')[0].text).group(1)
account.label = u'Carte PASS'
account.balance = Decimal('0')
for tr in div.xpath('.//table/tr'):
tds = tr.findall('td')
if len(tds) < 3:
continue
label = u''.join([txt.strip() for txt in tds[1].itertext()])
value = u''.join([txt.strip() for txt in tds[2].itertext()])
if 'encours depuis le dernier' in label.lower():
coming = u'-' + value
account.coming = Decimal(FrenchTransaction.clean_amount(coming))
account.currency = account.get_currency(coming)
elif u'arrêté de compte' in label.lower():
m = re.search(u'(\d+)/(\d+)/(\d+)', label)
if m:
account._outstanding_date = datetime.date(*reversed(map(int, m.groups())))
break
yield account
class Transaction(FrenchTransaction):
PATTERNS = [(re.compile(r'^(?P<text>.*?) (?P<dd>\d{2})/(?P<mm>\d{2})$'), FrenchTransaction.TYPE_CARD)]
class TransactionsPage(BasePage):
COL_DATE = 0
COL_TEXT = 1
COL_AMOUNT = 2
class TransactionsPage(LoggedPage, HTMLPage):
@method
class get_history(Transaction.TransactionsElement):
head_xpath = '//table[@id="creditHistory"]//thead/tr/th'
item_xpath = '//table[@id="creditHistory"]/tbody/tr'
def get_history(self, account):
transactions = []
last_order = None
for tr in self.document.split('\n')[1:]:
cols = tr.split(';')
if len(cols) < 4:
continue
t = FrenchTransaction(0)
date = cols[self.COL_DATE]
raw = cols[self.COL_TEXT]
amount = cols[self.COL_AMOUNT]
t.parse(date, re.sub(r'[ ]+', ' ', raw))
if t.raw.startswith('PRELEVEMENT ACHATS DIFFERES'):
t._coming = False
if last_order is None:
last_order = t.date
else:
t._coming = True
t.set_amount(amount)
transactions.append(t)
# go to the previous stop date before the last order
while last_order is not None and last_order.day != account._outstanding_date.day:
last_order = last_order - datetime.timedelta(days=1)
for t in transactions:
if t.date <= last_order:
t._coming = False
return iter(transactions)
class item(Transaction.TransactionElement):
obj_id = None
obj_type = Transaction.TYPE_CARD