diff --git a/modules/wiseed/__init__.py b/modules/wiseed/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..685c111381b7c78cb4f23fd83ddaa377578d875f
--- /dev/null
+++ b/modules/wiseed/__init__.py
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+
+# Copyright(C) 2019 Vincent A
+#
+# This file is part of a weboob module.
+#
+# This weboob module is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This weboob module 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this weboob module. If not, see .
+
+from __future__ import unicode_literals
+
+
+from .module import WiseedModule
+
+
+__all__ = ['WiseedModule']
diff --git a/modules/wiseed/browser.py b/modules/wiseed/browser.py
new file mode 100644
index 0000000000000000000000000000000000000000..09632b7ec86e2acc14b7bb4d58bcdf1a21b78555
--- /dev/null
+++ b/modules/wiseed/browser.py
@@ -0,0 +1,71 @@
+# -*- coding: utf-8 -*-
+
+# Copyright(C) 2019 Vincent A
+#
+# This file is part of a weboob module.
+#
+# This weboob module is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This weboob module 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this weboob module. If not, see .
+
+from __future__ import unicode_literals
+
+from weboob.browser import LoginBrowser, need_login, URL, StatesMixin
+from weboob.capabilities.bank import Account
+
+from .pages import LoginPage, LandPage, InvestPage
+
+
+# TODO implement documents and profile
+
+class WiseedBrowser(LoginBrowser, StatesMixin):
+ BASEURL = 'https://www.wiseed.com'
+
+ login = URL('/fr/connexion', LoginPage)
+ landing = URL('/fr/projets-en-financement', LandPage)
+ invests = URL('/fr/compte/portefeuille', InvestPage)
+
+ def do_login(self):
+ self.login.go()
+ self.page.do_login(self.username, self.password)
+
+ if self.login.is_here():
+ self.page.raise_error()
+
+ assert self.landing.is_here()
+
+ @need_login
+ def iter_accounts(self):
+ self.invests.stay_or_go()
+
+ acc = Account()
+ acc.id = '_wiseed_'
+ acc.type = Account.TYPE_MARKET
+ acc.number = self.page.get_user_id()
+ acc.label = 'WiSEED'
+ acc.currency = 'EUR'
+ # unfortunately there's little data
+ acc.balance = sum(inv.valuation for inv in self.iter_investment())
+
+ return [acc]
+
+ @need_login
+ def iter_investment(self):
+ self.invests.stay_or_go()
+
+ yield self.page.get_liquidities()
+
+ for inv in self.page.iter_funded():
+ yield inv
+
+ for inv in self.page.iter_funding():
+ yield inv
diff --git a/modules/wiseed/module.py b/modules/wiseed/module.py
new file mode 100644
index 0000000000000000000000000000000000000000..480163e5da0b2ea5f16651d2b6e6f15948ca32ea
--- /dev/null
+++ b/modules/wiseed/module.py
@@ -0,0 +1,57 @@
+# -*- coding: utf-8 -*-
+
+# Copyright(C) 2019 Vincent A
+#
+# This file is part of a weboob module.
+#
+# This weboob module is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This weboob module 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this weboob module. If not, see .
+
+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 WiseedBrowser
+
+
+__all__ = ['WiseedModule']
+
+
+class WiseedModule(Module, CapBankWealth):
+ NAME = 'wiseed'
+ DESCRIPTION = 'WiSEED'
+ MAINTAINER = 'Vincent A'
+ EMAIL = 'dev@indigo.re'
+ LICENSE = 'LGPLv3+'
+ VERSION = '1.6'
+
+ BROWSER = WiseedBrowser
+
+ CONFIG = BackendConfig(
+ ValueBackendPassword('login', label='E-mail', regexp='.*@.*', masked=False),
+ 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()
diff --git a/modules/wiseed/pages.py b/modules/wiseed/pages.py
new file mode 100644
index 0000000000000000000000000000000000000000..9eb89ce9eb362a28d9dd2ada605797158f4342f2
--- /dev/null
+++ b/modules/wiseed/pages.py
@@ -0,0 +1,101 @@
+# -*- coding: utf-8 -*-
+
+# Copyright(C) 2019 Vincent A
+#
+# This file is part of a weboob module.
+#
+# This weboob module is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This weboob module 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this weboob module. If not, see .
+
+from __future__ import unicode_literals
+
+from weboob.browser.pages import LoggedPage, HTMLPage
+from weboob.browser.filters.html import TableCell
+from weboob.browser.filters.standard import CleanText, CleanDecimal, Regexp
+from weboob.browser.elements import method, ItemElement, TableElement
+from weboob.exceptions import BrowserIncorrectPassword
+from weboob.capabilities.bank import Investment
+from weboob.tools.capabilities.bank.investments import create_french_liquidity
+
+
+class LoginPage(HTMLPage):
+ def do_login(self, login, password):
+ form = self.get_form(id='recaptcha') # wtf
+ form['emailConnexion'] = login
+ form['motDePasseConnexion'] = password
+ form.submit()
+
+ def raise_error(self):
+ msg = CleanText('//div[has-class("alert-danger")]')(self.doc)
+ if 'Email ou mot de passe invalide' in msg:
+ raise BrowserIncorrectPassword(msg)
+ assert False, 'unhandled message %r' % msg
+
+
+class LandPage(LoggedPage, HTMLPage):
+ pass
+
+
+class InvestPage(LoggedPage, HTMLPage):
+ def get_user_id(self):
+ return Regexp(
+ CleanText('//span[contains(text(), "ID Client")]'),
+ r'ID Client : (\d+)'
+ )(self.doc)
+
+ def get_liquidities(self):
+ value = CleanDecimal.French(CleanText('//a[starts-with(text(),"Compte de paiement")]'))(self.doc)
+ return create_french_liquidity(value)
+
+ @method
+ class iter_funded(TableElement):
+ item_xpath = '//table[@id="portefeuilleAction"]/tbody/tr'
+
+ head_xpath = '//table[@id="portefeuilleAction"]/thead//th'
+ col_bought = 'Vous avez investi'
+ col_label = 'Investissement dans'
+ col_valuation = 'Valeur estimée à date'
+ col_diff_ratio = 'Coef. de performance intermediaire'
+
+ class item(ItemElement):
+ klass = Investment
+
+ obj_label = CleanText(TableCell('label'))
+
+ # text is "0000000000000100 100,00 €", wtf
+ obj_valuation = CleanDecimal.SI(
+ Regexp(CleanText(TableCell('valuation')), r'^000(\d+)\b')
+ )
+
+ obj_diff_ratio = CleanDecimal.SI(
+ Regexp(CleanText(TableCell('diff_ratio')), r'^000(\d+)\b')
+ )
+
+ # unitprice and unitvalue are on a dedicated page, let's forget it
+
+ @method
+ class iter_funding(TableElement):
+ item_xpath = '//table[has-class("portefeuille-liste") and not(@id)]/tbody/tr'
+
+ head_xpath = '//table[has-class("portefeuille-liste") and not(@id)]/thead//th'
+ col_label = 'Opération / Cible'
+ col_details = 'Détails'
+
+ class item(ItemElement):
+ klass = Investment
+
+ obj_label = CleanText(TableCell('label'))
+ obj_valuation = CleanDecimal.French(Regexp(
+ CleanText(TableCell('details')),
+ r'^(.*?) €', # can be 100,00 € + Frais de 0,90 €
+ ))