social/mail_tracking/controllers/main.py
2022-04-20 14:46:22 +05:30

118 lines
3.9 KiB
Python

# Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import base64
import logging
from contextlib import contextmanager
import werkzeug
import odoo
from odoo import SUPERUSER_ID, api, http
from odoo.addons.mail.controllers.discuss import DiscussController
from odoo.addons.mail.controllers.mail import MailController
_logger = logging.getLogger(__name__)
BLANK = "R0lGODlhAQABAIAAANvf7wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="
@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()
yield api.Environment(cr, SUPERUSER_ID, {})
class MailTrackingController(MailController, DiscussController):
def _request_metadata(self):
"""Prepare remote info metadata"""
request = http.request.httprequest
return {
"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,
}
@http.route(
[
"/mail/tracking/all/<string:db>",
"/mail/tracking/event/<string:db>/<string:event_type>",
],
type="http",
auth="none",
csrf=False,
)
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:
res = env["mail.tracking.email"].event_process(
http.request, kw, metadata, event_type=event_type
)
except Exception as e:
_logger.warning(e)
if not res or res == "NOT FOUND":
return werkzeug.exceptions.NotAcceptable()
return res
@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"],
)
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:
tracking_email = env["mail.tracking.email"].search(
[("id", "=", tracking_email_id), ("token", "=", token)]
)
if not tracking_email:
_logger.warning(
"MailTracking email '%s' not found", tracking_email_id
)
elif tracking_email.state in ("sent", "delivered"):
tracking_email.event_create("open", metadata)
except Exception as e:
_logger.warning(e)
# Always return GIF blank image
response = werkzeug.wrappers.Response()
response.mimetype = "image/gif"
response.data = base64.b64decode(BLANK)
return response
@http.route()
def mail_init_messaging(self):
"""Route used to initial values of Discuss app"""
values = super().mail_init_messaging()
values.update(
{"failed_counter": http.request.env["mail.message"].get_failed_count()}
)
return values
@http.route("/mail/failed/messages", methods=["POST"], type="json", auth="user")
def discuss_failed_messages(self, max_id=None, min_id=None, limit=30, **kwargs):
return http.request.env["mail.message"]._message_fetch(
domain=[("is_failed_message", "=", True)],
max_id=max_id,
min_id=min_id,
limit=limit,
)