Sophie

Sophie

distrib > Mandriva > 2008.1 > x86_64 > media > main-release > by-pkgid > db93d7191b12a3d5ce887da46fc79bf1 > files > 260

python-twisted-core-doc-2.5.0-3mdv2008.1.x86_64.rpm

<?xml version="1.0"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "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="../../howto/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">twisted.web.resource.Resource</code> objects: <code class="python">UserStatusTree</code>, which will produce a listing of all
users at the base URL (<code>/</code>) of our site; <code class="python">UserStatus</code>, which gives the status of each user at the
locaton <code>/username</code>; and <code class="python">UserStatusXR</code>,
which exposes an XMLRPC interface to <code class="python">getUser</code> and
<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
was less trivial, we would want to use more sophisticated web templating and
design our system so that HTML rendering and logic were clearly separated.</p><div class="py-listing"><pre>
<span class="py-src-comment"># Do everything properly, and componentize
</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>
<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-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>
<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>
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">python</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">components</span>
<span class="py-src-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>
<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>
<span class="py-src-keyword">import</span> <span class="py-src-variable">cgi</span>

<span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerService</span>(<span class="py-src-parameter">Interface</span>):

    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUser</span>(<span class="py-src-parameter">user</span>):
        <span class="py-src-string">&quot;&quot;&quot;Return a deferred returning a string&quot;&quot;&quot;</span>

    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUsers</span>():
        <span class="py-src-string">&quot;&quot;&quot;Return a deferred returning a list of strings&quot;&quot;&quot;</span>

<span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerSetterService</span>(<span class="py-src-parameter">Interface</span>):

    <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>):
        <span class="py-src-string">&quot;&quot;&quot;Set the user's status to something&quot;&quot;&quot;</span>

<span class="py-src-keyword">def</span> <span class="py-src-identifier">catchError</span>(<span class="py-src-parameter">err</span>):
    <span class="py-src-keyword">return</span> <span class="py-src-string">&quot;Internal error in server&quot;</span>

<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>):

    <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>):
        <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>)
        <span class="py-src-variable">d</span>.<span class="py-src-variable">addErrback</span>(<span class="py-src-variable">catchError</span>)
        <span class="py-src-keyword">def</span> <span class="py-src-identifier">writeValue</span>(<span class="py-src-parameter">value</span>):
            <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>)
            <span class="py-src-variable">self</span>.<span class="py-src-variable">transport</span>.<span class="py-src-variable">loseConnection</span>()
        <span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">writeValue</span>)


<span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerFactory</span>(<span class="py-src-parameter">Interface</span>):

    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUser</span>(<span class="py-src-parameter">user</span>):
        <span class="py-src-string">&quot;&quot;&quot;Return a deferred returning a string&quot;&quot;&quot;</span>

    <span class="py-src-keyword">def</span> <span class="py-src-identifier">buildProtocol</span>(<span class="py-src-parameter">addr</span>):
        <span class="py-src-string">&quot;&quot;&quot;Return a protocol returning a string&quot;&quot;&quot;</span>


<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>):

    <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerFactory</span>)

    <span class="py-src-variable">protocol</span> = <span class="py-src-variable">FingerProtocol</span>

    <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>):
        <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>

    <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>):
        <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>)

<span class="py-src-variable">components</span>.<span class="py-src-variable">registerAdapter</span>(<span class="py-src-variable">FingerFactoryFromService</span>,
                           <span class="py-src-variable">IFingerService</span>,
                           <span class="py-src-variable">IFingerFactory</span>)

<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>):

    <span class="py-src-keyword">def</span> <span class="py-src-identifier">connectionMade</span>(<span class="py-src-parameter">self</span>):
        <span class="py-src-variable">self</span>.<span class="py-src-variable">lines</span> = []

    <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>):
        <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>)

    <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>):
        <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>:
            <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>)


<span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerSetterFactory</span>(<span class="py-src-parameter">Interface</span>):

    <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>):
        <span class="py-src-string">&quot;&quot;&quot;Return a deferred returning a string&quot;&quot;&quot;</span>

    <span class="py-src-keyword">def</span> <span class="py-src-identifier">buildProtocol</span>(<span class="py-src-parameter">addr</span>):
        <span class="py-src-string">&quot;&quot;&quot;Return a protocol returning a string&quot;&quot;&quot;</span>


<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>):

    <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerSetterFactory</span>)

    <span class="py-src-variable">protocol</span> = <span class="py-src-variable">FingerSetterProtocol</span>

    <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>):
        <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>

    <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>):
        <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>)


<span class="py-src-variable">components</span>.<span class="py-src-variable">registerAdapter</span>(<span class="py-src-variable">FingerSetterFactoryFromService</span>,
                           <span class="py-src-variable">IFingerSetterService</span>,
                           <span class="py-src-variable">IFingerSetterFactory</span>)

<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>):

    <span class="py-src-keyword">def</span> <span class="py-src-identifier">connectionMade</span>(<span class="py-src-parameter">self</span>):
        <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>
        <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>)

    <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>):
        <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>]
        <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>():
            <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>)
            <span class="py-src-variable">d</span>.<span class="py-src-variable">addErrback</span>(<span class="py-src-variable">catchError</span>)
            <span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-keyword">lambda</span> <span class="py-src-variable">m</span>: <span class="py-src-string">&quot;Status of %s: %s&quot;</span> % (<span class="py-src-variable">msg</span>, <span class="py-src-variable">m</span>))
            <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>))


<span class="py-src-keyword">class</span> <span class="py-src-identifier">IIRCClientFactory</span>(<span class="py-src-parameter">Interface</span>):

    <span class="py-src-string">&quot;&quot;&quot;
    @ivar nickname
    &quot;&quot;&quot;</span>

    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUser</span>(<span class="py-src-parameter">user</span>):
        <span class="py-src-string">&quot;&quot;&quot;Return a deferred returning a string&quot;&quot;&quot;</span>

    <span class="py-src-keyword">def</span> <span class="py-src-identifier">buildProtocol</span>(<span class="py-src-parameter">addr</span>):
        <span class="py-src-string">&quot;&quot;&quot;Return a protocol&quot;&quot;&quot;</span>


<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>):

    <span class="py-src-variable">implements</span>(<span class="py-src-variable">IIRCClientFactory</span>)

    <span class="py-src-variable">protocol</span> = <span class="py-src-variable">IRCReplyBot</span>
    <span class="py-src-variable">nickname</span> = <span class="py-src-variable">None</span>

    <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>):
        <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>

    <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>):
        <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>)

<span class="py-src-variable">components</span>.<span class="py-src-variable">registerAdapter</span>(<span class="py-src-variable">IRCClientFactoryFromService</span>,
                           <span class="py-src-variable">IFingerService</span>,
                           <span class="py-src-variable">IIRCClientFactory</span>)

<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>):

    <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>):
        <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>)
        <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span>=<span class="py-src-variable">service</span>

        <span class="py-src-comment"># add a specific child for the path &quot;RPC2&quot;
</span>        <span class="py-src-variable">self</span>.<span class="py-src-variable">putChild</span>(<span class="py-src-string">&quot;RPC2&quot;</span>, <span class="py-src-variable">UserStatusXR</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">service</span>))

        <span class="py-src-comment"># need to do this for resources at the root of the site
</span>        <span class="py-src-variable">self</span>.<span class="py-src-variable">putChild</span>(<span class="py-src-string">&quot;&quot;</span>, <span class="py-src-variable">self</span>)

    <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>):
        <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">&quot;&lt;li&gt;&lt;a href=\&quot;%s\&quot;&gt;%s&lt;/a&gt;&lt;/li&gt;&quot;</span> % (<span class="py-src-variable">user</span>, <span class="py-src-variable">user</span>)
                <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>])
        <span class="py-src-variable">request</span>.<span class="py-src-variable">write</span>(<span class="py-src-string">&quot;&quot;&quot;
            &lt;html&gt;&lt;head&gt;&lt;title&gt;Users&lt;/title&gt;&lt;/head&gt;&lt;body&gt;
            &lt;h1&gt;Users&lt;/h1&gt;
            &lt;ul&gt;
            %s
            &lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;&quot;&quot;&quot;</span> % <span class="py-src-variable">userOutput</span>)
        <span class="py-src-variable">request</span>.<span class="py-src-variable">finish</span>()

    <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>):
        <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>()
        <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>)

        <span class="py-src-comment"># signal that the rendering is not complete
</span>        <span class="py-src-keyword">return</span> <span class="py-src-variable">server</span>.<span class="py-src-variable">NOT_DONE_YET</span>

    <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>):
        <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>)

<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>)

<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>):

    <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>):
        <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>)
        <span class="py-src-variable">self</span>.<span class="py-src-variable">user</span> = <span class="py-src-variable">user</span>
        <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>

    <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>):
        <span class="py-src-variable">request</span>.<span class="py-src-variable">write</span>(<span class="py-src-string">&quot;&quot;&quot;&lt;html&gt;&lt;head&gt;&lt;title&gt;%s&lt;/title&gt;&lt;/head&gt;
        &lt;body&gt;&lt;h1&gt;%s&lt;/h1&gt;
        &lt;p&gt;%s&lt;/p&gt;
        &lt;/body&gt;&lt;/html&gt;&quot;&quot;&quot;</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>))
        <span class="py-src-variable">request</span>.<span class="py-src-variable">finish</span>()

    <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>):
        <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>)
        <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>)

        <span class="py-src-comment"># signal that the rendering is not complete
</span>        <span class="py-src-keyword">return</span> <span class="py-src-variable">server</span>.<span class="py-src-variable">NOT_DONE_YET</span>

<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>):

    <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>):
        <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>)
        <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>

    <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>):
        <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>)

    <span class="py-src-keyword">def</span> <span class="py-src-identifier">xmlrpc_getUsers</span>(<span class="py-src-parameter">self</span>):
        <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>()


<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>):

    <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerService</span>)

    <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>):
        <span class="py-src-variable">self</span>.<span class="py-src-variable">filename</span> = <span class="py-src-variable">filename</span>
        <span class="py-src-variable">self</span>.<span class="py-src-variable">_read</span>()

    <span class="py-src-keyword">def</span> <span class="py-src-identifier">_read</span>(<span class="py-src-parameter">self</span>):
        <span class="py-src-variable">self</span>.<span class="py-src-variable">users</span> = {}
        <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>):
            <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>)
            <span class="py-src-variable">user</span> = <span class="py-src-variable">user</span>.<span class="py-src-variable">strip</span>()
            <span class="py-src-variable">status</span> = <span class="py-src-variable">status</span>.<span class="py-src-variable">strip</span>()
            <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>
        <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>)

    <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>):
        <span class="py-src-keyword">return</span> <span class="py-src-variable">defer</span>.<span class="py-src-variable">succeed</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">users</span>.<span class="py-src-variable">get</span>(<span class="py-src-variable">user</span>, <span class="py-src-string">&quot;No such user&quot;</span>))

    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUsers</span>(<span class="py-src-parameter">self</span>):
        <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>())


<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>)
<span class="py-src-variable">f</span> = <span class="py-src-variable">FingerService</span>(<span class="py-src-string">'/etc/users'</span>)
<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>)
<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>)
                   ).<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">serviceCollection</span>)
<span class="py-src-variable">internet</span>.<span class="py-src-variable">TCPServer</span>(<span class="py-src-number">8000</span>, <span class="py-src-variable">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>))
                   ).<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">serviceCollection</span>)
<span class="py-src-variable">i</span> = <span class="py-src-variable">IIRCClientFactory</span>(<span class="py-src-variable">f</span>)
<span class="py-src-variable">i</span>.<span class="py-src-variable">nickname</span> = <span class="py-src-string">'fingerbot'</span>
<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>
                   ).<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">serviceCollection</span>)
</pre><div class="caption">Source listing - <a href="listings/finger/finger20.py"><span class="filename">listings/finger/finger20.py</span></a></div></div></div><p><a href="../../howto/index.html">Index</a></p><span class="version">Version: 2.5.0</span></body></html>