Initial import to Tizen
[profile/ivi/python-twisted.git] / doc / core / examples / courier.py
1 #!/usr/bin/env python
2
3 # Copyright (c) Twisted Matrix Laboratories.
4 # See LICENSE for details.
5
6 """
7 Example of a interfacing to Courier's mail filter interface.
8 """
9
10 LOGFILE = '/tmp/filter.log'
11
12 # Setup log file
13 from twisted.python import log
14 log.startLogging(open(LOGFILE, 'a'))
15 import sys
16 sys.stderr = log.logfile
17
18 # Twisted imports
19 from twisted.internet import reactor, stdio
20 from twisted.internet.protocol import Protocol, Factory
21 from twisted.protocols import basic
22
23 FILTERS='/var/lib/courier/filters'
24 ALLFILTERS='/var/lib/courier/allfilters'
25 FILTERNAME='twistedfilter'
26
27 import os, os.path 
28 from syslog import syslog, openlog, LOG_MAIL
29 from rfc822 import Message
30
31 def trace_dump():
32     t,v,tb = sys.exc_info()
33     openlog(FILTERNAME, 0, LOG_MAIL)
34     syslog('Unhandled exception: %s - %s' % (v, t))
35     while tb:
36         syslog('Trace: %s:%s %s' % (tb.tb_frame.f_code.co_filename,tb.tb_frame.f_code.co_name,tb.tb_lineno))
37         tb = tb.tb_next
38     # just to be safe
39     del tb
40
41 def safe_del(file):
42     try:
43         if os.path.isdir(file):
44             os.removedirs(file)
45         else:
46             os.remove(file)
47     except OSError:
48         pass
49
50
51 class DieWhenLost(Protocol):
52     def connectionLost(self, reason=None):
53         reactor.stop()
54
55
56 class MailProcessor(basic.LineReceiver):
57     """I process a mail message.
58     
59     Override filterMessage to do any filtering you want."""
60     messageFilename = None
61     delimiter = '\n'
62     
63     def connectionMade(self):
64         log.msg('Connection from %r' % self.transport)
65         self.state = 'connected'
66         self.metaInfo = []
67
68     def lineReceived(self, line):
69         if self.state == 'connected':
70             self.messageFilename = line
71             self.state = 'gotMessageFilename'
72         if self.state == 'gotMessageFilename':
73             if line:
74                 self.metaInfo.append(line)
75             else:
76                 if not self.metaInfo:
77                     self.transport.loseConnection()
78                     return
79                 self.filterMessage()
80
81     def filterMessage(self):
82         """Override this.
83
84         A trivial example is included.
85         """
86         try:
87             m = Message(open(self.messageFilename))
88             self.sendLine('200 Ok')
89         except:
90             trace_dump()
91             self.sendLine('435 %s processing error' % FILTERNAME)
92         
93
94 def main():
95     # Listen on the UNIX socket
96     f = Factory()
97     f.protocol = MailProcessor
98     safe_del('%s/%s' % (ALLFILTERS, FILTERNAME))
99     reactor.listenUNIX('%s/%s' % (ALLFILTERS, FILTERNAME), f, 10)
100
101     # Once started, close fd 3 to let Courier know we're ready
102     reactor.callLater(0, os.close, 3)
103
104     # When stdin is closed, it's time to exit.
105     s = stdio.StandardIO(DieWhenLost())
106
107     # Go!
108     reactor.run()
109
110 if __name__ == '__main__':
111     main()