Ejemplo n.º 1
0
        class item(ItemElement):
            klass = Account

            def condition(self):
                return self.page.accounts_list_condition(self.el)

            class Type(Filter):
                def filter(self, label):
                    for pattern, actype in AccountsPage.TYPES.items():
                        if pattern in label:
                            return actype
                    return Account.TYPE_UNKNOWN

            obj__title = CleanText('td[@class="ColonneLibelle"][2]')
            obj__nature = CleanText('td[@class="ColonneLibelle"][3]')
            obj_label = Format('%s %s', Field('_title'), Field('_nature'))
            obj_currency = FrenchTransaction.Currency(
                './td[@class="ColonneCode"]')
            obj_id = CleanText('td[@class="ColonneLibelle"][1]')
            obj__link = Link('td[@class="ColonneLibelle"][1]/a',
                             default=NotAvailable)
            obj__rib_link = Link('.//a[contains(@href, "rib.jsp")]')
            obj_type = Type(Field('label'))
            obj_balance = CleanDecimal('td[@class="ColonneNumerique"]/nobr',
                                       replace_dots=True)
Ejemplo n.º 2
0
        class item(ItemElement):
            klass = Recipe

            obj_id = Regexp(Link('.//a[has-class("bu_cuisine_recette_img")]'),
                            r'.*\/(.*)$')

            obj_url = Link('.//a[has-class("bu_cuisine_recette_img")]')
            obj_title = CleanText(
                './/p[has-class("bu_cuisine_recette_title")]')
            obj_short_description = NotAvailable
            obj_author = NotAvailable
            obj_ingredients = NotAvailable

            class obj_picture(ItemElement):
                klass = BaseImage

                obj_url = NotAvailable

                def obj_thumbnail(self):
                    style = Attr(
                        './/a[has-class("bu_cuisine_recette_img")]/span',
                        'style')(self)
                    return Thumbnail(
                        style.replace("background-image:url(",
                                      "").rstrip(");"))

            obj_instructions = NotAvailable
            obj_preparation_time = CleanDecimal(
                '(.//span[has-class("bu_cuisine_recette_carnet_duree")])[1]')
            obj_cooking_time = CleanDecimal(
                '(.//span[has-class("bu_cuisine_recette_carnet_duree")])[2]',
                default=0)
            obj_nb_person = NotAvailable
Ejemplo n.º 3
0
    def obj_coming(self):
        if Field('type')(self) == Account.TYPE_CHECKING and Field('balance')(self) != 0:
            # When the balance is 0, we get a website unavailable on the history page
            # and the following navigation is broken
            has_coming = False
            coming = 0

            details_page = self.page.browser.open(Field('url')(self))
            coming_op_link = Link('//a[contains(text(), "Opérations à venir")]', default=NotAvailable)(details_page.page.doc)
            if coming_op_link:
                coming_op_link = Regexp(Link('//a[contains(text(), "Opérations à venir")]'), r'../(.*)')(details_page.page.doc)
                coming_operations = self.page.browser.open(self.page.browser.BASEURL + '/voscomptes/canalXHTML/CCP/' + coming_op_link)
            else:
                coming_op_link = Link('//a[contains(text(), "Opérations en cours")]')(details_page.page.doc)
                coming_operations = self.page.browser.open(coming_op_link)

            if CleanText('//span[@id="amount_total"]')(coming_operations.page.doc):
                has_coming = True
                coming += CleanDecimal('//span[@id="amount_total"]', replace_dots=True)(coming_operations.page.doc)

            if CleanText(u'.//dt[contains(., "Débit différé à débiter")]')(self):
                has_coming = True
                coming += CleanDecimal(u'.//dt[contains(., "Débit différé à débiter")]/following-sibling::dd[1]',
                                       replace_dots=True)(self)

            return coming if has_coming else NotAvailable
        return NotAvailable
Ejemplo n.º 4
0
        class item(ItemElement):
            klass = Message

            obj_id = Regexp(Link('./div/div/small/a', default=''),
                            '/.+/status/(.+)',
                            default=None)

            obj_title = Regexp(
                CleanText(
                    './div[@class="content"]/div/p[has-class("tweet-text")]',
                    replace=[('@ ', '@'), ('# ', '#'),
                             ('http:// ', 'http://')]), '(.{50}|.+).+')
            obj_content = CleanText(
                './div[@class="content"]/div/p[has-class("tweet-text")]',
                replace=[('@ ', '@'), ('# ', '#'), ('http:// ', 'http://')])
            obj_sender = Regexp(Link('./div/div/small/a', default=''),
                                '/(.+)/status/.+',
                                default=None)
            obj_date = DatetimeFromTimestamp(
                Attr(
                    './div/div[@class="stream-item-header"]/small/a/span | ./div/div[@class="ProfileTweet-authorDetails"]/span/a/span',
                    'data-time'))

            def validate(self, obj):
                return obj.id is not None
Ejemplo n.º 5
0
        class item(ItemElement):
            klass = Suggestion

            obj_id = Regexp(Link('./td[2]/a'), '/([0-9]+)')
            obj_name = CleanText('./td[2]/a/text()')
            obj_description = Format('Genre: %s - Country: %s',
                                     CleanText('./td[3]/text()'),
                                     CleanText('./td[4]/text()'))
            obj_url = Link('./td[2]/a')
Ejemplo n.º 6
0
 def obj_url(self):
     url = Link(u'./a', default=NotAvailable)(self)
     if not url:
         url = Regexp(Attr(u'.//span', 'onclick', default=''), r'\'(https.*)\'', default=NotAvailable)(self)
     if url:
         if 'CreditRenouvelable' in url:
             url = Link(u'.//a[contains(text(), "espace de gestion crédit renouvelable")]')(self.el)
         return urljoin(self.page.url, url)
     return url
Ejemplo n.º 7
0
        class item(ItemElement):
            klass = BaseCalendarEvent

            obj_url = Link('./a[1]')
            obj_id = Regexp(Link('./a[1]'), r'\?(\d+)')
            obj_summary = CleanText('./a[1]')
            obj_start_date = Date(CleanText('./span[1]'))
            obj_category = CATEGORIES.CONCERT
            obj_status = STATUS.CONFIRMED
Ejemplo n.º 8
0
        def next_page(self):
            if Link(u'//a[text()="▶"]')(self) is not None:

                form = self.page.get_form(xpath='//*[@id="history_form"]')

                form['page'] = CleanDecimal(Link(u'//a[text()="▶"]'))(self)


                return requests.Request("POST", self.page.url, data=form)
Ejemplo n.º 9
0
 def obj_url(self):
     async_page = Async('details').loaded_page(self)
     url = Link(
         '//a[contains(@href, "download")]|//a[contains(@href, "generated_invoices")]',
         default=NotAvailable)(async_page.doc)
     if not url:
         url = Link(
             '//a[contains(text(), "Imprimer un récapitulatif de commande")]'
         )(async_page.doc)
     return url
Ejemplo n.º 10
0
        class item(ItemElement):
            klass = BaseCalendarEvent

            obj_url = Link('./div[@class="bbox"]/h1/a')
            obj_id = Regexp(Link('./div[@class="bbox"]/h1/a'), r'aspx\?(.+)')
            obj_location = CleanText('./div[@class="bbox"]/span/a')
            obj_start_date = DateTime(Attr('.//time', 'datetime'))
            obj_summary = Regexp(Attr('./div[@class="bbox"]/h1/a', 'title'),
                                 r'details of (.+)')
            obj_category = CATEGORIES.CONCERT
            obj_status = STATUS.CONFIRMED
Ejemplo n.º 11
0
        class item(ItemElement):
            klass = Subscription

            obj_id = Regexp(Link('.'), r'\bidContrat=(\d+)', default='')
            obj__page = Regexp(Link('.'), r'\bpage=([^&]+)', default='')
            obj_label = CleanText('.')

            def validate(self, obj):
                # unsubscripted contracts may still be there, skip them else
                # facture-historique could yield wrong bills
                return bool(obj.id) and obj._page != 'nec-tdb-ouvert'
Ejemplo n.º 12
0
        class item(ItemElement):
            klass = Housing

            def condition(self):
                return Regexp(Link('./div[has-class("box-header")]/a[@class="title-item"]'), '/annonces/(.*)', default=None)(self)

            obj_id = Regexp(Link('./div[has-class("box-header")]/a[@class="title-item"]'), '/annonces/(.*)')
            obj_title = CleanText('./div[has-class("box-header")]/a[@class="title-item"]')
            obj_area = CleanDecimal(Regexp(CleanText('./div[has-class("box-header")]/a/span[@class="h1"]'),
                                           '(.*?)(\d*) m\xb2(.*?)', '\\2'), default=NotAvailable)
            obj_cost = CleanDecimal(CleanText('./div[has-class("box-header")]/a/span[@class="price"]'),
                                    replace_dots=True, default=Decimal(0))
            obj_currency = Regexp(CleanText('./div[has-class("box-header")]/a/span[@class="price"]'),
                                  '.*([%s%s%s])' % (u'€', u'$', u'£'), default=u'€')
            obj_utilities = UTILITIES.UNKNOWN

            def obj_date(self):
                _date = Regexp(CleanText('./div[has-class("box-header")]/p[@class="date"]'),
                               '.* / (.*)')(self)
                return parse_french_date(_date)

            obj_station = CleanText('./div[@class="box-body"]/div/div/p[@class="item-transports"]', default=NotAvailable)
            obj_location = CleanText('./div[@class="box-body"]/div/div/p[@class="item-description"]/strong')
            obj_text = CleanText('./div[@class="box-body"]/div/div/p[@class="item-description"]')
            obj_rooms = CleanDecimal(
                './div[@class="box-body"]/div/div/div[@class="clearfix"]/ul[has-class("item-summary")]/li[1]/strong',
                default=NotAvailable
            )
            obj_price_per_meter = PricePerMeterFilter()

            def obj_bedrooms(self):
                rooms_bedrooms_area = XPath(
                    './div[@class="box-body"]/div/div/div[@class="clearfix"]/ul[has-class("item-summary")]/li'
                )(self)
                if len(rooms_bedrooms_area) > 2:
                    return CleanDecimal(
                        './div[@class="box-body"]/div/div/div[@class="clearfix"]/ul[has-class("item-summary")]/li[2]/strong',
                        default=NotAvailable
                    )(self)
                else:
                    return NotAvailable

            obj_url = Format(
                u'http://www.pap.fr%s',
                Link(
                    './div[@class="box-body"]/div/div/div[@class="clearfix"]/div[@class="float-right"]/a'
                )
            )

            def obj_photos(self):
                photos = []
                for img in XPath('./div[@class="box-body"]/div/div/a/img/@src')(self):
                    photos.append(HousingPhoto(u'%s' % img))
                return photos
Ejemplo n.º 13
0
        class item(ItemElement):
            klass = Bill

            load_details = Link('.//a[contains(text(), "détails")]') & MyAsyncLoad

            obj_id = Format('%s_%s', Env('subid'), Field('label'))
            obj_url = Async('details') & Link('//a[span[contains(text(), "Télécharger la facture")]]', default=NotAvailable)
            obj_date = Date(CleanText('./div[contains(@class, "cell-date")]'), dayfirst=True)
            obj_format = 'pdf'
            obj_label = Regexp(CleanText('./div[contains(@class, "cell-nb-order")]'), r' (.*)')
            obj_type = DocumentTypes.BILL
            obj_price = CleanDecimal(CleanText('./div[contains(@class, "cell-value")]'), replace_dots=(' ', '€'))
            obj_currency = 'EUR'
Ejemplo n.º 14
0
        class item(ItemElement):
            klass = Account

            load_details = Attr('.//a', 'href') & AsyncLoad

            obj__link_id = Async(
                'details', Link('//li/a[contains(text(), "Mouvements")]'))
            obj__link_inv = Link('./td[1]/a')
            obj_id = CleanText('./td[2]', replace=[(' ', '')])
            obj_label = CleanText('./td[1]')
            obj_balance = CleanDecimal('./td[3]', replace_dots=True)
            obj_currency = FrenchTransaction.Currency('./td[4]')
            obj__card_links = []
            obj_type = Account.TYPE_LIFE_INSURANCE
            obj__is_inv = True
Ejemplo n.º 15
0
 def populate(self, accounts):
     cards = []
     for account in accounts:
         for li in self.doc.xpath('//li[@class="nav-category"]'):
             title = CleanText().filter(li.xpath('./h3'))
             for a in li.xpath('./ul/li//a'):
                 label = CleanText().filter(
                     a.xpath('.//span[@class="nav-category__name"]'))
                 balance_el = a.xpath(
                     './/span[@class="nav-category__value"]')
                 balance = CleanDecimal(
                     replace_dots=True,
                     default=NotAvailable).filter(balance_el)
                 if 'CARTE' in label and balance:
                     acc = Account()
                     acc.balance = balance
                     acc.label = label
                     acc.currency = FrenchTransaction.Currency().filter(
                         balance_el)
                     acc._link = Link().filter(a.xpath('.'))
                     acc._history_page = acc._link
                     acc.id = acc._webid = Regexp(
                         pattern='([^=]+)$').filter(Link().filter(
                             a.xpath('.')))
                     acc.type = Account.TYPE_CARD
                     if not acc in cards:
                         cards.append(acc)
                 elif account.label == label and account.balance == balance:
                     if not account.type:
                         account.type = AccountsPage.ACCOUNT_TYPES.get(
                             title, Account.TYPE_UNKNOWN)
                     if account.type == Account.TYPE_LOAN:
                         account._history_page = None
                     elif account.type in (Account.TYPE_LIFE_INSURANCE,
                                           Account.TYPE_MARKET):
                         account._history_page = re.sub(
                             '/$', '',
                             Link().filter(a.xpath('.')))
                     elif '/compte/cav' in a.attrib[
                             'href'] or not 'titulaire' in self.url:
                         account._history_page = self.browser.other_transactions
                     else:
                         account._history_page = self.browser.budget_transactions
                     account._webid = Attr(
                         None, 'data-account-label').filter(
                             a.xpath(
                                 './/span[@class="nav-category__name"]'))
     accounts.extend(cards)
Ejemplo n.º 16
0
    class get_history(ListElement):
        item_xpath = '//table[@id="ContentTable_datas"]//tr[@class]'

        next_page = Link('//table[@id="tgDecorationFoot"]//b/following-sibling::a[1]')

        class item(ItemElement):
            klass = FrenchTransaction

            obj_rdate = FrenchTransaction.Date(CleanText('./td[1]'))
            obj_date = FrenchTransaction.Date(CleanText('./td[3]'))
            obj_raw = FrenchTransaction.Raw(CleanText('./td[2]'))
            _obj_amnt = FrenchTransaction.Amount(CleanText('./td[5]'), replace_dots=False)
            obj_original_amount = FrenchTransaction.Amount(CleanText('./td[4]'), replace_dots=False)
            obj_original_currency = FrenchTransaction.Currency(CleanText('./td[4]'))
            obj_commission = FrenchTransaction.Amount(CleanText('./td[6]'), replace_dots=False)

            def obj__coming(self):
                if Field('date')(self) >= date.today():
                    return True
                return

            def obj_amount(self):
                if not Field('obj_commission'):
                    return Field('_obj_amnt')
                else:
                    return CleanDecimal(replace_dots=False).filter(self.el.xpath('./td[5]')) - CleanDecimal(replace_dots=False).filter(self.el.xpath('./td[6]'))
Ejemplo n.º 17
0
    class iter_history(TableElement):
        item_xpath = '//table[@class="Tableau"]/tr[td[not(has-class("enteteTableau"))]]'
        head_xpath = '//table[@class="Tableau"]/tr[td[has-class("enteteTableau")]]/td'

        col_date = u'Date d\'effet'
        col_raw = u'Nature du mouvement'
        col_amount = u'Montant brut'

        next_page = Link('//a[contains(@href, "PageSuivante")]', default=None)

        class item(ItemElement):
            klass = Transaction

            load_details = Link('./td/a', default=None) & AsyncLoad

            obj_date = Date(CleanText(TableCell('date')), dayfirst=True)
            obj_raw = Transaction.Raw(TableCell('raw'))
            obj_amount = CleanDecimal(TableCell('amount'), replace_dots=True)
            obj_investments = Env('investments')

            def parse(self, el):
                try:
                    page = Async('details').loaded_page(self)
                except AttributeError:
                    page = None
                self.env['investments'] = list(page.get_investments(
                )) if page and 'numMvt' in page.url else []
Ejemplo n.º 18
0
    class iter_history(TableElement):
        item_xpath = '//table/tbody/tr'
        head_xpath = '//table/thead/tr/th'

        col_label = 'Nature'
        col_amount = 'Montant'
        col_date = 'Date d\'effet'

        next_page = Link('//li[@class="pagination__next"]/a')

        class item(ItemElement):
            klass = Transaction

            obj_date = Date(CleanText(TableCell('date')), dayfirst=True)
            obj_raw = Transaction.Raw(CleanText(TableCell('label')))
            obj_amount = CleanDecimal(TableCell('amount'),
                                      replace_dots=True,
                                      default=NotAvailable)
            obj__is_coming = False

            def parse(self, el):
                if el.xpath('./td[2]/a'):
                    m = re.search(
                        '(\d+)',
                        el.xpath('./td[2]/a')[0].get(
                            'data-modal-alert-behavior', ''))
                    if m:
                        self.env['account']._history_pages.append((Field('raw')(self),\
                                                                self.page.browser.open('%s%s%s' % (self.page.url.split('mouvements')[0], 'mouvement/', m.group(1))).page))
                        raise SkipItem()
Ejemplo n.º 19
0
    class iter_prices(ListElement):
        item_xpath = '//div[@class="adContainer "]'
        next_page = Link(
            '//section[@class="pagination"]/ul/li[@class="last"]/a')

        class item(ItemElement):
            klass = Price

            obj_id = CleanText('./p/a/@data-annid')
            obj_cost = CleanDecimal('./a/div/div/div/div[@class="fieldPrice"]')
            obj_currency = Regexp(
                CleanText('./a/div/div/div/div[@class="fieldPrice"]'),
                '.*([%s%s%s])' % (u'€', u'$', u'£'),
                default=u'€')
            obj_message = Format(
                '%s / %s / %s', CleanText('./a/div/div/h3'),
                CleanText('./a/div/div/div/div[@class="fieldYear"]'),
                CleanText('./a/div/div/div/div[@class="fieldMileage"]'))
            obj_url = Format('http://www.lacentrale.fr%s',
                             CleanText('./a/@href'))

            obj_product = LaCentraleProduct()

            def obj_shop(self):
                shop = Shop(CleanText('./p/a/@data-annid')(self))
                return shop
Ejemplo n.º 20
0
 def obj_code(self):
     link = Link(TableCell('label')(self)[0].xpath('./a'),
                 default=NotAvailable)(self)
     if not link:
         return NotAvailable
     return Regexp(pattern='isin=([A-Z\d]+)&?',
                   default=NotAvailable).filter(link)
Ejemplo n.º 21
0
 def companies_link(self):
     companies_link = []
     for tr in self.doc.xpath(
             '//table[@summary="Liste des titulaires de contrats cartes"]//tr'
     ):
         companies_link.append(Link(tr.xpath('.//a'))(self))
     return companies_link
Ejemplo n.º 22
0
    class iter_history(ListElement):
        item_xpath = '''//table[@class="ca-table"][caption[span[b[contains(text(), "HISTORIQUE DES OPERATIONS")]]]]
                        //tr[contains(@class, "ligne-")]'''
        next_page = Link(
            '//a[@class="liennavigationcorpspage"][img[@alt="Page suivante"]]',
            default=None)

        class item(ItemElement):
            klass = Transaction

            def fill_env(self, page, parent=None):
                # This *Element's parent has only the dateguesser in its env and we want to
                # use the same object, not copy it.
                self.env = parent.env

            def obj_date(self):
                # Dates in the first column may appear as '12/01/2019' or '12/01'
                date = CleanText('./td[1]/font//text()')(self)
                if len(date) == 10:
                    return Date(CleanText('./td[1]/font//text()'),
                                dayfirst=True)(self)
                elif len(date) == 5:
                    # Date has no indicated year.
                    return DateGuesser(CleanText('./td[1]//text()'),
                                       Env('date_guesser'))(self)

            obj_raw = Transaction.Raw(CleanText('./td[2]/font//text()'))
            obj_amount = CleanDecimal.French('./td[3]/font//text()')
            obj_rdate = Field('date')
Ejemplo n.º 23
0
        class item(ItemElement):
            klass = Account

            obj__owner = Regexp(
                CleanText('./td[1]/text()', replace=[(' ', '')]),
                'Titulaire:(.*)')
            obj_id = Format(
                '%s%s',
                Regexp(CleanText('./td[1]/a', replace=[(' ', '')]), '([\d]+)'),
                Field('_owner'))
            obj_label = Field('_owner')
            obj_balance = NotAvailable
            obj_currency = FrenchTransaction.Currency('./td[2]')
            obj__link_id = Link('./td[1]/a')
            obj_type = Account.TYPE_CARD
            obj__card_links = []
            obj__is_inv = False
            obj__is_webid = False

            def parse(self, el):
                account = [
                    acc for acc in self.env['accounts']
                    if acc.id == Field('id')(self)
                ]
                if account:
                    account[0]._card_links.append(Field('_link_id')(self))
                    raise SkipItem()
Ejemplo n.º 24
0
    class get_operations(ListElement):
        item_xpath = '//table[has-class("style-operations")]/tbody//tr'
        next_page = Link(
            '//div[@class="m-table-paginator full-width-xs"]//a[@id="next-page"]'
        )

        class item(ItemElement):
            klass = Transaction

            def condition(self):
                if 'tr-section' in self.el.attrib.get('class', ''):
                    return False
                elif 'tr-trigger' in self.el.attrib.get('class', ''):
                    return True

                return False

            def obj_date(self):
                return Transaction.Date(
                    Regexp(
                        CleanText(
                            './preceding::tr[has-class("tr-section")][1]/th'),
                        r'(\d+/\d+/\d+)'))(self)

            obj_raw = Transaction.Raw(
                Format(
                    '%s %s', CleanText('./td[1]'),
                    CleanText(
                        './following-sibling::tr[contains(@class, "tr-more")]/td/p[1]/span'
                    )))
            obj_amount = MyDecimal('./td[2]', replace_dots=True)
Ejemplo n.º 25
0
        class item(ItemElement):
            def klass(self):
                return BiplanCalendarEventConcert() if self.env['is_concert'] else BiplanCalendarEventTheatre()

            def condition(self):
                return (self.el.xpath('./div') and CleanText('./div/a/img/@src')(self)[-1] != '/')

            def validate(self, obj):
                return (self.is_valid_event(obj, self.env['city'], self.env['categories']) and
                        self.is_event_in_valid_period(obj.start_date, self.env['date_from'], self.env['date_to']))

            def is_valid_event(self, event, city, categories):
                if city and city != '' and city.upper() != event.city.upper():
                    return False

                if categories and len(categories) > 0 and event.category not in categories:
                    return False

                return True

            def is_event_in_valid_period(self, event_date, date_from, date_to):
                if event_date >= date_from:
                    if not date_to:
                        return True
                    else:
                        if event_date <= date_to:
                            return True
                return False

            obj_id = Regexp(Link('./div/a'), '/(.*?).html')
            obj_start_date = CombineDate(BiplanDate('div/div/b'), StartTime('div/div/b'))
            obj_end_date = CombineDate(BiplanDate('div/div/b'), EndTime('.'))
            obj_price = BiplanPrice('div/div/b')
            obj_summary = CleanText("div/div/div/a/strong")
Ejemplo n.º 26
0
        class item(ItemElement):
            klass = Account

            def obj_id(self):
                area_id = Regexp(CleanText('//span[@class="CelMnTiersT1"]'),
                                 r'\((\d+)\)',
                                 default='')(self)
                acc_id = Regexp(CleanText('./td[1]'), r'(\d+)\s*(\d+)',
                                r'\1\2')(self)
                if area_id:
                    return '%s.%s' % (area_id, acc_id)
                return acc_id

            def obj__formdata(self):
                js = Attr('./td/a[1]', 'onclick', default=None)(self)
                if js is None:
                    return
                args = re.search(r'\((.*)\)', js).group(1).split(',')

                form = args[0].strip().split('.')[1]
                idx = args[2].strip()
                idroot = args[4].strip().replace("'", "")
                return (form, idx, idroot)

            obj_url = Link('./td/a[1]', default=None)
Ejemplo n.º 27
0
    class iter_history(TableElement):
        item_xpath = '//table[@class="Tableau"]/tr[td[not(has-class("enteteTableau"))]]'
        head_xpath = '//table[@class="Tableau"]/tr[td[has-class("enteteTableau")]]/td'

        col_date = u'Date d\'effet'
        col_raw = u'Nature du mouvement'
        col_amount = u'Montant brut'

        next_page = Link('//a[contains(@href, "PageSuivante")]', default=None)

        class item(ItemElement):
            klass = Transaction

            obj_date = Date(CleanText(TableCell('date')), dayfirst=True)
            obj_raw = Transaction.Raw(TableCell('raw'))
            obj_amount = CleanDecimal(TableCell('amount'), replace_dots=True)
            obj__detail = Env('detail')

            def obj_id(self):
                try:
                    return Regexp(Link('./td/a', default=None), 'numMvt=(\d+)', default=None)(self)
                except TypeError:
                    return NotAvailable

            def parse(self, el):
                link = Link('./td/a', default=None)(self)
                page = self.page.browser.async_open(link) if link else None
                self.env['detail'] = page
Ejemplo n.º 28
0
    def get_account_details(self, account_id):
        balance = CleanDecimal.French(
            '//a[div[div[span[span[contains(text(), "%s")]]]]]/div[1]/div[2]/span/span'
            % account_id,
            default=NotAvailable)(self.doc)

        currency = Currency(
            '//a[div[div[span[span[contains(text(), "%s")]]]]]/div[1]/div[2]/span/span'
            % account_id,
            default=NotAvailable)(self.doc)

        label = CleanText(
            '//a[div[div[span[span[contains(text(), "%s")]]]]]/div[1]/div[1]/span/span'
            % account_id,
            default=NotAvailable)(self.doc)

        url = Link('//a[div[div[span[span[contains(text(), "%s")]]]]]' %
                   account_id,
                   default=None)(self.doc)
        if url:
            account_url = 'https://bgpi-gestionprivee.credit-agricole.fr' + url
        else:
            account_url = None

        return balance, currency, label, account_url
Ejemplo n.º 29
0
        class item(ItemElement):
            klass = Housing

            def condition(self):
                return Regexp(Link('./div[@class="header-annonce"]/a'), '/annonces/(.*)', default=None)(self)

            obj_id = Regexp(Link('./div[@class="header-annonce"]/a'), '/annonces/(.*)')
            obj_title = CleanText('./div[@class="header-annonce"]/a')
            obj_area = CleanDecimal(Regexp(CleanText('./div[@class="header-annonce"]/a/span[@class="desc"]'),
                                           '(.*?)(\d*) m\xb2(.*?)', '\\2'), default=NotAvailable)
            obj_cost = CleanDecimal(CleanText('./div[@class="header-annonce"]/a/span[@class="prix"]'),
                                    replace_dots=(',', '.'), default=Decimal(0))
            obj_currency = Regexp(CleanText('./div[@class="header-annonce"]/a/span[@class="prix"]'),
                                  '.*([%s%s%s])' % (u'€', u'$', u'£'), default=u'€')

            def obj_date(self):
                _date = CleanText('./div[@class="header-annonce"]/span[@class="date"]')(self)
                return parse_french_date(_date)

            obj_station = CleanText('./div/div/div[@cladd=metro]', default=NotAvailable)
            obj_location = CleanText('./div[@class="clearfix"]/div/a/span/img/@alt')
            obj_text = CleanText('./div[@class="clearfix"]/div[@class="description clearfix"]/p')

            def obj_photos(self):
                photos = []
                for img in XPath('//div[@class="vignette-annonce"]/a/span/img/@src')(self):
                    photos.append(HousingPhoto(u'%s' % img))
                return photos
Ejemplo n.º 30
0
 def populate(self, accounts):
     cards = []
     for account in accounts:
         for li in self.doc.xpath('//li[@class="nav-category"]'):
             title = CleanText().filter(li.xpath('./h3'))
             for a in li.xpath('./ul/li//a'):
                 label = CleanText().filter(a.xpath('.//span[@class="nav-category__name"]'))
                 balance_el = a.xpath('.//span[@class="nav-category__value"]')
                 balance = CleanDecimal(replace_dots=True, default=NotAvailable).filter(balance_el)
                 if 'CARTE' in label and not empty(balance):
                     acc = Account()
                     acc.balance = balance
                     acc.label = label
                     acc.currency = FrenchTransaction.Currency().filter(balance_el)
                     acc.url = urljoin(self.url, Link().filter(a.xpath('.')))
                     acc._history_page = acc.url
                     try:
                         acc.id = acc._webid = Regexp(pattern='carte/(.*)$').filter(Link().filter(a.xpath('.')))
                     except RegexpError:
                         # Those are external cards, ie: amex cards
                         continue
                     acc.type = Account.TYPE_CARD
                     if not acc in cards:
                         cards.append(acc)
                 elif account.label == label and account.balance == balance:
                     if not account.type:
                         account.type = AccountsPage.ACCOUNT_TYPES.get(title, Account.TYPE_UNKNOWN)
                     account._webid = Attr(None, 'data-account-label').filter(a.xpath('.//span[@class="nav-category__name"]'))
     if cards:
         self.browser.go_cards_number(cards[0].url)
         if self.browser.cards.is_here():
             self.browser.page.populate_cards_number(cards)
             accounts.extend(cards)