1
<?xml version="1.0"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><title>Twisted Documentation: The Evolution of Finger: a web frontend</title><link href="../stylesheet.css" type="text/css" rel="stylesheet" /></head><body bgcolor="white"><h1 class="title">The Evolution of Finger: a web frontend</h1><div class="toc"><ol><li><a href="#auto0">Introduction</a></li></ol></div><div class="content"><span></span><h2>Introduction<a name="auto0"></a></h2><p> This is the sixth part of the Twisted tutorial <a href="index.html">Twisted from Scratch, or The Evolution of Finger</a>.</p><p>In this part, we demonstrate adding a web frontend using simple <code class="API"><a href="http://twistedmatrix.com/documents/8.2.0/api/twisted.web.resource.Resource.html" title="twisted.web.resource.Resource">twisted.web.resource.Resource</a></code> objects: <code class="python">UserStatusTree</code>, which will produce a listing of all
1
<?xml version="1.0" encoding="utf-8"?>
3
PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN'
4
'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
5
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
7
<title>Twisted Documentation: The Evolution of Finger: a web frontend</title>
8
<link href="../stylesheet.css" rel="stylesheet" type="text/css"/>
11
<body bgcolor="white">
12
<h1 class="title">The Evolution of Finger: a web frontend</h1>
13
<div class="toc"><ol><li><a href="#auto0">Introduction</a></li></ol></div>
18
<h2>Introduction<a name="auto0"/></h2>
20
<p> This is the sixth part of the Twisted tutorial <a href="index.html" shape="rect">Twisted from Scratch, or The Evolution of Finger</a>.</p>
22
<p>In this part, we demonstrate adding a web frontend using simple <code class="API"><a href="http://twistedmatrix.com/documents/9.0.0/api/twisted.web.resource.Resource.html" title="twisted.web.resource.Resource">twisted.web.resource.Resource</a></code> objects: <code class="python">UserStatusTree</code>, which will produce a listing of all
3
23
users at the base URL (<code>/</code>) of our site; <code class="python">UserStatus</code>, which gives the status of each user at the
4
24
locaton <code>/username</code>; and <code class="python">UserStatusXR</code>,
5
25
which exposes an XMLRPC interface to <code class="python">getUser</code> and
6
<code class="python">getUsers</code> functions at the URL <code>/RPC2</code>.</p><p>In this example we construct HTML segments manually. If the web interface
26
<code class="python">getUsers</code> functions at the URL <code>/RPC2</code>.</p>
28
<p>In this example we construct HTML segments manually. If the web interface
7
29
was less trivial, we would want to use more sophisticated web templating and
8
design our system so that HTML rendering and logic were clearly separated.</p><div class="py-listing"><pre>
9
<span class="py-src-comment"># Do everything properly, and componentize
10
</span><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>
30
design our system so that HTML rendering and logic were clearly separated.</p>
32
<div class="py-listing"><pre><p class="py-linenumber"> 1
283
</p><span class="py-src-comment"># Do everything properly, and componentize</span>
284
<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>
11
285
<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>
12
286
<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>
13
287
<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>
158
432
<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>)
159
433
<span class="py-src-variable">self</span>.<span class="py-src-variable">service</span>=<span class="py-src-variable">service</span>
161
<span class="py-src-comment"># add a specific child for the path "RPC2"
162
</span> <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>))
435
<span class="py-src-comment"># add a specific child for the path "RPC2"</span>
436
<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>))
164
<span class="py-src-comment"># need to do this for resources at the root of the site
165
</span> <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>)
438
<span class="py-src-comment"># need to do this for resources at the root of the site</span>
439
<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>)
167
441
<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>):
168
442
<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>)
179
453
<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>()
180
454
<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>)
182
<span class="py-src-comment"># signal that the rendering is not complete
183
</span> <span class="py-src-keyword">return</span> <span class="py-src-variable">server</span>.<span class="py-src-variable">NOT_DONE_YET</span>
456
<span class="py-src-comment"># signal that the rendering is not complete</span>
457
<span class="py-src-keyword">return</span> <span class="py-src-variable">server</span>.<span class="py-src-variable">NOT_DONE_YET</span>
185
459
<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>):
186
460
<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>)
205
479
<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>)
206
480
<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>)
208
<span class="py-src-comment"># signal that the rendering is not complete
209
</span> <span class="py-src-keyword">return</span> <span class="py-src-variable">server</span>.<span class="py-src-variable">NOT_DONE_YET</span>
482
<span class="py-src-comment"># signal that the rendering is not complete</span>
483
<span class="py-src-keyword">return</span> <span class="py-src-variable">server</span>.<span class="py-src-variable">NOT_DONE_YET</span>
211
485
<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>):
228
502
<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>):
229
503
<span class="py-src-variable">self</span>.<span class="py-src-variable">filename</span> = <span class="py-src-variable">filename</span>
504
<span class="py-src-variable">self</span>.<span class="py-src-variable">users</span> = {}
230
505
<span class="py-src-variable">self</span>.<span class="py-src-variable">_read</span>()
232
507
<span class="py-src-keyword">def</span> <span class="py-src-identifier">_read</span>(<span class="py-src-parameter">self</span>):
233
<span class="py-src-variable">self</span>.<span class="py-src-variable">users</span> = {}
508
<span class="py-src-variable">self</span>.<span class="py-src-variable">users</span>.<span class="py-src-variable">clear</span>()
234
509
<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>):
235
510
<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>)
236
511
<span class="py-src-variable">user</span> = <span class="py-src-variable">user</span>.<span class="py-src-variable">strip</span>()
256
531
<span class="py-src-variable">i</span>.<span class="py-src-variable">nickname</span> = <span class="py-src-string">'fingerbot'</span>
257
532
<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>
258
533
).<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">serviceCollection</span>)
259
</pre><div class="caption">Source listing - <a href="listings/finger/finger20.tac"><span class="filename">listings/finger/finger20.tac</span></a></div></div></div><p><a href="../index.html">Index</a></p><span class="version">Version: 8.2.0</span></body></html>
b'\\ No newline at end of file'
534
</pre><div class="caption">Source listing - <a href="listings/finger/finger20.tac"><span class="filename">listings/finger/finger20.tac</span></a></div></div>
538
<p><a href="../index.html">Index</a></p>
539
<span class="version">Version: 9.0.0</span>
b'\\ No newline at end of file'