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">
3 <title>Twisted Documentation: The Evolution of Finger: pluggable backends</title>
4 <link href="../stylesheet.css" rel="stylesheet" type="text/css"/>
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>
14 <h2>Introduction<a name="auto0"/></h2>
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>
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>
26 <h2>Another Back-end<a name="auto1"/></h2>
28 <div class="py-listing"><pre><p class="py-linenumber"> 1
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>
50 <span class="py-src-comment"># Another back-end</span>
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>):
54 <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerService</span>)
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">"finger"</span>, [<span class="py-src-variable">user</span>])
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>([])
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>
67 Full source code here: <div class="py-listing"><pre><p class="py-linenumber"> 1
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>
370 <span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerService</span>(<span class="py-src-parameter">Interface</span>):
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">"""
374 Return a deferred returning a string.
375 """</span>
377 <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUsers</span>():
378 <span class="py-src-string">"""
379 Return a deferred returning a list of strings.
380 """</span>
383 <span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerSetterService</span>(<span class="py-src-parameter">Interface</span>):
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">"""
387 Set the user's status to something.
388 """</span>
391 <span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerSetterService</span>(<span class="py-src-parameter">Interface</span>):
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">"""
395 Set the user's status to something.
396 """</span>
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">"Internal error in server"</span>
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>):
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>)
414 <span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerFactory</span>(<span class="py-src-parameter">Interface</span>):
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">"""
418 Return a deferred returning a string.
419 """</span>
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">"""
423 Return a protocol returning a string.
424 """</span>
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>):
429 <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerFactory</span>)
431 <span class="py-src-variable">protocol</span> = <span class="py-src-variable">FingerProtocol</span>
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>
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>)
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>)
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>):
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> = []
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>)
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>)
457 <span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerSetterFactory</span>(<span class="py-src-parameter">Interface</span>):
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">"""
461 Return a deferred returning a string.
462 """</span>
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">"""
466 Return a protocol returning a string.
467 """</span>
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>):
472 <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerSetterFactory</span>)
474 <span class="py-src-variable">protocol</span> = <span class="py-src-variable">FingerSetterProtocol</span>
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>
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>)
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>)
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>):
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>)
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">"Status of %s: %s"</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>))
502 <span class="py-src-keyword">class</span> <span class="py-src-identifier">IIRCClientFactory</span>(<span class="py-src-parameter">Interface</span>):
504 <span class="py-src-string">"""
506 """</span>
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">"""
510 Return a deferred returning a string.
511 """</span>
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">"""
516 """</span>
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>):
521 <span class="py-src-variable">implements</span>(<span class="py-src-variable">IIRCClientFactory</span>)
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>
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>
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>)
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>)
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>):
539 <span class="py-src-variable">implements</span>(<span class="py-src-variable">resource</span>.<span class="py-src-variable">IResource</span>)
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>))
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">'<li><a href="%s">%s</a></li>'</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">'<ul>'</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">'</ul>'</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>
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">""</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>)
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>)
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>):
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>
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">'<h1>%s</h1>'</span>%<span class="py-src-variable">self</span>.<span class="py-src-variable">user</span>+<span class="py-src-string">'<p>%s</p>'</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>
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>):
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>
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>)
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>):
596 <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerService</span>)
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> = {}
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>)
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">"No such user"</span>))
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>())
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>)
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>()
626 <span class="py-src-comment"># Another back-end</span>
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>):
630 <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerService</span>)
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">"finger"</span>, [<span class="py-src-variable">user</span>])
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>([])
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>
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>
658 <h2>Yet Another Back-end: Doing the Standard Thing<a name="auto2"/></h2>
660 <div class="py-listing"><pre><p class="py-linenumber"> 1
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>
697 <span class="py-src-comment"># Yet another back-end</span>
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>):
701 <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerService</span>)
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">"No such user"</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">"No such user"</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>)
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>([])
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>
726 Full source code here: <div class="py-listing"><pre><p class="py-linenumber"> 1
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>
1043 <span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerService</span>(<span class="py-src-parameter">Interface</span>):
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">"""
1047 Return a deferred returning a string.
1048 """</span>
1050 <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUsers</span>():
1051 <span class="py-src-string">"""
1052 Return a deferred returning a list of strings.
1053 """</span>
1056 <span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerSetterService</span>(<span class="py-src-parameter">Interface</span>):
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">"""
1060 Set the user's status to something.
1061 """</span>
1064 <span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerSetterService</span>(<span class="py-src-parameter">Interface</span>):
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">"""
1068 Set the user's status to something.
1069 """</span>
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">"Internal error in server"</span>
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>):
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>)
1087 <span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerFactory</span>(<span class="py-src-parameter">Interface</span>):
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">"""
1091 Return a deferred returning a string.
1092 """</span>
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">"""
1096 Return a protocol returning a string.
1097 """</span>
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>):
1102 <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerFactory</span>)
1104 <span class="py-src-variable">protocol</span> = <span class="py-src-variable">FingerProtocol</span>
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>
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>)
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>)
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>):
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> = []
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>)
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>)
1130 <span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerSetterFactory</span>(<span class="py-src-parameter">Interface</span>):
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">"""
1134 Return a deferred returning a string.
1135 """</span>
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">"""
1139 Return a protocol returning a string.
1140 """</span>
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>):
1145 <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerSetterFactory</span>)
1147 <span class="py-src-variable">protocol</span> = <span class="py-src-variable">FingerSetterProtocol</span>
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>
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>)
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>)
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>):
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>)
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">"Status of %s: %s"</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>))
1176 <span class="py-src-keyword">class</span> <span class="py-src-identifier">IIRCClientFactory</span>(<span class="py-src-parameter">Interface</span>):
1178 <span class="py-src-string">"""
1180 """</span>
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">"""
1184 Return a deferred returning a string.
1185 """</span>
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">"""
1190 """</span>
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>):
1195 <span class="py-src-variable">implements</span>(<span class="py-src-variable">IIRCClientFactory</span>)
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>
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>
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>)
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>)
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>):
1213 <span class="py-src-variable">implements</span>(<span class="py-src-variable">resource</span>.<span class="py-src-variable">IResource</span>)
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>))
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">'<li><a href="%s">%s</a></li>'</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">'<ul>'</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">'</ul>'</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>
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">""</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>)
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>)
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>):
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>
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">'<h1>%s</h1>'</span>%<span class="py-src-variable">self</span>.<span class="py-src-variable">user</span>+<span class="py-src-string">'<p>%s</p>'</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>
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>):
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>
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>)
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>):
1270 <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerService</span>)
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> = {}
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>)
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">"No such user"</span>))
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>())
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>)
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>()
1300 <span class="py-src-comment"># Yet another back-end</span>
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>):
1304 <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerService</span>)
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">"No such user"</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">"No such user"</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>)
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>([])
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>
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>
1345 <p><a href="../index.html">Index</a></p>
1346 <span class="version">Version: 12.1.0</span>