diff --git a/modules/amundi/browser.py b/modules/amundi/browser.py index 222cb8d31dda2b47d0cec2f4b79ebfffcd9f7c9c..9b5bb2d9d45a4b9579388381af770db5c41f4ad8 100644 --- a/modules/amundi/browser.py +++ b/modules/amundi/browser.py @@ -18,46 +18,34 @@ # along with weboob. If not, see . -import ssl -from .pages import LoginPage, AccountsPage, AccountHistoryPage from weboob.browser import URL, LoginBrowser, need_login from weboob.tools.json import json from weboob.exceptions import BrowserIncorrectPassword from weboob.browser.exceptions import ClientError +from .pages import LoginPage, AccountsPage, AccountHistoryPage + class AmundiBrowser(LoginBrowser): TIMEOUT = 120.0 login = URL('/psf/authenticate', LoginPage) authorize = URL('/psf/authorize', LoginPage) - accounts = URL('/psf/api/individu/positionFonds\?flagUrlFicheFonds=true&inclurePositionVide=false', AccountsPage) - account_history = URL('/psf/api/individu/operations\?valeurExterne=false&filtreStatutModeExclusion=false&statut=CPTA', AccountHistoryPage) + accounts = URL(r'/psf/api/individu/positionFonds\?flagUrlFicheFonds=true&inclurePositionVide=false', AccountsPage) + account_history = URL(r'/psf/api/individu/operations\?valeurExterne=false&filtreStatutModeExclusion=false&statut=CPTA', AccountHistoryPage) def __init__(self, website, *args, **kwargs): self.BASEURL = website super(AmundiBrowser, self).__init__(*args, **kwargs) - def prepare_request(self, req): - """ - Amundi uses TLS v1.0. - """ - preq = super(AmundiBrowser, self).prepare_request(req) - conn = self.session.adapters['https://'].get_connection(preq.url) - conn.ssl_version = ssl.PROTOCOL_TLSv1 - return preq - def do_login(self): """ Attempt to log in. Note: this method does nothing if we are already logged in. """ - assert isinstance(self.username, basestring) - assert isinstance(self.password, basestring) - try: - self.login.go(data=json.dumps({'username' : self.username, 'password' : self.password}), \ + self.login.go(data=json.dumps({'username': self.username, 'password': self.password}), headers={'Content-Type': 'application/json;charset=UTF-8'}) self.token = self.authorize.go().get_token() except ClientError: @@ -65,13 +53,15 @@ def do_login(self): @need_login def iter_accounts(self): - return self.accounts.go(headers={'X-noee-authorization': ('noeprd %s' % self.token)}).iter_accounts() + return (self.accounts.go(headers={'X-noee-authorization': ('noeprd %s' % self.token)}) + .iter_accounts()) @need_login def iter_investments(self, account): - return self.accounts.go(headers={'X-noee-authorization': ('noeprd %s' % self.token)})\ - .iter_investments(account_id=account.id) + return (self.accounts.go(headers={'X-noee-authorization': ('noeprd %s' % self.token)}) + .iter_investments(account_id=account.id)) @need_login def iter_history(self, account): - return self.account_history.go(headers={'X-noee-authorization': ('noeprd %s' % self.token)}).iter_history(account=account) + return (self.account_history.go(headers={'X-noee-authorization': ('noeprd %s' % self.token)}) + .iter_history(account=account)) diff --git a/modules/amundi/module.py b/modules/amundi/module.py index bc4d7d5395497ae326d60c3825fcb407a275b658..3a2efefd2c809384faf140871abb132c239624d7 100644 --- a/modules/amundi/module.py +++ b/modules/amundi/module.py @@ -35,59 +35,29 @@ class AmundiModule(Module, CapBankWealth): EMAIL = 'james.galt.bi@gmail.com' LICENSE = 'AGPLv3+' VERSION = '1.4' - CONFIG = BackendConfig(ValueBackendPassword('login', label='Identifiant', regexp='\d+', masked=False), - ValueBackendPassword('password', label=u"Mot de passe", regexp='\d+'), + CONFIG = BackendConfig(ValueBackendPassword('login', label='Identifiant', regexp=r'\d+', masked=False), + ValueBackendPassword('password', label=u"Mot de passe", regexp=r'\d+'), Value('website', label='Type de compte', default='ee', - choices={'ee': 'Amundi Epargne Entreprise', - 'tc': 'Amundi Tenue de Compte'})) + choices={'ee': 'Amundi Epargne Entreprise', + 'tc': 'Amundi Tenue de Compte'})) BROWSER = AmundiBrowser def create_default_browser(self): w = {'ee': 'https://www.amundi-ee.com', 'tc': 'https://epargnants.amundi-tc.com'} - return self.create_browser(w[self.config['website'].get()], self.config['login'].get(), self.config['password'].get()) + return self.create_browser(w[self.config['website'].get()], self.config['login'].get(), + self.config['password'].get()) def get_account(self, id): - """ - Get an account from its ID. - - :param id: ID of the account - :type id: :class:`str` - :rtype: :class:`Account` - :raises: :class:`AccountNotFound` - """ return find_object(self.iter_accounts(), id=id, error=AccountNotFound) - def iter_accounts(self): - """ - Iter accounts. - - :rtype: iter[:class:`Account`] - """ return self.browser.iter_accounts() - def iter_investment(self, account): - """ - Iter investment of a market account - - :param account: account to get investments - :type account: :class:`Account` - :rtype: iter[:class:`Investment`] - :raises: :class:`AccountNotFound` - """ for inv in self.browser.iter_investments(account): if inv.valuation != 0: yield inv def iter_history(self, account): - """ - Iter history of transactions on a specific account. - - :param account: account to get history - :type account: :class:`Account` - :rtype: iter[:class:`Transaction`] - :raises: :class:`AccountNotFound` - """ return self.browser.iter_history(account) diff --git a/modules/amundi/pages.py b/modules/amundi/pages.py index b56d4d2045ee116c96e47477f04df80ea3871156..2424af2e798b7ab7209b6e04b7d63dc3e2e1bb4b 100644 --- a/modules/amundi/pages.py +++ b/modules/amundi/pages.py @@ -17,6 +17,8 @@ # You should have received a copy of the GNU Affero General Public License # along with weboob. If not, see . +from __future__ import unicode_literals + from datetime import datetime from weboob.browser.elements import ItemElement, method, DictElement @@ -60,7 +62,7 @@ def obj_number(self): # just the id is a kind of company id so it can be unique on a backend but not unique on multiple backends return '%s_%s' % (Field('id')(self), self.page.browser.username) - obj_currency = u"EUR" + obj_currency = 'EUR' def obj_type(self): return self.page.ACCOUNT_TYPES.get(Dict('typeDispositif')(self), Account.TYPE_LIFE_INSURANCE) @@ -68,7 +70,7 @@ def obj_type(self): def obj_label(self): try: return Dict('libelleDispositif')(self).encode('iso-8859-2').decode('utf8') - except (UnicodeEncodeError, UnicodeDecodeError): + except UnicodeError: try: return Dict('libelleDispositif')(self).encode('latin1').decode('utf8') except UnicodeDecodeError: @@ -102,8 +104,8 @@ def obj_code_type(self): class AccountHistoryPage(LoggedPage, JsonPage): def belongs(self, instructions, account): for ins in instructions: - if 'nomDispositif' in ins and 'codeDispositif' in ins and '%s%s' % (ins['nomDispositif'], ins['codeDispositif']) == \ - '%s%s' % (account.label, account.id): + if 'nomDispositif' in ins and 'codeDispositif' in ins and '%s%s' % ( + ins['nomDispositif'], ins['codeDispositif']) == '%s%s' % (account.label, account.id): return True return False @@ -111,8 +113,9 @@ def get_amount(self, instructions, account): amount = 0 for ins in instructions: - if 'nomDispositif' in ins and 'montantNet' in ins and 'codeDispositif' in ins and '%s%s' % (ins['nomDispositif'], ins['codeDispositif']) == \ - '%s%s' % (account.label, account.id): + if ('nomDispositif' in ins and 'montantNet' in ins and 'codeDispositif' in ins + and '%s%s' % (ins['nomDispositif'], ins['codeDispositif']) + == '%s%s' % (account.label, account.id)): amount += ins['montantNet'] return CleanDecimal().filter(amount) @@ -125,21 +128,7 @@ def iter_history(self, account): tr.amount = self.get_amount(hist['instructions'], account) tr.rdate = datetime.strptime(hist['dateComptabilisation'].split('T')[0], '%Y-%m-%d') tr.date = tr.rdate - tr.label = hist['libelleOperation'] if 'libelleOperation' in hist else hist['libelleCommunication'] + tr.label = hist.get('libelleOperation') or hist['libelleCommunication'] tr.type = Transaction.TYPE_UNKNOWN - # Bypassed because we don't have the ISIN code - # tr.investments = [] - # for ins in hist['instructions']: - # inv = Investment() - # inv.code = NotAvailable - # inv.label = ins['nomFonds'] - # inv.description = ' '.join([ins['type'], ins['nomDispositif']]) - # inv.vdate = datetime.strptime(ins.get('dateVlReel', ins.get('dateVlExecution')).split('T')[ - # 0], '%Y-%m-%d') - # inv.valuation = Decimal(ins['montantNet']) - # inv.quantity = Decimal(ins['nombreDeParts']) - # inv.unitprice = inv.unitvalue = Decimal(ins['vlReel']) - # tr.investments.append(inv) - yield tr diff --git a/tools/py3-compatible.modules b/tools/py3-compatible.modules index faeeb16ffb35fd3c36ad68b3c7fdd0da64801e37..f6f603c0846f6af190b90bb63020d26835fad497 100644 --- a/tools/py3-compatible.modules +++ b/tools/py3-compatible.modules @@ -11,6 +11,7 @@ amazon ameli americanexpress anticaptcha +amundi apec arte axabanque