smmapdfw/smmapd_prototype/SendmailSocketMapHandler.py

191 lines
5.3 KiB
Python
Raw Normal View History

2004-09-20 19:34:09 +00:00
import SocketServer
import time
from Logging import *
class NetStringError(ValueError): pass
def NetStringDecode(s):
try:
length, data = s.split(':')
except ValueError:
raise NetStringError, "Separator not found"
try:
length = int(length)
except ValueError:
raise NetStringError, "Can not read length"
if len(data) != length+1:
raise NetStringError, "Data has unexpected length"
if data[-1] != ',':
raise NetStringError, "End-delimiter not found"
return data[:-1]
def NetStringEncode(s):
return str(len(s)) + ":" + s + ","
class MyPermanentVerifierException(ValueError): pass
class MyTemporaryVerifierException(ValueError): pass
class MyBaseRequestHandler(SocketServer.BaseRequestHandler):
def handle(self):
debug("Connected from " + str(self.client_address))
self.localSetup()
while 1:
receivedData = self.request.recv(8192)
if (receivedData == None) or (len(receivedData) == 0): break
debug("Data: (%s)" % receivedData)
self.request.sendall(self.process(receivedData))
self.request.close();
self.localFinish()
debug("Disconnected")
def process(self, data):
debug("MyBaseRequestHandler.process")
return data
def localSetup(self): pass
def localfinish(self): pass
class SendmailAdaptor:
PERM = "PERM "
OK = "OK "
NOTFOUND = "NOTFOUND "
TEMP = "TEMP "
def preProcess(self, data):
try:
data = NetStringDecode(data)
klass, data = data.split(' ')
return klass, data
except NetStringError, arg:
raise MyPermanentVerifierException, arg
except ValueError:
raise MyPermanentVerifierException, "<class> <data> expected, only one found"
def postProcess(self, data):
return NetStringEncode(data)
def process(self, data):
startTime = time.time()
try:
klass, data2 = self.preProcess(data)
arg = self.execute(klass, data2)
code = SendmailAdaptor.OK
except MyPermanentVerifierException, arg:
code, arg = SendmailAdaptor.PERM, str(arg)
except MyTemporaryVerifierException, arg:
code, arg = SendmailAdaptor.TEMP, str(arg)
endTime = time.time()
log("Class: %s, Data: %s, Code: %s, Arg: %s, Delay: %f" % (klass, data2, code, arg, endTime-startTime))
return self.postProcess(code + arg)
def execute(self, data):
return data
class NullAdaptor(SendmailAdaptor):
def preProcess(self, data):
return re.compile(r'^(.*?)[\r\n]{1,2}$').match(data).group(1)
def postProcess(self, data):
return data + "\n"
class SendmailDispatcher(SendmailAdaptor, MyBaseRequestHandler):
pluginContainerObjects = {}
def registerAll(config):
for section in config.get('Daemon', 'Plugins').split(','):
SendmailDispatcher.register(section, config)
registerAll = staticmethod(registerAll)
def register(section, config):
cfg = Config(section, config)
className = cfg.get('ContainerClass')
moduleName = cfg.get('ContainerModule')
if className == None:
className = 'smmapBaseHandlerContainer'
else:
if moduleName == None:
moduleName == className
m = __import__(moduleName)
log("Registering %s, %s" % (section, className))
klass = eval("m.%s" % className)
containerObject = klass(cfg)
containerObject.setup()
SendmailDispatcher.pluginContainerObjects[section] = containerObject
register = staticmethod(register)
def localSetup(self):
self.pluginWorkerObjects = {}
def localFinish(self):
for o in self.pluginWorkerObjects.values():
o.finish()
def execute(self, klass, data):
if not self.pluginContainerObjects.has_key(klass):
raise MyPermanentVerifierException, "Class %s not implemented" % klass
elif not self.pluginWorkerObjects.has_key(klass):
debug("Instantiate worker %s" % klass)
self.pluginWorkerObjects[klass] = self.pluginContainerObjects[klass].getWorker()
return self.pluginWorkerObjects[klass].execute(data)
class Config(object):
def __init__(self, section, config):
self.section = section
self.config = config
def getSection(self):
return self.section
def get(self, item):
return self.config.get(self.section, item)
class smmapBaseHandlerWorker(object):
def __init__(self, container):
self.container = container
def setup(self): pass
def finish(self): pass
def execute(self, data):
raise NotImplementedError
class smmapBaseHandlerContainer(object):
def __init__(self, cfg):
self.config = cfg
workerClassName = cfg.get('WorkerClass')
workerModuleName = cfg.get('WorkerModule')
if workerModuleName == None:
workerModuleName = workerClassName
m = __import__(workerModuleName)
self.workerClass = eval("m.%s" % workerClassName)
def setup(self): pass
def finish(self): pass
def getWorker(self):
worker = self.workerClass(self)
worker.setup()
return worker