diff --git a/modules/boursorama/browser.py b/modules/boursorama/browser.py index df42dcd07800c8e714ffa96b76a18b58114fd8e2..63d0899e5ef52bb808180863060de8f12d5f5a62 100644 --- a/modules/boursorama/browser.py +++ b/modules/boursorama/browser.py @@ -26,7 +26,7 @@ from weboob.browser.retry import login_method, retry_on_logout, RetryLoginBrowser from weboob.browser.browsers import need_login, StatesMixin from weboob.browser.url import URL -from weboob.exceptions import BrowserIncorrectPassword, BrowserHTTPNotFound, BrowserUnavailable +from weboob.exceptions import BrowserIncorrectPassword, BrowserHTTPNotFound, NoAccountsException, BrowserUnavailable from weboob.browser.exceptions import LoggedOut, ClientError from weboob.capabilities.bank import ( Account, AccountNotFound, TransferError, TransferInvalidAmount, @@ -45,7 +45,7 @@ CardsNumberPage, CalendarPage, HomePage, PEPPage, TransferAccounts, TransferRecipients, TransferCharac, TransferConfirm, TransferSent, AddRecipientPage, StatusPage, CardHistoryPage, CardCalendarPage, CurrencyListPage, CurrencyConvertPage, - AccountsErrorPage, + AccountsErrorPage, NoAccountPage, ) @@ -69,9 +69,13 @@ class BoursoramaBrowser(RetryLoginBrowser, StatesMixin): error = URL('/connexion/compte-verrouille', '/infos-profil', ErrorPage) login = URL('/connexion/', LoginPage) + accounts = URL('/dashboard/comptes\?_hinclude=300000', AccountsPage) accounts_error = URL('/dashboard/comptes\?_hinclude=300000', AccountsErrorPage) pro_accounts = URL(r'/dashboard/comptes-professionnels\?_hinclude=1', AccountsPage) + no_account = URL('/dashboard/comptes\?_hinclude=300000', + '/dashboard/comptes-professionnels\?_hinclude=1', NoAccountPage) + acc_tit = URL('/comptes/titulaire/(?P.*)\?_hinclude=1', AccbisPage) acc_rep = URL('/comptes/representative/(?P.*)\?_hinclude=1', AccbisPage) acc_pro = URL('/comptes/professionnel/(?P.*)\?_hinclude=1', AccbisPage) @@ -196,9 +200,20 @@ def get_accounts_list(self): for x in range(3): if self.accounts_list is not None: break + self.accounts_list = [] self.loans_list = [] - self.accounts_list.extend(self.pro_accounts.go().iter_accounts()) + # Check that there is at least one account for this user + has_account = False + self.pro_accounts.go() + if self.pro_accounts.is_here(): + self.accounts_list.extend(self.page.iter_accounts()) + has_account = True + else: + # We dont want to let has_account=False if we landed on an unknown page + # it has to be the no_accounts page + assert self.no_account.is_here() + try: self.accounts.go() except BrowserUnavailable as e: @@ -207,9 +222,20 @@ def get_accounts_list(self): self.accounts_list = None continue else: - self.accounts_list.extend(self.page.iter_accounts()) + if self.accounts.is_here(): + self.accounts_list.extend(self.page.iter_accounts()) + has_account = True + else: + # We dont want to let has_account=False if we landed on an unknown page + # it has to be the no_accounts page + assert self.no_account.is_here() + exc = None + if not has_account: + # if we landed twice on NoAccountPage, it means there is neither pro accounts nor pp accounts + raise NoAccountsException() + # discard all unvalid card accounts (if opposed or not yet activated) valid_card_url = [] for account in self.accounts_list: diff --git a/modules/boursorama/pages.py b/modules/boursorama/pages.py index 84244cb28f500d8bc807dd294c15033d58412e87..e4e534a97d0f407b981a9de8c68ab4f67e0d3725 100644 --- a/modules/boursorama/pages.py +++ b/modules/boursorama/pages.py @@ -207,6 +207,7 @@ def on_load(self): class AccountsPage(LoggedPage, HTMLPage): def is_here(self): + # This id appears when there are no accounts (pro and pp) return not self.doc.xpath('//div[contains(@id, "alert-random")]') ACCOUNT_TYPES = {u'comptes courants': Account.TYPE_CHECKING, @@ -366,6 +367,12 @@ def obj_next_payment_date(self): return Date(CleanText('//p[contains(text(), "Date de la prochaine échéance")]/span'), parse_func=parse_french_date)(self) +class NoAccountPage(LoggedPage, HTMLPage): + def is_here(self): + err = CleanText('//div[contains(@id, "alert-random")]/text()', children=False)(self.doc) + return "compte inconnu" in err.lower() + + class CardCalendarPage(LoggedPage, RawPage): def is_here(self): return b'VCALENDAR' in self.doc