]>
code.delx.au - monosys/blob - mail/sendmail.py
4 import smtplib
, email
, urllib
5 import subprocess
, sys
, optparse
9 # Attempt to load this debugging decorator function
10 from decorators
import logCall
13 '''This is a no-op decorator function'''
16 #### USER CONFIG #####
19 SMTPProxy(remoteServer
='mail.internode.on.net', domainSuffix
='.internode.on.net'),
20 SMTPProxy(remoteServer
='smtp.usyd.edu.au', domainSuffix
='.usyd.edu.au'),
21 SMTPProxy(remoteServer
='mail.iinet.net.au', domainSuffix
='.iinet.net.au'),
22 SMTPProxy(remoteServer
='mail.netspace.net.au', domainSuffix
='.netspace.net.au'),
23 SMTPProxy(remoteServer
='mail.optusnet.com.au', domainSuffix
='.optusnet.com.au'),
24 SMTPProxySSH(remoteServer
='kagami.tsukasa.net.au'), # Fall back to sending the email via ssh if nothing else
29 #### REAL CODE STARTS HERE ####
31 class SMTPProxyBase(object):
33 return '%s(%s)' % (self
.__class
__.__name
__,
34 ', '.join('%s=%r' % (k
, getattr(self
, k
)) for k
in self
.__slots
__)
37 class SMTPProxy(SMTPProxyBase
):
46 def __init__(self
, remoteServer
, domainSuffix
, username
=None, password
=None, useSSL
=False):
47 self
.remoteServer
= remoteServer
48 self
.domainSuffix
= domainSuffix
50 self
.username
= username
51 self
.password
= password
54 def doesHandle(self
, localhostName
):
55 '''Determines if this SMTPProxy can be used within this domain'''
56 if localhostName
is None:
59 return localhostName
.endswith(self
.domainSuffix
)
61 def sendmail(self
, fromAddr
, toAddrs
, message
):
63 Actually send the mail.
65 Returns true if the mail was successfully send
68 smtp
= smtplib
.SMTP(self
.remoteServer
)
71 if self
.username
is not None and self
.password
is not None:
72 smtp
.login(self
.username
, self
.password
)
73 smtp
.sendmail(fromAddr
, toAddrs
, message
)
77 class SMTPProxySSH(SMTPProxyBase
):
78 __slots__
= ('remoteServer',)
80 def __init__(self
, remoteServer
):
81 self
.remoteServer
= remoteServer
83 def doesHandle(self
, *args
, **kwargs
):
85 Determines if this SMTPProxySSH can be used within this domain.
86 Note: This method returns true for all values.
90 def sendmail(self
, fromAddr
, toAddrs
, message
):
92 Actually send the mail.
94 Returns true if the mail was successfully send
96 cmdline
= ['ssh', self
.remoteServer
, '/usr/sbin/sendmail', '--']
97 cmdline
.extend(toAddrs
)
98 process
= subprocess
.Popen(cmdline
, stdin
=subprocess
.PIPE
)
99 process
.communicate(message
)
100 return not bool(process
.wait())
102 def getOptionParser():
103 parser
= optparse
.OptionParser(usage
="%prog [options] toAddress1 [toAddress2] ...")
104 parser
.add_option('--debug',
105 action
='store_const', dest
='debugLevel', const
=logging
.DEBUG
,
106 help='Sets the logging level to debug')
107 parser
.add_option('--warn',
108 action
='store_const', dest
='debugLevel', const
=logging
.WARNING
,
109 help='Sets the logging level to warn')
110 parser
.set_default('debugLevel', logging
.ERROR
)
115 # Get the to addresses
116 parser
= getOptionParser()
117 options
, toAddrs
= parser
.parse_args()
118 logging
.basicConfig(level
=options
.debugLevel
)
120 parser
.error('No to addresses found')
124 host
= urllib
.urlopen("http://suits.ug.it.usyd.edu.au/myip.php").read().strip()
127 logging
.exception('Failed to grab our external domain name')
129 for smtpProxy
in getUserConfig():
130 if smtpProxy
.doesHandle(host
):
131 # Got the correct smtpServer
132 logging
.info('Using the Proxy %r to connect from %s', smtpProxy
, host
)
135 logging
.error('Did not find a proxy to connect from %s', host
)
138 # Get the from address
139 message
= sys
.stdin
.read()
140 fromAddr
= email
.message_from_string(message
)["from"]
141 _
, fromAddr
= email
.utils
.parseaddr(fromAddr
)
143 return smtpProxy
.sendmail(fromAddr
, toAddrs
, message
)
145 if __name__
== "__main__":
146 # Specify SMTP servers here