trytond-smtp/smtp.py

200 lines
6.5 KiB
Python
Raw Normal View History

2016-04-12 13:39:27 +02:00
# This file is part smtp module for Tryton.
# The COPYRIGHT file at the top level of this repository contains
# the full copyright notices and license terms.
import logging
2012-10-30 10:24:06 +01:00
from trytond.model import ModelView, ModelSQL, fields
from trytond.pool import Pool
from trytond.pyson import Eval
import smtplib
from trytond.i18n import gettext
from trytond.exceptions import UserError
2012-10-30 10:24:06 +01:00
logger = logging.getLogger(__name__)
2012-10-30 10:24:06 +01:00
2012-12-04 17:07:52 +01:00
2012-10-30 10:24:06 +01:00
class SmtpServer(ModelSQL, ModelView):
'SMTP Servers'
__name__ = 'smtp.server'
name = fields.Char('Name', required=True)
smtp_server = fields.Char('Server', required=True,
states={
'readonly': (Eval('state') != 'draft'),
2016-04-12 13:39:27 +02:00
}, depends=['state'])
smtp_timeout = fields.Integer('Timeout', required=True,
states={
'readonly': (Eval('state') != 'draft'),
}, depends=['state'], help="Time in secods")
smtp_port = fields.Integer('Port', required=True,
2012-10-30 10:24:06 +01:00
states={
'readonly': (Eval('state') != 'draft'),
2016-04-12 13:39:27 +02:00
}, depends=['state'])
2012-10-30 10:24:06 +01:00
smtp_ssl = fields.Boolean('SSL',
states={
'readonly': (Eval('state') != 'draft'),
2016-04-12 13:39:27 +02:00
}, depends=['state'])
2012-10-30 10:24:06 +01:00
smtp_tls = fields.Boolean('TLS',
states={
'readonly': (Eval('state') != 'draft'),
2016-04-12 13:39:27 +02:00
}, depends=['state'])
2012-10-30 10:24:06 +01:00
smtp_user = fields.Char('User',
states={
'readonly': (Eval('state') != 'draft'),
2016-04-12 13:39:27 +02:00
}, depends=['state'])
smtp_password = fields.Char('Password', strip=False,
2012-10-30 10:24:06 +01:00
states={
'readonly': (Eval('state') != 'draft'),
2016-04-12 13:39:27 +02:00
}, depends=['state'])
smtp_use_email = fields.Boolean('Use email',
states={
'readonly': (Eval('state') != 'draft'),
2016-04-12 13:39:27 +02:00
}, depends=['state'], help='Force to send emails using this email')
smtp_email = fields.Char('Email', required=True,
states={
'readonly': (Eval('state') != 'draft'),
2016-04-12 13:39:27 +02:00
}, depends=['state'],
help='Default From (if active this option) and Reply Email')
2012-10-30 10:24:06 +01:00
state = fields.Selection([
2016-04-12 13:39:27 +02:00
('draft', 'Draft'),
('done', 'Done'),
], 'State', readonly=True, required=True)
2012-10-30 10:24:06 +01:00
default = fields.Boolean('Default')
models = fields.Many2Many('smtp.server-ir.model',
'server', 'model', 'Models',
states={
'readonly': Eval('state').in_(['done']),
},
depends=['state'])
2012-10-30 10:24:06 +01:00
@classmethod
def __setup__(cls):
super(SmtpServer, cls).__setup__()
cls._buttons.update({
2016-04-12 13:39:27 +02:00
'get_smtp_test': {},
'draft': {
'invisible': Eval('state') == 'draft',
2018-12-15 10:38:23 +01:00
'depends': ['state'],
2016-04-12 13:39:27 +02:00
},
'done': {
'invisible': Eval('state') == 'done',
2018-12-15 10:38:23 +01:00
'depends': ['state'],
2016-04-12 13:39:27 +02:00
},
})
2012-10-30 10:24:06 +01:00
@classmethod
def check_xml_record(cls, records, values):
return True
2012-10-30 10:24:06 +01:00
@staticmethod
def default_default():
return True
@staticmethod
def default_smtp_timeout():
return 60
2012-10-30 10:24:06 +01:00
@staticmethod
2013-12-09 12:43:33 +01:00
def default_smtp_ssl():
2012-10-30 10:24:06 +01:00
return True
@staticmethod
2013-12-09 12:43:33 +01:00
def default_smtp_port():
return 465
2012-10-30 10:24:06 +01:00
@staticmethod
def default_state():
return 'draft'
@classmethod
@ModelView.button
def draft(cls, servers):
cls.write(servers, {
2016-04-12 13:39:27 +02:00
'state': 'draft',
})
2012-10-30 10:24:06 +01:00
@classmethod
@ModelView.button
def done(cls, servers):
cls.write(servers, {
2016-04-12 13:39:27 +02:00
'state': 'done',
})
2012-10-30 10:24:06 +01:00
@classmethod
@ModelView.button
def get_smtp_test(cls, servers):
"""Checks SMTP credentials and confirms if outgoing connection works"""
for server in servers:
try:
server.get_smtp_server()
2018-08-18 11:12:46 +02:00
except Exception as message:
logger.error('Exception getting smtp server: %s', message)
raise UserError(gettext('smtp.smtp_test_details',
error=message))
raise UserError(gettext('smtp.smtp_successful'))
2012-10-30 10:24:06 +01:00
def get_smtp_server(self):
2012-10-30 10:24:06 +01:00
"""
Instanciate, configure and return a SMTP or SMTP_SSL instance from
smtplib.
:return: A SMTP instance. The quit() method must be call when all
the calls to sendmail() have been made.
"""
if self.smtp_ssl:
smtp_server = smtplib.SMTP_SSL(self.smtp_server, self.smtp_port,
timeout=self.smtp_timeout)
2012-10-30 10:24:06 +01:00
else:
smtp_server = smtplib.SMTP(self.smtp_server, self.smtp_port,
timeout=self.smtp_timeout)
2012-10-30 10:24:06 +01:00
if self.smtp_tls:
2012-10-30 10:24:06 +01:00
smtp_server.starttls()
if self.smtp_user and self.smtp_password:
2018-09-19 07:46:16 +02:00
smtp_server.login(self.smtp_user, self.smtp_password)
2012-10-30 10:24:06 +01:00
return smtp_server
@classmethod
def get_smtp_server_from_model(self, model):
"""
Return Server from Models
:param model: str Model name
return object server
"""
model = Pool().get('ir.model').search([('model', '=', model)])[0]
servers = Pool().get('smtp.server-ir.model').search([
2016-04-12 13:39:27 +02:00
('model', '=', model),
], limit=1)
if not servers:
logger.warning('No SMTP server found for model %s' % model)
raise UserError(gettext(
'smtp.server_model_not_found', model=model.name))
return servers[0].server
def send_mail(self, from_, cc, email):
try:
smtp_server = self.get_smtp_server()
2023-10-11 10:43:33 +02:00
smtp_server.sendmail(from_, cc, email)
smtp_server.quit()
return True
2018-08-18 11:12:46 +02:00
except smtplib.SMTPException as error:
logger.error('SMTPException: %s', error)
2020-11-05 16:22:17 +01:00
raise UserError(gettext('smtp.smtp_exception', error=error))
2018-08-18 11:12:46 +02:00
except smtplib.socket.error as error:
logger.error('socket.error: %s', error)
raise UserError(gettext('smtp.smtp_server_error', error=error))
except smtplib.SMTPRecipientsRefused as error:
logger.error('socket.error: %s', error)
raise UserError(gettext('smtp.smtp_server_error', error=error))
return False
class SmtpServerModel(ModelSQL):
'SMTP Server - Model'
__name__ = 'smtp.server-ir.model'
_table = 'smtp_server_ir_model'
server = fields.Many2One('smtp.server', 'Server', ondelete='CASCADE',
required=True)
model = fields.Many2One('ir.model', 'Model', ondelete='RESTRICT',
required=True)