diff --git a/CHANGELOG b/CHANGELOG index 7b0034e443..386b947c5f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Add option to ensure emails are sent * Allow keyword action for all models * Add sortable_values in tools * Remove default colors on graph and calendar diff --git a/doc/ref/sendmail.rst b/doc/ref/sendmail.rst index 4b77b31f2b..35e760b86f 100644 --- a/doc/ref/sendmail.rst +++ b/doc/ref/sendmail.rst @@ -25,16 +25,20 @@ Send email message like :meth:`sendmail_transactional` but directly without caring about the transaction. The caller may pass a server instance from `smtplib`_. -.. method:: get_smtp_server([uri]) +.. method:: get_smtp_server([uri[, strict]]) Return a SMTP instance from `smtplib`_ using the `uri` or the one defined in the `email` section of the :ref:`configuration `. +If strict is `True`, an exception is raised if it is not possible to connect to +the server. -.. class:: SMTPDataManager([uri]) +.. class:: SMTPDataManager([uri[, strict]]) A :class:`SMTPDataManager` implements a data manager which send queued email at commit. An option optional `uri` can be passed to configure the SMTP connection. +If strict is `True`, the data manager prevents the transaction if it fails to +send the emails. .. method:: SMTPDataManager.put(from_addr, to_addrs, msg) diff --git a/trytond/sendmail.py b/trytond/sendmail.py index 4c04fe5746..3454556936 100644 --- a/trytond/sendmail.py +++ b/trytond/sendmail.py @@ -25,9 +25,9 @@ def sendmail_transactional( datamanager.put(from_addr, to_addrs, msg) -def sendmail(from_addr, to_addrs, msg, server=None): +def sendmail(from_addr, to_addrs, msg, server=None, strict=False): if server is None: - server = get_smtp_server() + server = get_smtp_server(strict=strict) if not server: return quit = True @@ -38,6 +38,8 @@ def sendmail(from_addr, to_addrs, msg, server=None): try: senderrs = server.sendmail(from_addr, to_addrs, msg.as_string()) except Exception: + if strict: + raise logger.error('fail to send email', exc_info=True) else: if senderrs: @@ -52,10 +54,11 @@ def send_test_email(to_addrs, server=None): msg['From'] = from_ msg['To'] = to_addrs msg['Subject'] = 'Tryton test email' - sendmail(config.get('email', 'from'), to_addrs, msg, server=server) + sendmail( + config.get('email', 'from'), to_addrs, msg, server=server, strict=True) -def get_smtp_server(uri=None): +def get_smtp_server(uri=None, strict=False): if uri is None: uri = config.get('email', 'uri') uri = parse_uri(uri) @@ -71,6 +74,8 @@ def get_smtp_server(uri=None): try: server = connector(uri.hostname, uri.port, **extra) except Exception: + if strict: + raise logger.error('fail to connect to %s', uri, exc_info=True) return @@ -86,8 +91,9 @@ def get_smtp_server(uri=None): class SMTPDataManager(object): - def __init__(self, uri=None): + def __init__(self, uri=None, strict=False): self.uri = uri + self.strict = strict self.queue = [] self._server = None @@ -98,7 +104,7 @@ class SMTPDataManager(object): def __eq__(self, other): if not isinstance(other, SMTPDataManager): return NotImplemented - return self.uri == other.uri + return (self.uri == other.uri) and (self.strict == other.strict) def abort(self, trans): self._finish() @@ -111,7 +117,7 @@ class SMTPDataManager(object): def tpc_vote(self, trans): if self._server is None: - self._server = get_smtp_server(self.uri) + self._server = get_smtp_server(self.uri, strict=self.strict) def tpc_finish(self, trans): if self._server is not None: