Example #1
0
 def obj_currency(self):
     currency = CleanText(
         '//th[contains(text(), "Montant total")]/small')(self)
     if currency:
         return Currency().filter(currency)
     return Currency().filter(
         CleanText('//table[@class="fiche"]//td/small')(self))
Example #2
0
        class item(ItemElement):
            klass = Loan

            def condition(self):
                return 'Billet financier' not in CleanText('./td[1]')(self)

            obj_id = CleanText('./td[2]')
            obj_number = Field('id')
            obj_label = CleanText('./td[1]')
            obj_type = Map(Field('label'), ACCOUNT_TYPES, Account.TYPE_LOAN)
            obj_next_payment_amount = Env('next_payment_amount')
            obj_total_amount = Env('total_amount')
            obj_currency = Currency('./td[@class="cel-devise"]')
            obj_url = Link('./td[2]/a', default=None)
            obj_iban = None
            obj__form = None

            def obj_balance(self):
                balance = Env('balance')(self)
                return -abs(balance)

            def parse(self, obj):
                # We must handle Loan tables with 5 or 6 columns
                if CleanText('//tr[contains(@class, "colcelligne")][count(td) = 5]')(self):
                    # History table with 4 columns (no loan details)
                    self.env['next_payment_amount'] = NotAvailable
                    self.env['total_amount'] = NotAvailable
                    self.env['balance'] = CleanDecimal.French('./td[4]//*[@class="montant3" or @class="montant4"]', default=NotAvailable)(self)
                elif CleanText('//tr[contains(@class, "colcelligne")][count(td) = 6]')(self):
                    # History table with 5 columns (contains next_payment_amount & total_amount)
                    self.env['next_payment_amount'] = CleanDecimal.French('./td[3]//*[@class="montant3"]', default=NotAvailable)(self)
                    self.env['total_amount'] = CleanDecimal.French('./td[4]//*[@class="montant3"]', default=NotAvailable)(self)
                    self.env['balance'] = CleanDecimal.French('./td[5]//*[@class="montant3"]', default=NotAvailable)(self)
Example #3
0
    class get_unique_card(ItemElement):
        item_xpath = '//table[@class="ca-table"][@summary]'

        klass = Account

        # Transform 'n° 4999 78xx xxxx xx72' into '499978xxxxxxxx72'
        obj_number = CleanText('//table[@class="ca-table"][@summary]//tr[@class="ligne-impaire"]/td[@class="cel-texte"][1]',
                               replace=[(' ', ''), ('n°', '')])

        # Card ID is formatted as '499978xxxxxxxx72MrFirstnameLastname-'
        obj_id = Format('%s%s',
                        Field('number'),
                        CleanText('//table[@class="ca-table"][@summary]//caption[@class="caption"]//b',
                        replace=[(' ', '')]))

        # Card label is formatted as 'Carte VISA Premier - Mr M Lastname'
        obj_label = Format('%s - %s',
                           CleanText('//table[@class="ca-table"][@summary]//tr[@class="ligne-impaire ligne-bleu"]/th[@id="compte-1"]'),
                           CleanText('//table[@class="ca-table"][@summary]//caption[@class="caption"]//b'))

        obj_balance = CleanDecimal(0)
        obj_coming = CleanDecimal.French('//table[@class="ca-table"][@summary]//tr[@class="ligne-paire"]//td[@class="cel-num"]', default=0)
        obj_currency = Currency(Regexp(CleanText('//th[contains(text(), "Montant en")]'), r'^Montant en (.*)'))
        obj_type = Account.TYPE_CARD
        obj__form = None
Example #4
0
        class item(ItemElement):
            klass = Account

            def condition(self):
                # Skip card coming lines
                return 'Encours carte' not in CleanText(TableCell('label', colspan=True))(self)

            obj_id = CleanText(TableCell('id', colspan=True))
            obj_number = Field('id')
            obj_label = CleanText(TableCell('label', colspan=True))
            obj_type = Map(Field('label'), ACCOUNT_TYPES, Account.TYPE_UNKNOWN)
            obj_currency = Currency(TableCell('currency', colspan=True))
            obj_url = None

            # Accounts may have an 'Operations' balance or a 'Value' balance
            def obj_balance(self):
                value_balance = CleanText(TableCell('value_balance', default='', colspan=True))(self)
                # Skip invalid balance values in the 'Value' column (for example for Revolving credits)
                if value_balance not in ('', 'Montant disponible'):
                    return CleanDecimal.French().filter(value_balance)
                return CleanDecimal.French(CleanText(TableCell('operation_balance', default='', colspan=True)))(self)

            def obj__form(self):
                # Account forms look like 'javascript:fwkPUAvancerForm('Releves','frm1')'
                # From this we extract the name (frm1) and fetch the form name on the page.
                script = Link('.//a', default='')(TableCell('id', colspan=True)(self)[0])
                if 'javascript' in script:
                    form_search = re.search(r'frm\d+', script)
                    if form_search:
                        account_form = self.page.get_form(name=form_search.group(0))
                        return self.page.fill_form(account_form, card=False)
                return None
Example #5
0
 class fill_account(ItemElement):
     obj_balance = CleanDecimal.French(
         '//ul[has-class("m-data-group")]//strong')
     obj_currency = Currency('//ul[has-class("m-data-group")]//strong')
     obj_valuation_diff = CleanDecimal.French(
         '//h3[contains(., "value latente")]/following-sibling::p[1]',
         default=NotAvailable)
Example #6
0
        class item(ItemElement):
            klass = Account

            TYPES = {
                'assurance vie': Account.TYPE_LIFE_INSURANCE,
                'perp': Account.TYPE_PERP,
                'epargne retraite agipi pair': Account.TYPE_PERP,
                'epargne retraite agipi far': Account.TYPE_MADELIN,
                'epargne retraite ma retraite': Account.TYPE_PER,
                'novial avenir': Account.TYPE_MADELIN,
                'epargne retraite novial': Account.TYPE_LIFE_INSURANCE,
            }

            obj_id = Regexp(CleanText('.//span[has-class("small-title")]'),
                            r'([\d/]+)')
            obj_number = obj_id
            obj_label = CleanText('.//h3[has-class("card-title")]')
            obj_balance = CleanDecimal.French('.//p[has-class("amount-card")]')
            obj_valuation_diff = CleanDecimal.French(
                './/p[@class="performance"]', default=NotAvailable)
            obj_currency = Currency('.//p[has-class("amount-card")]')
            obj__acctype = "investment"
            obj_type = MapIn(Lower(Field('label')), TYPES,
                             Account.TYPE_UNKNOWN)
            obj_url = Attr('.', 'data-module-open-link--link')
            obj_ownership = AccountOwnership.OWNER
Example #7
0
    class get_housing(ItemElement):
        klass = Housing

        obj_id = Env('_id')
        obj_title = CleanText('//h1[@itemprop="name"]')
        obj_location = CleanText('//span[@class="informations-localisation"]')
        obj_cost = CleanDecimal('//span[@itemprop="price"]')
        obj_currency = Currency('//span[@itemprop="price"]')
        obj_text = CleanHTML('//div[@itemprop="description"]')
        obj_url = BrowserURL('housing', _id=Env('_id'))
        obj_area = CleanDecimal(Regexp(CleanText('//h1[@itemprop="name"]'),
                                       '(.*?)(\d*) m2(.*?)', '\\2'), default=NotAvailable)
        obj_price_per_meter = PricePerMeterFilter()

        def obj_photos(self):
            photos = []
            for img in XPath('//a[@class="thumbnail-link"]/img[@itemprop="image"]')(self):
                url = Regexp(CleanText('./@src'), 'http://thbr\.figarocms\.net.*(http://.*)')(img)
                photos.append(HousingPhoto(url))
            return photos

        def obj_details(self):
            details = dict()
            for item in XPath('//div[@class="features clearfix"]/ul/li')(self):
                key = CleanText('./span[@class="name"]')(item)
                value = CleanText('./span[@class="value"]')(item)
                if value and key:
                    details[key] = value

            key = CleanText('//div[@class="title-dpe clearfix"]')(self)
            value = CleanText('//div[@class="energy-consumption"]')(self)
            if value and key:
                details[key] = value
            return details
Example #8
0
        class item(ItemElement):
            klass = Bill

            obj_id = Format('facture-%s-%s-%s#%s',
                            Slugify(CleanText(TableCell('date'))),
                            Slugify(CleanText(TableCell('amount'))),
                            Slugify(CleanText(TableCell('type'))),
                            Env('sub_id'))
            obj_url = AbsoluteLink('./td[5]//a', default=NotAvailable)
            obj_date = Date(CleanText(TableCell('date')), dayfirst=True)
            obj_label = Format('%s %s %s', CleanText(TableCell('type')),
                               CleanText(TableCell('amount')),
                               CleanText(TableCell('date')))
            obj_type = DocumentTypes.BILL
            obj_price = CleanDecimal(TableCell('amount'), replace_dots=True)
            obj_currency = Currency(TableCell('amount'))
            obj_duedate = Date(Regexp(CleanText(TableCell('status')),
                                      r'le (\d+)/(\d+)/(\d+)', r'\1/\2/\3'),
                               dayfirst=True)

            def obj_format(self):
                if self.obj_url(self):
                    return 'pdf'
                return NotAvailable

            def obj_income(self):
                if self.obj_price(self) < 0:
                    return True
                return False
Example #9
0
        class Item(ItemElement):
            TYPES = {
                'CIFO': Account.TYPE_MARKET,
                'PEA': Account.TYPE_PEA,
                'Excelis VIE': Account.TYPE_LIFE_INSURANCE,
                'Satinium': Account.TYPE_LIFE_INSURANCE,
                'Satinium CAPI': Account.TYPE_LIFE_INSURANCE,
                'Excelis CAPI': Account.TYPE_LIFE_INSURANCE,
            }

            klass = Account

            obj_id = CleanText(TableCell('id'))
            obj_label = Format('%s %s', CleanText(TableCell('type')),
                               CleanText(TableCell('name')))
            obj_currency = Currency(TableCell('valorisation'))
            obj_bank_name = u'La Banque postale'
            obj_balance = CleanDecimal(TableCell('valorisation'),
                                       replace_dots=True)
            obj_url = Link(TableCell('id'))
            obj_iban = NotAvailable

            def obj_url(self):
                td = TableCell('id')(self)[0]
                return Link(td.xpath('./a'))(self)

            def obj_type(self):
                return self.TYPES.get(
                    CleanText(TableCell('type'))(self), Account.TYPE_UNKNOWN)
Example #10
0
        class item(ItemElement):
            klass = Account

            def obj_id(self):
                _id = CleanText('./td[1]')(self)
                _id = ''.join(i for i in _id if i.isdigit())
                return _id

            obj_number = obj_id
            obj_label = CleanText('./td[2]', replace=[(' o ', ' ')])
            obj__login = CleanDecimal('./td[1]')
            obj_currency = Currency('./td[6]')
            obj_company_name = CleanText('./td[3]')

            def obj__sublabel(self):
                # Use the second part of the label to determine account index
                # later on InvestmentPage and remove the 'N ' at the beginning
                sublabel = CleanText('./td[2]', children=False)(self)
                if sublabel.startswith('N '):
                    sublabel = sublabel[2:]
                return sublabel

            def obj_type(self):
                return MapIn(Field('label'), self.page.ACCOUNT_TYPES,
                             Account.TYPE_UNKNOWN)(self)

            def obj_balance(self):
                # This wonderful website randomly displays separators as '.' or ','
                # For example, numbers can look like "€12,345.67" or "12 345,67 €"
                try:
                    return CleanDecimal.French('./td[6]')(self)
                except NumberFormatError:
                    return CleanDecimal.US('./td[6]')(self)
Example #11
0
        class item(ItemElement):
            klass = Bill

            obj_id = Format('%s_%s', Env('subid'), Dict('id'))
            obj_url = Dict('url')
            obj_date = Date(Dict('date'))
            obj_format = 'pdf'
            obj_currency = Currency(Dict('currency'), default=NotAvailable)

            def obj_price(self):
                price = CleanDecimal(Dict('price'), default=NotAvailable)(self)
                if price:
                    return price / 100
                return NotAvailable

            def obj_income(self):
                if Dict('type')(self) == 'purchase':
                    return False
                else:  # type is 'refund'
                    return True

            def obj_label(self):
                if Field('income')(self):
                    return Format('Remboursement du %s', Field('date'))(self)
                else:
                    return Format('Achat du %s', Field('date'))(self)
Example #12
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
Example #13
0
        class item(ItemElement):
            klass = Account

            def condition(self):
                # Ignore cards that do not have a coming
                return CleanText('.//tr[1]/td[@class="cel-num"]')(self)

            # Transform 'n° 4999 78xx xxxx xx72' into '499978xxxxxxxx72'
            obj_number = CleanText('.//caption/span[@class="tdb-cartes-num"]',
                                   replace=[(' ', ''), ('n°', '')])
            # The raw number is used to access multiple cards details
            obj__raw_number = CleanText(
                './/caption/span[@class="tdb-cartes-num"]')

            # Multiple card IDs are formatted as '499978xxxxxxxx72MrFirstnameLastname'
            obj_id = Format(
                '%s%s', Field('number'),
                CleanText('.//caption/span[@class="tdb-cartes-prop"]',
                          replace=[(' ', '')]))

            # Card label is formatted as 'Carte VISA Premier - Mr M Lastname'
            obj_label = Format(
                '%s - %s',
                CleanText('.//caption/span[has-class("tdb-cartes-carte")]'),
                CleanText('.//caption/span[has-class("tdb-cartes-prop")]'))

            obj_type = Account.TYPE_CARD
            obj_balance = CleanDecimal(0)
            obj_coming = CleanDecimal.French(
                './/tr[1]/td[position() = last()]', default=0)
            obj_currency = Currency(
                Regexp(CleanText('//span[contains(text(), "Montants en")]'),
                       r'^Montants en (.*)'))
            obj__form = None
Example #14
0
        class item(ItemElement):
            klass = Account

            obj_id = CleanText('./td[2]')
            obj_number = Field('id')
            obj_label = CleanText('./td/span[@class="gras"]')
            obj_type = Map(Field('label'), ACCOUNT_TYPES, Account.TYPE_UNKNOWN)
            # Accounts without balance will be skipped later on
            obj_balance = CleanDecimal.French('./td//*[@class="montant3"]',
                                              default=NotAvailable)
            obj_currency = Currency('./td[@class="cel-devise"]')
            obj_iban = None
            obj__form = None

            def obj_url(self):
                url = Link('./td[2]/a', default=None)(self)
                if url and 'BGPI' in url:
                    # This URL is just the BGPI home page, not the account itself.
                    # The real account URL will be set by get_account_details() in BGPISpace.
                    return 'BGPI'
                return url

            def validate(self, obj):
                # Skip 'ESPE INTEG' accounts, these liquidities are already available
                # on the associated Market account on the Netfinca website
                return obj.label != 'ESPE INTEG'
Example #15
0
        class item(ItemElement):

            klass = Account

            def condition(self):
                return len(Dict('accountListInformation')(self)) == 1

            def obj_type(self):
                return self.parent.TYPE_ACCOUNTS.get(
                    Dict('dashboardAccountSubGroupIdentifier')(self))

            obj_number = CleanText(
                Dict('accountListInformation/0/accountNumber'))
            obj_id = CleanText(
                Dict('accountListInformation/0/accountNickName'))
            obj_currency = Currency(
                Dict('accountListInformation/0/currencyAccountCode'))
            obj_balance = CleanDecimal(
                Dict(
                    'accountGroupMultipleCurrencyInformation/0/accountMarketValueAmount'
                ))
            obj_valuation_diff = CleanDecimal(Dict(
                'accountGroupMultipleCurrencyInformation/0/profitLossUnrealizedAmount'
            ),
                                              default=NotAvailable)
Example #16
0
        class item(ItemElement):
            klass = Account

            TYPES = {
                u'assurance vie': Account.TYPE_LIFE_INSURANCE,
                u'perp': Account.TYPE_PERP,
                u'epargne retraite agipi pair': Account.TYPE_PERP,
                u'novial avenir': Account.TYPE_MADELIN,
                u'epargne retraite novial': Account.TYPE_LIFE_INSURANCE,
            }

            condition = lambda self: Field('balance')(self) is not NotAvailable

            obj_id = Regexp(CleanText('.//span[has-class("small-title")]'),
                            r'([\d/]+)')
            obj_label = CleanText('.//h3[has-class("card-title")]')
            obj_balance = CleanDecimal.French('.//p[has-class("amount-card")]')
            obj_valuation_diff = CleanDecimal.French(
                './/p[@class="performance"]', default=NotAvailable)

            def obj_url(self):
                url = Attr('.', 'data-route')(self)
                # The Assurance Vie xpath recently changed so we must verify that all
                # the accounts now have "/savings/" instead of "/assurances-vie/".
                assert "/savings/" in url
                return url

            obj_currency = Currency('.//p[has-class("amount-card")]')
            obj__acctype = "investment"

            obj_type = MapIn(Lower(Field('label')), TYPES,
                             Account.TYPE_UNKNOWN)
Example #17
0
        class item(ItemElement):
            klass = Account

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

            obj__history_url = Link('.//a[1]')
            obj_id = CleanText('.//span[has-class("numero-compte")]') & Regexp(
                pattern=r'(\d{3,}[\w]+)', default='')
            obj_label = CleanText('.//span[has-class("libelle")][1]')
            obj_currency = Currency('//span[has-class("montant")]')
            obj_balance = CleanDecimal('.//span[has-class("montant")]',
                                       replace_dots=True)
            obj_type = Type(Field('label'))
            # Last numbers replaced with XX... or we have to send sms to get RIB.
            obj_iban = NotAvailable

            # some accounts may appear on multiple areas, but the area where they come from is indicated
            obj__owner = CleanText(
                '(./preceding-sibling::tr[@class="LnMnTiers"])[last()]')

            def validate(self, obj):
                if obj.id is None:
                    obj.id = obj.label.replace(' ', '')
                return True
Example #18
0
        class item(ItemElement):
            klass = Housing

            obj_id = Format(
                'colocation-%s',
                CleanText('./div/header/@id', replace=[('header-offer-', '')]))
            obj_type = POSTS_TYPES.SHARING
            obj_advert_type = ADVERT_TYPES.PROFESSIONAL
            obj_title = CleanText(
                CleanHTML(
                    './div/header/section/p[@class="property-type"]/span/@title'
                ))

            obj_area = CleanDecimal(
                './div/header/section/p[@class="offer-attributes"]/a/span[@class="offer-area-number"]',
                default=0)

            obj_cost = CleanDecimal('./div/header/section/p[@class="price"]',
                                    default=0)
            obj_currency = Currency('./div/header/section/p[@class="price"]')
            obj_utilities = UTILITIES.UNKNOWN

            obj_text = CleanText(
                './div/div[@class="content-offer"]/section[has-class("content-desc")]/p/span[has-class("offer-text")]/@title',
                default=NotLoaded)

            obj_date = Date(
                Regexp(
                    CleanText(
                        './div/header/section/p[has-class("update-date")]'),
                    ".*(\d{2}/\d{2}/\d{4}).*"))

            obj_location = CleanText(
                '(./div/div[@class="content-offer"]/section[has-class("content-desc")]/p)[1]/span/@title',
                default=NotLoaded)
Example #19
0
        class item(ItemElement):
            klass = Account

            def obj_id(self):
                _id = CleanText('./td[1]')(self)
                _id = ''.join(i for i in _id if i.isdigit())
                return _id

            def obj_label(self):
                label = Format('%s', CleanText('./td[2]'))(self)
                label = label.replace(" o ", " ")
                return label

            obj__login = CleanDecimal('./td[1]')
            obj_currency = Currency('./td[6]')
            obj__company = CleanText('./td[3]')
            obj_type = Account.TYPE_PERP

            def obj_balance(self):
                # The page can be randomly in french or english and
                # the valuations can be "€12,345.67" or "12 345,67 €"
                try:
                    return CleanDecimal.French('./td[6]')(self)
                except NumberFormatError:
                    return CleanDecimal.US('./td[6]')(self)
Example #20
0
 def obj_original_currency(self):
     currency_text = Dict(
         'holdingDetailInformation/0/holdingDetailMultipleCurrencyInformation/1/currencyProductHoldingBookValueAmountCode'
     )(self)
     if currency_text:
         return Currency().filter(currency_text)
     else:
         return NotAvailable
Example #21
0
    class get_account(ItemElement):
        klass = Account

        obj_type = Account.TYPE_CHECKING
        obj__site = 'other'
        obj_balance = 0
        obj_number = obj_id = CleanText('//tr[td[text()="Mon numéro de compte"]]/td[@class="droite"]', replace=[(' ', '')])
        obj_coming = CleanDecimal('//div[@id="mod-paiementcomptant"]//tr[td[contains(text(),"débité le")]]/td[@class="droite"]', sign=lambda _: -1, default=0)
        obj_currency = Currency('//div[@id="mod-paiementcomptant"]//tr[td[starts-with(normalize-space(text()),"Montant disponible")]]/td[@class="droite"]')
Example #22
0
        class item(ItemElement):
            klass = Housing

            def condition(self):
                return Dict('cardType')(self) not in [
                    'advertising', 'localExpert'
                ] and Dict('id', default=False)(self)

            obj_id = Dict('id')

            def obj_type(self):
                idType = int(Env('query_type')(self))
                type = next(k for k, v in TYPES.items() if v == idType)
                if type == POSTS_TYPES.FURNISHED_RENT:
                    # SeLoger does not let us discriminate between furnished and not furnished.
                    return POSTS_TYPES.RENT
                return type

            def obj_title(self):
                return "{} - {} - {}".format(
                    Dict('estateType')(self), " / ".join(Dict('tags')(self)),
                    Field('location')(self))

            def obj_advert_type(self):
                is_agency = Dict('contact/agencyId', default=False)(self)
                if is_agency:
                    return ADVERT_TYPES.PROFESSIONAL
                else:
                    return ADVERT_TYPES.PERSONAL

            obj_utilities = UTILITIES.EXCLUDED

            def obj_photos(self):
                photos = []
                for photo in Dict('photos')(self):
                    photos.append(HousingPhoto(photo))
                return photos

            def obj_location(self):
                quartier = Dict('districtLabel')(self)
                quartier = quartier if quartier else ''
                ville = Dict('cityLabel')(self)
                ville = ville if ville else ''
                cp = Dict('zipCode')(self)
                cp = cp if cp else ''
                return u'%s %s (%s)' % (quartier, ville, cp)

            obj_url = Dict('classifiedURL')

            obj_text = Dict('description')

            obj_cost = CleanDecimal(Dict('pricing/price', default=NotLoaded),
                                    default=NotLoaded)
            obj_currency = Currency(Dict('pricing/price', default=NotLoaded),
                                    default=NotLoaded)
            obj_price_per_meter = CleanDecimal(
                Dict('pricing/squareMeterPrice'), default=PricePerMeterFilter)
Example #23
0
        class item(ItemElement):
            klass = Account

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

            obj__history_url = Link('./td[1]/a')
            obj_label = CleanText('./td[1]')
            obj_currency = Currency('//span[contains(text(), "Solde")]')
            obj_balance = CleanDecimal('./td[2]', replace_dots=True)
            obj_type = Type(Field('label'))
            # Last numbers replaced with XX... or we have to send sms to get RIB.
            obj_iban = NotAvailable

            # some accounts may appear on multiple areas, but the area where they come from is indicated
            obj__owner = CleanText(
                '(./preceding-sibling::tr[@class="LnMnTiers"])[last()]')

            def obj_id(self):
                history_url = Field('_history_url')(self)
                if history_url.startswith('javascript:'):
                    # Market account
                    page = self.page.browser.investment.go()

                    area_id = Regexp(
                        CleanText('//span[@class="CelMnTiersT1"]'),
                        r'\((\d+)\)',
                        default='')(page.doc)

                    for tr in page.doc.xpath(
                            './/table/tr[not(has-class("LnTit")) and not(has-class("LnTot"))]'
                    ):
                        # Try to match account with id and balance.
                        if CleanText('./td[2]//a')(tr) == Field('label')(self) \
                            and CleanDecimal('./td[3]//a')(tr) == Field('balance')(self):

                            acc_id = CleanText('./td[1]',
                                               replace=[(' ', '')])(tr)
                            if area_id:
                                # because the acc_id can be the same between multiple areas
                                return '%s.%s' % (area_id, acc_id)
                            return acc_id
                else:
                    page = self.page.browser.open(history_url).page
                    return Regexp(CleanText('//span[has-class("Rappel")]'),
                                  '(\d{18}) | (\d{3}\w\d{15})')(page.doc)

            def validate(self, obj):
                if obj.id is None:
                    obj.id = obj.label.replace(' ', '')
                return True
Example #24
0
        class item(ItemElement):
            klass = Bill

            obj_id = Format('%s_%s', Env('subid'), CleanText(TableCell('id')))
            obj_url = '/Account/CommandListingPage.aspx'
            obj_format = 'pdf'
            obj_price = CleanDecimal(TableCell('price'), replace_dots=True)
            obj_currency = Currency(TableCell('price'))

            def obj_date(self):
                return parse_french_date(CleanText(TableCell('date'))(self)).date()
Example #25
0
        class item(ItemElement):
            klass = Bill

            _num = Dict('document/id')

            obj_id = Format('%s_%s', Env('subid'), _num)
            obj_date = Eval(datetime.fromtimestamp, Dict('created_at'))
            obj_label = Format('Facture %s', Field('id'))
            obj_url = Dict('document/href')
            obj_price = CleanDecimal(Dict('amount/amount'))
            obj_currency = Currency(Dict('amount/currency'))
            obj_format = 'pdf'
Example #26
0
        class item(ItemElement):
            klass = Account

            obj_id = CleanText(TableCell('id'), replace=[(' ', '')])
            obj_label = CleanText(TableCell('label'))
            obj_balance = CleanDecimal.French(TableCell('balance'))
            obj_currency = Currency(TableCell('balance'))
            obj_type = Account.TYPE_LIFE_INSURANCE

            def obj_url(self):
                return AbsoluteLink(TableCell('id')(self)[0].xpath('.//a'),
                                    default=NotAvailable)(self)
Example #27
0
    class get_account(ItemElement):
        klass = Account

        obj_type = Account.TYPE_CARD
        obj__site = 'other'

        def obj_label(self):
            return self.page.browser.card_name

        obj_id = CleanText('//tr[td[text()="Mon numéro de compte"]]/td[@class="droite"]', replace=[(' ', '')])
        obj_balance = CleanDecimal('''//div[@id="mod-paiementcomptant"]//tr[td[starts-with(normalize-space(text()),"Disponible jusqu'au")]]/td[@class="droite"]''')
        obj_coming = CleanDecimal('''//div[@id="mod-paiementcomptant"]//tr[td[span[contains(text(),"prélevé le")]]]/td[@class="droite"]''', sign=lambda _: -1, default=0)
        obj_currency = Currency('''//div[@id="mod-paiementcomptant"]//tr[td[starts-with(normalize-space(text()),"Disponible jusqu'au")]]/td[@class="droite"]''')
Example #28
0
        class item(ItemElement):
            klass = Account

            # If user has professional accounts, owner_type must be defined
            OWNER_TYPE = {
                'Mes avoirs professionnels': AccountOwnerType.ORGANIZATION,
                'Mes avoirs personnels': AccountOwnerType.PRIVATE,
                'Mes crédits personnels': AccountOwnerType.PRIVATE,
            }

            # MapIn because, in case of private account, we actually catch "Mes avoirs personnels Mes crédits personnels" with CleanText which both can be use to recognize the owner_type as PRIVATE
            obj_owner_type = MapIn(CleanText('.//form[@id]/ancestor::div/h2'),
                                   OWNER_TYPE, NotAvailable)

            obj_label = Label(
                CleanText(
                    './/form[@id]/preceding-sibling::p/span[@class="hsbc-pib-text hsbc-pib-bloc-account-name" or @class="hsbc-pib-text--small"]'
                ))
            obj_type = AccountsType(Field('label'))
            obj_url = CleanText('.//form/@action')
            obj_currency = Currency('.//form[@id]/following-sibling::*[1]')
            obj__is_form = bool(CleanText('.//form/@id'))
            obj__amount = CleanDecimal.French(
                './/form[@id]/following-sibling::*[1]')

            def obj_balance(self):
                if Field('type')(self) == Account.TYPE_CARD:
                    return Decimal(0)
                elif 'Mes crédits' in CleanText(
                        './/ancestor::div[1]/preceding-sibling::*')(self):
                    return -abs(Field('_amount')(self))
                return Field('_amount')(self)

            def obj_coming(self):
                if Field('type')(self) == Account.TYPE_CARD:
                    return Field('_amount')(self)
                return NotAvailable

            def obj_id(self):
                # Investment accounts and main account can have the same id
                _id = CleanText('.//form[@id]/preceding-sibling::*[1]/span[2]',
                                replace=[('.', ''), (' ', '')])(self)
                if "Scpi" in Field('label')(self):
                    return _id + ".SCPI"
                # Same problem with scpi accounts.
                if Field('type')(self) == Account.TYPE_MARKET:
                    return _id + ".INVEST"
                # Cards are displayed like '4561 00XX XXXX 5813 - Carte à  débit différé'
                if 'Carte' in _id:
                    _id = Regexp(pattern=r'(.*)-Carte').filter(_id)
                return _id
Example #29
0
class SeLogerItem(ItemElement):
    klass = Housing

    obj_id = CleanText('idAnnonce')

    def obj_type(self):
        idType = int(CleanText('idTypeTransaction')(self))
        type = next(k for k, v in TYPES.items() if v == idType)
        if type == POSTS_TYPES.FURNISHED_RENT:
            # SeLoger does not let us discriminate between furnished and not
            # furnished.
            return POSTS_TYPES.RENT
        return type

    def obj_house_type(self):
        idType = CleanText('idTypeBien')(self)
        try:
            return next(k for k, v in RET.items() if v == idType)
        except StopIteration:
            return NotAvailable

    obj_title = Format(
        "%s %s%s - %s",
        CleanText('titre'),
        CleanText('surface'),
        CleanText('surfaceUnite'),
        CleanText('ville'),
    )
    obj_date = DateTime(CleanText('dtFraicheur'))
    obj_cost = CleanDecimal('prix')

    obj_currency = Currency('prixUnite')

    obj_area = CleanDecimal('surface', default=NotAvailable)
    obj_price_per_meter = PricePerMeterFilter()
    obj_text = CleanText('descriptif')
    obj_rooms = CleanDecimal('nbPiece|nbPieces', default=NotAvailable)
    obj_bedrooms = CleanDecimal('nbChambre|nbChambres', default=NotAvailable)

    def obj_location(self):
        location = CleanText('adresse', default="")(self)
        quartier = CleanText('quartier', default=None)(self)
        if not location and quartier is not None:
            location = quartier
        ville = CleanText('ville')(self)
        cp = CleanText('cp')(self)
        return u'%s %s (%s)' % (location, ville, cp)

    obj_station = CleanText('proximite', default=NotAvailable)
    obj_url = CleanText('permaLien')
Example #30
0
        class item(ItemElement):
            klass = Account

            obj_id = CleanText('.//div[@class="infos-contrat"]//strong')
            obj_label = CleanText('.//div[@class="type-contrat"]//h2')
            obj_type = Account.TYPE_LIFE_INSURANCE
            obj_balance = CleanDecimal(CleanText('.//div[@class="col-right"]',
                                                 children=False),
                                       replace_dots=True,
                                       default=NotAvailable)
            obj_currency = Currency(
                CleanText(u'.//div[@class="col-right"]',
                          children=False,
                          replace=[("Au", "")]))