mirror of https://github.com/OCA/social.git
[IMP] mail_tracking_mass_mailing: black, isort, prettier
parent
a25f6c8ade
commit
d3426a13d5
|
@ -10,16 +10,12 @@
|
|||
"version": "12.0.1.0.0",
|
||||
"category": "Social Network",
|
||||
"website": "https://github.com/OCA/social",
|
||||
"author": "Tecnativa, "
|
||||
"Odoo Community Association (OCA)",
|
||||
"author": "Tecnativa, " "Odoo Community Association (OCA)",
|
||||
"license": "AGPL-3",
|
||||
"application": False,
|
||||
"installable": True,
|
||||
'auto_install': True,
|
||||
"depends": [
|
||||
"mass_mailing",
|
||||
"mail_tracking",
|
||||
],
|
||||
"auto_install": True,
|
||||
"depends": ["mass_mailing", "mail_tracking"],
|
||||
"data": [
|
||||
"views/mail_tracking_email_view.xml",
|
||||
"views/mail_mail_statistics_view.xml",
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import logging
|
||||
|
||||
try:
|
||||
from odoo.addons.mail_tracking.hooks import column_add_with_value
|
||||
except ImportError:
|
||||
|
@ -13,8 +14,7 @@ _logger = logging.getLogger(__name__)
|
|||
|
||||
def pre_init_hook(cr):
|
||||
if column_add_with_value:
|
||||
_logger.info("Creating mail.mass_mailing.contact.email_score column "
|
||||
"with value 50.0")
|
||||
_logger.info("Creating mail.mass_mailing.contact.email_score column " "with value 50.0")
|
||||
column_add_with_value(
|
||||
cr, 'mail_mass_mailing_contact', 'email_score', 'double precision',
|
||||
50.0)
|
||||
cr, "mail_mass_mailing_contact", "email_score", "double precision", 50.0
|
||||
)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# Copyright 2017 Vicent Cubells - <vicent.cubells@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import models, api
|
||||
from odoo import api, models
|
||||
|
||||
|
||||
class MailMail(models.Model):
|
||||
|
@ -11,10 +11,11 @@ class MailMail(models.Model):
|
|||
@api.model
|
||||
def _tracking_email_prepare(self, partner, email):
|
||||
res = super(MailMail, self)._tracking_email_prepare(partner, email)
|
||||
res['mail_id_int'] = self.id
|
||||
res['mass_mailing_id'] = self.mailing_id.id
|
||||
res['mail_stats_id'] = self.statistics_ids[:1].id \
|
||||
if self.statistics_ids else False
|
||||
res["mail_id_int"] = self.id
|
||||
res["mass_mailing_id"] = self.mailing_id.id
|
||||
res["mail_stats_id"] = (
|
||||
self.statistics_ids[:1].id if self.statistics_ids else False
|
||||
)
|
||||
return res
|
||||
|
||||
@api.model
|
||||
|
|
|
@ -2,15 +2,18 @@
|
|||
# Copyright 2017 Vicent Cubells - <vicent.cubells@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import models, fields
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class MailMailStatistics(models.Model):
|
||||
_inherit = "mail.mail.statistics"
|
||||
|
||||
mail_tracking_id = fields.Many2one(
|
||||
string="Mail tracking", comodel_name='mail.tracking.email',
|
||||
readonly=True)
|
||||
string="Mail tracking", comodel_name="mail.tracking.email", readonly=True
|
||||
)
|
||||
tracking_event_ids = fields.One2many(
|
||||
string="Tracking events", comodel_name='mail.tracking.event',
|
||||
related='mail_tracking_id.tracking_event_ids', readonly=True)
|
||||
string="Tracking events",
|
||||
comodel_name="mail.tracking.event",
|
||||
related="mail_tracking_id.tracking_event_ids",
|
||||
readonly=True,
|
||||
)
|
||||
|
|
|
@ -2,20 +2,21 @@
|
|||
# Copyright 2017 Vicent Cubells - <vicent.cubells@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import models, api, fields
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class MailMassMailingContact(models.Model):
|
||||
_name = 'mail.mass_mailing.contact'
|
||||
_inherit = ['mail.mass_mailing.contact', 'mail.bounced.mixin']
|
||||
_name = "mail.mass_mailing.contact"
|
||||
_inherit = ["mail.mass_mailing.contact", "mail.bounced.mixin"]
|
||||
|
||||
email_score = fields.Float(
|
||||
string="Email score", readonly=True, store=False,
|
||||
compute='_compute_email_score')
|
||||
string="Email score", readonly=True, store=False, compute="_compute_email_score"
|
||||
)
|
||||
|
||||
@api.multi
|
||||
@api.depends('email')
|
||||
@api.depends("email")
|
||||
def _compute_email_score(self):
|
||||
for contact in self.filtered('email'):
|
||||
contact.email_score = self.env['mail.tracking.email'].\
|
||||
email_score_from_email(contact.email)
|
||||
for contact in self.filtered("email"):
|
||||
contact.email_score = self.env[
|
||||
"mail.tracking.email"
|
||||
].email_score_from_email(contact.email)
|
||||
|
|
|
@ -2,33 +2,31 @@
|
|||
# Copyright 2017 Vicent Cubells - <vicent.cubells@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import models, fields, api
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class MailTrackingEmail(models.Model):
|
||||
_inherit = "mail.tracking.email"
|
||||
|
||||
mass_mailing_id = fields.Many2one(
|
||||
string="Mass mailing", comodel_name='mail.mass_mailing', readonly=True)
|
||||
string="Mass mailing", comodel_name="mail.mass_mailing", readonly=True
|
||||
)
|
||||
mail_stats_id = fields.Many2one(
|
||||
string="Mail statistics", comodel_name='mail.mail.statistics',
|
||||
readonly=True)
|
||||
string="Mail statistics", comodel_name="mail.mail.statistics", readonly=True
|
||||
)
|
||||
mail_id_int = fields.Integer(string="Mail ID", readonly=True)
|
||||
|
||||
@api.model
|
||||
def _statistics_link_prepare(self, tracking):
|
||||
"""Inherit this method to link other object to mail.mail.statistics"""
|
||||
return {
|
||||
'mail_tracking_id': tracking.id,
|
||||
}
|
||||
return {"mail_tracking_id": tracking.id}
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
tracking = super(MailTrackingEmail, self).create(vals)
|
||||
# Link mail statistics with this tracking
|
||||
if tracking.mail_stats_id:
|
||||
tracking.mail_stats_id.write(
|
||||
self._statistics_link_prepare(tracking))
|
||||
tracking.mail_stats_id.write(self._statistics_link_prepare(tracking))
|
||||
return tracking
|
||||
|
||||
@api.multi
|
||||
|
@ -37,22 +35,23 @@ class MailTrackingEmail(models.Model):
|
|||
if event and event.recipient_address:
|
||||
recipients.append(event.recipient_address)
|
||||
else:
|
||||
recipients = list(filter(None, self.mapped('recipient_address')))
|
||||
recipients = list(filter(None, self.mapped("recipient_address")))
|
||||
for recipient in recipients:
|
||||
self.env['mail.mass_mailing.contact'].search([
|
||||
('email', '=ilike', recipient)
|
||||
]).email_bounced_set(self, reason, event=event)
|
||||
self.env["mail.mass_mailing.contact"].search(
|
||||
[("email", "=ilike", recipient)]
|
||||
).email_bounced_set(self, reason, event=event)
|
||||
|
||||
@api.multi
|
||||
def smtp_error(self, mail_server, smtp_server, exception):
|
||||
res = super(MailTrackingEmail, self).smtp_error(
|
||||
mail_server, smtp_server, exception)
|
||||
self._contacts_email_bounced_set('error')
|
||||
mail_server, smtp_server, exception
|
||||
)
|
||||
self._contacts_email_bounced_set("error")
|
||||
return res
|
||||
|
||||
@api.multi
|
||||
def event_create(self, event_type, metadata):
|
||||
res = super(MailTrackingEmail, self).event_create(event_type, metadata)
|
||||
if event_type in {'hard_bounce', 'spam', 'reject'}:
|
||||
if event_type in {"hard_bounce", "spam", "reject"}:
|
||||
self._contacts_email_bounced_set(event_type)
|
||||
return res
|
||||
|
|
|
@ -9,45 +9,48 @@ class MailTrackingEvent(models.Model):
|
|||
_inherit = "mail.tracking.event"
|
||||
|
||||
mass_mailing_id = fields.Many2one(
|
||||
string="Mass mailing", comodel_name='mail.mass_mailing', readonly=True,
|
||||
related='tracking_email_id.mass_mailing_id', store=True)
|
||||
string="Mass mailing",
|
||||
comodel_name="mail.mass_mailing",
|
||||
readonly=True,
|
||||
related="tracking_email_id.mass_mailing_id",
|
||||
store=True,
|
||||
)
|
||||
|
||||
@api.model
|
||||
def process_open(self, tracking_email, metadata):
|
||||
res = super(MailTrackingEvent, self).process_open(
|
||||
tracking_email, metadata)
|
||||
mail_mail_stats = self.sudo().env['mail.mail.statistics']
|
||||
res = super(MailTrackingEvent, self).process_open(tracking_email, metadata)
|
||||
mail_mail_stats = self.sudo().env["mail.mail.statistics"]
|
||||
mail_mail_stats.set_opened(mail_mail_ids=[tracking_email.mail_id_int])
|
||||
return res
|
||||
|
||||
def _tracking_set_bounce(self, tracking_email, metadata):
|
||||
mail_mail_stats = self.sudo().env['mail.mail.statistics']
|
||||
mail_mail_stats = self.sudo().env["mail.mail.statistics"]
|
||||
mail_mail_stats.set_bounced(mail_mail_ids=[tracking_email.mail_id_int])
|
||||
|
||||
@api.model
|
||||
def process_hard_bounce(self, tracking_email, metadata):
|
||||
res = super(MailTrackingEvent, self).process_hard_bounce(
|
||||
tracking_email, metadata)
|
||||
tracking_email, metadata
|
||||
)
|
||||
self._tracking_set_bounce(tracking_email, metadata)
|
||||
return res
|
||||
|
||||
@api.model
|
||||
def process_soft_bounce(self, tracking_email, metadata):
|
||||
res = super(MailTrackingEvent, self).process_soft_bounce(
|
||||
tracking_email, metadata)
|
||||
tracking_email, metadata
|
||||
)
|
||||
self._tracking_set_bounce(tracking_email, metadata)
|
||||
return res
|
||||
|
||||
@api.model
|
||||
def process_reject(self, tracking_email, metadata):
|
||||
res = super(MailTrackingEvent, self).process_reject(
|
||||
tracking_email, metadata)
|
||||
res = super(MailTrackingEvent, self).process_reject(tracking_email, metadata)
|
||||
self._tracking_set_bounce(tracking_email, metadata)
|
||||
return res
|
||||
|
||||
@api.model
|
||||
def process_spam(self, tracking_email, metadata):
|
||||
res = super(MailTrackingEvent, self).process_spam(
|
||||
tracking_email, metadata)
|
||||
res = super(MailTrackingEvent, self).process_spam(tracking_email, metadata)
|
||||
self._tracking_set_bounce(tracking_email, metadata)
|
||||
return res
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import mock
|
||||
from odoo.tools import mute_logger
|
||||
from odoo.tests.common import at_install, post_install, TransactionCase
|
||||
|
||||
mock_send_email = ('odoo.addons.base.models.ir_mail_server.'
|
||||
'IrMailServer.send_email')
|
||||
from odoo.tests.common import TransactionCase, at_install, post_install
|
||||
from odoo.tools import mute_logger
|
||||
|
||||
mock_send_email = "odoo.addons.base.models.ir_mail_server." "IrMailServer.send_email"
|
||||
|
||||
|
||||
@at_install(False)
|
||||
|
@ -17,43 +17,44 @@ mock_send_email = ('odoo.addons.base.models.ir_mail_server.'
|
|||
class TestMassMailing(TransactionCase):
|
||||
def setUp(self, *args, **kwargs):
|
||||
super(TestMassMailing, self).setUp(*args, **kwargs)
|
||||
self.list = self.env['mail.mass_mailing.list'].create({
|
||||
'name': 'Test mail tracking',
|
||||
})
|
||||
self.list.name = '%s #%s' % (self.list.name, self.list.id)
|
||||
self.contact_a = self.env['mail.mass_mailing.contact'].create({
|
||||
'list_ids': [(6, 0, self.list.ids)],
|
||||
'name': 'Test contact A',
|
||||
'email': 'contact_a@example.com',
|
||||
})
|
||||
self.mailing = self.env['mail.mass_mailing'].create({
|
||||
'name': 'Test subject',
|
||||
'email_from': 'from@example.com',
|
||||
'mailing_model_id': self.env.ref(
|
||||
'mass_mailing.model_mail_mass_mailing_contact'
|
||||
).id,
|
||||
'mailing_domain': "[('list_ids', 'in', %d)]" % self.list.id,
|
||||
'contact_list_ids': [(6, False, [self.list.id])],
|
||||
'body_html': '<p>Test email body</p>',
|
||||
'reply_to_mode': 'email',
|
||||
})
|
||||
self.list = self.env["mail.mass_mailing.list"].create({"name": "Test mail tracking"})
|
||||
self.list.name = "{} #{}".format(self.list.name, self.list.id)
|
||||
self.contact_a = self.env["mail.mass_mailing.contact"].create(
|
||||
{
|
||||
"list_ids": [(6, 0, self.list.ids)],
|
||||
"name": "Test contact A",
|
||||
"email": "contact_a@example.com",
|
||||
}
|
||||
)
|
||||
self.mailing = self.env["mail.mass_mailing"].create(
|
||||
{
|
||||
"name": "Test subject",
|
||||
"email_from": "from@example.com",
|
||||
"mailing_model_id": self.env.ref(
|
||||
"mass_mailing.model_mail_mass_mailing_contact"
|
||||
).id,
|
||||
"mailing_domain": "[('list_ids', 'in', %d)]" % self.list.id,
|
||||
"contact_list_ids": [(6, False, [self.list.id])],
|
||||
"body_html": "<p>Test email body</p>",
|
||||
"reply_to_mode": "email",
|
||||
}
|
||||
)
|
||||
|
||||
@mute_logger('odoo.addons.mail.models.mail_mail')
|
||||
@mute_logger("odoo.addons.mail.models.mail_mail")
|
||||
def test_smtp_error(self):
|
||||
with mock.patch(mock_send_email) as mock_func:
|
||||
mock_func.side_effect = Warning('Mock test error')
|
||||
mock_func.side_effect = Warning("Mock test error")
|
||||
self.mailing.send_mail()
|
||||
for stat in self.mailing.statistics_ids:
|
||||
if stat.mail_mail_id:
|
||||
stat.mail_mail_id.send()
|
||||
tracking = self.env['mail.tracking.email'].search([
|
||||
('mail_id_int', '=', stat.mail_mail_id_int),
|
||||
])
|
||||
tracking = self.env["mail.tracking.email"].search(
|
||||
[("mail_id_int", "=", stat.mail_mail_id_int)]
|
||||
)
|
||||
for track in tracking:
|
||||
self.assertEqual('error', track.state)
|
||||
self.assertEqual('Warning', track.error_type)
|
||||
self.assertEqual('Mock test error',
|
||||
track.error_description)
|
||||
self.assertEqual("error", track.state)
|
||||
self.assertEqual("Warning", track.error_type)
|
||||
self.assertEqual("Mock test error", track.error_description)
|
||||
self.assertTrue(self.contact_a.email_bounced)
|
||||
|
||||
def test_tracking_email_link(self):
|
||||
|
@ -61,22 +62,21 @@ class TestMassMailing(TransactionCase):
|
|||
for stat in self.mailing.statistics_ids:
|
||||
if stat.mail_mail_id:
|
||||
stat.mail_mail_id.send()
|
||||
tracking_email = self.env['mail.tracking.email'].search([
|
||||
('mail_id_int', '=', stat.mail_mail_id_int),
|
||||
])
|
||||
tracking_email = self.env["mail.tracking.email"].search(
|
||||
[("mail_id_int", "=", stat.mail_mail_id_int)]
|
||||
)
|
||||
self.assertTrue(tracking_email)
|
||||
self.assertEqual(
|
||||
tracking_email.mass_mailing_id.id, self.mailing.id)
|
||||
self.assertEqual(tracking_email.mass_mailing_id.id, self.mailing.id)
|
||||
self.assertEqual(tracking_email.mail_stats_id.id, stat.id)
|
||||
self.assertEqual(stat.mail_tracking_id.id, tracking_email.id)
|
||||
# And now open the email
|
||||
metadata = {
|
||||
'ip': '127.0.0.1',
|
||||
'user_agent': 'Odoo Test/1.0',
|
||||
'os_family': 'linux',
|
||||
'ua_family': 'odoo',
|
||||
"ip": "127.0.0.1",
|
||||
"user_agent": "Odoo Test/1.0",
|
||||
"os_family": "linux",
|
||||
"ua_family": "odoo",
|
||||
}
|
||||
tracking_email.event_create('open', metadata)
|
||||
tracking_email.event_create("open", metadata)
|
||||
self.assertTrue(stat.opened)
|
||||
|
||||
def _tracking_email_bounce(self, event_type, state):
|
||||
|
@ -84,36 +84,36 @@ class TestMassMailing(TransactionCase):
|
|||
for stat in self.mailing.statistics_ids:
|
||||
if stat.mail_mail_id:
|
||||
stat.mail_mail_id.send()
|
||||
tracking_email = self.env['mail.tracking.email'].search([
|
||||
('mail_id_int', '=', stat.mail_mail_id_int),
|
||||
])
|
||||
tracking_email = self.env["mail.tracking.email"].search(
|
||||
[("mail_id_int", "=", stat.mail_mail_id_int)]
|
||||
)
|
||||
# And now mark the email as bounce
|
||||
metadata = {
|
||||
'bounce_type': '499',
|
||||
'bounce_description': 'Unable to connect to MX servers',
|
||||
"bounce_type": "499",
|
||||
"bounce_description": "Unable to connect to MX servers",
|
||||
}
|
||||
tracking_email.event_create(event_type, metadata)
|
||||
self.assertTrue(stat.bounced)
|
||||
|
||||
def test_tracking_email_hard_bounce(self):
|
||||
self._tracking_email_bounce('hard_bounce', 'bounced')
|
||||
self._tracking_email_bounce("hard_bounce", "bounced")
|
||||
|
||||
def test_tracking_email_soft_bounce(self):
|
||||
self._tracking_email_bounce('soft_bounce', 'soft-bounced')
|
||||
self._tracking_email_bounce("soft_bounce", "soft-bounced")
|
||||
|
||||
def test_tracking_email_reject(self):
|
||||
self._tracking_email_bounce('reject', 'rejected')
|
||||
self._tracking_email_bounce("reject", "rejected")
|
||||
|
||||
def test_tracking_email_spam(self):
|
||||
self._tracking_email_bounce('spam', 'spam')
|
||||
self._tracking_email_bounce("spam", "spam")
|
||||
|
||||
def test_contact_tracking_emails(self):
|
||||
self._tracking_email_bounce('hard_bounce', 'bounced')
|
||||
self._tracking_email_bounce("hard_bounce", "bounced")
|
||||
self.assertTrue(self.contact_a.email_bounced)
|
||||
self.assertTrue(self.contact_a.email_score < 50.0)
|
||||
self.contact_a.email = 'other_contact_a@example.com'
|
||||
self.contact_a.email = "other_contact_a@example.com"
|
||||
self.assertFalse(self.contact_a.email_bounced)
|
||||
self.assertTrue(self.contact_a.email_score == 50.0)
|
||||
self.contact_a.email = 'contact_a@example.com'
|
||||
self.contact_a.email = "contact_a@example.com"
|
||||
self.assertTrue(self.contact_a.email_bounced)
|
||||
self.assertTrue(self.contact_a.email_score < 50.0)
|
||||
|
|
Loading…
Reference in New Issue