# Read from file, announce on the web, irc from twisted.application import internet, service from twisted.internet import protocol, reactor, defer from twisted.words.protocols import irc from twisted.protocols import basic from twisted.web import resource, server, static import cgi class FingerProtocol(basic.LineReceiver): def lineReceived(self, user): d = self.factory.getUser(user) def onError(err): return 'Internal error in server' d.addErrback(onError) def writeResponse(message): self.transport.write(message + '\r\n') self.transport.loseConnection() d.addCallback(writeResponse) class IRCReplyBot(irc.IRCClient): def connectionMade(self): self.nickname = self.factory.nickname irc.IRCClient.connectionMade(self) def privmsg(self, user, channel, msg): user = user.split('!')[0] if self.nickname.lower() == channel.lower(): d = self.factory.getUser(msg) def onError(err): return 'Internal error in server' d.addErrback(onError) def writeResponse(message): irc.IRCClient.msg(self, user, msg+': '+message) d.addCallback(writeResponse) class FingerService(service.Service): def __init__(self, filename): self.filename = filename self.users = {} def _read(self): self.users.clear() for line in file(self.filename): user, status = line.split(':', 1) user = user.strip() status = status.strip() self.users[user] = status self.call = reactor.callLater(30, self._read) def getUser(self, user): return defer.succeed(self.users.get(user, "No such user")) def getFingerFactory(self): f = protocol.ServerFactory() f.protocol = FingerProtocol f.getUser = self.getUser return f def getResource(self): r = resource.Resource() r.getChild = (lambda path, request: static.Data('
%s
' % tuple(map(cgi.escape, [path,self.users.get(path, "No such user usage: site/user")])), 'text/html')) return r def getIRCBot(self, nickname): f = protocol.ReconnectingClientFactory() f.protocol = IRCReplyBot f.nickname = nickname f.getUser = self.getUser return f def startService(self): self._read() service.Service.startService(self) def stopService(self): service.Service.stopService(self) self.call.cancel() application = service.Application('finger', uid=1, gid=1) f = FingerService('/etc/users') serviceCollection = service.IServiceCollection(application) f.setServiceParent(serviceCollection) internet.TCPServer(79, f.getFingerFactory() ).setServiceParent(serviceCollection) internet.TCPServer(8000, server.Site(f.getResource()) ).setServiceParent(serviceCollection) internet.TCPClient('irc.freenode.org', 6667, f.getIRCBot('fingerbot') ).setServiceParent(serviceCollection)