def obj_coming(self): page = self.page.browser.open( BrowserURL('account_coming', identifiant=Field('iban'))(self)).page coming = Eval( lambda x, y: x / 10**y, CleanDecimal( Dict('infoOperationsAvenir/cumulTotal/montant', default='0')), CleanDecimal( Dict('infoOperationsAvenir/cumulTotal/nb_dec', default='0')))(page.doc) # this so that card coming transactions aren't accounted twice in the total incoming amount for el in Dict('infoOperationsAvenir/natures')(page.doc): if Dict('nature/libelle')( el) == "Factures / Retraits cartes": coming_carte = Eval( lambda x, y: x / 10**y, CleanDecimal( Dict('cumulNatureMere/montant', default='0')), CleanDecimal( Dict('cumulNatureMere/nb_dec', default='0')))(el) coming -= coming_carte break return coming
class get_recipe(ItemElement): klass = Recipe def parse(self, el): json_content = CleanText(u'//script[@type="application/ld+json"]', replace=[('//<![CDATA[ ', ''), (' //]]>', '')])(self) self.el = json.loads(json_content) obj_id = Env('id') obj_title = Dict('name') obj_ingredients = Dict('recipeIngredient') obj_thumbnail_url = Dict('image') obj_picture_url = Dict('image') def obj_instructions(self): str = Dict('recipeInstructions')(self) return re.sub(r'(\d+\.)', r'\n\1', str) obj_preparation_time = Eval(int, CleanDecimal(Dict('prepTime'))) obj_cooking_time = Eval(int, CleanDecimal(Dict('cookTime'))) def obj_nb_person(self): return [Dict('recipeYield')(self)]
def iter_investment(self, account): for row, elem_repartition, elem_pocket, elem_diff in self.iter_invest_rows(account=account): inv = Investment() inv._account = account inv._el_pocket = elem_pocket inv.label = CleanText('.//td[1]')(row) inv.valuation = MyDecimal('.//td[2]')(row) # On all Cmes children the row shows percentages and the popup shows absolute values in currency. # On Cmes it is mirrored, the popup contains the percentage. is_mirrored = '%' in row.text_content() if not is_mirrored: inv.diff = MyDecimal('.//td[3]')(row) if elem_diff is not None: inv.diff_ratio = Eval(lambda x: x / 100, MyDecimal(Regexp(CleanText('.'), r'([+-]?[\d\s]+[\d,]+)\s*%')))(elem_diff) else: inv.diff = MyDecimal('.')(elem_diff) if elem_diff is not None: inv.diff_ratio = Eval(lambda x: x / 100, MyDecimal(Regexp(CleanText('.//td[3]'), r'([+-]?[\d\s]+[\d,]+)\s*%')))(row) if account.balance != 0: inv.portfolio_share = inv.valuation / account.balance yield inv
class get_recipe(ItemElement): klass = Recipe def parse(self, el): item = XPath(u'//script[@type="application/ld+json"]')(self) json_content = CleanText(u'.', replace=[('//<![CDATA[ ', ''), (' //]]>', '')])(item[1]) self.el = json.loads(json_content) obj_id = Env('id') obj_title = Dict('name') obj_ingredients = Dict('recipeIngredient') class obj_picture(ItemElement): klass = BaseImage obj_url = Dict('image') obj_thumbnail = Eval(Thumbnail, obj_url) def obj_instructions(self): instructions = '' for item in Dict('recipeInstructions')(self): instructions = u"{0} - {1}\n\n".format(instructions, item['text']) return instructions obj_preparation_time = Eval(int, CleanDecimal(Dict('prepTime'))) obj_cooking_time = Eval(int, CleanDecimal(Dict('cookTime'))) def obj_nb_person(self): return [Dict('recipeYield')(self)]
def get_performance_history(self): perfs = {} if CleanDecimal.French('//tr[td[text()="Fonds"]]//td[position()=last()-2]', default=None)(self.doc): perfs[1] = Eval(lambda x: x / 100, CleanDecimal.French('//tr[td[text()="Fonds"]]//td[position()=last()-2]'))(self.doc) if CleanDecimal.French('//tr[td[text()="Fonds"]]//td[position()=last()-1]', default=None)(self.doc): perfs[3] = Eval(lambda x: x / 100, CleanDecimal.French('//tr[td[text()="Fonds"]]//td[position()=last()-1]'))(self.doc) if CleanDecimal.French('//tr[td[text()="Fonds"]]//td[position()=last()]', default=None)(self.doc): perfs[5] = Eval(lambda x: x / 100, CleanDecimal.French('//tr[td[text()="Fonds"]]//td[position()=last()]'))(self.doc) return perfs
class item(ItemElement): klass = Account obj_id = Eval(str, Dict('id')) obj_label = Dict('name') obj_balance = Eval(float_to_decimal, Dict('current_value')) obj_valuation_diff = Eval(float_to_decimal, Dict('absolute_performance')) obj_currency = 'EUR' obj_type = Account.TYPE_LIFE_INSURANCE
class get_video(ItemElement): obj_title = CleanText('//article[@id="description"]//h1') obj_description = CleanText('//article[@id="description"]//section/following-sibling::div') obj_date = DateTime(Regexp( CleanText('//article[@id="description"]//span[contains(text(),"diffusé le")]'), r'(\d{2})\.(\d{2})\.(\d{2}) à (\d{2})h(\d{2})', r'20\3/\2/\1 \4:\5')) obj_duration = Eval(parse_duration, Regexp(CleanText('//div[span[text()="|"]]'), r'| (\d+)min')) obj_thumbnail = Eval(Thumbnail, Format('https:%s', Attr('//div[@id="playerPlaceholder"]//img', 'data-src'))) obj__number = Attr('//div[@id="player"]', 'data-main-video') obj_license = LICENSES.COPYRIGHT
def obj_performance_history(self): # The Amundi JSON only contains 1 year and 5 years performances. # It seems that when a value is unavailable, they display '0.0' instead... perfs = {} if Dict('performanceUnAn', default=None)(self) not in (0.0, None): perfs[1] = Eval(lambda x: x / 100, CleanDecimal( Dict('performanceUnAn')))(self) if Dict('performanceCinqAns', default=None)(self) not in (0.0, None): perfs[5] = Eval(lambda x: x / 100, CleanDecimal( Dict('performanceCinqAns')))(self) return perfs
class item(ItemElement): klass = Transaction def condition(self): # Only return validated transactions return Dict('status')(self) == 'DONE' obj_raw = Transaction.Raw(Dict('label')) obj_date = Date(Dict('date')) obj_amount = Eval(float_to_decimal, Dict('net_amount/value')) obj_gross_amount = Eval(float_to_decimal, Dict('gross_amount/value')) obj_type = Transaction.TYPE_BANK # 'oid' is used to get the transaction's investments obj__oid = Dict('id')
class item(ItemElement): klass = Investment def obj_label(self): if not CleanText(TableCell('code'))(self): return CleanText('./preceding-sibling::tr[1]/td[2]')(self) return CleanText(TableCell('label'))(self) def obj_code(self): if CleanText(TableCell('code'))(self): return CleanText(TableCell('code'))(self) return CleanText('./preceding-sibling::tr[1]/td[1]')(self) obj_quantity = CleanDecimal(TableCell('quantity'), default=NotAvailable) obj_unitvalue = CleanDecimal(TableCell('unitvalue'), default=NotAvailable) obj_unitprice = CleanDecimal(TableCell('unitprice')) obj_valuation = MyDecimal(TableCell('valuation')) obj_portfolio_share = Eval( lambda x: x / 100, CleanDecimal(TableCell('portfolio_share'))) obj_code_type = Investment.CODE_TYPE_ISIN def condition(self): return CleanDecimal(TableCell('quantity'), default=None)(self) is not None
class item(ItemElement): klass = Investment obj_label = CleanText(TableCell('label')) obj_valuation = CleanDecimal(TableCell('valuation'), replace_dots=True) obj_portfolio_share = Eval( lambda x: x / 100, CleanDecimal(TableCell('portfolio_share'), replace_dots=True)) # There is no "unitvalue" information available on the "Assurances Vie" space. def obj_quantity(self): quantity = TableCell('quantity')(self) if CleanText(quantity)(self) == '-': return NotAvailable return CleanDecimal(quantity, replace_dots=True)(self) def obj_code(self): isin = CleanText(TableCell('code')(self))(self) return isin or NotAvailable def obj_code_type(self): if is_isin_valid(Field('code')(self)): return Investment.CODE_TYPE_ISIN return NotAvailable def obj_vdate(self): return self.page.get_vdate()
class item(ItemElement): # Main account cards are all deferred and their # coming is already displayed with a '-' sign. klass = Account def condition(self): card_situation = Dict('codeSituationCarte')(self) if card_situation not in (5, 7): # Cards with codeSituationCarte equal to 7 are active and present on the website # Cards with codeSituationCarte equal to 5 are absent on the website, we skip them self.logger.warning( 'codeSituationCarte unknown, Check if the %s card is present on the website', Field('id')(self)) return card_situation != 5 obj_id = CleanText(Dict('idCarte'), replace=[(' ', '')]) obj_number = Field('id') obj_label = Format('Carte %s %s', Field('id'), CleanText(Dict('titulaire'))) obj_type = Account.TYPE_CARD obj_coming = Eval(float_to_decimal, Dict('encoursCarteM')) obj_balance = Decimal(0) obj__index = Dict('index') obj__id_element_contrat = None
def obj_date(self): actual_day = Eval(int, Regexp(CleanText('./div/h4'), '\w{3} (\d+)'))(self) actual_month_str = Regexp(CleanText('./div/h4'), '(\w+)')(self) actual_month = 0 base_date = date.today() month_dict = { 'JAN': 1, 'FEB': 2, 'MAR': 3, 'APR': 4, 'MAI': 5, 'JUN': 6, 'JUL': 7, 'AUG': 8, 'SEP': 9, 'OCT': 10, 'NOV': 11, 'DEC': 12 } for key, value in month_dict.items(): if actual_month_str.lower() == key.lower(): actual_month = value base_date = base_date.replace(day=actual_day) base_date = base_date.replace(month=actual_month) return base_date
class item(ItemElement): klass = Investment obj_label = CleanText('./td[1]/text()') obj_valuation = CleanDecimal('./td[2]/strong') obj_vdate = Date(CleanText('./td[2]/span'), dayfirst=True, default=NotAvailable) obj_portfolio_share = Eval(lambda x: x / 100, CleanDecimal('./td[1]/strong'))
def obj_portfolio_share(self): active_percent = Dict('pourcentageActif', default=NotAvailable)(self) if empty(active_percent): return NotAvailable return Eval(lambda x: x / 100, CleanDecimal(active_percent))(self)
class item(ItemElement): klass = Subscription obj__nom1 = CleanText(TableCell("nom")) obj__nom2 = CleanText( Attr('.//input[contains(@id, ".nom")]', "value")) obj__prenom1 = CleanText(TableCell("prenom")) obj__prenom2 = CleanText( Attr('.//input[contains(@id, ".prenom")]', "value")) obj__internal_id = CleanText( Attr('.//input[contains(@id, ".salaEmplPk.noIntSala")]', "value")) obj__pseudo_siret = CleanText( Attr('.//input[contains(@id, ".salaEmplPk.psdoSirt")]', "value")) obj__date_creation = Date( CleanText( Attr('.//input[contains(@id, ".dtCreation")]', "value")), dayfirst=True, ) obj_label = Format("%s %s", CleanText(Field("_prenom1")), CleanText(Field("_nom1"))) # obj_subscriber = Env("subscriber") obj__type = "employee" obj__active = Eval(lambda x: x[0].checked, (Child(TableCell("actif")))) obj_id = Field("_internal_id")
class item(ItemElement): klass = Transaction obj_date = Date(Regexp(CleanText('./div[1]'), r'(\d{2}\/\d{2}\/\d{4})'), dayfirst=True) obj_amount = Eval(lambda x: x / 100, CleanDecimal('./div[2]')) obj_label = Format( '%s %s', CleanText('./preceding::h3[1]'), Regexp(CleanText('./div[1]'), r'(\d{2}\/\d{2}\/\d{4})')) def obj_investments(self): investments = [] for elem in self.xpath('./following-sibling::div[1]//ul'): inv = Investment() inv.label = CleanText('./li[1]/p')(elem) inv.portfolio_share = CleanDecimal( './li[2]/p', replace_dots=True, default=NotAvailable)(elem) inv.quantity = CleanDecimal('./li[3]/p', replace_dots=True, default=NotAvailable)(elem) inv.valuation = CleanDecimal('./li[4]/p', replace_dots=True)(elem) investments.append(inv) return investments
class item(ItemElement): klass = Investment obj_label = CleanText(Dict('lcspt')) obj_valuation = Eval(float_to_decimal, Dict('mtvalspt')) def obj_portfolio_share(self): portfolio_share = Dict('txrpaspt', default=None)(self) if portfolio_share: return Eval(lambda x: float_to_decimal(x / 100), portfolio_share)(self) return NotAvailable def obj_unitvalue(self): unit_value = Dict('mtliqpaaspt', default=None)(self) if unit_value: return Eval(float_to_decimal, unit_value)(self) return NotAvailable def obj_quantity(self): quantity = Dict('qtpaaspt', default=None)(self) if quantity: return Eval(float_to_decimal, quantity)(self) return NotAvailable def obj_code(self): code = Dict('cdsptisn')(self) if is_isin_valid(code): return code return NotAvailable def obj_code_type(self): if Field('code')(self) == NotAvailable: return NotAvailable return Investment.CODE_TYPE_ISIN
class item(ItemElement): klass = Account def obj_id(self): return CleanText(Dict('numeroCompte'))(self)[2:] obj_balance = Eval(lambda x, y: x / 10**y, CleanDecimal(Dict('soldeComptable')), CleanDecimal(Dict('decSoldeComptable'))) obj_label = CleanText(Dict('libelleCompte')) obj_currency = CleanText(Dict('deviseTenue')) obj_iban = CleanText(Dict('numeroCompte', default=None), default=NotAvailable) def obj_type(self): return self.page.TYPES.get( Dict('libelleType')(self), Account.TYPE_UNKNOWN) def obj_coming(self): page = self.page.browser.open( BrowserURL('account_coming', identifiant=Field('iban'))(self)).page return Eval( lambda x, y: x / 10**y, CleanDecimal( Dict('infoOperationsAvenir/cumulTotal/montant', default='0')), CleanDecimal( Dict('infoOperationsAvenir/cumulTotal/nb_dec', default='0')))(page.doc)
class EventDetails(ItemElement): klass = CentQuatreEvent obj_id = Env('fileId') obj_start_date = DateTime(CleanText(u'//*[@class="date"]')) obj_end_date = Eval(lambda x: x + timedelta(hours=1), obj_start_date) obj_timezone = u'Europe/Paris' obj_summary = CleanText( u'//*[@class="content_product_info"]//*[contains(@class, "title")]' ) obj_city = u'Paris' obj_location = Format("%s, %s", CleanText(u'(//*[@class="location"])[1]'), CleanText(u'//*[@class="address"]')) obj_category = CATEGORIES.SPECTACLE obj_price = CleanDecimal( CleanText(u'(//*[@class="unit_price with_beneficiary"])[1]')) obj_description = Format( u'%s. %s. %.2f€.', CleanText( u'(//*[contains(@class, "tariff") and contains(@class, "with_beneficiary")])[1]' ), CleanText( u'(//*[contains(@class, "seat") and contains(@class, "with_beneficiary")])[1]' ), obj_price, ) obj_ticket = TICKET.AVAILABLE def obj_url(self): return (u'%s%s' % (self.page.browser.BASEURL, Link(u'//*[@class="alternative_button mticket"]/a') (self)))
class obj_picture(ItemElement): klass = BaseImage obj_url = Attr( '//article[has-class("bu_cuisine_main_recipe")]' '//img[has-class("bu_cuisine_img_noborder")]', 'src') obj_thumbnail = Eval(Thumbnail, obj_url)
class item(ItemElement): klass = Investment def condition(self): return Field('quantity')(self) != NotAvailable and Field( 'quantity')(self) > 0 obj_quantity = MyDecimal(TableCell('quantity'), default=NotAvailable) obj_unitvalue = MyDecimal(TableCell('unitvalue'), default=NotAvailable) obj_unitprice = MyDecimal(TableCell('unitprice'), default=NotAvailable) obj_valuation = MyDecimal(TableCell('valuation'), default=NotAvailable) obj_portfolio_share = Eval( lambda x: x / 100 if x else NotAvailable, MyDecimal(TableCell('portfolio_share'), default=NotAvailable)) obj_diff = MyDecimal(TableCell('diff', default=NotAvailable), default=NotAvailable) obj_code_type = Investment.CODE_TYPE_ISIN obj_label = CleanText( Regexp(CleanText('./preceding-sibling::tr/td[1]'), '(.*)- .*')) obj_code = Regexp(CleanText('./preceding-sibling::tr/td[1]'), '- (.*)')
class item(ItemElement): klass = Investment def condition(self): return (CleanText('./th')(self) != 'Total épargne constituée' ) and ('Détail' not in Field('label')(self)) obj_label = CleanText('./th') obj_quantity = CleanDecimal(TableCell('quantity'), default=NotAvailable) obj_unitvalue = CleanDecimal(TableCell('unitvalue'), default=NotAvailable) obj_valuation = CleanDecimal(TableCell('valuation'), default=NotAvailable) obj_portfolio_share = Eval( lambda x: x / 100, CleanDecimal(TableCell('portfolio_share'))) def obj_code(self): code = Regexp(Link('./th/a', default=''), r'isin=(\w+)|/(\w+)\.pdf', default=NotAvailable)(self) return code if is_isin_valid(code) else NotAvailable def obj_code_type(self): return Investment.CODE_TYPE_ISIN if is_isin_valid( Field('code')(self)) else NotAvailable
def obj_amount(self): decimal_nb = Dict('montantMvmt/nbDec', default=None)(self)\ or Dict('montantMvmt/nb_dec')(self) return Eval(lambda x, y: x / 10**y, CleanDecimal(Dict('montantMvmt/montant')), decimal_nb)(self)
class InvestItem(ItemElement): klass = Investment obj_label = CleanText(TableCell('label', support_th=True)) obj_portfolio_share = Eval(lambda x: x / 100 if x else NotAvailable, CleanDecimal(TableCell('share', support_th=True), replace_dots=True, default=NotAvailable)) obj_quantity = CleanDecimal(TableCell('quantity', support_th=True), replace_dots=True, default=NotAvailable) obj_valuation = CleanDecimal(TableCell('valuation', support_th=True), replace_dots=True, default=NotAvailable)
def handle_response(self, origin, recipient, amount, reason, exec_date): account_data = Dict('donnees/detailOrdre/compteEmetteur')(self.doc) recipient_data = Dict('donnees/listOperations/0/compteBeneficiaire')( self.doc) transfer_data = Dict('donnees/detailOrdre')(self.doc) transfer = Transfer() transfer._b64_id_transfer = Dict('idOrdre')(transfer_data) transfer.account_id = origin.id transfer.account_label = Dict('libelleCompte')(account_data) transfer.account_iban = Dict('ibanCompte')(account_data) transfer.account_balance = origin.balance transfer.recipient_id = recipient.id transfer.recipient_label = Dict('libelleCompte')(recipient_data) transfer.recipient_iban = Dict('ibanCompte')(recipient_data) transfer.currency = Dict('montantTotalOrdre/codeDevise')(transfer_data) transfer.amount = CleanDecimal( Eval(lambda x, y: x * (10**-y), Dict('montantTotalOrdre/valeurMontant'), Dict('montantTotalOrdre/codeDecimalisation')))(transfer_data) transfer.exec_date = Date(Dict('dateExecution'), dayfirst=True)(transfer_data) transfer.label = Dict('libelleClientOrdre')(transfer_data) return transfer
def obj_portfolio_share(self): if self.page.is_detail(): return NotAvailable return Eval( lambda x: x / 100, CleanDecimal(TableCell('portfolio_share'), replace_dots=True))(self)
class item(ItemElement): klass = Investment obj_label = CleanText(TableCell('label')) obj_vdate = Date(CleanText(TableCell('vdate')), dayfirst=True) obj_portfolio_share = Eval(lambda x: x / 100, CleanDecimal(TableCell('portfolio_share'))) obj_unitvalue = CleanDecimal(TableCell('unitvalue'), default=Decimal('1')) obj_valuation = CleanDecimal(TableCell('support_value')) def obj_diff_ratio(self): val = self.el.xpath('.//td')[4].text_content().strip().strip('%') if val == '-': return NotAvailable return Decimal(val) / 100 def obj_code(self): if "Fonds en euros" in Field('label')(self): return NotAvailable return Regexp(Link('.//a'), r'javascript:openSupportPerformanceWindow\(\'(.*?)\', \'(.*?)\'\)', '\\2')(self) def obj_quantity(self): # default for euro funds return CleanDecimal(TableCell('quantity'), default=CleanDecimal(TableCell('support_value'))(self))(self) def condition(self): return len(self.el.xpath('.//td')) > 1
class item(ItemElement): klass = Investment obj_label = CleanText(TableCell('label')) def obj_code(self): td = TableCell('label')(self)[0] return Attr('.//a', 'id', default=NotAvailable)(td) obj_code_type = Investment.CODE_TYPE_ISIN def obj_quantity(self): return MyDecimal(TableCell('quantity'))(self) or NotAvailable def obj_unitvalue(self): return MyDecimal(TableCell('unitvalue'))(self) or NotAvailable obj_valuation = MyDecimal(TableCell('valuation')) obj_portfolio_share = Eval( lambda x: x / 100, CleanDecimal(TableCell('portfolio_share'), replace_dots=True)) obj_vdate = Date(CleanText(TableCell('vdate')), dayfirst=True, default=NotAvailable)
def obj_date(self): actual_day_number = Eval( int, Regexp(CleanText('./dl/dt'), '\w{3} (\d+)'))(self) base_date = date.today() if base_date.day > actual_day_number: base_date = base_date.replace(month=base_date.month + 1) base_date = base_date.replace(day=actual_day_number) return base_date