diff --git a/tools/cookiecutter/README.md b/tools/cookiecutter/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a1584e0131f354da14d3c86e35f30ee8416ea624 --- /dev/null +++ b/tools/cookiecutter/README.md @@ -0,0 +1,44 @@ +Woob module cookiecutter template +================================= + +This is a basic template for scaffolding woob modules with cookiecutter. + +How to use +---------- + +Run cookiecutter: + + cookiecutter -o ../../modules . + +It will ask a few questions: + + full_name [Your Name]: + email [yourmail@example.com]: + site_url [https://example.com]: + site_name [Example]: + capability [CapSomething]: + module_name [twitter]: + class_prefix [TwitterSimple]: + year [2021]: + +Develop by editing files in `../modules/your_module/*.py`. + +Don't forget to let woob detect your module: + + woob update + +Create an instance of your module: + + [my_backend] + _module = my_module + login = something + password = + +Then you can test your module with the appropriate command: + + woob something -d -b my_backend + +Requirements +------------ + +This template requires at least cookiecutter 1.7.1. diff --git a/tools/cookiecutter/cookiecutter.json b/tools/cookiecutter/cookiecutter.json new file mode 100644 index 0000000000000000000000000000000000000000..b3993795d117e64a13ab5d4c08f36839ab24bb12 --- /dev/null +++ b/tools/cookiecutter/cookiecutter.json @@ -0,0 +1,14 @@ +{ + "full_name": "Your Name", + "email": "yourmail@example.com", + "site_url": "https://example.com", + "site_name": "Example", + "capability": "CapSomething", + "module_name": "{{cookiecutter.site_name | slugify | replace('-', '_')}}", + "class_prefix": "{{cookiecutter.module_name | replace('_', ' ') | title | replace(' ', '')}}", + "year": "{% now 'utc', '%Y' %}", + "_extensions": [ + "jinja2_time.TimeExtension", + "cookiecutter.extensions.SlugifyExtension" + ] +} diff --git a/tools/cookiecutter/{{cookiecutter.module_name}}/__init__.py b/tools/cookiecutter/{{cookiecutter.module_name}}/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..53fe825b9af3c761e7c7e20686f34de36f6b494a --- /dev/null +++ b/tools/cookiecutter/{{cookiecutter.module_name}}/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) {{cookiecutter.year}} {{cookiecutter.full_name}} +# +# 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 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, +# 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 woob module. If not, see . + +from __future__ import unicode_literals + +from .module import {{cookiecutter.class_prefix}}Module + + +__all__ = ["{{cookiecutter.class_prefix}}Module"] diff --git a/tools/cookiecutter/{{cookiecutter.module_name}}/browser.py b/tools/cookiecutter/{{cookiecutter.module_name}}/browser.py new file mode 100644 index 0000000000000000000000000000000000000000..19e37bf6913429d695a869c24e2863a811bacf7e --- /dev/null +++ b/tools/cookiecutter/{{cookiecutter.module_name}}/browser.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) {{cookiecutter.year}} {{cookiecutter.full_name}} +# +# 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 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, +# 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 woob module. If not, see . + +# flake8: compatible + +from __future__ import unicode_literals + +from woob.browser import LoginBrowser, URL, need_login +from woob.exceptions import BrowserIncorrectPassword + +from .pages import ( + LoginPage, SomethingPage, +) + + +class {{cookiecutter.class_prefix}}Browser(LoginBrowser): + BASEURL = "{{cookiecutter.site_url}}" + + login = URL(r"/login", LoginPage) + something = URL(r"/something", SomethingPage) + + def do_login(self): + self.login.go() + self.page.do_login(self.username, self.password) + + if self.page.something(): + raise BrowserIncorrectPassword() + + @need_login + def iter_something(self): + self.something.go() + return self.page.iter_something() diff --git a/tools/cookiecutter/{{cookiecutter.module_name}}/module.py b/tools/cookiecutter/{{cookiecutter.module_name}}/module.py new file mode 100644 index 0000000000000000000000000000000000000000..9f80f0c9f5989754f23aea6aa7747c2b43d5f760 --- /dev/null +++ b/tools/cookiecutter/{{cookiecutter.module_name}}/module.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) {{cookiecutter.year}} {{cookiecutter.full_name}} +# +# 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 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, +# 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 woob module. If not, see . + +# flake8: compatible + +from __future__ import unicode_literals + +from woob.capabilities.{{cookiecutter.capability | replace('Cap', '') | lower}} import {{cookiecutter.capability}} +from woob.tools.backend import Module, BackendConfig +from woob.tools.value import ValueBackendPassword + +from .browser import {{cookiecutter.class_prefix}}Browser + + +__all__ = ["{{cookiecutter.class_prefix}}Module"] + + +class {{cookiecutter.class_prefix}}Module(Module, {{cookiecutter.capability}}): + NAME = "{{cookiecutter.module_name}}" + DESCRIPTION = "{{cookiecutter.site_name}}" + MAINTAINER = "{{cookiecutter.full_name}}" + EMAIL = "{{cookiecutter.email}}" + LICENSE = "LGPLv3+" + VERSION = "3.1" + + BROWSER = {{cookiecutter.class_prefix}}Browser + + CONFIG = BackendConfig( + ValueBackendPassword("login", label="Username", masked=False), + ValueBackendPassword("password", label="Password"), + ) + + def create_default_browser(self): + return self.create_browser( + self.config["login"].get(), + self.config["password"].get() + ) + + def iter_something(self): + return self.browser.iter_something() diff --git a/tools/cookiecutter/{{cookiecutter.module_name}}/pages.py b/tools/cookiecutter/{{cookiecutter.module_name}}/pages.py new file mode 100644 index 0000000000000000000000000000000000000000..4e651892ba79e32131f603371b602dfba28043d2 --- /dev/null +++ b/tools/cookiecutter/{{cookiecutter.module_name}}/pages.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) {{cookiecutter.year}} {{cookiecutter.full_name}} +# +# 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 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, +# 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 woob module. If not, see . + +# flake8: compatible + +from __future__ import unicode_literals + +from woob.browser.elements import method, ListElement, ItemElement +from woob.browser.filters.html import AbsoluteLink +from woob.browser.filters.standard import ( + CleanText, CleanDecimal, Date, +) +from woob.browser.pages import LoggedPage, HTMLPage + + +class LoginPage(HTMLPage): + def login(self, username, password): + form = self.get_form(id="login") + form["login"] = username + form["password"] = password + form.submit() + + +class SomethingPage(LoggedPage, HTMLPage): + @method + class iter_something(ListElement): + item_xpath = "//div[@id='something']" + + class item(ItemElement): + klass = Something + + obj_label = CleanText(".//span[has-class('col-label')]") + obj_price = CleanDecimal.SI(".//span[has-class('col-amount')]") + obj_date = Date(CleanText(".//span[has-class('col-date')]")) + obj_url = AbsoluteLink(".//a") diff --git a/tools/cookiecutter/{{cookiecutter.module_name}}/test.py b/tools/cookiecutter/{{cookiecutter.module_name}}/test.py new file mode 100644 index 0000000000000000000000000000000000000000..e5c5f88db9c0c86d56ac0b499bebf539c9f2b2c2 --- /dev/null +++ b/tools/cookiecutter/{{cookiecutter.module_name}}/test.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) {{cookiecutter.year}} {{cookiecutter.full_name}} +# +# 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 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, +# 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 woob module. If not, see . + +# flake8: compatible + +from woob.tools.test import BackendTest + + +class TwitterTest(BackendTest): + MODULE = "{{cookiecutter.module_name}}" + + def test_something(self): + n = -1 + for obj, n in zip(self.backend.iter_something(), range(20)): + assert obj.label + assert obj.price + assert obj.url.startswith(self.backend.browser.BASEURL) + + assert n > -1 diff --git a/tools/pyflakes.sh b/tools/pyflakes.sh index aadf2440dad5c0cb53ffae98f36e33de640fde1c..e9efc5ad194c5c33f075b0d0b8a31cb130c77684 100755 --- a/tools/pyflakes.sh +++ b/tools/pyflakes.sh @@ -10,7 +10,7 @@ MODULE_FILES=$(git ls-files modules|grep '\.py$') # Takes PYFILES from env, if empty use all git tracked files : ${PYFILES:=} if [ -z "${PYFILES}" ]; then - PYFILES="$(git ls-files | grep '^scripts\|\.py$'|grep -v boilerplate_data|grep -v stable_backport_data|grep -v '^modules'|grep -v '^contrib')" + PYFILES="$(git ls-files | grep '^scripts\|\.py$'|grep -v boilerplate_data|grep -v stable_backport_data|grep -v '^modules'|grep -v '^contrib'|grep -v cookiecutter)" PYFILES="$PYFILES $MODULE_FILES" fi