Get transaction history on the new site
This commit is contained in:
parent
0ea938a0c6
commit
d552e43267
2 changed files with 63 additions and 16 deletions
|
|
@ -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():
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue