You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

95 lines
4.0 KiB

  1. # -*- coding: utf-8 -*-
  2. # © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
  3. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  4. import re
  5. import threading
  6. from odoo import models, api, tools
  7. class IrMailServer(models.Model):
  8. _inherit = "ir.mail_server"
  9. def _tracking_headers_add(self, tracking_email_id, headers):
  10. """Allow other addons to add its own tracking SMTP headers"""
  11. headers = headers or {}
  12. headers['X-Odoo-Database'] = getattr(
  13. threading.currentThread(), 'dbname', None),
  14. headers['X-Odoo-Tracking-ID'] = tracking_email_id
  15. return headers
  16. def _tracking_email_id_body_get(self, body):
  17. body = body or ''
  18. tracking_email_id = False
  19. # https://regex101.com/r/lW4cB1/2
  20. match = re.search(
  21. r'<img [^>]* data-odoo-tracking-email=["\']([0-9]*)["\']', body)
  22. if match:
  23. try:
  24. tracking_email_id = int(match.group(1))
  25. except: # pragma: no cover
  26. pass
  27. return tracking_email_id
  28. def build_email(self, email_from, email_to, subject, body, email_cc=None,
  29. email_bcc=None, reply_to=False, attachments=None,
  30. message_id=None, references=None, object_id=False,
  31. subtype='plain', headers=None, body_alternative=None,
  32. subtype_alternative='plain'):
  33. tracking_email_id = self._tracking_email_id_body_get(body)
  34. if tracking_email_id:
  35. headers = self._tracking_headers_add(tracking_email_id, headers)
  36. msg = super(IrMailServer, self).build_email(
  37. email_from, email_to, subject, body, email_cc=email_cc,
  38. email_bcc=email_bcc, reply_to=reply_to, attachments=attachments,
  39. message_id=message_id, references=references, object_id=object_id,
  40. subtype=subtype, headers=headers,
  41. body_alternative=body_alternative,
  42. subtype_alternative=subtype_alternative)
  43. return msg
  44. def _tracking_email_get(self, message):
  45. tracking_email_id = False
  46. if message.get('X-Odoo-Tracking-ID', '').isdigit():
  47. tracking_email_id = int(message['X-Odoo-Tracking-ID'])
  48. return self.env['mail.tracking.email'].browse(tracking_email_id)
  49. def _smtp_server_get(self, mail_server_id, smtp_server):
  50. smtp_server_used = False
  51. mail_server = None
  52. if mail_server_id:
  53. mail_server = self.browse(mail_server_id)
  54. elif not smtp_server:
  55. mail_server_ids = self.search([], order='sequence', limit=1)
  56. mail_server = mail_server_ids[0] if mail_server_ids else None
  57. if mail_server:
  58. smtp_server_used = mail_server.smtp_host
  59. else: # pragma: no cover
  60. smtp_server_used = smtp_server or tools.config.get('smtp_server')
  61. return smtp_server_used
  62. @api.model
  63. def send_email(self, message, mail_server_id=None, smtp_server=None,
  64. smtp_port=None, smtp_user=None, smtp_password=None,
  65. smtp_encryption=None, smtp_debug=False):
  66. message_id = False
  67. tracking_email = self._tracking_email_get(message)
  68. smtp_server_used = self.sudo()._smtp_server_get(
  69. mail_server_id, smtp_server,
  70. )
  71. try:
  72. message_id = super(IrMailServer, self).send_email(
  73. message, mail_server_id=mail_server_id,
  74. smtp_server=smtp_server, smtp_port=smtp_port,
  75. smtp_user=smtp_user, smtp_password=smtp_password,
  76. smtp_encryption=smtp_encryption, smtp_debug=smtp_debug)
  77. except Exception as e:
  78. if tracking_email:
  79. tracking_email.smtp_error(self, smtp_server_used, e)
  80. raise
  81. if message_id and tracking_email:
  82. vals = tracking_email._tracking_sent_prepare(
  83. self, smtp_server_used, message, message_id)
  84. if vals:
  85. self.env['mail.tracking.event'].sudo().create(vals)
  86. return message_id