Get transaction history on the new site

This commit is contained in:
Florent 2013-02-22 14:40:20 +01:00 committed by Romain Bignon
commit d552e43267
2 changed files with 63 additions and 16 deletions

View file

@ -16,6 +16,7 @@
# #
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with weboob. If not, see <http://www.gnu.org/licenses/>. # along with weboob. If not, see <http://www.gnu.org/licenses/>.
import urllib
import hashlib import hashlib
from weboob.tools.browser import BaseBrowser, BrowserIncorrectPassword from weboob.tools.browser import BaseBrowser, BrowserIncorrectPassword
@ -33,7 +34,7 @@ class Ing(BaseBrowser):
PROTOCOL = 'https' PROTOCOL = 'https'
DEBUG_HTTP = False DEBUG_HTTP = False
#DEBUG_HTTP = True #DEBUG_HTTP = True
ENCODING = None # refer to the HTML encoding ENCODING = "utf-8"
PAGES = {'.*pages/index.jsf.*': AccountsList, PAGES = {'.*pages/index.jsf.*': AccountsList,
'.*displayLogin.jsf.*': LoginPage, '.*displayLogin.jsf.*': LoginPage,
'.*accountDetail.jsf.*': AccountHistory, '.*accountDetail.jsf.*': AccountHistory,
@ -48,10 +49,11 @@ class Ing(BaseBrowser):
CERTHASH = "fba557b387cccc3d71ba038f9ef1de4d71541d7954744c79f6a7ff5f3cd4dc12" CERTHASH = "fba557b387cccc3d71ba038f9ef1de4d71541d7954744c79f6a7ff5f3cd4dc12"
loginpage = '/public/displayLogin.jsf' loginpage = '/public/displayLogin.jsf'
accountspage = '/general?command=displayTRAccountSummary' accountspage = '/protected/pages/index.jsf'
transferpage = '/protected/pages/cc/transfer/transferManagement.jsf' transferpage = '/protected/pages/cc/transfer/transferManagement.jsf'
dotransferpage = '/general?command=DisplayDoTransferCommand' dotransferpage = '/general?command=DisplayDoTransferCommand'
valtransferpage = '/protected/pages/cc/transfer/create/transferCreateValidation.jsf' valtransferpage = '/protected/pages/cc/transfer/create/transferCreateValidation.jsf'
where = None
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.birthday = kwargs.pop('birthday', None) self.birthday = kwargs.pop('birthday', None)
@ -81,7 +83,7 @@ class Ing(BaseBrowser):
def get_accounts_list(self): def get_accounts_list(self):
if not self.is_on_page(AccountsList): if not self.is_on_page(AccountsList):
self.location(self.accountspage) self.location(self.accountspage)
self.where = "start"
return self.page.get_list() return self.page.get_list()
def get_account(self, id): def get_account(self, id):
@ -105,17 +107,19 @@ class Ing(BaseBrowser):
def get_history(self, account): def get_history(self, account):
if not isinstance(account, Account): if not isinstance(account, Account):
account = self.get_account(account) account = self.get_account(account)
# The first and the second letter of the label are the account type if self.where != "start":
if account.label[0:2] == "CC": self.location(self.accountspage)
self.location('/protected/pages/cc/accountDetail.jsf?account=%s' data = {"AJAX:EVENTS_COUNT": 1,
% int(account._index)) "AJAXREQUEST": "_viewRoot",
elif account.label[0:2] == "LA" or account.label[0:3] == "LEO": "ajaxSingle": "index:setAccount",
# we want "displayTRHistoriqueLA" but this fucking page "autoScroll": "",
# is not directly available... "index": "index",
self.location('/general?command=goToAccount&account=%d&zone=COMPTE' "index:setAccount": "index:setAccount",
% int(account._index)) "javax.faces.ViewState": account._jid,
else: "cptnbr": account._id
raise NotImplementedError() }
self.location(self.accountspage, urllib.urlencode(data))
self.where = "history"
while 1: while 1:
hashlist = [] hashlist = []
for transaction in self.page.get_transactions(): for transaction in self.page.get_transactions():

View file

@ -19,9 +19,11 @@
from decimal import Decimal from decimal import Decimal
from datetime import date
import re import re
import hashlib
from weboob.capabilities.bank import Account, Currency from weboob.capabilities.bank import Account, Currency, Transaction
from weboob.capabilities.base import NotAvailable from weboob.capabilities.base import NotAvailable
from weboob.tools.browser import BasePage, BrowserUnavailable from weboob.tools.browser import BasePage, BrowserUnavailable
from weboob.tools.capabilities.bank.transactions import FrenchTransaction from weboob.tools.capabilities.bank.transactions import FrenchTransaction
@ -29,17 +31,29 @@ from weboob.tools.capabilities.bank.transactions import FrenchTransaction
__all__ = ['AccountsList'] __all__ = ['AccountsList']
class Transaction(FrenchTransaction):
PATTERNS = [(re.compile(u'^retrait dab (?P<dd>\d{2})/(?P<mm>\d{2})/(?P<yy>\d{4}) (?P<text>.*)'), FrenchTransaction.TYPE_WITHDRAWAL),
(re.compile(u'^carte (?P<dd>\d{2})/(?P<mm>\d{2})/(?P<yy>\d{4}) (?P<text>.*)'), Transaction.TYPE_CARD),
(re.compile(u'^virement ((sepa emis vers|emis vers|recu|emis)?) (?P<text>.*)'), Transaction.TYPE_TRANSFER),
(re.compile(u'^prelevement (?P<text>.*)'), Transaction.TYPE_ORDER),
]
class AccountsList(BasePage): class AccountsList(BasePage):
def on_loaded(self): def on_loaded(self):
pass pass
monthvalue = {u'janv.': '1', u'févr.': '2', u'mars.': '3', u'avri.': '4',
u'mai.': '5', u'juin.': '6', u'juil.': '7', u'août.': '8',
u'sept.': '9', u'octo.': '10', u'nove.': '11', u'déce.': '12',
}
def get_list(self): def get_list(self):
# TODO: no idea abount how proxy account are displayed # TODO: no idea abount how proxy account are displayed
for a in self.document.xpath('//a[@class="mainclic"]'): for a in self.document.xpath('//a[@class="mainclic"]'):
account = Account() account = Account()
account.currency = Currency.CUR_EUR account.currency = Currency.CUR_EUR
account.id = unicode(a.find('span[@class="account-number"]').text) account.id = unicode(a.find('span[@class="account-number"]').text)
account._id = account.id
account.label = unicode(a.find('span[@class="title"]').text) account.label = unicode(a.find('span[@class="title"]').text)
balance = a.find('span[@class="solde"]/label').text balance = a.find('span[@class="solde"]/label').text
account.balance = Decimal(FrenchTransaction.clean_amount(balance)) account.balance = Decimal(FrenchTransaction.clean_amount(balance))
@ -50,4 +64,33 @@ class AccountsList(BasePage):
account.id = "LA-" + account.id account.id = "LA-" + account.id
elif "Orange" in account.label: elif "Orange" in account.label:
account.id = "LEO-" + account.id account.id = "LEO-" + account.id
jid = self.document.find('//input[@name="javax.faces.ViewState"]')
account._jid = jid.attrib['value']
yield account yield account
def get_transactions(self):
for table in self.document.xpath('//table[@cellpadding="0"]'):
try:
textdate = table.find('.//td[@class="elmt tdate"]').text_content()
except AttributeError:
continue
frenchmonth = textdate.split(' ')[1]
month = self.monthvalue[frenchmonth]
textdate = textdate.replace(' ', '')
textdate = textdate.replace(frenchmonth, '/%s/' %month)
# We use lower for compatibility with old website
textraw = table.find('.//td[@class="elmt lbl"]').text_content().strip().lower()
# The id will be rewrite
op = Transaction(1)
amount = op.clean_amount(table.xpath('.//td[starts-with(@class, "elmt amount")]')[0].text_content())
id = hashlib.md5(textdate + textraw.encode('utf-8') + amount.encode('utf-8')).hexdigest()
op.id = id
op.parse(date = date(*reversed([int(x) for x in textdate.split('/')])),
raw = textraw)
# force the use of website category
#op.category = unicode(tr.find('td[@class="op_type"]').text)
op.amount = Decimal(amount)
yield op
def islast(self):
return True