Initial import to Tizen
[profile/ivi/python-twisted.git] / doc / core / howto / tutorial / listings / finger / finger17.tac
1 # Read from file, announce on the web, irc, xml-rpc
2 from twisted.application import internet, service
3 from twisted.internet import protocol, reactor, defer
4 from twisted.words.protocols import irc
5 from twisted.protocols import basic
6 from twisted.web import resource, server, static, xmlrpc
7 import cgi
8
9 class FingerProtocol(basic.LineReceiver):
10     def lineReceived(self, user):
11         d = self.factory.getUser(user)
12
13         def onError(err):
14             return 'Internal error in server'
15         d.addErrback(onError)
16
17         def writeResponse(message):
18             self.transport.write(message + '\r\n')
19             self.transport.loseConnection()
20         d.addCallback(writeResponse)
21
22
23 class IRCReplyBot(irc.IRCClient):
24     def connectionMade(self):
25         self.nickname = self.factory.nickname
26         irc.IRCClient.connectionMade(self)
27
28     def privmsg(self, user, channel, msg):
29         user = user.split('!')[0]
30         if self.nickname.lower() == channel.lower():
31             d = self.factory.getUser(msg)
32
33             def onError(err):
34                 return 'Internal error in server'
35             d.addErrback(onError)
36
37             def writeResponse(message):
38                 irc.IRCClient.msg(self, user, msg+': '+message)
39             d.addCallback(writeResponse)
40
41
42 class FingerService(service.Service):
43     def __init__(self, filename):
44         self.filename = filename
45         self.users = {}
46
47     def _read(self):
48         self.users.clear()
49         for line in file(self.filename):
50             user, status = line.split(':', 1)
51             user = user.strip()
52             status = status.strip()
53             self.users[user] = status
54         self.call = reactor.callLater(30, self._read)
55
56     def getUser(self, user):
57         return defer.succeed(self.users.get(user, "No such user"))
58
59     def getFingerFactory(self):
60         f = protocol.ServerFactory()
61         f.protocol = FingerProtocol
62         f.getUser = self.getUser
63         return f
64
65     def getResource(self):
66         r = resource.Resource()
67         r.getChild = (lambda path, request:
68                       static.Data('<h1>%s</h1><p>%s</p>' %
69                       tuple(map(cgi.escape,
70                       [path,self.users.get(path, "No such user")])),
71                       'text/html'))
72         x = xmlrpc.XMLRPC()
73         x.xmlrpc_getUser = self.getUser
74         r.putChild('RPC2', x)
75         return r
76
77     def getIRCBot(self, nickname):
78         f = protocol.ReconnectingClientFactory()
79         f.protocol = IRCReplyBot
80         f.nickname = nickname
81         f.getUser = self.getUser
82         return f
83
84     def startService(self):
85         self._read()
86         service.Service.startService(self)
87
88     def stopService(self):
89         service.Service.stopService(self)
90         self.call.cancel()
91
92
93 application = service.Application('finger', uid=1, gid=1)
94 f = FingerService('/etc/users')
95 serviceCollection = service.IServiceCollection(application)
96 f.setServiceParent(serviceCollection)
97 internet.TCPServer(79, f.getFingerFactory()
98                    ).setServiceParent(serviceCollection)
99 internet.TCPServer(8000, server.Site(f.getResource())
100                    ).setServiceParent(serviceCollection)
101 internet.TCPClient('irc.freenode.org', 6667, f.getIRCBot('fingerbot')
102                    ).setServiceParent(serviceCollection)