Browse Source

report_qweb_pdf_watermark (#86)

pull/236/head
Holger Brunn 8 years ago
committed by Pedro M. Baeza
parent
commit
ab26f7790d
  1. 62
      report_qweb_pdf_watermark/README.rst
  2. 4
      report_qweb_pdf_watermark/__init__.py
  3. 18
      report_qweb_pdf_watermark/__openerp__.py
  4. 30
      report_qweb_pdf_watermark/demo/report.xml
  5. 5
      report_qweb_pdf_watermark/models/__init__.py
  6. 14
      report_qweb_pdf_watermark/models/ir_actions_report_xml.py
  7. 87
      report_qweb_pdf_watermark/models/report.py
  8. BIN
      report_qweb_pdf_watermark/static/description/icon.png
  9. 4
      report_qweb_pdf_watermark/tests/__init__.py
  10. 32
      report_qweb_pdf_watermark/tests/test_report_qweb_pdf_watermark.py
  11. 15
      report_qweb_pdf_watermark/views/ir_actions_report_xml.xml

62
report_qweb_pdf_watermark/README.rst

@ -0,0 +1,62 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
=============
Pdf watermark
=============
This module was written to add watermarks (backgrounds) to PDF reports.
This is necessary because of the way wkhtmltopdf handles headers and footers, in the current versions if quite impossible to have a background for the complete page.
Usage
=====
To use this module, you need to:
#. go to your report
#. select a PDF or image to use as watermark. Note that resolutions and size must match, otherwise you'll have funny results
#. advanced users (members of group technical settings) can also fill in an expression that returns the data (base64 encoded) to be used as watermark
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/143/8.0
Bug Tracker
===========
Bugs are tracked on `GitHub Issues
<https://github.com/OCA/reporting-engine/issues>`_. In case of trouble, please
check there if your issue has already been reported. If you spotted it first,
help us smashing it by providing a detailed and welcomed feedback.
Credits
=======
Images
------
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_.
Contributors
------------
* Holger Brunn <hbrunn@therp.nl>
Do not contact contributors directly about help with questions or problems concerning this addon, but use the `community mailing list <mailto:community@mail.odoo.com>`_ or the `appropriate specialized mailinglist <https://odoo-community.org/groups>`_ for help, and the bug tracker linked in `Bug Tracker`_ above for technical issues.
Maintainer
----------
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
This module is maintained by the OCA.
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
To contribute to this module, please visit https://odoo-community.org.

4
report_qweb_pdf_watermark/__init__.py

@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# © 2016 Therp BV <http://therp.nl>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import models

18
report_qweb_pdf_watermark/__openerp__.py

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
# © 2016 Therp BV <http://therp.nl>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
"name": "Pdf watermark",
"version": "9.0.1.0.0",
"author": "Therp BV,Odoo Community Association (OCA)",
"license": "AGPL-3",
"category": "Reporting",
"summary": "Add watermarks to your QWEB PDF reports",
"depends": [
'report',
],
"data": [
"demo/report.xml",
"views/ir_actions_report_xml.xml",
],
}

30
report_qweb_pdf_watermark/demo/report.xml

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<report
id="demo_report"
string="Demo report"
model="res.users"
report_type="qweb-pdf"
name="report_qweb_pdf_watermark.demo_report_view"
file="report_qweb_pdf_watermark.demo_report_view"
paperformat="report.paperformat_euro"
/>
<record id="demo_report" model="ir.actions.report.xml">
<field name="pdf_watermark_expression">docs[:1].company_id.logo</field>
</record>
<template id="demo_report_view">
<t t-call="report.html_container">
<t t-call="report.external_layout">
<div class="page">
<ul>
<li t-foreach="docs" t-as="doc">
<t t-esc="doc.name" />
</li>
</ul>
</div>
</t>
</t>
</template>
</data>
</openerp>

5
report_qweb_pdf_watermark/models/__init__.py

@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
# © 2016 Therp BV <http://therp.nl>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import ir_actions_report_xml
from . import report

14
report_qweb_pdf_watermark/models/ir_actions_report_xml.py

@ -0,0 +1,14 @@
# -*- coding: utf-8 -*-
# © 2016 Therp BV <http://therp.nl>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import fields, models
class IrActionsReportXml(models.Model):
_inherit = 'ir.actions.report.xml'
pdf_watermark = fields.Binary('Watermark')
pdf_watermark_expression = fields.Char(
'Watermark expression', help='An expression yielding the base64 '
'encoded data to be used as watermark. \n'
'You have access to variables `env` and `docs`')

87
report_qweb_pdf_watermark/models/report.py

@ -0,0 +1,87 @@
# -*- coding: utf-8 -*-
# © 2016 Therp BV <http://therp.nl>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from base64 import b64decode
from logging import getLogger
from pyPdf import PdfFileWriter, PdfFileReader
from pyPdf.utils import PdfReadError
from PIL import Image
from StringIO import StringIO
from openerp import api, models, tools
logger = getLogger(__name__)
class Report(models.Model):
_inherit = 'report'
@api.v7
def get_pdf(
self, cr, uid, ids, report_name, html=None, data=None, context=None
):
# pylint: disable=R8110
# this override cannot be done in v8 api
result = super(Report, self).get_pdf(
cr, uid, ids, report_name, html=html, data=data,
context=context
)
report = self._get_report_from_name(cr, uid, report_name)
watermark = None
if report.pdf_watermark:
watermark = b64decode(report.pdf_watermark)
else:
env = api.Environment(cr, uid, context)
watermark = tools.safe_eval(
report.pdf_watermark_expression or 'None',
dict(env=env, docs=env[report.model].browse(ids)),
)
if watermark:
watermark = b64decode(watermark)
if not watermark:
return result
pdf = PdfFileWriter()
pdf_watermark = None
try:
pdf_watermark = PdfFileReader(StringIO(watermark))
except PdfReadError:
# let's see if we can convert this with pillow
try:
image = Image.open(StringIO(watermark))
pdf_buffer = StringIO()
if image.mode != 'RGB':
image = image.convert('RGB')
resolution = image.info.get(
'dpi', report.paperformat_id.dpi or 90
)
if isinstance(resolution, tuple):
resolution = resolution[0]
image.save(pdf_buffer, 'pdf', resolution=resolution)
pdf_watermark = PdfFileReader(pdf_buffer)
except:
logger.exception('Failed to load watermark')
if not pdf_watermark:
logger.error(
'No usable watermark found, got %s...', watermark[:100]
)
return result
if pdf_watermark.numPages < 1:
logger.error('Your watermark pdf does not contain any pages')
return result
if pdf_watermark.numPages > 1:
logger.debug('Your watermark pdf contains more than one page, '
'all but the first one will be ignored')
for page in PdfFileReader(StringIO(result)).pages:
watermark_page = pdf.addBlankPage(
page.mediaBox.getWidth(), page.mediaBox.getHeight()
)
watermark_page.mergePage(pdf_watermark.getPage(0))
watermark_page.mergePage(page)
pdf_content = StringIO()
pdf.write(pdf_content)
return pdf_content.getvalue()

BIN
report_qweb_pdf_watermark/static/description/icon.png

After

Width: 128  |  Height: 128  |  Size: 9.2 KiB

4
report_qweb_pdf_watermark/tests/__init__.py

@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# © 2016 Therp BV <http://therp.nl>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import test_report_qweb_pdf_watermark

32
report_qweb_pdf_watermark/tests/test_report_qweb_pdf_watermark.py

@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
# © 2016 Therp BV <http://therp.nl>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp.tests.common import TransactionCase
class TestReportQwebPdfWatermark(TransactionCase):
def test_report_qweb_pdf_watermark(self):
# with our image, we have three
self._test_report_images(3)
self.env.ref('report_qweb_pdf_watermark.demo_report').write({
'pdf_watermark_expression': False,
})
# without, we have two
self._test_report_images(2)
self.env.ref('report_qweb_pdf_watermark.demo_report').write({
'pdf_watermark': self.env.user.company_id.logo,
})
# and now we should have three again
self._test_report_images(3)
def _test_report_images(self, number):
pdf = self.registry['report'].get_pdf(
self.cr,
self.uid,
self.env['res.users'].search([]).ids,
'report_qweb_pdf_watermark.demo_report_view',
context={}
)
self.assertEqual(pdf.count('/Subtype /Image'), number)

15
report_qweb_pdf_watermark/views/ir_actions_report_xml.xml

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<record id="act_report_xml_view" model="ir.ui.view">
<field name="model">ir.actions.report.xml</field>
<field name="inherit_id" ref="base.act_report_xml_view" />
<field name="arch" type="xml">
<field name="attachment" position="after">
<field name="pdf_watermark" attrs="{'invisible': [('report_type', '!=', 'qweb-pdf')]}" />
<field name="pdf_watermark_expression" attrs="{'invisible': [('report_type', '!=', 'qweb-pdf')]}" groups="base.group_no_one" />
</field>
</field>
</record>
</data>
</openerp>
Loading…
Cancel
Save