~cbehrens/nova/lp844160-build-works-with-zones

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/doc/core/howto/tutorial/web.html

  • 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
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html  PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN'  'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
 
2
  <head>
 
3
<title>Twisted Documentation: The Evolution of Finger: a web frontend</title>
 
4
<link href="../stylesheet.css" rel="stylesheet" type="text/css"/>
 
5
  </head>
 
6
 
 
7
  <body bgcolor="white">
 
8
    <h1 class="title">The Evolution of Finger: a web frontend</h1>
 
9
    <div class="toc"><ol><li><a href="#auto0">Introduction</a></li></ol></div>
 
10
    <div class="content">
 
11
 
 
12
<span/>
 
13
 
 
14
<h2>Introduction<a name="auto0"/></h2>
 
15
 
 
16
<p> This is the sixth part of the Twisted tutorial <a href="index.html" shape="rect">Twisted from Scratch, or The Evolution of Finger</a>.</p>
 
17
 
 
18
<p>In this part, we demonstrate adding a web frontend using simple <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.web.resource.Resource.html" title="twisted.web.resource.Resource">twisted.web.resource.Resource</a></code> objects: <code class="python">UserStatusTree</code>, which will produce a listing of all
 
19
users at the base URL (<code>/</code>) of our site; <code class="python">UserStatus</code>, which gives the status of each user at the
 
20
locaton <code>/username</code>; and <code class="python">UserStatusXR</code>,
 
21
which exposes an XMLRPC interface to <code class="python">getUser</code> and
 
22
<code class="python">getUsers</code> functions at the URL <code>/RPC2</code>.</p>
 
23
 
 
24
<p>In this example we construct HTML segments manually. If the web interface
 
25
was less trivial, we would want to use more sophisticated web templating and
 
26
design our system so that HTML rendering and logic were clearly separated.</p>
 
27
 
 
28
<div class="py-listing"><pre><p class="py-linenumber">  1
 
29
  2
 
30
  3
 
31
  4
 
32
  5
 
33
  6
 
34
  7
 
35
  8
 
36
  9
 
37
 10
 
38
 11
 
39
 12
 
40
 13
 
41
 14
 
42
 15
 
43
 16
 
44
 17
 
45
 18
 
46
 19
 
47
 20
 
48
 21
 
49
 22
 
50
 23
 
51
 24
 
52
 25
 
53
 26
 
54
 27
 
55
 28
 
56
 29
 
57
 30
 
58
 31
 
59
 32
 
60
 33
 
61
 34
 
62
 35
 
63
 36
 
64
 37
 
65
 38
 
66
 39
 
67
 40
 
68
 41
 
69
 42
 
70
 43
 
71
 44
 
72
 45
 
73
 46
 
74
 47
 
75
 48
 
76
 49
 
77
 50
 
78
 51
 
79
 52
 
80
 53
 
81
 54
 
82
 55
 
83
 56
 
84
 57
 
85
 58
 
86
 59
 
87
 60
 
88
 61
 
89
 62
 
90
 63
 
91
 64
 
92
 65
 
93
 66
 
94
 67
 
95
 68
 
96
 69
 
97
 70
 
98
 71
 
99
 72
 
100
 73
 
101
 74
 
102
 75
 
103
 76
 
104
 77
 
105
 78
 
106
 79
 
107
 80
 
108
 81
 
109
 82
 
110
 83
 
111
 84
 
112
 85
 
113
 86
 
114
 87
 
115
 88
 
116
 89
 
117
 90
 
118
 91
 
119
 92
 
120
 93
 
121
 94
 
122
 95
 
123
 96
 
124
 97
 
125
 98
 
126
 99
 
127
100
 
128
101
 
129
102
 
130
103
 
131
104
 
132
105
 
133
106
 
134
107
 
135
108
 
136
109
 
137
110
 
138
111
 
139
112
 
140
113
 
141
114
 
142
115
 
143
116
 
144
117
 
145
118
 
146
119
 
147
120
 
148
121
 
149
122
 
150
123
 
151
124
 
152
125
 
153
126
 
154
127
 
155
128
 
156
129
 
157
130
 
158
131
 
159
132
 
160
133
 
161
134
 
162
135
 
163
136
 
164
137
 
165
138
 
166
139
 
167
140
 
168
141
 
169
142
 
170
143
 
171
144
 
172
145
 
173
146
 
174
147
 
175
148
 
176
149
 
177
150
 
178
151
 
179
152
 
180
153
 
181
154
 
182
155
 
183
156
 
184
157
 
185
158
 
186
159
 
187
160
 
188
161
 
189
162
 
190
163
 
191
164
 
192
165
 
193
166
 
194
167
 
195
168
 
196
169
 
197
170
 
198
171
 
199
172
 
200
173
 
201
174
 
202
175
 
203
176
 
204
177
 
205
178
 
206
179
 
207
180
 
208
181
 
209
182
 
210
183
 
211
184
 
212
185
 
213
186
 
214
187
 
215
188
 
216
189
 
217
190
 
218
191
 
219
192
 
220
193
 
221
194
 
222
195
 
223
196
 
224
197
 
225
198
 
226
199
 
227
200
 
228
201
 
229
202
 
230
203
 
231
204
 
232
205
 
233
206
 
234
207
 
235
208
 
236
209
 
237
210
 
238
211
 
239
212
 
240
213
 
241
214
 
242
215
 
243
216
 
244
217
 
245
218
 
246
219
 
247
220
 
248
221
 
249
222
 
250
223
 
251
224
 
252
225
 
253
226
 
254
227
 
255
228
 
256
229
 
257
230
 
258
231
 
259
232
 
260
233
 
261
234
 
262
235
 
263
236
 
264
237
 
265
238
 
266
239
 
267
240
 
268
241
 
269
242
 
270
243
 
271
244
 
272
245
 
273
246
 
274
247
 
275
248
 
276
249
 
277
250
 
278
251
 
279
</p><span class="py-src-comment"># Do everything properly, and componentize</span>
 
280
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">application</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">internet</span>, <span class="py-src-variable">service</span>
 
281
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">protocol</span>, <span class="py-src-variable">reactor</span>, <span class="py-src-variable">defer</span>
 
282
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">words</span>.<span class="py-src-variable">protocols</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">irc</span>
 
283
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">protocols</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">basic</span>
 
284
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">python</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">components</span>
 
285
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">resource</span>, <span class="py-src-variable">server</span>, <span class="py-src-variable">static</span>, <span class="py-src-variable">xmlrpc</span>, <span class="py-src-variable">microdom</span>
 
286
<span class="py-src-keyword">from</span> <span class="py-src-variable">zope</span>.<span class="py-src-variable">interface</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Interface</span>, <span class="py-src-variable">implements</span>
 
287
<span class="py-src-keyword">import</span> <span class="py-src-variable">cgi</span>
 
288
 
 
289
<span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerService</span>(<span class="py-src-parameter">Interface</span>):
 
290
 
 
291
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUser</span>(<span class="py-src-parameter">user</span>):
 
292
        <span class="py-src-string">&quot;&quot;&quot;Return a deferred returning a string&quot;&quot;&quot;</span>
 
293
 
 
294
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUsers</span>():
 
295
        <span class="py-src-string">&quot;&quot;&quot;Return a deferred returning a list of strings&quot;&quot;&quot;</span>
 
296
 
 
297
<span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerSetterService</span>(<span class="py-src-parameter">Interface</span>):
 
298
 
 
299
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">setUser</span>(<span class="py-src-parameter">user</span>, <span class="py-src-parameter">status</span>):
 
300
        <span class="py-src-string">&quot;&quot;&quot;Set the user's status to something&quot;&quot;&quot;</span>
 
301
 
 
302
<span class="py-src-keyword">def</span> <span class="py-src-identifier">catchError</span>(<span class="py-src-parameter">err</span>):
 
303
    <span class="py-src-keyword">return</span> <span class="py-src-string">&quot;Internal error in server&quot;</span>
 
304
 
 
305
<span class="py-src-keyword">class</span> <span class="py-src-identifier">FingerProtocol</span>(<span class="py-src-parameter">basic</span>.<span class="py-src-parameter">LineReceiver</span>):
 
306
 
 
307
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">lineReceived</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">user</span>):
 
308
        <span class="py-src-variable">d</span> = <span class="py-src-variable">self</span>.<span class="py-src-variable">factory</span>.<span class="py-src-variable">getUser</span>(<span class="py-src-variable">user</span>)
 
309
        <span class="py-src-variable">d</span>.<span class="py-src-variable">addErrback</span>(<span class="py-src-variable">catchError</span>)
 
310
        <span class="py-src-keyword">def</span> <span class="py-src-identifier">writeValue</span>(<span class="py-src-parameter">value</span>):
 
311
            <span class="py-src-variable">self</span>.<span class="py-src-variable">transport</span>.<span class="py-src-variable">write</span>(<span class="py-src-variable">value</span>+<span class="py-src-string">'\r\n'</span>)
 
312
            <span class="py-src-variable">self</span>.<span class="py-src-variable">transport</span>.<span class="py-src-variable">loseConnection</span>()
 
313
        <span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">writeValue</span>)
 
314
 
 
315
 
 
316
<span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerFactory</span>(<span class="py-src-parameter">Interface</span>):
 
317
 
 
318
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUser</span>(<span class="py-src-parameter">user</span>):
 
319
        <span class="py-src-string">&quot;&quot;&quot;Return a deferred returning a string&quot;&quot;&quot;</span>
 
320
 
 
321
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">buildProtocol</span>(<span class="py-src-parameter">addr</span>):
 
322
        <span class="py-src-string">&quot;&quot;&quot;Return a protocol returning a string&quot;&quot;&quot;</span>
 
323
 
 
324
 
 
325
<span class="py-src-keyword">class</span> <span class="py-src-identifier">FingerFactoryFromService</span>(<span class="py-src-parameter">protocol</span>.<span class="py-src-parameter">ServerFactory</span>):
 
326
 
 
327
    <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerFactory</span>)
 
328
 
 
329
    <span class="py-src-variable">protocol</span> = <span class="py-src-variable">FingerProtocol</span>
 
330
 
 
331
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">__init__</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">service</span>):
 
332
        <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>
 
333
 
 
334
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUser</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">user</span>):
 
335
        <span class="py-src-keyword">return</span> <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span>.<span class="py-src-variable">getUser</span>(<span class="py-src-variable">user</span>)
 
336
 
 
337
<span class="py-src-variable">components</span>.<span class="py-src-variable">registerAdapter</span>(<span class="py-src-variable">FingerFactoryFromService</span>,
 
338
                           <span class="py-src-variable">IFingerService</span>,
 
339
                           <span class="py-src-variable">IFingerFactory</span>)
 
340
 
 
341
<span class="py-src-keyword">class</span> <span class="py-src-identifier">FingerSetterProtocol</span>(<span class="py-src-parameter">basic</span>.<span class="py-src-parameter">LineReceiver</span>):
 
342
 
 
343
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">connectionMade</span>(<span class="py-src-parameter">self</span>):
 
344
        <span class="py-src-variable">self</span>.<span class="py-src-variable">lines</span> = []
 
345
 
 
346
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">lineReceived</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">line</span>):
 
347
        <span class="py-src-variable">self</span>.<span class="py-src-variable">lines</span>.<span class="py-src-variable">append</span>(<span class="py-src-variable">line</span>)
 
348
 
 
349
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">connectionLost</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">reason</span>):
 
350
        <span class="py-src-keyword">if</span> <span class="py-src-variable">len</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">lines</span>) == <span class="py-src-number">2</span>:
 
351
            <span class="py-src-variable">self</span>.<span class="py-src-variable">factory</span>.<span class="py-src-variable">setUser</span>(*<span class="py-src-variable">self</span>.<span class="py-src-variable">lines</span>)
 
352
 
 
353
 
 
354
<span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerSetterFactory</span>(<span class="py-src-parameter">Interface</span>):
 
355
 
 
356
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">setUser</span>(<span class="py-src-parameter">user</span>, <span class="py-src-parameter">status</span>):
 
357
        <span class="py-src-string">&quot;&quot;&quot;Return a deferred returning a string&quot;&quot;&quot;</span>
 
358
 
 
359
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">buildProtocol</span>(<span class="py-src-parameter">addr</span>):
 
360
        <span class="py-src-string">&quot;&quot;&quot;Return a protocol returning a string&quot;&quot;&quot;</span>
 
361
 
 
362
 
 
363
<span class="py-src-keyword">class</span> <span class="py-src-identifier">FingerSetterFactoryFromService</span>(<span class="py-src-parameter">protocol</span>.<span class="py-src-parameter">ServerFactory</span>):
 
364
 
 
365
    <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerSetterFactory</span>)
 
366
 
 
367
    <span class="py-src-variable">protocol</span> = <span class="py-src-variable">FingerSetterProtocol</span>
 
368
 
 
369
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">__init__</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">service</span>):
 
370
        <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>
 
371
 
 
372
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">setUser</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">user</span>, <span class="py-src-parameter">status</span>):
 
373
        <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span>.<span class="py-src-variable">setUser</span>(<span class="py-src-variable">user</span>, <span class="py-src-variable">status</span>)
 
374
 
 
375
 
 
376
<span class="py-src-variable">components</span>.<span class="py-src-variable">registerAdapter</span>(<span class="py-src-variable">FingerSetterFactoryFromService</span>,
 
377
                           <span class="py-src-variable">IFingerSetterService</span>,
 
378
                           <span class="py-src-variable">IFingerSetterFactory</span>)
 
379
 
 
380
<span class="py-src-keyword">class</span> <span class="py-src-identifier">IRCReplyBot</span>(<span class="py-src-parameter">irc</span>.<span class="py-src-parameter">IRCClient</span>):
 
381
 
 
382
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">connectionMade</span>(<span class="py-src-parameter">self</span>):
 
383
        <span class="py-src-variable">self</span>.<span class="py-src-variable">nickname</span> = <span class="py-src-variable">self</span>.<span class="py-src-variable">factory</span>.<span class="py-src-variable">nickname</span>
 
384
        <span class="py-src-variable">irc</span>.<span class="py-src-variable">IRCClient</span>.<span class="py-src-variable">connectionMade</span>(<span class="py-src-variable">self</span>)
 
385
 
 
386
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">privmsg</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">user</span>, <span class="py-src-parameter">channel</span>, <span class="py-src-parameter">msg</span>):
 
387
        <span class="py-src-variable">user</span> = <span class="py-src-variable">user</span>.<span class="py-src-variable">split</span>(<span class="py-src-string">'!'</span>)[<span class="py-src-number">0</span>]
 
388
        <span class="py-src-keyword">if</span> <span class="py-src-variable">self</span>.<span class="py-src-variable">nickname</span>.<span class="py-src-variable">lower</span>() == <span class="py-src-variable">channel</span>.<span class="py-src-variable">lower</span>():
 
389
            <span class="py-src-variable">d</span> = <span class="py-src-variable">self</span>.<span class="py-src-variable">factory</span>.<span class="py-src-variable">getUser</span>(<span class="py-src-variable">msg</span>)
 
390
            <span class="py-src-variable">d</span>.<span class="py-src-variable">addErrback</span>(<span class="py-src-variable">catchError</span>)
 
391
            <span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-keyword">lambda</span> <span class="py-src-variable">m</span>: <span class="py-src-string">&quot;Status of %s: %s&quot;</span> % (<span class="py-src-variable">msg</span>, <span class="py-src-variable">m</span>))
 
392
            <span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-keyword">lambda</span> <span class="py-src-variable">m</span>: <span class="py-src-variable">self</span>.<span class="py-src-variable">msg</span>(<span class="py-src-variable">user</span>, <span class="py-src-variable">m</span>))
 
393
 
 
394
 
 
395
<span class="py-src-keyword">class</span> <span class="py-src-identifier">IIRCClientFactory</span>(<span class="py-src-parameter">Interface</span>):
 
396
 
 
397
    <span class="py-src-string">&quot;&quot;&quot;
 
398
    @ivar nickname
 
399
    &quot;&quot;&quot;</span>
 
400
 
 
401
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUser</span>(<span class="py-src-parameter">user</span>):
 
402
        <span class="py-src-string">&quot;&quot;&quot;Return a deferred returning a string&quot;&quot;&quot;</span>
 
403
 
 
404
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">buildProtocol</span>(<span class="py-src-parameter">addr</span>):
 
405
        <span class="py-src-string">&quot;&quot;&quot;Return a protocol&quot;&quot;&quot;</span>
 
406
 
 
407
 
 
408
<span class="py-src-keyword">class</span> <span class="py-src-identifier">IRCClientFactoryFromService</span>(<span class="py-src-parameter">protocol</span>.<span class="py-src-parameter">ClientFactory</span>):
 
409
 
 
410
    <span class="py-src-variable">implements</span>(<span class="py-src-variable">IIRCClientFactory</span>)
 
411
 
 
412
    <span class="py-src-variable">protocol</span> = <span class="py-src-variable">IRCReplyBot</span>
 
413
    <span class="py-src-variable">nickname</span> = <span class="py-src-variable">None</span>
 
414
 
 
415
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">__init__</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">service</span>):
 
416
        <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>
 
417
 
 
418
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUser</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">user</span>):
 
419
        <span class="py-src-keyword">return</span> <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span>.<span class="py-src-variable">getUser</span>(<span class="py-src-variable">user</span>)
 
420
 
 
421
<span class="py-src-variable">components</span>.<span class="py-src-variable">registerAdapter</span>(<span class="py-src-variable">IRCClientFactoryFromService</span>,
 
422
                           <span class="py-src-variable">IFingerService</span>,
 
423
                           <span class="py-src-variable">IIRCClientFactory</span>)
 
424
 
 
425
<span class="py-src-keyword">class</span> <span class="py-src-identifier">UserStatusTree</span>(<span class="py-src-parameter">resource</span>.<span class="py-src-parameter">Resource</span>):
 
426
 
 
427
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">__init__</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">service</span>):
 
428
        <span class="py-src-variable">resource</span>.<span class="py-src-variable">Resource</span>.<span class="py-src-variable">__init__</span>(<span class="py-src-variable">self</span>)
 
429
        <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span>=<span class="py-src-variable">service</span>
 
430
 
 
431
        <span class="py-src-comment"># add a specific child for the path &quot;RPC2&quot;</span>
 
432
        <span class="py-src-variable">self</span>.<span class="py-src-variable">putChild</span>(<span class="py-src-string">&quot;RPC2&quot;</span>, <span class="py-src-variable">UserStatusXR</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">service</span>))
 
433
 
 
434
        <span class="py-src-comment"># need to do this for resources at the root of the site</span>
 
435
        <span class="py-src-variable">self</span>.<span class="py-src-variable">putChild</span>(<span class="py-src-string">&quot;&quot;</span>, <span class="py-src-variable">self</span>)
 
436
 
 
437
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">_cb_render_GET</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">users</span>, <span class="py-src-parameter">request</span>):
 
438
        <span class="py-src-variable">userOutput</span> = <span class="py-src-string">''</span>.<span class="py-src-variable">join</span>([<span class="py-src-string">&quot;&lt;li&gt;&lt;a href=\&quot;%s\&quot;&gt;%s&lt;/a&gt;&lt;/li&gt;&quot;</span> % (<span class="py-src-variable">user</span>, <span class="py-src-variable">user</span>)
 
439
                <span class="py-src-keyword">for</span> <span class="py-src-variable">user</span> <span class="py-src-keyword">in</span> <span class="py-src-variable">users</span>])
 
440
        <span class="py-src-variable">request</span>.<span class="py-src-variable">write</span>(<span class="py-src-string">&quot;&quot;&quot;
 
441
            &lt;html&gt;&lt;head&gt;&lt;title&gt;Users&lt;/title&gt;&lt;/head&gt;&lt;body&gt;
 
442
            &lt;h1&gt;Users&lt;/h1&gt;
 
443
            &lt;ul&gt;
 
444
            %s
 
445
            &lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;&quot;&quot;&quot;</span> % <span class="py-src-variable">userOutput</span>)
 
446
        <span class="py-src-variable">request</span>.<span class="py-src-variable">finish</span>()
 
447
 
 
448
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">render_GET</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">request</span>):
 
449
        <span class="py-src-variable">d</span> = <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span>.<span class="py-src-variable">getUsers</span>()
 
450
        <span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">_cb_render_GET</span>, <span class="py-src-variable">request</span>)
 
451
 
 
452
        <span class="py-src-comment"># signal that the rendering is not complete</span>
 
453
        <span class="py-src-keyword">return</span> <span class="py-src-variable">server</span>.<span class="py-src-variable">NOT_DONE_YET</span>
 
454
 
 
455
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getChild</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">path</span>, <span class="py-src-parameter">request</span>):
 
456
        <span class="py-src-keyword">return</span> <span class="py-src-variable">UserStatus</span>(<span class="py-src-variable">user</span>=<span class="py-src-variable">path</span>, <span class="py-src-variable">service</span>=<span class="py-src-variable">self</span>.<span class="py-src-variable">service</span>)
 
457
 
 
458
<span class="py-src-variable">components</span>.<span class="py-src-variable">registerAdapter</span>(<span class="py-src-variable">UserStatusTree</span>, <span class="py-src-variable">IFingerService</span>, <span class="py-src-variable">resource</span>.<span class="py-src-variable">IResource</span>)
 
459
 
 
460
<span class="py-src-keyword">class</span> <span class="py-src-identifier">UserStatus</span>(<span class="py-src-parameter">resource</span>.<span class="py-src-parameter">Resource</span>):
 
461
 
 
462
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">__init__</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">user</span>, <span class="py-src-parameter">service</span>):
 
463
        <span class="py-src-variable">resource</span>.<span class="py-src-variable">Resource</span>.<span class="py-src-variable">__init__</span>(<span class="py-src-variable">self</span>)
 
464
        <span class="py-src-variable">self</span>.<span class="py-src-variable">user</span> = <span class="py-src-variable">user</span>
 
465
        <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>
 
466
 
 
467
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">_cb_render_GET</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">status</span>, <span class="py-src-parameter">request</span>):
 
468
        <span class="py-src-variable">request</span>.<span class="py-src-variable">write</span>(<span class="py-src-string">&quot;&quot;&quot;&lt;html&gt;&lt;head&gt;&lt;title&gt;%s&lt;/title&gt;&lt;/head&gt;
 
469
        &lt;body&gt;&lt;h1&gt;%s&lt;/h1&gt;
 
470
        &lt;p&gt;%s&lt;/p&gt;
 
471
        &lt;/body&gt;&lt;/html&gt;&quot;&quot;&quot;</span> % (<span class="py-src-variable">self</span>.<span class="py-src-variable">user</span>, <span class="py-src-variable">self</span>.<span class="py-src-variable">user</span>, <span class="py-src-variable">status</span>))
 
472
        <span class="py-src-variable">request</span>.<span class="py-src-variable">finish</span>()
 
473
 
 
474
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">render_GET</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">request</span>):
 
475
        <span class="py-src-variable">d</span> = <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span>.<span class="py-src-variable">getUser</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">user</span>)
 
476
        <span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">_cb_render_GET</span>, <span class="py-src-variable">request</span>)
 
477
 
 
478
        <span class="py-src-comment"># signal that the rendering is not complete</span>
 
479
        <span class="py-src-keyword">return</span> <span class="py-src-variable">server</span>.<span class="py-src-variable">NOT_DONE_YET</span>
 
480
 
 
481
<span class="py-src-keyword">class</span> <span class="py-src-identifier">UserStatusXR</span>(<span class="py-src-parameter">xmlrpc</span>.<span class="py-src-parameter">XMLRPC</span>):
 
482
 
 
483
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">__init__</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">service</span>):
 
484
        <span class="py-src-variable">xmlrpc</span>.<span class="py-src-variable">XMLRPC</span>.<span class="py-src-variable">__init__</span>(<span class="py-src-variable">self</span>)
 
485
        <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>
 
486
 
 
487
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">xmlrpc_getUser</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">user</span>):
 
488
        <span class="py-src-keyword">return</span> <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span>.<span class="py-src-variable">getUser</span>(<span class="py-src-variable">user</span>)
 
489
 
 
490
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">xmlrpc_getUsers</span>(<span class="py-src-parameter">self</span>):
 
491
        <span class="py-src-keyword">return</span> <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span>.<span class="py-src-variable">getUsers</span>()
 
492
 
 
493
 
 
494
<span class="py-src-keyword">class</span> <span class="py-src-identifier">FingerService</span>(<span class="py-src-parameter">service</span>.<span class="py-src-parameter">Service</span>):
 
495
 
 
496
    <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerService</span>)
 
497
 
 
498
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">__init__</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">filename</span>):
 
499
        <span class="py-src-variable">self</span>.<span class="py-src-variable">filename</span> = <span class="py-src-variable">filename</span>
 
500
        <span class="py-src-variable">self</span>.<span class="py-src-variable">users</span> = {}
 
501
        <span class="py-src-variable">self</span>.<span class="py-src-variable">_read</span>()
 
502
 
 
503
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">_read</span>(<span class="py-src-parameter">self</span>):
 
504
        <span class="py-src-variable">self</span>.<span class="py-src-variable">users</span>.<span class="py-src-variable">clear</span>()
 
505
        <span class="py-src-keyword">for</span> <span class="py-src-variable">line</span> <span class="py-src-keyword">in</span> <span class="py-src-variable">file</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">filename</span>):
 
506
            <span class="py-src-variable">user</span>, <span class="py-src-variable">status</span> = <span class="py-src-variable">line</span>.<span class="py-src-variable">split</span>(<span class="py-src-string">':'</span>, <span class="py-src-number">1</span>)
 
507
            <span class="py-src-variable">user</span> = <span class="py-src-variable">user</span>.<span class="py-src-variable">strip</span>()
 
508
            <span class="py-src-variable">status</span> = <span class="py-src-variable">status</span>.<span class="py-src-variable">strip</span>()
 
509
            <span class="py-src-variable">self</span>.<span class="py-src-variable">users</span>[<span class="py-src-variable">user</span>] = <span class="py-src-variable">status</span>
 
510
        <span class="py-src-variable">self</span>.<span class="py-src-variable">call</span> = <span class="py-src-variable">reactor</span>.<span class="py-src-variable">callLater</span>(<span class="py-src-number">30</span>, <span class="py-src-variable">self</span>.<span class="py-src-variable">_read</span>)
 
511
 
 
512
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUser</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">user</span>):
 
513
        <span class="py-src-keyword">return</span> <span class="py-src-variable">defer</span>.<span class="py-src-variable">succeed</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">users</span>.<span class="py-src-variable">get</span>(<span class="py-src-variable">user</span>, <span class="py-src-string">&quot;No such user&quot;</span>))
 
514
 
 
515
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUsers</span>(<span class="py-src-parameter">self</span>):
 
516
        <span class="py-src-keyword">return</span> <span class="py-src-variable">defer</span>.<span class="py-src-variable">succeed</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">users</span>.<span class="py-src-variable">keys</span>())
 
517
 
 
518
 
 
519
<span class="py-src-variable">application</span> = <span class="py-src-variable">service</span>.<span class="py-src-variable">Application</span>(<span class="py-src-string">'finger'</span>, <span class="py-src-variable">uid</span>=<span class="py-src-number">1</span>, <span class="py-src-variable">gid</span>=<span class="py-src-number">1</span>)
 
520
<span class="py-src-variable">f</span> = <span class="py-src-variable">FingerService</span>(<span class="py-src-string">'/etc/users'</span>)
 
521
<span class="py-src-variable">serviceCollection</span> = <span class="py-src-variable">service</span>.<span class="py-src-variable">IServiceCollection</span>(<span class="py-src-variable">application</span>)
 
522
<span class="py-src-variable">internet</span>.<span class="py-src-variable">TCPServer</span>(<span class="py-src-number">79</span>, <span class="py-src-variable">IFingerFactory</span>(<span class="py-src-variable">f</span>)
 
523
                   ).<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">serviceCollection</span>)
 
524
<span class="py-src-variable">internet</span>.<span class="py-src-variable">TCPServer</span>(<span class="py-src-number">8000</span>, <span class="py-src-variable">server</span>.<span class="py-src-variable">Site</span>(<span class="py-src-variable">resource</span>.<span class="py-src-variable">IResource</span>(<span class="py-src-variable">f</span>))
 
525
                   ).<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">serviceCollection</span>)
 
526
<span class="py-src-variable">i</span> = <span class="py-src-variable">IIRCClientFactory</span>(<span class="py-src-variable">f</span>)
 
527
<span class="py-src-variable">i</span>.<span class="py-src-variable">nickname</span> = <span class="py-src-string">'fingerbot'</span>
 
528
<span class="py-src-variable">internet</span>.<span class="py-src-variable">TCPClient</span>(<span class="py-src-string">'irc.freenode.org'</span>, <span class="py-src-number">6667</span>, <span class="py-src-variable">i</span>
 
529
                   ).<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">serviceCollection</span>)
 
530
</pre><div class="caption">Source listing - <a href="listings/finger/finger20.tac"><span class="filename">listings/finger/finger20.tac</span></a></div></div>
 
531
 
 
532
</div>
 
533
 
 
534
    <p><a href="../index.html">Index</a></p>
 
535
    <span class="version">Version: 10.0.0</span>
 
536
  </body>
 
537
</html>
 
 
b'\\ No newline at end of file'