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.

97 lines
3.3 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 PIL import Image
  7. from StringIO import StringIO
  8. from pyPdf import PdfFileWriter, PdfFileReader
  9. from pyPdf.utils import PdfReadError
  10. try:
  11. from PyPDF2 import PdfFileWriter, PdfFileReader # pylint: disable=W0404
  12. from PyPDF2.utils import PdfReadError # pylint: disable=W0404
  13. except ImportError:
  14. pass
  15. try:
  16. # we need this to be sure PIL has loaded PDF support
  17. from PIL import PdfImagePlugin # noqa: F401
  18. except ImportError:
  19. pass
  20. from openerp import api, models, tools
  21. logger = getLogger(__name__)
  22. class Report(models.Model):
  23. _inherit = 'report'
  24. @api.v7
  25. def get_pdf(
  26. self, cr, uid, ids, report_name, html=None, data=None, context=None
  27. ):
  28. # pylint: disable=R8110
  29. # this override cannot be done in v8 api
  30. result = super(Report, self).get_pdf(
  31. cr, uid, ids, report_name, html=html, data=data,
  32. context=context
  33. )
  34. report = self._get_report_from_name(cr, uid, report_name)
  35. watermark = None
  36. if report.pdf_watermark:
  37. watermark = b64decode(report.pdf_watermark)
  38. else:
  39. env = api.Environment(cr, uid, context)
  40. watermark = tools.safe_eval(
  41. report.pdf_watermark_expression or 'None',
  42. dict(env=env, docs=env[report.model].browse(ids)),
  43. )
  44. if watermark:
  45. watermark = b64decode(watermark)
  46. if not watermark:
  47. return result
  48. pdf = PdfFileWriter()
  49. pdf_watermark = None
  50. try:
  51. pdf_watermark = PdfFileReader(StringIO(watermark))
  52. except PdfReadError:
  53. # let's see if we can convert this with pillow
  54. try:
  55. image = Image.open(StringIO(watermark))
  56. pdf_buffer = StringIO()
  57. if image.mode != 'RGB':
  58. image = image.convert('RGB')
  59. resolution = image.info.get(
  60. 'dpi', report.paperformat_id.dpi or 90
  61. )
  62. if isinstance(resolution, tuple):
  63. resolution = resolution[0]
  64. image.save(pdf_buffer, 'pdf', resolution=resolution)
  65. pdf_watermark = PdfFileReader(pdf_buffer)
  66. except:
  67. logger.exception('Failed to load watermark')
  68. if not pdf_watermark:
  69. logger.error(
  70. 'No usable watermark found, got %s...', watermark[:100]
  71. )
  72. return result
  73. if pdf_watermark.numPages < 1:
  74. logger.error('Your watermark pdf does not contain any pages')
  75. return result
  76. if pdf_watermark.numPages > 1:
  77. logger.debug('Your watermark pdf contains more than one page, '
  78. 'all but the first one will be ignored')
  79. for page in PdfFileReader(StringIO(result)).pages:
  80. watermark_page = pdf.addBlankPage(
  81. page.mediaBox.getWidth(), page.mediaBox.getHeight()
  82. )
  83. watermark_page.mergePage(pdf_watermark.getPage(0))
  84. watermark_page.mergePage(page)
  85. pdf_content = StringIO()
  86. pdf.write(pdf_content)
  87. return pdf_content.getvalue()