fix coding style and login errors handling

This commit is contained in:
Romain Bignon 2014-04-14 16:41:54 +02:00
commit 558b94e9b9
3 changed files with 54 additions and 40 deletions

View file

@ -20,6 +20,7 @@
from weboob.capabilities.bank import ICapBank, AccountNotFound from weboob.capabilities.bank import ICapBank, AccountNotFound
from weboob.capabilities.base import find_object
from weboob.tools.backend import BaseBackend, BackendConfig from weboob.tools.backend import BaseBackend, BackendConfig
from weboob.tools.value import ValueBackendPassword, Value from weboob.tools.value import ValueBackendPassword, Value
@ -51,12 +52,7 @@ class HSBCBackend(BaseBackend, ICapBank):
yield account yield account
def get_account(self, _id): def get_account(self, _id):
with self.browser: return find_object(self.browser.get_accounts_list(), id=_id, error=AccountNotFound)
account = self.browser.get_account(_id)
if account:
return account
else:
raise AccountNotFound()
def iter_history(self, account): def iter_history(self, account):
for tr in self.browser.get_history(account): for tr in self.browser.get_history(account):

View file

@ -18,6 +18,7 @@
# along with weboob. If not, see <http://www.gnu.org/licenses/>. # along with weboob. If not, see <http://www.gnu.org/licenses/>.
import ssl
from datetime import timedelta from datetime import timedelta
from weboob.tools.date import LinearDateGuesser from weboob.tools.date import LinearDateGuesser
@ -30,22 +31,30 @@ __all__ = ['HSBC']
class HSBC(LoginBrowser): class HSBC(LoginBrowser):
VERIFY = False
BASEURL = 'https://client.hsbc.fr' BASEURL = 'https://client.hsbc.fr'
CERTHASH = '48d84a782728eeeb622e9ff721688365e24f555ae1aec49b3be33831c7fe24e6'
connection = URL('https://www.hsbc.fr/1/2/hsbc-france/particuliers/connexion', LoginPage) connection = URL(r'https://www.hsbc.fr/1/2/hsbc-france/particuliers/connexion', LoginPage)
login = URL('https://www.hsbc.fr/1/*', LoginPage) login = URL(r'https://www.hsbc.fr/1/*', LoginPage)
cptPage = URL('/cgi-bin/emcgi.*\&CPT_IdPrestation.*', cptPage = URL(r'/cgi-bin/emcgi.*\&CPT_IdPrestation.*',
'/cgi-bin/emcgi.*\&Ass_IdPrestation.*', r'/cgi-bin/emcgi.*\&Ass_IdPrestation.*',
CPTOperationPage) CPTOperationPage)
cbPage = URL('/cgi-bin/emcgi.*\&CB_IdPrestation.*', cbPage = URL(r'/cgi-bin/emcgi.*\&CB_IdPrestation.*',
CBOperationPage) CBOperationPage)
accounts = URL('/cgi-bin/emcgi', AccountsPage) accounts = URL(r'/cgi-bin/emcgi', AccountsPage)
def __init__(self, username, password, secret, *args, **kwargs): def __init__(self, username, password, secret, *args, **kwargs):
self.secret = secret self.secret = secret
LoginBrowser.__init__(self, username, password, *args, **kwargs) LoginBrowser.__init__(self, username, password, *args, **kwargs)
def prepare_request(self, req):
preq = super(HSBC, self).prepare_request(req)
conn = self.session.adapters['https://'].get_connection(preq.url)
conn.ssl_version = ssl.PROTOCOL_TLSv1
return preq
def home(self): def home(self):
return self.login.go() return self.login.go()
@ -58,7 +67,7 @@ class HSBC(LoginBrowser):
raise BrowserIncorrectPassword() raise BrowserIncorrectPassword()
self.location(no_secure_key_link) self.location(no_secure_key_link)
self.page.login_w_secure(self.login, self.password, self.secret) self.page.login_w_secure(self.password, self.secret)
self.page.useless_form() self.page.useless_form()
home_url = self.page.get_frame() home_url = self.page.get_frame()
@ -90,7 +99,7 @@ class HSBC(LoginBrowser):
if self.cbPage.is_here(): if self.cbPage.is_here():
guesser = LinearDateGuesser(date_max_bump=timedelta(45)) guesser = LinearDateGuesser(date_max_bump=timedelta(45))
return self.pagination(lambda: self.page.get_history(date_guesser=guesser)) return self.page.get_history(date_guesser=guesser)
else: else:
return self._get_history() return self._get_history()

View file

@ -20,25 +20,26 @@
from urlparse import urlparse, parse_qs from urlparse import urlparse, parse_qs
import re import re
from weboob.tools.browser2.page import HTMLPage, method, ListElement, ItemElement, SkipItem, LoggedPage
from weboob.tools.browser2.filters import Filter, Env, CleanText, CleanDecimal, Link, Field, DateGuesser, TableCell
from weboob.capabilities import NotAvailable from weboob.capabilities import NotAvailable
from weboob.capabilities.bank import Account from weboob.capabilities.bank import Account
from weboob.tools.capabilities.bank.transactions import FrenchTransaction from weboob.tools.capabilities.bank.transactions import FrenchTransaction
class Transaction(FrenchTransaction): from weboob.tools.browser import BrowserIncorrectPassword
PATTERNS = [(re.compile('^VIR(EMENT)? (?P<text>.*)'), FrenchTransaction.TYPE_TRANSFER), from weboob.tools.browser2.page import HTMLPage, method, ListElement, ItemElement, SkipItem, LoggedPage, pagination
(re.compile('^PRLV (?P<text>.*)'), FrenchTransaction.TYPE_ORDER), from weboob.tools.browser2.filters import Filter, Env, CleanText, CleanDecimal, Link, Field, DateGuesser, TableCell
(re.compile('^(?P<text>.*) CARTE \d+ PAIEMENT CB\s+(?P<dd>\d{2})(?P<mm>\d{2}) ?(.*)$'),
FrenchTransaction.TYPE_CARD),
(re.compile('^RETRAIT DAB (?P<dd>\d{2})(?P<mm>\d{2}) (?P<text>.*) CARTE [\*\d]+'),
FrenchTransaction.TYPE_WITHDRAWAL),
(re.compile('^CHEQUE( (?P<text>.*))?$'), FrenchTransaction.TYPE_CHECK),
(re.compile('^(F )?COTIS\.? (?P<text>.*)'),FrenchTransaction.TYPE_BANK),
(re.compile('^(REMISE|REM CHQ) (?P<text>.*)'),FrenchTransaction.TYPE_DEPOSIT),
]
_is_coming = False
class Transaction(FrenchTransaction):
PATTERNS = [(re.compile(r'^VIR(EMENT)? (?P<text>.*)'), FrenchTransaction.TYPE_TRANSFER),
(re.compile(r'^PRLV (?P<text>.*)'), FrenchTransaction.TYPE_ORDER),
(re.compile(r'^CB (?P<text>.*)\s+(?P<dd>\d+)/(?P<mm>\d+)\s*(?P<loc>.*)'),
FrenchTransaction.TYPE_CARD),
(re.compile(r'^DAB (?P<dd>\d{2})/(?P<mm>\d{2}) ((?P<HH>\d{2})H(?P<MM>\d{2}) )?(?P<text>.*?)( CB N°.*)?$'),
FrenchTransaction.TYPE_WITHDRAWAL),
(re.compile(r'^CHEQUE$'), FrenchTransaction.TYPE_CHECK),
(re.compile(r'^COTIS\.? (?P<text>.*)'), FrenchTransaction.TYPE_BANK),
(re.compile(r'^REMISE (?P<text>.*)'), FrenchTransaction.TYPE_DEPOSIT),
]
class AccountsPage(LoggedPage, HTMLPage): class AccountsPage(LoggedPage, HTMLPage):
def get_frame(self): def get_frame(self):
@ -114,6 +115,7 @@ class Pagination(object):
class CBOperationPage(LoggedPage, HTMLPage): class CBOperationPage(LoggedPage, HTMLPage):
@pagination
@method @method
class get_history(Pagination, Transaction.TransactionsElement): class get_history(Pagination, Transaction.TransactionsElement):
head_xpath = '//table//tr/th' head_xpath = '//table//tr/th'
@ -127,18 +129,22 @@ class CBOperationPage(LoggedPage, HTMLPage):
class CPTOperationPage(LoggedPage, HTMLPage): class CPTOperationPage(LoggedPage, HTMLPage):
def get_history(self): def get_history(self):
for script in self.doc.xpath('//script'): for script in self.doc.xpath('//script'):
if script.text is None or script.text.find('\nCL(0') < 0: if script.text is None or script.text.find('\nCL(0') < 0:
continue continue
for m in re.finditer(r"CL\((\d+),'(.+)','(.+)','(.+)','([\d -\.,]+)',('([\d -\.,]+)',)?'\d+','\d+','[\w\s]+'\);", script.text, flags=re.MULTILINE): for m in re.finditer(r"CL\((\d+),'(.+)','(.+)','(.+)','([\d -\.,]+)',('([\d -\.,]+)',)?'\d+','\d+','[\w\s]+'\);", script.text, flags=re.MULTILINE):
op = Transaction(m.group(1)) op = Transaction(m.group(1))
op.parse(date=m.group(3), raw=re.sub(u'[ ]+', u' ', m.group(4).replace(u'\n', u' '))) op.parse(date=m.group(3), raw=re.sub(u'[ ]+', u' ', m.group(4).replace(u'\n', u' ')))
op.set_amount(m.group(5)) op.set_amount(m.group(5))
op._coming = (re.match('\d+/\d+/\d+', m.group(2)) is None) op._coming = (re.match(r'\d+/\d+/\d+', m.group(2)) is None)
yield op yield op
class LoginPage(HTMLPage): class LoginPage(HTMLPage):
def on_load(self):
for message in self.doc.getroot().cssselect('div.csPanelErrors, div.csPanelAlert'):
raise BrowserIncorrectPassword(CleanText('.')(message))
def login(self, login): def login(self, login):
form = self.get_form(nr=2) form = self.get_form(nr=2)
form['userid'] = login form['userid'] = login
@ -152,12 +158,15 @@ class LoginPage(HTMLPage):
else: else:
return a.attrib['href'] return a.attrib['href']
def login_w_secure(self, login, password, secret): def login_w_secure(self, password, secret):
form = self.get_form(nr=0) form = self.get_form(nr=0)
form['memorableAnswer'] = secret form['memorableAnswer'] = secret
inputs = self.doc.xpath(u'//input[starts-with(@id, "keyrcc_password_first")]') inputs = self.doc.xpath(u'//input[starts-with(@id, "keyrcc_password_first")]')
split_pass = u'' split_pass = u''
for i,inpu in enumerate(inputs): if len(password) != len(inputs):
raise BrowserIncorrectPassword('Your password must be %d chars long' % len(inputs))
for i, inpu in enumerate(inputs):
#The good field are 1,2,3 and the bad one are 11,12,21,23,24,31 and so one #The good field are 1,2,3 and the bad one are 11,12,21,23,24,31 and so one
if int(inpu.attrib['id'].split('first')[1]) < 10: if int(inpu.attrib['id'].split('first')[1]) < 10:
split_pass += password[i] split_pass += password[i]