1
2
3 """Deliver messages using (E)SMTP."""
4
5
6 import logging
7 import socket
8
9 from smtplib import SMTP, SMTPException, SMTPRecipientsRefused, SMTPSenderRefused, SMTPServerDisconnected
10
11 from turbomail.api import Transport, TransportFactory
12 from turbomail.compat import get_message
13 from turbomail.control import interface
14 from turbomail.exceptions import MailConfigurationException, TransportExhaustedException
15
16
17 __all__ = ['load']
18
19 log = logging.getLogger("turbomail.transport")
20 deliverylog = logging.getLogger("turbomail.delivery")
21
22
23
26
27
30 super(SMTPTransport, self).__init__()
31 log.debug("SMTPTransport created.")
32
33 self.server = self.config_get('mail.smtp.server', None)
34 if self.server == None:
35 raise MailConfigurationException('no server configured for smtp ("mail.smtp.server")')
36 self.username = self.config_get("mail.smtp.username")
37 self.password = self.config_get("mail.smtp.password")
38 self.use_tls = self.config_get("mail.smtp.tls", None)
39 self.debug = self.config_get("mail.smtp.debug", False)
40
41 self.max_number_of_messages_per_connection = \
42 self.config_get('mail.smtp.max_messages_per_connection', default=1, tm2_key='jobs')
43
44 self.connection = None
45 self.nr_messages_sent_with_this_connection = None
46
48 if self.is_connected():
49 log.debug("Closing SMTP connection.")
50 try:
51 try:
52 self.connection.quit()
53 except SMTPServerDisconnected:
54 pass
55 except (SMTPException, socket.error), e:
56 msg = 'Exception occured when stopping connection' + unicode(e)
57 log.exception(msg)
58 finally:
59 self.connection = None
60
64
66 return getattr(self.connection, 'sock', None) is not None
67
82
84 connection = SMTP()
85 connection.set_debuglevel(self.debug)
86 log.info("Connecting to SMTP server %s." % self.server)
87 connection.connect(self.server)
88
89 self._encrypt_connection_with_tls_if_configured(connection)
90 if self.username and self.password:
91 log.info("Authenticating as %s." % self.username)
92 connection.login(self.username, self.password)
93 return connection
94
99
101 return self.nr_messages_sent_with_this_connection < self.max_number_of_messages_per_connection
102
104 try:
105 self.nr_messages_sent_with_this_connection += 1
106 sender = str(message.envelope_sender)
107 recipients = message.recipients.string_addresses
108 self.connection.sendmail(sender, recipients, str(message))
109 except SMTPSenderRefused, e:
110
111 deliverylog.error("%s REFUSED %s %s" % (message.id, e.__class__.__name__, get_message(e)))
112 raise
113 except SMTPRecipientsRefused, e:
114
115
116 deliverylog.warning("%s REFUSED %s %s" % (message.id, e.__class__.__name__, get_message(e)))
117 raise
118 except SMTPServerDisconnected, e:
119 raise TransportExhaustedException
120 except Exception, e:
121 cls_name = e.__class__.__name__
122 deliverylog.debug("%s EXCEPTION %s" % (message.id, cls_name), exc_info=True)
123
124 if message.nr_retries >= 0:
125 deliverylog.warning("%s DEFERRED %s" % (message.id, cls_name))
126 message.nr_retries -= 1
127 interface.manager.deliver(message)
128 return
129 else:
130 deliverylog.error("%s REFUSED %s" % (message.id, cls_name), exc_info=True)
131 raise
132
144
145
149