[DOC] mail: clean some docstrings and helpers

As I was passing by I found some docstrings or helpers could be updated or
rephrased a bit more clearly. This is free as in free beers, without beers.

Some code about mail features (posting) may also be re-indented to ease
understanding of future modifications. Or just because we had to read
it and go through many files. Still free beers.

LINKS

Task ID-2477444
Prepares Task ID-2377974 (trace management cleaning task)
Prepares Task ID-2070632 (channel members main task)
Prepares Task ID-2419762 (channel members followup task)
COM PR odoo/odoo#67382
UPG PR odoo/upgrade#2245
This commit is contained in:
Thibault Delavallée
2021-03-05 15:20:53 +00:00
parent cc1780cdbc
commit d2079b1fca
5 changed files with 119 additions and 32 deletions
+8 -5
View File
@@ -50,11 +50,14 @@ class MailChatController(BusController):
email_from = mail_channel.anonymous_name or mail_channel.create_uid.company_id.catchall_formatted
# post a message without adding followers to the channel. email_from=False avoid to get author from email data
body = tools.plaintext2html(message_content)
message = mail_channel.with_context(mail_create_nosubscribe=True).message_post(author_id=author_id,
email_from=email_from, body=body,
message_type='comment',
subtype_xmlid='mail.mt_comment')
return message and message.id or False
message = mail_channel.with_context(mail_create_nosubscribe=True).message_post(
author_id=author_id,
email_from=email_from,
body=body,
message_type='comment',
subtype_xmlid='mail.mt_comment'
)
return message.id if message else False
@route(['/mail/chat_history'], type="json", auth="public", cors="*")
def mail_chat_history(self, uuid, last_id=False, limit=20):
+14 -8
View File
@@ -260,10 +260,8 @@ GROUP BY fol.id%s%s""" % (
res_model and the document res_ids. This method does not handle access rights. This is the
role of the caller to ensure there is no security breach.
:param partner_subtypes: optional subtypes for new partner followers. If not given, default
ones are computed;
:param channel_subtypes: optional subtypes for new channel followers. If not given, default
ones are computed;
:param partner_subtypes: see ``_add_followers``. If not given, default ones are computed.
:param channel_subtypes: see ``_add_followers``. If not given, default ones are computed.
:param customer_ids: see ``_add_default_followers``
:param check_existing: see ``_add_followers``;
:param existing_policy: see ``_add_followers``;
@@ -329,10 +327,18 @@ GROUP BY fol.id%s%s""" % (
* second one is a dict which keys are follower ids. Value is a dict of values valid for
updating the related follower record;
:param check_existing: if True, check for existing followers for given documents and handle
them according to existing_policy parameter. Setting to False allows to save some computation
if caller is sure there are no conflict for followers;
:param existing policy: if check_existing, tells what to do with already-existing followers:
:param partner_subtypes: optional subtypes for new partner followers. This
is a dict whose keys are partner IDs and value subtype IDs for that
partner.
:param channel_subtypes: optional subtypes for new channel followers. This
is a dict whose keys are channel IDs and value subtype IDs for that
channel.
:param check_existing: if True, check for existing followers for given
documents and handle them according to existing_policy parameter.
Setting to False allows to save some computation if caller is sure
there are no conflict for followers;
:param existing policy: if check_existing, tells what to do with already
existing followers:
* skip: simply skip existing followers, do not touch them;
* force: update existing with given subtypes only;
+45 -3
View File
@@ -5,7 +5,6 @@ import logging
import re
from binascii import Error as binascii_error
from collections import defaultdict
from operator import itemgetter
from odoo import _, api, Command, fields, models, modules, tools
@@ -19,8 +18,51 @@ _image_dataurl = re.compile(r'(data:image/[a-z]+?);base64,([a-z0-9+/\n]{3,}=*)\n
class Message(models.Model):
""" Messages model: system notification (replacing res.log notifications),
comments (OpenChatter discussion) and incoming emails. """
""" Message model: notification (system, replacing res.log notifications),
comment (user input), email (incoming emails) and user_notification
(user-specific notification)
Note:: State management / Error codes / Failure types summary
* mail.notification
* notification_status
'ready', 'sent', 'bounce', 'exception', 'canceled'
* notification_type
'inbox', 'email', 'sms' (SMS addon), 'snail' (snailmail addon)
* failure_type
# mail
"SMTP", "RECIPIENT", "BOUNCE", "UNKNOWN"
# sms (SMS addon)
'sms_number_missing', 'sms_number_format', 'sms_credit',
'sms_server', 'sms_acc'
# snailmail (snailmail addon)
'sn_credit', 'sn_trial', 'sn_price', 'sn_fields',
'sn_format', 'sn_error'
* mail.mail
* state
'outgoing', 'sent', 'received', 'exception', 'cancel'
* failure_reason: text
* sms.sms (SMS addon)
* state
'outgoing', 'sent', 'error', 'canceled'
* error_code
'sms_number_missing', 'sms_number_format', 'sms_credit',
'sms_server', 'sms_acc',
# mass mode specific codes
'sms_blacklist', 'sms_duplicate'
* snailmail.letter (snailmail addon)
* state
'pending', 'sent', 'error', 'canceled'
* error_code
'CREDIT_ERROR', 'TRIAL_ERROR', 'NO_PRICE_AVAILABLE', 'FORMAT_ERROR',
'UNKNOWN_ERROR',
See ``mailing.trace`` model in mass_mailing application for mailing trace
information.
"""
_name = 'mail.message'
_description = 'Message'
_order = 'id desc'
+15 -15
View File
@@ -1761,13 +1761,15 @@ class MailThread(models.AbstractModel):
:param str body: body of the message, usually raw HTML that will
be sanitized
:param str subject: subject of the message
:param str message_type: see mail_message.message_type field. Can be anything but
:param str message_type: see mail_message.message_type field. Can be anything but
user_notification, reserved for message_notify
:param int parent_id: handle thread formation
:param int subtype_id: subtype_id of the message, mainly use fore
followers mechanism
:param list(int) partner_ids: partner_ids to notify
:param list(int) channel_ids: channel_ids to notify
:param int subtype_id: subtype_id of the message, used mainly use for
followers notification mechanism;
:param list(int) partner_ids: partner_ids to notify in addition to partners
computed based on subtype / followers matching;
:param list(int) channel_ids: channel_ids to notify in addition to partners
computed based on subtype / followers matching;
:param list(tuple(str,str), tuple(str,str, dict) or int) attachments : list of attachment tuples in the form
``(name,content)`` or ``(name,content, info)``, where content is NOT base64 encoded
:param list id attachment_ids: list of existing attachement to link to this message
@@ -1783,13 +1785,17 @@ class MailThread(models.AbstractModel):
msg_kwargs = dict((key, val) for key, val in kwargs.items() if key in self.env['mail.message']._fields)
notif_kwargs = dict((key, val) for key, val in kwargs.items() if key not in msg_kwargs)
# preliminary value safety check
partner_ids = set(partner_ids or [])
channel_ids = set(channel_ids or [])
if self._name == 'mail.thread' or not self.id or message_type == 'user_notification':
raise ValueError('message_post should only be call to post message on record. Use message_notify instead')
raise ValueError(_('Posting a message should be done on a business document. Use message_notify to send a notification to an user.'))
if 'model' in msg_kwargs or 'res_id' in msg_kwargs:
raise ValueError("message_post doesn't support model and res_id parameters anymore. Please call message_post on record.")
raise ValueError(_("message_post does not support model and res_id parameters anymore. Please call message_post on record."))
if 'subtype' in kwargs:
raise ValueError("message_post doesn't support subtype parameter anymore. Please give a valid subtype_id or subtype_xmlid value instead.")
raise ValueError(_("message_post does not support subtype parameter anymore. Please give a valid subtype_id or subtype_xmlid value instead."))
if any(not isinstance(pc_id, int) for pc_id in partner_ids | channel_ids):
raise ValueError(_('message_post partner_ids and channel_ids must be integer list, not commands.'))
self = self._fallback_lang() # add lang to context imediatly since it will be usefull in various flows latter.
@@ -1798,12 +1804,6 @@ class MailThread(models.AbstractModel):
self.check_access_rule('read')
record_name = record_name or self.display_name
partner_ids = set(partner_ids or [])
channel_ids = set(channel_ids or [])
if any(not isinstance(pc_id, int) for pc_id in partner_ids | channel_ids):
raise ValueError('message_post partner_ids and channel_ids must be integer list, not commands')
# Find the message's author
author_id, email_from = self._message_compute_author(author_id, email_from, raise_exception=True)
+37 -1
View File
@@ -8,7 +8,43 @@ class MailingTrace(models.Model):
""" MailingTrace models the statistics collected about emails. Those statistics
are stored in a separated model and table to avoid bloating the mail_mail table
with statistics values. This also allows to delete emails send with mass mailing
without loosing the statistics about them. """
without loosing the statistics about them.
Note:: State management / Error codes / Failure types summary
* state
'outgoing', 'sent', 'opened', 'replied',
'exception', 'bounced', 'ignored'
* failure_type
# mass_mailing
"SMTP", "RECIPIENT", "BOUNCE", "UNKNOWN"
# mass_mailing_sms
'sms_number_missing', 'sms_number_format', 'sms_credit',
'sms_server', 'sms_acc'
# mass_mailing_sms mass mode specific codes
'sms_blacklist', 'sms_duplicate'
* ignored:
* mail: set in get_mail_values in composer, if email is blacklisted
(mail) or in opt_out / seen list (mass_mailing) or email_to is void
or incorrectly formatted (mass_mailing) - based on mail cancel state
* sms: set in _prepare_mass_sms_trace_values in composer if sms is
in cancel state; either blacklisted (sms) or in opt_out / seen list
(sms);
* difference: void mail -> cancel -> ignore, void sms -> error
sms_number_missing -> exception
* difference: invalid mail -> cancel -> ignore, invalid sms -> error
sms_number_format -> sent + bounce;
* exception: set in _postprocess_sent_message (_postprocess_iap_sent_sms)
if mail (sms) not sent with failure type, reset if sent; also set for
sms in _prepare_mass_sms_trace_values if void number
* sent: set in _postprocess_sent_message (_postprocess_iap_sent_sms) if
mail (sms) sent
* clicked: triggered by add_click
* opened: triggered by add_click + blank gif (mail) + gateway reply (mail)
* replied: triggered by gateway reply (mail)
* bounced: triggered by gateway bounce (mail) or in _prepare_mass_sms_trace_values
if sms_number_format error when sending sms (sms)
"""
_name = 'mailing.trace'
_description = 'Mailing Statistics'
_rec_name = 'id'