portal/models/mail_message.py

125 lines
5.3 KiB
Python
Raw Permalink Normal View History

2024-05-03 12:57:08 +03:00
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import models
from odoo.http import request
from odoo.tools import format_datetime
class MailMessage(models.Model):
_inherit = 'mail.message'
def portal_message_format(self, options=None):
""" Simpler and portal-oriented version of 'message_format'. Purpose
is to prepare, organize and format values required by frontend widget
(frontend Chatter).
This public API asks for read access on messages before doing the
actual computation in the private implementation.
:param dict options: options, used notably for inheritance and adding
specific fields or properties to compute;
:return list: list of dict, one per message in self. Each dict contains
values for either fields, either properties derived from fields.
"""
self.check_access_rule('read')
return self._portal_message_format(
self._portal_get_default_format_properties_names(options=options),
options=options,
)
def _portal_get_default_format_properties_names(self, options=None):
""" Fields and values to compute for portal format.
:param dict options: options, used notably for inheritance and adding
specific fields or properties to compute;
:return set: fields or properties derived from fields
"""
return {
'attachment_ids',
'author_avatar_url',
'author_id',
'body',
'date',
'id',
'is_internal',
'is_message_subtype_note',
'published_date_str',
'subtype_id',
}
def _portal_message_format(self, properties_names, options=None):
""" Format messages for portal frontend. This private implementation
does not check for access that should be checked beforehand.
Notes:
* when asking for attachments: ensure an access token is present then
access them (using sudo);
:param set properties_names: fields or properties derived from fields
for which we are going to compute values;
:return list: list of dict, one per message in self. Each dict contains
values for either fields, either properties derived from fields.
"""
message_to_attachments = {}
if 'attachment_ids' in properties_names:
properties_names.remove('attachment_ids')
attachments_sudo = self.sudo().attachment_ids
attachments_sudo.generate_access_token()
related_attachments = {
att_read_values['id']: att_read_values
for att_read_values in attachments_sudo.read(
["access_token", "checksum", "id", "mimetype", "name", "res_id", "res_model"]
)
}
message_to_attachments = {
message.id: [
self._portal_message_format_attachments(related_attachments[att_id])
for att_id in message.attachment_ids.ids
]
for message in self.sudo()
}
fnames = {
property_name for property_name in properties_names
if property_name in self._fields
}
vals_list = self._read_format(fnames)
note_id = self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note')
for message, values in zip(self, vals_list):
if message_to_attachments:
values['attachment_ids'] = message_to_attachments.get(message.id, {})
if 'author_avatar_url' in properties_names:
if options and 'token' in options:
values['author_avatar_url'] = f'/mail/avatar/mail.message/{message.id}/author_avatar/50x50?access_token={options["token"]}'
elif options and options.keys() >= {"hash", "pid"}:
values['author_avatar_url'] = f'/mail/avatar/mail.message/{message.id}/author_avatar/50x50?_hash={options["hash"]}&pid={options["pid"]}'
else:
values['author_avatar_url'] = f'/web/image/mail.message/{message.id}/author_avatar/50x50'
if 'is_message_subtype_note' in properties_names:
values['is_message_subtype_note'] = (values.get('subtype_id') or [False, ''])[0] == note_id
if 'published_date_str' in properties_names:
values['published_date_str'] = format_datetime(self.env, values['date']) if values.get('date') else ''
return vals_list
def _portal_message_format_attachments(self, attachment_values):
""" From 'attachment_values' get an updated version formatted for
frontend display.
:param dict attachment_values: values coming from reading attachments
in database;
:return dict: updated attachment_values
"""
safari = request and request.httprequest.user_agent and request.httprequest.user_agent.browser == 'safari'
attachment_values['filename'] = attachment_values['name']
attachment_values['mimetype'] = (
'application/octet-stream' if safari and
'video' in (attachment_values["mimetype"] or "")
else attachment_values["mimetype"])
return attachment_values