Initial import to Tizen
[profile/ivi/python-twisted.git] / doc / core / howto / tutorial / listings / finger / finger19a.tac
1 # Do everything properly, and componentize
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.python import components
7 from twisted.web import resource, server, static, xmlrpc
8 from zope.interface import Interface, implements
9 import cgi
10
11 class IFingerService(Interface):
12
13     def getUser(user):
14         """Return a deferred returning a string"""
15
16     def getUsers():
17         """Return a deferred returning a list of strings"""
18
19 class IFingerSetterService(Interface):
20
21     def setUser(user, status):
22         """Set the user's status to something"""
23
24 def catchError(err):
25     return "Internal error in server"
26
27 class FingerProtocol(basic.LineReceiver):
28
29     def lineReceived(self, user):
30         d = self.factory.getUser(user)
31         d.addErrback(catchError)
32         def writeValue(value):
33             self.transport.write(value+'\r\n')
34             self.transport.loseConnection()
35         d.addCallback(writeValue)
36
37
38 class IFingerFactory(Interface):
39
40     def getUser(user):
41         """Return a deferred returning a string"""
42
43     def buildProtocol(addr):
44         """Return a protocol returning a string"""
45
46
47 class FingerFactoryFromService(protocol.ServerFactory):
48
49     implements(IFingerFactory)
50
51     protocol = FingerProtocol
52
53     def __init__(self, service):
54         self.service = service
55
56     def getUser(self, user):
57         return self.service.getUser(user)
58
59 components.registerAdapter(FingerFactoryFromService,
60                            IFingerService,
61                            IFingerFactory)
62
63 class FingerSetterProtocol(basic.LineReceiver):
64
65     def connectionMade(self):
66         self.lines = []
67
68     def lineReceived(self, line):
69         self.lines.append(line)
70
71     def connectionLost(self, reason):
72         if len(self.lines) == 2:
73             self.factory.setUser(*self.lines)
74
75
76 class IFingerSetterFactory(Interface):
77
78     def setUser(user, status):
79         """Return a deferred returning a string"""
80
81     def buildProtocol(addr):
82         """Return a protocol returning a string"""
83
84
85 class FingerSetterFactoryFromService(protocol.ServerFactory):
86
87     implements(IFingerSetterFactory)
88
89     protocol = FingerSetterProtocol
90
91     def __init__(self, service):
92         self.service = service
93
94     def setUser(self, user, status):
95         self.service.setUser(user, status)
96
97
98 components.registerAdapter(FingerSetterFactoryFromService,
99                            IFingerSetterService,
100                            IFingerSetterFactory)
101
102 class IRCReplyBot(irc.IRCClient):
103
104     def connectionMade(self):
105         self.nickname = self.factory.nickname
106         irc.IRCClient.connectionMade(self)
107
108     def privmsg(self, user, channel, msg):
109         user = user.split('!')[0]
110         if self.nickname.lower() == channel.lower():
111             d = self.factory.getUser(msg)
112             d.addErrback(catchError)
113             d.addCallback(lambda m: "Status of %s: %s" % (msg, m))
114             d.addCallback(lambda m: self.msg(user, m))
115
116
117 class IIRCClientFactory(Interface):
118
119     """
120     @ivar nickname
121     """
122
123     def getUser(user):
124         """Return a deferred returning a string"""
125
126     def buildProtocol(addr):
127         """Return a protocol"""
128
129
130 class IRCClientFactoryFromService(protocol.ClientFactory):
131
132     implements(IIRCClientFactory)
133
134     protocol = IRCReplyBot
135     nickname = None
136
137     def __init__(self, service):
138         self.service = service
139
140     def getUser(self, user):
141         return self.service.getUser(user)
142
143 components.registerAdapter(IRCClientFactoryFromService,
144                            IFingerService,
145                            IIRCClientFactory)
146
147 class UserStatusTree(resource.Resource):
148
149     implements(resource.IResource)
150
151     def __init__(self, service):
152         resource.Resource.__init__(self)
153         self.service = service
154         self.putChild('RPC2', UserStatusXR(self.service))
155
156     def render_GET(self, request):
157         d = self.service.getUsers()
158         def formatUsers(users):
159             l = ['<li><a href="%s">%s</a></li>' % (user, user)
160                  for user in users]
161             return '<ul>'+''.join(l)+'</ul>'
162         d.addCallback(formatUsers)
163         d.addCallback(request.write)
164         d.addCallback(lambda _: request.finish())
165         return server.NOT_DONE_YET
166
167     def getChild(self, path, request):
168         if path=="":
169             return UserStatusTree(self.service)
170         else:
171             return UserStatus(path, self.service)
172
173 components.registerAdapter(UserStatusTree, IFingerService,
174                            resource.IResource)
175
176 class UserStatus(resource.Resource):
177
178     def __init__(self, user, service):
179         resource.Resource.__init__(self)
180         self.user = user
181         self.service = service
182
183     def render_GET(self, request):
184         d = self.service.getUser(self.user)
185         d.addCallback(cgi.escape)
186         d.addCallback(lambda m:
187                       '<h1>%s</h1>'%self.user+'<p>%s</p>'%m)
188         d.addCallback(request.write)
189         d.addCallback(lambda _: request.finish())
190         return server.NOT_DONE_YET
191
192
193 class UserStatusXR(xmlrpc.XMLRPC):
194
195     def __init__(self, service):
196         xmlrpc.XMLRPC.__init__(self)
197         self.service = service
198
199     def xmlrpc_getUser(self, user):
200         return self.service.getUser(user)
201
202 class MemoryFingerService(service.Service):
203
204     implements([IFingerService, IFingerSetterService])
205
206     def __init__(self, **kwargs):
207         self.users = kwargs
208
209     def getUser(self, user):
210         return defer.succeed(self.users.get(user, "No such user"))
211
212     def getUsers(self):
213         return defer.succeed(self.users.keys())
214
215     def setUser(self, user, status):
216         self.users[user] = status
217
218
219 application = service.Application('finger', uid=1, gid=1)
220 f = MemoryFingerService(moshez='Happy and well')
221 serviceCollection = service.IServiceCollection(application)
222 internet.TCPServer(79, IFingerFactory(f)
223                    ).setServiceParent(serviceCollection)
224 internet.TCPServer(8000, server.Site(resource.IResource(f))
225                    ).setServiceParent(serviceCollection)
226 i = IIRCClientFactory(f)
227 i.nickname = 'fingerbot'
228 internet.TCPClient('irc.freenode.org', 6667, i
229                    ).setServiceParent(serviceCollection)
230 internet.TCPServer(1079, IFingerSetterFactory(f), interface='127.0.0.1'
231                    ).setServiceParent(serviceCollection)