~vishvananda/nova/network-refactor

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/doc/core/howto/tutorial/listings/finger/finger21.tac

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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, microdom
 
8
from twisted.spread import pb
 
9
from zope.interface import Interface, implements
 
10
import cgi
 
11
 
 
12
class IFingerService(Interface):
 
13
 
 
14
    def getUser(user):
 
15
        """Return a deferred returning a string"""
 
16
 
 
17
    def getUsers():
 
18
        """Return a deferred returning a list of strings"""
 
19
 
 
20
class IFingerSetterService(Interface):
 
21
 
 
22
    def setUser(user, status):
 
23
        """Set the user's status to something"""
 
24
 
 
25
def catchError(err):
 
26
    return "Internal error in server"
 
27
 
 
28
class FingerProtocol(basic.LineReceiver):
 
29
 
 
30
    def lineReceived(self, user):
 
31
        d = self.factory.getUser(user)
 
32
        d.addErrback(catchError)
 
33
        def writeValue(value):
 
34
            self.transport.write(value+'\r\n')
 
35
            self.transport.loseConnection()
 
36
        d.addCallback(writeValue)
 
37
 
 
38
 
 
39
class IFingerFactory(Interface):
 
40
 
 
41
    def getUser(user):
 
42
        """Return a deferred returning a string"""
 
43
 
 
44
    def buildProtocol(addr):
 
45
        """Return a protocol returning a string"""
 
46
 
 
47
 
 
48
class FingerFactoryFromService(protocol.ServerFactory):
 
49
 
 
50
    implements(IFingerFactory)
 
51
 
 
52
    protocol = FingerProtocol
 
53
 
 
54
    def __init__(self, service):
 
55
        self.service = service
 
56
 
 
57
    def getUser(self, user):
 
58
        return self.service.getUser(user)
 
59
 
 
60
components.registerAdapter(FingerFactoryFromService,
 
61
                           IFingerService,
 
62
                           IFingerFactory)
 
63
 
 
64
class FingerSetterProtocol(basic.LineReceiver):
 
65
 
 
66
    def connectionMade(self):
 
67
        self.lines = []
 
68
 
 
69
    def lineReceived(self, line):
 
70
        self.lines.append(line)
 
71
 
 
72
    def connectionLost(self, reason):
 
73
        if len(self.lines) == 2:
 
74
            self.factory.setUser(*self.lines)
 
75
 
 
76
 
 
77
class IFingerSetterFactory(Interface):
 
78
 
 
79
    def setUser(user, status):
 
80
        """Return a deferred returning a string"""
 
81
 
 
82
    def buildProtocol(addr):
 
83
        """Return a protocol returning a string"""
 
84
 
 
85
 
 
86
class FingerSetterFactoryFromService(protocol.ServerFactory):
 
87
 
 
88
    implements(IFingerSetterFactory)
 
89
 
 
90
    protocol = FingerSetterProtocol
 
91
 
 
92
    def __init__(self, service):
 
93
        self.service = service
 
94
 
 
95
    def setUser(self, user, status):
 
96
        self.service.setUser(user, status)
 
97
 
 
98
 
 
99
components.registerAdapter(FingerSetterFactoryFromService,
 
100
                           IFingerSetterService,
 
101
                           IFingerSetterFactory)
 
102
 
 
103
class IRCReplyBot(irc.IRCClient):
 
104
 
 
105
    def connectionMade(self):
 
106
        self.nickname = self.factory.nickname
 
107
        irc.IRCClient.connectionMade(self)
 
108
 
 
109
    def privmsg(self, user, channel, msg):
 
110
        user = user.split('!')[0]
 
111
        if self.nickname.lower() == channel.lower():
 
112
            d = self.factory.getUser(msg)
 
113
            d.addErrback(catchError)
 
114
            d.addCallback(lambda m: "Status of %s: %s" % (msg, m))
 
115
            d.addCallback(lambda m: self.msg(user, m))
 
116
 
 
117
 
 
118
class IIRCClientFactory(Interface):
 
119
 
 
120
    """
 
121
    @ivar nickname
 
122
    """
 
123
 
 
124
    def getUser(user):
 
125
        """Return a deferred returning a string"""
 
126
 
 
127
    def buildProtocol(addr):
 
128
        """Return a protocol"""
 
129
 
 
130
 
 
131
class IRCClientFactoryFromService(protocol.ClientFactory):
 
132
 
 
133
    implements(IIRCClientFactory)
 
134
 
 
135
    protocol = IRCReplyBot
 
136
    nickname = None
 
137
 
 
138
    def __init__(self, service):
 
139
        self.service = service
 
140
 
 
141
    def getUser(self, user):
 
142
        return self.service.getUser(user)
 
143
 
 
144
components.registerAdapter(IRCClientFactoryFromService,
 
145
                           IFingerService,
 
146
                           IIRCClientFactory)
 
147
 
 
148
class UserStatusTree(resource.Resource):
 
149
 
 
150
    def __init__(self, service):
 
151
        resource.Resource.__init__(self)
 
152
        self.service=service
 
153
 
 
154
        # add a specific child for the path "RPC2"
 
155
        self.putChild("RPC2", UserStatusXR(self.service))
 
156
 
 
157
        # need to do this for resources at the root of the site
 
158
        self.putChild("", self)
 
159
 
 
160
    def _cb_render_GET(self, users, request):
 
161
        userOutput = ''.join(["<li><a href=\"%s\">%s</a></li>" % (user, user)
 
162
                for user in users])
 
163
        request.write("""
 
164
            <html><head><title>Users</title></head><body>
 
165
            <h1>Users</h1>
 
166
            <ul>
 
167
            %s
 
168
            </ul></body></html>""" % userOutput)
 
169
        request.finish()
 
170
        
 
171
    def render_GET(self, request):
 
172
        d = self.service.getUsers()
 
173
        d.addCallback(self._cb_render_GET, request)
 
174
 
 
175
        # signal that the rendering is not complete
 
176
        return server.NOT_DONE_YET
 
177
 
 
178
    def getChild(self, path, request):
 
179
        return UserStatus(user=path, service=self.service)
 
180
 
 
181
components.registerAdapter(UserStatusTree, IFingerService, resource.IResource)
 
182
 
 
183
class UserStatus(resource.Resource):
 
184
 
 
185
    def __init__(self, user, service):
 
186
        resource.Resource.__init__(self)
 
187
        self.user = user
 
188
        self.service = service
 
189
 
 
190
    def _cb_render_GET(self, status, request):
 
191
        request.write("""<html><head><title>%s</title></head>
 
192
        <body><h1>%s</h1>
 
193
        <p>%s</p>
 
194
        </body></html>""" % (self.user, self.user, status))
 
195
        request.finish()
 
196
    
 
197
    def render_GET(self, request):
 
198
        d = self.service.getUser(self.user)
 
199
        d.addCallback(self._cb_render_GET, request)
 
200
 
 
201
        # signal that the rendering is not complete
 
202
        return server.NOT_DONE_YET
 
203
 
 
204
class UserStatusXR(xmlrpc.XMLRPC):
 
205
 
 
206
    def __init__(self, service):
 
207
        xmlrpc.XMLRPC.__init__(self)
 
208
        self.service = service
 
209
 
 
210
    def xmlrpc_getUser(self, user):
 
211
        return self.service.getUser(user)
 
212
 
 
213
    def xmlrpc_getUsers(self):
 
214
        return self.service.getUsers()
 
215
 
 
216
 
 
217
class IPerspectiveFinger(Interface):
 
218
 
 
219
    def remote_getUser(username):
 
220
        """return a user's status"""
 
221
 
 
222
    def remote_getUsers():
 
223
        """return a user's status"""
 
224
 
 
225
class PerspectiveFingerFromService(pb.Root):
 
226
 
 
227
    implements(IPerspectiveFinger)
 
228
 
 
229
    def __init__(self, service):
 
230
        self.service = service
 
231
 
 
232
    def remote_getUser(self, username):
 
233
        return self.service.getUser(username)
 
234
 
 
235
    def remote_getUsers(self):
 
236
        return self.service.getUsers()
 
237
 
 
238
components.registerAdapter(PerspectiveFingerFromService,
 
239
                           IFingerService,
 
240
                           IPerspectiveFinger)
 
241
 
 
242
 
 
243
class FingerService(service.Service):
 
244
 
 
245
    implements(IFingerService)
 
246
 
 
247
    def __init__(self, filename):
 
248
        self.filename = filename
 
249
        self.users = {}
 
250
        self._read()
 
251
 
 
252
    def _read(self):
 
253
        self.users.clear()
 
254
        for line in file(self.filename):
 
255
            user, status = line.split(':', 1)
 
256
            user = user.strip()
 
257
            status = status.strip()
 
258
            self.users[user] = status
 
259
        self.call = reactor.callLater(30, self._read)
 
260
 
 
261
    def getUser(self, user):
 
262
        return defer.succeed(self.users.get(user, "No such user"))
 
263
 
 
264
    def getUsers(self):
 
265
        return defer.succeed(self.users.keys())
 
266
 
 
267
 
 
268
application = service.Application('finger', uid=1, gid=1)
 
269
f = FingerService('/etc/users')
 
270
serviceCollection = service.IServiceCollection(application)
 
271
internet.TCPServer(79, IFingerFactory(f)
 
272
                   ).setServiceParent(serviceCollection)
 
273
internet.TCPServer(8000, server.Site(resource.IResource(f))
 
274
                   ).setServiceParent(serviceCollection)
 
275
i = IIRCClientFactory(f)
 
276
i.nickname = 'fingerbot'
 
277
internet.TCPClient('irc.freenode.org', 6667, i
 
278
                   ).setServiceParent(serviceCollection)
 
279
internet.TCPServer(8889, pb.PBServerFactory(IPerspectiveFinger(f))
 
280
                   ).setServiceParent(serviceCollection)