Initial import to Tizen
[profile/ivi/python-twisted.git] / doc / core / howto / tutorial / configuration.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: configuration and packaging of the finger service</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: configuration and packaging of the finger service</h1>
9     <div class="toc"><ol><li><a href="#auto0">Introduction</a></li><li><a href="#auto1">Plugins</a></li><li><a href="#auto2">OS Integration</a></li><ul><li><a href="#auto3">Debian</a></li><li><a href="#auto4">Red Hat / Mandrake</a></li></ul></ol></div>
10     <div class="content">
11
12 <span/>
13
14 <h2>Introduction<a name="auto0"/></h2>
15
16 <p> This is the eleventh 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 make it easier for non-programmers to configure a finger
19 server and show how to package it in the .deb and RPM package formats. Plugins
20 are discussed further in the <a href="../plugin.html" shape="rect">Twisted Plugin System</a>
21 howto. Writing twistd plugins is covered in <a href="../tap.html" shape="rect">Writing a
22 twistd Plugin</a>, and .tac applications are covered in <a href="../application.html" shape="rect">Using the Twisted Application Framework</a>.</p>
23
24 <h2>Plugins<a name="auto1"/></h2>
25
26 <p>So far, the user had to be somewhat of a programmer to be able to configure
27 stuff. Maybe we can eliminate even that? Move old code
28 to <code>finger/__init__.py</code> and...</p>
29 <p>
30 Full source code for finger module here: <div class="py-listing"><pre><p class="py-linenumber">  1
31   2
32   3
33   4
34   5
35   6
36   7
37   8
38   9
39  10
40  11
41  12
42  13
43  14
44  15
45  16
46  17
47  18
48  19
49  20
50  21
51  22
52  23
53  24
54  25
55  26
56  27
57  28
58  29
59  30
60  31
61  32
62  33
63  34
64  35
65  36
66  37
67  38
68  39
69  40
70  41
71  42
72  43
73  44
74  45
75  46
76  47
77  48
78  49
79  50
80  51
81  52
82  53
83  54
84  55
85  56
86  57
87  58
88  59
89  60
90  61
91  62
92  63
93  64
94  65
95  66
96  67
97  68
98  69
99  70
100  71
101  72
102  73
103  74
104  75
105  76
106  77
107  78
108  79
109  80
110  81
111  82
112  83
113  84
114  85
115  86
116  87
117  88
118  89
119  90
120  91
121  92
122  93
123  94
124  95
125  96
126  97
127  98
128  99
129 100
130 101
131 102
132 103
133 104
134 105
135 106
136 107
137 108
138 109
139 110
140 111
141 112
142 113
143 114
144 115
145 116
146 117
147 118
148 119
149 120
150 121
151 122
152 123
153 124
154 125
155 126
156 127
157 128
158 129
159 130
160 131
161 132
162 133
163 134
164 135
165 136
166 137
167 138
168 139
169 140
170 141
171 142
172 143
173 144
174 145
175 146
176 147
177 148
178 149
179 150
180 151
181 152
182 153
183 154
184 155
185 156
186 157
187 158
188 159
189 160
190 161
191 162
192 163
193 164
194 165
195 166
196 167
197 168
198 169
199 170
200 171
201 172
202 173
203 174
204 175
205 176
206 177
207 178
208 179
209 180
210 181
211 182
212 183
213 184
214 185
215 186
216 187
217 188
218 189
219 190
220 191
221 192
222 193
223 194
224 195
225 196
226 197
227 198
228 199
229 200
230 201
231 202
232 203
233 204
234 205
235 206
236 207
237 208
238 209
239 210
240 211
241 212
242 213
243 214
244 215
245 216
246 217
247 218
248 219
249 220
250 221
251 222
252 223
253 224
254 225
255 226
256 227
257 228
258 229
259 230
260 231
261 232
262 233
263 234
264 235
265 236
266 237
267 238
268 239
269 240
270 241
271 242
272 243
273 244
274 245
275 246
276 247
277 248
278 249
279 250
280 251
281 252
282 253
283 254
284 255
285 256
286 257
287 258
288 259
289 260
290 261
291 262
292 263
293 264
294 265
295 266
296 267
297 268
298 269
299 270
300 271
301 272
302 273
303 274
304 275
305 276
306 277
307 278
308 279
309 280
310 281
311 282
312 283
313 284
314 285
315 286
316 287
317 288
318 289
319 290
320 291
321 292
322 293
323 294
324 295
325 296
326 297
327 298
328 299
329 300
330 301
331 302
332 303
333 304
334 305
335 306
336 307
337 308
338 309
339 310
340 311
341 312
342 313
343 314
344 315
345 316
346 317
347 318
348 319
349 320
350 321
351 322
352 323
353 324
354 325
355 326
356 327
357 328
358 329
359 330
360 331
361 332
362 333
363 334
364 335
365 336
366 337
367 338
368 339
369 340
370 341
371 342
372 343
373 344
374 345
375 346
376 347
377 348
378 349
379 350
380 351
381 352
382 353
383 354
384 355
385 356
386 357
387 358
388 359
389 360
390 361
391 362
392 363
393 364
394 365
395 366
396 367
397 368
398 </p><span class="py-src-comment"># finger.py module</span>
399
400 <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>
401
402 <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>
403 <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>
404 <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>
405 <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>
406 <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>, <span class="py-src-variable">log</span>
407 <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">xmlrpc</span>
408 <span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">spread</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">pb</span>
409
410 <span class="py-src-keyword">from</span> <span class="py-src-variable">OpenSSL</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">SSL</span>
411
412 <span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerService</span>(<span class="py-src-parameter">Interface</span>):
413
414     <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUser</span>(<span class="py-src-parameter">user</span>):
415         <span class="py-src-string">&quot;&quot;&quot;
416         Return a deferred returning a string.
417         &quot;&quot;&quot;</span>
418
419     <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUsers</span>():
420         <span class="py-src-string">&quot;&quot;&quot;
421         Return a deferred returning a list of strings.
422         &quot;&quot;&quot;</span>
423
424
425 <span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerSetterService</span>(<span class="py-src-parameter">Interface</span>):
426
427     <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>):
428         <span class="py-src-string">&quot;&quot;&quot;
429         Set the user's status to something.
430         &quot;&quot;&quot;</span>
431
432
433 <span class="py-src-keyword">def</span> <span class="py-src-identifier">catchError</span>(<span class="py-src-parameter">err</span>):
434     <span class="py-src-keyword">return</span> <span class="py-src-string">&quot;Internal error in server&quot;</span>
435
436
437 <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>):
438
439     <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>):
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">user</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-keyword">def</span> <span class="py-src-identifier">writeValue</span>(<span class="py-src-parameter">value</span>):
443             <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">'\n'</span>)
444             <span class="py-src-variable">self</span>.<span class="py-src-variable">transport</span>.<span class="py-src-variable">loseConnection</span>()
445         <span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">writeValue</span>)
446
447
448 <span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerFactory</span>(<span class="py-src-parameter">Interface</span>):
449
450     <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUser</span>(<span class="py-src-parameter">user</span>):
451         <span class="py-src-string">&quot;&quot;&quot;
452         Return a deferred returning a string.
453         &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;
457         Return a protocol returning a string.
458         &quot;&quot;&quot;</span>
459
460
461 <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>):
462     <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerFactory</span>)
463
464     <span class="py-src-variable">protocol</span> = <span class="py-src-variable">FingerProtocol</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">FingerFactoryFromService</span>,
473                            <span class="py-src-variable">IFingerService</span>,
474                            <span class="py-src-variable">IFingerFactory</span>)
475
476
477 <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>):
478
479     <span class="py-src-keyword">def</span> <span class="py-src-identifier">connectionMade</span>(<span class="py-src-parameter">self</span>):
480         <span class="py-src-variable">self</span>.<span class="py-src-variable">lines</span> = []
481
482     <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>):
483         <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>)
484
485     <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>):
486         <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>:
487             <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>)
488
489
490 <span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerSetterFactory</span>(<span class="py-src-parameter">Interface</span>):
491
492     <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>):
493         <span class="py-src-string">&quot;&quot;&quot;
494         Return a deferred returning a string.
495         &quot;&quot;&quot;</span>
496
497     <span class="py-src-keyword">def</span> <span class="py-src-identifier">buildProtocol</span>(<span class="py-src-parameter">addr</span>):
498         <span class="py-src-string">&quot;&quot;&quot;
499         Return a protocol returning a string.
500         &quot;&quot;&quot;</span>
501
502
503 <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>):
504
505     <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerSetterFactory</span>)
506
507     <span class="py-src-variable">protocol</span> = <span class="py-src-variable">FingerSetterProtocol</span>
508
509     <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>):
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">setUser</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">user</span>, <span class="py-src-parameter">status</span>):
513         <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>)
514
515
516 <span class="py-src-variable">components</span>.<span class="py-src-variable">registerAdapter</span>(<span class="py-src-variable">FingerSetterFactoryFromService</span>,
517                            <span class="py-src-variable">IFingerSetterService</span>,
518                            <span class="py-src-variable">IFingerSetterFactory</span>)
519
520
521 <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>):
522
523     <span class="py-src-keyword">def</span> <span class="py-src-identifier">connectionMade</span>(<span class="py-src-parameter">self</span>):
524         <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>
525         <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>)
526
527     <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>):
528         <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>]
529         <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>():
530             <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>)
531             <span class="py-src-variable">d</span>.<span class="py-src-variable">addErrback</span>(<span class="py-src-variable">catchError</span>)
532             <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>))
533             <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>))
534
535
536 <span class="py-src-keyword">class</span> <span class="py-src-identifier">IIRCClientFactory</span>(<span class="py-src-parameter">Interface</span>):
537
538     <span class="py-src-string">&quot;&quot;&quot;
539     @ivar nickname
540     &quot;&quot;&quot;</span>
541
542     <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUser</span>(<span class="py-src-parameter">user</span>):
543         <span class="py-src-string">&quot;&quot;&quot;
544         Return a deferred returning a string.
545         &quot;&quot;&quot;</span>
546
547     <span class="py-src-keyword">def</span> <span class="py-src-identifier">buildProtocol</span>(<span class="py-src-parameter">addr</span>):
548         <span class="py-src-string">&quot;&quot;&quot;
549         Return a protocol.
550         &quot;&quot;&quot;</span>
551
552
553 <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>):
554
555     <span class="py-src-variable">implements</span>(<span class="py-src-variable">IIRCClientFactory</span>)
556
557     <span class="py-src-variable">protocol</span> = <span class="py-src-variable">IRCReplyBot</span>
558     <span class="py-src-variable">nickname</span> = <span class="py-src-variable">None</span>
559
560     <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>):
561         <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>
562
563     <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>):
564         <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>)
565
566 <span class="py-src-variable">components</span>.<span class="py-src-variable">registerAdapter</span>(<span class="py-src-variable">IRCClientFactoryFromService</span>,
567                            <span class="py-src-variable">IFingerService</span>,
568                            <span class="py-src-variable">IIRCClientFactory</span>)
569
570
571 <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>):
572
573     <span class="py-src-variable">template</span> = <span class="py-src-string">&quot;&quot;&quot;&lt;html&gt;&lt;head&gt;&lt;title&gt;Users&lt;/title&gt;&lt;/head&gt;&lt;body&gt;
574     &lt;h1&gt;Users&lt;/h1&gt;
575     &lt;ul&gt;
576     %(users)s
577     &lt;/ul&gt;
578     &lt;/body&gt;
579     &lt;/html&gt;&quot;&quot;&quot;</span>
580
581     <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>):
582         <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>)
583         <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>
584
585     <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>):
586         <span class="py-src-keyword">if</span> <span class="py-src-variable">path</span> == <span class="py-src-string">''</span>:
587             <span class="py-src-keyword">return</span> <span class="py-src-variable">self</span>
588         <span class="py-src-keyword">elif</span> <span class="py-src-variable">path</span> == <span class="py-src-string">'RPC2'</span>:
589             <span class="py-src-keyword">return</span> <span class="py-src-variable">UserStatusXR</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">service</span>)
590         <span class="py-src-keyword">else</span>:
591             <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>)
592
593     <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>):
594         <span class="py-src-variable">users</span> = <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span>.<span class="py-src-variable">getUsers</span>()
595         <span class="py-src-keyword">def</span> <span class="py-src-identifier">cbUsers</span>(<span class="py-src-parameter">users</span>):
596             <span class="py-src-variable">request</span>.<span class="py-src-variable">write</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">template</span> % {<span class="py-src-string">'users'</span>: <span class="py-src-string">''</span>.<span class="py-src-variable">join</span>([
597                     <span class="py-src-comment"># Name should be quoted properly these uses.</span>
598                     <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">name</span>, <span class="py-src-variable">name</span>)
599                     <span class="py-src-keyword">for</span> <span class="py-src-variable">name</span> <span class="py-src-keyword">in</span> <span class="py-src-variable">users</span>])})
600             <span class="py-src-variable">request</span>.<span class="py-src-variable">finish</span>()
601         <span class="py-src-variable">users</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">cbUsers</span>)
602         <span class="py-src-keyword">def</span> <span class="py-src-identifier">ebUsers</span>(<span class="py-src-parameter">err</span>):
603             <span class="py-src-variable">log</span>.<span class="py-src-variable">err</span>(<span class="py-src-variable">err</span>, <span class="py-src-string">&quot;UserStatusTree failed&quot;</span>)
604             <span class="py-src-variable">request</span>.<span class="py-src-variable">finish</span>()
605         <span class="py-src-variable">users</span>.<span class="py-src-variable">addErrback</span>(<span class="py-src-variable">ebUsers</span>)
606         <span class="py-src-keyword">return</span> <span class="py-src-variable">server</span>.<span class="py-src-variable">NOT_DONE_YET</span>
607
608 <span class="py-src-variable">components</span>.<span class="py-src-variable">registerAdapter</span>(<span class="py-src-variable">UserStatusTree</span>, <span class="py-src-variable">IFingerService</span>, <span class="py-src-variable">resource</span>.<span class="py-src-variable">IResource</span>)
609
610
611 <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>):
612
613     <span class="py-src-variable">template</span>=<span class="py-src-string">'''&lt;html&gt;&lt;head&gt;&lt;title&gt;%(title)s&lt;/title&gt;&lt;/head&gt;
614     &lt;body&gt;&lt;h1&gt;%(name)s&lt;/h1&gt;&lt;p&gt;%(status)s&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;'''</span>
615
616     <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>):
617         <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>)
618         <span class="py-src-variable">self</span>.<span class="py-src-variable">user</span> = <span class="py-src-variable">user</span>
619         <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>
620
621     <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>):
622         <span class="py-src-variable">status</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>)
623         <span class="py-src-keyword">def</span> <span class="py-src-identifier">cbStatus</span>(<span class="py-src-parameter">status</span>):
624             <span class="py-src-variable">request</span>.<span class="py-src-variable">write</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">template</span> % {
625                 <span class="py-src-string">'title'</span>: <span class="py-src-variable">self</span>.<span class="py-src-variable">user</span>,
626                 <span class="py-src-string">'name'</span>: <span class="py-src-variable">self</span>.<span class="py-src-variable">user</span>,
627                 <span class="py-src-string">'status'</span>: <span class="py-src-variable">status</span>})
628             <span class="py-src-variable">request</span>.<span class="py-src-variable">finish</span>()
629         <span class="py-src-variable">status</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">cbStatus</span>)
630         <span class="py-src-keyword">def</span> <span class="py-src-identifier">ebStatus</span>(<span class="py-src-parameter">err</span>):
631             <span class="py-src-variable">log</span>.<span class="py-src-variable">err</span>(<span class="py-src-variable">err</span>, <span class="py-src-string">&quot;UserStatus failed&quot;</span>)
632             <span class="py-src-variable">request</span>.<span class="py-src-variable">finish</span>()
633         <span class="py-src-variable">status</span>.<span class="py-src-variable">addErrback</span>(<span class="py-src-variable">ebStatus</span>)
634         <span class="py-src-keyword">return</span> <span class="py-src-variable">server</span>.<span class="py-src-variable">NOT_DONE_YET</span>
635
636
637 <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>):
638
639     <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>):
640         <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>)
641         <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>
642
643     <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>):
644         <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>)
645
646     <span class="py-src-keyword">def</span> <span class="py-src-identifier">xmlrpc_getUsers</span>(<span class="py-src-parameter">self</span>):
647         <span class="py-src-keyword">return</span> <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span>.<span class="py-src-variable">getUsers</span>()
648
649
650 <span class="py-src-keyword">class</span> <span class="py-src-identifier">IPerspectiveFinger</span>(<span class="py-src-parameter">Interface</span>):
651
652     <span class="py-src-keyword">def</span> <span class="py-src-identifier">remote_getUser</span>(<span class="py-src-parameter">username</span>):
653         <span class="py-src-string">&quot;&quot;&quot;
654         Return a user's status.
655         &quot;&quot;&quot;</span>
656
657     <span class="py-src-keyword">def</span> <span class="py-src-identifier">remote_getUsers</span>():
658         <span class="py-src-string">&quot;&quot;&quot;
659         Return a user's status.
660         &quot;&quot;&quot;</span>
661
662
663 <span class="py-src-keyword">class</span> <span class="py-src-identifier">PerspectiveFingerFromService</span>(<span class="py-src-parameter">pb</span>.<span class="py-src-parameter">Root</span>):
664
665     <span class="py-src-variable">implements</span>(<span class="py-src-variable">IPerspectiveFinger</span>)
666
667     <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>):
668         <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>
669
670     <span class="py-src-keyword">def</span> <span class="py-src-identifier">remote_getUser</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">username</span>):
671         <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">username</span>)
672
673     <span class="py-src-keyword">def</span> <span class="py-src-identifier">remote_getUsers</span>(<span class="py-src-parameter">self</span>):
674         <span class="py-src-keyword">return</span> <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span>.<span class="py-src-variable">getUsers</span>()
675
676 <span class="py-src-variable">components</span>.<span class="py-src-variable">registerAdapter</span>(<span class="py-src-variable">PerspectiveFingerFromService</span>,
677                            <span class="py-src-variable">IFingerService</span>,
678                            <span class="py-src-variable">IPerspectiveFinger</span>)
679
680
681 <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>):
682
683     <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerService</span>)
684
685     <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>):
686         <span class="py-src-variable">self</span>.<span class="py-src-variable">filename</span> = <span class="py-src-variable">filename</span>
687
688     <span class="py-src-keyword">def</span> <span class="py-src-identifier">_read</span>(<span class="py-src-parameter">self</span>):
689         <span class="py-src-variable">self</span>.<span class="py-src-variable">users</span> = {}
690         <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>):
691             <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>)
692             <span class="py-src-variable">user</span> = <span class="py-src-variable">user</span>.<span class="py-src-variable">strip</span>()
693             <span class="py-src-variable">status</span> = <span class="py-src-variable">status</span>.<span class="py-src-variable">strip</span>()
694             <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>
695         <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>)
696
697     <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>):
698         <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>))
699
700     <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUsers</span>(<span class="py-src-parameter">self</span>):
701         <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>())
702
703     <span class="py-src-keyword">def</span> <span class="py-src-identifier">startService</span>(<span class="py-src-parameter">self</span>):
704         <span class="py-src-variable">self</span>.<span class="py-src-variable">_read</span>()
705         <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>)
706
707     <span class="py-src-keyword">def</span> <span class="py-src-identifier">stopService</span>(<span class="py-src-parameter">self</span>):
708         <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>)
709         <span class="py-src-variable">self</span>.<span class="py-src-variable">call</span>.<span class="py-src-variable">cancel</span>()
710
711
712 <span class="py-src-keyword">class</span> <span class="py-src-identifier">ServerContextFactory</span>:
713
714     <span class="py-src-keyword">def</span> <span class="py-src-identifier">getContext</span>(<span class="py-src-parameter">self</span>):
715         <span class="py-src-string">&quot;&quot;&quot;
716         Create an SSL context.
717
718         This is a sample implementation that loads a certificate from a file
719         called 'server.pem'.
720         &quot;&quot;&quot;</span>
721         <span class="py-src-variable">ctx</span> = <span class="py-src-variable">SSL</span>.<span class="py-src-variable">Context</span>(<span class="py-src-variable">SSL</span>.<span class="py-src-variable">SSLv23_METHOD</span>)
722         <span class="py-src-variable">ctx</span>.<span class="py-src-variable">use_certificate_file</span>(<span class="py-src-string">'server.pem'</span>)
723         <span class="py-src-variable">ctx</span>.<span class="py-src-variable">use_privatekey_file</span>(<span class="py-src-string">'server.pem'</span>)
724         <span class="py-src-keyword">return</span> <span class="py-src-variable">ctx</span>
725
726
727
728 <span class="py-src-comment"># Easy configuration</span>
729
730 <span class="py-src-keyword">def</span> <span class="py-src-identifier">makeService</span>(<span class="py-src-parameter">config</span>):
731     <span class="py-src-comment"># finger on port 79</span>
732     <span class="py-src-variable">s</span> = <span class="py-src-variable">service</span>.<span class="py-src-variable">MultiService</span>()
733     <span class="py-src-variable">f</span> = <span class="py-src-variable">FingerService</span>(<span class="py-src-variable">config</span>[<span class="py-src-string">'file'</span>])
734     <span class="py-src-variable">h</span> = <span class="py-src-variable">internet</span>.<span class="py-src-variable">TCPServer</span>(<span class="py-src-number">1079</span>, <span class="py-src-variable">IFingerFactory</span>(<span class="py-src-variable">f</span>))
735     <span class="py-src-variable">h</span>.<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">s</span>)
736
737
738     <span class="py-src-comment"># website on port 8000</span>
739     <span class="py-src-variable">r</span> = <span class="py-src-variable">resource</span>.<span class="py-src-variable">IResource</span>(<span class="py-src-variable">f</span>)
740     <span class="py-src-variable">r</span>.<span class="py-src-variable">templateDirectory</span> = <span class="py-src-variable">config</span>[<span class="py-src-string">'templates'</span>]
741     <span class="py-src-variable">site</span> = <span class="py-src-variable">server</span>.<span class="py-src-variable">Site</span>(<span class="py-src-variable">r</span>)
742     <span class="py-src-variable">j</span> = <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">site</span>)
743     <span class="py-src-variable">j</span>.<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">s</span>)
744
745     <span class="py-src-comment"># ssl on port 443</span>
746 <span class="py-src-comment">#    if config.get('ssl'):</span>
747 <span class="py-src-comment">#        k = internet.SSLServer(443, site, ServerContextFactory())</span>
748 <span class="py-src-comment">#        k.setServiceParent(s)</span>
749
750     <span class="py-src-comment"># irc fingerbot</span>
751     <span class="py-src-keyword">if</span> <span class="py-src-variable">config</span>.<span class="py-src-variable">has_key</span>(<span class="py-src-string">'ircnick'</span>):
752         <span class="py-src-variable">i</span> = <span class="py-src-variable">IIRCClientFactory</span>(<span class="py-src-variable">f</span>)
753         <span class="py-src-variable">i</span>.<span class="py-src-variable">nickname</span> = <span class="py-src-variable">config</span>[<span class="py-src-string">'ircnick'</span>]
754         <span class="py-src-variable">ircserver</span> = <span class="py-src-variable">config</span>[<span class="py-src-string">'ircserver'</span>]
755         <span class="py-src-variable">b</span> = <span class="py-src-variable">internet</span>.<span class="py-src-variable">TCPClient</span>(<span class="py-src-variable">ircserver</span>, <span class="py-src-number">6667</span>, <span class="py-src-variable">i</span>)
756         <span class="py-src-variable">b</span>.<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">s</span>)
757
758     <span class="py-src-comment"># Pespective Broker on port 8889</span>
759     <span class="py-src-keyword">if</span> <span class="py-src-variable">config</span>.<span class="py-src-variable">has_key</span>(<span class="py-src-string">'pbport'</span>):
760         <span class="py-src-variable">m</span> = <span class="py-src-variable">internet</span>.<span class="py-src-variable">TCPServer</span>(
761             <span class="py-src-variable">int</span>(<span class="py-src-variable">config</span>[<span class="py-src-string">'pbport'</span>]),
762             <span class="py-src-variable">pb</span>.<span class="py-src-variable">PBServerFactory</span>(<span class="py-src-variable">IPerspectiveFinger</span>(<span class="py-src-variable">f</span>)))
763         <span class="py-src-variable">m</span>.<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">s</span>)
764
765     <span class="py-src-keyword">return</span> <span class="py-src-variable">s</span>
766 </pre><div class="caption">finger module - <a href="listings/finger/finger/finger.py"><span class="filename">listings/finger/finger/finger.py</span></a></div></div>
767 </p>
768
769 <div class="py-listing"><pre><p class="py-linenumber"> 1
770  2
771  3
772  4
773  5
774  6
775  7
776  8
777  9
778 10
779 11
780 12
781 13
782 14
783 15
784 16
785 17
786 18
787 19
788 20
789 </p><span class="py-src-comment"># finger/tap.py</span>
790 <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>
791 <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">interfaces</span>
792 <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">usage</span>
793 <span class="py-src-keyword">import</span> <span class="py-src-variable">finger</span>
794
795 <span class="py-src-keyword">class</span> <span class="py-src-identifier">Options</span>(<span class="py-src-parameter">usage</span>.<span class="py-src-parameter">Options</span>):
796
797     <span class="py-src-variable">optParameters</span> = [
798         [<span class="py-src-string">'file'</span>, <span class="py-src-string">'f'</span>, <span class="py-src-string">'/etc/users'</span>],
799         [<span class="py-src-string">'templates'</span>, <span class="py-src-string">'t'</span>, <span class="py-src-string">'/usr/share/finger/templates'</span>],
800         [<span class="py-src-string">'ircnick'</span>, <span class="py-src-string">'n'</span>, <span class="py-src-string">'fingerbot'</span>],
801         [<span class="py-src-string">'ircserver'</span>, <span class="py-src-variable">None</span>, <span class="py-src-string">'irc.freenode.net'</span>],
802         [<span class="py-src-string">'pbport'</span>, <span class="py-src-string">'p'</span>, <span class="py-src-number">8889</span>],
803         ]
804
805     <span class="py-src-variable">optFlags</span> = [[<span class="py-src-string">'ssl'</span>, <span class="py-src-string">'s'</span>]]
806
807 <span class="py-src-keyword">def</span> <span class="py-src-identifier">makeService</span>(<span class="py-src-parameter">config</span>):
808     <span class="py-src-keyword">return</span> <span class="py-src-variable">finger</span>.<span class="py-src-variable">makeService</span>(<span class="py-src-variable">config</span>)
809 </pre><div class="caption">finger/tap.py - <a href="listings/finger/finger/tap.py"><span class="filename">listings/finger/finger/tap.py</span></a></div></div>
810
811 <p>And register it all:</p>
812
813 <div class="py-listing"><pre><p class="py-linenumber">1
814 2
815 3
816 4
817 5
818 </p><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-variable">service</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">ServiceMaker</span>
819
820 <span class="py-src-variable">finger</span> = <span class="py-src-variable">ServiceMaker</span>(
821     <span class="py-src-string">'finger'</span>, <span class="py-src-string">'finger.tap'</span>, <span class="py-src-string">'Run a finger service'</span>, <span class="py-src-string">'finger'</span>)
822 </pre><div class="caption">
823 twisted/plugins/finger_tutorial.py
824  - <a href="listings/finger/twisted/plugins/finger_tutorial.py"><span class="filename">listings/finger/twisted/plugins/finger_tutorial.py</span></a></div></div>
825
826 <p>Note that the second argument to <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.application.service.ServiceMaker.html" title="twisted.application.service.ServiceMaker">ServiceMaker</a></code>,
827 <code>finger.tap</code>, is a reference to a module
828 (<code>finger/tap.py</code>), not to a filename.</p>
829
830 <p>And now, the following works</p>
831
832 <pre class="shell" xml:space="preserve">
833 % sudo twistd -n finger --file=/etc/users --ircnick=fingerbot
834 </pre>
835
836 <p>
837   For more details about this, see the <a href="../tap.html" shape="rect">twistd plugin
838   documentation</a>.
839 </p>
840
841 <h2>OS Integration<a name="auto2"/></h2>
842
843 <p>If we already have the <q>finger</q> package installed in
844  <code>PYTHONPATH</code> (e.g.  we added it to <code>site-packages</code>), we
845 can achieve easy integration:</p>
846
847 <h3>Debian<a name="auto3"/></h3>
848
849 <pre class="shell" xml:space="preserve">
850 % tap2deb --unsigned -m &quot;Foo &lt;foo@example.com&gt;&quot; --type=python finger.tac
851 % sudo dpkg -i .build/*.deb
852 </pre>
853
854 <h3>Red Hat / Mandrake<a name="auto4"/></h3>
855
856 <pre class="shell" xml:space="preserve">
857 % tap2rpm --type=python finger.tac
858 % sudo rpm -i *.rpm
859 </pre>
860
861 <p>These packages will properly install and register <code>init.d</code>
862 scripts, etc. for the given file.</p>
863
864 <p>If it doesn't work on your favorite OS: patches accepted!</p>
865 </div>
866
867     <p><a href="../index.html">Index</a></p>
868     <span class="version">Version: 12.1.0</span>
869   </body>
870 </html>