mirror of https://github.com/OCA/social.git
[MIG] mail_tracking: Migration to 11.0
parent
9365804a27
commit
0fd2b031ef
|
@ -10,7 +10,6 @@ This module shows email notification tracking status for any messages in
|
|||
mail thread (chatter). Each notified partner will have an intuitive icon just
|
||||
right to his name.
|
||||
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
|
@ -20,7 +19,6 @@ you need to add ``mail_tracking`` addon to wide load addons list
|
|||
(by default, only ``web`` addon), setting ``--load`` option.
|
||||
For example, ``--load=web,mail_tracking``
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
|
@ -63,7 +61,7 @@ These are all available status icons:
|
|||
|
||||
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
|
||||
:alt: Try me on Runbot
|
||||
:target: https://runbot.odoo-community.org/runbot/205/10.0
|
||||
:target: https://runbot.odoo-community.org/runbot/205/11.0
|
||||
|
||||
If you want to see all tracking emails and events you can go to
|
||||
|
||||
|
@ -93,8 +91,11 @@ Images
|
|||
Contributors
|
||||
------------
|
||||
|
||||
* Pedro M. Baeza <pedro.baeza@tecnativa.com>
|
||||
* Antonio Espinosa <antonio.espinosa@tecnativa.com>
|
||||
* `Tecnativa <https://www.tecnativa.com>`_:
|
||||
|
||||
* Pedro M. Baeza <pedro.baeza@tecnativa.com>
|
||||
* Antonio Espinosa <antonio.espinosa@tecnativa.com>
|
||||
* David Vidal <david.vidal@tecnativa.com>
|
||||
|
||||
Maintainer
|
||||
----------
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
# flake8: noqa
|
||||
|
||||
from . import models
|
||||
from . import controllers
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# Copyright 2018 David Vidal - <david.vidal@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
{
|
||||
"name": "Email tracking",
|
||||
"summary": "Email tracking system for all mails sent",
|
||||
"version": "10.0.1.1.1",
|
||||
"version": "11.0.1.0.0",
|
||||
"category": "Social Network",
|
||||
"website": "http://www.tecnativa.com",
|
||||
"website": "http://github.com/OCA/social",
|
||||
"author": "Tecnativa, "
|
||||
"Odoo Community Association (OCA)",
|
||||
"license": "AGPL-3",
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
# flake8: noqa
|
||||
|
||||
from . import main
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import werkzeug
|
||||
|
@ -8,7 +7,7 @@ from odoo import api, http, registry, SUPERUSER_ID
|
|||
import logging
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
BLANK = 'R0lGODlhAQABAIAAANvf7wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='
|
||||
BLANK = b'R0lGODlhAQABAIAAANvf7wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='
|
||||
|
||||
|
||||
def _env_get(db, callback, tracking_id, event_type, **kw):
|
||||
|
@ -22,7 +21,7 @@ def _env_get(db, callback, tracking_id, event_type, **kw):
|
|||
reg = registry(db)
|
||||
except OperationalError:
|
||||
_logger.warning("Selected BD '%s' not found", db)
|
||||
except: # pragma: no cover
|
||||
except Exception: # pragma: no cover
|
||||
_logger.warning("Selected BD '%s' connection error", db)
|
||||
if reg:
|
||||
_logger.info("New environment for database '%s'", db)
|
||||
|
@ -83,5 +82,5 @@ class MailTrackingController(http.Controller):
|
|||
# Always return GIF blank image
|
||||
response = werkzeug.wrappers.Response()
|
||||
response.mimetype = 'image/gif'
|
||||
response.data = BLANK.decode('base64')
|
||||
response.data = BLANK
|
||||
return response
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
<!-- Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
|
||||
<odoo>
|
||||
<record forcecreate="True" id="decimal_tracking_timestamp" model="decimal.precision">
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import logging
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
# flake8: noqa
|
||||
|
||||
from . import ir_mail_server
|
||||
from . import mail_mail
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import re
|
||||
|
@ -20,16 +19,10 @@ class IrMailServer(models.Model):
|
|||
|
||||
def _tracking_email_id_body_get(self, body):
|
||||
body = body or ''
|
||||
tracking_email_id = False
|
||||
# https://regex101.com/r/lW4cB1/2
|
||||
match = re.search(
|
||||
r'<img[^>]*data-odoo-tracking-email=["\']([0-9]*)["\']', body)
|
||||
if match:
|
||||
try:
|
||||
tracking_email_id = int(match.group(1))
|
||||
except: # pragma: no cover
|
||||
pass
|
||||
return tracking_email_id
|
||||
return int(match.group(1)) if match.group(1) else False
|
||||
|
||||
def build_email(self, email_from, email_to, subject, body, email_cc=None,
|
||||
email_bcc=None, reply_to=False, attachments=None,
|
||||
|
@ -64,14 +57,14 @@ class IrMailServer(models.Model):
|
|||
mail_server = mail_server_ids[0] if mail_server_ids else None
|
||||
if mail_server:
|
||||
smtp_server_used = mail_server.smtp_host
|
||||
else: # pragma: no cover
|
||||
else:
|
||||
smtp_server_used = smtp_server or tools.config.get('smtp_server')
|
||||
return smtp_server_used
|
||||
|
||||
@api.model
|
||||
def send_email(self, message, mail_server_id=None, smtp_server=None,
|
||||
smtp_port=None, smtp_user=None, smtp_password=None,
|
||||
smtp_encryption=None, smtp_debug=False):
|
||||
smtp_encryption=None, smtp_debug=False, smtp_session=None):
|
||||
message_id = False
|
||||
tracking_email = self._tracking_email_get(message)
|
||||
smtp_server_used = self.sudo()._smtp_server_get(
|
||||
|
@ -82,7 +75,8 @@ class IrMailServer(models.Model):
|
|||
message, mail_server_id=mail_server_id,
|
||||
smtp_server=smtp_server, smtp_port=smtp_port,
|
||||
smtp_user=smtp_user, smtp_password=smtp_password,
|
||||
smtp_encryption=smtp_encryption, smtp_debug=smtp_debug)
|
||||
smtp_encryption=smtp_encryption, smtp_debug=smtp_debug,
|
||||
smtp_session=smtp_session)
|
||||
except Exception as e:
|
||||
if tracking_email:
|
||||
tracking_email.smtp_error(self, smtp_server_used, e)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import time
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import models, api
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import logging
|
||||
import urlparse
|
||||
import urllib.parse
|
||||
import time
|
||||
import re
|
||||
from datetime import datetime
|
||||
|
@ -93,27 +92,20 @@ class MailTrackingEmail(models.Model):
|
|||
string="Tracking events", comodel_name='mail.tracking.event',
|
||||
inverse_name='tracking_email_id', readonly=True)
|
||||
|
||||
@api.model
|
||||
def _email_score_tracking_filter(self, domain, order='time desc',
|
||||
limit=10):
|
||||
"""Default tracking search. Ready to be inherited."""
|
||||
return self.search(domain, limit=limit, order=order)
|
||||
|
||||
@api.model
|
||||
def email_is_bounced(self, email):
|
||||
if email:
|
||||
return len(self._email_score_tracking_filter([
|
||||
return self.search_count([
|
||||
('recipient_address', '=', email.lower()),
|
||||
('state', 'in', ('error', 'rejected', 'spam', 'bounced')),
|
||||
])) > 0
|
||||
]) > 0
|
||||
return False
|
||||
|
||||
@api.model
|
||||
def email_score_from_email(self, email):
|
||||
if email:
|
||||
return self._email_score_tracking_filter([
|
||||
('recipient_address', '=', email.lower())
|
||||
]).email_score()
|
||||
return self.search([
|
||||
('recipient_address', '=', email.lower())]).email_score()
|
||||
return 0.
|
||||
|
||||
@api.model
|
||||
|
@ -183,7 +175,7 @@ class MailTrackingEmail(models.Model):
|
|||
'db': self.env.cr.dbname,
|
||||
'tracking_email_id': self.id,
|
||||
})
|
||||
track_url = urlparse.urljoin(base_url, path_url)
|
||||
track_url = urllib.parse.urljoin(base_url, path_url)
|
||||
return (
|
||||
'<img src="%(url)s" alt="" '
|
||||
'data-odoo-tracking-email="%(tracking_email_id)s"/>' % {
|
||||
|
@ -197,7 +189,7 @@ 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 = [x for x in self.mapped('recipient_address') if x]
|
||||
for recipient in recipients:
|
||||
self.env['res.partner'].search([
|
||||
('email', '=ilike', recipient)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import re
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import models, api, fields
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
<!-- Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
|
||||
<odoo>
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
/* Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). */
|
||||
|
||||
.mail_tracking span {
|
||||
|
|
|
@ -1,20 +1,33 @@
|
|||
/* © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
/* Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
Copyright 2018 David Vidal - <david.vidal@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). */
|
||||
|
||||
odoo.define('mail_tracking.partner_tracking', function(require){
|
||||
"use strict";
|
||||
"use strict";
|
||||
|
||||
var core = require('web.core');
|
||||
var session = require('web.session');
|
||||
var Model = require('web.Model');
|
||||
var ActionManager = require('web.ActionManager');
|
||||
var ChatThread = require('mail.ChatThread');
|
||||
var core = require('web.core');
|
||||
var session = require('web.session');
|
||||
var data = require('web.data');
|
||||
var ActionManager = require('web.ActionManager');
|
||||
var chat_manager = require('mail.chat_manager');
|
||||
var ChatThread = require('mail.ChatThread');
|
||||
var Chatter = require('mail.Chatter');
|
||||
|
||||
var _t = core._t;
|
||||
var MessageModel = new Model('mail.message', session.context);
|
||||
var _t = core._t;
|
||||
|
||||
// chat_manager is a simple dictionary, not an OdooClass
|
||||
chat_manager._make_message_super = chat_manager.make_message;
|
||||
chat_manager.make_message = function(data) {
|
||||
var msg = this._make_message_super(data);
|
||||
msg.partner_trackings = data.partner_trackings || [];
|
||||
return msg;
|
||||
};
|
||||
|
||||
ChatThread.include({
|
||||
ChatThread.include({
|
||||
events: _.extend(ChatThread.prototype.events, {
|
||||
'click .o_mail_action_tracking_partner': 'on_tracking_partner_click',
|
||||
'click .o_mail_action_tracking_status': 'on_tracking_status_click',
|
||||
}),
|
||||
_preprocess_message: function (message) {
|
||||
var msg = this._super.apply(this, arguments);
|
||||
msg.partner_trackings = msg.partner_trackings || [];
|
||||
|
@ -60,39 +73,11 @@ ChatThread.include({
|
|||
};
|
||||
this.do_action(action);
|
||||
},
|
||||
bind_events: function () {
|
||||
this.$el.on('click', '.o_mail_action_tracking_partner',
|
||||
this.on_tracking_partner_click);
|
||||
this.$el.on('click', '.o_mail_action_tracking_status',
|
||||
this.on_tracking_status_click);
|
||||
},
|
||||
init: function (parent, options) {
|
||||
this._super.apply(this, arguments);
|
||||
this.action_manager = this.findAncestor(function(ancestor){
|
||||
return ancestor instanceof ActionManager;
|
||||
});
|
||||
},
|
||||
start: function () {
|
||||
this._super();
|
||||
this.bind_events();
|
||||
},
|
||||
render: function(messages, options) {
|
||||
var self = this, render_super = this._super,
|
||||
msgs = {},
|
||||
msg_ids = [];
|
||||
// Update trackings (async) each time we re-render thread
|
||||
_.each(messages, function (message) {
|
||||
msgs[message.id] = message;
|
||||
msg_ids.push(message.id);
|
||||
});
|
||||
MessageModel.call('tracking_status', [msg_ids]).then(function (trackings) {
|
||||
_.each(trackings, function (tracking, id) {
|
||||
msgs[id].partner_trackings = tracking;
|
||||
});
|
||||
render_super.apply(self, [messages, options]);
|
||||
});
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
}); // odoo.define
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
<!-- Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
|
||||
<template>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
# flake8: noqa
|
||||
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import mock
|
||||
from odoo.tools import mute_logger
|
||||
import base64
|
||||
import time
|
||||
from odoo import http
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
@ -29,12 +28,10 @@ class TestMailTracking(TransactionCase):
|
|||
self.sender = self.env['res.partner'].create({
|
||||
'name': 'Test sender',
|
||||
'email': 'sender@example.com',
|
||||
'notify_email': 'always',
|
||||
})
|
||||
self.recipient = self.env['res.partner'].create({
|
||||
'name': 'Test recipient',
|
||||
'email': 'recipient@example.com',
|
||||
'notify_email': 'always',
|
||||
})
|
||||
self.last_request = http.request
|
||||
http.request = type('obj', (object,), {
|
||||
|
@ -138,7 +135,7 @@ class TestMailTracking(TransactionCase):
|
|||
def test_mail_send(self):
|
||||
controller = MailTrackingController()
|
||||
db = self.env.cr.dbname
|
||||
image = base64.decodestring(BLANK)
|
||||
image = BLANK
|
||||
mail, tracking = self.mail_send(self.recipient.email)
|
||||
self.assertEqual(mail.email_to, tracking.recipient)
|
||||
self.assertEqual(mail.email_from, tracking.sender)
|
||||
|
@ -310,8 +307,8 @@ class TestMailTracking(TransactionCase):
|
|||
db = self.env.cr.dbname
|
||||
controller = MailTrackingController()
|
||||
not_found = controller.mail_tracking_all('not_found_db')
|
||||
self.assertEqual('NOT FOUND', not_found.response[0])
|
||||
self.assertEqual(b'NOT FOUND', not_found.response[0])
|
||||
none = controller.mail_tracking_all(db)
|
||||
self.assertEqual('NONE', none.response[0])
|
||||
self.assertEqual(b'NONE', none.response[0])
|
||||
none = controller.mail_tracking_event(db, 'open')
|
||||
self.assertEqual('NONE', none.response[0])
|
||||
self.assertEqual(b'NONE', none.response[0])
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
<!-- Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
|
||||
<odoo>
|
||||
<template id="assets_backend"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
<!-- Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
|
||||
<odoo>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
<!-- Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
|
||||
<odoo>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
<!-- Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
|
||||
<odoo>
|
||||
|
||||
|
|
Loading…
Reference in New Issue