diff --git a/gotenberg/README.md b/gotenberg/README.md new file mode 100644 index 0000000..08a2cfd --- /dev/null +++ b/gotenberg/README.md @@ -0,0 +1,63 @@ +# Gotenberg integration in Odoo + + +##Gotenberg is a Docker-powered stateless API for PDF files. + +**In other words:** + +- It's a Docker image containing all the required dependencies; no need to install them on each environment. +- It scales smoothly and works nicely in a distributed context. +- It provides multipart/form-data endpoints for converting documents to PDF files, transforming them, merging them, and more! +- It has HTTP/2 support (H2C). + +Gotenberg provides a developer-friendly API to interact with powerful tools like Chromium and LibreOffice +to convert many documents (HTML, Markdown, Word, Excel, etc.) to PDF, transform them, merge them, and more! + + +## Quick Start + +Open a terminal and run the following command: + +``` +docker run --rm -p 3000:3000 gotenberg/gotenberg:6 +``` + +or + +``` +docker run --rm -p 3000:3000 thecodingmachine/gotenberg:6 +``` + +The API is now available on your host at http://localhost:3000. + +Head to the [documentation](https://gotenberg.dev/docs/about) to learn how to interact with it 🚀 + +## Configuration + +For a service running in a docker, you need to add an environment variable **GOTENBERG_SERVER** + +For a service running on a remote server, you need to specify the connection data in the settings. +## Use + + +## Development and Testing + +### Requirements + +There are a few things that we need for running the test suite. + +- A database instance WITH demo data. So when you are creating a database from that database creation screen, make sure to mark to include demo data. +- Run odoo with the --test-enable flag +- Run odoo with the -d {my_database} flag +- Run odoo with the -i {modules_to_install} flag +- (optional) Sometimes it’s also nice to use --stop-after-init + +### Run The Tests +```shell +$ docker-compose stop +$ docker-compose run web \ + --test-enable \ + --stop-after-init \ + -d test_db \ + -i test_module +``` \ No newline at end of file diff --git a/gotenberg/__init__.py b/gotenberg/__init__.py new file mode 100644 index 0000000..40e1190 --- /dev/null +++ b/gotenberg/__init__.py @@ -0,0 +1,4 @@ +from . import models # noqa: F401 +from . import service # noqa: F401 + +# from . import tests # noqa: F401 diff --git a/gotenberg/__manifest__.py b/gotenberg/__manifest__.py new file mode 100644 index 0000000..38da27d --- /dev/null +++ b/gotenberg/__manifest__.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# noinspection PyStatementEffect +{ + "name": "Gotenberg™ integration", + "summary": """Gotenberg integration with Odoo for file conversion.""", + "description": """ + This module complements the functionality of docx_report_generation, + namely it allows you to generate printed forms in PDF from docx templates. + """, + "license": "LGPL-3", + "author": "RYDLAB", + "website": "http://rydlab.ru", + "category": "Productivity", + "version": "0.1", + # |------------------------------------------------------------------------- + # | Dependencies + # |------------------------------------------------------------------------- + # | + # | References of all modules that this module depends on. If this module + # | is ever installed or upgrade, it will automatically install any + # | dependencies as well. + # | + "depends": ["base_setup"], + # |------------------------------------------------------------------------- + # | Data References + # |------------------------------------------------------------------------- + # | + # | References to all XML data that this module relies on. These XML files + # | are automatically pulled into the system and processed. + # | + "data": [ + "views/res_config_settings_views.xml", + ], + # |------------------------------------------------------------------------- + # | Demo Data + # |------------------------------------------------------------------------- + # | + # | A reference to demo data + # | + "demo": [], + # |------------------------------------------------------------------------- + # | Is Installable + # |------------------------------------------------------------------------- + # | + # | Gives the user the option to look at Local Modules and install, upgrade + # | or uninstall. This seems to be used by most developers as a switch for + # | modules that are either active / inactive. + # | + "installable": True, + # |------------------------------------------------------------------------- + # | Auto Install + # |------------------------------------------------------------------------- + # | + # | Lets Odoo know if this module should be automatically installed when + # | the server is started. + # | + "auto_install": False, +} diff --git a/gotenberg/models/__init__.py b/gotenberg/models/__init__.py new file mode 100644 index 0000000..d33c902 --- /dev/null +++ b/gotenberg/models/__init__.py @@ -0,0 +1,2 @@ +# noinspection PyUnresolvedReferences +from . import res_config_settings diff --git a/gotenberg/models/res_config_settings.py b/gotenberg/models/res_config_settings.py new file mode 100644 index 0000000..3f62458 --- /dev/null +++ b/gotenberg/models/res_config_settings.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +from odoo import fields, models + + +class ResConfigSettings(models.TransientModel): + _inherit = "res.config.settings" + + module_gotenberg = fields.Boolean(string="Gotenberg") + server = fields.Char( + string="Server", + config_parameter="service.gotenberg_server", + ) + method_authentication = fields.Selection( + [ + ("none", "None"), + ("basic", "Basic Authentication"), + ], + default="none", + config_parameter="service.gotenberg_method_authentication", + ) + username = fields.Char( + string="Username", config_parameter="service.gotenberg_username" + ) + password = fields.Char( + string="Password", config_parameter="service.gotenberg__password" + ) diff --git a/gotenberg/service/__init__.py b/gotenberg/service/__init__.py new file mode 100644 index 0000000..8e274ad --- /dev/null +++ b/gotenberg/service/__init__.py @@ -0,0 +1,3 @@ +# noinspection PyUnresolvedReferences +from . import environment +from . import utils diff --git a/gotenberg/service/environment.py b/gotenberg/service/environment.py new file mode 100644 index 0000000..ca6bed5 --- /dev/null +++ b/gotenberg/service/environment.py @@ -0,0 +1,14 @@ +from contextlib import contextmanager + +from odoo import api, registry, SUPERUSER_ID +from odoo.tests import common + + +@contextmanager +def environment(): + """Return an environment with a new cursor for the current database; the + cursor is committed and closed after the context block. + """ + reg = registry(common.get_db_name()) + with reg.cursor() as cr: + yield api.Environment(cr, SUPERUSER_ID, {}) diff --git a/gotenberg/service/utils.py b/gotenberg/service/utils.py new file mode 100644 index 0000000..7edb55f --- /dev/null +++ b/gotenberg/service/utils.py @@ -0,0 +1,53 @@ +import re +import os +from .environment import environment + + +GOTENBERG_DEFAULT_SERVER = "localhost:3000" +CONVERT_PDF_FROM_OFFICE_PATH = "convert/office" +HOST_PATTERN = re.compile(r"https?://(www\.)?") + + +def get_hostname(server): + return HOST_PATTERN.sub("", server).strip().strip("/") + + +def _gotenberg_server() -> str: + env_value = os.environ.get("GOTENBERG_SERVER") + + with environment() as env: + param_value = ( + env["ir.config_parameter"].sudo().get_param("service.gotenberg_server") + ) + server = env_value if env_value else param_value + + return server if server else GOTENBERG_DEFAULT_SERVER + + +def convert_pdf_from_office_url() -> str: + return _gotenberg_server() + CONVERT_PDF_FROM_OFFICE_PATH + + +def get_auth(): + with environment() as env: + conf = env["ir.config_parameter"].sudo() + auth = conf.get_param("service.gotenberg_method_authentication") + + if auth == "basic": + username = conf.get_param("service.gotenberg_username") + password = conf.get_param("service.gotenberg__password") + return username, password + + return + + +def check_gotenberg_installed(): + with environment() as env: + gotenberg_rec = ( + env["ir.module.module"].sudo().search([("name", "=", "gotenberg")]) + ) + return ( + True + if gotenberg_rec and gotenberg_rec.sudo().state == "installed" + else False + ) diff --git a/gotenberg/views/res_config_settings_views.xml b/gotenberg/views/res_config_settings_views.xml new file mode 100644 index 0000000..573263a --- /dev/null +++ b/gotenberg/views/res_config_settings_views.xml @@ -0,0 +1,53 @@ + + + + gotenberg.config.settings + res.config.settings + + + +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+