diff --git a/weboob/backends/lcl/__init__.py b/weboob/backends/lcl/__init__.py new file mode 100644 index 00000000..52159f52 --- /dev/null +++ b/weboob/backends/lcl/__init__.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2010 Romain Bignon +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, version 3 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +from .backend import LCLBackend + +__all__ = ['LCLBackend'] diff --git a/weboob/backends/lcl/backend.py b/weboob/backends/lcl/backend.py new file mode 100644 index 00000000..13e42a8c --- /dev/null +++ b/weboob/backends/lcl/backend.py @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2010 Romain Bignon +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, version 3 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +from weboob.capabilities.bank import ICapBank, AccountNotFound +from weboob.tools.backend import BaseBackend + +from .browser import LCLBrowser + + +__all__ = ['LCLBackend'] + + +class LCLBackend(BaseBackend, ICapBank): + NAME = 'lcl' + MAINTAINER = 'Romain Bignon' + EMAIL = 'romain@peerfuse.org' + VERSION = '0.2' + DESCRIPTION = 'Credit Agricole french bank\'s website' + LICENSE = 'GPLv3' + CONFIG = {'login': BaseBackend.ConfigField(description='Account ID'), + 'password': BaseBackend.ConfigField(description='Password of account', is_masked=True), + 'agency': BaseBackend.ConfigField(description='Agency code', regexp='^\d{1,3}$'), + } + BROWSER = LCLBrowser + + def create_default_browser(self): + return self.create_browser(self.config['agency'], self.config['login'], self.config['password']) + + def iter_accounts(self): + for account in self.browser.get_accounts_list(): + yield account + + def get_account(self, _id): + try: + _id = long(_id) + except ValueError: + raise AccountNotFound() + else: + account = self.browser.get_account(_id) + if account: + return account + else: + raise AccountNotFound() + + def iter_operations(self, account): + """ TODO Not supported yet """ + return iter([]) + + def iter_history(self, account): + """ TODO Not supported yet """ + return iter([]) diff --git a/weboob/backends/lcl/browser.py b/weboob/backends/lcl/browser.py new file mode 100644 index 00000000..ab0541c6 --- /dev/null +++ b/weboob/backends/lcl/browser.py @@ -0,0 +1,76 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2010 Romain Bignon +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, version 3 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +from weboob.tools.browser import BaseBrowser, BrowserIncorrectPassword + +from .pages import LoginPage, LoginErrorPage, AccountsPage + + +__all__ = ['LCLBrowser'] + + +# Browser +class LCLBrowser(BaseBrowser): + PROTOCOL = 'https' + DOMAIN = 'particuliers.secure.lcl.fr' + ENCODING = 'utf-8' + USER_AGENT = 'Wget/1.11.4' + PAGES = {'https://particuliers.secure.lcl.fr/index.html': LoginPage, + 'https://particuliers.secure.lcl.fr/everest/UWBI/UWBIAccueil\?DEST=IDENTIFICATION': LoginErrorPage, + 'https://particuliers.secure.lcl.fr/outil/UWSP/Synthese/accesSynthese': AccountsPage + } + is_logging = False + + def __init__(self, agency, *args, **kwargs): + self.agency = agency + BaseBrowser.__init__(self, *args, **kwargs) + + def is_logged(self): + return self.page and not self.is_on_page(LoginPage) + + def login(self): + assert isinstance(self.username, basestring) + assert isinstance(self.password, basestring) + + if not self.is_on_page(LoginPage): + self.home() + + self.page.login(self.agency, self.username, self.password) + + if not self.is_logged() or self.is_on_page(LoginErrorPage): + raise BrowserIncorrectPassword() + + def get_accounts_list(self): + if not self.is_on_page(AccountsPage): + self.home() + return self.page.get_list() + + def get_account(self, id): + assert isinstance(id, (int, long)) + + l = self.get_accounts_list() + for a in l: + if a.id == id: + return a + + return None + + #def get_coming_operations(self, account): + # if not self.is_on_page(AccountComing) or self.page.account.id != account.id: + # self.location('/NS_AVEEC?ch4=%s' % account.link_id) + # return self.page.get_operations() diff --git a/weboob/backends/lcl/pages.py b/weboob/backends/lcl/pages.py new file mode 100644 index 00000000..27fde768 --- /dev/null +++ b/weboob/backends/lcl/pages.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2010 Romain Bignon +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, version 3 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +from weboob.tools.browser import BasePage + +class LoginPage(BasePage): + def login(self, agency, login, passwd): + self.browser.select_form(nr=0) + self.browser['agenceId'] = agency + self.browser['compteId'] = login + self.browser['CodeId'] = passwd + self.browser.submit() + +class LoginErrorPage(BasePage): + pass + +class AccountsPage(BasePage): + def get_list(self): + raise NotImplementedError() diff --git a/weboob/backends/lcl/test.py b/weboob/backends/lcl/test.py new file mode 100644 index 00000000..29c7a813 --- /dev/null +++ b/weboob/backends/lcl/test.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2010 Romain Bignon +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, version 3 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +from weboob.tools.test import BackendTest + +class LCLtTest(BackendTest): + BACKEND = 'lcl' + + def test_lcl(self): + list(self.backend.iter_accounts())