~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/backends.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: pluggable backends</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: pluggable backends</h1>
 
9
    <div class="toc"><ol><li><a href="#auto0">Introduction</a></li><li><a href="#auto1">Another Back-end</a></li><li><a href="#auto2">Yet Another Back-end: Doing the Standard Thing</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 fifth 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 will add new several new backends to our finger service
 
19
using the component-based architecture developed in <a href="components.html" shape="rect">The Evolution of Finger: moving to a
 
20
component based architecture</a>. This will show just how convenient it is to
 
21
implement new back-ends when we move to a component based architecture. Note
 
22
that here we also use an interface we previously wrote, FingerSetterFactory,
 
23
by supporting one single method. We manage to preserve the service's ignorance
 
24
of the network.</p>
 
25
 
 
26
<h2>Another Back-end<a name="auto1"/></h2>
 
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
</p><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>, <span class="py-src-variable">utils</span>
 
48
<span class="py-src-keyword">import</span> <span class="py-src-variable">pwd</span>
 
49
 
 
50
<span class="py-src-comment"># Another back-end</span>
 
51
 
 
52
<span class="py-src-keyword">class</span> <span class="py-src-identifier">LocalFingerService</span>(<span class="py-src-parameter">service</span>.<span class="py-src-parameter">Service</span>):
 
53
 
 
54
    <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerService</span>)
 
55
 
 
56
    <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>):
 
57
    <span class="py-src-comment"># need a local finger daemon running for this to work</span>
 
58
        <span class="py-src-keyword">return</span> <span class="py-src-variable">utils</span>.<span class="py-src-variable">getProcessOutput</span>(<span class="py-src-string">&quot;finger&quot;</span>, [<span class="py-src-variable">user</span>])
 
59
 
 
60
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUsers</span>(<span class="py-src-parameter">self</span>):
 
61
        <span class="py-src-keyword">return</span> <span class="py-src-variable">defer</span>.<span class="py-src-variable">succeed</span>([])
 
62
 
 
63
 
 
64
<span class="py-src-variable">f</span> = <span class="py-src-variable">LocalFingerService</span>()
 
65
</pre><div class="caption">Source listing - <a href="listings/finger/finger19b_changes.py"><span class="filename">listings/finger/finger19b_changes.py</span></a></div></div>
 
66
<p>
 
67
Full source code here: <div class="py-listing"><pre><p class="py-linenumber">  1
 
68
  2
 
69
  3
 
70
  4
 
71
  5
 
72
  6
 
73
  7
 
74
  8
 
75
  9
 
76
 10
 
77
 11
 
78
 12
 
79
 13
 
80
 14
 
81
 15
 
82
 16
 
83
 17
 
84
 18
 
85
 19
 
86
 20
 
87
 21
 
88
 22
 
89
 23
 
90
 24
 
91
 25
 
92
 26
 
93
 27
 
94
 28
 
95
 29
 
96
 30
 
97
 31
 
98
 32
 
99
 33
 
100
 34
 
101
 35
 
102
 36
 
103
 37
 
104
 38
 
105
 39
 
106
 40
 
107
 41
 
108
 42
 
109
 43
 
110
 44
 
111
 45
 
112
 46
 
113
 47
 
114
 48
 
115
 49
 
116
 50
 
117
 51
 
118
 52
 
119
 53
 
120
 54
 
121
 55
 
122
 56
 
123
 57
 
124
 58
 
125
 59
 
126
 60
 
127
 61
 
128
 62
 
129
 63
 
130
 64
 
131
 65
 
132
 66
 
133
 67
 
134
 68
 
135
 69
 
136
 70
 
137
 71
 
138
 72
 
139
 73
 
140
 74
 
141
 75
 
142
 76
 
143
 77
 
144
 78
 
145
 79
 
146
 80
 
147
 81
 
148
 82
 
149
 83
 
150
 84
 
151
 85
 
152
 86
 
153
 87
 
154
 88
 
155
 89
 
156
 90
 
157
 91
 
158
 92
 
159
 93
 
160
 94
 
161
 95
 
162
 96
 
163
 97
 
164
 98
 
165
 99
 
166
100
 
167
101
 
168
102
 
169
103
 
170
104
 
171
105
 
172
106
 
173
107
 
174
108
 
175
109
 
176
110
 
177
111
 
178
112
 
179
113
 
180
114
 
181
115
 
182
116
 
183
117
 
184
118
 
185
119
 
186
120
 
187
121
 
188
122
 
189
123
 
190
124
 
191
125
 
192
126
 
193
127
 
194
128
 
195
129
 
196
130
 
197
131
 
198
132
 
199
133
 
200
134
 
201
135
 
202
136
 
203
137
 
204
138
 
205
139
 
206
140
 
207
141
 
208
142
 
209
143
 
210
144
 
211
145
 
212
146
 
213
147
 
214
148
 
215
149
 
216
150
 
217
151
 
218
152
 
219
153
 
220
154
 
221
155
 
222
156
 
223
157
 
224
158
 
225
159
 
226
160
 
227
161
 
228
162
 
229
163
 
230
164
 
231
165
 
232
166
 
233
167
 
234
168
 
235
169
 
236
170
 
237
171
 
238
172
 
239
173
 
240
174
 
241
175
 
242
176
 
243
177
 
244
178
 
245
179
 
246
180
 
247
181
 
248
182
 
249
183
 
250
184
 
251
185
 
252
186
 
253
187
 
254
188
 
255
189
 
256
190
 
257
191
 
258
192
 
259
193
 
260
194
 
261
195
 
262
196
 
263
197
 
264
198
 
265
199
 
266
200
 
267
201
 
268
202
 
269
203
 
270
204
 
271
205
 
272
206
 
273
207
 
274
208
 
275
209
 
276
210
 
277
211
 
278
212
 
279
213
 
280
214
 
281
215
 
282
216
 
283
217
 
284
218
 
285
219
 
286
220
 
287
221
 
288
222
 
289
223
 
290
224
 
291
225
 
292
226
 
293
227
 
294
228
 
295
229
 
296
230
 
297
231
 
298
232
 
299
233
 
300
234
 
301
235
 
302
236
 
303
237
 
304
238
 
305
239
 
306
240
 
307
241
 
308
242
 
309
243
 
310
244
 
311
245
 
312
246
 
313
247
 
314
248
 
315
249
 
316
250
 
317
251
 
318
252
 
319
253
 
320
254
 
321
255
 
322
256
 
323
257
 
324
</p><span class="py-src-comment"># Do everything properly, and componentize</span>
 
325
<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>
 
326
<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>, <span class="py-src-variable">utils</span>
 
327
<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>
 
328
<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>
 
329
<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>
 
330
<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>
 
331
<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>
 
332
<span class="py-src-keyword">import</span> <span class="py-src-variable">cgi</span>
 
333
<span class="py-src-keyword">import</span> <span class="py-src-variable">pwd</span>
 
334
 
 
335
<span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerService</span>(<span class="py-src-parameter">Interface</span>):
 
336
 
 
337
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUser</span>(<span class="py-src-parameter">user</span>):
 
338
        <span class="py-src-string">&quot;&quot;&quot;Return a deferred returning a string&quot;&quot;&quot;</span>
 
339
 
 
340
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUsers</span>():
 
341
        <span class="py-src-string">&quot;&quot;&quot;Return a deferred returning a list of strings&quot;&quot;&quot;</span>
 
342
 
 
343
<span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerSetterService</span>(<span class="py-src-parameter">Interface</span>):
 
344
 
 
345
    <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>):
 
346
        <span class="py-src-string">&quot;&quot;&quot;Set the user's status to something&quot;&quot;&quot;</span>
 
347
 
 
348
<span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerSetterService</span>(<span class="py-src-parameter">Interface</span>):
 
349
 
 
350
    <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>):
 
351
        <span class="py-src-string">&quot;&quot;&quot;Set the user's status to something&quot;&quot;&quot;</span>
 
352
 
 
353
<span class="py-src-keyword">def</span> <span class="py-src-identifier">catchError</span>(<span class="py-src-parameter">err</span>):
 
354
    <span class="py-src-keyword">return</span> <span class="py-src-string">&quot;Internal error in server&quot;</span>
 
355
 
 
356
<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>):
 
357
 
 
358
    <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>):
 
359
        <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>)
 
360
        <span class="py-src-variable">d</span>.<span class="py-src-variable">addErrback</span>(<span class="py-src-variable">catchError</span>)
 
361
        <span class="py-src-keyword">def</span> <span class="py-src-identifier">writeValue</span>(<span class="py-src-parameter">value</span>):
 
362
            <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>)
 
363
            <span class="py-src-variable">self</span>.<span class="py-src-variable">transport</span>.<span class="py-src-variable">loseConnection</span>()
 
364
        <span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">writeValue</span>)
 
365
 
 
366
 
 
367
<span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerFactory</span>(<span class="py-src-parameter">Interface</span>):
 
368
 
 
369
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUser</span>(<span class="py-src-parameter">user</span>):
 
370
        <span class="py-src-string">&quot;&quot;&quot;Return a deferred returning a string&quot;&quot;&quot;</span>
 
371
 
 
372
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">buildProtocol</span>(<span class="py-src-parameter">addr</span>):
 
373
        <span class="py-src-string">&quot;&quot;&quot;Return a protocol returning a string&quot;&quot;&quot;</span>
 
374
 
 
375
 
 
376
<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>):
 
377
 
 
378
    <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerFactory</span>)
 
379
 
 
380
    <span class="py-src-variable">protocol</span> = <span class="py-src-variable">FingerProtocol</span>
 
381
 
 
382
    <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>):
 
383
        <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>
 
384
 
 
385
    <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>):
 
386
        <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>)
 
387
 
 
388
<span class="py-src-variable">components</span>.<span class="py-src-variable">registerAdapter</span>(<span class="py-src-variable">FingerFactoryFromService</span>,
 
389
                           <span class="py-src-variable">IFingerService</span>,
 
390
                           <span class="py-src-variable">IFingerFactory</span>)
 
391
 
 
392
<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>):
 
393
 
 
394
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">connectionMade</span>(<span class="py-src-parameter">self</span>):
 
395
        <span class="py-src-variable">self</span>.<span class="py-src-variable">lines</span> = []
 
396
 
 
397
    <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>):
 
398
        <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>)
 
399
 
 
400
    <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>):
 
401
        <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>:
 
402
            <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>)
 
403
 
 
404
 
 
405
<span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerSetterFactory</span>(<span class="py-src-parameter">Interface</span>):
 
406
 
 
407
    <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>):
 
408
        <span class="py-src-string">&quot;&quot;&quot;Return a deferred returning a string&quot;&quot;&quot;</span>
 
409
 
 
410
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">buildProtocol</span>(<span class="py-src-parameter">addr</span>):
 
411
        <span class="py-src-string">&quot;&quot;&quot;Return a protocol returning a string&quot;&quot;&quot;</span>
 
412
 
 
413
 
 
414
<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>):
 
415
 
 
416
    <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerSetterFactory</span>)
 
417
 
 
418
    <span class="py-src-variable">protocol</span> = <span class="py-src-variable">FingerSetterProtocol</span>
 
419
 
 
420
    <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>):
 
421
        <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>
 
422
 
 
423
    <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>):
 
424
        <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>)
 
425
 
 
426
 
 
427
<span class="py-src-variable">components</span>.<span class="py-src-variable">registerAdapter</span>(<span class="py-src-variable">FingerSetterFactoryFromService</span>,
 
428
                           <span class="py-src-variable">IFingerSetterService</span>,
 
429
                           <span class="py-src-variable">IFingerSetterFactory</span>)
 
430
 
 
431
<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>):
 
432
 
 
433
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">connectionMade</span>(<span class="py-src-parameter">self</span>):
 
434
        <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>
 
435
        <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>)
 
436
 
 
437
    <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>):
 
438
        <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>]
 
439
        <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>():
 
440
            <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>)
 
441
            <span class="py-src-variable">d</span>.<span class="py-src-variable">addErrback</span>(<span class="py-src-variable">catchError</span>)
 
442
            <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>))
 
443
            <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>))
 
444
 
 
445
 
 
446
<span class="py-src-keyword">class</span> <span class="py-src-identifier">IIRCClientFactory</span>(<span class="py-src-parameter">Interface</span>):
 
447
 
 
448
    <span class="py-src-string">&quot;&quot;&quot;
 
449
    @ivar nickname
 
450
    &quot;&quot;&quot;</span>
 
451
 
 
452
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUser</span>(<span class="py-src-parameter">user</span>):
 
453
        <span class="py-src-string">&quot;&quot;&quot;Return a deferred returning a string&quot;&quot;&quot;</span>
 
454
 
 
455
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">buildProtocol</span>(<span class="py-src-parameter">addr</span>):
 
456
        <span class="py-src-string">&quot;&quot;&quot;Return a protocol&quot;&quot;&quot;</span>
 
457
 
 
458
 
 
459
<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>):
 
460
 
 
461
    <span class="py-src-variable">implements</span>(<span class="py-src-variable">IIRCClientFactory</span>)
 
462
 
 
463
    <span class="py-src-variable">protocol</span> = <span class="py-src-variable">IRCReplyBot</span>
 
464
    <span class="py-src-variable">nickname</span> = <span class="py-src-variable">None</span>
 
465
 
 
466
    <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>):
 
467
        <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>
 
468
 
 
469
    <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>):
 
470
        <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>)
 
471
 
 
472
<span class="py-src-variable">components</span>.<span class="py-src-variable">registerAdapter</span>(<span class="py-src-variable">IRCClientFactoryFromService</span>,
 
473
                           <span class="py-src-variable">IFingerService</span>,
 
474
                           <span class="py-src-variable">IIRCClientFactory</span>)
 
475
 
 
476
<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>):
 
477
 
 
478
    <span class="py-src-variable">implements</span>(<span class="py-src-variable">resource</span>.<span class="py-src-variable">IResource</span>)
 
479
 
 
480
    <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>):
 
481
        <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>)
 
482
        <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>
 
483
        <span class="py-src-variable">self</span>.<span class="py-src-variable">putChild</span>(<span class="py-src-string">'RPC2'</span>, <span class="py-src-variable">UserStatusXR</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">service</span>))
 
484
 
 
485
    <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>):
 
486
        <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>()
 
487
        <span class="py-src-keyword">def</span> <span class="py-src-identifier">formatUsers</span>(<span class="py-src-parameter">users</span>):
 
488
            <span class="py-src-variable">l</span> = [<span class="py-src-string">'&lt;li&gt;&lt;a href=&quot;%s&quot;&gt;%s&lt;/a&gt;&lt;/li&gt;'</span> % (<span class="py-src-variable">user</span>, <span class="py-src-variable">user</span>)
 
489
                 <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>]
 
490
            <span class="py-src-keyword">return</span> <span class="py-src-string">'&lt;ul&gt;'</span>+<span class="py-src-string">''</span>.<span class="py-src-variable">join</span>(<span class="py-src-variable">l</span>)+<span class="py-src-string">'&lt;/ul&gt;'</span>
 
491
        <span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">formatUsers</span>)
 
492
        <span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">request</span>.<span class="py-src-variable">write</span>)
 
493
        <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">_</span>: <span class="py-src-variable">request</span>.<span class="py-src-variable">finish</span>())
 
494
        <span class="py-src-keyword">return</span> <span class="py-src-variable">server</span>.<span class="py-src-variable">NOT_DONE_YET</span>
 
495
 
 
496
    <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>):
 
497
        <span class="py-src-keyword">if</span> <span class="py-src-variable">path</span>==<span class="py-src-string">&quot;&quot;</span>:
 
498
            <span class="py-src-keyword">return</span> <span class="py-src-variable">UserStatusTree</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">service</span>)
 
499
        <span class="py-src-keyword">else</span>:
 
500
            <span class="py-src-keyword">return</span> <span class="py-src-variable">UserStatus</span>(<span class="py-src-variable">path</span>, <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span>)
 
501
 
 
502
<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>,
 
503
                           <span class="py-src-variable">resource</span>.<span class="py-src-variable">IResource</span>)
 
504
 
 
505
<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>):
 
506
 
 
507
    <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>):
 
508
        <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>)
 
509
        <span class="py-src-variable">self</span>.<span class="py-src-variable">user</span> = <span class="py-src-variable">user</span>
 
510
        <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>
 
511
 
 
512
    <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>):
 
513
        <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>)
 
514
        <span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">cgi</span>.<span class="py-src-variable">escape</span>)
 
515
        <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>:
 
516
                      <span class="py-src-string">'&lt;h1&gt;%s&lt;/h1&gt;'</span>%<span class="py-src-variable">self</span>.<span class="py-src-variable">user</span>+<span class="py-src-string">'&lt;p&gt;%s&lt;/p&gt;'</span>%<span class="py-src-variable">m</span>)
 
517
        <span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">request</span>.<span class="py-src-variable">write</span>)
 
518
        <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">_</span>: <span class="py-src-variable">request</span>.<span class="py-src-variable">finish</span>())
 
519
        <span class="py-src-keyword">return</span> <span class="py-src-variable">server</span>.<span class="py-src-variable">NOT_DONE_YET</span>
 
520
 
 
521
 
 
522
<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>):
 
523
 
 
524
    <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>):
 
525
        <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>)
 
526
        <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>
 
527
 
 
528
    <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>):
 
529
        <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>)
 
530
 
 
531
 
 
532
<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>):
 
533
 
 
534
    <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerService</span>)
 
535
 
 
536
    <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>):
 
537
        <span class="py-src-variable">self</span>.<span class="py-src-variable">filename</span> = <span class="py-src-variable">filename</span>
 
538
        <span class="py-src-variable">self</span>.<span class="py-src-variable">users</span> = {}
 
539
        <span class="py-src-variable">self</span>.<span class="py-src-variable">_read</span>()
 
540
 
 
541
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">_read</span>(<span class="py-src-parameter">self</span>):
 
542
        <span class="py-src-variable">self</span>.<span class="py-src-variable">users</span>.<span class="py-src-variable">clear</span>()
 
543
        <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>):
 
544
            <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>)
 
545
            <span class="py-src-variable">user</span> = <span class="py-src-variable">user</span>.<span class="py-src-variable">strip</span>()
 
546
            <span class="py-src-variable">status</span> = <span class="py-src-variable">status</span>.<span class="py-src-variable">strip</span>()
 
547
            <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>
 
548
        <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>)
 
549
 
 
550
    <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>):
 
551
        <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>))
 
552
 
 
553
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUsers</span>(<span class="py-src-parameter">self</span>):
 
554
        <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>())
 
555
 
 
556
<span class="py-src-comment"># Another back-end</span>
 
557
 
 
558
<span class="py-src-keyword">class</span> <span class="py-src-identifier">LocalFingerService</span>(<span class="py-src-parameter">service</span>.<span class="py-src-parameter">Service</span>):
 
559
 
 
560
    <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerService</span>)
 
561
 
 
562
    <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>):
 
563
    <span class="py-src-comment"># need a local finger daemon running for this to work</span>
 
564
        <span class="py-src-keyword">return</span> <span class="py-src-variable">utils</span>.<span class="py-src-variable">getProcessOutput</span>(<span class="py-src-string">&quot;finger&quot;</span>, [<span class="py-src-variable">user</span>])
 
565
 
 
566
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUsers</span>(<span class="py-src-parameter">self</span>):
 
567
        <span class="py-src-keyword">return</span> <span class="py-src-variable">defer</span>.<span class="py-src-variable">succeed</span>([])
 
568
 
 
569
 
 
570
<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>)
 
571
<span class="py-src-variable">f</span> = <span class="py-src-variable">LocalFingerService</span>()
 
572
<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>)
 
573
<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>)
 
574
                   ).<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">serviceCollection</span>)
 
575
<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>))
 
576
                   ).<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">serviceCollection</span>)
 
577
<span class="py-src-variable">i</span> = <span class="py-src-variable">IIRCClientFactory</span>(<span class="py-src-variable">f</span>)
 
578
<span class="py-src-variable">i</span>.<span class="py-src-variable">nickname</span> = <span class="py-src-string">'fingerbot'</span>
 
579
<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>
 
580
                   ).<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">serviceCollection</span>)
 
581
</pre><div class="caption">Source listing - <a href="listings/finger/finger19b.tac"><span class="filename">listings/finger/finger19b.tac</span></a></div></div>
 
582
</p>
 
583
 
 
584
<p>We've already written this, but now we get more for less work:
 
585
the network code is completely separate from the back-end.</p>
 
586
 
 
587
 
 
588
<h2>Yet Another Back-end: Doing the Standard Thing<a name="auto2"/></h2>
 
589
 
 
590
<div class="py-listing"><pre><p class="py-linenumber"> 1
 
591
 2
 
592
 3
 
593
 4
 
594
 5
 
595
 6
 
596
 7
 
597
 8
 
598
 9
 
599
10
 
600
11
 
601
12
 
602
13
 
603
14
 
604
15
 
605
16
 
606
17
 
607
18
 
608
19
 
609
20
 
610
21
 
611
22
 
612
23
 
613
24
 
614
25
 
615
26
 
616
27
 
617
28
 
618
29
 
619
30
 
620
31
 
621
32
 
622
</p><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>, <span class="py-src-variable">utils</span>
 
623
<span class="py-src-keyword">import</span> <span class="py-src-variable">pwd</span>
 
624
<span class="py-src-keyword">import</span> <span class="py-src-variable">os</span>
 
625
 
 
626
 
 
627
<span class="py-src-comment"># Yet another back-end</span>
 
628
 
 
629
<span class="py-src-keyword">class</span> <span class="py-src-identifier">LocalFingerService</span>(<span class="py-src-parameter">service</span>.<span class="py-src-parameter">Service</span>):
 
630
 
 
631
    <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerService</span>)
 
632
 
 
633
    <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>):
 
634
        <span class="py-src-variable">user</span> = <span class="py-src-variable">user</span>.<span class="py-src-variable">strip</span>()
 
635
        <span class="py-src-keyword">try</span>:
 
636
            <span class="py-src-variable">entry</span> = <span class="py-src-variable">pwd</span>.<span class="py-src-variable">getpwnam</span>(<span class="py-src-variable">user</span>)
 
637
        <span class="py-src-keyword">except</span> <span class="py-src-variable">KeyError</span>:
 
638
            <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-string">&quot;No such user&quot;</span>)
 
639
        <span class="py-src-keyword">try</span>:
 
640
            <span class="py-src-variable">f</span> = <span class="py-src-variable">file</span>(<span class="py-src-variable">os</span>.<span class="py-src-variable">path</span>.<span class="py-src-variable">join</span>(<span class="py-src-variable">entry</span>[<span class="py-src-number">5</span>],<span class="py-src-string">'.plan'</span>))
 
641
        <span class="py-src-keyword">except</span> (<span class="py-src-variable">IOError</span>, <span class="py-src-variable">OSError</span>):
 
642
            <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-string">&quot;No such user&quot;</span>)
 
643
        <span class="py-src-variable">data</span> = <span class="py-src-variable">f</span>.<span class="py-src-variable">read</span>()
 
644
        <span class="py-src-variable">data</span> = <span class="py-src-variable">data</span>.<span class="py-src-variable">strip</span>()
 
645
        <span class="py-src-variable">f</span>.<span class="py-src-variable">close</span>()
 
646
        <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">data</span>)
 
647
 
 
648
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUsers</span>(<span class="py-src-parameter">self</span>):
 
649
        <span class="py-src-keyword">return</span> <span class="py-src-variable">defer</span>.<span class="py-src-variable">succeed</span>([])
 
650
 
 
651
 
 
652
 
 
653
<span class="py-src-variable">f</span> = <span class="py-src-variable">LocalFingerService</span>()
 
654
</pre><div class="caption">Source listing - <a href="listings/finger/finger19c_changes.py"><span class="filename">listings/finger/finger19c_changes.py</span></a></div></div>
 
655
<p>
 
656
Full source code here: <div class="py-listing"><pre><p class="py-linenumber">  1
 
657
  2
 
658
  3
 
659
  4
 
660
  5
 
661
  6
 
662
  7
 
663
  8
 
664
  9
 
665
 10
 
666
 11
 
667
 12
 
668
 13
 
669
 14
 
670
 15
 
671
 16
 
672
 17
 
673
 18
 
674
 19
 
675
 20
 
676
 21
 
677
 22
 
678
 23
 
679
 24
 
680
 25
 
681
 26
 
682
 27
 
683
 28
 
684
 29
 
685
 30
 
686
 31
 
687
 32
 
688
 33
 
689
 34
 
690
 35
 
691
 36
 
692
 37
 
693
 38
 
694
 39
 
695
 40
 
696
 41
 
697
 42
 
698
 43
 
699
 44
 
700
 45
 
701
 46
 
702
 47
 
703
 48
 
704
 49
 
705
 50
 
706
 51
 
707
 52
 
708
 53
 
709
 54
 
710
 55
 
711
 56
 
712
 57
 
713
 58
 
714
 59
 
715
 60
 
716
 61
 
717
 62
 
718
 63
 
719
 64
 
720
 65
 
721
 66
 
722
 67
 
723
 68
 
724
 69
 
725
 70
 
726
 71
 
727
 72
 
728
 73
 
729
 74
 
730
 75
 
731
 76
 
732
 77
 
733
 78
 
734
 79
 
735
 80
 
736
 81
 
737
 82
 
738
 83
 
739
 84
 
740
 85
 
741
 86
 
742
 87
 
743
 88
 
744
 89
 
745
 90
 
746
 91
 
747
 92
 
748
 93
 
749
 94
 
750
 95
 
751
 96
 
752
 97
 
753
 98
 
754
 99
 
755
100
 
756
101
 
757
102
 
758
103
 
759
104
 
760
105
 
761
106
 
762
107
 
763
108
 
764
109
 
765
110
 
766
111
 
767
112
 
768
113
 
769
114
 
770
115
 
771
116
 
772
117
 
773
118
 
774
119
 
775
120
 
776
121
 
777
122
 
778
123
 
779
124
 
780
125
 
781
126
 
782
127
 
783
128
 
784
129
 
785
130
 
786
131
 
787
132
 
788
133
 
789
134
 
790
135
 
791
136
 
792
137
 
793
138
 
794
139
 
795
140
 
796
141
 
797
142
 
798
143
 
799
144
 
800
145
 
801
146
 
802
147
 
803
148
 
804
149
 
805
150
 
806
151
 
807
152
 
808
153
 
809
154
 
810
155
 
811
156
 
812
157
 
813
158
 
814
159
 
815
160
 
816
161
 
817
162
 
818
163
 
819
164
 
820
165
 
821
166
 
822
167
 
823
168
 
824
169
 
825
170
 
826
171
 
827
172
 
828
173
 
829
174
 
830
175
 
831
176
 
832
177
 
833
178
 
834
179
 
835
180
 
836
181
 
837
182
 
838
183
 
839
184
 
840
185
 
841
186
 
842
187
 
843
188
 
844
189
 
845
190
 
846
191
 
847
192
 
848
193
 
849
194
 
850
195
 
851
196
 
852
197
 
853
198
 
854
199
 
855
200
 
856
201
 
857
202
 
858
203
 
859
204
 
860
205
 
861
206
 
862
207
 
863
208
 
864
209
 
865
210
 
866
211
 
867
212
 
868
213
 
869
214
 
870
215
 
871
216
 
872
217
 
873
218
 
874
219
 
875
220
 
876
221
 
877
222
 
878
223
 
879
224
 
880
225
 
881
226
 
882
227
 
883
228
 
884
229
 
885
230
 
886
231
 
887
232
 
888
233
 
889
234
 
890
235
 
891
236
 
892
237
 
893
238
 
894
239
 
895
240
 
896
241
 
897
242
 
898
243
 
899
244
 
900
245
 
901
246
 
902
247
 
903
248
 
904
249
 
905
250
 
906
251
 
907
252
 
908
253
 
909
254
 
910
255
 
911
256
 
912
257
 
913
258
 
914
259
 
915
260
 
916
261
 
917
262
 
918
263
 
919
264
 
920
265
 
921
266
 
922
267
 
923
268
 
924
269
 
925
</p><span class="py-src-comment"># Do everything properly, and componentize</span>
 
926
<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>
 
927
<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>, <span class="py-src-variable">utils</span>
 
928
<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>
 
929
<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>
 
930
<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>
 
931
<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>
 
932
<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>
 
933
<span class="py-src-keyword">import</span> <span class="py-src-variable">cgi</span>
 
934
<span class="py-src-keyword">import</span> <span class="py-src-variable">pwd</span>
 
935
<span class="py-src-keyword">import</span> <span class="py-src-variable">os</span>
 
936
 
 
937
<span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerService</span>(<span class="py-src-parameter">Interface</span>):
 
938
 
 
939
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUser</span>(<span class="py-src-parameter">user</span>):
 
940
        <span class="py-src-string">&quot;&quot;&quot;Return a deferred returning a string&quot;&quot;&quot;</span>
 
941
 
 
942
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUsers</span>():
 
943
        <span class="py-src-string">&quot;&quot;&quot;Return a deferred returning a list of strings&quot;&quot;&quot;</span>
 
944
 
 
945
<span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerSetterService</span>(<span class="py-src-parameter">Interface</span>):
 
946
 
 
947
    <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>):
 
948
        <span class="py-src-string">&quot;&quot;&quot;Set the user's status to something&quot;&quot;&quot;</span>
 
949
 
 
950
<span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerSetterService</span>(<span class="py-src-parameter">Interface</span>):
 
951
 
 
952
    <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>):
 
953
        <span class="py-src-string">&quot;&quot;&quot;Set the user's status to something&quot;&quot;&quot;</span>
 
954
 
 
955
<span class="py-src-keyword">def</span> <span class="py-src-identifier">catchError</span>(<span class="py-src-parameter">err</span>):
 
956
    <span class="py-src-keyword">return</span> <span class="py-src-string">&quot;Internal error in server&quot;</span>
 
957
 
 
958
<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>):
 
959
 
 
960
    <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>):
 
961
        <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>)
 
962
        <span class="py-src-variable">d</span>.<span class="py-src-variable">addErrback</span>(<span class="py-src-variable">catchError</span>)
 
963
        <span class="py-src-keyword">def</span> <span class="py-src-identifier">writeValue</span>(<span class="py-src-parameter">value</span>):
 
964
            <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>)
 
965
            <span class="py-src-variable">self</span>.<span class="py-src-variable">transport</span>.<span class="py-src-variable">loseConnection</span>()
 
966
        <span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">writeValue</span>)
 
967
 
 
968
 
 
969
<span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerFactory</span>(<span class="py-src-parameter">Interface</span>):
 
970
 
 
971
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUser</span>(<span class="py-src-parameter">user</span>):
 
972
        <span class="py-src-string">&quot;&quot;&quot;Return a deferred returning a string&quot;&quot;&quot;</span>
 
973
 
 
974
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">buildProtocol</span>(<span class="py-src-parameter">addr</span>):
 
975
        <span class="py-src-string">&quot;&quot;&quot;Return a protocol returning a string&quot;&quot;&quot;</span>
 
976
 
 
977
 
 
978
<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>):
 
979
 
 
980
    <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerFactory</span>)
 
981
 
 
982
    <span class="py-src-variable">protocol</span> = <span class="py-src-variable">FingerProtocol</span>
 
983
 
 
984
    <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>):
 
985
        <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>
 
986
 
 
987
    <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>):
 
988
        <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>)
 
989
 
 
990
<span class="py-src-variable">components</span>.<span class="py-src-variable">registerAdapter</span>(<span class="py-src-variable">FingerFactoryFromService</span>,
 
991
                           <span class="py-src-variable">IFingerService</span>,
 
992
                           <span class="py-src-variable">IFingerFactory</span>)
 
993
 
 
994
<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>):
 
995
 
 
996
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">connectionMade</span>(<span class="py-src-parameter">self</span>):
 
997
        <span class="py-src-variable">self</span>.<span class="py-src-variable">lines</span> = []
 
998
 
 
999
    <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>):
 
1000
        <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>)
 
1001
 
 
1002
    <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>):
 
1003
        <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>:
 
1004
            <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>)
 
1005
 
 
1006
 
 
1007
<span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerSetterFactory</span>(<span class="py-src-parameter">Interface</span>):
 
1008
 
 
1009
    <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>):
 
1010
        <span class="py-src-string">&quot;&quot;&quot;Return a deferred returning a string&quot;&quot;&quot;</span>
 
1011
 
 
1012
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">buildProtocol</span>(<span class="py-src-parameter">addr</span>):
 
1013
        <span class="py-src-string">&quot;&quot;&quot;Return a protocol returning a string&quot;&quot;&quot;</span>
 
1014
 
 
1015
 
 
1016
<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>):
 
1017
 
 
1018
    <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerSetterFactory</span>)
 
1019
 
 
1020
    <span class="py-src-variable">protocol</span> = <span class="py-src-variable">FingerSetterProtocol</span>
 
1021
 
 
1022
    <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>):
 
1023
        <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>
 
1024
 
 
1025
    <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>):
 
1026
        <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>)
 
1027
 
 
1028
 
 
1029
<span class="py-src-variable">components</span>.<span class="py-src-variable">registerAdapter</span>(<span class="py-src-variable">FingerSetterFactoryFromService</span>,
 
1030
                           <span class="py-src-variable">IFingerSetterService</span>,
 
1031
                           <span class="py-src-variable">IFingerSetterFactory</span>)
 
1032
 
 
1033
<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>):
 
1034
 
 
1035
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">connectionMade</span>():
 
1036
        <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>
 
1037
        <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>)
 
1038
 
 
1039
    <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>):
 
1040
        <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>]
 
1041
        <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>():
 
1042
            <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>)
 
1043
            <span class="py-src-variable">d</span>.<span class="py-src-variable">addErrback</span>(<span class="py-src-variable">catchError</span>)
 
1044
            <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>))
 
1045
            <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>))
 
1046
 
 
1047
 
 
1048
<span class="py-src-keyword">class</span> <span class="py-src-identifier">IIRCClientFactory</span>(<span class="py-src-parameter">Interface</span>):
 
1049
 
 
1050
    <span class="py-src-string">&quot;&quot;&quot;
 
1051
    @ivar nickname
 
1052
    &quot;&quot;&quot;</span>
 
1053
 
 
1054
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUser</span>(<span class="py-src-parameter">user</span>):
 
1055
        <span class="py-src-string">&quot;&quot;&quot;Return a deferred returning a string&quot;&quot;&quot;</span>
 
1056
 
 
1057
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">buildProtocol</span>(<span class="py-src-parameter">addr</span>):
 
1058
        <span class="py-src-string">&quot;&quot;&quot;Return a protocol&quot;&quot;&quot;</span>
 
1059
 
 
1060
 
 
1061
<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>):
 
1062
 
 
1063
    <span class="py-src-variable">implements</span>(<span class="py-src-variable">IIRCClientFactory</span>)
 
1064
 
 
1065
    <span class="py-src-variable">protocol</span> = <span class="py-src-variable">IRCReplyBot</span>
 
1066
    <span class="py-src-variable">nickname</span> = <span class="py-src-variable">None</span>
 
1067
 
 
1068
    <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>):
 
1069
        <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>
 
1070
 
 
1071
    <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>):
 
1072
        <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>)
 
1073
 
 
1074
<span class="py-src-variable">components</span>.<span class="py-src-variable">registerAdapter</span>(<span class="py-src-variable">IRCClientFactoryFromService</span>,
 
1075
                           <span class="py-src-variable">IFingerService</span>,
 
1076
                           <span class="py-src-variable">IIRCClientFactory</span>)
 
1077
 
 
1078
<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>):
 
1079
 
 
1080
    <span class="py-src-variable">implements</span>(<span class="py-src-variable">resource</span>.<span class="py-src-variable">IResource</span>)
 
1081
 
 
1082
    <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>):
 
1083
        <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>)
 
1084
        <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>
 
1085
        <span class="py-src-variable">self</span>.<span class="py-src-variable">putChild</span>(<span class="py-src-string">'RPC2'</span>, <span class="py-src-variable">UserStatusXR</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">service</span>))
 
1086
 
 
1087
    <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>):
 
1088
        <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>()
 
1089
        <span class="py-src-keyword">def</span> <span class="py-src-identifier">formatUsers</span>(<span class="py-src-parameter">users</span>):
 
1090
            <span class="py-src-variable">l</span> = [<span class="py-src-string">'&lt;li&gt;&lt;a href=&quot;%s&quot;&gt;%s&lt;/a&gt;&lt;/li&gt;'</span> % (<span class="py-src-variable">user</span>, <span class="py-src-variable">user</span>)
 
1091
                 <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>]
 
1092
            <span class="py-src-keyword">return</span> <span class="py-src-string">'&lt;ul&gt;'</span>+<span class="py-src-string">''</span>.<span class="py-src-variable">join</span>(<span class="py-src-variable">l</span>)+<span class="py-src-string">'&lt;/ul&gt;'</span>
 
1093
        <span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">formatUsers</span>)
 
1094
        <span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">request</span>.<span class="py-src-variable">write</span>)
 
1095
        <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">_</span>: <span class="py-src-variable">request</span>.<span class="py-src-variable">finish</span>())
 
1096
        <span class="py-src-keyword">return</span> <span class="py-src-variable">server</span>.<span class="py-src-variable">NOT_DONE_YET</span>
 
1097
 
 
1098
    <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>):
 
1099
        <span class="py-src-keyword">if</span> <span class="py-src-variable">path</span>==<span class="py-src-string">&quot;&quot;</span>:
 
1100
            <span class="py-src-keyword">return</span> <span class="py-src-variable">UserStatusTree</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">service</span>)
 
1101
        <span class="py-src-keyword">else</span>:
 
1102
            <span class="py-src-keyword">return</span> <span class="py-src-variable">UserStatus</span>(<span class="py-src-variable">path</span>, <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span>)
 
1103
 
 
1104
<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>,
 
1105
                           <span class="py-src-variable">resource</span>.<span class="py-src-variable">IResource</span>)
 
1106
 
 
1107
<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>):
 
1108
 
 
1109
    <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>):
 
1110
        <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>)
 
1111
        <span class="py-src-variable">self</span>.<span class="py-src-variable">user</span> = <span class="py-src-variable">user</span>
 
1112
        <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>
 
1113
 
 
1114
    <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>):
 
1115
        <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>)
 
1116
        <span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">cgi</span>.<span class="py-src-variable">escape</span>)
 
1117
        <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>:
 
1118
                      <span class="py-src-string">'&lt;h1&gt;%s&lt;/h1&gt;'</span>%<span class="py-src-variable">self</span>.<span class="py-src-variable">user</span>+<span class="py-src-string">'&lt;p&gt;%s&lt;/p&gt;'</span>%<span class="py-src-variable">m</span>)
 
1119
        <span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">request</span>.<span class="py-src-variable">write</span>)
 
1120
        <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">_</span>: <span class="py-src-variable">request</span>.<span class="py-src-variable">finish</span>())
 
1121
        <span class="py-src-keyword">return</span> <span class="py-src-variable">server</span>.<span class="py-src-variable">NOT_DONE_YET</span>
 
1122
 
 
1123
 
 
1124
<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>):
 
1125
 
 
1126
    <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>):
 
1127
        <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>)
 
1128
        <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>
 
1129
 
 
1130
    <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>):
 
1131
        <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>)
 
1132
 
 
1133
 
 
1134
<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>):
 
1135
 
 
1136
    <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerService</span>)
 
1137
 
 
1138
    <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>):
 
1139
        <span class="py-src-variable">self</span>.<span class="py-src-variable">filename</span> = <span class="py-src-variable">filename</span>
 
1140
        <span class="py-src-variable">self</span>.<span class="py-src-variable">users</span> = {}
 
1141
        <span class="py-src-variable">self</span>.<span class="py-src-variable">_read</span>()
 
1142
 
 
1143
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">_read</span>(<span class="py-src-parameter">self</span>):
 
1144
        <span class="py-src-variable">self</span>.<span class="py-src-variable">users</span>.<span class="py-src-variable">clear</span>()
 
1145
        <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>):
 
1146
            <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>)
 
1147
            <span class="py-src-variable">user</span> = <span class="py-src-variable">user</span>.<span class="py-src-variable">strip</span>()
 
1148
            <span class="py-src-variable">status</span> = <span class="py-src-variable">status</span>.<span class="py-src-variable">strip</span>()
 
1149
            <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>
 
1150
        <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>)
 
1151
 
 
1152
    <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>):
 
1153
        <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>))
 
1154
 
 
1155
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUsers</span>(<span class="py-src-parameter">self</span>):
 
1156
        <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>())
 
1157
 
 
1158
<span class="py-src-comment"># Yet another back-end</span>
 
1159
 
 
1160
<span class="py-src-keyword">class</span> <span class="py-src-identifier">LocalFingerService</span>(<span class="py-src-parameter">service</span>.<span class="py-src-parameter">Service</span>):
 
1161
 
 
1162
    <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerService</span>)
 
1163
 
 
1164
    <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>):
 
1165
        <span class="py-src-variable">user</span> = <span class="py-src-variable">user</span>.<span class="py-src-variable">strip</span>()
 
1166
        <span class="py-src-keyword">try</span>:
 
1167
            <span class="py-src-variable">entry</span> = <span class="py-src-variable">pwd</span>.<span class="py-src-variable">getpwnam</span>(<span class="py-src-variable">user</span>)
 
1168
        <span class="py-src-keyword">except</span> <span class="py-src-variable">KeyError</span>:
 
1169
            <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-string">&quot;No such user&quot;</span>)
 
1170
        <span class="py-src-keyword">try</span>:
 
1171
            <span class="py-src-variable">f</span> = <span class="py-src-variable">file</span>(<span class="py-src-variable">os</span>.<span class="py-src-variable">path</span>.<span class="py-src-variable">join</span>(<span class="py-src-variable">entry</span>[<span class="py-src-number">5</span>],<span class="py-src-string">'.plan'</span>))
 
1172
        <span class="py-src-keyword">except</span> (<span class="py-src-variable">IOError</span>, <span class="py-src-variable">OSError</span>):
 
1173
            <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-string">&quot;No such user&quot;</span>)
 
1174
        <span class="py-src-variable">data</span> = <span class="py-src-variable">f</span>.<span class="py-src-variable">read</span>()
 
1175
        <span class="py-src-variable">data</span> = <span class="py-src-variable">data</span>.<span class="py-src-variable">strip</span>()
 
1176
        <span class="py-src-variable">f</span>.<span class="py-src-variable">close</span>()
 
1177
        <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">data</span>)
 
1178
 
 
1179
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUsers</span>(<span class="py-src-parameter">self</span>):
 
1180
        <span class="py-src-keyword">return</span> <span class="py-src-variable">defer</span>.<span class="py-src-variable">succeed</span>([])
 
1181
 
 
1182
 
 
1183
<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>)
 
1184
<span class="py-src-variable">f</span> = <span class="py-src-variable">LocalFingerService</span>()
 
1185
<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>)
 
1186
<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>)
 
1187
                   ).<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">serviceCollection</span>)
 
1188
<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>))
 
1189
                   ).<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">serviceCollection</span>)
 
1190
<span class="py-src-variable">i</span> = <span class="py-src-variable">IIRCClientFactory</span>(<span class="py-src-variable">f</span>)
 
1191
<span class="py-src-variable">i</span>.<span class="py-src-variable">nickname</span> = <span class="py-src-string">'fingerbot'</span>
 
1192
<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>
 
1193
                   ).<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">serviceCollection</span>)
 
1194
</pre><div class="caption">Source listing - <a href="listings/finger/finger19c.tac"><span class="filename">listings/finger/finger19c.tac</span></a></div></div>
 
1195
</p>
 
1196
 
 
1197
<p>Not much to say except that now we
 
1198
can be churn out backends like crazy. Feel like doing a back-end
 
1199
for Advogato, for example? Dig out the XML-RPC client support Twisted
 
1200
has, and get to work!</p>
 
1201
 
 
1202
</div>
 
1203
 
 
1204
    <p><a href="../index.html">Index</a></p>
 
1205
    <span class="version">Version: 10.0.0</span>
 
1206
  </body>
 
1207
</html>
 
 
b'\\ No newline at end of file'