In order to allow modifying background images, we need information on the image, this is done by creating a placeholder img and calling the loadImageInfo function on it. However this function did not account for the case where an image had not src attribute, which causes an unnecessary rpc. Other problems could arise from this as an attachment that doesn't have the correct mimetype but has a matching src could be returned, causing its image_src field to be false, which we would then attempt to load as a valid image, causing crashes. This commit fixes that by not trying to load image infos when the src of an image is empty, only looking for attachments of the supported mimetypes, and also checking that we actually did receive an image_src before setting it as the original src of the image, which will prevent accidentally trying to load a falsy src as an actual image. closes odoo/odoo#60982 X-original-commit: b0993370b6fcec1f966e4bf2994eee7f31da82d5 Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
63 lines
2.7 KiB
Python
63 lines
2.7 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
from werkzeug.urls import url_quote
|
|
|
|
from odoo import api, models, fields, tools
|
|
|
|
SUPPORTED_IMAGE_MIMETYPES = ['image/gif', 'image/jpe', 'image/jpeg', 'image/jpg', 'image/gif', 'image/png', 'image/svg+xml']
|
|
|
|
class IrAttachment(models.Model):
|
|
|
|
_inherit = "ir.attachment"
|
|
|
|
local_url = fields.Char("Attachment URL", compute='_compute_local_url')
|
|
image_src = fields.Char(compute='_compute_image_src')
|
|
image_width = fields.Integer(compute='_compute_image_size')
|
|
image_height = fields.Integer(compute='_compute_image_size')
|
|
original_id = fields.Many2one('ir.attachment', string="Original (unoptimized, unresized) attachment", index=True)
|
|
|
|
def _compute_local_url(self):
|
|
for attachment in self:
|
|
if attachment.url:
|
|
attachment.local_url = attachment.url
|
|
else:
|
|
attachment.local_url = '/web/image/%s?unique=%s' % (attachment.id, attachment.checksum)
|
|
|
|
@api.depends('mimetype', 'url', 'name')
|
|
def _compute_image_src(self):
|
|
for attachment in self:
|
|
# Only add a src for supported images
|
|
if attachment.mimetype not in SUPPORTED_IMAGE_MIMETYPES:
|
|
attachment.image_src = False
|
|
continue
|
|
|
|
if attachment.type == 'url':
|
|
attachment.image_src = attachment.url
|
|
else:
|
|
# Adding unique in URLs for cache-control
|
|
unique = attachment.checksum[:8]
|
|
if attachment.url:
|
|
# For attachments-by-url, unique is used as a cachebuster. They
|
|
# currently do not leverage max-age headers.
|
|
attachment.image_src = '%s?unique=%s' % (attachment.url, unique)
|
|
else:
|
|
name = url_quote(attachment.name)
|
|
attachment.image_src = '/web/image/%s-%s/%s' % (attachment.id, unique, name)
|
|
|
|
@api.depends('datas')
|
|
def _compute_image_size(self):
|
|
for attachment in self:
|
|
try:
|
|
image = tools.base64_to_image(attachment.datas)
|
|
attachment.image_width = image.width
|
|
attachment.image_height = image.height
|
|
except Exception:
|
|
attachment.image_width = 0
|
|
attachment.image_height = 0
|
|
|
|
def _get_media_info(self):
|
|
"""Return a dict with the values that we need on the media dialog."""
|
|
self.ensure_one()
|
|
return self._read_format(['id', 'name', 'description', 'mimetype', 'checksum', 'url', 'type', 'res_id', 'res_model', 'public', 'access_token', 'image_src', 'image_width', 'image_height', 'original_id'])[0]
|