pax_global_header 0000666 0000000 0000000 00000000064 13514067645 0014525 g ustar 00root root 0000000 0000000 52 comment=d55ee1b5fb5ebdd456ab724438e5913e5a54d0c9
woob-d55ee1b5fb5ebdd456ab724438e5913e5a54d0c9-modules-ekwateur/ 0000775 0000000 0000000 00000000000 13514067645 0023134 5 ustar 00root root 0000000 0000000 woob-d55ee1b5fb5ebdd456ab724438e5913e5a54d0c9-modules-ekwateur/modules/ 0000775 0000000 0000000 00000000000 13514067645 0024604 5 ustar 00root root 0000000 0000000 woob-d55ee1b5fb5ebdd456ab724438e5913e5a54d0c9-modules-ekwateur/modules/ekwateur/ 0000775 0000000 0000000 00000000000 13514067645 0026433 5 ustar 00root root 0000000 0000000 woob-d55ee1b5fb5ebdd456ab724438e5913e5a54d0c9-modules-ekwateur/modules/ekwateur/__init__.py 0000664 0000000 0000000 00000001577 13514067645 0030556 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# Copyright(C) 2018 Phyks (Lucas Verney)
#
# 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 EkwateurModule
__all__ = ['EkwateurModule']
woob-d55ee1b5fb5ebdd456ab724438e5913e5a54d0c9-modules-ekwateur/modules/ekwateur/browser.py 0000664 0000000 0000000 00000003660 13514067645 0030475 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# Copyright(C) 2018 Phyks (Lucas Verney)
#
# 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
import itertools
from weboob.browser import LoginBrowser, need_login, URL
from weboob.exceptions import BrowserIncorrectPassword
from .pages import BillsPage, DocumentsPage, LoginPage
class EkwateurBrowser(LoginBrowser):
BASEURL = 'https://mon-espace.ekwateur.fr/'
login_page = URL('/se_connecter', LoginPage)
bills_page = URL('/mes_factures_et_acomptes', BillsPage)
documents_page = URL('/documents', DocumentsPage)
def do_login(self):
self.login_page.go().do_login(self.username, self.password)
self.bills_page.stay_or_go()
if not self.bills_page.is_here():
raise BrowserIncorrectPassword
@need_login
def iter_subscriptions(self):
return self.bills_page.stay_or_go().get_subscriptions()
@need_login
def iter_documents(self, sub_id):
return itertools.chain(
self.documents_page.stay_or_go().get_documents(sub_id=sub_id),
self.documents_page.stay_or_go().get_cgv(sub_id),
self.documents_page.stay_or_go().get_justificatif(sub_id),
self.bills_page.stay_or_go().get_bills(sub_id=sub_id)
)
woob-d55ee1b5fb5ebdd456ab724438e5913e5a54d0c9-modules-ekwateur/modules/ekwateur/module.py 0000664 0000000 0000000 00000005511 13514067645 0030274 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# Copyright(C) 2018 Phyks (Lucas Verney)
#
# 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 Value, ValueBackendPassword
from weboob.capabilities.base import find_object
from weboob.capabilities.bill import (
CapDocument, Document, DocumentNotFound, Subscription, DocumentTypes,
)
from .browser import EkwateurBrowser
__all__ = ['EkwateurModule']
class EkwateurModule(Module, CapDocument):
NAME = 'ekwateur'
DESCRIPTION = 'ekwateur website'
MAINTAINER = 'Phyks (Lucas Verney)'
EMAIL = 'phyks@phyks.me'
LICENSE = 'LGPLv3+'
VERSION = '1.6'
BROWSER = EkwateurBrowser
CONFIG = BackendConfig(
Value('login', help='Email or identifier'),
ValueBackendPassword('password', help='Password'),
)
accepted_document_types = (DocumentTypes.BILL,)
def create_default_browser(self):
return self.create_browser(self.config['login'].get(), self.config['password'].get())
def get_document(self, id):
"""
Get a document.
:param id: ID of document
:rtype: :class:`Document`
:raises: :class:`DocumentNotFound`
"""
return find_object(
self.iter_documents(id.split("#")[-1]),
id=id,
error=DocumentNotFound
)
def download_document(self, doc):
if not isinstance(doc, Document):
doc = self.get_document(doc)
if not doc.url:
return None
return self.browser.open(doc.url).content
def iter_documents(self, subscription):
"""
Iter documents.
:param subscription: subscription to get documents
:type subscription: :class:`Subscription`
:rtype: iter[:class:`Document`]
"""
if isinstance(subscription, Subscription):
subscription = subscription.id
return self.browser.iter_documents(subscription)
def iter_subscription(self):
"""
Iter subscriptions.
:rtype: iter[:class:`Subscription`]
"""
return self.browser.iter_subscriptions()
woob-d55ee1b5fb5ebdd456ab724438e5913e5a54d0c9-modules-ekwateur/modules/ekwateur/pages.py 0000664 0000000 0000000 00000012604 13514067645 0030107 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# Copyright(C) 2018 Phyks (Lucas Verney)
#
# 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.elements import (
ItemElement, ListElement, TableElement, method
)
from weboob.browser.pages import HTMLPage
from weboob.browser.filters.standard import (
Date, CleanDecimal, CleanText, Currency, Env, Format, Regexp, Slugify,
TableCell
)
from weboob.browser.filters.html import AbsoluteLink, Attr, Link, XPath
from weboob.capabilities.base import NotAvailable
from weboob.capabilities.bill import DocumentTypes, Subscription, Bill, Document
class LoginPage(HTMLPage):
def do_login(self, login, password):
form = self.get_form(nr=0)
form['_username'] = login
form['_password'] = password
form.submit()
class EkwateurPage(HTMLPage):
@property
def logged(self):
return bool(self.doc.xpath(u'//*[has-class("menu__user__infos")]'))
class BillsPage(EkwateurPage):
@method
class get_subscriptions(ListElement):
item_xpath = '//a[has-class("nom_contrat")]'
class item(ItemElement):
klass = Subscription
obj_subscriber = CleanText(
'(//h1[has-class("menu__user__infos__title")])[1]'
)
def obj_id(self):
return Link('.')(self).split('/')[-1]
def obj_label(self):
name = Attr('.', 'data-nomcontrat', default=None)(self)
if not name:
name = CleanText('.')(self)
return name
@method
class get_bills(TableElement):
item_xpath = '//table[@id="dataHistorique"]/tbody/tr'
head_xpath = '//table[@id="dataHistorique"]/thead/tr/td/text()'
col_date = 'Date'
col_type = 'Type'
col_amount = 'Montant'
col_status = 'Statut'
class item(ItemElement):
klass = Bill
obj_id = Format(
'facture-%s-%s-%s#%s',
Slugify(CleanText(TableCell('date'))),
Slugify(CleanText(TableCell('amount'))),
Slugify(CleanText(TableCell('type'))),
Env('sub_id')
)
obj_url = AbsoluteLink('./td[5]//a', default=NotAvailable)
obj_date = Date(CleanText(TableCell('date')), dayfirst=True)
obj_label = Format(
'%s %s %s',
CleanText(TableCell('type')),
CleanText(TableCell('amount')),
CleanText(TableCell('date'))
)
obj_type = DocumentTypes.BILL
obj_price = CleanDecimal(TableCell('amount'), replace_dots=True)
obj_currency = Currency(TableCell('amount'))
obj_duedate = Date(
Regexp(
CleanText(TableCell('status')),
r'le (\d+)/(\d+)/(\d+)',
r'\1/\2/\3'
),
dayfirst=True
)
def obj_format(self):
if self.obj_url(self):
return 'pdf'
return NotAvailable
def obj_income(self):
if self.obj_price(self) < 0:
return True
return False
class DocumentsPage(EkwateurPage):
@method
class get_documents(TableElement):
item_xpath = '//table[@id="otherDocuments"]/tbody/tr'
head_xpath = '//table[@id="otherDocuments"]/thead/tr/td/text()'
col_date = 'Date'
col_type = 'Type'
class item(ItemElement):
klass = Document
obj_date = Date(CleanText(TableCell('date')), dayfirst=True)
obj_format = 'pdf'
obj_label = CleanText(TableCell('type'))
obj_url = AbsoluteLink('./td[3]//a', default=NotAvailable)
obj_id = Format(
'doc-%s-%s#%s',
Slugify(CleanText(TableCell('date'))),
Slugify(CleanText(TableCell('type'))),
Env('sub_id')
)
def get_justificatif(self, sub_id):
doc = Document()
doc.id = 'doc-justificatif#%s' % sub_id
doc.format = 'pdf'
doc.date = NotAvailable
doc.label = 'Justificatif de domicile'
doc.url = 'https://mon-espace.ekwateur.fr/client/justificatif_de_domicile'
yield doc
def get_cgv(self, sub_id):
CGV = Document()
CGV.id = 'doc-CGV#%s' % sub_id
CGV.format = 'pdf'
CGV.date = NotAvailable
CGV.label = 'CGV électricité'
CGV.type = 'cgv'
for item in XPath(
'.//div[has-class("table__foot__adobe-reader__link")]//a'
)(self.doc):
if 'CGV' in item.text:
CGV.url = item.attrib['href']
yield CGV
woob-d55ee1b5fb5ebdd456ab724438e5913e5a54d0c9-modules-ekwateur/modules/ekwateur/test.py 0000664 0000000 0000000 00000002414 13514067645 0027765 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# Copyright(C) 2018 Phyks (Lucas Verney)
#
# 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 EkwateurTest(BackendTest):
MODULE = 'ekwateur'
def test_document(self):
subscriptions = list(self.backend.iter_subscription())
assert subscriptions
for sub in subscriptions:
docs = list(self.backend.iter_documents(sub))
assert docs
for doc in docs:
content = self.backend.download_document(doc)
assert content