'ls' and 'history' boobank commands implemented for the new backend fortuneo

This commit is contained in:
sputnick 2012-04-20 23:58:18 +02:00 committed by Romain Bignon
commit d9c8e9ccdb
6 changed files with 155 additions and 267 deletions

View file

@ -17,146 +17,88 @@
# You should have received a copy of the GNU Affero General Public License
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
# AccountsList, IndexPage
from urlparse import parse_qs, urlparse
from lxml.etree import XML
from cStringIO import StringIO
from decimal import Decimal
import re
import datetime
from weboob.capabilities.bank import Account
from weboob.tools.capabilities.bank.transactions import FrenchTransaction
from weboob.tools.browser import BasePage, BrokenPageError
from weboob.tools.capabilities.bank.transactions import Transaction
from weboob.tools.browser import BasePage #, BrokenPageError
__all__ = ['AccountsList', 'AccountHistoryPage']
#__all__ = ['IndexPage', 'AccountsList', 'AccountHistory']
__all__ = ['AccountHistory']
class AccountHistoryPage(BasePage):
def get_operations(self, _id):
"""history, see http://docs.weboob.org/api/capabilities/bank.html?highlight=transaction#weboob.capabilities.bank.Transaction"""
operations = []
tables = self.document.findall(".//*[@id='tabHistoriqueOperations']/tbody/tr")
#class IndexPage(BasePage):
# def on_loaded(self):
# pass
#
# def get_list(self):
# l = []
# account.label = "test"
# account.id = "Livret +"
# account.balance = "20"
# account._link_id = "https://www.fortuneo.fr/fr/prive/default.jsp?ANav=1"
# l.append(account)
# return l
for i in range(len(tables)):
operation = Transaction(len(operations))
#class AccountsList(BasePage):
# def on_loaded(self):
# pass
#
# def get_list(self):
# #print "DEBUG self.document="+self.document
# account = []
# account.append('test')
# account.append('Livret +')
# account.append('20')
# account.append('https://www.fortuneo.fr/fr/prive/default.jsp?ANav=1')
# return account
# #account.append(account)
# #for el in self.document.xpath('//table[@id="tableauComptesTitEtCotit"]/tbody/'):
# #l.append(account)
# ##for tr in self.document.getiterator('tr'):
# ## if 'LGNTableRow' in tr.attrib.get('class', '').split():
# ## account = Account()
# ## for td in tr.getiterator('td'):
# ## if td.attrib.get('headers', '') == 'TypeCompte':
# ## a = td.find('a')
# ## account.label = unicode(a.find("span").text)
# ## account._link_id = a.get('href', '')
#
# ## elif td.attrib.get('headers', '') == 'NumeroCompte':
# ## id = td.text
# ## id = id.replace(u'\xa0','')
# ## account.id = id
#
# ## elif td.attrib.get('headers', '') == 'Libelle':
# ## pass
#
# ## elif td.attrib.get('headers', '') == 'Solde':
# ## balance = td.find('div').text
# ## if balance != None:
# ## balance = balance.replace(u'\xa0','').replace(',','.')
# ## account.balance = Decimal(balance)
# ## else:
# ## account.balance = Decimal(0)
#
# ## l.append(account)
#
# #return l
date_oper = tables[i].xpath("./td[2]/text()")[0]
date_val = tables[i].xpath("./td[3]/text()")[0]
label = tables[i].xpath("./td[4]/text()")[0]
label = label.strip()
amount = tables[i].xpath("./td[5]/text() | ./td[6]/text()")
operation.date = datetime.datetime.strptime(date_val, "%d/%m/%Y")
operation.rdate = datetime.datetime.strptime(date_oper,"%d/%m/%Y")
operation.type = 0
operation.raw = label
operation.label = u""+label
#class Transaction(FrenchTransaction):
# pass
#PATTERNS = [(re.compile(r'^CARTE \w+ RETRAIT DAB.* (?P<dd>\d{2})/(?P<mm>\d{2}) (?P<HH>\d+)H(?P<MM>\d+) (?P<text>.*)'),
# FrenchTransaction.TYPE_WITHDRAWAL),
# (re.compile(r'^(?P<category>CARTE) \w+ (?P<dd>\d{2})/(?P<mm>\d{2}) (?P<text>.*)'),
# FrenchTransaction.TYPE_CARD),
# (re.compile(r'^(?P<category>(COTISATION|PRELEVEMENT|TELEREGLEMENT|TIP)) (?P<text>.*)'),
# FrenchTransaction.TYPE_ORDER),
# (re.compile(r'^(?P<category>VIR(EMEN)?T? \w+) (?P<text>.*)'),
# FrenchTransaction.TYPE_TRANSFER),
# (re.compile(r'^(CHEQUE) (?P<text>.*)'), FrenchTransaction.TYPE_CHECK),
# (re.compile(r'^(FRAIS) (?P<text>.*)'), FrenchTransaction.TYPE_BANK),
# (re.compile(r'^(?P<category>ECHEANCEPRET)(?P<text>.*)'),
# FrenchTransaction.TYPE_LOAN_PAYMENT),
# (re.compile(r'^(?P<category>REMISE CHEQUES)(?P<text>.*)'),
# FrenchTransaction.TYPE_DEPOSIT),
# ]
if amount[1] == u'\xa0':
amount = amount[0].replace(u"\xa0", "").replace(",", ".").strip()
else:
amount = amount[1].replace(u"\xa0", "").replace(",", ".").strip()
operation.amount = Decimal(amount)
class AccountHistory(BasePage):
get_list = [1, 2, 3, 4]
def get_part_url(self):
print "DEBUG AccountHistory.get_part_url a implementer"
pass
#for script in self.document.getiterator('script'):
# if script.text is None:
# continue
operation.category = u" " # blank category
operation.origin = u" " # blank origin
operation.recipient = u" " # blank rcpt
# m = re.search('var listeEcrCavXmlUrl="(.*)";', script.text)
# if m:
# return m.group(1)
operations.append(operation)
#raise BrokenPageError('Unable to find link to history part')
return operations
#def iter_transactions(self):
# print "DEBUG iter_transactions a implementer"
# pass
# #url = self.get_part_url()
# #while 1:
# # d = XML(self.browser.readurl(url))
# # el = d.xpath('//dataBody')[0]
# # s = StringIO(el.text)
# # doc = self.browser.get_document(s)
class AccountsList(BasePage):
def get_list(self):
l = []
# # for tr in self._iter_transactions(doc):
# # yield tr
for cpt in self.document.xpath(".//*[@id='tableauComptesTitEtCotit']/tbody/tr"):
account = Account()
# # el = d.xpath('//dataHeader')[0]
# # if int(el.find('suite').text) != 1:
# # return
# account.id
account.id = cpt.xpath("./td[1]/a/text()")[0]
account.id = str(account.id)
# account balance
account.balance = Decimal(cpt.xpath("./td[3]/text()")[0].replace("EUR", "").replace("\n", "").replace("\t", "").replace(u"\xa0", ""))
# account coming
mycomingval = cpt.xpath("./td[4]/text()")[0].replace("EUR", "").replace("\n", "").replace("\t", "")
if mycomingval == '-':
account.coming = float(0)
else:
account.coming = float(mycomingval)
# # url = urlparse(url)
# # p = parse_qs(url.query)
# # url = self.browser.buildurl(url.path, n10_nrowcolor=0,
# # operationNumberPG=el.find('operationNumber').text,
# # operationTypePG=el.find('operationType').text,
# # pageNumberPG=el.find('pageNumber').text,
# # sign=p['sign'][0],
# # src=p['src'][0])
# account._link_id
url_to_parse = cpt.xpath('./td[1]/a/@href')[0] # link
compte_id_re = re.compile(r'.*COMPTE_ACTIF=([^\&]+)\&.*')
account._link_id = '/fr/prive/mes-comptes/livret/consulter-situation/consulter-solde.jsp?COMPTE_ACTIF='+compte_id_re.search(str(url_to_parse)).groups()[0]
account._link_id = str(account._link_id)
# account.label
tpl = cpt.xpath("./td[2]/a/text()")[0].split(' ')
account.label = tpl[0] + u" " + tpl[1]
account.label = str(u""+account.label)
def _iter_transactions(self, doc):
print "DEBUG _iter_transactions a implementer"
pass
#for i, tr in enumerate(self.parser.select(doc.getroot(), 'tr')):
# t = Transaction(i)
# t.parse(date=tr.xpath('./td[@headers="Date"]')[0].text,
# raw=tr.attrib['title'].strip())
# t.set_amount(*reversed([el.text for el in tr.xpath('./td[@class="right"]')]))
# t._coming = tr.xpath('./td[@headers="AVenir"]')[0].text
# yield t
account.raw = str(u""+account.label)
l.append(account)
return l
# vim:ts=4:sw=4

View file

@ -18,85 +18,18 @@
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from logging import error
#from logging import error
from weboob.tools.browser import BasePage, BrowserUnavailable
#from lxml import etree
from weboob.tools.browser import BasePage #, BrowserUnavailable
__all__ = ['LoginPage']
def dump(obj):
for attr in dir(obj):
print "obj.%s = %s" % (attr, getattr(obj, attr))
class LoginPage(BasePage):
def login(self, login, passwd):
#print "DEBUG BasePage=", BasePage.url
#dump(BasePage)
self.browser.select_form(nr=3)
#self.browser['locale'] = 'fr'
self.browser['login'] = login
self.browser['passwd'] = passwd
#self.browser['idDyn'] = 'false'
self.browser.submit()
#print "DEBUG ", self.page
#class LoginPage(BasePage):
# def on_loaded(self):
# pass
# #for td in self.document.getroot().cssselect('td.LibelleErreur'):
# # if td.text is None:
# # continue
# # msg = td.text.strip()
# # if 'indisponible' in msg:
# # raise BrowserUnavailable(msg)
#
# def login(self, login, password):
# DOMAIN_LOGIN = self.browser.DOMAIN_LOGIN
# DOMAIN = self.browser.DOMAIN
#
# url_login = 'https://' + DOMAIN_LOGIN + '/index.html'
#
# base_url = 'https://' + DOMAIN
# url = base_url + '/cvcsgenclavier?mode=jsom&estSession=0'
# headers = {
# 'Referer': url_login
# }
# request = self.browser.request_class(url, None, headers)
# infos_data = self.browser.readurl(request)
# infos_xml = etree.XML(infos_data)
# infos = {}
# for el in ("cryptogramme", "nblignes", "nbcolonnes"):
# infos[el] = infos_xml.find(el).text
#
# infos["grille"] = ""
# for g in infos_xml.findall("grille"):
# infos["grille"] += g.text + ","
# infos["keyCodes"] = infos["grille"].split(",")
#
# url = base_url + '/cvcsgenimage?modeClavier=0&cryptogramme=' + infos["cryptogramme"]
# img = Captcha(self.browser.openurl(url), infos)
#
# try:
# img.build_tiles()
# except TileError, err:
# error("Error: %s" % err)
# if err.tile:
# err.tile.display()
#
# self.browser.openurl(url_login)
# self.browser.select_form('authentification')
# self.browser.set_all_readonly(False)
#
# self.browser['codcli'] = login
# self.browser['codsec'] = img.get_codes(password)
# self.browser['cryptocvcs'] = infos["cryptogramme"]
# self.browser.submit()
#class BadLoginPage(BasePage):
#print "DEBUG BasePage"
# import sys
#sys.exit(1)
# vim:ts=4:sw=4