Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: OCA/reporting-engine
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 16.0
Choose a base ref
...
head repository: legalsylvain/reporting-engine
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 16.0-ADD-weasyprint-lru-cache-idiot
Choose a head ref
Can’t automatically merge. Don’t worry, you can still create the pull request.
  • 6 commits
  • 34 files changed
  • 1 contributor

Commits on Apr 25, 2023

  1. Copy the full SHA
    7f0bf74 View commit details
  2. Copy the full SHA
    4aec4ef View commit details
  3. [WIP]

    legalsylvain committed Apr 25, 2023
    Copy the full SHA
    8ecb3a5 View commit details

Commits on Apr 28, 2023

  1. [WIP] remove odoocdn

    legalsylvain committed Apr 28, 2023
    Copy the full SHA
    6ce5a2c View commit details
  2. [WIP]

    legalsylvain committed Apr 28, 2023
    Copy the full SHA
    2555b3c View commit details
  3. wip

    legalsylvain committed Apr 28, 2023
    Copy the full SHA
    1e200b8 View commit details
Showing with 1,225 additions and 0 deletions.
  1. 0 report_qweb_custom_renderer/README.rst
  2. +3 −0 report_qweb_custom_renderer/__init__.py
  3. +17 −0 report_qweb_custom_renderer/__manifest__.py
  4. +3 −0 report_qweb_custom_renderer/models/__init__.py
  5. +45 −0 report_qweb_custom_renderer/models/ir_actions_report.py
  6. +1 −0 report_qweb_custom_renderer/readme/CONTRIBUTORS.rst
  7. +1 −0 report_qweb_custom_renderer/readme/CREDITS.rst
  8. +1 −0 report_qweb_custom_renderer/readme/DESCRIPTION.rst
  9. +1 −0 report_qweb_custom_renderer/readme/ROADMAP.rst
  10. BIN report_qweb_custom_renderer/static/description/icon.png
  11. +411 −0 report_qweb_custom_renderer/static/description/index.html
  12. +15 −0 report_qweb_custom_renderer/views/ir_actions_report.xml
  13. 0 report_qweb_weasyprint_renderer/README.rst
  14. +3 −0 report_qweb_weasyprint_renderer/__init__.py
  15. +24 −0 report_qweb_weasyprint_renderer/__manifest__.py
  16. +74 −0 report_qweb_weasyprint_renderer/demo/report.xml
  17. +3 −0 report_qweb_weasyprint_renderer/models/__init__.py
  18. +86 −0 report_qweb_weasyprint_renderer/models/ir_actions_report.py
  19. +1 −0 report_qweb_weasyprint_renderer/readme/CONTRIBUTORS.rst
  20. +2 −0 report_qweb_weasyprint_renderer/readme/CREDITS.rst
  21. +1 −0 report_qweb_weasyprint_renderer/readme/DESCRIPTION.rst
  22. +5 −0 report_qweb_weasyprint_renderer/readme/ROADMAP.rst
  23. +5 −0 report_qweb_weasyprint_renderer/readme/USAGE.rst
  24. BIN report_qweb_weasyprint_renderer/static/description/icon.png
  25. +446 −0 report_qweb_weasyprint_renderer/static/description/index.html
  26. +34 −0 ...rt_qweb_weasyprint_renderer/static/src/css/report_qweb_weasyprint_renderer_wkhtmltopdf_compat.css
  27. +3 −0 report_qweb_weasyprint_renderer/tests/__init__.py
  28. +12 −0 report_qweb_weasyprint_renderer/tests/test_report_qweb_weasyprint_renderer.py
  29. +13 −0 report_qweb_weasyprint_renderer/views/templates.xml
  30. +1 −0 requirements.txt
  31. +1 −0 setup/report_qweb_custom_renderer/odoo/addons/report_qweb_custom_renderer
  32. +6 −0 setup/report_qweb_custom_renderer/setup.py
  33. +1 −0 setup/report_qweb_weasyprint_renderer/odoo/addons/report_qweb_weasyprint_renderer
  34. +6 −0 setup/report_qweb_weasyprint_renderer/setup.py
Empty file.
3 changes: 3 additions & 0 deletions report_qweb_custom_renderer/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Copyright 2018 Therp BV <https://therp.nl>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from . import models
17 changes: 17 additions & 0 deletions report_qweb_custom_renderer/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright 2018 Therp BV <https://therp.nl>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
{
"name": "Custom QWEB rendering",
"version": "16.0.1.0.0",
"author": "Therp BV,Odoo Community Association (OCA)",
"website": "https://github.com/OCA/reporting-engine",
"license": "AGPL-3",
"category": "Hidden/Dependency",
"summary": "Base module for non-wkhtmlpdf report rendering",
"depends": [
"base",
],
"data": [
"views/ir_actions_report.xml",
],
}
3 changes: 3 additions & 0 deletions report_qweb_custom_renderer/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Copyright 2018 Therp BV <https://therp.nl>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from . import ir_actions_report
45 changes: 45 additions & 0 deletions report_qweb_custom_renderer/models/ir_actions_report.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Copyright 2018 Therp BV <https://therp.nl>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
import logging
import time

from odoo import fields, models

_logger = logging.getLogger(__name__)


class IrActionsReport(models.Model):
_inherit = "ir.actions.report"

qweb_pdf_engine = fields.Selection(
[("wkhtmltopdf", "wkhtmltopdf")],
default="wkhtmltopdf",
string="PDF Engine",
)

def _render_qweb_pdf(self, report_ref, res_ids=None, data=None):
qweb_pdf_engine = "wkhtmltopdf"
qweb_pdf_engine = "weasyprint"

_logger.info("========================================")
_logger.info("=================<begin> render_qweb_pdf")
_logger.info("========================================")
time_1 = time.time()
if qweb_pdf_engine == "wkhtmltopdf":
result = super()._render_qweb_pdf(
report_ref,
res_ids=res_ids,
data=data,
)
else:
result = getattr(self, "_render_qweb_pdf_%s" % qweb_pdf_engine)(
report_ref,
res_ids=res_ids,
data=data,
)
time_2 = time.time()
_logger.info("%s: %s seconds" % (qweb_pdf_engine, time_2 - time_1))
_logger.info("========================================")
_logger.info("=================<end> render_qweb_pdf")
_logger.info("========================================")
return result
1 change: 1 addition & 0 deletions report_qweb_custom_renderer/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* Holger Brunn <hbrunn@therp.nl>
1 change: 1 addition & 0 deletions report_qweb_custom_renderer/readme/CREDITS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_.
1 change: 1 addition & 0 deletions report_qweb_custom_renderer/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This module is a base module for other addons that provide a different PDF renderer than Odoo's default wkhtmltopdf.
1 change: 1 addition & 0 deletions report_qweb_custom_renderer/readme/ROADMAP.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* support attachments
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
411 changes: 411 additions & 0 deletions report_qweb_custom_renderer/static/description/index.html

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions report_qweb_custom_renderer/views/ir_actions_report.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="view_ir_actions_report_form" model="ir.ui.view">
<field name="model">ir.actions.report</field>
<field name="inherit_id" ref="base.act_report_xml_view" />
<field name="arch" type="xml">
<field name="report_type" position="after">
<field
name="qweb_pdf_engine"
attrs="{'invisible': [('report_type', '!=', 'qweb-pdf')], 'required': [('report_type', '=', 'qweb-pdf')]}"
/>
</field>
</field>
</record>
</odoo>
Empty file.
3 changes: 3 additions & 0 deletions report_qweb_weasyprint_renderer/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Copyright 2018 Therp BV <https://therp.nl>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from . import models
24 changes: 24 additions & 0 deletions report_qweb_weasyprint_renderer/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Copyright 2018 Therp BV <https://therp.nl>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
{
"name": "Weasyprint QWEB renderer",
"version": "16.0.1.0.0",
"author": "Therp BV,Odoo Community Association (OCA)",
"website": "https://github.com/OCA/reporting-engine",
"license": "AGPL-3",
"category": "Reporting",
"summary": "Use WeasyPrint to create PDFs",
"depends": [
"report_qweb_custom_renderer",
"web",
],
"demo": [
"demo/report.xml",
],
"data": [
"views/templates.xml",
],
"external_dependencies": {
"python": ["weasyprint"],
},
}
74 changes: 74 additions & 0 deletions report_qweb_weasyprint_renderer/demo/report.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<template id="view_demo_report_qweb">
<html>
<head>
<style type="text/css">
@page {
size: A4;
padding: 20px;
@top-center {
content: '<t t-esc="env.user.name" /> - ' string(title);
}
@bottom-center {
content: counter(page) ' of ' counter(pages);
}
}
h1 {
string-set: title content();
page-break-before: always;
}
h1:first-of-type {
page-break-before: avoid;
}
.desc {
white-space: pre-line;
font-family: monospace;
}
.index {
list-style: none;
padding-left: 0em;
}
.index li a {
text-decoration: none;
color: inherit;
}
.index li a::after {
content: target-counter(attr(href), page);
float: right;
}
.img {
margin: .1em;
float: right;
}
</style>
</head>
<body>
<h1>Index</h1>
<ul class="index">
<li t-foreach="docs" t-as="this">
<a t-attf-href="#chapter{{this.id}}" t-esc="this.shortdesc" />
</li>
</ul>
<t t-foreach="docs" t-as="this">
<h1 t-attf-id="chapter{{this.id}}" t-esc="this.shortdesc" />
<img
class="img"
t-attf-src="data:img/*;base64,{{this.icon_image}}"
/>
<div class="desc" t-esc="this.description" />
</t>
</body>
</html>
</template>
<report
id="demo_report"
string="WeasyPrint demo report"
model="ir.module.module"
name="report_qweb_weasyprint_renderer.view_demo_report_qweb"
report_type="qweb-pdf"
/>
<record id="demo_report" model="ir.actions.report">
<field name="qweb_pdf_engine">weasyprint</field>
</record>
</odoo>
3 changes: 3 additions & 0 deletions report_qweb_weasyprint_renderer/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Copyright 2018 Therp BV <https://therp.nl>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from . import ir_actions_report
86 changes: 86 additions & 0 deletions report_qweb_weasyprint_renderer/models/ir_actions_report.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Copyright 2018 Therp BV <https://therp.nl>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
import logging
import re
from functools import lru_cache
from pathlib import Path

from odoo import fields, models
from odoo.modules.module import get_module_path

try:
from weasyprint import HTML, default_url_fetcher
except ImportError:
HTML = None
default_url_fetcher = None


_logger = logging.getLogger(__name__)
_weasyprint_logger = logging.getLogger("weasyprint")
_weasyprint_logger.setLevel(logging.CRITICAL)
_fonttools_logger = logging.getLogger("fontTools")
_fonttools_logger.setLevel(logging.CRITICAL)


_STATIC_MODULE_FILE_REG = (
r"/(?P<module_name>\w+)" r"/(?P<relative_file_path>static/[\w+|\/|\-|\.]+)"
)


@lru_cache()
def _external_cdn_data(url):
_logger.info("Caching %s" % url)
try:
return default_url_fetcher(url)
except Exception:
pass


def _weasyprint_url_fetcher(url):
"""
This function will replace url by file content.
As a result, weasyprint will not make a lot of http requests
to your odoo instance or odoocdn, and will return
assets more quickly.
"""
static_asset_search = re.search(_STATIC_MODULE_FILE_REG, url)
if static_asset_search:
module_name, relative_file_path = static_asset_search.groups()
file = Path(get_module_path(module_name)) / relative_file_path
return {"string": file.read_bytes()}

if "odoocdn.com" in url:
return _external_cdn_data(url)

return default_url_fetcher(url)


class IrActionsReport(models.Model):
_inherit = "ir.actions.report"

qweb_pdf_engine = fields.Selection(
selection_add=[("weasyprint", "WeasyPrint")],
)

def _render_qweb_pdf_weasyprint(self, report_ref, res_ids=None, data=None):
data = data or {}
data["report_type"] = "pdf"
context = dict(self.env.context)
context["qweb_pdf_engine"] = "weasyprint"

html = self.with_context(**context)._render_qweb_html(
report_ref, res_ids, data=data
)
with open("/tmp/tralala_weasyprint.html", "wb+") as f:
f.write(html[0])

return (
HTML(
string=html[0],
# TODO: pass a custom url fetcher to never actually use the port
base_url=self.env["ir.config_parameter"].get_param("report.url")
or self.env["ir.config_parameter"].get_param("web.base.url"),
url_fetcher=_weasyprint_url_fetcher,
).write_pdf(),
"pdf",
)
1 change: 1 addition & 0 deletions report_qweb_weasyprint_renderer/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* Holger Brunn <hbrunn@therp.nl>
2 changes: 2 additions & 0 deletions report_qweb_weasyprint_renderer/readme/CREDITS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_.
* `weasyprint <https://weasyprint.org>`_
1 change: 1 addition & 0 deletions report_qweb_weasyprint_renderer/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This module allows you to use weasyprint to render PDFs, which allows for more print related HTML features than using Odoo's standard wkhtmltopdf.
5 changes: 5 additions & 0 deletions report_qweb_weasyprint_renderer/readme/ROADMAP.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
* add a compatibility layer to replace wkhtmltopdf
* support paper formats
* add some sensible templates for weasyprint specific internal and external layouts

- CUSTOM : FIX lru_cache()
5 changes: 5 additions & 0 deletions report_qweb_weasyprint_renderer/readme/USAGE.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
To use this module, you need to set ``qweb_pdf_engine`` to ``weasyprint``::

<record id="demo_report" model="ir.actions.report">
<field name="qweb_pdf_engine">weasyprint</field>
</record>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
446 changes: 446 additions & 0 deletions report_qweb_weasyprint_renderer/static/description/index.html

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
@page {
margin-left: 1cm;
margin-right: 1cm;
margin-top: 2cm;
margin-bottom: 2cm;
@top-center {
content: element(header);
width: 100%;
}
@bottom-center {
content: element(footer);
width: 100%;
}
}
body {
margin: 0px;
padding: 0px;
}
.header {
position: running(header);
}
.header * {
white-space: nowrap;
}
.footer {
position: running(footer);
width: 100%;
}
.page:before {
content: counter(page);
}
.topage:before {
content: counter(pages);
}
3 changes: 3 additions & 0 deletions report_qweb_weasyprint_renderer/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Copyright 2018 Therp BV <https://therp.nl>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from . import test_report_qweb_weasyprint_renderer
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Copyright 2018 Therp BV <https://therp.nl>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from odoo.tests.common import TransactionCase


class TestReportQwebWeasyprintRenderer(TransactionCase):
def test_report_qweb_weasyprint_renderer(self):
pdf, file_type = self.env.ref(
"report_qweb_weasyprint_renderer.demo_report"
).render(self.env["res.company"].search([]).ids)
self.assertEqual(file_type, "pdf")
self.assertTrue(pdf.startswith(b"%PDF"))
13 changes: 13 additions & 0 deletions report_qweb_weasyprint_renderer/views/templates.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<template id="weasyprint_wkhtmltopf" inherit_id="web.report_layout" active="True">
<xpath expr="html/head" position="inside">
<!-- this doesn't work yet /-->
<link
t-if="user.env.context.get('qweb_pdf_engine') == 'weasyprint'"
rel="stylesheet"
href="/report_qweb_weasyprint_renderer/static/src/css/report_qweb_weasyprint_renderer_wkhtmltopdf_compat.css"
/>
</xpath>
</template>
</odoo>
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# generated from manifests external_dependencies
lxml
weasyprint
xlrd
xlsxwriter
6 changes: 6 additions & 0 deletions setup/report_qweb_custom_renderer/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import setuptools

setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)
6 changes: 6 additions & 0 deletions setup/report_qweb_weasyprint_renderer/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import setuptools

setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)