OCA reporting engine fork for dev and update.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

87 lines
3.1 KiB

  1. # -*- coding: utf-8 -*-
  2. # © 2016 Therp BV <http://therp.nl>
  3. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  4. from base64 import b64decode
  5. from logging import getLogger
  6. from pyPdf import PdfFileWriter, PdfFileReader
  7. from pyPdf.utils import PdfReadError
  8. from PIL import Image
  9. from StringIO import StringIO
  10. from odoo import api, models, tools
  11. from PIL import PdfImagePlugin # flake8: noqa
  12. # PdfImagePlugin must be loaded in order to work PNG to PDF transformation
  13. # This issue is related to Pillow creation, as can be seen in its source code:
  14. # https://github.com/python-pillow/Pillow/blob/master/PIL/PdfImagePlugin.py
  15. logger = getLogger(__name__)
  16. class Report(models.Model):
  17. _inherit = 'report'
  18. @api.model
  19. def get_pdf(self, docids, report_name, html=None, data=None):
  20. result = super(Report, self).get_pdf(
  21. docids, report_name, html=html, data=data)
  22. report = self._get_report_from_name(report_name)
  23. watermark = None
  24. if report.pdf_watermark:
  25. watermark = b64decode(report.pdf_watermark)
  26. else:
  27. watermark = tools.safe_eval(
  28. report.pdf_watermark_expression or 'None',
  29. dict(env=self.env, docs=self.env[report.model].browse(docids)),
  30. )
  31. if watermark:
  32. watermark = b64decode(watermark)
  33. if not watermark:
  34. return result
  35. pdf = PdfFileWriter()
  36. pdf_watermark = None
  37. try:
  38. pdf_watermark = PdfFileReader(StringIO(watermark))
  39. except PdfReadError:
  40. # let's see if we can convert this with pillow
  41. try:
  42. Image.init()
  43. image = Image.open(StringIO(watermark))
  44. pdf_buffer = StringIO()
  45. if image.mode != 'RGB':
  46. image = image.convert('RGB')
  47. resolution = image.info.get(
  48. 'dpi', report.paperformat_id.dpi or 90
  49. )
  50. if isinstance(resolution, tuple):
  51. resolution = resolution[0]
  52. image.save(pdf_buffer, 'pdf', resolution=resolution)
  53. pdf_watermark = PdfFileReader(pdf_buffer)
  54. except:
  55. logger.exception('Failed to load watermark')
  56. if not pdf_watermark:
  57. logger.error(
  58. 'No usable watermark found, got %s...', watermark[:100]
  59. )
  60. return result
  61. if pdf_watermark.numPages < 1:
  62. logger.error('Your watermark pdf does not contain any pages')
  63. return result
  64. if pdf_watermark.numPages > 1:
  65. logger.debug('Your watermark pdf contains more than one page, '
  66. 'all but the first one will be ignored')
  67. for page in PdfFileReader(StringIO(result)).pages:
  68. watermark_page = pdf.addBlankPage(
  69. page.mediaBox.getWidth(), page.mediaBox.getHeight()
  70. )
  71. watermark_page.mergePage(pdf_watermark.getPage(0))
  72. watermark_page.mergePage(page)
  73. pdf_content = StringIO()
  74. pdf.write(pdf_content)
  75. return pdf_content.getvalue()