[FIX] mail, mail_group: recipients of mail groups
Mailing lists (mail.group) should not send specific notification emails. Indeed there can be a lot of recipients and customizing each email can take time to compute. This leads to posting a message on a mail.group being very slow. It is now possible for a model to customize the notification email recipients computation. The first use is to ensure that mail.group encodes recipients using email_to instead of recipients_ids. This way less processing is performed on notification emails.
This commit is contained in:
parent
a1db9c3ac0
commit
d4a1eb4435
|
@ -211,15 +211,19 @@ class mail_notification(osv.Model):
|
|||
chunks = [email_pids[x:x + max_recipients] for x in xrange(0, len(email_pids), max_recipients)]
|
||||
email_ids = []
|
||||
for chunk in chunks:
|
||||
if message.model and message.res_id and self.pool.get(message.model) and hasattr(self.pool[message.model], 'message_get_recipient_values'):
|
||||
recipient_values = self.pool[message.model].message_get_recipient_values(cr, uid, message.res_id, notif_message=message, recipient_ids=chunk, context=context)
|
||||
else:
|
||||
recipient_values = self.pool['mail.thread'].message_get_recipient_values(cr, uid, message.res_id, notif_message=message, recipient_ids=chunk, context=context)
|
||||
mail_values = {
|
||||
'mail_message_id': message.id,
|
||||
'auto_delete': (context or {}).get('mail_auto_delete', True),
|
||||
'mail_server_id': (context or {}).get('mail_server_id', False),
|
||||
'body_html': body_html,
|
||||
'recipient_ids': [(4, id) for id in chunk],
|
||||
'references': references,
|
||||
}
|
||||
mail_values.update(custom_values)
|
||||
mail_values.update(recipient_values)
|
||||
email_ids.append(self.pool.get('mail.mail').create(cr, uid, mail_values, context=context))
|
||||
# NOTE:
|
||||
# 1. for more than 50 followers, use the queue system
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
from email.utils import formataddr
|
||||
|
||||
import openerp
|
||||
import openerp.tools as tools
|
||||
from openerp.osv import osv
|
||||
|
@ -240,3 +242,13 @@ class mail_group(osv.Model):
|
|||
headers['X-Forge-To'] = list_to
|
||||
res['headers'] = repr(headers)
|
||||
return res
|
||||
|
||||
def message_get_recipient_values(self, cr, uid, id, notif_message=None, recipient_ids=None, context=None):
|
||||
group = self.browse(cr, uid, id, context=context)
|
||||
# real mailing list: multiple recipients (hidden by X-Forge-To)
|
||||
if group.alias_domain and group.alias_name:
|
||||
return {
|
||||
'email_to': ','.join(formataddr((partner.name, partner.email)) for partner in self.pool['res.partner'].browse(cr, SUPERUSER_ID, recipient_ids, context=context)),
|
||||
'recipient_ids': [],
|
||||
}
|
||||
return super(mail_group, self).message_get_recipient_values(cr, uid, id, notif_message=notif_message, recipient_ids=recipient_ids, context=context)
|
||||
|
|
|
@ -755,6 +755,16 @@ class mail_thread(osv.AbstractModel):
|
|||
res = dict()
|
||||
return res
|
||||
|
||||
def message_get_recipient_values(self, cr, uid, id, notif_message=None, recipient_ids=None, context=None):
|
||||
""" Get specific notification recipient values to store on the notification
|
||||
mail_mail. Basic method just set the recipient partners as mail_mail
|
||||
recipients. Inherit this method to add custom behavior like using
|
||||
recipient email_to to bypass the recipint_ids heuristics in the
|
||||
mail sending mechanism. """
|
||||
return {
|
||||
'recipient_ids': [(4, pid) for pid in recipient_ids]
|
||||
}
|
||||
|
||||
#------------------------------------------------------
|
||||
# Mail gateway
|
||||
#------------------------------------------------------
|
||||
|
|
|
@ -47,9 +47,13 @@ class TestMail(common.SavepointCase):
|
|||
def send_email(self, cr, uid, message, *args, **kwargs):
|
||||
return message['Message-Id']
|
||||
|
||||
def mail_group_message_get_recipient_values(self, cr, uid, id, notif_message=None, recipient_ids=None, context=None):
|
||||
return self.pool['mail.thread'].message_get_recipient_values(cr, uid, id, notif_message=notif_message, recipient_ids=recipient_ids, context=context)
|
||||
|
||||
cls._init_mock_build_email()
|
||||
cls.registry('ir.mail_server')._patch_method('build_email', build_email)
|
||||
cls.registry('ir.mail_server')._patch_method('send_email', send_email)
|
||||
cls.registry('mail.group')._patch_method('message_get_recipient_values', mail_group_message_get_recipient_values)
|
||||
|
||||
# Usefull models
|
||||
cls.ir_model = cls.registry('ir.model')
|
||||
|
@ -133,4 +137,5 @@ class TestMail(common.SavepointCase):
|
|||
# Remove mocks
|
||||
cls.registry('ir.mail_server')._revert_method('build_email')
|
||||
cls.registry('ir.mail_server')._revert_method('send_email')
|
||||
cls.registry('mail.group')._revert_method('message_get_recipient_values')
|
||||
super(TestMail, cls).tearDownClass()
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
from email.utils import formataddr
|
||||
|
||||
from .common import TestMail
|
||||
from openerp.exceptions import AccessError
|
||||
from openerp.osv.orm import except_orm
|
||||
|
@ -27,6 +29,20 @@ from openerp.tools import mute_logger
|
|||
|
||||
class TestMailGroup(TestMail):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestMailGroup, cls).setUpClass()
|
||||
# for specific tests of mail group, get back to its expected behavior
|
||||
cls.registry('mail.group')._revert_method('message_get_recipient_values')
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
# set master class behavior back
|
||||
def mail_group_message_get_recipient_values(self, cr, uid, id, notif_message=None, recipient_ids=None, context=None):
|
||||
return self.pool['mail.thread'].message_get_recipient_values(cr, uid, id, notif_message=notif_message, recipient_ids=recipient_ids, context=context)
|
||||
cls.registry('mail.group')._patch_method('message_get_recipient_values', mail_group_message_get_recipient_values)
|
||||
super(TestMail, cls).tearDownClass()
|
||||
|
||||
@mute_logger('openerp.addons.base.ir.ir_model', 'openerp.models')
|
||||
def test_00_mail_group_access_rights(self):
|
||||
""" Testing mail_group access rights and basic mail_thread features """
|
||||
|
@ -70,3 +86,39 @@ class TestMailGroup(TestMail):
|
|||
self.assertFalse(fol_ids, 'unlinked document should not have any followers left')
|
||||
msg_ids = self.mail_message.search(cr, uid, [('model', '=', 'mail.group'), ('res_id', '=', self.group_priv_id)])
|
||||
self.assertFalse(msg_ids, 'unlinked document should not have any followers left')
|
||||
|
||||
def test_mail_group_notification_recipients_grouped(self):
|
||||
# Data: set alias_domain to see emails with alias
|
||||
self.registry('ir.config_parameter').set_param(self.cr, self.uid, 'mail.catchall.domain', 'schlouby.fr')
|
||||
|
||||
self.mail_group.message_subscribe_users(
|
||||
self.cr, self.uid,
|
||||
[self.group_pigs_id],
|
||||
[self.user_raoul_id, self.user_bert_id]
|
||||
)
|
||||
|
||||
self.mail_group.message_post(self.cr, self.uid, [self.group_pigs_id], body="Test", type='comment', subtype='mt_comment')
|
||||
sent_emails = self._build_email_kwargs_list
|
||||
self.assertEqual(len(sent_emails), 1)
|
||||
for email in sent_emails:
|
||||
self.assertEqual(
|
||||
set(email['email_to']),
|
||||
set([self.user_raoul.email, self.user_bert.email]))
|
||||
|
||||
def test_mail_group_notification_recipients_separated(self):
|
||||
# Remove alias, should trigger classic behavior of mail group
|
||||
self.mail_group.write(self.cr, self.uid, [self.group_pigs_id], {'alias_name': False})
|
||||
|
||||
self.mail_group.message_subscribe_users(
|
||||
self.cr, self.uid,
|
||||
[self.group_pigs_id],
|
||||
[self.user_raoul_id, self.user_bert_id]
|
||||
)
|
||||
|
||||
self.mail_group.message_post(self.cr, self.uid, [self.group_pigs_id], body="Test", type='comment', subtype='mt_comment')
|
||||
sent_emails = self._build_email_kwargs_list
|
||||
self.assertEqual(len(sent_emails), 2)
|
||||
for email in sent_emails:
|
||||
self.assertIn(
|
||||
email['email_to'][0],
|
||||
[formataddr((self.user_raoul.name, self.user_raoul.email)), formataddr((self.user_bert.name, self.user_bert.email))])
|
||||
|
|
Loading…
Reference in New Issue