~ntt-pf-lab/nova/monkey_patch_notification

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/doc/core/howto/tutorial/listings/finger/finger/finger.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
# finger.py module
 
2
 
 
3
from zope.interface import Interface, implements
 
4
 
 
5
from twisted.application import internet, service
 
6
from twisted.internet import protocol, reactor, defer
 
7
from twisted.words.protocols import irc
 
8
from twisted.protocols import basic
 
9
from twisted.python import components, log
 
10
from twisted.web import resource, server, xmlrpc
 
11
from twisted.spread import pb
 
12
 
 
13
from OpenSSL import SSL
 
14
 
 
15
class IFingerService(Interface):
 
16
 
 
17
    def getUser(user):
 
18
        """Return a deferred returning a string"""
 
19
 
 
20
    def getUsers():
 
21
        """Return a deferred returning a list of strings"""
 
22
 
 
23
class IFingerSetterService(Interface):
 
24
 
 
25
    def setUser(user, status):
 
26
        """Set the user's status to something"""
 
27
 
 
28
def catchError(err):
 
29
    return "Internal error in server"
 
30
 
 
31
class FingerProtocol(basic.LineReceiver):
 
32
 
 
33
    def lineReceived(self, user):
 
34
        d = self.factory.getUser(user)
 
35
        d.addErrback(catchError)
 
36
        def writeValue(value):
 
37
            self.transport.write(value+'\n')
 
38
            self.transport.loseConnection()
 
39
        d.addCallback(writeValue)
 
40
 
 
41
 
 
42
class IFingerFactory(Interface):
 
43
 
 
44
    def getUser(user):
 
45
        """Return a deferred returning a string"""
 
46
 
 
47
    def buildProtocol(addr):
 
48
        """Return a protocol returning a string"""
 
49
 
 
50
 
 
51
class FingerFactoryFromService(protocol.ServerFactory):
 
52
    implements(IFingerFactory)
 
53
 
 
54
    protocol = FingerProtocol
 
55
 
 
56
    def __init__(self, service):
 
57
        self.service = service
 
58
 
 
59
    def getUser(self, user):
 
60
        return self.service.getUser(user)
 
61
 
 
62
components.registerAdapter(FingerFactoryFromService,
 
63
                           IFingerService,
 
64
                           IFingerFactory)
 
65
 
 
66
class FingerSetterProtocol(basic.LineReceiver):
 
67
 
 
68
    def connectionMade(self):
 
69
        self.lines = []
 
70
 
 
71
    def lineReceived(self, line):
 
72
        self.lines.append(line)
 
73
 
 
74
    def connectionLost(self, reason):
 
75
        if len(self.lines) == 2:
 
76
            self.factory.setUser(*self.lines)
 
77
 
 
78
 
 
79
class IFingerSetterFactory(Interface):
 
80
 
 
81
    def setUser(user, status):
 
82
        """Return a deferred returning a string"""
 
83
 
 
84
    def buildProtocol(addr):
 
85
        """Return a protocol returning a string"""
 
86
 
 
87
 
 
88
class FingerSetterFactoryFromService(protocol.ServerFactory):
 
89
 
 
90
    implements(IFingerSetterFactory)
 
91
 
 
92
    protocol = FingerSetterProtocol
 
93
 
 
94
    def __init__(self, service):
 
95
        self.service = service
 
96
 
 
97
    def setUser(self, user, status):
 
98
        self.service.setUser(user, status)
 
99
 
 
100
 
 
101
components.registerAdapter(FingerSetterFactoryFromService,
 
102
                           IFingerSetterService,
 
103
                           IFingerSetterFactory)
 
104
 
 
105
class IRCReplyBot(irc.IRCClient):
 
106
 
 
107
    def connectionMade(self):
 
108
        self.nickname = self.factory.nickname
 
109
        irc.IRCClient.connectionMade(self)
 
110
 
 
111
    def privmsg(self, user, channel, msg):
 
112
        user = user.split('!')[0]
 
113
        if self.nickname.lower() == channel.lower():
 
114
            d = self.factory.getUser(msg)
 
115
            d.addErrback(catchError)
 
116
            d.addCallback(lambda m: "Status of %s: %s" % (msg, m))
 
117
            d.addCallback(lambda m: self.msg(user, m))
 
118
 
 
119
 
 
120
class IIRCClientFactory(Interface):
 
121
 
 
122
    """
 
123
    @ivar nickname
 
124
    """
 
125
 
 
126
    def getUser(user):
 
127
        """Return a deferred returning a string"""
 
128
 
 
129
    def buildProtocol(addr):
 
130
        """Return a protocol"""
 
131
 
 
132
 
 
133
class IRCClientFactoryFromService(protocol.ClientFactory):
 
134
 
 
135
    implements(IIRCClientFactory)
 
136
 
 
137
    protocol = IRCReplyBot
 
138
    nickname = None
 
139
 
 
140
    def __init__(self, service):
 
141
        self.service = service
 
142
 
 
143
    def getUser(self, user):
 
144
        return self.service.getUser(user)
 
145
 
 
146
components.registerAdapter(IRCClientFactoryFromService,
 
147
                           IFingerService,
 
148
                           IIRCClientFactory)
 
149
 
 
150
class UserStatusTree(resource.Resource):
 
151
 
 
152
    template = """<html><head><title>Users</title></head><body>
 
153
    <h1>Users</h1>
 
154
    <ul>
 
155
    %(users)s
 
156
    </ul>
 
157
    </body>
 
158
    </html>"""
 
159
 
 
160
    def __init__(self, service):
 
161
        resource.Resource.__init__(self)
 
162
        self.service = service
 
163
 
 
164
    def getChild(self, path, request):
 
165
        if path == '':
 
166
            return self
 
167
        elif path == 'RPC2':
 
168
            return UserStatusXR(self.service)
 
169
        else:
 
170
            return UserStatus(path, self.service)
 
171
 
 
172
    def render_GET(self, request):
 
173
        users = self.service.getUsers()
 
174
        def cbUsers(users):
 
175
            request.write(self.template % {'users': ''.join([
 
176
                    # Name should be quoted properly these uses.
 
177
                    '<li><a href="%s">%s</a></li>' % (name, name)
 
178
                    for name in users])})
 
179
            request.finish()
 
180
        users.addCallback(cbUsers)
 
181
        def ebUsers(err):
 
182
            log.err(err, "UserStatusTree failed")
 
183
            request.finish()
 
184
        users.addErrback(ebUsers)
 
185
        return server.NOT_DONE_YET
 
186
 
 
187
components.registerAdapter(UserStatusTree, IFingerService, resource.IResource)
 
188
 
 
189
 
 
190
class UserStatus(resource.Resource):
 
191
 
 
192
    template='''<html><head><title>%(title)s</title></head>
 
193
    <body><h1>%(name)s</h1><p>%(status)s</p></body></html>'''
 
194
 
 
195
    def __init__(self, user, service):
 
196
        resource.Resource.__init__(self)
 
197
        self.user = user
 
198
        self.service = service
 
199
 
 
200
    def render_GET(self, request):
 
201
        status = self.service.getUser(self.user)
 
202
        def cbStatus(status):
 
203
            request.write(self.template % {
 
204
                'title': self.user,
 
205
                'name': self.user,
 
206
                'status': status})
 
207
            request.finish()
 
208
        status.addCallback(cbStatus)
 
209
        def ebStatus(err):
 
210
            log.err(err, "UserStatus failed")
 
211
            request.finish()
 
212
        status.addErrback(ebStatus)
 
213
        return server.NOT_DONE_YET
 
214
 
 
215
 
 
216
class UserStatusXR(xmlrpc.XMLRPC):
 
217
 
 
218
    def __init__(self, service):
 
219
        xmlrpc.XMLRPC.__init__(self)
 
220
        self.service = service
 
221
 
 
222
    def xmlrpc_getUser(self, user):
 
223
        return self.service.getUser(user)
 
224
 
 
225
    def xmlrpc_getUsers(self):
 
226
        return self.service.getUsers()
 
227
 
 
228
 
 
229
class IPerspectiveFinger(Interface):
 
230
 
 
231
    def remote_getUser(username):
 
232
        """return a user's status"""
 
233
 
 
234
    def remote_getUsers():
 
235
        """return a user's status"""
 
236
 
 
237
class PerspectiveFingerFromService(pb.Root):
 
238
 
 
239
    implements(IPerspectiveFinger)
 
240
 
 
241
    def __init__(self, service):
 
242
        self.service = service
 
243
 
 
244
    def remote_getUser(self, username):
 
245
        return self.service.getUser(username)
 
246
 
 
247
    def remote_getUsers(self):
 
248
        return self.service.getUsers()
 
249
 
 
250
components.registerAdapter(PerspectiveFingerFromService,
 
251
                           IFingerService,
 
252
                           IPerspectiveFinger)
 
253
 
 
254
 
 
255
class FingerService(service.Service):
 
256
 
 
257
    implements(IFingerService)
 
258
 
 
259
    def __init__(self, filename):
 
260
        self.filename = filename
 
261
        self._read()
 
262
 
 
263
    def _read(self):
 
264
        self.users = {}
 
265
        for line in file(self.filename):
 
266
            user, status = line.split(':', 1)
 
267
            user = user.strip()
 
268
            status = status.strip()
 
269
            self.users[user] = status
 
270
        self.call = reactor.callLater(30, self._read)
 
271
 
 
272
    def getUser(self, user):
 
273
        return defer.succeed(self.users.get(user, "No such user"))
 
274
 
 
275
    def getUsers(self):
 
276
        return defer.succeed(self.users.keys())
 
277
 
 
278
 
 
279
class ServerContextFactory:
 
280
 
 
281
    def getContext(self):
 
282
        """Create an SSL context.
 
283
 
 
284
        This is a sample implementation that loads a certificate from a file
 
285
        called 'server.pem'."""
 
286
        ctx = SSL.Context(SSL.SSLv23_METHOD)
 
287
        ctx.use_certificate_file('server.pem')
 
288
        ctx.use_privatekey_file('server.pem')
 
289
        return ctx
 
290
 
 
291
 
 
292
 
 
293
 
 
294
# Easy configuration
 
295
 
 
296
def makeService(config):
 
297
    # finger on port 79
 
298
    s = service.MultiService()
 
299
    f = FingerService(config['file'])
 
300
    h = internet.TCPServer(1079, IFingerFactory(f))
 
301
    h.setServiceParent(s)
 
302
 
 
303
 
 
304
    # website on port 8000
 
305
    r = resource.IResource(f)
 
306
    r.templateDirectory = config['templates']
 
307
    site = server.Site(r)
 
308
    j = internet.TCPServer(8000, site)
 
309
    j.setServiceParent(s)
 
310
 
 
311
    # ssl on port 443
 
312
#    if config.get('ssl'):
 
313
#        k = internet.SSLServer(443, site, ServerContextFactory())
 
314
#        k.setServiceParent(s)
 
315
 
 
316
    # irc fingerbot
 
317
    if config.has_key('ircnick'):
 
318
        i = IIRCClientFactory(f)
 
319
        i.nickname = config['ircnick']
 
320
        ircserver = config['ircserver']
 
321
        b = internet.TCPClient(ircserver, 6667, i)
 
322
        b.setServiceParent(s)
 
323
 
 
324
    # Pespective Broker on port 8889
 
325
    if config.has_key('pbport'):
 
326
        m = internet.TCPServer(
 
327
            int(config['pbport']),
 
328
            pb.PBServerFactory(IPerspectiveFinger(f)))
 
329
        m.setServiceParent(s)
 
330
 
 
331
    return s