diff --git a/modules/binck/browser.py b/modules/binck/browser.py index 7dba65057d4199d4cb278fbd29265ab97f36554c..ebcebe0633ed2747550b1271dd80da759e849b13 100644 --- a/modules/binck/browser.py +++ b/modules/binck/browser.py @@ -30,6 +30,7 @@ from .pages import ( LoginPage, HomePage, AccountsPage, OldAccountsPage, HistoryPage, InvestmentPage, InvestDetailPage, InvestmentListPage, QuestionPage, ChangePassPage, LogonFlowPage, ViewPage, SwitchPage, + HandlePasswordsPage, PostponePasswords, ) @@ -61,6 +62,8 @@ class BinckBrowser(LoginBrowser): r'FsmaMandatoryQuestionnairesOverview', QuestionPage) change_pass = URL(r'/ChangePassword/Index', r'/EditSetting/GetSetting\?code=MutationPassword', ChangePassPage) + handle_passwords = URL(r'/PersonalCredentials/Index', HandlePasswordsPage) + postpone_passwords = URL(r'/PersonalCredentials/PostPone', PostponePasswords) def deinit(self): if self.page and self.page.logged: @@ -94,6 +97,13 @@ def switch_account(self, account_id): @need_login def iter_accounts(self): + # If we already know that it is an old website connection, + # we can call old_website_connection() right away. + if self.old_website_connection: + for account in self.iter_old_accounts(): + yield account + return + if self.unique_account: self.account.stay_or_go() else: @@ -121,41 +131,46 @@ def iter_accounts(self): # so we need to fetch them on the OldAccountsPage for now: else: self.old_website_connection = True - self.old_accounts.go() - for a in self.page.iter_accounts(): - try: - self.old_accounts.stay_or_go().go_to_account(a.id) - except ServerError as exception: - # get html error to parse - parser = etree.HTMLParser() - html_error = etree.parse(StringIO(exception.response.text), parser) - account_error = html_error.xpath('//p[contains(text(), "Votre compte est")]/text()') - if account_error: - raise ActionNeeded(account_error[0]) - else: - raise - - a.iban = self.page.get_iban() - # Get token - token = self.page.get_token() - # Get investment page - data = {'grouping': "SecurityCategory"} - try: - a._invpage = self.investment.go(data=data, headers=token) \ - if self.page.is_investment() else None - except HTTPNotFound: - # if it's not an invest account, the portfolio link may be present but hidden and return a 404 - a._invpage = None + for account in self.iter_old_accounts(): + yield account + + @need_login + def iter_old_accounts(self): + self.old_accounts.go() + for a in self.page.iter_accounts(): + try: + self.old_accounts.stay_or_go().go_to_account(a.id) + except ServerError as exception: + # get html error to parse + parser = etree.HTMLParser() + html_error = etree.parse(StringIO(exception.response.text), parser) + account_error = html_error.xpath('//p[contains(text(), "Votre compte est")]/text()') + if account_error: + raise ActionNeeded(account_error[0]) + else: + raise + + a.iban = self.page.get_iban() + # Get token + token = self.page.get_token() + # Get investment page + data = {'grouping': "SecurityCategory"} + try: + a._invpage = self.investment.go(data=data, headers=token) \ + if self.page.is_investment() else None + except HTTPNotFound: + # if it's not an invest account, the portfolio link may be present but hidden and return a 404 + a._invpage = None - if a._invpage: - a.valuation_diff = a._invpage.get_valuation_diff() - # Get history page - data = [('currencyCode', a.currency), ('startDate', ""), ('endDate', "")] - a._histpages = [self.history.go(data=data, headers=token)] - while self.page.doc['EndOfData'] is False: - a._histpages.append(self.history.go(data=self.page.get_nextpage_data(data[:]), headers=token)) + if a._invpage: + a.valuation_diff = a._invpage.get_valuation_diff() + # Get history page + data = [('currencyCode', a.currency), ('startDate', ""), ('endDate', "")] + a._histpages = [self.history.go(data=data, headers=token)] + while self.page.doc['EndOfData'] is False: + a._histpages.append(self.history.go(data=self.page.get_nextpage_data(data[:]), headers=token)) - yield a + yield a @need_login def iter_investment(self, account): diff --git a/modules/binck/pages.py b/modules/binck/pages.py index bb8c7bf9f4a236ee03c5dbec373cf198a2b97b93..9f32f323c02b9e2a092f1f39391ee407f136270e 100644 --- a/modules/binck/pages.py +++ b/modules/binck/pages.py @@ -75,6 +75,20 @@ def on_load(self): raise BrowserPasswordExpired(message) +class HandlePasswordsPage(LoggedPage, HTMLPage): + def on_load(self): + token = self.get_token() + self.browser.postpone_passwords.go(headers=token, method='POST') + self.browser.home_page.go() + + def get_token(self): + return [{Attr('.', 'name')(input): Attr('.', 'value')(input)} + for input in self.doc.xpath('//input[contains(@name, "Token")]')][0] + + +class PostponePasswords(LoggedPage, HTMLPage): + pass + class LogonFlowPage(HTMLPage): def on_load(self): raise ActionNeeded(CleanText('//article//h1 | //article//h3')(self.doc)) @@ -104,7 +118,7 @@ def has_accounts_table(self): return self.doc.xpath('//table[contains(@class, "accountoverview-table")]') def get_token(self): - return [{Attr('.', 'name')(input): Attr('.', 'value')(input)} \ + return [{Attr('.', 'name')(input): Attr('.', 'value')(input)} for input in self.doc.xpath('//input[contains(@name, "Token")]')][0] @method @@ -155,7 +169,7 @@ def get_iban(self): return CleanText('//div[@class="iban"]/text()', replace=[(' ', '')], default=NotAvailable)(self.doc) def get_token(self): - return [{Attr('.', 'name')(input): Attr('.', 'value')(input)} \ + return [{Attr('.', 'name')(input): Attr('.', 'value')(input)} for input in self.doc.xpath('//input[contains(@name, "Token")]')][0] def is_investment(self):