1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
# Read from file, announce on the web, irc, xml-rpc
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, xmlrpc
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 = {}
self._read()
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('<h1>%s</h1><p>%s</p>' %
tuple(map(cgi.escape,
[path,self.users.get(path, "No such user")])),
'text/html'))
x = xmlrpc.XMLRPC()
x.xmlrpc_getUser = self.getUser
r.putChild('RPC2', x)
return r
def getIRCBot(self, nickname):
f = protocol.ReconnectingClientFactory()
f.protocol = IRCReplyBot
f.nickname = nickname
f.getUser = self.getUser
return f
application = service.Application('finger', uid=1, gid=1)
f = FingerService('/etc/users')
serviceCollection = service.IServiceCollection(application)
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)
|