<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
     xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:wfw="http://wellformedweb.org/CommentAPI/"
     >
  <channel>
    <title>kusut</title>
    <link>http://kusut.web.id</link>
    <description>kusut blog</description>
    <pubDate>Wed, 02 May 2012 13:26:49 GMT</pubDate>
    <generator>Blogofile</generator>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>My Colour Theme</title>
      <link>http://kusut.web.id/2011/07/24/my-colour-theme</link>
      <pubDate>Sun, 24 Jul 2011 00:06:00 WIT</pubDate>
      <category><![CDATA[codes]]></category>
      <guid isPermaLink="true">http://kusut.web.id/2011/07/24/my-colour-theme</guid>
      <description>My Colour Theme</description>
      <content:encoded><![CDATA[<div class="document">
<p>This works fine on 256-colour terminal. <a class="reference external" href="http://thingamajig.kusut.web.id/boring.png">Screenshot</a></p>


<div class="pygments_friendly"><pre><span class="p">(</span><span class="nb">require</span> <span class="ss">&#39;color-theme</span><span class="p">)</span>

<span class="c1">;foregrounds</span>
<span class="p">(</span><span class="nb">defvar</span> <span class="nv">gainsboro</span> <span class="s">&quot;#dcdcdc&quot;</span><span class="p">)</span>
<span class="p">(</span><span class="nb">defvar</span> <span class="nv">pearlaqua</span> <span class="s">&quot;#88d8c0&quot;</span><span class="p">)</span>
<span class="p">(</span><span class="nb">defvar</span> <span class="nv">blue</span> <span class="s">&quot;#7ea4cd&quot;</span><span class="p">)</span>
<span class="p">(</span><span class="nb">defvar</span> <span class="nv">slategray</span> <span class="s">&quot;#708090&quot;</span><span class="p">)</span>
<span class="p">(</span><span class="nb">defvar</span> <span class="nv">wisteria</span> <span class="s">&quot;#c9a0dc&quot;</span><span class="p">)</span>
<span class="p">(</span><span class="nb">defvar</span> <span class="nv">papayawhip</span> <span class="s">&quot;#ffefd5&quot;</span><span class="p">)</span>

<span class="c1">;backgrounds</span>
<span class="p">(</span><span class="nb">defvar</span> <span class="nv">bg</span> <span class="s">&quot;#343434&quot;</span><span class="p">)</span>
<span class="p">(</span><span class="nb">defvar</span> <span class="nv">gray</span> <span class="s">&quot;#595959&quot;</span><span class="p">)</span>


<span class="p">(</span><span class="nb">defun</span> <span class="nv">boring</span> <span class="p">()</span>
  <span class="p">(</span><span class="nv">interactive</span><span class="p">)</span>
  <span class="p">(</span><span class="nv">color-theme-install</span>
   <span class="p">(</span><span class="nb">list</span>
    <span class="ss">&#39;boring</span>

     <span class="o">`</span><span class="p">((</span><span class="nv">background-color</span> <span class="o">.</span> <span class="o">,</span><span class="nv">bg</span><span class="p">)</span>
       <span class="p">(</span><span class="nv">background-mode</span> <span class="o">.</span> <span class="nv">dark</span><span class="p">)</span>
       <span class="p">(</span><span class="nv">border-color</span> <span class="o">.</span> <span class="o">,</span><span class="nv">bg</span><span class="p">)</span>
       <span class="p">(</span><span class="nv">cursor-color</span> <span class="o">.</span> <span class="o">,</span><span class="nv">gainsboro</span><span class="p">)</span>
       <span class="p">(</span><span class="nv">foreground-color</span> <span class="o">.</span> <span class="o">,</span><span class="nv">gainsboro</span><span class="p">)</span>
       <span class="p">(</span><span class="nv">mouse-color</span> <span class="o">.</span> <span class="o">,</span><span class="nv">bg</span><span class="p">))</span>

     <span class="o">`</span><span class="p">(</span><span class="nv">plain</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:foreground</span> <span class="o">,</span><span class="nv">gainsboro</span><span class="p">))))</span>
     <span class="o">`</span><span class="p">(</span><span class="nv">reserved</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:foreground</span> <span class="o">,</span><span class="nv">blue</span><span class="p">))))</span>
     <span class="o">`</span><span class="p">(</span><span class="nv">comment</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:foreground</span> <span class="o">,</span><span class="nv">slategray</span><span class="p">))))</span>
     <span class="o">`</span><span class="p">(</span><span class="nv">funclass</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:foreground</span> <span class="o">,</span><span class="nv">pearlaqua</span><span class="p">))))</span>
     <span class="o">`</span><span class="p">(</span><span class="nv">consvar</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:foreground</span> <span class="o">,</span><span class="nv">papayawhip</span><span class="p">))))</span>
     <span class="o">`</span><span class="p">(</span><span class="nv">literal</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:foreground</span> <span class="o">,</span><span class="nv">wisteria</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">exception</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">literal</span> <span class="ss">:bold</span> <span class="no">t</span><span class="p">))))</span>

     <span class="o">`</span><span class="p">(</span><span class="nv">hilite</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:background</span> <span class="o">,</span><span class="nv">gray</span><span class="p">))))</span>

     <span class="o">`</span><span class="p">(</span><span class="nv">fringe</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:background</span> <span class="o">,</span><span class="nv">bg</span><span class="p">))))</span>
     <span class="o">`</span><span class="p">(</span><span class="nv">mode-line</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:foreground</span> <span class="o">,</span><span class="nv">gainsboro</span> <span class="ss">:background</span> <span class="o">,</span><span class="nv">gray</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">region</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">hilite</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">flymake-errline</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">hilite</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">minibuffer-prompt</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">reserved</span> <span class="ss">:bold</span> <span class="no">t</span><span class="p">))))</span>

     <span class="o">&#39;</span><span class="p">(</span><span class="nv">font-lock-builtin-face</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">reserved</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">font-lock-keyword-face</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">reserved</span> <span class="ss">:bold</span> <span class="no">t</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">font-lock-function-name-face</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">funclass</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">font-lock-type-face</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">funclass</span> <span class="ss">:bold</span> <span class="no">t</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">font-lock-comment-face</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">comment</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">font-lock-string-face</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">literal</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">font-lock-variable-name-face</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">consvar</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">font-lock-constant-face</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">consvar</span> <span class="ss">:bold</span> <span class="no">t</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">font-lock-warning-face</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">exception</span><span class="p">))))</span>

     <span class="o">&#39;</span><span class="p">(</span><span class="nv">comint-highlight-input</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">plain</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">comint-highlight-prompt</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">reserved</span> <span class="ss">:bold</span> <span class="no">t</span><span class="p">))))</span>

     <span class="o">&#39;</span><span class="p">(</span><span class="nv">eshell-prompt</span>  <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">reserved</span> <span class="ss">:bold</span> <span class="no">t</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">eshell-ls-directory</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">reserved</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">eshell-ls-executable</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">literal</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">eshell-ls-archive</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">consvar</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">eshell-ls-product</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">consvar</span> <span class="ss">:bold</span> <span class="no">t</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">eshell-ls-symlink</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">funclass</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">eshell-ls-special</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">funclass</span> <span class="ss">:bold</span> <span class="no">t</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">eshell-ls-unreadable</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">comment</span> <span class="ss">:bold</span> <span class="no">t</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">eshell-ls-missing</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">comment</span> <span class="ss">:bold</span> <span class="no">t</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">eshell-ls-backup</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">comment</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">eshell-ls-clutter</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">comment</span><span class="p">))))</span>


     <span class="o">&#39;</span><span class="p">(</span><span class="nv">isearch</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">hilite</span> <span class="ss">:bold</span> <span class="no">t</span><span class="p">))))</span>
     <span class="o">`</span><span class="p">(</span><span class="nv">isearch-lazy-highlight-face</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:background</span> <span class="o">,</span><span class="nv">gray</span><span class="p">))))</span>

     <span class="o">&#39;</span><span class="p">(</span><span class="nv">erc-action-face</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">plain</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">erc-default-face</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">plain</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">erc-input-face</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">plain</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">erc-notice-face</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">comment</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">erc-nick-default-face</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">funclass</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">erc-nick-msg-face</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">funclass</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">erc-my-nick-face</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">funclass</span> <span class="ss">:bold</span> <span class="no">t</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">erc-current-nick-face</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">funclass</span> <span class="ss">:bold</span> <span class="no">t</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">erc-timestamp-face</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">consvar</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">erc-prompt-face</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">consvar</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">erc-direct-msg-face</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">reserved</span><span class="p">))))</span>
     <span class="o">&#39;</span><span class="p">(</span><span class="nv">erc-error-face</span> <span class="p">((</span><span class="no">t</span> <span class="p">(</span><span class="ss">:inherit</span> <span class="nv">exception</span><span class="p">))))</span>
     <span class="p">)))</span>

<span class="p">(</span><span class="k">setq</span> <span class="nv">frame-background-mode</span> <span class="ss">&#39;dark</span><span class="p">)</span> <span class="c1">;for rst</span>
<span class="p">(</span><span class="nb">provide</span> <span class="ss">&#39;boring</span><span class="p">)</span>
</pre></div>



</div>
]]></content:encoded>
    </item>
    <item>
      <title>Pyramid Traversal and MongoDB</title>
      <link>http://kusut.web.id/2011/03/27/pyramid-traversal-and-mongodb</link>
      <pubDate>Sun, 27 Mar 2011 22:06:00 WIT</pubDate>
      <category><![CDATA[codes]]></category>
      <guid isPermaLink="true">http://kusut.web.id/2011/03/27/pyramid-traversal-and-mongodb</guid>
      <description>Pyramid Traversal and MongoDB</description>
      <content:encoded><![CDATA[<div class="document">
<p>This post will talk about creating a simple web application with <a class="reference external" href="http://pylonsproject.org">Pyramid</a> and <a class="reference external" href="http://mongodb.org">MongoDB</a>. It will also talk about using a traversal method to map a requested URL to a callable function (controller/method/view/etc) in your application code.</p>
<div class="section" id="the-app">
<h3>The App</h3>
<p>Enter Troll, an anonymous board web application. It is a simple application that is similar to a blog app (post and comment). The features are:</p>
<ul class="simple">
<li>Sorted by activity (recently commented posts come first).</li>
<li>Automatic removal for the least commented post (there is  a maximum number of posts).</li>
<li>Lord Inglip summoning pedestal (read: recaptcha).</li>
</ul>
<p>The non-features:</p>
<ul class="simple">
<li>No pagination. Maybe later with webhelper. Post limit is set to 10 by default anyway.</li>
<li>No test.</li>
<li>etc</li>
</ul>
<p>The app uses a single mongodb collection for posts. The comments are embedded to a post document.</p>
<p>Source code is available <a class="reference external" href="https://bitbucket.org/kusut/troll/src">here</a>.</p>
</div>
<div class="section" id="the-stack">
<h3>The Stack</h3>
<p>This app uses few technologies</p>
<ul class="simple">
<li><a class="reference external" href="http://makotemplates.org">Mako</a> - a templating engine</li>
<li><a class="reference external" href="http://wtforms.simplecodes.com/">WTForms</a> - form generation and validation, similar to django (new)forms</li>
<li><a class="reference external" href="http://pypi.python.org/pypi/wtforms-recaptcha">wtforms-recaptcha</a> - Inglip</li>
<li><a class="reference external" href="http://mongodb.org">MongoDB</a> (<a class="reference external" href="http://api.mongodb.org/python/">pymongo</a>) - data persistence</li>
</ul>
</div>
<div class="section" id="traversal">
<h3>Traversal</h3>
<p><strong>NOTE</strong> : Traversal is optional in Pyramid. You can still use URL dispatch (pattern matching thing).</p>
<p>Traversal is a method of matching a requested URL to your application code just like a more familiar method, URL parsing and comparing it to a set of patterns. Traversal requires you to build a resource <a class="reference external" href="http://en.wikipedia.org/wiki/Tree_%28data_structure%29">tree</a> which is probably analogous to a file-system hierarchy. Pyramid will take a URL, and then traverse your resource tree trying to find a resource for that URL. Once a resource is found, Pyramid will try to find a function associated with that resource. The resource object found (or last traversed) is called context.</p>
<p><a class="reference external" href="http://www.serverzen.net/2010/11/8/getting-started-with-pyramid-a-notes-application">This post</a> gave me a good idea about traversal.</p>
<p>For this application, two kinds of resource object are needed. The first one is the root object. This object will act as a container to post objects.</p>


<div class="pygments_friendly"><pre><span class="k">class</span> <span class="nc">Root</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="n">__name__</span> <span class="o">=</span> <span class="bp">None</span>
    <span class="n">__parent__</span> <span class="o">=</span> <span class="bp">None</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">collection</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">post</span>

    <span class="k">def</span> <span class="nf">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
        <span class="n">post</span> <span class="o">=</span> <span class="n">Post</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">collection</span><span class="o">.</span><span class="n">find_one</span><span class="p">(</span><span class="nb">dict</span><span class="p">(</span><span class="n">_id</span><span class="o">=</span><span class="n">ObjectId</span><span class="p">(</span><span class="n">name</span><span class="p">))))</span>
        <span class="k">return</span> <span class="n">_assign</span><span class="p">(</span><span class="n">post</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">__len__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">collection</span><span class="o">.</span><span class="n">count</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">__iter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="p">(</span> <span class="n">_assign</span><span class="p">(</span><span class="n">Post</span><span class="p">(</span><span class="n">x</span><span class="p">),</span> <span class="nb">str</span><span class="p">(</span><span class="n">x</span><span class="p">[</span><span class="s">&#39;_id&#39;</span><span class="p">]),</span> <span class="bp">self</span><span class="p">)</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">collection</span><span class="o">.</span><span class="n">find</span><span class="p">()</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="s">&#39;updated&#39;</span><span class="p">,</span> <span class="n">DESCENDING</span><span class="p">)</span> <span class="p">)</span>
</pre></div>



<p>The __getitem__ method will return post object (the child of the root object). The root object contains all posts. _assign is just a simple function to set some attributes of resource object.</p>


<div class="pygments_friendly"><pre><span class="k">def</span> <span class="nf">_assign</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">parent</span><span class="p">):</span>
    <span class="n">obj</span><span class="o">.</span><span class="n">__name__</span> <span class="o">=</span> <span class="n">name</span>
    <span class="n">obj</span><span class="o">.</span><span class="n">__parent__</span> <span class="o">=</span> <span class="n">parent</span>
    <span class="k">return</span> <span class="n">obj</span>
</pre></div>



<p>Next is the post object. This object is a slightly modified python dictionary (pymongo returns mongodb document as a python dict). Resource tree objects need to have a __parent__ attribute.</p>


<div class="pygments_friendly"><pre><span class="k">class</span> <span class="nc">Post</span><span class="p">(</span><span class="nb">dict</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">a_dict</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Post</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">a_dict</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">__name__</span> <span class="o">=</span> <span class="bp">None</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">__parent__</span> <span class="o">=</span> <span class="bp">None</span>
</pre></div>



</div>
<div class="section" id="the-views">
<h3>The Views</h3>
<p>This is the function for viewing a resource object.</p>


<div class="pygments_friendly"><pre><span class="nd">@view_config</span><span class="p">(</span><span class="n">renderer</span><span class="o">=</span><span class="s">&#39;single.html&#39;</span><span class="p">,</span> <span class="n">context</span><span class="o">=</span><span class="n">resources</span><span class="o">.</span><span class="n">Post</span><span class="p">)</span>
<span class="nd">@view_config</span><span class="p">(</span><span class="n">renderer</span><span class="o">=</span><span class="s">&#39;index.html&#39;</span><span class="p">,</span> <span class="n">context</span><span class="o">=</span><span class="n">resources</span><span class="o">.</span><span class="n">Root</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">view</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
    <span class="n">form</span> <span class="o">=</span> <span class="n">TrollForm</span><span class="p">()</span>
    <span class="k">return</span> <span class="p">{</span><span class="s">&#39;p&#39;</span><span class="p">:</span> <span class="n">context</span><span class="p">,</span> <span class="s">&#39;form&#39;</span><span class="p">:</span> <span class="n">form</span><span class="p">}</span>
</pre></div>



<p>Pyramid allows you to write a function once and then register it multiple times for different contexts. Coming up is the function for handling post and comment addition.</p>


<div class="pygments_friendly"><pre><span class="nd">@view_config</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s">&#39;add&#39;</span><span class="p">,</span> <span class="n">request_method</span><span class="o">=</span><span class="s">&#39;POST&#39;</span><span class="p">,</span> <span class="n">context</span><span class="o">=</span><span class="n">resources</span><span class="o">.</span><span class="n">Post</span><span class="p">)</span>
<span class="nd">@view_config</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s">&#39;add&#39;</span><span class="p">,</span> <span class="n">request_method</span><span class="o">=</span><span class="s">&#39;POST&#39;</span><span class="p">,</span> <span class="n">context</span><span class="o">=</span><span class="n">resources</span><span class="o">.</span><span class="n">Root</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">add</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
    <span class="n">author</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">params</span><span class="p">[</span><span class="s">&#39;name&#39;</span><span class="p">]</span>
    <span class="n">content</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">params</span><span class="p">[</span><span class="s">&#39;content&#39;</span><span class="p">]</span>
    <span class="n">_add</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="n">author</span><span class="p">,</span> <span class="n">content</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">HTTPFound</span><span class="p">(</span><span class="n">location</span><span class="o">=</span><span class="n">request</span><span class="o">.</span><span class="n">resource_url</span><span class="p">(</span><span class="n">context</span><span class="p">))</span>
</pre></div>



<p>Here is the _add function.</p>


<div class="pygments_friendly"><pre><span class="k">def</span> <span class="nf">_add</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="n">author</span><span class="p">,</span> <span class="n">content</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">context</span><span class="o">.</span><span class="n">__parent__</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
        <span class="n">_post</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">collection</span><span class="p">,</span>
              <span class="n">author</span><span class="p">,</span>
              <span class="n">content</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">_comment</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">__parent__</span><span class="o">.</span><span class="n">collection</span><span class="p">,</span>
                 <span class="n">context</span><span class="p">[</span><span class="s">&#39;_id&#39;</span><span class="p">],</span>
                 <span class="n">author</span><span class="p">,</span>
                 <span class="n">content</span><span class="p">)</span>
</pre></div>



<p>Finally, doing insert/upsert to MongoDB.</p>


<div class="pygments_friendly"><pre><span class="k">def</span> <span class="nf">_post</span><span class="p">(</span><span class="n">collection</span><span class="p">,</span> <span class="n">author</span><span class="p">,</span> <span class="n">content</span><span class="p">):</span>
    <span class="n">p</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="n">author</span><span class="o">=</span><span class="n">author</span><span class="p">,</span>
             <span class="n">content</span><span class="o">=</span><span class="n">content</span><span class="p">,</span>
             <span class="n">comments</span><span class="o">=</span><span class="p">[],</span>
             <span class="n">updated</span><span class="o">=</span><span class="n">datetime</span><span class="o">.</span><span class="n">utcnow</span><span class="p">(),</span>
             <span class="n">time</span><span class="o">=</span><span class="n">datetime</span><span class="o">.</span><span class="n">utcnow</span><span class="p">())</span>
    <span class="n">collection</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span><span class="n">p</span><span class="p">)</span>
    <span class="c">#remove unpopular post if &gt;  10</span>
    <span class="k">if</span> <span class="n">collection</span><span class="o">.</span><span class="n">find</span><span class="p">()</span><span class="o">.</span><span class="n">count</span><span class="p">()</span> <span class="o">&gt;</span> <span class="mi">10</span><span class="p">:</span>
        <span class="n">collection</span><span class="o">.</span><span class="n">remove</span><span class="p">({</span><span class="s">&#39;_id&#39;</span><span class="p">:</span> <span class="p">[</span><span class="n">x</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">collection</span><span class="o">.</span><span class="n">find</span><span class="p">()</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="s">&quot;updated&quot;</span><span class="p">,</span> <span class="n">DESCENDING</span><span class="p">)][</span><span class="o">-</span><span class="mi">1</span><span class="p">][</span><span class="s">&#39;_id&#39;</span><span class="p">]})</span>


<span class="k">def</span> <span class="nf">_comment</span><span class="p">(</span><span class="n">collection</span><span class="p">,</span> <span class="n">post_id</span><span class="p">,</span> <span class="n">author</span><span class="p">,</span> <span class="n">comment</span><span class="p">):</span>
    <span class="n">post</span> <span class="o">=</span> <span class="n">collection</span><span class="o">.</span><span class="n">find_one</span><span class="p">(</span><span class="nb">dict</span><span class="p">(</span><span class="n">_id</span><span class="o">=</span><span class="n">post_id</span><span class="p">))</span>
    <span class="n">time</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">utcnow</span><span class="p">()</span>
    <span class="n">post</span><span class="p">[</span><span class="s">&#39;comments&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">dict</span><span class="p">(</span><span class="n">author</span><span class="o">=</span><span class="n">author</span><span class="p">,</span>
                                 <span class="n">comment</span><span class="o">=</span><span class="n">comment</span><span class="p">,</span>
                                 <span class="n">time</span><span class="o">=</span><span class="n">time</span><span class="p">))</span>
    <span class="n">post</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="nb">dict</span><span class="p">(</span><span class="n">updated</span><span class="o">=</span><span class="n">time</span><span class="p">))</span>
    <span class="n">collection</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="n">post</span><span class="p">)</span>
</pre></div>



</div>
<div class="section" id="templating">
<h3>Templating</h3>
<p>Post form and comment form have the same fields (author, content, and captcha) and use the same form class (from wtforms). To prevent typing the same thing in many places, I created a template macro.</p>


<div class="pygments_friendly"><pre><span class="cp">&lt;%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">&quot;createform(c, form)&quot;</span><span class="cp">&gt;</span><span class="x"></span>
<span class="x">    </span><span class="cp">&lt;%</span> <span class="n">link</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">resource_url</span><span class="p">(</span><span class="n">c</span><span class="p">)</span><span class="cp">%&gt;</span><span class="x"></span>
<span class="x">    &lt;form method=&quot;POST&quot; action=&quot;</span><span class="cp">${</span><span class="n">link</span><span class="cp">}</span><span class="x">@@add&quot;&gt;</span>
<span class="x">        &lt;div&gt; </span><span class="cp">${</span><span class="n">form</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">label</span><span class="cp">}</span><span class="x">: </span><span class="cp">${</span><span class="n">form</span><span class="o">.</span><span class="n">name</span><span class="p">(</span><span class="n">size</span><span class="o">=</span><span class="mi">50</span><span class="p">)</span><span class="cp">}</span><span class="x">&lt;/div&gt;</span>
<span class="x">        &lt;div&gt; </span><span class="cp">${</span><span class="n">form</span><span class="o">.</span><span class="n">content</span><span class="o">.</span><span class="n">label</span><span class="cp">}</span><span class="x">: </span><span class="cp">${</span><span class="n">form</span><span class="o">.</span><span class="n">content</span><span class="p">(</span><span class="n">rows</span><span class="o">=</span><span class="mi">5</span><span class="p">,</span> <span class="n">cols</span><span class="o">=</span><span class="mi">50</span><span class="p">)</span><span class="cp">}</span><span class="x">&lt;/div&gt;</span>
<span class="x">        </span><span class="cp">${</span><span class="n">form</span><span class="o">.</span><span class="n">captcha</span><span class="cp">}</span><span class="x"></span>
<span class="x">        &lt;input type=&quot;submit&quot; value=&quot;Submit!&quot;/&gt;</span>
<span class="x">    &lt;/form&gt;</span>
<span class="cp">&lt;/%</span><span class="nb">def</span><span class="cp">&gt;</span><span class="x"></span>
</pre></div>



<p>This macro takes a context and a form object, to generate an html form. URL for any resource can easily be retrieved via resource_url method on request object. The '&#64;&#64;' means the start of a view name. Pyramid will traverse the URL until '&#64;&#64;', and search for a view named 'add' for that context.</p>
<p>This is how to use it.</p>


<div class="pygments_friendly"><pre><span class="cp">${</span><span class="n">createform</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">context</span><span class="p">,</span> <span class="n">form</span><span class="p">)</span><span class="cp">}</span><span class="x"></span>
</pre></div>



<p>If you want to use it on another template file, import it first.</p>


<div class="pygments_friendly"><pre><span class="cp">&lt;%</span><span class="nb">namespace</span> <span class="na">file=</span><span class="s">&quot;base.html&quot;</span> <span class="na">import=</span><span class="s">&quot;createform&quot;</span> <span class="cp">/&gt;</span><span class="x"></span>
</pre></div>



</div>
<div class="section" id="conclusion">
<h3>Conclusion</h3>
<p>Pyramid is a fun framework to tinker with.</p>
<p><a class="reference external" href="https://bitbucket.org/kusut/troll/src">Source Code</a></p>
</div>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>Hello World</title>
      <link>http://kusut.web.id/2011/03/12/hello-world</link>
      <pubDate>Sat, 12 Mar 2011 22:24:00 WIT</pubDate>
      <category><![CDATA[codes]]></category>
      <guid isPermaLink="true">http://kusut.web.id/2011/03/12/hello-world</guid>
      <description>Hello World</description>
      <content:encoded><![CDATA[<div class="document">
<p>I finally decided to stop using wordpress and do static blogging instead. I chose <a class="reference external" href="http://blogofile.com">Blogofile</a> as my new blog engine because it's python, pretty active and has good docs.</p>
<div class="section" id="my-changes">
<h3>My Changes</h3>
<p>These are what I learned.</p>
<ul>
<li><p class="first">I want to write my blog in rst format. I am not familiar with it so I am going to use my blog as a learning tool. The problem is, currently, rst does not play nice with code highlighting. Luckily, there is already <a class="reference external" href="http://techspot.zzzeek.org/2010/12/06/my-blogofile-hacks">a great solution</a>  for that.</p>
</li>
<li><p class="first">I feel pygments' default style, 'murphy', does not look right in my theme so I changed the default style to 'friendly' by putting this on syntax_highlighter.py:</p>


<div class="pygments_friendly"><pre><span class="n">config</span> <span class="o">=</span> <span class="p">{</span><span class="s">&#39;style&#39;</span><span class="p">:</span> <span class="s">&#39;friendly&#39;</span><span class="p">}</span>
</pre></div>



</li>
<li><p class="first">Blogofile assumes that your disqus username is similar to your site name (sitename.disqus.com). You might want to store them in a different variables if they are different, and use them accordingly on template files.</p>
</li>
<li><p class="first">Be sure sure to load your css files made by pygments:</p>


<div class="pygments_friendly"><pre><span class="cp">%</span> <span class="k">for</span> <span class="n">css_file</span> <span class="ow">in</span> <span class="n">bf</span><span class="o">.</span><span class="n">config</span><span class="o">.</span><span class="n">filters</span><span class="o">.</span><span class="n">syntax_highlight</span><span class="o">.</span><span class="n">mod</span><span class="o">.</span><span class="n">css_files_written</span><span class="p">:</span><span class="x"></span>
<span class="x">    &lt;link rel=&#39;stylesheet&#39; href=&#39;</span><span class="cp">${</span><span class="n">css_file</span><span class="cp">}</span><span class="x">&#39; type=&#39;text/css&#39; /&gt;</span>
<span class="cp">%</span><span class="k"> endfor</span><span class="x"></span>
</pre></div>



</li>
</ul>
<p>That is probably it. I also learned about mako a bit. So, all set? Not quite. There is one thing left.</p>
</div>
<div class="section" id="deployment-method">
<h3>Deployment Method</h3>
<p>Using a static blogging engine (web compiler) needs you to figure out how you want to update your blog on live server. It is a lot of work compared to usual dynamic blogging but with the right tools it can be handled. The plus is it is easy moving/updating sites once you are set.</p>
<p>I am still undecided on this issue. Here are my concerns:</p>
<ul class="simple">
<li>Do I include compiled files in version control? or just the source?</li>
<li>What is the favorable method for me to bring the site live? mercurial hook or fabric and scp/rsync?</li>
</ul>
<p>I tried mercurial hooks and it went well. I also installed python 2.7.1 and blogofile on the server, so the blog can be built there. I have a feeling that I will not decide on this matter for a long time and continue to use only ssh and scp. Nevertheless, I am going to put this on revision control even if I do not end up using its hooks for deployment.</p>
<p><strong>Update</strong> : I chose to use fabric to manage this blog. Only compiled html files are deployed (build locally).</p>
</div>
</div>
]]></content:encoded>
    </item>
  </channel>
</rss>

