[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:
@@ -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):
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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'
|
||||
|
||||
Reference in New Issue
Block a user