Sophie

Sophie

distrib > Mandriva > 2010.0 > i586 > media > contrib-release > by-pkgid > 4a6f76725dc8922dc15f7eb0d84d77ef > files > 283

python-enthought-envisagecore-3.1.1-2mdv2010.0.noarch.rpm

<!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">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>The “Message of the Day” (MOTD) Example &mdash; EnvisageCore v3.1.1 documentation</title>
    <link rel="stylesheet" href="_static/default.css" type="text/css" />
    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '',
        VERSION:     '3.1.1',
        COLLAPSE_MODINDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>
    <script type="text/javascript" src="_static/jquery.js"></script>
    <script type="text/javascript" src="_static/doctools.js"></script>
    <link rel="top" title="EnvisageCore v3.1.1 documentation" href="index.html" />
    <link rel="next" title="The “Message of the Day” (MOTD) Example" href="message_of_the_day_(using_eggs).html" />
    <link rel="prev" title="Plugins" href="plugins.html" /> 
  </head>
  <body>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="message_of_the_day_(using_eggs).html" title="The “Message of the Day” (MOTD) Example"
             accesskey="N">next</a> |</li>
        <li class="right" >
          <a href="plugins.html" title="Plugins"
             accesskey="P">previous</a> |</li>
        <li><a href="index.html">EnvisageCore v3.1.1 documentation</a> &raquo;</li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
            
  <div class="section" id="the-message-of-the-day-motd-example">
<h1>The &#8220;Message of the Day&#8221; (MOTD) Example<a class="headerlink" href="#the-message-of-the-day-motd-example" title="Permalink to this headline">¶</a></h1>
<p>Only marginally more complicated than the traditional &#8220;Hello World&#8221; example,
this is a simple application that prints a witty, educational, or
inspiring &#8220;Message of the Day&#8221;. Obviously, if we actually had to write this
application, we might not choose to use a framework like Envisage (it is one of
the rare applications that is so simple that why would you bother), but it does
serve to illustrate all of the fundamental aspects of building an Envisage
application.</p>
<p>All of the code for this example can be found in the <a class="reference external" href="https://svn.enthought.com/enthought/browser/EnvisageCore/trunk/examples/MOTD">examples/MOTD</a> directory
of the Envisage distribution, and to run it simply type:</p>
<div class="highlight-python"><pre>cd .../examples/MOTD
python run.py</pre>
</div>
<p>(or equivalent, depending on your operating system and shell)</p>
<p>Before we dive right in to building our extensible application, let&#8217;s take a
small, but important, step back. Envisage is designed to be an integration
platform &#8211; a place where you can bring existing code and with a (hopefully)
minimal amount of effort, make it work with the rest of the application.
Because of this, we will start the MOTD example by designing the application
without any knowledge of Envisage whatsoever. This is obviously a good idea in
general, as it allows our code to be reused outside of Envisage applications.</p>
<div class="section" id="plain-ol-motd">
<h2>Plain Ol&#8217; MOTD<a class="headerlink" href="#plain-ol-motd" title="Permalink to this headline">¶</a></h2>
<p>So lets take a look at our non-Envisage aware MOTD application, the code for
which is in the <a class="reference external" href="https://svn.enthought.com/enthought/browser/EnvisageCore/trunk/examples/MOTD/acme/motd/api.py">acme.motd</a> package. A good place to start as a developer
<em>using</em> any package in Envisage (and, for that matter, the entire Enthought
tool-suite) is to look at any interfaces and classes exposed via its &#8216;api.py&#8217;
module.</p>
<p>In this case, there are 2 interfaces</p>
<ol class="arabic simple">
<li><a class="reference external" href="https://svn.enthought.com/enthought/browser/EnvisageCore/trunk/examples/MOTD/acme/motd/i_motd.py">IMOTD</a></li>
</ol>
<blockquote>
The interface for simple &#8220;Message of the Day&#8221; functionality.</blockquote>
<ol class="arabic simple" start="2">
<li><a class="reference external" href="https://svn.enthought.com/enthought/browser/EnvisageCore/trunk/examples/MOTD/acme/motd/i_message.py">IMessage</a></li>
</ol>
<blockquote>
The interface supported by each message returned by the motd() method on
the <a class="reference external" href="https://svn.enthought.com/enthought/browser/EnvisageCore/trunk/examples/MOTD/acme/motd/i_motd.py">IMOTD</a> interface.</blockquote>
<p>We also (<em>not</em> coincidentally!) have 2 corresponding implementation classes:</p>
<ol class="arabic simple">
<li><a class="reference external" href="https://svn.enthought.com/enthought/browser/EnvisageCore/trunk/examples/MOTD/acme/motd/motd.py">MOTD</a></li>
<li><a class="reference external" href="https://svn.enthought.com/enthought/browser/EnvisageCore/trunk/examples/MOTD/acme/motd/message.py">Message</a></li>
</ol>
<p>As you can see, the <a class="reference external" href="https://svn.enthought.com/enthought/browser/EnvisageCore/trunk/examples/MOTD/acme/motd/motd.py">MOTD</a> class simply contains a list of messages and
when its motd() method is called, it returns a random choice from that list.</p>
<p>An example of using our <a class="reference external" href="https://svn.enthought.com/enthought/browser/EnvisageCore/trunk/examples/MOTD/acme/motd/motd.py">MOTD</a> class at the Python prompt might be:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">acme.motd.api</span> <span class="kn">import</span> <span class="n">Message</span><span class="p">,</span> <span class="n">MOTD</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">motd</span> <span class="o">=</span> <span class="n">MOTD</span><span class="p">(</span><span class="n">messages</span><span class="o">=</span><span class="p">[</span><span class="n">Message</span><span class="p">(</span><span class="n">author</span><span class="o">=</span><span class="s">&#39;Anon&#39;</span><span class="p">,</span> <span class="n">text</span><span class="o">=</span><span class="s">&#39;Hello World!&#39;</span><span class="p">)])</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">message</span> <span class="o">=</span> <span class="n">motd</span><span class="o">.</span><span class="n">motd</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="s">&#39;&quot;</span><span class="si">%s</span><span class="s">&quot; - </span><span class="si">%s</span><span class="s">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">text</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">author</span><span class="p">)</span>
<span class="go">&quot;Hello World!&quot; - Anon</span>
<span class="go">&gt;&gt;&gt;</span>
</pre></div>
</div>
<p>Well, we had to get &#8220;Hello World&#8221; in there somewhere!</p>
<p>The important point here is that this code is written without any knowledge of
Envisage or extensibility whatsoever. It is just a small, reusable piece of
code (albeit a very simple one).</p>
</div>
<div class="section" id="not-so-plain-ol-motd">
<h2>Not So Plain Ol&#8217; MOTD<a class="headerlink" href="#not-so-plain-ol-motd" title="Permalink to this headline">¶</a></h2>
<p>Now lets look at the steps that we have to go through to use this code and
turn it into an extensible, pluggable Envisage application.</p>
</div>
<div class="section" id="create-the-main-application-class">
<h2>1) Create the main Application class<a class="headerlink" href="#create-the-main-application-class" title="Permalink to this headline">¶</a></h2>
<p>First of all, we need to create an object that represents the application
itself. In Envisage, this can be any object that implements the <a class="reference external" href="https://svn.enthought.com/enthought/browser/EnvisageCore/trunk/enthought/envisage/i_application.py">IApplication</a>
interface, but is usually either an instance of the default <a class="reference external" href="https://svn.enthought.com/enthought/browser/EnvisageCore/trunk/enthought/envisage/application.py">Application</a> class,
or one derived from it.</p>
<p>In the <a class="reference external" href="https://svn.enthought.com/enthought/browser/EnvisageCore/trunk/examples/MOTD/acme/motd/motd.py">MOTD</a> example, we create the class in the <a class="reference external" href="https://svn.enthought.com/enthought/browser/EnvisageCore/trunk/examples/MOTD/run.py">run.py</a> module as follows:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">application</span> <span class="o">=</span> <span class="n">Application</span><span class="p">(</span>
    <span class="nb">id</span>      <span class="o">=</span> <span class="s">&#39;acme.motd&#39;</span><span class="p">,</span>
    <span class="n">plugins</span> <span class="o">=</span> <span class="p">[</span><span class="n">CorePlugin</span><span class="p">(),</span> <span class="n">MOTDPlugin</span><span class="p">(),</span> <span class="n">SoftwareQuotesPlugin</span><span class="p">()]</span>
<span class="p">)</span>

<span class="n">application</span><span class="o">.</span><span class="n">run</span><span class="p">()</span>
</pre></div>
</div>
<p>In this case, we use the simplest way to tell Envisage which plugins make up
the application by passing them in explicitly. Envisage applications allow you
to completely configure how plugins are located by setting the plugin manager.
Envisage ships with two plugin managers by default, one that simply takes a
list of plugins as in the above example, and one that finds all plugins
offered via the &#8216;enthought.envisage.plugins&#8217; entry point in Python Eggs.</p>
</div>
<div class="section" id="the-acme-motd-plugin">
<h2>2) The &#8216;acme.motd&#8217; plugin<a class="headerlink" href="#the-acme-motd-plugin" title="Permalink to this headline">¶</a></h2>
<p>As showm above, the corresponding plugin implementation is in the
<a class="reference external" href="https://svn.enthought.com/enthought/browser/EnvisageCore/trunk/examples/MOTD/acme/motd/motd_plugin.py">MOTDPlugin</a> class:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">MOTDPlugin</span><span class="p">(</span><span class="n">Plugin</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot; The &#39;Message of the Day&#39; plugin.</span>

<span class="sd">    This plugin simply prints the &#39;Message of the Day&#39; to stdout.</span>

<span class="sd">    &quot;&quot;&quot;</span>

    <span class="c"># The IDs of the extension points that this plugin offers.</span>
    <span class="n">MESSAGES</span> <span class="o">=</span> <span class="s">&#39;acme.motd.messages&#39;</span>

    <span class="c"># The IDs of the extension points that this plugin contributes to.</span>
    <span class="n">SERVICE_OFFERS</span> <span class="o">=</span> <span class="s">&#39;enthought.envisage.service_offers&#39;</span>

    <span class="c">#### &#39;IPlugin&#39; interface ##################################################</span>

    <span class="c"># The plugin&#39;s unique identifier.</span>
    <span class="nb">id</span> <span class="o">=</span> <span class="s">&#39;acme.motd&#39;</span>

    <span class="c"># The plugin&#39;s name (suitable for displaying to the user).</span>
    <span class="n">name</span> <span class="o">=</span> <span class="s">&#39;MOTD&#39;</span>

    <span class="c">#### Extension points offered by this plugin ##############################</span>

    <span class="c"># The messages extension point.</span>
    <span class="c">#</span>
    <span class="c"># Notice that we use the string name of the &#39;IMessage&#39; interface rather</span>
    <span class="c"># than actually importing it. This makes sure that the import only happens</span>
    <span class="c"># when somebody actually gets the contributions to the extension point.</span>
    <span class="n">messages</span> <span class="o">=</span> <span class="n">ExtensionPoint</span><span class="p">(</span>
        <span class="n">List</span><span class="p">(</span><span class="n">Instance</span><span class="p">(</span><span class="s">&#39;acme.motd.api.IMessage&#39;</span><span class="p">)),</span> <span class="nb">id</span><span class="o">=</span><span class="n">MESSAGES</span><span class="p">,</span> <span class="n">desc</span><span class="o">=</span><span class="s">&quot;&quot;&quot;</span>

<span class="s">        This extension point allows you to contribute messages to the &#39;Message</span>
<span class="s">        Of The Day&#39;.</span>

<span class="s">        &quot;&quot;&quot;</span>
    <span class="p">)</span>

    <span class="c">#### Contributions to extension points made by this plugin ################</span>

    <span class="n">service_offers</span> <span class="o">=</span> <span class="n">List</span><span class="p">(</span><span class="n">contributes_to</span><span class="o">=</span><span class="n">SERVICE_OFFERS</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">_service_offers_default</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot; Trait initializer. &quot;&quot;&quot;</span>

        <span class="c"># Register the protocol as a string containing the actual module path</span>
        <span class="c"># (do not use a module path that goes via an &#39;api.py&#39; file as this does</span>
        <span class="c"># not match what Python thinks the module is!). This allows the service</span>
        <span class="c"># to be looked up by passing either the exact same string, or the</span>
        <span class="c"># actual protocol object itself.</span>
        <span class="n">motd_service_offer</span> <span class="o">=</span> <span class="n">ServiceOffer</span><span class="p">(</span>
            <span class="n">protocol</span> <span class="o">=</span> <span class="s">&#39;acme.motd.i_motd.IMOTD&#39;</span><span class="p">,</span>
            <span class="n">factory</span>  <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_create_motd_service</span>
        <span class="p">)</span>

        <span class="k">return</span> <span class="p">[</span><span class="n">motd_service_offer</span><span class="p">]</span>

    <span class="c">###########################################################################</span>
    <span class="c"># Private interface.</span>
    <span class="c">###########################################################################</span>

    <span class="k">def</span> <span class="nf">_create_motd_service</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot; Factory method for the &#39;MOTD&#39; service. &quot;&quot;&quot;</span>

        <span class="c"># Only do imports when you need to! This makes sure that the import</span>
        <span class="c"># only happens when somebody needs an &#39;IMOTD&#39; service.</span>
        <span class="kn">from</span> <span class="nn">motd</span> <span class="kn">import</span> <span class="n">MOTD</span>

        <span class="k">return</span> <span class="n">MOTD</span><span class="p">(</span><span class="n">messages</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">messages</span><span class="p">)</span>

    <span class="c"># This plugin does all of its work in this method which gets called when</span>
    <span class="c"># the application has started all of its plugins.</span>
    <span class="nd">@on_trait_change</span><span class="p">(</span><span class="s">&#39;application:started&#39;</span><span class="p">)</span>
    <span class="k">def</span> <span class="nf">_print_motd</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot; Print the &#39;Message of the Day&#39; to stdout! &quot;&quot;&quot;</span>

        <span class="c"># Note that we always offer the service via its name, but look it up</span>
        <span class="c"># via the actual protocol.</span>
        <span class="kn">from</span> <span class="nn">acme.motd.api</span> <span class="kn">import</span> <span class="n">IMOTD</span>

        <span class="c"># Lookup the MOTD service.</span>
        <span class="n">motd</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">application</span><span class="o">.</span><span class="n">get_service</span><span class="p">(</span><span class="n">IMOTD</span><span class="p">)</span>

        <span class="c"># Get the message of the day...</span>
        <span class="n">message</span> <span class="o">=</span> <span class="n">motd</span><span class="o">.</span><span class="n">motd</span><span class="p">()</span>

        <span class="c"># ... and print it.</span>
        <span class="k">print</span> <span class="s">&#39;</span><span class="se">\n</span><span class="s">&quot;</span><span class="si">%s</span><span class="s">&quot;</span><span class="se">\n\n</span><span class="s">- </span><span class="si">%s</span><span class="s">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">text</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">author</span><span class="p">)</span>

        <span class="k">return</span>
</pre></div>
</div>
<p>Although it is obviously a bit of overkill, the example shows how we would
take a <a class="reference external" href="https://svn.enthought.com/enthought/browser/EnvisageCore/trunk/examples/MOTD/acme/motd/motd.py">MOTD</a> object and register it a service for other parts of the
application to use. Sadly, in this example, there are no other parts of the
application, so we just lookup and use the service ourselves!</p>
</div>
<div class="section" id="the-acme-motd-software-quotes-plugin">
<h2>3) The &#8216;acme.motd.software_quotes&#8217; plugin<a class="headerlink" href="#the-acme-motd-software-quotes-plugin" title="Permalink to this headline">¶</a></h2>
<p>First of all, we have to create the messages that we want to add. Remember that
when the <a class="reference external" href="https://svn.enthought.com/enthought/browser/EnvisageCore/trunk/examples/MOTD/acme/motd/api.py">acme.motd</a> plugin advertised the extension point, it told us that
every contribution had to implement the <a class="reference external" href="https://svn.enthought.com/enthought/browser/EnvisageCore/trunk/examples/MOTD/acme/motd/i_message.py">IMessage</a> interface. Happily, there is
a class that does just that already defined for us (<a class="reference external" href="https://svn.enthought.com/enthought/browser/EnvisageCore/trunk/examples/MOTD/acme/motd/message.py">Message</a>) and so we create
a simple module (&#8216;messages.py&#8217;_) and add our <a class="reference external" href="https://svn.enthought.com/enthought/browser/EnvisageCore/trunk/examples/MOTD/acme/motd/message.py">Message</a> instances to it:</p>
<div class="highlight-python"><pre>messages = [
    ...

    Message(
        author = "Martin Fowler",
        text   = "Any fool can write code that a computer can understand. Good"
        " programmers write code that humans can understand."
    )

    Message(
        author = "Chet Hendrickson",
        text   = "The rule is, 'Do the simplest thing that could possibly"
        " work', not the most stupid."
    )

    ...
]</pre>
</div>
<p>Now we create a plugin for the <a class="reference external" href="https://svn.enthought.com/enthought/browser/EnvisageCore/trunk/examples/MOTD/acme/motd/software_quotes/setup.py">acme.motd.software_quotes</a> package and tell
Envisage about the messages that we have just created:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">SoftwareQuotesPlugin</span><span class="p">(</span><span class="n">Plugin</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot; The &#39;Software Quotes&#39; plugin. &quot;&quot;&quot;</span>

    <span class="c">#### &#39;IPlugin&#39; interface ##################################################</span>

    <span class="c"># The plugin&#39;s unique identifier.</span>
    <span class="nb">id</span> <span class="o">=</span> <span class="s">&#39;acme.motd.software_quotes&#39;</span>

    <span class="c"># The plugin&#39;s name (suitable for displaying to the user).</span>
    <span class="n">name</span> <span class="o">=</span> <span class="s">&#39;Software Quotes&#39;</span>

    <span class="c">#### Contributions to extension points made by this plugin ################</span>

    <span class="c"># Messages for the &#39;Message Of The Day&#39;.</span>
    <span class="n">messages</span> <span class="o">=</span> <span class="n">List</span><span class="p">(</span><span class="n">contributes_to</span><span class="o">=</span><span class="s">&#39;acme.motd.messages&#39;</span><span class="p">)</span>

    <span class="c">###########################################################################</span>
    <span class="c"># &#39;SoftwareQuotesPlugin&#39; interface.</span>
    <span class="c">###########################################################################</span>

    <span class="k">def</span> <span class="nf">_messages_default</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot; Trait initializer. &quot;&quot;&quot;</span>

        <span class="c"># Only do imports when you need to!</span>
        <span class="kn">from</span> <span class="nn">messages</span> <span class="kn">import</span> <span class="n">messages</span>

        <span class="k">return</span> <span class="n">messages</span>
</pre></div>
</div>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar">
        <div class="sphinxsidebarwrapper">
            <h3><a href="index.html">Table Of Contents</a></h3>
            <ul>
<li><a class="reference external" href="">The &#8220;Message of the Day&#8221; (MOTD) Example</a><ul>
<li><a class="reference external" href="#plain-ol-motd">Plain Ol&#8217; MOTD</a></li>
<li><a class="reference external" href="#not-so-plain-ol-motd">Not So Plain Ol&#8217; MOTD</a></li>
<li><a class="reference external" href="#create-the-main-application-class">1) Create the main Application class</a></li>
<li><a class="reference external" href="#the-acme-motd-plugin">2) The &#8216;acme.motd&#8217; plugin</a></li>
<li><a class="reference external" href="#the-acme-motd-software-quotes-plugin">3) The &#8216;acme.motd.software_quotes&#8217; plugin</a></li>
</ul>
</li>
</ul>

            <h4>Previous topic</h4>
            <p class="topless"><a href="plugins.html"
                                  title="previous chapter">Plugins</a></p>
            <h4>Next topic</h4>
            <p class="topless"><a href="message_of_the_day_(using_eggs).html"
                                  title="next chapter">The &#8220;Message of the Day&#8221; (MOTD) Example</a></p>
            <h3>This Page</h3>
            <ul class="this-page-menu">
              <li><a href="_sources/message_of_the_day.txt"
                     rel="nofollow">Show Source</a></li>
            </ul>
          <div id="searchbox" style="display: none">
            <h3>Quick search</h3>
              <form class="search" action="search.html" method="get">
                <input type="text" name="q" size="18" />
                <input type="submit" value="Go" />
                <input type="hidden" name="check_keywords" value="yes" />
                <input type="hidden" name="area" value="default" />
              </form>
              <p class="searchtip" style="font-size: 90%">
              Enter search terms or a module, class or function name.
              </p>
          </div>
          <script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="message_of_the_day_(using_eggs).html" title="The “Message of the Day” (MOTD) Example"
             >next</a> |</li>
        <li class="right" >
          <a href="plugins.html" title="Plugins"
             >previous</a> |</li>
        <li><a href="index.html">EnvisageCore v3.1.1 documentation</a> &raquo;</li> 
      </ul>
    </div>
    <div class="footer">
      &copy; Copyright 2008, Martin Chivers.
      Last updated on Aug 21, 2009.
      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.2.
    </div>
  </body>
</html>