Support transfer with browser2

This commit is contained in:
Florent 2014-03-28 14:15:45 +01:00
commit 2738538fb6
3 changed files with 81 additions and 101 deletions

View file

@ -80,23 +80,21 @@ class INGBackend(BaseBackend, ICapBank, ICapBill):
yield history yield history
def iter_transfer_recipients(self, account): def iter_transfer_recipients(self, account):
with self.browser: if not isinstance(account, Account):
if not isinstance(account, Account): account = self.get_account(account)
account = self.get_account(account) for recipient in self.browser.get_recipients(account):
for recipient in self.browser.get_recipients(account): yield recipient
yield recipient
def transfer(self, account, recipient, amount, reason): def transfer(self, account, recipient, amount, reason):
with self.browser: if not reason:
if not reason: raise UserError('Reason is mandatory to do a transfer on ING website')
raise UserError('Reason is mandatory to do a transfer on ING website') if not isinstance(account, Account):
if not isinstance(account, Account): account = self.get_account(account)
account = self.get_account(account) if not isinstance(recipient, Recipient):
if not isinstance(recipient, Recipient): # Remove weboob identifier prefix (LA-, CC-...)
# Remove weboob identifier prefix (LA-, CC-...) if "-" in recipient:
if "-" in recipient: recipient = recipient.split('-')[1]
recipient = recipient.split('-')[1] return self.browser.transfer(account, recipient, amount, reason)
return self.browser.transfer(account, recipient, amount, reason)
def iter_investment(self, account): def iter_investment(self, account):
if not isinstance(account, Account): if not isinstance(account, Account):

View file

@ -145,16 +145,16 @@ class IngBrowser(LoginBrowser):
} }
self.accountspage.go(data=data) self.accountspage.go(data=data)
@need_login
def get_recipients(self, account): def get_recipients(self, account):
if not self.is_on_page(TransferPage): self.transferpage.stay_or_go()
self.location(self.transferpage)
if self.page.ischecked(account): if self.page.ischecked(account):
return self.page.get_recipients() return self.page.get_recipients()
else: else:
# It is hard to check the box and to get the real list. # It is hard to check the box and to get the real list.
# We try an alternative way like normal users # We try an alternative way like normal users
self.get_history(account.id).next() self.get_history(account.id).next()
self.location(self.dotransferpage) self.transferpage.stay_or_go()
return self.page.get_recipients() return self.page.get_recipients()
def transfer(self, account, recipient, amount, reason): def transfer(self, account, recipient, amount, reason):
@ -168,15 +168,14 @@ class IngBrowser(LoginBrowser):
recipient = destination recipient = destination
break break
if found: if found:
self.openurl(self.transferpage, self.transferpage.open(data=self.page.buildonclick(recipient, account))
self.page.buildonclick(recipient, account))
self.page.transfer(recipient, amount, reason) self.page.transfer(recipient, amount, reason)
self.location(self.valtransferpage) self.valtransferpage.go()
if not self.is_on_page(TransferConfirmPage): if not self.valtransferpage.is_here():
raise TransferError("Invalid transfer (no confirmation page)") raise TransferError("Invalid transfer (no confirmation page)")
else: else:
self.page.confirm(self.password) self.page.confirm(self.password)
self.location(self.valtransferpage) self.valtransferpage.go()
return self.page.recap() return self.page.recap()
else: else:
raise TransferError('Recipient not found') raise TransferError('Recipient not found')

View file

@ -22,21 +22,18 @@ from decimal import Decimal
from weboob.tools.capabilities.bank.transactions import FrenchTransaction from weboob.tools.capabilities.bank.transactions import FrenchTransaction
from weboob.tools.captcha.virtkeyboard import VirtKeyboardError from weboob.tools.captcha.virtkeyboard import VirtKeyboardError
from weboob.capabilities.bank import Recipient, AccountNotFound, Transfer from weboob.capabilities.bank import Recipient, AccountNotFound, Transfer
from weboob.tools.browser import BasePage, BrokenPageError from weboob.tools.browser2.page import HTMLPage, LoggedPage
from weboob.tools.mech import ClientForm from weboob.tools.browser import BrokenPageError
from .login import INGVirtKeyboard from .login import INGVirtKeyboard
from logging import error from logging import error
__all__ = ['TransferPage'] __all__ = ['TransferPage']
class TransferPage(BasePage): class TransferPage(LoggedPage, HTMLPage):
def on_loaded(self):
pass
def get_recipients(self): def get_recipients(self):
# First, internals recipients # First, internals recipients
table = self.document.xpath('//table[@id="transfer_form:receiptAccount"]') table = self.doc.xpath('//table[@id="transfer_form:receiptAccount"]')
for tr in table[0].xpath('tbody/tr'): for tr in table[0].xpath('tbody/tr'):
tds = tr.xpath('td') tds = tr.xpath('td')
id = tds[0].xpath('input')[0].attrib['value'] id = tds[0].xpath('input')[0].attrib['value']
@ -50,7 +47,7 @@ class TransferPage(BasePage):
yield recipient yield recipient
# Second, externals recipients # Second, externals recipients
select = self.document.xpath('//select[@id="transfer_form:externalAccounts"]') select = self.doc.xpath('//select[@id="transfer_form:externalAccounts"]')
if len(select) > 0: if len(select) > 0:
recipients = select[0].xpath('option') recipients = select[0].xpath('option')
recipients.pop(0) recipients.pop(0)
@ -66,66 +63,55 @@ class TransferPage(BasePage):
# remove prefix (CC-, LA-, ...) # remove prefix (CC-, LA-, ...)
if "-" in id: if "-" in id:
id = id.split('-')[1] id = id.split('-')[1]
option = self.document.xpath('//input[@value="%s"]' % id) option = self.doc.xpath('//input[@value="%s"]' % id)
if len(option) == 0: if len(option) == 0:
raise AccountNotFound() raise AccountNotFound()
else: else:
option = option[0] option = option[0]
try: try:
if option.attrib["checked"] == "checked": return option.attrib["checked"] == "checked"
return True
else:
return False
except: except:
return False return False
def transfer(self, recipient, amount, reason): def transfer(self, recipient, amount, reason):
self.browser.select_form("transfer_form") form = self.get_form(name="transfer_form")
self.browser.set_all_readonly(False) form.pop('transfer_form:_link_hidden_')
for a in self.browser.controls[:]: form.pop('transfer_form:j_idcl')
#for label in a.get_labels(): form['AJAXREQUEST'] = "_viewRoot"
if "transfer_form:_link_hidden_" in str(a) or "transfer_form:j_idcl" in str(a): form['AJAX:EVENTS_COUNT'] = "1"
self.browser.controls.remove(a) form['transfer_form:transferMotive'] = reason
if "transfer_form:valide" in str(a): form["transfer_form:valide"] = "transfer_form:valide"
self.browser.controls.remove(a) form["transfer_form:validateDoTransfer"] = "needed"
self.browser.controls.append(ClientForm.TextControl('text', form["transfer_form:transferAmount"] = str(amount)
'AJAXREQUEST', {'value': "_viewRoot"}))
self.browser.controls.append(ClientForm.TextControl('text',
'AJAX:EVENTS_COUNT', {'value': "1"}))
self.browser['transfer_form:transferMotive'] = reason.encode('ISO-8859-1')
self.browser.controls.append(ClientForm.TextControl('text', 'transfer_form:valide', {'value': "transfer_form:valide"}))
self.browser['transfer_form:validateDoTransfer'] = "needed"
self.browser['transfer_form:transferAmount'] = str(amount)
if recipient._type == "int": if recipient._type == "int":
self.browser['transfer_recipient_radio'] = [recipient.id] form['transfer_recipient_radio'] = recipient.id
else: else:
self.browser['transfer_form:externalAccounts'] = [recipient.id] form['transfer_form:externalAccounts'] = recipient.id
self.browser.submit() form.submit()
def buildonclick(self, recipient, account): def buildonclick(self, recipient, account):
javax = self.document.xpath('//input[@id="javax.faces.ViewState"]')[0].attrib['value'] javax = self.doc.xpath('//input[@id="javax.faces.ViewState"]')[0].attrib['value']
if recipient._type == "ext": if recipient._type == "ext":
select = self.document.xpath('//select[@id="transfer_form:externalAccounts"]')[0] select = self.doc.xpath('//select[@id="transfer_form:externalAccounts"]')[0]
onclick = select.attrib['onchange'] onclick = select.attrib['onchange']
params = onclick.split(',')[3].split('{')[1] params = onclick.split(',')[3].split('{')[1]
idparam = params.split("'")[1] idparam = params.split("'")[1]
param = params.split("'")[3] param = params.split("'")[3]
request = self.browser.buildurl('', ("AJAXREQUEST", "transfer_form:transfer_radios_form"), request = {"AJAXREQUEST": "transfer_form:transfer_radios_form",
("transfer_form:generalMessages", ""), "transfer_form:generalMessages": "",
("transfer_issuer_radio", account.id[3:]), "transfer_issuer_radio": account.id[3:],
("transfer_form:externalAccounts", recipient.id), "transfer_form:externalAccounts": recipient.id,
("transfer_date", 0), "transfer_date": "0",
("transfer_form:transferAmount", ""), "transfer_form:transferAmount": "",
("transfer_form:transferMotive", ""), "transfer_form:transferMotive": "",
("transfer_form:validateDoTransfer", "needed"), "transfer_form:validateDoTransfer": "needed",
("transfer_form", "transfer_form"), "transfer_form": "transfer_form",
("autoScrol", ""), "autoScrol": "",
("javax.faces.ViewState", javax), "javax.faces.ViewState": javax,
(idparam, param)) idparam: param}
request = request[1:] # remove the "?"
return request return request
elif recipient._type == "int": elif recipient._type == "int":
for input in self.document.xpath('//input[@value=%s]' % recipient.id): for input in self.doc.xpath('//input[@value=%s]' % recipient.id):
if input.attrib['name'] == "transfer_recipient_radio": if input.attrib['name'] == "transfer_recipient_radio":
onclick = input.attrib['onclick'] onclick = input.attrib['onclick']
break break
@ -133,23 +119,22 @@ class TransferPage(BasePage):
params = onclick.split(',')[3].split('{')[1] params = onclick.split(',')[3].split('{')[1]
idparam = params.split("'")[1] idparam = params.split("'")[1]
param = params.split("'")[3] param = params.split("'")[3]
request = self.browser.buildurl('', ("AJAXREQUEST", "transfer_form:transfer_radios_form"), request = {"AJAXREQUEST": "transfer_form:transfer_radios_form",
('transfer_issuer_radio', account.id[3:]), 'transfer_issuer_radio': account.id[3:],
("transfer_recipient_radio", recipient.id), "transfer_recipient_radio": recipient.id,
("transfer_form:externalAccounts", "na"), "transfer_form:externalAccounts": "na",
("transfer_date", 0), "transfer_date": 0,
("transfer_form:transferAmount", ""), "transfer_form:transferAmount": "",
("transfer_form:transferMotive", ""), "transfer_form:transferMotive": "",
("transfer_form:validateDoTransfer", "needed"), "transfer_form:validateDoTransfer": "needed",
("transfer_form", "transfer_form"), "transfer_form": "transfer_form",
("autoScroll", ""), "autoScroll": "",
("javax.faces.ViewState", javax), "javax.faces.ViewState": javax,
(idparam, param)) idparam: param}
request = request[1:]
return request return request
class TransferConfirmPage(BasePage): class TransferConfirmPage(HTMLPage):
def on_loaded(self): def on_loaded(self):
pass pass
@ -160,14 +145,14 @@ class TransferConfirmPage(BasePage):
error("Error: %s" % err) error("Error: %s" % err)
return return
realpasswd = "" realpasswd = ""
span = self.document.find('//span[@id="digitpadtransfer"]') span = self.doc.find('//span[@id="digitpadtransfer"]')
i = 0 i = 0
for font in span.getiterator('font'): for font in span.getiterator('font'):
if font.attrib.get('class') == "vide": if font.attrib.get('class') == "vide":
realpasswd += password[i] realpasswd += password[i]
i += 1 i += 1
confirmform = None confirmform = None
divform = self.document.xpath('//div[@id="transfer_panel"]')[0] divform = self.doc.xpath('//div[@id="transfer_panel"]')[0]
for form in divform.xpath('./form'): for form in divform.xpath('./form'):
try: try:
if form.attrib['name'][0:4] == "j_id": if form.attrib['name'][0:4] == "j_id":
@ -179,26 +164,24 @@ class TransferConfirmPage(BasePage):
raise BrokenPageError('Unable to find confirm form') raise BrokenPageError('Unable to find confirm form')
formname = confirmform.attrib['name'] formname = confirmform.attrib['name']
self.browser.logger.debug('We are looking for : ' + realpasswd) self.browser.logger.debug('We are looking for : ' + realpasswd)
self.browser.select_form(formname)
self.browser.set_all_readonly(False) form = self.get_form(name=formname)
for a in self.browser.controls[:]: for elem in form:
if "_link_hidden_" in str(a) or "j_idcl" in str(a): if "_link_hidden_" in elem or "j_idcl" in elem:
self.browser.controls.remove(a) form.pop(elem)
coordinates = vk.get_string_code(realpasswd) coordinates = vk.get_string_code(realpasswd)
self.browser.logger.debug("Coordonates: " + coordinates) self.browser.logger.debug("Coordonates: " + coordinates)
self.browser.controls.append(ClientForm.TextControl('text', form['AJAXREQUEST'] = '_viewRoot'
'AJAXREQUEST', {'value': '_viewRoot'})) form['%s:mrgtransfer' % formname] = '%s:mrgtransfer' % formname
self.browser.controls.append(ClientForm.TextControl( form['%s:mrltransfer' % formname] = coordinates
'text', '%s:mrgtransfer' % formname, form.submit()
{'value': '%s:mrgtransfer' % formname}))
self.browser['%s:mrltransfer' % formname] = coordinates
self.browser.submit(nologin=True)
def recap(self): def recap(self):
if len(self.document.xpath('//p[@class="alert alert-success"]')) == 0: if len(self.doc.xpath('//p[@class="alert alert-success"]')) == 0:
raise BrokenPageError('Unable to find confirmation') raise BrokenPageError('Unable to find confirmation')
div = self.document.find( div = self.doc.find(
'//div[@class="encadre transfert-validation"]') '//div[@class="encadre transfert-validation"]')
transfer = Transfer(0) transfer = Transfer(0)
transfer.amount = Decimal(FrenchTransaction.clean_amount( transfer.amount = Decimal(FrenchTransaction.clean_amount(