~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/finger19c.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, utils
 
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
import pwd
 
11
import os
 
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
class IFingerSetterService(Interface):
 
27
 
 
28
    def setUser(user, status):
 
29
        """Set the user's status to something"""
 
30
 
 
31
def catchError(err):
 
32
    return "Internal error in server"
 
33
 
 
34
class FingerProtocol(basic.LineReceiver):
 
35
 
 
36
    def lineReceived(self, user):
 
37
        d = self.factory.getUser(user)
 
38
        d.addErrback(catchError)
 
39
        def writeValue(value):
 
40
            self.transport.write(value+'\r\n')
 
41
            self.transport.loseConnection()
 
42
        d.addCallback(writeValue)
 
43
 
 
44
 
 
45
class IFingerFactory(Interface):
 
46
 
 
47
    def getUser(user):
 
48
        """Return a deferred returning a string"""
 
49
 
 
50
    def buildProtocol(addr):
 
51
        """Return a protocol returning a string"""
 
52
 
 
53
 
 
54
class FingerFactoryFromService(protocol.ServerFactory):
 
55
 
 
56
    implements(IFingerFactory)
 
57
 
 
58
    protocol = FingerProtocol
 
59
 
 
60
    def __init__(self, service):
 
61
        self.service = service
 
62
 
 
63
    def getUser(self, user):
 
64
        return self.service.getUser(user)
 
65
 
 
66
components.registerAdapter(FingerFactoryFromService,
 
67
                           IFingerService,
 
68
                           IFingerFactory)
 
69
 
 
70
class FingerSetterProtocol(basic.LineReceiver):
 
71
 
 
72
    def connectionMade(self):
 
73
        self.lines = []
 
74
 
 
75
    def lineReceived(self, line):
 
76
        self.lines.append(line)
 
77
 
 
78
    def connectionLost(self, reason):
 
79
        if len(self.lines) == 2:
 
80
            self.factory.setUser(*self.lines)
 
81
 
 
82
 
 
83
class IFingerSetterFactory(Interface):
 
84
 
 
85
    def setUser(user, status):
 
86
        """Return a deferred returning a string"""
 
87
 
 
88
    def buildProtocol(addr):
 
89
        """Return a protocol returning a string"""
 
90
 
 
91
 
 
92
class FingerSetterFactoryFromService(protocol.ServerFactory):
 
93
 
 
94
    implements(IFingerSetterFactory)
 
95
 
 
96
    protocol = FingerSetterProtocol
 
97
 
 
98
    def __init__(self, service):
 
99
        self.service = service
 
100
 
 
101
    def setUser(self, user, status):
 
102
        self.service.setUser(user, status)
 
103
 
 
104
 
 
105
components.registerAdapter(FingerSetterFactoryFromService,
 
106
                           IFingerSetterService,
 
107
                           IFingerSetterFactory)
 
108
 
 
109
class IRCReplyBot(irc.IRCClient):
 
110
 
 
111
    def connectionMade():
 
112
        self.nickname = self.factory.nickname
 
113
        irc.IRCClient.connectionMade(self)
 
114
 
 
115
    def privmsg(self, user, channel, msg):
 
116
        user = user.split('!')[0]
 
117
        if self.nickname.lower() == channel.lower():
 
118
            d = self.factory.getUser(msg)
 
119
            d.addErrback(catchError)
 
120
            d.addCallback(lambda m: "Status of %s: %s" % (msg, m))
 
121
            d.addCallback(lambda m: self.msg(user, m))
 
122
 
 
123
 
 
124
class IIRCClientFactory(Interface):
 
125
 
 
126
    """
 
127
    @ivar nickname
 
128
    """
 
129
 
 
130
    def getUser(user):
 
131
        """Return a deferred returning a string"""
 
132
 
 
133
    def buildProtocol(addr):
 
134
        """Return a protocol"""
 
135
 
 
136
 
 
137
class IRCClientFactoryFromService(protocol.ClientFactory):
 
138
 
 
139
    implements(IIRCClientFactory)
 
140
 
 
141
    protocol = IRCReplyBot
 
142
    nickname = None
 
143
 
 
144
    def __init__(self, service):
 
145
        self.service = service
 
146
 
 
147
    def getUser(self, user):
 
148
        return self.service.getUser(user)
 
149
 
 
150
components.registerAdapter(IRCClientFactoryFromService,
 
151
                           IFingerService,
 
152
                           IIRCClientFactory)
 
153
 
 
154
class UserStatusTree(resource.Resource):
 
155
 
 
156
    implements(resource.IResource)
 
157
 
 
158
    def __init__(self, service):
 
159
        resource.Resource.__init__(self)
 
160
        self.service = service
 
161
        self.putChild('RPC2', UserStatusXR(self.service))
 
162
 
 
163
    def render_GET(self, request):
 
164
        d = self.service.getUsers()
 
165
        def formatUsers(users):
 
166
            l = ['<li><a href="%s">%s</a></li>' % (user, user)
 
167
                 for user in users]
 
168
            return '<ul>'+''.join(l)+'</ul>'
 
169
        d.addCallback(formatUsers)
 
170
        d.addCallback(request.write)
 
171
        d.addCallback(lambda _: request.finish())
 
172
        return server.NOT_DONE_YET
 
173
 
 
174
    def getChild(self, path, request):
 
175
        if path=="":
 
176
            return UserStatusTree(self.service)
 
177
        else:
 
178
            return UserStatus(path, self.service)
 
179
 
 
180
components.registerAdapter(UserStatusTree, IFingerService,
 
181
                           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 render_GET(self, request):
 
191
        d = self.service.getUser(self.user)
 
192
        d.addCallback(cgi.escape)
 
193
        d.addCallback(lambda m:
 
194
                      '<h1>%s</h1>'%self.user+'<p>%s</p>'%m)
 
195
        d.addCallback(request.write)
 
196
        d.addCallback(lambda _: request.finish())
 
197
        return server.NOT_DONE_YET
 
198
 
 
199
 
 
200
class UserStatusXR(xmlrpc.XMLRPC):
 
201
 
 
202
    def __init__(self, service):
 
203
        xmlrpc.XMLRPC.__init__(self)
 
204
        self.service = service
 
205
 
 
206
    def xmlrpc_getUser(self, user):
 
207
        return self.service.getUser(user)
 
208
 
 
209
 
 
210
class FingerService(service.Service):
 
211
 
 
212
    implements(IFingerService)
 
213
 
 
214
    def __init__(self, filename):
 
215
        self.filename = filename
 
216
        self.users = {}
 
217
        self._read()
 
218
 
 
219
    def _read(self):
 
220
        self.users.clear()
 
221
        for line in file(self.filename):
 
222
            user, status = line.split(':', 1)
 
223
            user = user.strip()
 
224
            status = status.strip()
 
225
            self.users[user] = status
 
226
        self.call = reactor.callLater(30, self._read)
 
227
 
 
228
    def getUser(self, user):
 
229
        return defer.succeed(self.users.get(user, "No such user"))
 
230
 
 
231
    def getUsers(self):
 
232
        return defer.succeed(self.users.keys())
 
233
 
 
234
# Yet another back-end
 
235
 
 
236
class LocalFingerService(service.Service):
 
237
 
 
238
    implements(IFingerService)
 
239
 
 
240
    def getUser(self, user):
 
241
        user = user.strip()
 
242
        try:
 
243
            entry = pwd.getpwnam(user)
 
244
        except KeyError:
 
245
            return defer.succeed("No such user")
 
246
        try:
 
247
            f = file(os.path.join(entry[5],'.plan'))
 
248
        except (IOError, OSError):
 
249
            return defer.succeed("No such user")
 
250
        data = f.read()
 
251
        data = data.strip()
 
252
        f.close()
 
253
        return defer.succeed(data)
 
254
    
 
255
    def getUsers(self):
 
256
        return defer.succeed([])
 
257
 
 
258
 
 
259
application = service.Application('finger', uid=1, gid=1)
 
260
f = LocalFingerService()
 
261
serviceCollection = service.IServiceCollection(application)
 
262
internet.TCPServer(79, IFingerFactory(f)
 
263
                   ).setServiceParent(serviceCollection)
 
264
internet.TCPServer(8000, server.Site(resource.IResource(f))
 
265
                   ).setServiceParent(serviceCollection)
 
266
i = IIRCClientFactory(f)
 
267
i.nickname = 'fingerbot'
 
268
internet.TCPClient('irc.freenode.org', 6667, i
 
269
                   ).setServiceParent(serviceCollection)