[IMP] mail_tracking_mass_mailing: black, isort, prettier

pull/550/head
Katherine Zaoral 2020-06-09 10:10:30 -03:00
parent a25f6c8ade
commit d3426a13d5
8 changed files with 116 additions and 113 deletions

View File

@ -10,16 +10,12 @@
"version": "12.0.1.0.0", "version": "12.0.1.0.0",
"category": "Social Network", "category": "Social Network",
"website": "https://github.com/OCA/social", "website": "https://github.com/OCA/social",
"author": "Tecnativa, " "author": "Tecnativa, " "Odoo Community Association (OCA)",
"Odoo Community Association (OCA)",
"license": "AGPL-3", "license": "AGPL-3",
"application": False, "application": False,
"installable": True, "installable": True,
'auto_install': True, "auto_install": True,
"depends": [ "depends": ["mass_mailing", "mail_tracking"],
"mass_mailing",
"mail_tracking",
],
"data": [ "data": [
"views/mail_tracking_email_view.xml", "views/mail_tracking_email_view.xml",
"views/mail_mail_statistics_view.xml", "views/mail_mail_statistics_view.xml",

View File

@ -3,6 +3,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging import logging
try: try:
from odoo.addons.mail_tracking.hooks import column_add_with_value from odoo.addons.mail_tracking.hooks import column_add_with_value
except ImportError: except ImportError:
@ -13,8 +14,7 @@ _logger = logging.getLogger(__name__)
def pre_init_hook(cr): def pre_init_hook(cr):
if column_add_with_value: if column_add_with_value:
_logger.info("Creating mail.mass_mailing.contact.email_score column " _logger.info("Creating mail.mass_mailing.contact.email_score column " "with value 50.0")
"with value 50.0")
column_add_with_value( column_add_with_value(
cr, 'mail_mass_mailing_contact', 'email_score', 'double precision', cr, "mail_mass_mailing_contact", "email_score", "double precision", 50.0
50.0) )

View File

@ -2,7 +2,7 @@
# Copyright 2017 Vicent Cubells - <vicent.cubells@tecnativa.com> # Copyright 2017 Vicent Cubells - <vicent.cubells@tecnativa.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # 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): class MailMail(models.Model):
@ -11,10 +11,11 @@ class MailMail(models.Model):
@api.model @api.model
def _tracking_email_prepare(self, partner, email): def _tracking_email_prepare(self, partner, email):
res = super(MailMail, self)._tracking_email_prepare(partner, email) res = super(MailMail, self)._tracking_email_prepare(partner, email)
res['mail_id_int'] = self.id res["mail_id_int"] = self.id
res['mass_mailing_id'] = self.mailing_id.id res["mass_mailing_id"] = self.mailing_id.id
res['mail_stats_id'] = self.statistics_ids[:1].id \ res["mail_stats_id"] = (
if self.statistics_ids else False self.statistics_ids[:1].id if self.statistics_ids else False
)
return res return res
@api.model @api.model

View File

@ -2,15 +2,18 @@
# Copyright 2017 Vicent Cubells - <vicent.cubells@tecnativa.com> # Copyright 2017 Vicent Cubells - <vicent.cubells@tecnativa.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # 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): class MailMailStatistics(models.Model):
_inherit = "mail.mail.statistics" _inherit = "mail.mail.statistics"
mail_tracking_id = fields.Many2one( mail_tracking_id = fields.Many2one(
string="Mail tracking", comodel_name='mail.tracking.email', string="Mail tracking", comodel_name="mail.tracking.email", readonly=True
readonly=True) )
tracking_event_ids = fields.One2many( tracking_event_ids = fields.One2many(
string="Tracking events", comodel_name='mail.tracking.event', string="Tracking events",
related='mail_tracking_id.tracking_event_ids', readonly=True) comodel_name="mail.tracking.event",
related="mail_tracking_id.tracking_event_ids",
readonly=True,
)

View File

@ -2,20 +2,21 @@
# Copyright 2017 Vicent Cubells - <vicent.cubells@tecnativa.com> # Copyright 2017 Vicent Cubells - <vicent.cubells@tecnativa.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # 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): class MailMassMailingContact(models.Model):
_name = 'mail.mass_mailing.contact' _name = "mail.mass_mailing.contact"
_inherit = ['mail.mass_mailing.contact', 'mail.bounced.mixin'] _inherit = ["mail.mass_mailing.contact", "mail.bounced.mixin"]
email_score = fields.Float( email_score = fields.Float(
string="Email score", readonly=True, store=False, string="Email score", readonly=True, store=False, compute="_compute_email_score"
compute='_compute_email_score') )
@api.multi @api.multi
@api.depends('email') @api.depends("email")
def _compute_email_score(self): def _compute_email_score(self):
for contact in self.filtered('email'): for contact in self.filtered("email"):
contact.email_score = self.env['mail.tracking.email'].\ contact.email_score = self.env[
email_score_from_email(contact.email) "mail.tracking.email"
].email_score_from_email(contact.email)

View File

@ -2,33 +2,31 @@
# Copyright 2017 Vicent Cubells - <vicent.cubells@tecnativa.com> # Copyright 2017 Vicent Cubells - <vicent.cubells@tecnativa.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # 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): class MailTrackingEmail(models.Model):
_inherit = "mail.tracking.email" _inherit = "mail.tracking.email"
mass_mailing_id = fields.Many2one( 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( mail_stats_id = fields.Many2one(
string="Mail statistics", comodel_name='mail.mail.statistics', string="Mail statistics", comodel_name="mail.mail.statistics", readonly=True
readonly=True) )
mail_id_int = fields.Integer(string="Mail ID", readonly=True) mail_id_int = fields.Integer(string="Mail ID", readonly=True)
@api.model @api.model
def _statistics_link_prepare(self, tracking): def _statistics_link_prepare(self, tracking):
"""Inherit this method to link other object to mail.mail.statistics""" """Inherit this method to link other object to mail.mail.statistics"""
return { return {"mail_tracking_id": tracking.id}
'mail_tracking_id': tracking.id,
}
@api.model @api.model
def create(self, vals): def create(self, vals):
tracking = super(MailTrackingEmail, self).create(vals) tracking = super(MailTrackingEmail, self).create(vals)
# Link mail statistics with this tracking # Link mail statistics with this tracking
if tracking.mail_stats_id: if tracking.mail_stats_id:
tracking.mail_stats_id.write( tracking.mail_stats_id.write(self._statistics_link_prepare(tracking))
self._statistics_link_prepare(tracking))
return tracking return tracking
@api.multi @api.multi
@ -37,22 +35,23 @@ class MailTrackingEmail(models.Model):
if event and event.recipient_address: if event and event.recipient_address:
recipients.append(event.recipient_address) recipients.append(event.recipient_address)
else: else:
recipients = list(filter(None, self.mapped('recipient_address'))) recipients = list(filter(None, self.mapped("recipient_address")))
for recipient in recipients: for recipient in recipients:
self.env['mail.mass_mailing.contact'].search([ self.env["mail.mass_mailing.contact"].search(
('email', '=ilike', recipient) [("email", "=ilike", recipient)]
]).email_bounced_set(self, reason, event=event) ).email_bounced_set(self, reason, event=event)
@api.multi @api.multi
def smtp_error(self, mail_server, smtp_server, exception): def smtp_error(self, mail_server, smtp_server, exception):
res = super(MailTrackingEmail, self).smtp_error( res = super(MailTrackingEmail, self).smtp_error(
mail_server, smtp_server, exception) mail_server, smtp_server, exception
self._contacts_email_bounced_set('error') )
self._contacts_email_bounced_set("error")
return res return res
@api.multi @api.multi
def event_create(self, event_type, metadata): def event_create(self, event_type, metadata):
res = super(MailTrackingEmail, self).event_create(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) self._contacts_email_bounced_set(event_type)
return res return res

View File

@ -9,45 +9,48 @@ class MailTrackingEvent(models.Model):
_inherit = "mail.tracking.event" _inherit = "mail.tracking.event"
mass_mailing_id = fields.Many2one( mass_mailing_id = fields.Many2one(
string="Mass mailing", comodel_name='mail.mass_mailing', readonly=True, string="Mass mailing",
related='tracking_email_id.mass_mailing_id', store=True) comodel_name="mail.mass_mailing",
readonly=True,
related="tracking_email_id.mass_mailing_id",
store=True,
)
@api.model @api.model
def process_open(self, tracking_email, metadata): def process_open(self, tracking_email, metadata):
res = super(MailTrackingEvent, self).process_open( res = super(MailTrackingEvent, self).process_open(tracking_email, metadata)
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_opened(mail_mail_ids=[tracking_email.mail_id_int]) mail_mail_stats.set_opened(mail_mail_ids=[tracking_email.mail_id_int])
return res return res
def _tracking_set_bounce(self, tracking_email, metadata): 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]) mail_mail_stats.set_bounced(mail_mail_ids=[tracking_email.mail_id_int])
@api.model @api.model
def process_hard_bounce(self, tracking_email, metadata): def process_hard_bounce(self, tracking_email, metadata):
res = super(MailTrackingEvent, self).process_hard_bounce( res = super(MailTrackingEvent, self).process_hard_bounce(
tracking_email, metadata) tracking_email, metadata
)
self._tracking_set_bounce(tracking_email, metadata) self._tracking_set_bounce(tracking_email, metadata)
return res return res
@api.model @api.model
def process_soft_bounce(self, tracking_email, metadata): def process_soft_bounce(self, tracking_email, metadata):
res = super(MailTrackingEvent, self).process_soft_bounce( res = super(MailTrackingEvent, self).process_soft_bounce(
tracking_email, metadata) tracking_email, metadata
)
self._tracking_set_bounce(tracking_email, metadata) self._tracking_set_bounce(tracking_email, metadata)
return res return res
@api.model @api.model
def process_reject(self, tracking_email, metadata): def process_reject(self, tracking_email, metadata):
res = super(MailTrackingEvent, self).process_reject( res = super(MailTrackingEvent, self).process_reject(tracking_email, metadata)
tracking_email, metadata)
self._tracking_set_bounce(tracking_email, metadata) self._tracking_set_bounce(tracking_email, metadata)
return res return res
@api.model @api.model
def process_spam(self, tracking_email, metadata): def process_spam(self, tracking_email, metadata):
res = super(MailTrackingEvent, self).process_spam( res = super(MailTrackingEvent, self).process_spam(tracking_email, metadata)
tracking_email, metadata)
self._tracking_set_bounce(tracking_email, metadata) self._tracking_set_bounce(tracking_email, metadata)
return res return res

View File

@ -5,11 +5,11 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import mock 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.' from odoo.tests.common import TransactionCase, at_install, post_install
'IrMailServer.send_email') from odoo.tools import mute_logger
mock_send_email = "odoo.addons.base.models.ir_mail_server." "IrMailServer.send_email"
@at_install(False) @at_install(False)
@ -17,43 +17,44 @@ mock_send_email = ('odoo.addons.base.models.ir_mail_server.'
class TestMassMailing(TransactionCase): class TestMassMailing(TransactionCase):
def setUp(self, *args, **kwargs): def setUp(self, *args, **kwargs):
super(TestMassMailing, self).setUp(*args, **kwargs) super(TestMassMailing, self).setUp(*args, **kwargs)
self.list = self.env['mail.mass_mailing.list'].create({ self.list = self.env["mail.mass_mailing.list"].create({"name": "Test mail tracking"})
'name': 'Test mail tracking', self.list.name = "{} #{}".format(self.list.name, self.list.id)
}) self.contact_a = self.env["mail.mass_mailing.contact"].create(
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)],
'list_ids': [(6, 0, self.list.ids)], "name": "Test contact A",
'name': 'Test contact A', "email": "contact_a@example.com",
'email': 'contact_a@example.com', }
}) )
self.mailing = self.env['mail.mass_mailing'].create({ self.mailing = self.env["mail.mass_mailing"].create(
'name': 'Test subject', {
'email_from': 'from@example.com', "name": "Test subject",
'mailing_model_id': self.env.ref( "email_from": "from@example.com",
'mass_mailing.model_mail_mass_mailing_contact' "mailing_model_id": self.env.ref(
).id, "mass_mailing.model_mail_mass_mailing_contact"
'mailing_domain': "[('list_ids', 'in', %d)]" % self.list.id, ).id,
'contact_list_ids': [(6, False, [self.list.id])], "mailing_domain": "[('list_ids', 'in', %d)]" % self.list.id,
'body_html': '<p>Test email body</p>', "contact_list_ids": [(6, False, [self.list.id])],
'reply_to_mode': 'email', "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): def test_smtp_error(self):
with mock.patch(mock_send_email) as mock_func: 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() self.mailing.send_mail()
for stat in self.mailing.statistics_ids: for stat in self.mailing.statistics_ids:
if stat.mail_mail_id: if stat.mail_mail_id:
stat.mail_mail_id.send() stat.mail_mail_id.send()
tracking = self.env['mail.tracking.email'].search([ tracking = self.env["mail.tracking.email"].search(
('mail_id_int', '=', stat.mail_mail_id_int), [("mail_id_int", "=", stat.mail_mail_id_int)]
]) )
for track in tracking: for track in tracking:
self.assertEqual('error', track.state) self.assertEqual("error", track.state)
self.assertEqual('Warning', track.error_type) self.assertEqual("Warning", track.error_type)
self.assertEqual('Mock test error', self.assertEqual("Mock test error", track.error_description)
track.error_description)
self.assertTrue(self.contact_a.email_bounced) self.assertTrue(self.contact_a.email_bounced)
def test_tracking_email_link(self): def test_tracking_email_link(self):
@ -61,22 +62,21 @@ class TestMassMailing(TransactionCase):
for stat in self.mailing.statistics_ids: for stat in self.mailing.statistics_ids:
if stat.mail_mail_id: if stat.mail_mail_id:
stat.mail_mail_id.send() stat.mail_mail_id.send()
tracking_email = self.env['mail.tracking.email'].search([ tracking_email = self.env["mail.tracking.email"].search(
('mail_id_int', '=', stat.mail_mail_id_int), [("mail_id_int", "=", stat.mail_mail_id_int)]
]) )
self.assertTrue(tracking_email) self.assertTrue(tracking_email)
self.assertEqual( self.assertEqual(tracking_email.mass_mailing_id.id, self.mailing.id)
tracking_email.mass_mailing_id.id, self.mailing.id)
self.assertEqual(tracking_email.mail_stats_id.id, stat.id) self.assertEqual(tracking_email.mail_stats_id.id, stat.id)
self.assertEqual(stat.mail_tracking_id.id, tracking_email.id) self.assertEqual(stat.mail_tracking_id.id, tracking_email.id)
# And now open the email # And now open the email
metadata = { metadata = {
'ip': '127.0.0.1', "ip": "127.0.0.1",
'user_agent': 'Odoo Test/1.0', "user_agent": "Odoo Test/1.0",
'os_family': 'linux', "os_family": "linux",
'ua_family': 'odoo', "ua_family": "odoo",
} }
tracking_email.event_create('open', metadata) tracking_email.event_create("open", metadata)
self.assertTrue(stat.opened) self.assertTrue(stat.opened)
def _tracking_email_bounce(self, event_type, state): def _tracking_email_bounce(self, event_type, state):
@ -84,36 +84,36 @@ class TestMassMailing(TransactionCase):
for stat in self.mailing.statistics_ids: for stat in self.mailing.statistics_ids:
if stat.mail_mail_id: if stat.mail_mail_id:
stat.mail_mail_id.send() stat.mail_mail_id.send()
tracking_email = self.env['mail.tracking.email'].search([ tracking_email = self.env["mail.tracking.email"].search(
('mail_id_int', '=', stat.mail_mail_id_int), [("mail_id_int", "=", stat.mail_mail_id_int)]
]) )
# And now mark the email as bounce # And now mark the email as bounce
metadata = { metadata = {
'bounce_type': '499', "bounce_type": "499",
'bounce_description': 'Unable to connect to MX servers', "bounce_description": "Unable to connect to MX servers",
} }
tracking_email.event_create(event_type, metadata) tracking_email.event_create(event_type, metadata)
self.assertTrue(stat.bounced) self.assertTrue(stat.bounced)
def test_tracking_email_hard_bounce(self): 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): 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): def test_tracking_email_reject(self):
self._tracking_email_bounce('reject', 'rejected') self._tracking_email_bounce("reject", "rejected")
def test_tracking_email_spam(self): def test_tracking_email_spam(self):
self._tracking_email_bounce('spam', 'spam') self._tracking_email_bounce("spam", "spam")
def test_contact_tracking_emails(self): 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_bounced)
self.assertTrue(self.contact_a.email_score < 50.0) 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.assertFalse(self.contact_a.email_bounced)
self.assertTrue(self.contact_a.email_score == 50.0) 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_bounced)
self.assertTrue(self.contact_a.email_score < 50.0) self.assertTrue(self.contact_a.email_score < 50.0)