~certify-web-dev/twisted/certify-trunk

« back to all changes in this revision

Viewing changes to doc/howto/tutorial/listings/finger/finger/finger.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2006-01-16 19:56:10 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20060116195610-ykmxbia4mnnod9o2
Tags: 2.1.0-0ubuntu2
debian/copyright: Include copyright for python 2.3; some 2.3 files
are included in the upstream tarball, but not in the binary packages.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# finger.py module
 
2
 
 
3
from twisted.application import internet, service, strports
 
4
from twisted.internet import protocol, reactor, defer
 
5
from twisted.protocols import basic, irc
 
6
from twisted.python import components
 
7
from twisted.web import resource, server, static, xmlrpc, microdom
 
8
from twisted.web.woven import page, model, interfaces
 
9
from twisted.spread import pb
 
10
from OpenSSL import SSL
 
11
import cgi
 
12
 
 
13
class IFingerService(components.Interface):
 
14
 
 
15
    def getUser(self, user):
 
16
        """Return a deferred returning a string"""
 
17
 
 
18
    def getUsers(self):
 
19
        """Return a deferred returning a list of strings"""
 
20
 
 
21
class IFingerSetterService(components.Interface):
 
22
 
 
23
    def setUser(self, 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+'\n')
 
36
            self.transport.loseConnection()
 
37
        d.addCallback(writeValue)
 
38
 
 
39
 
 
40
class IFingerFactory(components.Interface):
 
41
 
 
42
    def getUser(self, user):
 
43
        """Return a deferred returning a string"""
 
44
 
 
45
    def buildProtocol(self, addr):
 
46
        """Return a protocol returning a string"""
 
47
 
 
48
 
 
49
class FingerFactoryFromService(protocol.ServerFactory):
 
50
    __implements__ = protocol.ServerFactory.__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(components.Interface):
 
78
 
 
79
    def setUser(self, user, status):
 
80
        """Return a deferred returning a string"""
 
81
 
 
82
    def buildProtocol(self, addr):
 
83
        """Return a protocol returning a string"""
 
84
 
 
85
 
 
86
class FingerSetterFactoryFromService(protocol.ServerFactory):
 
87
 
 
88
    __implements__ = protocol.ServerFactory.__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(components.Interface):
 
119
 
 
120
    """
 
121
    @ivar nickname
 
122
    """
 
123
 
 
124
    def getUser(self, user):
 
125
        """Return a deferred returning a string"""
 
126
 
 
127
    def buildProtocol(self, addr):
 
128
        """Return a protocol"""
 
129
 
 
130
 
 
131
class IRCClientFactoryFromService(protocol.ClientFactory):
 
132
 
 
133
    __implements__ = protocol.ClientFactory.__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 UsersModel(model.MethodModel):
 
149
 
 
150
    def initialize(self, *args, **kwargs):
 
151
        self.service=args[0]
 
152
 
 
153
    def wmfactory_users(self, request):
 
154
        return self.service.getUsers()
 
155
 
 
156
components.registerAdapter(UsersModel, IFingerService, interfaces.IModel)
 
157
 
 
158
class UserStatusTree(page.Page):
 
159
 
 
160
    template = """<html><head><title>Users</title></head><body>
 
161
    <h1>Users</h1>
 
162
    <ul model="users" view="List">
 
163
    <li pattern="listItem"><a view="Anchor" /></li>
 
164
    </ul></body></html>"""
 
165
 
 
166
    def initialize(self, *args, **kwargs):
 
167
        self.service=args[0]
 
168
 
 
169
    def getDynamicChild(self, path, request):
 
170
        return UserStatus(user=path, service=self.service)
 
171
 
 
172
    def wchild_RPC2 (self, request):
 
173
        return UserStatusXR(self.service)
 
174
 
 
175
components.registerAdapter(UserStatusTree, IFingerService, resource.IResource)
 
176
 
 
177
 
 
178
class UserStatus(page.Page):
 
179
 
 
180
    template='''<html><head><title view="Text" model="user"/></head>
 
181
    <body><h1 view="Text" model="user"/>
 
182
    <p model="status" view="Text" />
 
183
    </body></html>'''
 
184
 
 
185
    def initialize(self, **kwargs):
 
186
        self.user = kwargs['user']
 
187
        self.service = kwargs['service']
 
188
 
 
189
    def wmfactory_user(self, request):
 
190
        return self.user
 
191
 
 
192
    def wmfactory_status(self, request):
 
193
        return self.service.getUser(self.user)
 
194
 
 
195
 
 
196
class UserStatusXR(xmlrpc.XMLRPC):
 
197
 
 
198
    def __init__(self, service):
 
199
        xmlrpc.XMLRPC.__init__(self)
 
200
        self.service = service
 
201
 
 
202
    def xmlrpc_getUser(self, user):
 
203
        return self.service.getUser(user)
 
204
 
 
205
    def xmlrpc_getUsers(self):
 
206
        return self.service.getUsers()
 
207
 
 
208
 
 
209
class IPerspectiveFinger(components.Interface):
 
210
 
 
211
    def remote_getUser(self, username):
 
212
        """return a user's status"""
 
213
 
 
214
    def remote_getUsers(self):
 
215
        """return a user's status"""
 
216
 
 
217
class PerspectiveFingerFromService(pb.Root):
 
218
 
 
219
    __implements__ = pb.Root.__implements__, IPerspectiveFinger
 
220
 
 
221
    def __init__(self, service):
 
222
        self.service = service
 
223
 
 
224
    def remote_getUser(self, username):
 
225
        return self.service.getUser(username)
 
226
 
 
227
    def remote_getUsers(self):
 
228
        return self.service.getUsers()
 
229
 
 
230
components.registerAdapter(PerspectiveFingerFromService,
 
231
                           IFingerService,
 
232
                           IPerspectiveFinger)
 
233
 
 
234
 
 
235
class FingerService(service.Service):
 
236
 
 
237
    __implements__ = service.Service.__implements__, IFingerService
 
238
 
 
239
    def __init__(self, filename):
 
240
        self.filename = filename
 
241
        self._read()
 
242
 
 
243
    def _read(self):
 
244
        self.users = {}
 
245
        for line in file(self.filename):
 
246
            user, status = line.split(':', 1)
 
247
            user = user.strip()
 
248
            status = status.strip()
 
249
            self.users[user] = status
 
250
        self.call = reactor.callLater(30, self._read)
 
251
 
 
252
    def getUser(self, user):
 
253
        return defer.succeed(self.users.get(user, "No such user"))
 
254
 
 
255
    def getUsers(self):
 
256
        return defer.succeed(self.users.keys())
 
257
 
 
258
 
 
259
class ServerContextFactory:
 
260
 
 
261
    def getContext(self):
 
262
        """Create an SSL context.
 
263
 
 
264
        This is a sample implementation that loads a certificate from a file
 
265
        called 'server.pem'."""
 
266
        ctx = SSL.Context(SSL.SSLv23_METHOD)
 
267
        ctx.use_certificate_file('server.pem')
 
268
        ctx.use_privatekey_file('server.pem')
 
269
        return ctx
 
270
 
 
271
 
 
272
 
 
273
 
 
274
# Easy configuration
 
275
 
 
276
def makeService(config):
 
277
    # finger on port 79
 
278
    s = service.MultiService()
 
279
    f = FingerService(config['file'])
 
280
    h = internet.TCPServer(79, IFingerFactory(f))
 
281
    h.setServiceParent(s)
 
282
 
 
283
 
 
284
    # website on port 8000
 
285
    r = resource.IResource(f)
 
286
    r.templateDirectory = config['templates']
 
287
    site = server.Site(r)
 
288
    j = internet.TCPServer(8000, site)
 
289
    j.setServiceParent(s)
 
290
 
 
291
    # ssl on port 443
 
292
#    if config.get('ssl'):
 
293
#        k = internet.SSLServer(443, site, ServerContextFactory())
 
294
#        k.setServiceParent(s)
 
295
 
 
296
    # irc fingerbot
 
297
    if config.has_key('ircnick'):
 
298
        i = IIRCClientFactory(f)
 
299
        i.nickname = config['ircnick']
 
300
        ircserver = config['ircserver']
 
301
        b = internet.TCPClient(ircserver, 6667, i)
 
302
        b.setServiceParent(s)
 
303
 
 
304
    # Pespective Broker on port 8889
 
305
    if config.has_key('pbport'):
 
306
        m = internet.TCPServer(
 
307
            int(config['pbport']),
 
308
            pb.PBServerFactory(IPerspectiveFinger(f)))
 
309
        m.setServiceParent(s)
 
310
 
 
311
    return s