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.

81 lines
3.0 KiB

  1. # -*- coding: utf-8 -*-
  2. # Copyright 2017-18 Eficent Business and IT Consulting Services S.L.
  3. # (www.eficent.com)
  4. # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
  5. import email
  6. import xmlrpclib
  7. import logging
  8. from email.message import Message
  9. from odoo import api, models
  10. from odoo.tools import decode_smtp_header as decode
  11. _logger = logging.getLogger(__name__)
  12. class MailThread(models.AbstractModel):
  13. _inherit = 'mail.thread'
  14. @api.model
  15. def message_parse_basic_data(self, message):
  16. """Parses a string or email.message.Message representing an RFC-2822
  17. email, and returns a generic dict holding the message details.
  18. :param message: the message to parse
  19. :rtype: dict
  20. :return: A dict with the following structure, where each field
  21. may not be present if missing in original message:
  22. { 'message_id': msg_id,
  23. 'subject': subject,
  24. 'from': from,
  25. 'to': to,
  26. 'cc': cc
  27. }
  28. """
  29. msg_dict = {
  30. 'message_type': 'email',
  31. }
  32. if not isinstance(message, Message):
  33. if isinstance(message, unicode):
  34. # Warning: message_from_string doesn't always work
  35. # correctly on unicode, we must use utf-8 strings here :-(
  36. message = message.encode('utf-8')
  37. message = email.message_from_string(message)
  38. message_id = message['message-id']
  39. if not message_id:
  40. message_id = 'None'
  41. msg_dict['message_id'] = message_id
  42. if message.get('Subject'):
  43. msg_dict['subject'] = decode(message.get('Subject'))
  44. # Envelope fields not stored in mail.message but made available
  45. # for message_new()
  46. msg_dict['from'] = decode(message.get('from'))
  47. msg_dict['to'] = decode(message.get('to'))
  48. msg_dict['cc'] = decode(message.get('cc'))
  49. msg_dict['email_from'] = decode(message.get('from'))
  50. return msg_dict
  51. @api.model
  52. def message_process(self, model, message, custom_values=None,
  53. save_original=False, strip_attachments=False,
  54. thread_id=None):
  55. if isinstance(message, xmlrpclib.Binary):
  56. message = str(message.data)
  57. # Warning: message_from_string doesn't always work correctly on
  58. # unicode, we must use utf-8 strings here :-(
  59. if isinstance(message, unicode):
  60. message = message.encode('utf-8')
  61. msg_txt = email.message_from_string(message)
  62. msg = self.message_parse_basic_data(msg_txt)
  63. _logger.info(
  64. 'Fetched mail from %s to %s with Message-Id %s',
  65. msg.get('from'), msg.get('to'), msg.get('message_id'))
  66. return super(MailThread, self).message_process(
  67. model, message, custom_values=custom_values,
  68. save_original=save_original,
  69. strip_attachments=strip_attachments, thread_id=thread_id)