Initial import to Tizen
[profile/ivi/python-twisted.git] / doc / mail / examples / smtpclient_tls.py
1
2 """
3 Demonstrate sending mail via SMTP while employing TLS and performing
4 authentication.
5 """
6
7 import sys
8
9 from OpenSSL.SSL import SSLv3_METHOD
10
11 from twisted.mail.smtp import ESMTPSenderFactory
12 from twisted.python.usage import Options, UsageError
13 from twisted.internet.ssl import ClientContextFactory
14 from twisted.internet.defer import Deferred
15 from twisted.internet import reactor
16
17 def sendmail(
18     authenticationUsername, authenticationSecret,
19     fromAddress, toAddress,
20     messageFile,
21     smtpHost, smtpPort=25
22     ):
23     """
24     @param authenticationUsername: The username with which to authenticate.
25     @param authenticationSecret: The password with which to authenticate.
26     @param fromAddress: The SMTP reverse path (ie, MAIL FROM)
27     @param toAddress: The SMTP forward path (ie, RCPT TO)
28     @param messageFile: A file-like object containing the headers and body of
29     the message to send.
30     @param smtpHost: The MX host to which to connect.
31     @param smtpPort: The port number to which to connect.
32
33     @return: A Deferred which will be called back when the message has been
34     sent or which will errback if it cannot be sent.
35     """
36
37     # Create a context factory which only allows SSLv3 and does not verify
38     # the peer's certificate.
39     contextFactory = ClientContextFactory()
40     contextFactory.method = SSLv3_METHOD
41
42     resultDeferred = Deferred()
43
44     senderFactory = ESMTPSenderFactory(
45         authenticationUsername,
46         authenticationSecret,
47         fromAddress,
48         toAddress,
49         messageFile,
50         resultDeferred,
51         contextFactory=contextFactory)
52
53     reactor.connectTCP(smtpHost, smtpPort, senderFactory)
54
55     return resultDeferred
56
57
58
59 class SendmailOptions(Options):
60     synopsis = "smtpclient_tls.py [options]"
61
62     optParameters = [
63         ('username', 'u', None,
64          'The username with which to authenticate to the SMTP server.'),
65         ('password', 'p', None,
66          'The password with which to authenticate to the SMTP server.'),
67         ('from-address', 'f', None,
68          'The address from which to send the message.'),
69         ('to-address', 't', None,
70          'The address to which to send the message.'),
71         ('message', 'm', None,
72          'The filename which contains the message to send.'),
73         ('smtp-host', 'h', None,
74          'The host through which to send the message.'),
75         ('smtp-port', None, '25',
76          'The port number on smtp-host to which to connect.')]
77
78
79     def postOptions(self):
80         """
81         Parse integer parameters, open the message file, and make sure all
82         required parameters have been specified.
83         """
84         try:
85             self['smtp-port'] = int(self['smtp-port'])
86         except ValueError:
87             raise UsageError("--smtp-port argument must be an integer.")
88         if self['username'] is None:
89             raise UsageError(
90                 "Must specify authentication username with --username")
91         if self['password'] is None:
92             raise UsageError(
93                 "Must specify authentication password with --password")
94         if self['from-address'] is None:
95             raise UsageError("Must specify from address with --from-address")
96         if self['to-address'] is None:
97             raise UsageError("Must specify from address with --to-address")
98         if self['smtp-host'] is None:
99             raise UsageError("Must specify smtp host with --smtp-host")
100         if self['message'] is None:
101             raise UsageError(
102                 "Must specify a message file to send with --message")
103         try:
104             self['message'] = file(self['message'])
105         except Exception, e:
106             raise UsageError(e)
107
108
109
110 def cbSentMessage(result):
111     """
112     Called when the message has been sent.
113
114     Report success to the user and then stop the reactor.
115     """
116     print "Message sent"
117     reactor.stop()
118
119
120
121 def ebSentMessage(err):
122     """
123     Called if the message cannot be sent.
124
125     Report the failure to the user and then stop the reactor.
126     """
127     err.printTraceback()
128     reactor.stop()
129
130
131
132 def main(args=None):
133     """
134     Parse arguments and send an email based on them.
135     """
136     o = SendmailOptions()
137     try:
138         o.parseOptions(args)
139     except UsageError, e:
140         raise SystemExit(e)
141     else:
142         from twisted.python import log
143         log.startLogging(sys.stdout)
144         result = sendmail(
145             o['username'],
146             o['password'],
147             o['from-address'],
148             o['to-address'],
149             o['message'],
150             o['smtp-host'],
151             o['smtp-port'])
152         result.addCallbacks(cbSentMessage, ebSentMessage)
153         reactor.run()
154
155
156 if __name__ == '__main__':
157     main(sys.argv[1:])