102 lines
3.6 KiB
Python
102 lines
3.6 KiB
Python
|
|
# -*- coding: utf-8 -*-
|
||
|
|
# ir_attachment.py
|
||
|
|
from odoo import models, _
|
||
|
|
from odoo.exceptions import UserError
|
||
|
|
import base64
|
||
|
|
|
||
|
|
|
||
|
|
def human_file_size(size_bytes):
|
||
|
|
"""Convert bytes to human readable format"""
|
||
|
|
if size_bytes == 0:
|
||
|
|
return "0 B"
|
||
|
|
size_name = ("B", "KB", "MB", "GB", "TB")
|
||
|
|
import math
|
||
|
|
i = int(math.floor(math.log(size_bytes, 1024)))
|
||
|
|
p = math.pow(1024, i)
|
||
|
|
s = round(size_bytes / p, 2)
|
||
|
|
return "%s %s" % (s, size_name[i])
|
||
|
|
|
||
|
|
|
||
|
|
class IrHttp(models.AbstractModel):
|
||
|
|
_inherit = "ir.http"
|
||
|
|
|
||
|
|
def session_info(self):
|
||
|
|
print("session_info called ✅")
|
||
|
|
|
||
|
|
session_info = super().session_info()
|
||
|
|
|
||
|
|
user = self.env.user
|
||
|
|
current_user_id = user.id
|
||
|
|
|
||
|
|
user_id = self.env['res.users'].browse(current_user_id)
|
||
|
|
|
||
|
|
max_attachment_size_bytes = None
|
||
|
|
|
||
|
|
if user_id and user_id.user_select_attachment_size_unit and user_id.users_general_size_limit_attachment > 0:
|
||
|
|
unit = user_id.user_select_attachment_size_unit
|
||
|
|
size = user_id.users_general_size_limit_attachment
|
||
|
|
|
||
|
|
if unit == 'kb':
|
||
|
|
max_attachment_size_bytes = size * 1024
|
||
|
|
elif unit == 'mb':
|
||
|
|
max_attachment_size_bytes = size * 1024 * 1024
|
||
|
|
else:
|
||
|
|
max_attachment_size_bytes = size * 1024 * 1024
|
||
|
|
|
||
|
|
else:
|
||
|
|
enable_general_limit = self.env['ir.config_parameter'].sudo().get_param(
|
||
|
|
'pys_attachment_size_limitation.enable_general_size_limit_attachment',
|
||
|
|
False
|
||
|
|
)
|
||
|
|
|
||
|
|
if enable_general_limit:
|
||
|
|
unit = self.env["ir.config_parameter"].sudo().get_param(
|
||
|
|
"pys_attachment_size_limitation.select_attachment_size_unit",
|
||
|
|
)
|
||
|
|
|
||
|
|
size = int(
|
||
|
|
self.env["ir.config_parameter"].sudo().get_param(
|
||
|
|
"pys_attachment_size_limitation.general_size_limit_attachment",
|
||
|
|
0
|
||
|
|
)
|
||
|
|
)
|
||
|
|
|
||
|
|
if unit and size > 0:
|
||
|
|
if unit == 'kb':
|
||
|
|
max_attachment_size_bytes = size * 1024
|
||
|
|
elif unit == 'mb':
|
||
|
|
max_attachment_size_bytes = size * 1024 * 1024
|
||
|
|
else:
|
||
|
|
max_attachment_size_bytes = size * 1024 * 1024
|
||
|
|
|
||
|
|
# Ensure it's an integer
|
||
|
|
session_info["max_attachment_size"] = int(max_attachment_size_bytes) if max_attachment_size_bytes else None
|
||
|
|
|
||
|
|
print("max_attachment_size (in bytes):", session_info["max_attachment_size"])
|
||
|
|
return session_info
|
||
|
|
|
||
|
|
|
||
|
|
class IrAttachment(models.Model):
|
||
|
|
_inherit = 'ir.attachment'
|
||
|
|
|
||
|
|
def create(self, vals_list):
|
||
|
|
# Check size before creation
|
||
|
|
for vals in vals_list:
|
||
|
|
if vals.get('datas'):
|
||
|
|
try:
|
||
|
|
decoded_data = base64.b64decode(vals['datas'])
|
||
|
|
max_size = self.env['ir.http'].session_info().get('max_attachment_size')
|
||
|
|
|
||
|
|
if max_size and max_size > 0 and len(decoded_data) > max_size:
|
||
|
|
raise UserError(_(
|
||
|
|
"Attachment size (%s) exceeds the maximum allowed size (%s)."
|
||
|
|
) % (
|
||
|
|
human_file_size(len(decoded_data)),
|
||
|
|
human_file_size(max_size)
|
||
|
|
))
|
||
|
|
except Exception as e:
|
||
|
|
if isinstance(e, UserError):
|
||
|
|
raise
|
||
|
|
# If base64 decoding fails, continue
|
||
|
|
|
||
|
|
return super().create(vals_list)
|