Skip to content
Commits on Source (3)
# -*- coding: utf-8 -*-
# Copyright(C) 2014 Vincent A
#
# This file is part of a woob module.
#
# This woob module 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.
#
# This woob 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this woob module. If not, see <http://www.gnu.org/licenses/>.
from base64 import b64encode
from io import BytesIO
from woob.browser import PagesBrowser, URL
from woob.tools.capabilities.paste import image_mime
from .pages import PageHome, PageImage, PageError
__all__ = ['PixtoilelibreBrowser']
class PixtoilelibreBrowser(PagesBrowser):
BASEURL = 'http://pix.toile-libre.org'
home = URL(r'/$', PageHome)
error = URL(r'/\?action=upload', PageError)
img = URL(r'/\?img=(?P<id>.+)', PageImage)
def post_image(self, filename, contents, private=False, description=''):
self.location('/')
assert self.home.is_here()
mime = image_mime(b64encode(contents))
form = self.page.get_form(nr=0)
form['private'] = int(private)
form['description'] = description or ''
del form['img']
f = (filename, BytesIO(contents), mime)
self.location(form.url, data=form, files={'img': f})
assert self.img.is_here()
return self.page.get_info()
def get_contents(self, id):
return self.open('/upload/original/%s' % id).content
# -*- coding: utf-8 -*-
# Copyright(C) 2014 Vincent A
#
# This file is part of a woob module.
#
# This woob module 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.
#
# This woob 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this woob module. If not, see <http://www.gnu.org/licenses/>.
from base64 import b64decode
import re
from woob.tools.backend import Module
from woob.capabilities.paste import CapPaste, BasePaste
from woob.tools.capabilities.paste import image_mime, bin_to_b64
from .browser import PixtoilelibreBrowser
__all__ = ['PixtoilelibreModule']
class PixPaste(BasePaste):
@classmethod
def id2url(cls, id):
return 'http://pix.toile-libre.org/?img=%s' % id
class PixtoilelibreModule(Module, CapPaste):
NAME = 'pixtoilelibre'
DESCRIPTION = u'toile-libre image hosting website'
MAINTAINER = u'Vincent A'
EMAIL = 'dev@indigo.re'
LICENSE = 'AGPLv3+'
VERSION = '3.1'
BROWSER = PixtoilelibreBrowser
def can_post(self, contents, title=None, public=None, max_age=None):
if re.search(r'[^a-zA-Z0-9=+/\s]', contents):
return 0
elif max_age:
return 0 # expiration is not possible
else:
mime = image_mime(contents, ('gif', 'jpeg', 'png'))
return 20 * int(mime is not None)
def get_paste(self, id):
m = self.browser.img.match(id)
if m:
id = m.group('id')
paste = PixPaste(id)
contents = self.browser.get_contents(id)
if contents:
paste.contents = bin_to_b64(contents)
return paste
def new_paste(self, *a, **kw):
return PixPaste(*a, **kw)
def post_paste(self, paste, max_age=None):
d = self.browser.post_image(paste.title or '-', b64decode(paste.contents), private=(not paste.public), description=paste.title)
paste.id = d['id']
return paste
# -*- coding: utf-8 -*-
# Copyright(C) 2014 Vincent A
#
# This file is part of a woob module.
#
# This woob module 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.
#
# This woob 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this woob module. If not, see <http://www.gnu.org/licenses/>.
from woob.browser.pages import HTMLPage
import re
class PageHome(HTMLPage):
pass
class PageImage(HTMLPage):
def get_info(self):
id = re.search(r'img=([^&]+)', self.url).group(1)
return {'url': self.url, 'id': id}
class PageError(HTMLPage):
pass
# -*- coding: utf-8 -*-
# Copyright(C) 2014 Vincent A
#
# This file is part of a woob module.
#
# This woob module 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.
#
# This woob 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this woob module. If not, see <http://www.gnu.org/licenses/>.
from base64 import b64decode
from woob.tools.test import BackendTest
class PixtoilelibreTest(BackendTest):
MODULE = 'pixtoilelibre'
# small gif file
DATA = 'R0lGODlhAQABAIAAAP///wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==\n'
def test_pixtoilelibre(self):
assert self.backend.can_post(self.DATA, max_age=0)
post = self.backend.new_paste(None)
post.contents = self.DATA
post.public = True
self.backend.post_paste(post, max_age=0)
assert post.id
got = self.backend.get_paste(post.id)
assert got
self.assertEquals(b64decode(got.contents), b64decode(self.DATA))
# -*- coding: utf-8 -*-
# Copyright(C) 2014 Vincent A
# Copyright(C) 2019 Vincent A
#
# This file is part of a woob module.
# This file is part of a weboob module.
#
# This woob module is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# 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 woob module is distributed in the hope that it will be useful,
# 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 Affero General Public License for more details.
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this woob module. If not, see <http://www.gnu.org/licenses/>.
# You should have received a copy of the GNU Lesser General Public License
# along with this weboob module. If not, see <http://www.gnu.org/licenses/>.
from __future__ import unicode_literals
from .module import PixtoilelibreModule
from .module import PrimonialreimModule
__all__ = ['PixtoilelibreModule']
__all__ = ['PrimonialreimModule']
# -*- 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 <http://www.gnu.org/licenses/>.
# flake8: compatible
from __future__ import unicode_literals
from woob.browser import LoginBrowser, need_login, URL
from .pages import (
LoginPage, AfterLoginPage, AccountsPage, TaxDocsPage,
)
class PrimonialreimBrowser(LoginBrowser):
BASEURL = 'https://www.primonialreim.com'
login = URL("/login", LoginPage)
accounts = URL("/group/extranet-associes/mon-patrimoine", AccountsPage)
tax_documents = URL("/group/extranet-associes/ma-fiscalit%C3%A9", TaxDocsPage)
home = URL("/group/extranet-associes", AfterLoginPage)
def do_login(self):
self.login.go()
self.page.do_login(self.username, self.password)
# twice because site submits username first then password
self.page.do_login(self.username, self.password)
@need_login
def iter_accounts(self):
self.accounts.go()
return self.page.iter_accounts()
@need_login
def iter_documents(self):
self.tax_documents.go()
return self.page.iter_documents()
# -*- 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 <http://www.gnu.org/licenses/>.
# flake8: compatible
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.bank import CapBank, Account
from weboob.capabilities.bill import (
CapDocument, Subscription, SubscriptionNotFound, DocumentNotFound,
)
from .browser import PrimonialreimBrowser
__all__ = ['PrimonialreimModule']
class PrimonialreimModule(Module, CapBank, CapDocument):
NAME = 'primonialreim'
DESCRIPTION = 'Primonial REIM'
MAINTAINER = 'Vincent A'
EMAIL = 'dev@indigo.re'
LICENSE = 'LGPLv3+'
VERSION = '3.1'
BROWSER = PrimonialreimBrowser
CONFIG = BackendConfig(
Value('username', label='Identifiant'),
ValueBackendPassword('password', label='Mot de passe'),
)
def create_default_browser(self):
return self.create_browser(self.config['username'].get(), self.config['password'].get())
# CapBank
def iter_accounts(self):
return self.browser.iter_accounts()
# CapDocument
def iter_subscription(self):
return [Subscription.from_dict(dict(id="primonial", label="Primonial"))]
def get_subscription(self, id):
return find_object(self.iter_subscription(), id=id, error=SubscriptionNotFound)
def iter_documents(self, subscription):
return self.browser.iter_documents()
def download_document(self, document):
if isinstance(document, str):
document = find_object(self.iter_documents(None), id=document, error=DocumentNotFound)
return self.browser.open(document.url).content
# CapCollection
def iter_resources(self, objs, split_path):
if Account in objs:
self._restrict_level(split_path)
return self.iter_accounts()
if Subscription in objs:
self._restrict_level(split_path)
return self.iter_subscription()
# -*- 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 <http://www.gnu.org/licenses/>.
# flake8: compatible
from __future__ import unicode_literals
import datetime
from decimal import Decimal
import re
import json
from woob.capabilities.bank.base import Account
from woob.capabilities.bill import Document, DocumentTypes
from woob.browser.pages import HTMLPage, LoggedPage
from woob.browser.filters.standard import (
CleanText, Format, Regexp,
)
from woob.browser.filters.html import AbsoluteLink
from woob.browser.elements import ListElement, ItemElement, method
class LoginPage(HTMLPage):
def do_login(self, username, password):
form = self.get_form(xpath="//form[contains(@action, 'login')]")
url = form.el.attrib["action"]
token = re.search(r"INSTANCE_([a-zA-Z0-9]+)_", url)[1]
form[f"_com_preim_portlet_login_PreimLoginPortlet_INSTANCE_{token}_username"] = username
form[f"_com_preim_portlet_login_PreimLoginPortlet_INSTANCE_{token}_password"] = password
form.submit()
class AfterLoginPage(LoggedPage, HTMLPage):
pass
class AccountsPage(LoggedPage, HTMLPage):
def iter_accounts(self):
jdata = json.loads(self.doc.xpath("//div/@js-new-graph[contains(., 'bar')]")[0])
jdata = {item["legendText"]: item["dataPoints"] for item in jdata["data"]}
for jpoint in jdata["Valeur totale d achat"]:
yield Account.from_dict(dict(
id=jpoint["label"].lower().replace(" ", ""),
label=jpoint["label"],
balance=Decimal(str(jpoint["y"])),
type=Account.TYPE_REAL_ESTATE,
))
class TaxDocsPage(LoggedPage, HTMLPage):
@method
class iter_documents(ListElement):
item_xpath = "//a[contains(@href, '.pdf')]"
class item(ItemElement):
klass = Document
obj_type = DocumentTypes.NOTICE
obj_url = AbsoluteLink(".")
obj_id = Regexp(obj_url, r"/([^/]+)\.pdf")
obj__year = Regexp(obj_url, r"(\d+)\.pdf")
obj_label = Format(
"%s %s",
CleanText("."),
obj__year
)
def obj_date(self):
return datetime.date(int(self.obj._year) + 1, 1, 1)
# -*- 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 <http://www.gnu.org/licenses/>.
from __future__ import unicode_literals
from weboob.tools.test import BackendTest
class PrimonialreimTest(BackendTest):
MODULE = 'primonialreim'
def test_accounts(self):
accounts = list(self.backend.iter_accounts())
assert accounts
for account in accounts:
assert account.id
assert account.label
assert account.balance
assert account.type
def test_documents(self):
sub, = self.backend.iter_subscription()
docs = list(self.backend.iter_documents())
assert docs
for doc in docs:
assert doc.id
assert doc.label
assert doc.date
assert doc.type
assert self.backend.download_document(docs[0])
......@@ -38,7 +38,7 @@ class TransatplanModule(Module, CapBankWealth):
MAINTAINER = 'Vincent Ardisson'
EMAIL = 'vardisson@budget-insight.com'
LICENSE = 'LGPLv3+'
VERSION = '1.4'
VERSION = '3.1'
BROWSER = TransatplanBrowser
......