ntome
Builds for 1 pipeline failed in 3 minutes 50 seconds

[nalo] new CapBankWealth module

# -*- coding: utf-8 -*-
# Copyright(C) 2018 Vincent A
#
# This file is part of weboob.
#
# weboob is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# weboob 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from __future__ import unicode_literals
from .module import NaloModule
__all__ = ['NaloModule']
# -*- coding: utf-8 -*-
# Copyright(C) 2018 Vincent A
#
# This file is part of weboob.
#
# weboob is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# weboob 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from __future__ import unicode_literals
from weboob.browser import LoginBrowser, need_login, URL
from weboob.capabilities.bank import Investment
from .pages import LoginPage, AccountsPage, AccountPage, InvestPage
class NaloBrowser(LoginBrowser):
BASEURL = 'https://nalo.fr'
login = URL(r'/api/v1/login', LoginPage)
accounts = URL(r'/api/v1/projects/mine/without_details', AccountsPage)
history = URL(r'/api/v1/projects/(?P<id>\d+)/history')
account = URL(r'/api/v1/projects/(?P<id>\d+)', AccountPage)
invests = URL(r'https://app.nalo.fr/scripts/data/data.json', InvestPage)
token = None
def do_login(self):
self.login.go(json={
'email': self.username,
'password': self.password,
'userToken': False,
})
self.token = self.page.get_token()
def build_request(self, *args, **kwargs):
if 'json' in kwargs:
kwargs.setdefault('headers', {})['Accept'] = 'application/json'
if self.token:
kwargs.setdefault('headers', {})['Authorization'] = 'Token %s' % self.token
return super(NaloBrowser, self).build_request(*args, **kwargs)
@need_login
def iter_accounts(self):
self.accounts.go()
return self.page.iter_accounts()
@need_login
def iter_history(self, account):
self.history.go(id=account.id)
return self.page.iter_history()
@need_login
def iter_investment(self, account):
self.account.go(id=account.id)
key = self.page.get_invest_key()
self.invests.go()
data = self.page.get_invest(*key)
for item in data:
inv = Investment()
inv.code = item['isin']
inv.label = item['name']
inv.portfolio_share = item['share']
inv.valuation = account.balance * inv.portfolio_share
yield inv
# -*- coding: utf-8 -*-
# Copyright(C) 2018 Vincent A
#
# This file is part of weboob.
#
# weboob is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# weboob 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from __future__ import unicode_literals
from weboob.tools.backend import Module, BackendConfig
from weboob.tools.value import ValueBackendPassword
from weboob.capabilities.bank import CapBankWealth
from .browser import NaloBrowser
__all__ = ['NaloModule']
class NaloModule(Module, CapBankWealth):
NAME = 'nalo'
DESCRIPTION = 'Nalo'
MAINTAINER = 'Vincent A'
EMAIL = 'dev@indigo.re'
LICENSE = 'AGPLv3+'
VERSION = '1.4'
BROWSER = NaloBrowser
CONFIG = BackendConfig(
ValueBackendPassword('login', label='E-mail', masked=False, regexp='.+@.+'),
ValueBackendPassword('password', label='Mot de passe'),
)
def create_default_browser(self):
return self.create_browser(self.config['login'].get(), self.config['password'].get())
def iter_accounts(self):
return self.browser.iter_accounts()
def iter_investment(self, account):
return self.browser.iter_investment(account)
# -*- coding: utf-8 -*-
# Copyright(C) 2018 Vincent A
#
# This file is part of weboob.
#
# weboob is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# weboob 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from __future__ import unicode_literals
from decimal import Decimal
from weboob.browser.pages import LoggedPage, JsonPage
from weboob.browser.elements import method, DictElement, ItemElement
from weboob.browser.filters.json import Dict
from weboob.browser.filters.standard import Eval
from weboob.capabilities.bank import Account
def float_to_decimal(v):
return Decimal(str(v))
class LoginPage(JsonPage):
def get_token(self):
return self.doc['detail']['token']
class AccountsPage(LoggedPage, JsonPage):
ENCODING = 'utf-8' # chardet is shit
@method
class iter_accounts(DictElement):
item_xpath = 'detail'
class item(ItemElement):
klass = Account
obj_id = Eval(str, Dict('id'))
obj_label = Dict('name')
obj_balance = Eval(float_to_decimal, Dict('current_value'))
obj_valuation_diff = Eval(float_to_decimal, Dict('absolute_performance'))
obj_currency = 'EUR'
obj_type = Account.TYPE_LIFE_INSURANCE
class AccountPage(LoggedPage, JsonPage):
def get_invest_key(self):
return self.doc['detail']['project_kind'], self.doc['detail']['risk_level']
def get_kind(self):
return self.doc['detail']['project_kind']
def get_risk(self):
return self.doc['detail']['risk_level']
class HistoryPage(LoggedPage, JsonPage):
pass
class InvestPage(LoggedPage, JsonPage):
ENCODING = 'utf-8'
def get_invest(self, kind, risk):
for pk in self.doc['portfolios']:
if pk['kind'] == kind:
break
else:
assert False
for p in pk['target_portfolios']:
if p['risk_id'] == risk:
break
else:
assert False
for line in p['lines']:
yield {
'isin': line['isin'],
'name': line['name'],
'share': float_to_decimal(line['weight']) / 100,
}
......@@ -96,6 +96,7 @@ meteofrance
monster
myfoncia
n26
nalo
nectarine
nova
oney
......