2018-03-19 16:41:26 +01:00
|
|
|
# Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
2016-06-14 17:22:17 +02:00
|
|
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
|
|
|
|
2019-11-18 11:46:59 +01:00
|
|
|
import base64
|
|
|
|
import logging
|
|
|
|
from contextlib import contextmanager
|
|
|
|
|
2016-06-14 17:22:17 +02:00
|
|
|
import werkzeug
|
2019-11-18 11:46:59 +01:00
|
|
|
|
2019-10-17 03:28:42 +02:00
|
|
|
import odoo
|
2019-11-18 11:46:59 +01:00
|
|
|
from odoo import SUPERUSER_ID, api, http
|
2019-10-17 03:28:42 +02:00
|
|
|
|
2019-07-05 14:20:27 +02:00
|
|
|
from odoo.addons.mail.controllers.main import MailController
|
2019-11-18 11:46:59 +01:00
|
|
|
|
2016-06-14 17:22:17 +02:00
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
2019-11-18 11:46:59 +01:00
|
|
|
BLANK = "R0lGODlhAQABAIAAANvf7wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="
|
2016-06-14 17:22:17 +02:00
|
|
|
|
|
|
|
|
2019-10-17 03:28:42 +02:00
|
|
|
@contextmanager
|
|
|
|
def db_env(dbname):
|
|
|
|
if not http.db_filter([dbname]):
|
|
|
|
raise werkzeug.exceptions.BadRequest()
|
|
|
|
cr = None
|
|
|
|
if dbname == http.request.db:
|
|
|
|
cr = http.request.cr
|
|
|
|
if not cr:
|
|
|
|
cr = odoo.sql_db.db_connect(dbname).cursor()
|
|
|
|
with api.Environment.manage():
|
|
|
|
yield api.Environment(cr, SUPERUSER_ID, {})
|
2016-06-14 17:22:17 +02:00
|
|
|
|
|
|
|
|
2019-07-05 14:20:27 +02:00
|
|
|
class MailTrackingController(MailController):
|
2016-06-14 17:22:17 +02:00
|
|
|
def _request_metadata(self):
|
2019-10-17 03:28:42 +02:00
|
|
|
"""Prepare remote info metadata"""
|
2016-06-14 17:22:17 +02:00
|
|
|
request = http.request.httprequest
|
|
|
|
return {
|
2019-11-18 11:46:59 +01:00
|
|
|
"ip": request.remote_addr or False,
|
|
|
|
"user_agent": request.user_agent or False,
|
|
|
|
"os_family": request.user_agent.platform or False,
|
|
|
|
"ua_family": request.user_agent.browser or False,
|
2016-06-14 17:22:17 +02:00
|
|
|
}
|
|
|
|
|
2019-11-18 11:46:59 +01:00
|
|
|
@http.route(
|
|
|
|
[
|
|
|
|
"/mail/tracking/all/<string:db>",
|
|
|
|
"/mail/tracking/event/<string:db>/<string:event_type>",
|
|
|
|
],
|
|
|
|
type="http",
|
|
|
|
auth="none",
|
|
|
|
csrf=False,
|
|
|
|
)
|
2019-10-17 03:28:42 +02:00
|
|
|
def mail_tracking_event(self, db, event_type=None, **kw):
|
|
|
|
"""Route used by external mail service"""
|
|
|
|
metadata = self._request_metadata()
|
|
|
|
res = None
|
|
|
|
with db_env(db) as env:
|
|
|
|
try:
|
2019-11-18 11:46:59 +01:00
|
|
|
res = env["mail.tracking.email"].event_process(
|
|
|
|
http.request, kw, metadata, event_type=event_type
|
|
|
|
)
|
2019-10-17 03:28:42 +02:00
|
|
|
except Exception:
|
|
|
|
pass
|
2019-11-18 11:46:59 +01:00
|
|
|
if not res or res == "NOT FOUND":
|
2019-10-17 03:28:42 +02:00
|
|
|
return werkzeug.exceptions.NotAcceptable()
|
|
|
|
return res
|
2016-06-14 17:22:17 +02:00
|
|
|
|
2019-11-18 11:46:59 +01:00
|
|
|
@http.route(
|
|
|
|
[
|
|
|
|
"/mail/tracking/open/<string:db>" "/<int:tracking_email_id>/blank.gif",
|
|
|
|
"/mail/tracking/open/<string:db>"
|
|
|
|
"/<int:tracking_email_id>/<string:token>/blank.gif",
|
|
|
|
],
|
|
|
|
type="http",
|
|
|
|
auth="none",
|
|
|
|
methods=["GET"],
|
|
|
|
)
|
2019-10-17 03:28:42 +02:00
|
|
|
def mail_tracking_open(self, db, tracking_email_id, token=False, **kw):
|
|
|
|
"""Route used to track mail openned (With & Without Token)"""
|
|
|
|
metadata = self._request_metadata()
|
|
|
|
with db_env(db) as env:
|
|
|
|
try:
|
2019-11-18 11:46:59 +01:00
|
|
|
tracking_email = env["mail.tracking.email"].search(
|
2020-03-30 18:41:27 +02:00
|
|
|
[("id", "=", tracking_email_id), ("token", "=", token)]
|
2019-11-18 11:46:59 +01:00
|
|
|
)
|
2020-03-30 18:41:27 +02:00
|
|
|
if not tracking_email:
|
2019-10-17 03:28:42 +02:00
|
|
|
_logger.warning(
|
2019-11-18 11:46:59 +01:00
|
|
|
"MailTracking email '%s' not found", tracking_email_id
|
|
|
|
)
|
2020-03-30 18:41:27 +02:00
|
|
|
elif tracking_email.state in ("sent", "delivered"):
|
|
|
|
tracking_email.event_create("open", metadata)
|
2019-10-17 03:28:42 +02:00
|
|
|
except Exception:
|
|
|
|
pass
|
2016-06-14 17:22:17 +02:00
|
|
|
|
|
|
|
# Always return GIF blank image
|
|
|
|
response = werkzeug.wrappers.Response()
|
2019-11-18 11:46:59 +01:00
|
|
|
response.mimetype = "image/gif"
|
2019-07-24 12:39:27 +02:00
|
|
|
response.data = base64.b64decode(BLANK)
|
2016-06-14 17:22:17 +02:00
|
|
|
return response
|
2019-07-05 14:20:27 +02:00
|
|
|
|
|
|
|
@http.route()
|
2019-10-17 03:28:42 +02:00
|
|
|
def mail_init_messaging(self):
|
|
|
|
"""Route used to initial values of Discuss app"""
|
|
|
|
values = super().mail_init_messaging()
|
2019-11-18 11:46:59 +01:00
|
|
|
values.update(
|
|
|
|
{"failed_counter": http.request.env["mail.message"].get_failed_count()}
|
|
|
|
)
|
2019-07-05 14:20:27 +02:00
|
|
|
return values
|