~justin-fathomdb/nova/justinsb-openstack-api-volumes

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/doc/core/howto/tutorial/listings/finger/finger22.py

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