[IMP] base, web: use converted WebP images in wkhtmltopdf

Wkhtmltopdf is unable to render WebP images.
This commit intercepts the requests for the image data during PDF
reports rendering to replace them by the converted image that was
uploaded with it.

task-2774352

Part-of: odoo/odoo#85494
This commit is contained in:
Benoit Socias
2023-07-15 05:10:46 +02:00
parent 4095539765
commit 8210bf4f27
2 changed files with 22 additions and 3 deletions
@@ -794,6 +794,7 @@ class IrActionsReport(models.Model):
if (tools.config['test_enable'] or tools.config['test_file']) and not self.env.context.get('force_report_rendering'):
return self._render_qweb_html(report_ref, res_ids, data=data)
self = self.with_context(webp_as_jpg=True)
collected_streams = self._render_qweb_pdf_prepare_streams(report_ref, data, res_ids=res_ids)
# access the report details with sudo() but keep evaluation context as current user
+21 -3
View File
@@ -359,6 +359,7 @@ structure.
"""
import base64
import fnmatch
import io
import logging
@@ -384,7 +385,7 @@ from odoo.tools.constants import SUPPORTED_DEBUGGER, EXTERNAL_ASSET
from odoo.tools.safe_eval import assert_valid_codeobj, _BUILTINS, to_opcodes, _EXPR_OPCODES, _BLACKLIST
from odoo.tools.json import scriptsafe
from odoo.tools.misc import str2bool
from odoo.tools.image import image_data_uri
from odoo.tools.image import image_data_uri, FILETYPE_BASE64_MAGICWORD
from odoo.http import request
from odoo.tools.profiler import QwebTracker
from odoo.exceptions import UserError, AccessDenied, AccessError, MissingError, ValidationError
@@ -861,6 +862,24 @@ class IrQWeb(models.AbstractModel):
# values for running time
def _get_converted_image_data_uri(self, base64_source):
if self.env.context.get('webp_as_jpg'):
mimetype = FILETYPE_BASE64_MAGICWORD.get(base64_source[:1], 'png')
if 'webp' in mimetype:
# Use converted image so that is recognized by wkhtmltopdf.
bin_source = base64.b64decode(base64_source)
Attachment = self.env['ir.attachment']
checksum = Attachment._compute_checksum(bin_source)
origins = Attachment.search([['res_field', '!=', None], ['checksum', '=', checksum]])
if origins:
converted = Attachment.search([
['res_model', '=', 'ir.attachment'],
['res_id', 'in', origins.ids],
], limit=1)
if converted:
base64_source = converted.datas
return image_data_uri(base64_source)
def _prepare_environment(self, values):
""" Prepare the values and context that will sent to the
compiled and evaluated function.
@@ -878,7 +897,6 @@ class IrQWeb(models.AbstractModel):
values.setdefault('debug', debug)
values.setdefault('user_id', self.env.user.with_env(self.env))
values.setdefault('res_company', self.env.company.sudo())
values.update(
request=request, # might be unbound if we're not in an httprequest context
test_mode_enabled=bool(config['test_enable'] or config['test_file']),
@@ -887,7 +905,7 @@ class IrQWeb(models.AbstractModel):
time=safe_eval.time,
datetime=safe_eval.datetime,
relativedelta=relativedelta,
image_data_uri=image_data_uri,
image_data_uri=self._get_converted_image_data_uri,
# specific 'math' functions to ease rounding in templates and lessen controller marshmalling
floor=math.floor,
ceil=math.ceil,