69 lines
3.4 KiB
Python
69 lines
3.4 KiB
Python
# -*- coding: utf-8 -*-
|
|
import base64
|
|
import io
|
|
import logging
|
|
from PIL import Image
|
|
|
|
from odoo import http
|
|
from odoo.http import request
|
|
from odoo.tools.image import image_process
|
|
from odoo.addons.sign.controllers.main import Sign
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
class SignController(Sign):
|
|
|
|
@http.route(['/sign/sign/<int:request_id>/<token>'], type='jsonrpc', auth='public')
|
|
def sign_document(self, request_id, token, signature=None, items=None, **kwargs):
|
|
if items:
|
|
# Filter items that look like images (base64)
|
|
# We can't easily know the type of item just from the ID without a lookup
|
|
# But we can try to decode and compress if it looks like a large base64 string
|
|
|
|
# Optimization: Fetch all item types at once to identify image field types
|
|
item_ids = [int(k) for k in items.keys()]
|
|
sign_items = request.env['sign.item'].sudo().browse(item_ids)
|
|
image_items_ids = set(sign_items.filtered(lambda i: i.type_id.item_type == 'image').ids)
|
|
|
|
for key, value in items.items():
|
|
if int(key) in image_items_ids and value and isinstance(value, str):
|
|
if value.startswith('/sign/image/'):
|
|
# Skip URLs (handled by sign_sequence_field or already processed)
|
|
continue
|
|
|
|
try:
|
|
# Value comes as "data:image/png;base64,..." usually
|
|
# But Odoo sometimes strips header or not.
|
|
# sign_image_upload.js sends the full data URL.
|
|
|
|
header = None
|
|
image_data = value
|
|
if ',' in value:
|
|
header, image_data = value.split(',', 1)
|
|
|
|
# Compress
|
|
# Decode
|
|
image_bytes = base64.b64decode(image_data)
|
|
|
|
# Process image: limit size to max 1920x1920 and reasonable quality
|
|
# image_process returns the processed image binary
|
|
processed_image = image_process(image_bytes, size=(1920, 1920), quality=80, output_format='JPEG')
|
|
|
|
# Re-encode
|
|
new_base64 = base64.b64encode(processed_image).decode('utf-8')
|
|
|
|
# Re-attach header if it was there, but ensure it matches new format (JPEG)
|
|
# Actually, keeping original header type might be misleading if we converted to JPEG.
|
|
# But for Odoo chatter/display, usually data:image/jpeg;base64 is safer if we converted.
|
|
|
|
new_value = f"data:image/jpeg;base64,{new_base64}"
|
|
items[key] = new_value
|
|
|
|
_logger.info(f"Compressed image for item {key}: {len(value)} -> {len(new_value)} chars")
|
|
|
|
except Exception as e:
|
|
_logger.warning(f"Failed to compress image for item {key}: {e}")
|
|
# Leave original value if compression fails
|
|
|
|
return super().sign_document(request_id, token, signature=signature, items=items, **kwargs)
|