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