From 08678b382feb963f704bd9b79c276547f2dc30ea Mon Sep 17 00:00:00 2001 From: Vincent Ardisson Date: Mon, 22 May 2017 16:32:57 +0200 Subject: [PATCH] [apivie] quick port to browser2 No declarative code is used --- modules/apivie/browser.py | 64 +++++++++++++++++-------------------- modules/apivie/pages.py | 67 ++++++++++++++++++++++----------------- 2 files changed, 67 insertions(+), 64 deletions(-) diff --git a/modules/apivie/browser.py b/modules/apivie/browser.py index c87a2f30e1..19136fbc4f 100644 --- a/modules/apivie/browser.py +++ b/modules/apivie/browser.py @@ -18,7 +18,9 @@ # along with weboob. If not, see . -from weboob.deprecated.browser import Browser, BrowserIncorrectPassword +from weboob.browser import LoginBrowser, URL, need_login +from weboob.capabilities.base import find_object +from weboob.exceptions import BrowserIncorrectPassword from .pages import LoginPage, AccountsPage, InvestmentsPage, OperationsPage @@ -26,62 +28,54 @@ __all__ = ['ApivieBrowser'] -class ApivieBrowser(Browser): - PROTOCOL = 'https' - ENCODING = None - - PAGES = { - 'https?://[^/]+/': LoginPage, - 'https?://[^/]+/accueil': LoginPage, - 'https?://[^/]+/perte.*': LoginPage, - 'https?://[^/]+/accueil-connect': AccountsPage, - 'https?://[^/]+/synthese-contrat.*': InvestmentsPage, - 'https?://[^/]+/historique-contrat.*': OperationsPage, - } +class ApivieBrowser(LoginBrowser): + login = URL(r'/$', + r'/accueil$', + r'/perte.*', + LoginPage) + accounts = URL(r'/accueil-connect', AccountsPage) + investments = URL(r'/synthese-contrat.*', InvestmentsPage) + operations = URL(r'/historique-contrat.*', OperationsPage) def __init__(self, website, *args, **kwargs): - self.DOMAIN = website - Browser.__init__(self, *args, **kwargs) + self.BASEURL = 'https://%s' % website + super(ApivieBrowser, self).__init__(*args, **kwargs) def home(self): - self.location('https://%s/accueil-connect' % self.DOMAIN) - - def login(self): - assert isinstance(self.username, basestring) - assert isinstance(self.password, basestring) + self.location('%s/accueil-connect' % self.BASEURL) - if not self.is_on_page(LoginPage): - self.location('/accueil', no_login=True) + def do_login(self): + if not self.login.is_here(): + self.location('/accueil') self.page.login(self.username, self.password) - if not self.is_logged(): + if self.login.is_here(): raise BrowserIncorrectPassword() - def is_logged(self): - return not self.is_on_page(LoginPage) - + @need_login def iter_accounts(self): self.location('/accueil-connect') return self.page.iter_accounts() + @need_login def get_account(self, _id): - try: - return next(a for a in self.iter_accounts() if a.id == _id) - except StopIteration: - return None + return find_object(self.iter_accounts(), id=_id) + @need_login def iter_investment(self, account): - self.location(self.buildurl('/synthese-contrat', contratId=account.id)) + self.location('/synthese-contrat', params={'contratId': account.id}) - assert self.is_on_page(InvestmentsPage) + assert self.investments.is_here() return self.page.iter_investment() + @need_login def iter_history(self, account): - self.location(self.buildurl('/historique-contrat', contratId=account.id)) + self.location('/historique-contrat', params={'contratId': account.id}) - assert self.is_on_page(OperationsPage) + assert self.operations.is_here() return self.page.iter_history() + @need_login def get_subscription_list(self): - return iter([]) + return [] diff --git a/modules/apivie/pages.py b/modules/apivie/pages.py index bc4ee52973..5e3e2ed510 100644 --- a/modules/apivie/pages.py +++ b/modules/apivie/pages.py @@ -22,21 +22,21 @@ from weboob.capabilities.bank import Account, Investment from weboob.capabilities.base import NotAvailable -from weboob.deprecated.browser import Page +from weboob.browser.pages import LoggedPage, HTMLPage from weboob.tools.capabilities.bank.transactions import FrenchTransaction from weboob.browser.filters.standard import Date, CleanText from weboob.browser.filters.html import Attr -class LoginPage(Page): +class LoginPage(HTMLPage): def login(self, username, password): - self.browser.select_form(nr=0) - self.browser['_58_login'] = username.encode('utf-8') - self.browser['_58_password'] = password.encode('utf-8') - self.browser.submit(nologin=True) + form = self.get_form(nr=0) + form['_58_login'] = username.encode('utf-8') + form['_58_password'] = password.encode('utf-8') + return form.submit() -class AccountsPage(Page): +class AccountsPage(LoggedPage, HTMLPage): TYPES = {u'APIVIE': Account.TYPE_LIFE_INSURANCE, u'LINXEA ZEN CLIENT': Account.TYPE_LIFE_INSURANCE, u'PERP': Account.TYPE_PERP @@ -48,43 +48,50 @@ class AccountsPage(Page): COL_AMOUNT = 3 def iter_accounts(self): - for line in self.document.xpath('//table[@summary="informations contrat"]/tbody/tr'): + for line in self.doc.xpath('//table[@summary="informations contrat"]/tbody/tr'): yield self._get_account(line) def _get_account(self, line): + cleaner = CleanText().filter + tds = line.findall('td') account = Account() - account.id = self.parser.tocleanstring(tds[self.COL_ID]) - account.label = self.parser.tocleanstring(tds[self.COL_LABEL]) - account.type = self.TYPES.get(Attr('//a[contains(@class, "logo")]/img', \ - 'alt')(self.document).upper(), Account.TYPE_UNKNOWN) - balance_str = self.parser.tocleanstring(tds[self.COL_AMOUNT]) + account.id = cleaner(tds[self.COL_ID]) + account.label = cleaner(tds[self.COL_LABEL]) + tlabel = Attr('//a[contains(@class, "logo")]/img', 'alt')(self.doc).upper() + account.type = self.TYPES.get(tlabel, Account.TYPE_UNKNOWN) + balance_str = cleaner(tds[self.COL_AMOUNT]) account.balance = Decimal(FrenchTransaction.clean_amount(balance_str)) account.currency = account.get_currency(balance_str) return account -class InvestmentsPage(Page): +class InvestmentsPage(LoggedPage, HTMLPage): COL_LABEL = 0 COL_CODE = 1 COL_VALUATION = 2 COL_PORTFOLIO_SHARE = 3 def iter_investment(self): - for line in self.document.xpath('//div[@class="supportTable"]//table/tbody/tr'): + cleaner = CleanText().filter + + for line in self.doc.xpath('//div[@class="supportTable"]//table/tbody/tr'): tds = line.findall('td') if len(tds) < 4: continue inv = Investment() - inv.vdate = Date(dayfirst=True).filter(CleanText().filter( \ - self.document.xpath('//div[@id="table-evolution-contrat"]//table/tbody/tr[1]/td[1]'))) \ - if self.document.xpath('//div[@id="table-evolution-contrat"]//table/tbody/tr[1]/td[1]') else NotAvailable - inv.label = self.parser.tocleanstring(tds[self.COL_LABEL]) - inv.code = self.parser.tocleanstring(tds[self.COL_CODE]) - inv.valuation = Decimal(FrenchTransaction.clean_amount( \ - self.parser.tocleanstring(tds[self.COL_VALUATION]))) - inv.portfolio_share = Decimal(FrenchTransaction.clean_amount( \ - self.parser.tocleanstring(tds[self.COL_PORTFOLIO_SHARE]))) / 100 + + if self.doc.xpath('//div[@id="table-evolution-contrat"]//table/tbody/tr[1]/td[1]'): + inv.vdate = Date(dayfirst=True).filter(CleanText().filter( + self.doc.xpath('//div[@id="table-evolution-contrat"]//table/tbody/tr[1]/td[1]'))) + else: + inv.vdate = NotAvailable + inv.label = cleaner(tds[self.COL_LABEL]) + inv.code = cleaner(tds[self.COL_CODE]) + inv.valuation = Decimal(FrenchTransaction.clean_amount( + cleaner(tds[self.COL_VALUATION]))) + inv.portfolio_share = Decimal(FrenchTransaction.clean_amount( + cleaner(tds[self.COL_PORTFOLIO_SHARE]))) / 100 yield inv @@ -92,20 +99,22 @@ class Transaction(FrenchTransaction): pass -class OperationsPage(Page): +class OperationsPage(LoggedPage, HTMLPage): COL_DATE = 0 COL_LABEL = 1 COL_AMOUNT = 2 def iter_history(self): - for line in self.document.xpath('//table[@role="treegrid"]/tbody/tr'): + cleaner = CleanText().filter + + for line in self.doc.xpath('//table[@role="treegrid"]/tbody/tr'): tds = line.findall('td') operation = Transaction() - date = self.parser.tocleanstring(tds[self.COL_DATE]) - label = self.parser.tocleanstring(tds[self.COL_LABEL]) - amount = self.parser.tocleanstring(tds[self.COL_AMOUNT]) + date = cleaner(tds[self.COL_DATE]) + label = cleaner(tds[self.COL_LABEL]) + amount = cleaner(tds[self.COL_AMOUNT]) if len(amount) == 0: continue -- GitLab