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.

128 lines
4.8 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. import logging
  2. import re
  3. import imaplib
  4. import threading
  5. from odoo import tools
  6. from odoo.exceptions import ValidationError
  7. from odoo import fields
  8. from odoo import models
  9. from odoo import api
  10. from odoo.tools.translate import _
  11. _logger = logging.getLogger(__name__)
  12. _test_logger = logging.getLogger('odoo.tests')
  13. class IrMailServer(models.Model):
  14. _inherit = 'ir.mail_server'
  15. imap_mailbox_folder = fields.Many2one('ir.mail.imap.folder',
  16. 'Imap Folders',)
  17. imap_mailbox_verified = fields.Boolean('IMAP Connection Verified', )
  18. store_outgoing_mail = fields.Boolean()
  19. has_separate_imap_server = fields.Boolean('Use Separate Imap Server', )
  20. separate_imap_server = fields.Char()
  21. active = fields.Boolean()
  22. @api.model
  23. def parse_list_response(self, line):
  24. line = line.decode('utf-8')
  25. list_response_pattern = re.compile(
  26. r'\((?P<flags>.*?)\) "(?P<delimiter>.*)" (?P<name>.*)'
  27. )
  28. flags, delimiter, mailbox_name = \
  29. list_response_pattern.match(line).groups()
  30. mailbox_name = mailbox_name.strip('"')
  31. return (flags, delimiter, mailbox_name)
  32. @api.multi
  33. def test_imap_connection(self):
  34. self.ensure_one()
  35. imap_pool = self.env['ir.mail.imap.folder']
  36. maillib = None
  37. if self.has_separate_imap_server:
  38. smtp_server = self.separate_imap_server
  39. else:
  40. smtp_server = self.smtp_host
  41. try:
  42. if getattr(threading.currentThread(), 'testing', False) or \
  43. self.env.registry.in_test_mode():
  44. _test_logger.info("skip sending email in test mode")
  45. return True
  46. maillib = imaplib.IMAP4_SSL(smtp_server)
  47. maillib.login(self.smtp_user, self.smtp_pass)
  48. typ, mBoxes = maillib.list()
  49. folder_ids = imap_pool.search([('server_id', '=', self.id)])
  50. for folder in folder_ids:
  51. folder.unlink()
  52. for line in mBoxes:
  53. flags, delimiter, \
  54. mailbox_name = self.parse_list_response(line)
  55. res = {'server_id': self.id, 'name': mailbox_name, }
  56. imap_pool.create(res)
  57. self.write({'imap_mailbox_verified': True})
  58. except Exception as e:
  59. raise ValidationError(
  60. _("Connection Test Failed! "
  61. "Here is what we got instead:\n %s") % tools.ustr(e))
  62. finally:
  63. if maillib:
  64. maillib.logout()
  65. @api.model
  66. def send_email(self, message, mail_server_id=None,
  67. smtp_server=None, smtp_port=None, smtp_user=None,
  68. smtp_password=None, smtp_encryption=None,
  69. smtp_debug=False, smtp_session=None):
  70. res = super(IrMailServer, self).send_email(
  71. message, mail_server_id, smtp_server, smtp_port,
  72. smtp_user, smtp_password, smtp_encryption, smtp_debug,
  73. smtp_session)
  74. self._save_sent_message_to_sentbox(message, mail_server_id)
  75. return res
  76. @api.model
  77. def _save_sent_message_to_sentbox(self, msg, mail_server_id=None):
  78. mail_server = None
  79. smtp_server = None
  80. maillib = None
  81. if mail_server_id:
  82. mail_server = self.sudo().browse(mail_server_id)
  83. else:
  84. mail_server = self.sudo().search([], order='sequence', limit=1)
  85. if mail_server:
  86. if not mail_server.store_outgoing_mail:
  87. return True
  88. if mail_server.has_separate_imap_server:
  89. smtp_server = mail_server.separate_imap_server
  90. else:
  91. smtp_server = mail_server.smtp_host
  92. smtp_user = mail_server.smtp_user
  93. smtp_password = mail_server.smtp_pass
  94. try:
  95. if getattr(threading.currentThread(), 'testing', False) or \
  96. self.env.registry.in_test_mode():
  97. _test_logger.info("skip sending email in test mode")
  98. return True
  99. maillib = imaplib.IMAP4_SSL(smtp_server)
  100. maillib.login(smtp_user, smtp_password)
  101. folder = mail_server.imap_mailbox_folder.name.join('""')
  102. maillib.append(str.encode(folder),
  103. r'\Seen', None, str(msg).encode())
  104. except Exception as ex:
  105. _logger.error(_(
  106. 'Failed attaching mail via imap to server %s %s')
  107. % (ex, msg))
  108. finally:
  109. if maillib:
  110. maillib.logout()
  111. return True
  112. class IrMailImapFolder(models.Model):
  113. _name = 'ir.mail.imap.folder'
  114. _description = 'Imap Folder'
  115. server_id = fields.Many2one('ir.mail_server', 'Mail Server', )
  116. name = fields.Char('Foldername',)