3
# Copyright (c) 2009 Twisted Matrix Laboratories.
4
# See LICENSE for details.
7
Example of a interfacing to Courier's mail filter interface.
10
LOGFILE = '/tmp/filter.log'
13
from twisted.python import log
14
log.startLogging(open(LOGFILE, 'a'))
16
sys.stderr = log.logfile
19
from twisted.internet import reactor, stdio
20
from twisted.internet.protocol import Protocol, Factory
21
from twisted.protocols import basic
23
FILTERS='/var/lib/courier/filters'
24
ALLFILTERS='/var/lib/courier/allfilters'
25
FILTERNAME='twistedfilter'
28
from syslog import syslog, openlog, LOG_MAIL
29
from rfc822 import Message
32
t,v,tb = sys.exc_info()
33
openlog(FILTERNAME, 0, LOG_MAIL)
34
syslog('Unhandled exception: %s - %s' % (v, t))
36
syslog('Trace: %s:%s %s' % (tb.tb_frame.f_code.co_filename,tb.tb_frame.f_code.co_name,tb.tb_lineno))
43
if os.path.isdir(file):
51
class DieWhenLost(Protocol):
52
def connectionLost(self, reason=None):
56
class MailProcessor(basic.LineReceiver):
57
"""I process a mail message.
59
Override filterMessage to do any filtering you want."""
60
messageFilename = None
63
def connectionMade(self):
64
log.msg('Connection from %r' % self.transport)
65
self.state = 'connected'
68
def lineReceived(self, line):
69
if self.state == 'connected':
70
self.messageFilename = line
71
self.state = 'gotMessageFilename'
72
if self.state == 'gotMessageFilename':
74
self.metaInfo.append(line)
77
self.transport.loseConnection()
81
def filterMessage(self):
84
A trivial example is included.
87
m = Message(open(self.messageFilename))
88
self.sendLine('200 Ok')
91
self.sendLine('435 %s processing error' % FILTERNAME)
95
# Listen on the UNIX socket
97
f.protocol = MailProcessor
98
safe_del('%s/%s' % (ALLFILTERS, FILTERNAME))
99
reactor.listenUNIX('%s/%s' % (ALLFILTERS, FILTERNAME), f, 10)
101
# Once started, close fd 3 to let Courier know we're ready
102
reactor.callLater(0, os.close, 3)
104
# When stdin is closed, it's time to exit.
105
s = stdio.StandardIO(DieWhenLost())
110
if __name__ == '__main__':