87 lines
3.5 KiB
Python
87 lines
3.5 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': '.gif',
|
||
|
'image/jpe': '.jpe',
|
||
|
'image/jpeg': '.jpeg',
|
||
|
'image/jpg': '.jpg',
|
||
|
'image/png': '.png',
|
||
|
'image/svg+xml': '.svg',
|
||
|
'image/webp': '.webp',
|
||
|
}
|
||
|
|
||
|
|
||
|
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")
|
||
|
|
||
|
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':
|
||
|
if attachment.url.startswith('/'):
|
||
|
# Local URL
|
||
|
attachment.image_src = attachment.url
|
||
|
else:
|
||
|
name = url_quote(attachment.name)
|
||
|
attachment.image_src = '/web/image/%s-redirect/%s' % (attachment.id, name)
|
||
|
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.
|
||
|
separator = '&' if '?' in attachment.url else '?'
|
||
|
attachment.image_src = '%s%sunique=%s' % (attachment.url, separator, 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]
|
||
|
|
||
|
def _can_bypass_rights_on_media_dialog(self, **attachment_data):
|
||
|
""" This method is meant to be overridden, for instance to allow to
|
||
|
create image attachment despite the user not allowed to create
|
||
|
attachment, eg:
|
||
|
- Portal user uploading an image on the forum (bypass acl)
|
||
|
- Non admin user uploading an unsplash image (bypass binary/url check)
|
||
|
"""
|
||
|
return False
|