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: Twisted client support using Perspective Broker</title>
4
<link href="../stylesheet.css" rel="stylesheet" type="text/css"/>
8
<h1 class="title">The Evolution of Finger: Twisted client support using Perspective Broker</h1>
9
<div class="toc"><ol><li><a href="#auto0">Introduction</a></li><li><a href="#auto1">Use Perspective Broker</a></li></ol></div>
14
<h2>Introduction<a name="auto0"/></h2>
16
<p> This is the seventh 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 add a Perspective Broker service to the finger application
19
so that Twisted clients can access the finger server. Perspective Broker is
20
introduced in depth in its own <a href="../index.html#pb" shape="rect">section</a> of the
23
<h2>Use Perspective Broker<a name="auto1"/></h2>
25
<p>We add support for perspective broker, Twisted's native remote object
26
protocol. Now, Twisted clients will not have to go through XML-RPCish
27
contortions to get information about users.</p>
29
<div class="py-listing"><pre><p class="py-linenumber"> 1
309
</p><span class="py-src-comment"># Do everything properly, and componentize</span>
310
<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>
311
<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>
312
<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>
313
<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>
314
<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>
315
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">resource</span>, <span class="py-src-variable">server</span>, <span class="py-src-variable">static</span>, <span class="py-src-variable">xmlrpc</span>, <span class="py-src-variable">microdom</span>
316
<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>
317
<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>
318
<span class="py-src-keyword">import</span> <span class="py-src-variable">cgi</span>
320
<span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerService</span>(<span class="py-src-parameter">Interface</span>):
322
<span class="py-src-keyword">def</span> <span class="py-src-identifier">getUser</span>(<span class="py-src-parameter">user</span>):
323
<span class="py-src-string">"""Return a deferred returning a string"""</span>
325
<span class="py-src-keyword">def</span> <span class="py-src-identifier">getUsers</span>():
326
<span class="py-src-string">"""Return a deferred returning a list of strings"""</span>
328
<span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerSetterService</span>(<span class="py-src-parameter">Interface</span>):
330
<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>):
331
<span class="py-src-string">"""Set the user's status to something"""</span>
333
<span class="py-src-keyword">def</span> <span class="py-src-identifier">catchError</span>(<span class="py-src-parameter">err</span>):
334
<span class="py-src-keyword">return</span> <span class="py-src-string">"Internal error in server"</span>
336
<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>):
338
<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>):
339
<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>)
340
<span class="py-src-variable">d</span>.<span class="py-src-variable">addErrback</span>(<span class="py-src-variable">catchError</span>)
341
<span class="py-src-keyword">def</span> <span class="py-src-identifier">writeValue</span>(<span class="py-src-parameter">value</span>):
342
<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>)
343
<span class="py-src-variable">self</span>.<span class="py-src-variable">transport</span>.<span class="py-src-variable">loseConnection</span>()
344
<span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">writeValue</span>)
347
<span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerFactory</span>(<span class="py-src-parameter">Interface</span>):
349
<span class="py-src-keyword">def</span> <span class="py-src-identifier">getUser</span>(<span class="py-src-parameter">user</span>):
350
<span class="py-src-string">"""Return a deferred returning a string"""</span>
352
<span class="py-src-keyword">def</span> <span class="py-src-identifier">buildProtocol</span>(<span class="py-src-parameter">addr</span>):
353
<span class="py-src-string">"""Return a protocol returning a string"""</span>
356
<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>):
358
<span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerFactory</span>)
360
<span class="py-src-variable">protocol</span> = <span class="py-src-variable">FingerProtocol</span>
362
<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>):
363
<span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>
365
<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>):
366
<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>)
368
<span class="py-src-variable">components</span>.<span class="py-src-variable">registerAdapter</span>(<span class="py-src-variable">FingerFactoryFromService</span>,
369
<span class="py-src-variable">IFingerService</span>,
370
<span class="py-src-variable">IFingerFactory</span>)
372
<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>):
374
<span class="py-src-keyword">def</span> <span class="py-src-identifier">connectionMade</span>(<span class="py-src-parameter">self</span>):
375
<span class="py-src-variable">self</span>.<span class="py-src-variable">lines</span> = []
377
<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>):
378
<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>)
380
<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>):
381
<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>:
382
<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>)
385
<span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerSetterFactory</span>(<span class="py-src-parameter">Interface</span>):
387
<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>):
388
<span class="py-src-string">"""Return a deferred returning a string"""</span>
390
<span class="py-src-keyword">def</span> <span class="py-src-identifier">buildProtocol</span>(<span class="py-src-parameter">addr</span>):
391
<span class="py-src-string">"""Return a protocol returning a string"""</span>
394
<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>):
396
<span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerSetterFactory</span>)
398
<span class="py-src-variable">protocol</span> = <span class="py-src-variable">FingerSetterProtocol</span>
400
<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>):
401
<span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>
403
<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>):
404
<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>)
407
<span class="py-src-variable">components</span>.<span class="py-src-variable">registerAdapter</span>(<span class="py-src-variable">FingerSetterFactoryFromService</span>,
408
<span class="py-src-variable">IFingerSetterService</span>,
409
<span class="py-src-variable">IFingerSetterFactory</span>)
411
<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>):
413
<span class="py-src-keyword">def</span> <span class="py-src-identifier">connectionMade</span>(<span class="py-src-parameter">self</span>):
414
<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>
415
<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>)
417
<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>):
418
<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>]
419
<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>():
420
<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>)
421
<span class="py-src-variable">d</span>.<span class="py-src-variable">addErrback</span>(<span class="py-src-variable">catchError</span>)
422
<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>))
423
<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>))
426
<span class="py-src-keyword">class</span> <span class="py-src-identifier">IIRCClientFactory</span>(<span class="py-src-parameter">Interface</span>):
428
<span class="py-src-string">"""
430
"""</span>
432
<span class="py-src-keyword">def</span> <span class="py-src-identifier">getUser</span>(<span class="py-src-parameter">user</span>):
433
<span class="py-src-string">"""Return a deferred returning a string"""</span>
435
<span class="py-src-keyword">def</span> <span class="py-src-identifier">buildProtocol</span>(<span class="py-src-parameter">addr</span>):
436
<span class="py-src-string">"""Return a protocol"""</span>
439
<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>):
441
<span class="py-src-variable">implements</span>(<span class="py-src-variable">IIRCClientFactory</span>)
443
<span class="py-src-variable">protocol</span> = <span class="py-src-variable">IRCReplyBot</span>
444
<span class="py-src-variable">nickname</span> = <span class="py-src-variable">None</span>
446
<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>):
447
<span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>
449
<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>):
450
<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>)
452
<span class="py-src-variable">components</span>.<span class="py-src-variable">registerAdapter</span>(<span class="py-src-variable">IRCClientFactoryFromService</span>,
453
<span class="py-src-variable">IFingerService</span>,
454
<span class="py-src-variable">IIRCClientFactory</span>)
456
<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>):
458
<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>):
459
<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>)
460
<span class="py-src-variable">self</span>.<span class="py-src-variable">service</span>=<span class="py-src-variable">service</span>
462
<span class="py-src-comment"># add a specific child for the path "RPC2"</span>
463
<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>))
465
<span class="py-src-comment"># need to do this for resources at the root of the site</span>
466
<span class="py-src-variable">self</span>.<span class="py-src-variable">putChild</span>(<span class="py-src-string">""</span>, <span class="py-src-variable">self</span>)
468
<span class="py-src-keyword">def</span> <span class="py-src-identifier">_cb_render_GET</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">users</span>, <span class="py-src-parameter">request</span>):
469
<span class="py-src-variable">userOutput</span> = <span class="py-src-string">''</span>.<span class="py-src-variable">join</span>([<span class="py-src-string">"<li><a href=\"%s\">%s</a></li>"</span> % (<span class="py-src-variable">user</span>, <span class="py-src-variable">user</span>)
470
<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>])
471
<span class="py-src-variable">request</span>.<span class="py-src-variable">write</span>(<span class="py-src-string">"""
472
<html><head><title>Users</title></head><body>
473
<h1>Users</h1>
476
</ul></body></html>"""</span> % <span class="py-src-variable">userOutput</span>)
477
<span class="py-src-variable">request</span>.<span class="py-src-variable">finish</span>()
479
<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>):
480
<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>()
481
<span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">_cb_render_GET</span>, <span class="py-src-variable">request</span>)
483
<span class="py-src-comment"># signal that the rendering is not complete</span>
484
<span class="py-src-keyword">return</span> <span class="py-src-variable">server</span>.<span class="py-src-variable">NOT_DONE_YET</span>
486
<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>):
487
<span class="py-src-keyword">return</span> <span class="py-src-variable">UserStatus</span>(<span class="py-src-variable">user</span>=<span class="py-src-variable">path</span>, <span class="py-src-variable">service</span>=<span class="py-src-variable">self</span>.<span class="py-src-variable">service</span>)
489
<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>)
491
<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>):
493
<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>):
494
<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>)
495
<span class="py-src-variable">self</span>.<span class="py-src-variable">user</span> = <span class="py-src-variable">user</span>
496
<span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>
498
<span class="py-src-keyword">def</span> <span class="py-src-identifier">_cb_render_GET</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">status</span>, <span class="py-src-parameter">request</span>):
499
<span class="py-src-variable">request</span>.<span class="py-src-variable">write</span>(<span class="py-src-string">"""<html><head><title>%s</title></head>
500
<body><h1>%s</h1>
501
<p>%s</p>
502
</body></html>"""</span> % (<span class="py-src-variable">self</span>.<span class="py-src-variable">user</span>, <span class="py-src-variable">self</span>.<span class="py-src-variable">user</span>, <span class="py-src-variable">status</span>))
503
<span class="py-src-variable">request</span>.<span class="py-src-variable">finish</span>()
505
<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>):
506
<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>)
507
<span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">_cb_render_GET</span>, <span class="py-src-variable">request</span>)
509
<span class="py-src-comment"># signal that the rendering is not complete</span>
510
<span class="py-src-keyword">return</span> <span class="py-src-variable">server</span>.<span class="py-src-variable">NOT_DONE_YET</span>
512
<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>):
514
<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>):
515
<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>)
516
<span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>
518
<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>):
519
<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>)
521
<span class="py-src-keyword">def</span> <span class="py-src-identifier">xmlrpc_getUsers</span>(<span class="py-src-parameter">self</span>):
522
<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>()
525
<span class="py-src-keyword">class</span> <span class="py-src-identifier">IPerspectiveFinger</span>(<span class="py-src-parameter">Interface</span>):
527
<span class="py-src-keyword">def</span> <span class="py-src-identifier">remote_getUser</span>(<span class="py-src-parameter">username</span>):
528
<span class="py-src-string">"""return a user's status"""</span>
530
<span class="py-src-keyword">def</span> <span class="py-src-identifier">remote_getUsers</span>():
531
<span class="py-src-string">"""return a user's status"""</span>
533
<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>):
535
<span class="py-src-variable">implements</span>(<span class="py-src-variable">IPerspectiveFinger</span>)
537
<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>):
538
<span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>
540
<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>):
541
<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>)
543
<span class="py-src-keyword">def</span> <span class="py-src-identifier">remote_getUsers</span>(<span class="py-src-parameter">self</span>):
544
<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>()
546
<span class="py-src-variable">components</span>.<span class="py-src-variable">registerAdapter</span>(<span class="py-src-variable">PerspectiveFingerFromService</span>,
547
<span class="py-src-variable">IFingerService</span>,
548
<span class="py-src-variable">IPerspectiveFinger</span>)
551
<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>):
553
<span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerService</span>)
555
<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>):
556
<span class="py-src-variable">self</span>.<span class="py-src-variable">filename</span> = <span class="py-src-variable">filename</span>
557
<span class="py-src-variable">self</span>.<span class="py-src-variable">users</span> = {}
558
<span class="py-src-variable">self</span>.<span class="py-src-variable">_read</span>()
560
<span class="py-src-keyword">def</span> <span class="py-src-identifier">_read</span>(<span class="py-src-parameter">self</span>):
561
<span class="py-src-variable">self</span>.<span class="py-src-variable">users</span>.<span class="py-src-variable">clear</span>()
562
<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>):
563
<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>)
564
<span class="py-src-variable">user</span> = <span class="py-src-variable">user</span>.<span class="py-src-variable">strip</span>()
565
<span class="py-src-variable">status</span> = <span class="py-src-variable">status</span>.<span class="py-src-variable">strip</span>()
566
<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>
567
<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>)
569
<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>):
570
<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>))
572
<span class="py-src-keyword">def</span> <span class="py-src-identifier">getUsers</span>(<span class="py-src-parameter">self</span>):
573
<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>())
576
<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>)
577
<span class="py-src-variable">f</span> = <span class="py-src-variable">FingerService</span>(<span class="py-src-string">'/etc/users'</span>)
578
<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>)
579
<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>)
580
).<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">serviceCollection</span>)
581
<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>))
582
).<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">serviceCollection</span>)
583
<span class="py-src-variable">i</span> = <span class="py-src-variable">IIRCClientFactory</span>(<span class="py-src-variable">f</span>)
584
<span class="py-src-variable">i</span>.<span class="py-src-variable">nickname</span> = <span class="py-src-string">'fingerbot'</span>
585
<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>
586
).<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">serviceCollection</span>)
587
<span class="py-src-variable">internet</span>.<span class="py-src-variable">TCPServer</span>(<span class="py-src-number">8889</span>, <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>))
588
).<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">serviceCollection</span>)
589
</pre><div class="caption">Source listing - <a href="listings/finger/finger21.tac"><span class="filename">listings/finger/finger21.tac</span></a></div></div>
591
<p>A simple client to test the perspective broker finger:</p>
593
<div class="py-listing"><pre><p class="py-linenumber"> 1
619
</p><span class="py-src-comment"># test the PB finger on port 8889</span>
620
<span class="py-src-comment"># this code is essentially the same as</span>
621
<span class="py-src-comment"># the first example in howto/pb-usage</span>
623
<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>
624
<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">reactor</span>
626
<span class="py-src-keyword">def</span> <span class="py-src-identifier">gotObject</span>(<span class="py-src-parameter">object</span>):
627
<span class="py-src-keyword">print</span> <span class="py-src-string">"got object:"</span>, <span class="py-src-variable">object</span>
628
<span class="py-src-variable">object</span>.<span class="py-src-variable">callRemote</span>(<span class="py-src-string">"getUser"</span>,<span class="py-src-string">"moshez"</span>).<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">gotData</span>)
629
<span class="py-src-comment"># or</span>
630
<span class="py-src-comment"># object.callRemote("getUsers").addCallback(gotData)</span>
632
<span class="py-src-keyword">def</span> <span class="py-src-identifier">gotData</span>(<span class="py-src-parameter">data</span>):
633
<span class="py-src-keyword">print</span> <span class="py-src-string">'server sent:'</span>, <span class="py-src-variable">data</span>
634
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">stop</span>()
636
<span class="py-src-keyword">def</span> <span class="py-src-identifier">gotNoObject</span>(<span class="py-src-parameter">reason</span>):
637
<span class="py-src-keyword">print</span> <span class="py-src-string">"no object:"</span>,<span class="py-src-variable">reason</span>
638
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">stop</span>()
640
<span class="py-src-variable">factory</span> = <span class="py-src-variable">pb</span>.<span class="py-src-variable">PBClientFactory</span>()
641
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">connectTCP</span>(<span class="py-src-string">"127.0.0.1"</span>,<span class="py-src-number">8889</span>, <span class="py-src-variable">factory</span>)
642
<span class="py-src-variable">factory</span>.<span class="py-src-variable">getRootObject</span>().<span class="py-src-variable">addCallbacks</span>(<span class="py-src-variable">gotObject</span>,<span class="py-src-variable">gotNoObject</span>)
643
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">run</span>()
644
</pre><div class="caption">Source listing - <a href="listings/finger/fingerPBclient.py"><span class="filename">listings/finger/fingerPBclient.py</span></a></div></div>
647
<p><a href="../index.html">Index</a></p>
648
<span class="version">Version: 10.0.0</span>
b'\\ No newline at end of file'