def get_list(self): for tr in self.doc.xpath('//table[@class="compteTable"]/tr'): if not tr.attrib.get('class', '').startswith('ligne_'): continue cols = tr.findall('td') if len(cols) < 2: continue try: amount = sum([ Decimal(FrenchTransaction.clean_amount(txt)) for txt in cols[-1].itertext() if len(txt.strip()) > 0 ]) except InvalidOperation: continue a = cols[0].find('a') if a is None: for a in cols[0].xpath('.//li/a'): args = self.js2args(a.attrib['href']) if 'numero_compte' not in args or 'numero_poste' not in args: self.logger.warning('Card link with strange args: %s' % args) continue account = Account() account.id = '%s.%s' % (args['numero_compte'], args['numero_poste']) account.label = u'Carte %s' % CleanText().filter(a) account.balance = amount account.type = account.TYPE_CARD account.currency = [ account.get_currency(txt) for txt in cols[-1].itertext() if len(txt.strip()) > 0 ][0] yield account continue args = self.js2args(a.attrib['href']) if 'numero_compte' not in args or 'numero_poste' not in args: self.logger.warning( 'Account link for %r with strange args: %s' % (a.attrib.get('alt', a.text), args)) continue account = Account() account.id = u'%s.%s' % (args['numero_compte'], args['numero_poste']) account.label = to_unicode(a.attrib.get('alt', a.text.strip())) account.balance = amount account.currency = [ account.get_currency(txt) for txt in cols[-1].itertext() if len(txt.strip()) > 0 ][0] account.type = self.ACCOUNT_TYPES.get(account.label, Account.TYPE_UNKNOWN) yield account
def get_loan_list(self): accounts = OrderedDict() # Old website for tr in self.doc.xpath( '//table[@cellpadding="1"]/tr[not(@class) and td[a]]'): tds = tr.findall('td') account = Account() account.id = CleanText('./a')(tds[2]).split('-')[0].strip() account.label = CleanText('./a')(tds[2]).split('-')[-1].strip() account.type = Account.TYPE_LOAN account.balance = -CleanDecimal('./a', replace_dots=True)(tds[4]) account.currency = account.get_currency(CleanText('./a')(tds[4])) accounts[account.id] = account if len(accounts) == 0: # New website for table in self.doc.xpath('//div[@class="panel"]'): title = table.getprevious() if title is None: continue account_type = self.ACCOUNT_TYPES.get( CleanText('.')(title), Account.TYPE_UNKNOWN) for tr in table.xpath( './table/tbody/tr[contains(@id,"MM_SYNTHESE_CREDITS") and contains(@id,"IdTrGlobal")]' ): tds = tr.findall('td') if len(tds) == 0: continue for i in tds[0].xpath('.//a/strong'): label = i.text.strip() break if len(tds) == 3 and Decimal( FrenchTransaction.clean_amount( CleanText('.')(tds[-2]))) and any( cls in Attr('.', 'id')(tr) for cls in ['dgImmo', 'dgConso']) == False: # in case of Consumer credit or revolving credit, we substract avalaible amount with max amout # to get what was spend balance = Decimal( FrenchTransaction.clean_amount( CleanText('.')(tds[-2]))) - Decimal( FrenchTransaction.clean_amount( CleanText('.')(tds[-1]))) else: balance = Decimal( FrenchTransaction.clean_amount( CleanText('.')(tds[-1]))) account = Account() account.id = label.split(' ')[-1] account.label = unicode(label) account.type = account_type account.balance = -abs(balance) account.currency = account.get_currency( CleanText('.')(tds[-1])) account._card_links = [] accounts[account.id] = account return accounts.itervalues()
def iter_accounts(self): # Throw error from password value or random error self.maybe_generate_error(8) accounts = [] first_account = Account() first_account.id = 'FR235711131719@fakebank' first_account.label = 'Compte chèque' first_account.currency = Currency.get_currency('42 €') first_account.iban = 'FR235711131719' first_account.balance = Decimal(random.uniform(0, 150)) first_account.type = Account.TYPE_CHECKING accounts.append(first_account) second_account = Account() second_account.id = 'livretA@fakebank' second_account.label = 'Livret A' second_account.currency = Currency.get_currency('$42') second_account.balance = Decimal(500.0) second_account.type = Account.TYPE_SAVINGS accounts.append(second_account) third_account = Account() third_account.id = 'PEL@fakebank' third_account.label = 'Plan Epargne Logement' third_account.balance = Decimal(0.0) third_account.type = Account.TYPE_SAVINGS accounts.append(third_account) return accounts
def get_accounts(self): accounts = {} content = self.doc.xpath( '//div[@id="moneyPage" or @id="MoneyPage"]')[0] # Multiple accounts lines = content.xpath( '(//div[@class="col-md-8 multi-currency"])[1]/ul/li') for li in lines: account = Account() account.iban = NotAvailable account.type = Account.TYPE_CHECKING currency_code = CleanText().filter( (li.xpath('./span[@class="currencyUnit"]/span') or li.xpath('./span[1]'))[0]) currency = Currency.get_currency(currency_code) if not currency: self.logger.warning('Unable to find currency %r', currency_code) continue account.id = currency account.currency = currency account.balance = CleanDecimal(replace_dots=True).filter( li.xpath('./span[@class="amount"]/text()')) account.label = u'%s %s*' % (self.browser.username, account.currency) accounts[account.id] = account self.browser.account_currencies.append(account.currency) if not accounts: # Primary currency account primary_account = Account() primary_account.iban = NotAvailable primary_account.type = Account.TYPE_CHECKING try: balance = CleanText('.')(content.xpath( '//div[contains(@class, "col-md-6")][contains(@class, "available")]' )[0]) except IndexError: primary_account.id = 'EUR' primary_account.currency = u'EUR' primary_account.balance = NotAvailable primary_account.label = u'%s' % (self.browser.username) else: primary_account.currency = Account.get_currency(balance) primary_account.id = unicode(primary_account.currency) primary_account.balance = Decimal( FrenchTransaction.clean_amount(balance)) primary_account.label = u'%s %s*' % (self.browser.username, primary_account.currency) accounts[primary_account.id] = primary_account return accounts
def get_accounts(self): accounts = {} content = self.doc.xpath('//section[@id="contents"]')[0] # Multiple accounts lines = content.xpath('.//ul[@class="multiCurrency-container"][1]/li') for li in lines: account = Account() account.iban = NotAvailable account.type = Account.TYPE_CHECKING currency = CleanText().filter( li.xpath( './/span[contains(@class, "multiCurrency-label_alignMiddle")]' )[0]) account.id = currency account.currency = currency account.balance = CleanDecimal(replace_dots=True).filter( li.xpath( './/span[contains(@class, "multiCurrency-label_right")]/text()' )[0]) account.label = u'%s %s*' % (self.browser.username, account.currency) accounts[account.id] = account self.browser.account_currencies.append(account.currency) if not accounts: # Primary currency account primary_account = Account() primary_account.iban = NotAvailable primary_account.type = Account.TYPE_CHECKING try: balance = CleanText('.')(content.xpath( '//div[contains(@class, "col-md-6")][contains(@class, "available")]' )[0]) except IndexError: primary_account.id = 'EUR' primary_account.currency = u'EUR' primary_account.balance = NotAvailable primary_account.label = u'%s' % (self.browser.username) else: primary_account.currency = Account.get_currency(balance) primary_account.id = unicode(primary_account.currency) primary_account.balance = Decimal( FrenchTransaction.clean_amount(balance)) primary_account.label = u'%s %s*' % (self.browser.username, primary_account.currency) accounts[primary_account.id] = primary_account return accounts
def get_accounts_list(self): for table in self.doc.xpath('//div[@class="comptestabl"]/table'): try: account_type = self.ACCOUNT_TYPES[table.get('summary').lower()] if not account_type: account_type = self.ACCOUNT_TYPES[table.xpath( './caption/text()')[0].strip().lower()] except (IndexError, KeyError): account_type = Account.TYPE_UNKNOWN for tr in table.xpath('./tbody/tr'): cols = tr.findall('td') link = cols[0].find('a') if link is None: continue a = Account() a.type = account_type a.id = unicode( re.search('([A-Z\d]{4}[A-Z\d\*]{3}[A-Z\d]{4})', link.attrib['title']).group(1)) a.label = unicode(link.attrib['title'].replace( '%s ' % a.id, '')) # We use '.text_content()' to avoid HTML comments like '<!-- ... -->' tmp_balance = CleanText(None).filter(cols[1].text_content()) a.currency = a.get_currency(tmp_balance) if not a.currency: a.currency = u'EUR' a.balance = Decimal(Transaction.clean_amount(tmp_balance)) a._has_cards = False a.url = urljoin(self.url, link.attrib['href']) yield a
def get_list(self): for div in self.document.xpath('.//div[@id="card-details"]'): a = Account() a.id = self.parser.tocleanstring( div.xpath('.//span[@class="acc-num"]')[0]) a.label = self.parser.tocleanstring( div.xpath('.//span[@class="card-desc"]')[0]) if "carte" in a.label.lower(): a.type = Account.TYPE_CARD balance = self.parser.tocleanstring( div.xpath('.//span[@class="balance-data"]')[0]) if balance in (u'Indisponible', u'Indisponible Facturation en cours', ''): a.balance = NotAvailable else: a.currency = a.get_currency(balance) a.balance = -abs( CleanDecimal( replace_dots=a.currency == 'EUR').filter(balance)) # Cancel card don't have a link to watch history link = self.document.xpath('.//div[@class="wide-bar"]/h3/a') if len(link) == 1: a._link = link[0].attrib['href'] else: a._link = None yield a
def get_list(self): for tr in self.document.xpath('//table[@class="datas"]//tr'): if tr.attrib.get('class', '') == 'entete': continue cols = tr.findall('td') a = Account() a.label = unicode(cols[self.COL_ID].xpath( './/span[@class="left-underline"]')[0].text.strip()) a.type = self.get_account_type(a.label) balance = self.parser.tocleanstring(cols[self.COL_BALANCE]) a.balance = Decimal(FrenchTransaction.clean_amount(balance)) a.currency = a.get_currency(balance) a._link, a._args = self.params_from_js( cols[self.COL_ID].find('a').attrib['href']) a._acc_nb = cols[self.COL_ID].xpath( './/span[@class="right-underline"]')[0].text.replace( ' ', '').strip() if a._args: a.id = '%s%s%s' % (a._acc_nb, a._args['IndiceCompte'], a._args['Indiceclassement']) else: a.id = a._acc_nb a._card_ids = [] a._inv = False yield a
def get_list(self): table = self.find_table() for tr in self.parser.select(table, 'tr', 'many'): tds = self.parser.select(tr, 'td') if len(tds) != 6: continue tdlabel, tdid, tdcur, tdupdated, tdbal, tdbalcur = tds account = Account() account.label = to_unicode(tdlabel.text_content().strip()) # this is important - and is also the last part of the id (considering spaces) # we can't use only the link as it does not goes where we want try: link = self.parser.select(tdlabel, 'a', 1) except BrokenPageError: # probably an account we can't display the history account._link_id = None else: account._link_id = parse_qs(link.attrib['href'])['ch4'][0] account.id = to_unicode(tdid.text.strip().replace(' ', '')) account.iban = 'FR76' + account.id # just in case we are showing the converted balances account._main_currency = Account.get_currency(tdcur.text) # we have to ignore those accounts, because using NotAvailable # makes boobank and probably many others crash if tdbal.text_content().strip() == 'indisponible': continue account.balance = Decimal( Transaction.clean_amount(tdbal.text_content())) account.currency = Account.get_currency(tdbalcur.text) account._updated = datetime.strptime(tdupdated.text, '%d/%m/%Y') yield account
def iter_accounts(self): if self.accounts: for account in self.accounts: yield account return for project in self.users['projects']: me = self.request('/user/%s/project/%s/' % (self.users['userId'], project['projectId'])) a = Account() a.id = "".join(me['numeroContrat'].split()) a.label = " ".join(me['supportEpargne'].split("_")) a.type = Account.TYPE_LIFE_INSURANCE if "assurance vie" in a.label.lower() else \ Account.TYPE_MARKET if "compte titre" in a.label.lower() else \ Account.TYPE_UNKNOWN a.balance = CleanDecimal().filter(me['solde']) a.iban = me['ibancompteTitre'] if me[ 'ibancompteTitre'] else NotAvailable a.number = project['projectId'] a.valuation_diff = CleanDecimal().filter(me['performanceEuro']) a._startbalance = me['montantDepart'] self.accounts.append(a) self.iter_investment(a, me['sousJacents']) yield a
def get_account(self): for div in self.doc.xpath('.//div[@id="card-details"]'): a = Account() a.id = CleanText().filter(div.xpath('.//span[@class="acc-num"]')) a.label = CleanText().filter( div.xpath('.//span[@class="card-desc"]')) if "carte" in a.label.lower(): a.type = Account.TYPE_CARD balance = CleanText().filter( div.xpath('.//span[@class="balance-data"]')) if balance in (u'Indisponible', u'Indisponible Facturation en cours', ''): a.balance = NotAvailable else: a.currency = a.get_currency(balance) a.balance = -abs(parse_decimal(balance)) # Cancel card don't have a link to watch history link = self.doc.xpath('.//div[@class="wide-bar"]/h3/a') if len(link) == 1: a.url = urljoin(self.url, link[0].attrib['href']) else: a.url = None return a
def get_list(self): for tr in self.document.getiterator('tr'): tds = tr.findall('td') if len(tds) != 3 or tds[0].find('a') is None or tds[0].find('a').attrib.get('class', '') != 'flecheM': continue account = Account() account.id = tds[1].text.strip() a = tds[0].findall('a')[-1] account.label = a.text.strip() account._link_id = a.attrib['href'] m = re.search('(\w+)_IdPrestation', account._link_id) if not m or m.group(1) != 'CPT': account._link_id = None if m: account.id += '.%s' % m.group(1) tag = tds[2].find('font') if tag is None: tag = tds[2] account.balance = Decimal(tag.text.replace('.','').replace(',','.').replace(' ', '').strip(u' \t\u20ac\xa0€\n\r')) account.coming = NotAvailable yield account
def get_cards(self, account_id): divs = self.doc.xpath('//div[@class="content-boxed"]') assert len(divs) msgs = re.compile(u'Vous avez fait opposition sur cette carte bancaire.' + '|Votre carte bancaire a été envoyée.' + '|BforBank a fait opposition sur votre carte' + '|Pour des raisons de sécurité, la demande de réception du code confidentiel de votre carte par SMS est indisponible') divs = [d for d in divs if not msgs.search(CleanText('.//div[has-class("alert")]', default='')(d))] divs = [d.xpath('.//div[@class="m-card-infos"]')[0] for d in divs] divs = [d for d in divs if not d.xpath('.//div[@class="m-card-infos-body-text"][text()="Débit immédiat"]')] if not len(divs): self.logger.warning('all cards are cancelled, acting as if there is no card') return [] cards = [] for div in divs: label = CleanText('.//div[@class="m-card-infos-body-title"]')(div) number = CleanText('.//div[@class="m-card-infos-body-num"]', default='')(div) number = re.sub('[^\d*]', '', number).replace('*', 'x') debit = CleanText(u'.//div[@class="m-card-infos-body-text"][contains(text(),"Débit")]')(div) assert debit == u'Débit différé', 'unrecognized card type %s: %s' % (number, debit) card = Account() card.id = '%s.%s' % (account_id, number) card.label = label card.number = number card.type = Account.TYPE_CARD cards.append(card) return cards
def get_loan_list(self): accounts = OrderedDict() # New website for table in self.document.xpath('//div[@class="panel"]'): title = table.getprevious() if title is None: continue account_type = self.ACCOUNT_TYPES.get( self.parser.tocleanstring(title), Account.TYPE_UNKNOWN) for tr in table.xpath( './table/tbody/tr[contains(@id,"MM_SYNTHESE_CREDITS") and contains(@id,"IdTrGlobal")]' ): tds = tr.findall('td') if len(tds) == 0: continue for i in tds[0].xpath('.//a/strong'): label = i.text.strip() break balance = Decimal( FrenchTransaction.clean_amount( self.parser.tocleanstring(tds[-1]))) account = Account() account.id = label.split(' ')[-1] account.label = unicode(label) account.type = account_type account.balance = -abs(balance) account.currency = account.get_currency( self.parser.tocleanstring(tds[-1])) account._card_links = [] accounts[account.id] = account return accounts.itervalues()
def iter_accounts(self): for line in self.doc.xpath( '//script[@id="initial-state"]')[0].text.split('\n'): m = re.search('window.__INITIAL_STATE__ = (.*);', line) if m: data = json.loads(literal_eval(m.group(1))) break else: assert False, "data was not found" assert data[13] == 'core' assert len(data[14]) == 3 assert len(data[14][2]) == 85 assert data[14][2][63] == 'products' assert len(data[14][2][64]) == 2 assert data[14][2][64][1][4] == 'productsList' accounts_data = data[14][2][64][1][5] for account_data in accounts_data: if isinstance(account_data, str): token = account_data elif isinstance(account_data, list): acc = Account() acc.number = '-%s' % account_data[2][2] acc.label = '%s %s' % (account_data[6][4], account_data[10][-1]) acc._token = acc.id = token yield acc
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)
def _add_account(self, accounts, link, label, account_type, balance): info = self._get_account_info(link) if info is None: self.logger.warning('Unable to parse account %r: %r' % (label, link)) return account = Account() account.id = info['id'] account.iban = u'FR76' + info['id'] account._info = info account.label = label account.type = info['acc_type'] if 'acc_type' in info else account_type account.balance = Decimal(FrenchTransaction.clean_amount( balance)) if balance else self.get_balance(account) account.currency = account.get_currency(balance) account._card_links = [] if account._info['type'] == 'HISTORIQUE_CB' and account.id in accounts: a = accounts[account.id] if not a.coming: a.coming = Decimal('0.0') a.coming += account.balance a._card_links.append(account._info) return accounts[account.id] = account
def get_list(self): # TODO: no idea abount how proxy account are displayed for a in self.document.xpath('//a[@class="mainclic"]'): account = Account() account.currency = Currency.CUR_EUR account.id = unicode(a.find('span[@class="account-number"]').text) account._id = account.id account.label = unicode(a.find('span[@class="title"]').text) balance = a.find('span[@class="solde"]/label').text account.balance = Decimal(FrenchTransaction.clean_amount(balance)) account.coming = NotAvailable if "Courant" in account.label: account.id = "CC-" + account.id account.type = Account.TYPE_CHECKING elif "Livret A" in account.label: account.id = "LA-" + account.id account.type = Account.TYPE_SAVINGS elif "Orange" in account.label: account.id = "LEO-" + account.id account.type = Account.TYPE_SAVINGS elif "Durable" in account.label: account.id = "LDD-" + account.id account.type = Account.TYPE_SAVINGS elif "Titres" in account.label: account.id = "TITRE-" + account.id account.type = Account.TYPE_MARKET elif "PEA" in account.label: account.id = "PEA-" + account.id account.type = Account.TYPE_MARKET jid = self.document.find('//input[@name="javax.faces.ViewState"]') account._jid = jid.attrib['value'] yield account
def account(self): id_ = self.doc.xpath( u'//strong[contains(text(),' '"credit card account ending in")]/text()')[0].strip()[-4:] balance = self.doc.xpath( u'//section[@id=" account_summary"]' '//span[text()="Current Balance"]/../span[2]/text()')[0].strip() cardlimit = self.doc.xpath(u'//span[contains(text(),"Credit limit")]' '/text()')[0].split()[-1] paymin = self.doc.xpath( u'//section[@id=" account_summary"]' '//strong[text()="Minimum Payment Due"]/../../span[2]/text()' )[0].strip() a = Account() a.id = id_ a.label = u'ACCOUNT ENDING IN %s' % id_ a.currency = Account.get_currency(balance) a.balance = -AmTr.decimal_amount(balance) a.type = Account.TYPE_CARD a.cardlimit = AmTr.decimal_amount(cardlimit) a.paymin = AmTr.decimal_amount(paymin) #TODO: Add paydate. #Oleg: I don't have an account with scheduled payment. # Need to wait for a while... return a
def get_list(self): accounts = [] previous_account = None noaccounts = self.get_from_js('_js_noMvts =', ';') if noaccounts is not None: assert 'avez aucun compte' in noaccounts return [] txt = self.get_from_js('_data = new Array(', ');', is_list=True) if txt is None: raise BrowserUnavailable('Unable to find accounts list in scripts') data = json.loads('[%s]' % txt.replace("'", '"')) for line in data: a = Account() a.id = line[self.COL_ID].replace(' ', '') if re.match(r'Classement=(.*?):::Banque=(.*?):::Agence=(.*?):::SScompte=(.*?):::Serie=(.*)', a.id): a.id = str(CleanDecimal().filter(a.id)) a._acc_nb = a.id.split('_')[0] if len(a.id.split('_')) > 1 else None a.label = MyStrip(line[self.COL_LABEL], xpath='.//div[@class="libelleCompteTDB"]') # This account can be multiple life insurance accounts if a.label == 'ASSURANCE VIE-BON CAPI-SCPI-DIVERS *': continue a.balance = Decimal(FrenchTransaction.clean_amount(line[self.COL_BALANCE])) a.currency = a.get_currency(line[self.COL_BALANCE]) a.type = self.get_account_type(a.label) # The parent account must be created right before if a.type == Account.TYPE_CARD: # duplicate if find_object(accounts, id=a.id): self.logger.warning('Ignoring duplicate card %r', a.id) continue a.parent = previous_account if line[self.COL_HISTORY] == 'true': a._inv = False a._link = self.get_history_link() a._args = self.make__args_dict(line) else: a._inv = True a._args = {'_ipc_eventValue': line[self.COL_ID], '_ipc_fireEvent': line[self.COL_FIRE_EVENT], } a._link = self.doc.xpath('//form[@name="changePageForm"]')[0].attrib['action'] if a.type is Account.TYPE_CARD: a.coming = a.balance a.balance = Decimal('0.0') accounts.append(a) previous_account = a return accounts
def get_list(self): for trCompte in self.document.xpath('//table[@id="compte"]/tbody/tr'): tds = trCompte.findall('td') account = Account() account.id = tds[self.CPT_ROW_ID].text.strip() account.label = unicode(tds[self.CPT_ROW_NAME].text.strip()) account_type_str = "".join([ td.text for td in tds[self.CPT_ROW_NATURE].xpath('.//td[@class="txt"]') ]).strip() account.type = self.ACCOUNT_TYPES.get(account_type_str, Account.TYPE_UNKNOWN) account.balance = Decimal( FrenchTransaction.clean_amount( self.parser.tocleanstring(tds[self.CPT_ROW_BALANCE]))) account.coming = Decimal( FrenchTransaction.clean_amount( self.parser.tocleanstring(tds[self.CPT_ROW_ENCOURS]))) account.currency = account.get_currency( tds[self.CPT_ROW_BALANCE].find("a").text) yield account return
def get_accounts_list(self): for table in self.document.xpath('//div[@class="comptestabl"]/table'): try: account_type = self.ACCOUNT_TYPES[table.get('summary')] if not account_type: account_type = self.ACCOUNT_TYPES[table.xpath( './caption/text()')[0].strip()] except (IndexError, KeyError): account_type = Account.TYPE_UNKNOWN for tr in table.xpath('./tbody/tr'): cols = tr.findall('td') link = cols[0].find('a') if link is None: continue a = Account() a.type = account_type a.id = unicode( re.search('([A-Z\d]{4}[A-Z\d\*]{3}[A-Z\d]{4})', link.attrib['title']).group(1)) a.label = unicode(link.attrib['title'].replace( '%s ' % a.id, '')) tmp_balance = self.parser.tocleanstring(cols[1]) a.currency = a.get_currency(tmp_balance) a.balance = Decimal(Transaction.clean_amount(tmp_balance)) a._card_links = [] a._link_id = link.attrib['href'] yield a
def parse_table(self, what): tables = self.document.xpath("//table[@id='%s']" % what, smart_strings=False) if len(tables) < 1: return lines = tables[0].xpath(".//tbody/tr") for line in lines: account = Account() tmp = line.xpath("./td//a")[0] account.label = to_unicode(tmp.text) account._link_id = tmp.get("href") if 'BourseEnLigne' in account._link_id: continue tmp = line.xpath("./td/span/strong") if len(tmp) >= 2: tmp_id = tmp[0].text tmp_balance = tmp[1].text else: tmp_id = line.xpath("./td//span")[1].text tmp_balance = tmp[0].text account.id = tmp_id account.balance = Decimal(''.join( tmp_balance.replace('.', '').replace(',', '.').split())) self.account_list.append(account)
def account(self): label = u' '.join( self.doc.xpath('//div[contains(@class,"myCreditCardDetails")]') [0].text_content().split()) balance = self.amount(u'Balance') cardlimit = self.doc.xpath( u'//li[text()="Available to Spend"]')[0].text_content()\ .replace(u'Available to Spend', u'').replace(u'Limit', u'').strip() paymin = self.amount(u'Payment Due') if self.doc.xpath(u'//li[@class="noPaymentDue"]'): # If payment date is not scheduled yet, set it somewhere in a # distant future, so that we always have a valid date. paydate = datetime.now() + timedelta(days=999) else: rawtext = self.doc.xpath( u'//li[contains(text(),"Due Date")]')[0].text_content() datetext = re.match('.*(\d\d/\d\d/\d\d\d\d).*', rawtext).group(1) paydate = datetime.strptime(datetext, '%m/%d/%Y') a = Account() a.id = label[-4:] a.label = label a.currency = Account.get_currency(balance) a.balance = -AmTr.decimal_amount(balance) a.type = Account.TYPE_CARD a.cardlimit = AmTr.decimal_amount(cardlimit) a.paymin = AmTr.decimal_amount(paymin) if paydate is not None: a.paydate = paydate return a
def _parse_account(self, tr): account = Account() account.id = tr.xpath('.//td[@class="libelleCompte"]/input')[0].attrib['id'][len('libelleCompte'):] if len(str(account.id)) == 23: account.id = str(account.id)[5:21] a = tr.xpath('.//td[@class="libelleCompte"]/a')[0] m = re.match(r'javascript:goToStatements\(\'(\d+)\'', a.get('onclick', '')) if m: account._link_id = m.group(1) else: # Can't get history for this account. account._link_id = None # To prevent multiple-IDs for CIF (for example), add an arbitrary char in ID. account.id += 'C' account.label = u''+a.text.strip() tds = tr.findall('td') account.balance = self._parse_amount(tds[3].find('a')) if tds[4].find('a') is not None: account.coming = self._parse_amount(tds[4].find('a')) else: account.coming = NotAvailable return account
def get_accounts_list(self): r = self.api_open('/transactionnel/services/rest/Account/accounts') for content in r.json()['content']: if self.accnum != '00000000000' and content[ 'numero'] != self.accnum: continue for poste in content['postes']: a = Account() a._number = content['numeroLong'] a._nature = poste['codeNature'] a._consultable = poste['consultable'] a.id = '%s.%s' % (a._number, a._nature) a.type = self.ACCOUNT_TYPES.get(poste['codeNature'], Account.TYPE_UNKNOWN) if 'numeroDossier' in poste and poste['numeroDossier']: a._file_number = poste['numeroDossier'] a.id += '.%s' % a._file_number if poste['postePortefeuille']: a.label = u'Portefeuille Titres' a.balance = Decimal(str(poste['montantTitres']['valeur'])) a.currency = poste['montantTitres']['monnaie'][ 'code'].strip() yield a if 'libelle' not in poste: continue a.label = ' '.join( [content['intitule'].strip(), poste['libelle'].strip()]) a.balance = Decimal(str(poste['solde']['valeur'])) a.currency = poste['solde']['monnaie']['code'].strip() yield a
def get_list(self): for tr in self.document.xpath('//table[@class="ca-table"]/tr'): if not tr.attrib.get('class', '').startswith('colcelligne'): continue cols = tr.findall('td') if not cols: continue account = Account() account.id = self.parser.tocleanstring(cols[self.COL_ID]) account.label = self.parser.tocleanstring(cols[self.COL_LABEL]) account.type = self.TYPES.get(account.label, Account.TYPE_UNKNOWN) balance = self.parser.tocleanstring(cols[self.COL_VALUE]) # we have to ignore those accounts, because using NotAvailable # makes boobank and probably many others crash if balance in ('indisponible', ''): continue account.balance = Decimal(Transaction.clean_amount(balance)) account.currency = account.get_currency( self.parser.tocleanstring(cols[self.COL_CURRENCY])) account._link = None a = cols[0].find('a') if a is not None: account._link = a.attrib['href'].replace(' ', '%20') yield account
def get_accounts(self): accounts = {} content = self.doc.xpath('//div[@id="moneyPage"]')[0] # Primary currency account primary_account = Account() primary_account.type = Account.TYPE_CHECKING try: balance = CleanText('.')(content.xpath( '//div[contains(@class, "col-md-6")][contains(@class, "available")]' )[0]) except IndexError: primary_account.id = 'EUR' primary_account.currency = u'EUR' primary_account.balance = NotAvailable primary_account.label = u'%s' % (self.browser.username) else: primary_account.currency = Account.get_currency(balance) primary_account.id = unicode(primary_account.currency) primary_account.balance = Decimal( FrenchTransaction.clean_amount(balance)) primary_account.label = u'%s %s*' % (self.browser.username, primary_account.currency) accounts[primary_account.id] = primary_account return accounts
def get_list(self): for box in self.document.getroot().cssselect( 'div.roundedBox div.contentBox'): a = Account() a.id = self.parser.tocleanstring( box.xpath( './/tr[@id="summaryImageHeaderRow"]//div[@class="summaryTitles"]' )[0]) a.label = self.parser.tocleanstring( box.xpath('.//span[@class="cardTitle"]')[0]) if "carte" in a.label.lower(): a.type = Account.TYPE_CARD balance = self.parser.tocleanstring( self.parser.select(box, 'td#colOSBalance div.summaryValues', 1)) if balance in (u'Indisponible', u'Indisponible Facturation en cours', ''): a.balance = NotAvailable else: a.currency = a.get_currency(balance) a.balance = -abs( CleanDecimal( replace_dots=a.currency == 'EUR').filter(balance)) a._link = self.parser.select(box, 'div.summaryTitles a.summaryLink', 1).attrib['href'] yield a
def get_list(self, accounts_ids): l = [] # Read the json data json_data = self.browser.readurl('/banque/PA_Autonomy-war/ProxyIAService?cleOutil=IA_SMC_UDC&service=getlstcpt&dashboard=true&refreshSession=true&cre=udc&poka=true') json_infos = json.loads(json_data) for famille in json_infos['smc']['data']['familleCompte']: id_famille = famille['idFamilleCompte'] for compte in famille['compte']: account = Account() account.label = u''+compte['libellePersoProduit'] account.currency = account.get_currency(compte['devise']) account.balance = Decimal(compte['soldeDispo']) account.coming = Decimal(compte['soldeAVenir']) account.type = self.ACCOUNT_TYPES.get(id_famille, Account.TYPE_UNKNOWN) account.id = 0 account._link_id = 'KEY'+compte['key'] # IBAN aren't in JSON # Fast method, get it from transfer page. for i,a in accounts_ids.items(): if a.label == account.label: account.id = i # But it's doesn't work with LOAN and MARKET, so use slow method : Get it from transaction page. if account.id == 0: account.id = self.browser.get_IBAN_from_account(account) l.append(account) if len(l) == 0: print 'no accounts' # oops, no accounts? check if we have not exhausted the allowed use # of this password for img in self.document.getroot().cssselect('img[align="middle"]'): if img.attrib.get('alt', '') == 'Changez votre code secret': raise BrowserPasswordExpired('Your password has expired') return l