From 58bd6532c58cb3c517f8f8d3ac24d1f922b2f063 Mon Sep 17 00:00:00 2001 From: Vincent A Date: Tue, 14 Jul 2020 15:57:13 +0200 Subject: [PATCH] [enercoop] new CapDocument module TODO implement for a single subscription --- modules/enercoop/__init__.py | 26 ++++++++ modules/enercoop/browser.py | 80 ++++++++++++++++++++++ modules/enercoop/favicon.png | Bin 0 -> 10544 bytes modules/enercoop/module.py | 65 ++++++++++++++++++ modules/enercoop/pages.py | 124 +++++++++++++++++++++++++++++++++++ modules/enercoop/test.py | 43 ++++++++++++ 6 files changed, 338 insertions(+) create mode 100644 modules/enercoop/__init__.py create mode 100644 modules/enercoop/browser.py create mode 100644 modules/enercoop/favicon.png create mode 100644 modules/enercoop/module.py create mode 100644 modules/enercoop/pages.py create mode 100644 modules/enercoop/test.py diff --git a/modules/enercoop/__init__.py b/modules/enercoop/__init__.py new file mode 100644 index 0000000000..24b5bab946 --- /dev/null +++ b/modules/enercoop/__init__.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2020 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 EnercoopModule + + +__all__ = ['EnercoopModule'] diff --git a/modules/enercoop/browser.py b/modules/enercoop/browser.py new file mode 100644 index 0000000000..8cc7a6b270 --- /dev/null +++ b/modules/enercoop/browser.py @@ -0,0 +1,80 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2020 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 . + +# flake8: compatible + +from __future__ import unicode_literals + +from weboob.browser import LoginBrowser, URL, need_login + +from .pages import BillsPage, ProfilePage + + +class EnercoopBrowser(LoginBrowser): + BASEURL = 'https://espace-client.enercoop.fr' + + login = URL('/login') + bills = URL( + r'/mon-espace/factures/', + r'/mon-espace/factures/\?c=(?P\d+)', + BillsPage + ) + + profile = URL( + r'/mon-espace/compte/', + r'/mon-espace/compte/\?c=(?P\d+)', + ProfilePage + ) + + def do_login(self): + self.login.go(data={ + 'email': self.username, + 'password': self.password, + }) + + def export_session(self): + return { + **super().export_session(), + 'url': self.bills.build(), + } + + @need_login + def iter_subscription(self): + self.bills.go() + subs = {sub.id: sub for sub in self.page.iter_other_subscriptions()} + if subs: + self.bills.go(id=next(iter(subs))) + subs.update({sub.id: sub for sub in self.page.iter_other_subscriptions()}) + + for sub in subs: + self.profile.go(id=sub) + self.page.fill_sub(subs[sub]) + + return subs.values() + + raise NotImplementedError("how to get info when no selector?") + + @need_login + def iter_documents(self, id): + self.bills.go(id=id) + return self.page.iter_documents() + + @need_login + def download_document(self, document): + return self.open(document.url).content diff --git a/modules/enercoop/favicon.png b/modules/enercoop/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..49969fe89054178cd11d2b9056a07a02e6f49c5a GIT binary patch literal 10544 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 LJV2DIT88~UBA3K_ literal 0 HcmV?d00001 diff --git a/modules/enercoop/module.py b/modules/enercoop/module.py new file mode 100644 index 0000000000..194767f2b5 --- /dev/null +++ b/modules/enercoop/module.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2020 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 . + +# flake8: compatible + +from __future__ import unicode_literals + +from weboob.tools.backend import Module, BackendConfig +from weboob.tools.value import ValueBackendPassword +from weboob.capabilities.bill import ( + DocumentTypes, CapDocument, Subscription, +) + +from .browser import EnercoopBrowser + + +__all__ = ['EnercoopModule'] + + +class EnercoopModule(Module, CapDocument): + NAME = 'enercoop' + DESCRIPTION = 'Enercoop' + MAINTAINER = 'Vincent A' + EMAIL = 'dev@indigo.re' + LICENSE = 'LGPLv3+' + VERSION = '2.1' + + BROWSER = EnercoopBrowser + + CONFIG = BackendConfig( + ValueBackendPassword('email', regexp='.+@.+', masked=False), + ValueBackendPassword('password'), + ) + + accepted_document_types = (DocumentTypes.BILL,) + + def create_default_browser(self): + return self.create_browser(self.config['email'].get(), self.config['password'].get()) + + def iter_subscription(self): + return self.browser.iter_subscription() + + def iter_documents(self, subscription): + if isinstance(subscription, Subscription): + subscription = subscription.id + return self.browser.iter_documents(subscription) + + def download_document(self, id): + return self.browser.download_document(id) diff --git a/modules/enercoop/pages.py b/modules/enercoop/pages.py new file mode 100644 index 0000000000..70235a98b9 --- /dev/null +++ b/modules/enercoop/pages.py @@ -0,0 +1,124 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2020 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 . + +# flake8: compatible + +from __future__ import unicode_literals + +from weboob.browser.elements import ( + ItemElement, ListElement, method +) +from weboob.browser.pages import HTMLPage +from weboob.browser.filters.standard import ( + Date, CleanDecimal, CleanText, Format, Regexp, QueryValue, +) +from weboob.browser.filters.html import ( + AbsoluteLink, Attr, FormValue, +) +from weboob.capabilities.base import NotAvailable +from weboob.capabilities.address import PostalAddress +from weboob.capabilities.profile import Person +from weboob.capabilities.bill import ( + Subscription, Bill, +) + + +class LoggedMixin: + @property + def logged(self): + return bool(self.doc.xpath('//a[@id="logout"]')) + + +class BillsPage(LoggedMixin, HTMLPage): + @method + class iter_other_subscriptions(ListElement): + item_xpath = '//li[@id="contract-switch"]//a[@role="menuitem"][@href]' + + class item(ItemElement): + klass = Subscription + + obj_url = AbsoluteLink('.') + obj_id = QueryValue(obj_url, 'c') + obj_number = Regexp(CleanText('.'), r'(CNT-\d+-\d+)') + obj_label = Format( + '%s %s', + CleanText('./span', children=False), + obj_number, + ) + + @method + class iter_documents(ListElement): + item_xpath = '//div[@id="invoices-container"]/ul/li' + + class item(ItemElement): + klass = Bill + + obj_id = Attr('.', 'data-invoice-id') + + obj_total_price = CleanDecimal.French('.//div[has-class("amount")]') + obj_currency = 'EUR' + + obj_date = Date(CleanText('.//div[has-class("dueDate")]'), dayfirst=True) + + obj_format = 'pdf' + + def obj_url(self): + url = AbsoluteLink('.//a[@target="_blank"]')(self) + if '//download' in url: + return NotAvailable + return url + + def obj_has_file(self): + return bool(self.obj_url()) + + +class ProfilePage(LoggedMixin, HTMLPage): + @method + class get_profile(ItemElement): + klass = Person + + obj_name = FormValue('//input[@name="name"]') + obj_email = FormValue('//input[@name="email"]') + obj_phone = Format( + '%s%s', + Regexp( + CleanText(FormValue('//select[@id="phone_number_indic"]')), + r'\+\d+' + ), + FormValue('//input[@id="phone_number"]') + ) + obj_country = 'France' + + class obj_postal_address(ItemElement): + klass = PostalAddress + + # there can be a lot of whitespace in city name + obj_city = CleanText(FormValue('//select[@id="cities"]')) + + obj_street = Format( + '%s %s', + FormValue('//input[@name="num"]'), + FormValue('//input[@name="street"]') + ) + obj_postal_code = FormValue('//input[@name="zip_code"]') + obj_country = 'France' + + def fill_sub(self, sub): + sub._profile = self.get_profile() + sub.subscriber = sub._profile.name diff --git a/modules/enercoop/test.py b/modules/enercoop/test.py new file mode 100644 index 0000000000..f0e7da7052 --- /dev/null +++ b/modules/enercoop/test.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2020 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.test import BackendTest + + +class EnercoopTest(BackendTest): + MODULE = 'enercoop' + + def test_subs(self): + subs = list(self.backend.iter_subscription()) + assert subs + sub = subs[0] + assert subs[0].id + assert subs[0].label + + docs = list(self.backend.iter_documents(sub)) + assert docs + + doc = docs[0] + assert doc.id + assert doc.label + assert doc.total_price + assert doc.url -- GitLab