コード例 #1
0
ファイル: pages.py プロジェクト: dasimon/weboob
    def iter_investment(self):
        for line in self.document.xpath('//table[contains(@class, "ca-data-table")]/descendant::tr[count(td)>=7]'):
            for sub in line.xpath('./td[@class="info-produit"]'):
                sub.drop_tree()
            cells = line.findall('td')

            if cells[self.COL_ID].find('div/a') is None:
                continue
            inv = Investment()
            inv.label = unicode(cells[self.COL_ID].find('div/a').text.strip())
            inv.code = cells[self.COL_ID].find('div/br').tail.strip().split(u'\xa0')[0]
            inv.quantity = self.parse_decimal(cells[self.COL_QUANTITY].find('span').text)
            inv.valuation = self.parse_decimal(cells[self.COL_VALUATION].text)
            inv.diff = self.parse_decimal(cells[self.COL_DIFF].text_content())
            if "%" in cells[self.COL_UNITPRICE].text and "%" in cells[self.COL_UNITVALUE].text:
                inv.unitvalue = inv.valuation / inv.quantity
                inv.unitprice = (inv.valuation - inv.diff) / inv.quantity
            else:
                inv.unitprice = self.parse_decimal(cells[self.COL_UNITPRICE].text)
                inv.unitvalue = self.parse_decimal(cells[self.COL_UNITVALUE].text)
            date = cells[self.COL_UNITVALUE].find('span').text
            if ':' in date:
                inv.vdate = ddate.today()
            else:
                day, month = map(int, date.split('/', 1))
                date_guesser = LinearDateGuesser()
                inv.vdate = date_guesser.guess_date(day, month)

            yield inv
コード例 #2
0
 def get_card_transactions(self, latest_date, ongoing_coming):
     for item in self.doc.xpath('//table[@class="ca-table"][2]//tr[td]'):
         if CleanText('./td[2]/b')(item):
             # This node is a summary containing the 'date' for all following transactions.
             raw_date = Regexp(CleanText('./td[2]/b/text()'),
                               r'le (.*) :')(item)
             if latest_date and parse_french_date(
                     raw_date).date() > latest_date:
                 # This summary has already been fetched
                 continue
             latest_date = parse_french_date(raw_date).date()
             if latest_date < ongoing_coming:
                 # This summary is anterior to the ongoing_coming so we create a transaction from it
                 tr = FrenchTransaction()
                 tr.date = tr.rdate = latest_date
                 tr.raw = tr.label = CleanText('./td[2]/b/text()')(item)
                 tr.amount = -CleanDecimal.French(
                     './td[position()=last()]')(item)
                 tr.type = FrenchTransaction.TYPE_CARD_SUMMARY
                 yield tr
         else:
             # This node is a real transaction.
             # Its 'date' is the date of the most recently encountered summary node.
             tr = FrenchTransaction()
             tr.date = latest_date
             date_guesser = LinearDateGuesser(latest_date)
             tr.rdate = tr.bdate = DateGuesser(
                 CleanText('./td[1]//text()'),
                 date_guesser=date_guesser)(item)
             tr.label = tr.raw = CleanText('./td[2]')(item)
             tr.amount = CleanDecimal.French('./td[last()]')(item)
             tr.type = FrenchTransaction.TYPE_DEFERRED_CARD
             yield tr
コード例 #3
0
ファイル: browser.py プロジェクト: yang2lalang/weboob
    def get_history(self, account):
        # some accounts may exist without a link to any history page
        if account._link_id is None:
            return
        history_url = account._link_id
        operations_count = 0

        # 1st, go on the account page
        self.logger.debug('going on: %s' % history_url)
        self.location('https://%s%s' % (self.DOMAIN, history_url))

        if self.page is None:
            return

        # Some regions have a "Show more" (well, actually "Voir les 25
        # suivants") link we have to use to get all the operations.
        # However, it does not show only the 25 next results, it *adds* them
        # to the current view. Therefore, we have to parse each new page using
        # an offset, in order to ignore all already-fetched operations.
        # This especially occurs on CA Centre.
        use_expand_url = bool(self.page.expand_history_page_url())
        date_guesser = LinearDateGuesser()
        while True:
            # we skip "operations_count" operations on each page if we are in the case described above
            operations_offset = operations_count if use_expand_url else 0
            for page_operation in self.page.get_history(
                    date_guesser, operations_count, operations_offset):
                operations_count += 1
                yield page_operation
            history_url = self.page.expand_history_page_url(
            ) if use_expand_url else self.page.next_page_url()
            if not history_url:
                break
            self.logger.debug('going on: %s' % history_url)
            self.location('https://%s%s' % (self.DOMAIN, history_url))
コード例 #4
0
    def get_history(self, account, coming=False):
        if account._link_id is None:
            return

        if account._link_id.startswith('javascript') or '&Crd=' in account._link_id:
            raise NotImplementedError()

        self.location(self.accounts_list[account.id]._link_id)

        #If we relogin on hsbc, all link have change
        if self.app_gone:
            self.app_gone = False
            self.update_accounts_list()
            self.location(self.accounts_list[account.id]._link_id)

        if self.page is None:
            return

        if self.cbPage.is_here():
            guesser = LinearDateGuesser(date_max_bump=timedelta(45))
            return [tr for tr in self.page.get_history(date_guesser=guesser) if (coming and tr.date > date.today()) or (not coming and tr.date <= date.today())]
        elif not coming:
            return self._get_history()
        else:
            raise NotImplementedError()
コード例 #5
0
ファイル: browser.py プロジェクト: dermorz/weboob
    def iter_history(self, account):
        self.fetch_areas()

        if account._history_url.startswith('javascript:'):
            raise NotImplementedError()

        # Manage multiple areas
        self.subscription.go()
        self.location(account._area)
        self.accounts.go()

        # Query history for 6 last months
        def format_date(d):
            return datetime.date.strftime(d, '%d/%m/%Y')

        today = datetime.date.today()
        period = (today - relativedelta(months=6), today)
        query = {'date': ''.join(map(format_date, period))}

        # Let's go
        self.location(account._history_url)
        first_page = self.page
        rest_page = self.history.go(data=query)
        date_guesser = LinearDateGuesser()

        return chain(
            first_page.iter_history(date_guesser=date_guesser),
            reversed(list(rest_page.iter_history(date_guesser=date_guesser))))
コード例 #6
0
 def get_coming(self):
     transactions = list(
         self.groupamaes_page.go(
             page='&_pid=OperationsTraitees&_fid=GoWaitingOperations').
         get_history(date_guesser=LinearDateGuesser(), coming=True))
     transactions.sort(key=lambda tr: tr.rdate, reverse=True)
     return transactions
コード例 #7
0
    def get_history(self, account):
        if not self.is_on_page(AccountsPage):
            self.go_on_accounts_list()

        url = account._link

        coming = True
        date_guesser = LinearDateGuesser()

        while url is not None:
            self.select_form(name='leftnav')
            self.form.action = self.absurl(url)
            self.submit()

            assert self.is_on_page(TransactionsPage)

            for tr in self.page.get_history(date_guesser):
                if tr.amount > 0:
                    coming = False
                tr._is_coming = coming
                yield tr

            if self.page.is_last():
                url = None
            else:
                v = urlsplit(url)
                args = dict(parse_qsl(v.query))
                args['BPIndex'] = int(args['BPIndex']) + 1
                url = self.buildurl(v.path, **args)
コード例 #8
0
 def get_coming(self):
     transactions = list(
         self.groupamaes_page.go(
             page='&_pid=OperationsTraitees&_fid=GoWaitingOperations').
         get_history(date_guesser=LinearDateGuesser(), coming=True))
     transactions = sorted_transactions(transactions)
     return transactions
コード例 #9
0
 def get_history(self):
     transactions = list(
         self.groupamaes_page.go(
             page='&_pid=MenuOperations&_fid=GoOperationsTraitees').
         get_history(date_guesser=LinearDateGuesser()))
     transactions = sorted_transactions(transactions)
     return transactions
コード例 #10
0
ファイル: browser.py プロジェクト: skeptycal/weboob-devel
    def get_history(self, account):
        # some accounts may exist without a link to any history page
        if account._link is None:
            return

        # card accounts need to get an updated link
        if account.type == Account.TYPE_CARD:
            account = self.get_account(account.id)

        date_guesser = LinearDateGuesser()
        self.location(account._link)

        if self.is_on_page(CardsPage):
            for tr in self.page.get_history(date_guesser):
                yield tr
        else:
            url = self.page.get_order_by_date_url()

            while url:
                self.location(url)
                assert self.is_on_page(TransactionsPage)

                for tr in self.page.get_history(date_guesser):
                    yield tr

                url = self.page.get_next_url()
コード例 #11
0
ファイル: pages.py プロジェクト: dermorz/weboob
        def obj_date(self):
            _date = Regexp(CleanText('//p[has-class("line")]', replace=[(u'à', '')]),
                           '.*Mise en ligne le (.*)')(self)

            for fr, en in DATE_TRANSLATE_FR:
                _date = fr.sub(en, _date)

            self.env['tmp'] = _date
            return DateTime(Env('tmp'), LinearDateGuesser())(self)
コード例 #12
0
        def obj_date(self):
            _date = Regexp(
                CleanText('//div[@class="upload_by"]', replace=[(u'à', '')]),
                '.*- Mise en ligne le (.*).')(self)

            for fr, en in DATE_TRANSLATE_FR:
                _date = fr.sub(en, _date)

            self.env['tmp'] = _date
            return DateTime(Env('tmp'), LinearDateGuesser())(self)
コード例 #13
0
            def obj_date(self):
                _date = CleanText('./div[@class="lbc"]/div[@class="date"]',
                                  replace=[('Aujourd\'hui', str(date.today())),
                                           ('Hier',
                                            str((date.today() - timedelta(1))))
                                           ])(self)
                for fr, en in DATE_TRANSLATE_FR:
                    _date = fr.sub(en, _date)

                self.env['tmp'] = _date
                return DateTime(Env('tmp'), LinearDateGuesser())(self)
コード例 #14
0
ファイル: browser.py プロジェクト: dasimon/weboob
    def get_history(self, account):
        if account.type in (Account.TYPE_MARKET, Account.TYPE_LIFE_INSURANCE):
            self.logger.warning('This account is not supported')
            raise NotImplementedError()

        # some accounts may exist without a link to any history page
        if account._link is None:
            return

        did_move = False
        if account._perimeter != self.current_perimeter:
            self.go_perimeter(account._perimeter)
            did_move = True

        # card accounts need to get an updated link
        if account.type == Account.TYPE_CARD:
            accounts = [acc for acc in self.get_cards() if acc.id == account.id]
            assert len(accounts) == 1
            account = accounts[0]

        date_guesser = LinearDateGuesser()
        if account.type != Account.TYPE_CARD or not self.page.is_on_right_detail(account):
            self.location(account._link.format(self.sag))

        if self.is_on_page(CardsPage):
            url = self.page.url
            state = None
            notfirst = False
            while url:
                if notfirst:
                    self.location(url)
                else:
                    notfirst = True
                assert self.is_on_page(CardsPage)
                for state, tr in self.page.get_history(date_guesser, state):
                    yield tr

                url = self.page.get_next_url()

        elif self.page:
            url = self.page.get_order_by_date_url()
            while url:
                self.location(url)
                assert self.is_on_page(TransactionsPage)

                for tr in self.page.get_history(date_guesser):
                    yield tr

                url = self.page.get_next_url()

        # Ugly hack needed for for following card accounts history
        if did_move:
            self.get_accounts_list()
コード例 #15
0
        class item(ItemElement):
            klass = Transaction

            obj_date = DateGuesser(CleanText('.//span[contains(., "/")]'), LinearDateGuesser(date_max_bump=timedelta(45)))
            obj_label = CleanText('.//h3/strong')
            obj_amount = MyDecimal('./td[@class="al-r"]/div/span[has-class("badge")]')
            def obj_type(self):
                amount = Field('amount')(self)
                if amount < 0:
                    return Transaction.TYPE_CARD
                else:
                    return Transaction.TYPE_TRANSFER
コード例 #16
0
ファイル: pages.py プロジェクト: sourcery-ai-bot/weboob
 def get_roadmap(self):
     for step in self.doc.xpath(
             '//table[@class="trajet_etapes"]/tr[@class="etape"]'):
         roadstep = RoadStep()
         roadstep.line = '%s %s' % (DepartureTypeFilter(
             step.xpath('./td[@class="moyen"]'))(self),
                                    CleanText('./td[@class="moyen"]')(step))
         roadstep.start_time = DateTime(
             CleanText('./th/span[@class="depart"]'),
             LinearDateGuesser())(step)
         roadstep.end_time = DateTime(
             CleanText(
                 './th/span[@class="depart"]/following-sibling::span'),
             LinearDateGuesser())(step)
         roadstep.departure = CleanText('./td[@class="arret"]/p/strong')(
             step)
         roadstep.arrival = CleanText(
             './td[@class="arret"]/p/following-sibling::p/strong')(step)
         roadstep.duration = RoadMapDuration(
             CleanText('./td[@class="time"]'))(step)
         yield roadstep
コード例 #17
0
ファイル: pages.py プロジェクト: dermorz/weboob
            def obj_date(self):
                _date = CleanText('./section[@class="item_infos"]/aside/p[@class="item_supp"]/text()',
                                  replace=[('Aujourd\'hui', str(date.today())),
                                           ('Hier', str((date.today() - timedelta(1))))])(self)

                if not _date:
                    return NotAvailable

                for fr, en in DATE_TRANSLATE_FR:
                    _date = fr.sub(en, _date)

                self.env['tmp'] = _date
                return DateTime(Env('tmp'), LinearDateGuesser())(self)
コード例 #18
0
ファイル: browser.py プロジェクト: sourcery-ai-bot/weboob
    def get_history(self, account):
        if account._link_id is None:
            return
        self.location(account._link_id)

        if self.page is None:
            return

        if self.cbPage.is_here():
            guesser = LinearDateGuesser(date_max_bump=timedelta(45))
            return self.page.get_history(date_guesser=guesser)
        else:
            return self._get_history()
コード例 #19
0
ファイル: browser.py プロジェクト: dermorz/weboob
    def get_history(self, account, coming=False):
        if account._link_id is None:
            return

        if account._link_id.startswith('javascript') or '&Crd=' in account._link_id:
            raise NotImplementedError()

        if account.type == Account.TYPE_LIFE_INSURANCE:
            if coming is True:
                raise NotImplementedError()

            try:
                self._go_to_life_insurance(account.id)
            except (XMLSyntaxError, HTTPNotFound, AccountNotFound):
                self._quit_li_space()
                return iter([])
            except HTTPNotFound:
                self.accounts.go()
                return iter([])

            self.life_insurances.go(data={'url_suivant': 'HISTORIQUECONTRATB2C', 'strMonnaie': 'EURO'})

            history = [t for t in self.page.iter_history()]

            self._quit_li_space()

            return history

        try:
            self.location(self.accounts_list[account.id]._link_id)
        except HTTPNotFound: # sometime go to hsbc life insurance space do logout
            self.app_gone = True
            self.do_logout()
            self.do_login()

        #If we relogin on hsbc, all link have change
        if self.app_gone:
            self.app_gone = False
            self.update_accounts_list()
            self.location(self.accounts_list[account.id]._link_id)

        if self.page is None:
            return

        if self.cbPage.is_here():
            guesser = LinearDateGuesser(date_max_bump=timedelta(45))
            return [tr for tr in self.page.get_history(date_guesser=guesser) if (coming and tr.date > date.today()) or (not coming and tr.date <= date.today())]
        elif not coming:
            return self._get_history()
        else:
            raise NotImplementedError()
コード例 #20
0
    def get_history(self, account):
        if account.type in (Account.TYPE_MARKET, Account.TYPE_PEA,
                            Account.TYPE_LIFE_INSURANCE):
            self.logger.warning('This account is not supported')
            raise NotImplementedError()

        # some accounts may exist without a link to any history page
        if account.url is None or 'CATITRES' in account.url:
            return

        if account._perimeter != self.current_perimeter:
            self.go_perimeter(account._perimeter)

        # card accounts need to get an updated link
        if account.type == Account.TYPE_CARD:
            account = self.get_cards_or_card(account.number)

        if account.type != Account.TYPE_CARD or not self.page.is_on_right_detail(
                account):
            self.location(account.url.format(self.sag))

        if self.cards.is_here():
            date_guesser = ChaoticDateGuesser(date.today() -
                                              timedelta(weeks=42))
            url = self.page.url
            state = None
            notfirst = False
            while url:
                if notfirst:
                    self.location(url)
                else:
                    notfirst = True
                assert self.cards.is_here()
                for state, tr in self.page.get_history(date_guesser, state):
                    yield tr

                url = self.page.get_next_url()

        elif self.page:
            date_guesser = LinearDateGuesser()
            self.page.order_transactions()
            while True:
                assert self.transactions.is_here()

                for tr in self.page.get_history(date_guesser):
                    yield tr

                url = self.page.get_next_url()
                if url is None:
                    break
                self.location(url)
コード例 #21
0
ファイル: browser.py プロジェクト: lissyx/weboob
    def _get_history(self, link):
        num_page = 0
        guesser = LinearDateGuesser(date_max_bump=timedelta(45))
        while link is not None:
            self.location(link)

            if self.page is None:
                return

            for tr in self.page.get_operations(num_page, guesser):
                yield tr

            link = self.page.get_next_link()
            num_page += 1
コード例 #22
0
ファイル: pages.py プロジェクト: dasimon/weboob
    def iter_investment(self):
        for line in self.document.xpath(
                '//table[contains(@class, "ca-data-table")]/descendant::tr[count(td)>=7]'
        ):
            for sub in line.xpath('./td[@class="info-produit"]'):
                sub.drop_tree()
            cells = line.findall('td')

            if cells[self.COL_ID].find('div/a') is None:
                continue
            inv = Investment()
            inv.label = unicode(cells[self.COL_ID].find('div/a').text.strip())
            inv.code = cells[self.COL_ID].find('div/br').tail.strip().split(
                u'\xa0')[0]
            inv.quantity = self.parse_decimal(
                cells[self.COL_QUANTITY].find('span').text)
            inv.valuation = self.parse_decimal(cells[self.COL_VALUATION].text)
            inv.diff = self.parse_decimal(cells[self.COL_DIFF].text_content())
            if "%" in cells[self.COL_UNITPRICE].text and "%" in cells[
                    self.COL_UNITVALUE].text:
                inv.unitvalue = inv.valuation / inv.quantity
                inv.unitprice = (inv.valuation - inv.diff) / inv.quantity
            else:
                inv.unitprice = self.parse_decimal(
                    cells[self.COL_UNITPRICE].text)
                inv.unitvalue = self.parse_decimal(
                    cells[self.COL_UNITVALUE].text)
            date = cells[self.COL_UNITVALUE].find('span').text
            if ':' in date:
                inv.vdate = ddate.today()
            else:
                day, month = map(int, date.split('/', 1))
                date_guesser = LinearDateGuesser()
                inv.vdate = date_guesser.guess_date(day, month)

            yield inv
コード例 #23
0
ファイル: browser.py プロジェクト: dkremer-ledger/weboob
    def get_history(self, account):
        if hasattr(account, '_market_link') and account._market_link:
            self.connexion_bourse()
            self.location(account._link_id,
                          params={
                              'nump': account._market_id,
                          })
            self.page.get_fullhistory()
            for tr in self.page.iter_history():
                yield tr
            self.deconnexion_bourse()
        elif hasattr(account, '_link_id') and account._link_id:
            try:
                self.location(account._link_id)
            except ServerError:
                return
            if self.login.is_here():
                # Website crashed and we are disconnected.
                raise BrowserUnavailable()
            date_guesser = LinearDateGuesser()
            for tr in self.page.get_operations(date_guesser=date_guesser):
                yield tr

        elif account.type == Account.TYPE_CARD:
            for tr in self.get_cb_operations(account=account, month=1):
                yield tr

        elif account.type == Account.TYPE_LIFE_INSURANCE:
            if not account._external_website:
                self.logger.warning(
                    'This account is limited, there is no available history.')
                return

            if account._is_calie_account:
                # TODO build parsing of history page, all-you-can-eat js in it
                # follow 'account._history_url' for that
                raise NotImplementedError()
            else:
                self.assurancevie.stay_or_go()
                self.go_life_insurance_website()
                assert self.av_list.is_here(
                ), 'Something went wrong during iter life insurance history'
                # Need to be on account details page to do history request
                self.av_investments.go(life_insurance_id=account.id)
                self.av_history.go()
                for tr in self.page.iter_history():
                    yield tr
                self.go_back_from_life_insurance_website()
コード例 #24
0
    def get_history(self, account):
        # some accounts may exist without a link to any history page
        if account._link is None:
            return

        date_guesser = LinearDateGuesser()
        self.location(account._link)

        if self.is_on_page(CardsPage):
            yield from self.page.get_history(date_guesser)
        else:
            url = self.page.get_order_by_date_url()

            while url:
                self.location(url)
                assert self.is_on_page(TransactionsPage)

                yield from self.page.get_history(date_guesser)
                url = self.page.get_next_url()
コード例 #25
0
    def get_history(self, account):
        if account.type in (Account.TYPE_MARKET, Account.TYPE_LIFE_INSURANCE):
            self.logger.warning('This account is not supported')
            return

        # some accounts may exist without a link to any history page
        if account._link is None:
            return

        did_move = False
        if account._perimeter != self.current_perimeter:
            self.go_perimeter(account._perimeter)
            did_move = True

        # card accounts need to get an updated link
        if account.type == Account.TYPE_CARD:
            account = self.get_account(account.id, no_move=True)

        date_guesser = LinearDateGuesser()
        self.location(account._link.format(self.sag))

        if self.is_on_page(CardsPage):
            for tr in self.page.get_history(date_guesser):
                yield tr
        else:
            url = self.page.get_order_by_date_url()

            while url:
                self.location(url)
                assert self.is_on_page(TransactionsPage)

                for tr in self.page.get_history(date_guesser):
                    yield tr

                url = self.page.get_next_url()

        # Ugly hack needed for for following card accounts history
        if did_move:
            self.get_accounts_list()
コード例 #26
0
    def iter_history(self, account):
        if account._history_url.startswith('javascript:') or account._history_url == '#':
            raise NotImplementedError()

        account = find_object(self.iter_accounts(), id=account.id)
        # this url (reached with a GET) return some transactions, but not in same format than POST method
        # and some transactions are duplicated and other are missing, don't take them from GET
        # because we don't want to manage both way in iter_history

        # fetch csrf token
        self.go_with_ssodomi(self.accounts)
        # we have to update the url at this moment because history consultation has to follow immediatly accounts page consultation.
        account._history_url = self.update_csrf_token(account._history_url)

        self.location(account._history_url)
        date_range_list = self.page.get_date_range_list()

        # a date_range is a couple of date like '01/03/201831/03/2018' but current month is often missing and we have to rebuild it
        # from first one to get very recent transaction without scrap them from 1st page (reached with GET url)
        if len(date_range_list):
            date_range_list = [self._build_next_date_range(date_range_list[0])] + date_range_list

        for date_range in date_range_list:
            date_guesser = LinearDateGuesser(datetime.datetime.strptime(date_range[10:], "%d/%m/%Y"))
            try:
                self.location(account._history_url, data={'date': date_range})
            except ServerError as error:
                if error.response.status_code == 500:
                    if 'RELEVE NON DISPONIBLE A CETTE PERIODE' in error.response.text:
                        continue
                        # just skip because it's still possible to have transactions next months
                        # Yes, they really did that heresy...
                    else:
                        raise
            for tr in sorted_transactions(self.page.iter_history(date_guesser=date_guesser)):
                yield tr
コード例 #27
0
    def get_history(self, account, coming=False, retry_li=True):
        self._quit_li_space()

        self.update_accounts_list(False)
        account = self.accounts_list[account.id]

        if account.url is None:
            return []

        if account.url.startswith('javascript') or '&Crd=' in account.url:
            raise NotImplementedError()

        if account.type == Account.TYPE_LIFE_INSURANCE:
            if coming is True:
                return []

            try:
                if not self._go_to_life_insurance(account):
                    self._quit_li_space()
                    return []
            except (XMLSyntaxError, HTTPNotFound):
                self._quit_li_space()
                return []
            except AccountNotFound:
                self.go_post(self.js_url)

                # often if we visit life insurance subsite multiple times too quickly, the site just returns an error
                # so we just retry (we might relogin...)
                # TODO find out how to avoid the error, or avoid relogin
                if retry_li:
                    self.logger.warning(
                        'life insurance seems unavailable for account %s',
                        account.id)
                    return self.get_history(account, coming, False)

                self.logger.error(
                    'life insurance seems unavailable for account %s',
                    account.id)
                return []

            self.life_insurances.go(data={
                'url_suivant': 'HISTORIQUECONTRATB2C',
                'strMonnaie': 'EURO'
            })

            history = [t for t in self.page.iter_history()]

            self._quit_li_space()

            return history

        try:
            self.go_post(self.accounts_list[account.id].url)
        # sometime go to hsbc life insurance space do logout
        except HTTPNotFound:
            self.app_gone = True
            self.do_logout()
            self.do_login()

        # If we relogin on hsbc, all link have change
        if self.app_gone:
            self.app_gone = False
            self.update_accounts_list()
            self.location(self.accounts_list[account.id].url)

        if self.page is None:
            return []

        if self.cbPage.is_here():
            guesser = LinearDateGuesser(date_max_bump=timedelta(45))
            history = list(self.page.get_history(date_guesser=guesser))
            for url, params in self.page.get_params(self.url):
                self.location(url, params=params)
                if self.cbPage.is_here():
                    history.extend(self.page.get_history(date_guesser=guesser))
            history.extend(self.get_monthly_transactions(history))
            return [
                tr for tr in history
                if (coming and tr.date > date.today()) or (
                    not coming and tr.date <= date.today())
            ]
        elif not coming:
            return self._get_history()
        else:
            raise NotImplementedError()
コード例 #28
0
ファイル: browser.py プロジェクト: antibios/weboob
    def get_history(self, account):
        if account.type in (Account.TYPE_MARKET, Account.TYPE_PEA,
                            Account.TYPE_LIFE_INSURANCE):
            self.logger.warning('This account is not supported')
            raise NotImplementedError()

        # some accounts may exist without a link to any history page
        if not hasattr(account, '_form') and (not account.url
                                              or 'CATITRES' in account.url):
            return

        if account._perimeter != self.current_perimeter:
            self.go_perimeter(account._perimeter)

        if hasattr(account, '_form'):
            # the account needs a form submission to go to the history
            # but we need to get the latest form data
            self.location(self.accounts_url.format(self.sag))
            accounts = self.page.get_list(use_links=False)
            new_account = find_object(accounts, AccountNotFound, id=account.id)

            self.location(new_account._form.request)

        # card accounts need to get an updated link
        if account.type == Account.TYPE_CARD:
            account = self.get_card(account.id)

        if account.url and (account.type != Account.TYPE_CARD
                            or not self.page.is_on_right_detail(account)):
            self.location(account.url.format(self.sag))

        if self.cards.is_here():
            date_guesser = ChaoticDateGuesser(date.today() -
                                              timedelta(weeks=42))
            url = self.page.url
            state = None
            notfirst = False
            while url:
                if notfirst:
                    self.location(url)
                else:
                    notfirst = True
                assert self.cards.is_here()
                for state, tr in self.page.get_history(date_guesser, state):
                    yield tr

                url = self.page.get_next_url()

        elif self.page:
            date_guesser = LinearDateGuesser()
            self.page.order_transactions()
            while True:
                assert self.transactions.is_here()

                for tr in self.page.get_history(date_guesser):
                    yield tr

                url = self.page.get_next_url()
                if url is None:
                    break
                self.location(url)
コード例 #29
0
    def iter_history(self, account, coming=False):
        handled_history_types = (
            Account.TYPE_CHECKING,
            Account.TYPE_CARD,
            Account.TYPE_SAVINGS,
            Account.TYPE_PEA,
        )
        if account.type not in handled_history_types:
            self.unhandled_method(account.id)
            return

        if account.type == Account.TYPE_CARD:
            self.go_to_perimeter(account._perimeter)
            self.accounts.go()
            self.page.go_to_card(account._card_link)

            assert (self.cards_page.is_here() or self.multiple_cards_page.is_here()), \
                   'Failed to reach card details for card %s.' % account.id

            if self.multiple_cards_page.is_here():
                # We need to go to the correct card transactions with its number.
                card_url = self.page.get_transactions_link(account._raw_number)
                self.location(card_url)

            # When there are several future coming summaries,
            # we must skip the ongoing one but fetch the other ones
            # even if they are in the future.
            ongoing_coming = self.page.get_ongoing_coming()
            if not ongoing_coming:
                # This card has no available history or coming.
                return

            card_transactions = []
            latest_date = None
            for tr in self.page.get_card_transactions(latest_date,
                                                      ongoing_coming):
                card_transactions.append(tr)

            if not card_transactions:
                return

            # Pagination: we must fetch the date of the last transaction
            # because the summary of next transactions may not
            # be available on the next page
            latest_date = card_transactions[-1].date
            next_page_url = self.page.get_next_page()
            while next_page_url:
                self.location(next_page_url)
                for tr in self.page.get_card_transactions(
                        latest_date, ongoing_coming):
                    card_transactions.append(tr)
                next_page_url = self.page.get_next_page()

            for tr in sorted_transactions(card_transactions):
                yield tr
            return

        # Transactions of accounts without form/url or with 'CATITRES' and 'bgpi' in url cannot be handled.
        if not account._form and (not account.url or 'CATITRES' in account.url
                                  or 'bgpi' in account.url):
            self.unhandled_method(account.id)
            return

        # Access acount details:
        if account.url:
            # Refresh the session_value before going to the account URL
            new_session_value = 'sessionSAG=' + self.session_value
            updated_url = re.sub(r'sessionSAG=([^&]+)', new_session_value,
                                 account.url)
            self.location(updated_url)

        elif account._form:
            # We cannot use forms if we are not on the account's perimeter:
            # we need to go to the correct perimeter and refresh forms.
            # The form submission sometimes fails so we try several
            # times until we get to the account history page.
            for form in range(3):
                self.accounts.stay_or_go()
                self.go_to_perimeter(account._perimeter)

                # Only fetch the perimeter's regular accounts (Checking & Savings)
                # No need to go to Wealth, Loans or Netfinca for transactions
                refreshed_account = find_object(
                    self.iter_perimeter_regular_accounts(iban=False),
                    AccountNotFound,
                    id=account.id)
                refreshed_account._form.submit()
                if self.failed_history.is_here():
                    self.logger.warning(
                        'Form submission failed to reach the account history, we try again.'
                    )
                    continue
                break

        # 3 types of history pages were identified so far
        if not (self.checking_history.is_here()
                or self.savings_history.is_here()
                or self.other_savings_history.is_here()):
            self.unhandled_method(account.id)

        date_guesser = LinearDateGuesser(date_max_bump=timedelta(30))
        for tr in self.page.iter_history(date_guesser=date_guesser):
            yield tr
コード例 #30
0
ファイル: browser.py プロジェクト: sourcery-ai-bot/weboob
 def get_coming(self):
     transactions = list(self.operations_futures.go().get_list(
         date_guesser=LinearDateGuesser()))
     transactions.sort(key=lambda tr: tr.rdate, reverse=True)
     return transactions
コード例 #31
0
ファイル: browser.py プロジェクト: sourcery-ai-bot/weboob
 def get_history(self):
     transactions = list(self.operations_traitees.go().get_history(
         date_guesser=LinearDateGuesser()))
     transactions.sort(key=lambda tr: tr.rdate, reverse=True)
     return transactions