Package turbomail :: Module dispatch
[hide private]
[frames] | no frames]

Source Code for Module turbomail.dispatch

  1  # encoding: utf-8 
  2   
  3  """This module contains only the primary SMTP Dispatch class.""" 
  4   
  5  import logging 
  6  log = logging.getLogger("turbomail.dispatch") 
  7   
  8  from smtplib import SMTP 
  9   
 10   
 11  __all__ = ['Dispatch'] 
 12   
 13   
14 -class Dispatch(object):
15 """SMTP message dispatch class. 16 17 An instance of the Dispatch class is created for each SMTP 18 connection. Usually, this means one Dispatch instance per 19 running thread. 20 21 Example usage:: 22 23 import turbomail 24 dispatch = turbomail.Dispatch("localhost") 25 message = turbomail.Message( 26 "from@localhost", 27 "to@localhost", 28 "Subject", 29 plain="Hello world!" 30 ) 31 dispatch(message) 32 """ 33
34 - def __init__(self, server, username=None, password=None, tls=None, debug=False):
35 """Initialize the Dispatch class. 36 37 Authentication is only performed if both I{username} and 38 I{password} are not None. An instance of Dispatch is callable. 39 40 @param server: The server (with optional port number) to 41 connect this instance to. 42 @type server: string 43 44 @param username: The username to use during authentication. 45 I{Optional.} 46 @type username: string 47 48 @param password: The password to use during authentaction. 49 I{Optional.} 50 @type password: string 51 52 @param debug: Enable SMTP verbose logging. This outputs all 53 communications between the client and server. 54 @type debug: bool 55 """ 56 57 super(Dispatch, self).__init__() 58 59 self.server = server 60 self.username = username 61 self.password = password 62 self.tls = tls 63 self.debug = debug 64 self.log = None 65 66 log.debug("Creating SMTP object.") 67 self.connection = SMTP() 68 self.connection.set_debuglevel(debug)
69
70 - def connected(self):
71 """Return the current SMTP connection status.""" 72 73 return getattr(self.connection, 'sock', None) is not None
74 connected = property(connected) 75
76 - def connect(self):
77 """Connect to the SMTP server if not already connected. 78 79 This process also automatically enables TLS, if available, and 80 authenticates against the username and password previousally 81 provided. 82 """ 83 84 if self.connected: return 85 86 log.debug("Connecting to SMTP server %s." % self.server) 87 self.connection.connect(self.server) 88 89 if self.tls or self.tls is None: 90 self.connection.ehlo() 91 92 if self.connection.has_extn('STARTTLS') or self.tls: 93 self.connection.starttls() 94 self.connection.ehlo() 95 log.debug("TLS enabled on SMTP server.") 96 self.tls = True 97 98 else: 99 log.debug("TLS not available on SMTP server.") 100 self.tls = False 101 102 if self.username and self.password: 103 log.debug("Authenticating as %s." % self.username) 104 self.connection.login(self.username, self.password)
105
106 - def disconnect(self):
107 """Disconnect from the SMTP server if connected.""" 108 109 if not self.connected: return 110 111 log.debug("Closing SMTP connection.") 112 self.connection.quit()
113
114 - def __call__(self, message):
115 """Deliver a message via the current SMTP connection. 116 117 Calling an instance of the Dispatch class will automatically 118 connect, if needed, and will also automatically disconnect if 119 debug mode has been enabled. 120 121 @param message: This paramater must be a callable which returns 122 a tuple of (from, to, message), where all three 123 are strings, and message is valid content for an 124 e-mail message. 125 @type message: callable 126 """ 127 128 self.connect() 129 130 if callable(message): 131 pack = message() 132 else: 133 pack = message 134 135 pack.update(dict( 136 user="", 137 server=self.server, 138 size=len(pack['message']), 139 )) 140 if self.username: pack['user'] = self.username + "@" 141 142 packUpdate = {} 143 if isinstance(pack['sender'], tuple): 144 packUpdate['addrfrom'] = '"%s" %s' % pack['sender'] 145 packUpdate['smtpfrom'] = pack['sender'][1] 146 else: 147 packUpdate['addrfrom'] = '- %s' % pack['sender'] 148 packUpdate['smtpfrom'] = pack['sender'] 149 150 if 'smtpfrom' in pack: 151 if isinstance(pack['smtpfrom'], tuple): 152 packUpdate['smtpfrom'] = pack['smtpfrom'][1] 153 else: 154 packUpdate['smtpfrom'] = pack['smtpfrom'] 155 156 pack.update(packUpdate) 157 158 if len(pack['to']) > 1: 159 pack.update(dict(addrto="- (%d)" % len(pack['to']))) 160 else: 161 if isinstance(pack['to'][0], tuple): 162 pack.update(dict(addrto='"%s" %s' % pack['to'][0])) 163 else: 164 pack.update(dict(addrto='- %s' % pack['to'][0])) 165 166 log.info( 167 "%(user)s%(server)s %(size)d %(addrfrom)s %(addrto)s - %(subject)s" % pack 168 ) 169 self.connection.sendmail(pack['smtpfrom'], pack['recipients'], pack['message']) 170 171 if self.debug: self.disconnect()
172