<?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>Death of a Gremmie</title>
    <link>http://deathofagremmie.com</link>
    <description>Brian Neal's blog about programming.</description>
    <pubDate>Fri, 28 Dec 2012 17:08:15 GMT</pubDate>
    <generator>Blogofile</generator>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>A Red-Black Tree in Python</title>
      <link>http://deathofagremmie.com/2012/12/28/a-red-black-tree-in-python</link>
      <pubDate>Fri, 28 Dec 2012 11:10:00 CST</pubDate>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[datastructures]]></category>
      <guid isPermaLink="true">http://deathofagremmie.com/2012/12/28/a-red-black-tree-in-python</guid>
      <description>A Red-Black Tree in Python</description>
      <content:encoded><![CDATA[<div class="document">
<p>I've been working my way through Allen Downey's <a class="reference external" href="http://www.greenteapress.com/compmod/">Think Complexity</a> book. I'm
not very far in, but so far it's a great way to brush up on algorithms and
datastructures, and learn some new stuff about complexity science. Plus, all of
the code is written in Python! I've been doing the exercises, and most of them
take at most fifteen or twenty minutes. But at the end of his explanation on
hash tables he casually lobs this one out (3.4, exercise 5):</p>
<blockquote>
<p>A drawback of hashtables is that the elements have to be hashable, which
usually means they have to be immutable. That’s why, in Python, you can use
tuples but not lists as keys in a dictionary. An alternative is to use
a tree-based map.</p>
<p>Write an implementation of the map interface called TreeMap that uses
a red-black tree to perform add and get in log time.</p>
</blockquote>
<p>I've never researched red-black trees before, but as a C++ programmer I know
they are the datastructure that powers <tt class="docutils literal"><span class="pre">std::set</span></tt> and <tt class="docutils literal"><span class="pre">std::map</span></tt>. So
I decided to take a look. I quickly realized this was not going to be a simple
exercise, as red-black trees are quite complicated to understand and implement.
They are basically binary search trees that do a lot of work to keep themselves
approximately balanced.</p>
<p>I spent a few nights reading up on red-black trees. A good explanation can be
found in <a class="reference external" href="http://en.wikipedia.org/wiki/Red%E2%80%93black_tree">Wikipedia</a>. There are even a handful of Python implementations
floating about, of varying quality. But finally I found a detailed explanation
that really clicked with me at <a class="reference external" href="http://www.eternallyconfuzzled.com/tuts/datastructures/jsw_tut_rbtree.aspx">Eternally Confuzzled</a>. Julienne Walker derives
his own algorithm based upon the rules for red-black trees, and his
implementation code is non-recursive and top-down. Most of the other
implementations I found on the web seem to be based on the textbook
<a class="reference external" href="http://mitpress.mit.edu/books/introduction-algorithms">Introduction To Algorithms</a>, and often involve the use of parent pointers
and using dummy nodes to represent the nil leaves of the tree. Julienne's
solution avoided these things and seemed a bit less complex. However the best
reason to study his tutorial was his explanation was very coherent and
detailed. The other sources on the web seemed to be fragmented, missing
details, and lacking in explanation.</p>
<p>So to complete my <a class="reference external" href="http://www.greenteapress.com/compmod/">Think Complexity</a> exercise, I decided to port Julienne's
red-black tree algorithm from C to Python, and hopefully learn something along
the way. After a couple nights of work, and one <a class="reference external" href="http://deathofagremmie.com/2012/12/27/a-c-python-chained-assignment-gotcha/">very embarrassing bug</a>, I've
completed it. I can't say I quite understand every bit of the algorithm, but
I certainly learned a lot. You can view the <a class="reference external" href="https://bitbucket.org/bgneal/think_complexity/src/0326803882adc4a598d890ee4d7d39d93cb64af7/redblacktree.py?at=default">source code at Bitbucket</a>, or
clone my <a class="reference external" href="https://bitbucket.org/bgneal/think_complexity">Think Complexity repository</a>.</p>
<p>Many thanks to Julienne Walker for his <a class="reference external" href="http://www.eternallyconfuzzled.com/tuts/datastructures/jsw_tut_rbtree.aspx">great tutorial</a>! And I highly recommend
<a class="reference external" href="http://www.greenteapress.com/compmod/">Think Complexity</a>. Check them both out.</p>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>A C & Python chained assignment gotcha</title>
      <link>http://deathofagremmie.com/2012/12/27/a-c-python-chained-assignment-gotcha</link>
      <pubDate>Thu, 27 Dec 2012 14:45:00 CST</pubDate>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[C++]]></category>
      <guid isPermaLink="true">http://deathofagremmie.com/2012/12/27/a-c-python-chained-assignment-gotcha</guid>
      <description>A C & Python chained assignment gotcha</description>
      <content:encoded><![CDATA[<div class="document">
<p>Late last night I had a marathon debugging session where I discovered I had
been burned by not fully understanding chaining assignment statements in
Python. I was porting some C code to Python that had some chained assignment
expressions. C and C++ programmers are well used to this idiom which has the
following meaning:</p>
<div class="highlight"><pre><span class="n">a</span> <span class="o">=</span> <span class="n">b</span> <span class="o">=</span> <span class="n">c</span> <span class="o">=</span> <span class="n">d</span> <span class="o">=</span> <span class="n">e</span><span class="p">;</span>      <span class="c1">// C/C++ code</span>

<span class="c1">// The above is equivalent to this:</span>

<span class="n">a</span> <span class="o">=</span> <span class="p">(</span><span class="n">b</span> <span class="o">=</span> <span class="p">(</span><span class="n">c</span> <span class="o">=</span> <span class="p">(</span><span class="n">d</span> <span class="o">=</span> <span class="n">e</span><span class="p">)));</span>
</pre></div>
<p>This is because in C, assignments are actually expressions that return a value,
and they are right-associative.</p>
<p>I knew that Python supported this syntax, and I had a vague memory that it was
not the same semantically as C, but I was in a hurry. After playing a bit in the
shell I convinced myself this chained assignment was doing what I wanted. My
Python port kept this syntax and I drove on. A huge mistake!</p>
<p>Hours later, of course, I found out the hard way the two are not exactly
equivalent. For one thing, in Python, assignment is a statement, not an
expression. There is no 'return value' from an assignment. The Python syntax
does allow chaining for convenience, but the meaning is subtly different.</p>
<div class="highlight"><pre><span class="n">a</span> <span class="o">=</span> <span class="n">b</span> <span class="o">=</span> <span class="n">c</span> <span class="o">=</span> <span class="n">d</span> <span class="o">=</span> <span class="n">e</span>    <span class="c"># Python code</span>

<span class="c"># The above is equivalent to these lines of code:</span>
<span class="n">a</span> <span class="o">=</span> <span class="n">e</span>
<span class="n">b</span> <span class="o">=</span> <span class="n">e</span>
<span class="n">c</span> <span class="o">=</span> <span class="n">e</span>
<span class="n">d</span> <span class="o">=</span> <span class="n">e</span>
</pre></div>
<p>Now usually, I suspect, you can mix the C/C++ meaning with Python and not get
tripped up. But I was porting some tricky red-black tree code, and it made
a huge difference. Here is the C code first, and then the Python.</p>
<div class="highlight"><pre><span class="n">p</span> <span class="o">=</span> <span class="n">p</span><span class="o">-&gt;</span><span class="n">link</span><span class="p">[</span><span class="n">last</span><span class="p">]</span> <span class="o">=</span> <span class="n">tree_rotate</span><span class="p">(</span><span class="n">q</span><span class="p">,</span> <span class="n">dir</span><span class="p">);</span>

<span class="c1">// The above is equivalent to:</span>

<span class="n">p</span> <span class="o">=</span> <span class="p">(</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">link</span><span class="p">[</span><span class="n">last</span><span class="p">]</span> <span class="o">=</span> <span class="n">tree_rotate</span><span class="p">(</span><span class="n">q</span><span class="p">,</span> <span class="n">dir</span><span class="p">));</span>
</pre></div>
<p>The straight (and incorrect) Python port of this code:</p>
<div class="highlight"><pre><span class="n">p</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="n">link</span><span class="p">[</span><span class="n">last</span><span class="p">]</span> <span class="o">=</span> <span class="n">tree_rotate</span><span class="p">(</span><span class="n">q</span><span class="p">,</span> <span class="n">d</span><span class="p">)</span>

<span class="c"># The above code is equivalent to this:</span>
<span class="n">temp</span> <span class="o">=</span> <span class="n">tree_rotate</span><span class="p">(</span><span class="n">q</span><span class="p">,</span> <span class="n">d</span><span class="p">)</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">temp</span>                                   <span class="c"># Oops</span>
<span class="n">p</span><span class="o">.</span><span class="n">link</span><span class="p">[</span><span class="n">last</span><span class="p">]</span> <span class="o">=</span> <span class="n">temp</span>                        <span class="c"># Oops</span>
</pre></div>
<p>Do you see the problem? It is glaringly obvious to me now. The C and Python
versions are not equivalent because the Python version is executing the code in
a different order. The flaw comes about because <tt class="docutils literal">p</tt> is used multiple times in
the chained assignment and is now susceptible to an out-of-order problem.</p>
<p>In the C version, the tree node pointed at by <tt class="docutils literal">p</tt> has one of its child links
changed first, then <tt class="docutils literal">p</tt> is advanced to the value of the new child. In the
Python version, the tree node referenced by the name <tt class="docutils literal">p</tt> is changed first,
and then its child link is altered! This introduced a very subtle bug that cost
me a few hours of bleary-eyed debugging.</p>
<p>Watch out for this when you are porting C to Python or vice versa. I already
avoid this syntax in both languages in my own code, but I do admit it is nice
for conciseness and let it slip in occasionally.</p>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>Integrating Django and MoinMoin with Redis</title>
      <link>http://deathofagremmie.com/2012/12/02/integrating-django-and-moinmoin-with-redis</link>
      <pubDate>Sun, 02 Dec 2012 14:50:00 CST</pubDate>
      <category><![CDATA[MoinMoin]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[Django]]></category>
      <guid isPermaLink="true">http://deathofagremmie.com/2012/12/02/integrating-django-and-moinmoin-with-redis</guid>
      <description>Integrating Django and MoinMoin with Redis</description>
      <content:encoded><![CDATA[<div class="document">
<div class="section" id="we-want-a-wiki">
<h3>We want a Wiki!</h3>
<p>Over at <a class="reference external" href="http://surfguitar101.com">SurfGuitar101.com</a>, we decided we'd like to have a wiki to capture
community knowledge. I briefly looked at candidate wiki engines with an eye
towards integrating them with <a class="reference external" href="https://www.djangoproject.com">Django</a>, the framework that powers
<a class="reference external" href="http://surfguitar101.com">SurfGuitar101.com</a>. And of course I was biased towards a wiki solution that was
written in <a class="reference external" href="http://www.python.org">Python</a>. I had tried a few wikis in the past, including the behemoth
<a class="reference external" href="http://www.mediawiki.org">MediaWiki</a>. MediaWiki is a very powerful piece of software, but it is also
quite complex, and I didn't want to have to maintain a PHP infrastructure to run
it.</p>
<p>Enter <a class="reference external" href="http://moinmo.in/">MoinMoin</a>. This is a mature wiki platform that is actively maintained and
written in Python. It is full featured but did not seem overly complex to me.
It stores its pages in flat files, which seemed appealing for our likely small
wiki needs. It turns out I had been a user of MoinMoin for many years without
really knowing it. The <a class="reference external" href="http://wiki.python.org/moin/">Python.org wiki</a>, <a class="reference external" href="http://mercurial.selenic.com/wiki/">Mercurial wiki</a>, and <a class="reference external" href="http://www.omniorb-support.com/omniwiki">omniORB
wiki</a> are all powered by <a class="reference external" href="http://moinmo.in/">MoinMoin</a>. We'd certainly be in good company.</p>
</div>
<div class="section" id="single-sign-on">
<h3>Single Sign-On</h3>
<p>The feature that clinched it was MoinMoin's flexible <a class="reference external" href="http://moinmo.in/HelpOnAuthentication">authentication system</a>.
It would be very desirable if my users did not have to sign into Django and
then sign in again to the wiki with possibly a different username. Managing two
different password databases would be a real headache. The ideal solution would
mean signing into Django would log the user into MoinMoin with the same
username automatically.</p>
<p>MoinMoin supports this with their <a class="reference external" href="http://moinmo.in/HelpOnAuthentication/ExternalCookie">external cookie authentication</a> mechanism.
The details are provided in the previous link; basically a Django site needs to
perform the following:</p>
<ol class="arabic simple">
<li>Set an external cookie for MoinMoin to read whenever a user logs into Django.</li>
<li>To prevent spoofing, the Django application should create a record that the
cookie was created in some shared storage area accessible to MoinMoin. This
allows MoinMoin to validate that the cookie is legitimate and not a fake.</li>
<li>When the user logs out of the Django application, it should delete this
external cookie and the entry in the shared storage area.</li>
<li>Periodically the Django application should expire entires in the shared
storage area for clean-up purposes. Otherwise this storage would grow and
grow if users never logged out. Deleting entries older than the external
cookie's age should suffice.</li>
</ol>
</div>
<div class="section" id="my-django-implementation">
<h3>My Django Implementation</h3>
<p>There are of course many ways to approach this problem. Here is what I came up
with. I created a Django application called <em>wiki</em> to hold this integration
code. There is quite a lot of code here, too much to conveniently show in this
blog post. I will post snippets below, but you can refer to the complete code
in my <a class="reference external" href="https://bitbucket.org/bgneal/sg101">Bitbucket repository</a>. You can also view online the <a class="reference external" href="https://bitbucket.org/bgneal/sg101/src/a5b8f25e1752faf71ed429ec7f22ff6f3b3dc851/wiki?at=default">wiki application in
bitbucket</a> for convenience.</p>
<p>Getting notified of when users log into or out of Django is made easy thanks to
Django's <a class="reference external" href="https://docs.djangoproject.com/en/1.4/topics/auth/#login-and-logout-signals">login and logout signals</a>. By creating a signal handler I can be
notified when a user logs in or out. The signal handler code looks like this:</p>
<div class="highlight"><pre><span class="kn">import</span> <span class="nn">logging</span>
<span class="kn">from</span> <span class="nn">django.contrib.auth.signals</span> <span class="kn">import</span> <span class="n">user_logged_in</span><span class="p">,</span> <span class="n">user_logged_out</span>
<span class="kn">from</span> <span class="nn">wiki.constants</span> <span class="kn">import</span> <span class="n">SESSION_SET_MEMBER</span>

<span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="n">__name__</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">login_callback</span><span class="p">(</span><span class="n">sender</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Signal callback function for a user logging in.</span>

<span class="sd">    Sets a flag for the middleware to create an external cookie.</span>

<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&#39;User login: </span><span class="si">%s</span><span class="s">&#39;</span><span class="p">,</span> <span class="n">user</span><span class="o">.</span><span class="n">username</span><span class="p">)</span>

    <span class="n">request</span><span class="o">.</span><span class="n">wiki_set_cookie</span> <span class="o">=</span> <span class="bp">True</span>

<span class="k">def</span> <span class="nf">logout_callback</span><span class="p">(</span><span class="n">sender</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Signal callback function for a user logging in.</span>

<span class="sd">    Sets a flag for the middleware to delete the external cookie.</span>

<span class="sd">    Since the user is about to logout, her session will be wiped out after</span>
<span class="sd">    this function returns. This forces us to set an attribute on the request</span>
<span class="sd">    object so that the response middleware can delete the wiki&#39;s cookie.</span>

<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="n">user</span><span class="p">:</span>
        <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&#39;User logout: </span><span class="si">%s</span><span class="s">&#39;</span><span class="p">,</span> <span class="n">user</span><span class="o">.</span><span class="n">username</span><span class="p">)</span>

        <span class="c"># Remember what Redis set member to delete by adding an attribute to the</span>
        <span class="c"># request object:</span>
        <span class="n">request</span><span class="o">.</span><span class="n">wiki_delete_cookie</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">SESSION_SET_MEMBER</span><span class="p">)</span>


<span class="n">user_logged_in</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">login_callback</span><span class="p">,</span> <span class="n">dispatch_uid</span><span class="o">=</span><span class="s">&#39;wiki.signals.login&#39;</span><span class="p">)</span>
<span class="n">user_logged_out</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">logout_callback</span><span class="p">,</span> <span class="n">dispatch_uid</span><span class="o">=</span><span class="s">&#39;wiki.signals.logout&#39;</span><span class="p">)</span>
</pre></div>
<p>When a user logs in I want to create an external cookie for MoinMoin. But
cookies can only be created on <a class="reference external" href="https://docs.djangoproject.com/en/1.4/ref/request-response/#httpresponse-objects">HttpResponse</a> objects, and all we have access to
here in the signal handler is the request object. The solution here is to set
an attribute on the request object that a later piece of <a class="reference external" href="https://docs.djangoproject.com/en/1.4/topics/http/middleware/">middleware</a> will
process. I at first resisted this approach, thinking it was kind of hacky.
I initially decided to set a flag in the session, but then found out that in
some cases the session is not always available. I then reviewed some of the
Django supplied middleware classes and saw that they also set attributes on the
request object, so this must be an acceptable practice.</p>
<p>My middleware looks like this.</p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">WikiMiddleware</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Check for flags on the request object to determine when to set or delete an</span>
<span class="sd">    external cookie for the wiki application. When creating a cookie, also</span>
<span class="sd">    set an entry in Redis that the wiki application can validate to prevent</span>
<span class="sd">    spoofing.</span>

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

    <span class="k">def</span> <span class="nf">process_response</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="n">response</span><span class="p">):</span>

        <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="s">&#39;wiki_set_cookie&#39;</span><span class="p">):</span>
            <span class="n">create_wiki_session</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">response</span><span class="p">)</span>
        <span class="k">elif</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="s">&#39;wiki_delete_cookie&#39;</span><span class="p">):</span>
            <span class="n">destroy_wiki_session</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">wiki_delete_cookie</span><span class="p">,</span> <span class="n">response</span><span class="p">)</span>

        <span class="k">return</span> <span class="n">response</span>
</pre></div>
<p>The <tt class="docutils literal">create_wiki_session()</tt> function creates the cookie for MoinMoin and
stores a hash of the cookie in a shared storage area for MoinMoin to validate.
In our case, <a class="reference external" href="http://redis.io/">Redis</a> makes an excellent shared storage area. We create a sorted
set in Redis to store our cookie hashes. The score for each hash is the
timestamp of when the cookie was created. This allows us to easily delete
expired cookies by score periodically.</p>
<div class="highlight"><pre><span class="k">def</span> <span class="nf">create_wiki_session</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">response</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Sets up the session for the external wiki application.</span>

<span class="sd">    Creates the external cookie for the Wiki.</span>
<span class="sd">    Updates the Redis set so the Wiki can verify the cookie.</span>

<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">now</span> <span class="o">=</span> <span class="n">datetime</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">value</span> <span class="o">=</span> <span class="n">cookie_value</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">user</span><span class="p">,</span> <span class="n">now</span><span class="p">)</span>
    <span class="n">response</span><span class="o">.</span><span class="n">set_cookie</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">WIKI_COOKIE_NAME</span><span class="p">,</span>
            <span class="n">value</span><span class="o">=</span><span class="n">value</span><span class="p">,</span>
            <span class="n">max_age</span><span class="o">=</span><span class="n">settings</span><span class="o">.</span><span class="n">WIKI_COOKIE_AGE</span><span class="p">,</span>
            <span class="n">domain</span><span class="o">=</span><span class="n">settings</span><span class="o">.</span><span class="n">WIKI_COOKIE_DOMAIN</span><span class="p">)</span>

    <span class="c"># Update a sorted set in Redis with a hash of our cookie and a score</span>
    <span class="c"># of the current time as a timestamp. This allows us to delete old</span>
    <span class="c"># entries by score periodically. To verify the cookie, the external wiki</span>
    <span class="c"># application computes a hash of the cookie value and checks to see if</span>
    <span class="c"># it is in our Redis set.</span>

    <span class="n">h</span> <span class="o">=</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">sha256</span><span class="p">()</span>
    <span class="n">h</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
    <span class="n">name</span> <span class="o">=</span> <span class="n">h</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>
    <span class="n">score</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">mktime</span><span class="p">(</span><span class="n">now</span><span class="o">.</span><span class="n">utctimetuple</span><span class="p">())</span>
    <span class="n">conn</span> <span class="o">=</span> <span class="n">get_redis_connection</span><span class="p">()</span>

    <span class="k">try</span><span class="p">:</span>
        <span class="n">conn</span><span class="o">.</span><span class="n">zadd</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">WIKI_REDIS_SET</span><span class="p">,</span> <span class="n">score</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
    <span class="k">except</span> <span class="n">redis</span><span class="o">.</span><span class="n">RedisError</span><span class="p">:</span>
        <span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">&quot;Error adding wiki cookie key&quot;</span><span class="p">)</span>

    <span class="c"># Store the set member name in the session so we can delete it when the</span>
    <span class="c"># user logs out:</span>
    <span class="n">request</span><span class="o">.</span><span class="n">session</span><span class="p">[</span><span class="n">SESSION_SET_MEMBER</span><span class="p">]</span> <span class="o">=</span> <span class="n">name</span>
</pre></div>
<p>We store the name of the Redis set member in the user's session so we can
delete it from Redis when the user logs out. During logout, this set member is
retrieved from the session in the logout signal handler and stored on the
request object. This is because the session will be destroyed after the logout
signal handler runs and before the middleware can access it. The middleware
can check for the existence of this attribute as its cue to delete the wiki
session.</p>
<div class="highlight"><pre><span class="k">def</span> <span class="nf">destroy_wiki_session</span><span class="p">(</span><span class="n">set_member</span><span class="p">,</span> <span class="n">response</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Destroys the session for the external wiki application.</span>

<span class="sd">    Delete the external cookie.</span>
<span class="sd">    Deletes the member from the Redis set as this entry is no longer valid.</span>

<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">response</span><span class="o">.</span><span class="n">delete_cookie</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">WIKI_COOKIE_NAME</span><span class="p">,</span>
                           <span class="n">domain</span><span class="o">=</span><span class="n">settings</span><span class="o">.</span><span class="n">WIKI_COOKIE_DOMAIN</span><span class="p">)</span>

    <span class="k">if</span> <span class="n">set_member</span><span class="p">:</span>
        <span class="n">conn</span> <span class="o">=</span> <span class="n">get_redis_connection</span><span class="p">()</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">conn</span><span class="o">.</span><span class="n">zrem</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">WIKI_REDIS_SET</span><span class="p">,</span> <span class="n">set_member</span><span class="p">)</span>
        <span class="k">except</span> <span class="n">redis</span><span class="o">.</span><span class="n">RedisError</span><span class="p">:</span>
            <span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">&quot;Error deleting wiki cookie set member&quot;</span><span class="p">)</span>
</pre></div>
<p>As suggested in the MoinMoin external cookie documentation, I create a cookie
whose value consists of the username, email address, and a key separated by
the <tt class="docutils literal">#</tt> character. The key is just a string of stuff that makes it difficult
for a spoofer to recreate.</p>
<div class="highlight"><pre><span class="k">def</span> <span class="nf">cookie_value</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">now</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Creates the value for the external wiki cookie.&quot;&quot;&quot;</span>

    <span class="c"># The key part of the cookie is just a string that would make things</span>
    <span class="c"># difficult for a spoofer; something that can&#39;t be easily made up:</span>

    <span class="n">h</span> <span class="o">=</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">sha256</span><span class="p">()</span>
    <span class="n">h</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">user</span><span class="o">.</span><span class="n">username</span> <span class="o">+</span> <span class="n">user</span><span class="o">.</span><span class="n">email</span><span class="p">)</span>
    <span class="n">h</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">now</span><span class="o">.</span><span class="n">isoformat</span><span class="p">())</span>
    <span class="n">h</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="s">&#39;&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">random</span><span class="o">.</span><span class="n">sample</span><span class="p">(</span><span class="n">string</span><span class="o">.</span><span class="n">printable</span><span class="p">,</span> <span class="mi">64</span><span class="p">)))</span>
    <span class="n">h</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">SECRET_KEY</span><span class="p">)</span>
    <span class="n">key</span> <span class="o">=</span> <span class="n">h</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>

    <span class="n">parts</span> <span class="o">=</span> <span class="p">(</span><span class="n">user</span><span class="o">.</span><span class="n">username</span><span class="p">,</span> <span class="n">user</span><span class="o">.</span><span class="n">email</span><span class="p">,</span> <span class="n">key</span><span class="p">)</span>
    <span class="k">return</span> <span class="s">&#39;#&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">parts</span><span class="p">)</span>
</pre></div>
<p>Finally on the Django side we should periodically delete expired Redis set
members in case users do not log out. Since I am using <a class="reference external" href="http://celeryproject.org/">Celery</a> with my Django
application, I created a Celery task that runs periodically to delete old set
members. This function is a bit longer than it probably needs to be, but
I wanted to log how big this set is before and after we cull the expired
entries.</p>
<div class="highlight"><pre><span class="nd">@task</span>
<span class="k">def</span> <span class="nf">expire_cookies</span><span class="p">():</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Periodically run this task to remove expired cookies from the Redis set</span>
<span class="sd">    that is shared between this Django application &amp; the MoinMoin wiki for</span>
<span class="sd">    authentication.</span>

<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">now</span> <span class="o">=</span> <span class="n">datetime</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">cutoff</span> <span class="o">=</span> <span class="n">now</span> <span class="o">-</span> <span class="n">datetime</span><span class="o">.</span><span class="n">timedelta</span><span class="p">(</span><span class="n">seconds</span><span class="o">=</span><span class="n">settings</span><span class="o">.</span><span class="n">WIKI_COOKIE_AGE</span><span class="p">)</span>
    <span class="n">min_score</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">mktime</span><span class="p">(</span><span class="n">cutoff</span><span class="o">.</span><span class="n">utctimetuple</span><span class="p">())</span>

    <span class="n">conn</span> <span class="o">=</span> <span class="n">get_redis_connection</span><span class="p">()</span>

    <span class="n">set_name</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">WIKI_REDIS_SET</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="n">count</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="n">zcard</span><span class="p">(</span><span class="n">set_name</span><span class="p">)</span>
    <span class="k">except</span> <span class="n">redis</span><span class="o">.</span><span class="n">RedisError</span><span class="p">:</span>
        <span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">&quot;Error getting zcard&quot;</span><span class="p">)</span>
        <span class="k">return</span>

    <span class="k">try</span><span class="p">:</span>
        <span class="n">removed</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="n">zremrangebyscore</span><span class="p">(</span><span class="n">set_name</span><span class="p">,</span> <span class="mf">0.0</span><span class="p">,</span> <span class="n">min_score</span><span class="p">)</span>
    <span class="k">except</span> <span class="n">redis</span><span class="o">.</span><span class="n">RedisError</span><span class="p">:</span>
        <span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">&quot;Error removing by score&quot;</span><span class="p">)</span>
        <span class="k">return</span>

    <span class="n">total</span> <span class="o">=</span> <span class="n">count</span> <span class="o">-</span> <span class="n">removed</span>
    <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;Expire wiki cookies: removed </span><span class="si">%d</span><span class="s">, total is now </span><span class="si">%d</span><span class="s">&quot;</span><span class="p">,</span>
            <span class="n">removed</span><span class="p">,</span> <span class="n">total</span><span class="p">)</span>
</pre></div>
</div>
<div class="section" id="moinmoin-implementation">
<h3>MoinMoin Implementation</h3>
<p>As described in the MoinMoin external cookie documentation, you have to
configure MoinMoin to use your external cookie authentication mechanism.
It is also nice to disable the ability for the MoinMoin user to change their
username and email address since that is being managed by the Django
application. These changes to the MoinMoin <tt class="docutils literal">Config</tt> class are shown below.</p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">Config</span><span class="p">(</span><span class="n">multiconfig</span><span class="o">.</span><span class="n">DefaultConfig</span><span class="p">):</span>

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

    <span class="c"># Use ExternalCookie method for integration authentication with Django:</span>
    <span class="n">auth</span> <span class="o">=</span> <span class="p">[</span><span class="n">ExternalCookie</span><span class="p">(</span><span class="n">autocreate</span><span class="o">=</span><span class="bp">True</span><span class="p">)]</span>

    <span class="c"># remove ability to change username &amp; email, etc.</span>
    <span class="n">user_form_disable</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;name&#39;</span><span class="p">,</span> <span class="s">&#39;aliasname&#39;</span><span class="p">,</span> <span class="s">&#39;email&#39;</span><span class="p">,]</span>
    <span class="n">user_form_remove</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;password&#39;</span><span class="p">,</span> <span class="s">&#39;password2&#39;</span><span class="p">,</span> <span class="s">&#39;css_url&#39;</span><span class="p">,</span> <span class="s">&#39;logout&#39;</span><span class="p">,</span> <span class="s">&#39;create&#39;</span><span class="p">,</span>
            <span class="s">&#39;account_sendmail&#39;</span><span class="p">,</span> <span class="s">&#39;jid&#39;</span><span class="p">]</span>
</pre></div>
<p>Next we create an <tt class="docutils literal">ExternalCookie</tt> class and associated helper functions to
process the cookie and verify it in Redis. This code is shown in its entirety
below. It is based off the example in the MoinMoin external cookie
documentation, but uses Redis as the shared storage area.</p>
<div class="highlight"><pre><span class="kn">import</span> <span class="nn">hashlib</span>
<span class="kn">import</span> <span class="nn">Cookie</span>
<span class="kn">import</span> <span class="nn">logging</span>

<span class="kn">from</span> <span class="nn">MoinMoin.auth</span> <span class="kn">import</span> <span class="n">BaseAuth</span>
<span class="kn">from</span> <span class="nn">MoinMoin.user</span> <span class="kn">import</span> <span class="n">User</span>
<span class="kn">import</span> <span class="nn">redis</span>

<span class="n">COOKIE_NAME</span> <span class="o">=</span> <span class="s">&#39;YOUR_COOKIE_NAME_HERE&#39;</span>

<span class="c"># Redis connection and database settings</span>
<span class="n">REDIS_HOST</span> <span class="o">=</span> <span class="s">&#39;localhost&#39;</span>
<span class="n">REDIS_PORT</span> <span class="o">=</span> <span class="mi">6379</span>
<span class="n">REDIS_DB</span> <span class="o">=</span> <span class="mi">0</span>

<span class="c"># The name of the set in Redis that holds cookie hashes</span>
<span class="n">REDIS_SET</span> <span class="o">=</span> <span class="s">&#39;wiki_cookie_keys&#39;</span>

<span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="n">__name__</span><span class="p">)</span>


<span class="k">def</span> <span class="nf">get_cookie_value</span><span class="p">(</span><span class="n">cookie</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Returns the value of the Django cookie from the cookie.</span>
<span class="sd">    None is returned if the cookie is invalid or the value cannot be</span>
<span class="sd">    determined.</span>

<span class="sd">    This function works around an issue with different Python versions.</span>
<span class="sd">    In Python 2.5, if you construct a SimpleCookie with a dict, then</span>
<span class="sd">        type(cookie[key]) == unicode</span>
<span class="sd">    whereas in later versions of Python:</span>
<span class="sd">        type(cookie[key]) == Cookie.Morsel</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="n">cookie</span><span class="p">:</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">morsel</span> <span class="o">=</span> <span class="n">cookie</span><span class="p">[</span><span class="n">COOKIE_NAME</span><span class="p">]</span>
        <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
            <span class="k">return</span> <span class="bp">None</span>

        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">morsel</span><span class="p">,</span> <span class="nb">unicode</span><span class="p">):</span>             <span class="c"># Python 2.5</span>
            <span class="k">return</span> <span class="n">morsel</span>
        <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">morsel</span><span class="p">,</span> <span class="n">Cookie</span><span class="o">.</span><span class="n">Morsel</span><span class="p">):</span>     <span class="c"># Python 2.6+</span>
            <span class="k">return</span> <span class="n">morsel</span><span class="o">.</span><span class="n">value</span>

    <span class="k">return</span> <span class="bp">None</span>


<span class="k">def</span> <span class="nf">get_redis_connection</span><span class="p">(</span><span class="n">host</span><span class="o">=</span><span class="n">REDIS_HOST</span><span class="p">,</span> <span class="n">port</span><span class="o">=</span><span class="n">REDIS_PORT</span><span class="p">,</span> <span class="n">db</span><span class="o">=</span><span class="n">REDIS_DB</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Create and return a Redis connection using the supplied parameters.</span>

<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">return</span> <span class="n">redis</span><span class="o">.</span><span class="n">StrictRedis</span><span class="p">(</span><span class="n">host</span><span class="o">=</span><span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="o">=</span><span class="n">port</span><span class="p">,</span> <span class="n">db</span><span class="o">=</span><span class="n">db</span><span class="p">)</span>


<span class="k">def</span> <span class="nf">validate_cookie</span><span class="p">(</span><span class="n">value</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Determines if cookie was created by Django. Returns True on success,</span>
<span class="sd">    False on failure.</span>

<span class="sd">    Looks up the hash of the cookie value in Redis. If present, cookie</span>
<span class="sd">    is deemed legit.</span>

<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">h</span> <span class="o">=</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">sha256</span><span class="p">()</span>
    <span class="n">h</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
    <span class="n">set_member</span> <span class="o">=</span> <span class="n">h</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>

    <span class="n">conn</span> <span class="o">=</span> <span class="n">get_redis_connection</span><span class="p">()</span>
    <span class="n">success</span> <span class="o">=</span> <span class="bp">False</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="n">score</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="n">zscore</span><span class="p">(</span><span class="n">REDIS_SET</span><span class="p">,</span> <span class="n">set_member</span><span class="p">)</span>
        <span class="n">success</span> <span class="o">=</span> <span class="n">score</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span>
    <span class="k">except</span> <span class="n">redis</span><span class="o">.</span><span class="n">RedisError</span><span class="p">:</span>
        <span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">&#39;Could not check Redis for ExternalCookie auth&#39;</span><span class="p">)</span>

    <span class="k">return</span> <span class="n">success</span>


<span class="k">class</span> <span class="nc">ExternalCookie</span><span class="p">(</span><span class="n">BaseAuth</span><span class="p">):</span>
    <span class="n">name</span> <span class="o">=</span> <span class="s">&#39;external_cookie&#39;</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">autocreate</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">autocreate</span> <span class="o">=</span> <span class="n">autocreate</span>
        <span class="n">BaseAuth</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="k">def</span> <span class="nf">request</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="n">user_obj</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="n">user</span> <span class="o">=</span> <span class="bp">None</span>
        <span class="n">try_next</span> <span class="o">=</span> <span class="bp">True</span>

        <span class="k">try</span><span class="p">:</span>
            <span class="n">cookie</span> <span class="o">=</span> <span class="n">Cookie</span><span class="o">.</span><span class="n">SimpleCookie</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">cookies</span><span class="p">)</span>
        <span class="k">except</span> <span class="n">Cookie</span><span class="o">.</span><span class="n">CookieError</span><span class="p">:</span>
            <span class="n">cookie</span> <span class="o">=</span> <span class="bp">None</span>

        <span class="n">val</span> <span class="o">=</span> <span class="n">get_cookie_value</span><span class="p">(</span><span class="n">cookie</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">val</span><span class="p">:</span>
            <span class="k">try</span><span class="p">:</span>
                <span class="n">username</span><span class="p">,</span> <span class="n">email</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">val</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&#39;#&#39;</span><span class="p">)</span>
            <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
                <span class="k">return</span> <span class="n">user</span><span class="p">,</span> <span class="n">try_next</span>

            <span class="k">if</span> <span class="n">validate_cookie</span><span class="p">(</span><span class="n">val</span><span class="p">):</span>
                <span class="n">user</span> <span class="o">=</span> <span class="n">User</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="n">username</span><span class="p">,</span> <span class="n">auth_username</span><span class="o">=</span><span class="n">username</span><span class="p">,</span>
                        <span class="n">auth_method</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>

                <span class="n">changed</span> <span class="o">=</span> <span class="bp">False</span>
                <span class="k">if</span> <span class="n">email</span> <span class="o">!=</span> <span class="n">user</span><span class="o">.</span><span class="n">email</span><span class="p">:</span>
                    <span class="n">user</span><span class="o">.</span><span class="n">email</span> <span class="o">=</span> <span class="n">email</span>
                    <span class="n">changed</span> <span class="o">=</span> <span class="bp">True</span>

                <span class="k">if</span> <span class="n">user</span><span class="p">:</span>
                    <span class="n">user</span><span class="o">.</span><span class="n">create_or_update</span><span class="p">(</span><span class="n">changed</span><span class="p">)</span>
                <span class="k">if</span> <span class="n">user</span> <span class="ow">and</span> <span class="n">user</span><span class="o">.</span><span class="n">valid</span><span class="p">:</span>
                    <span class="n">try_next</span> <span class="o">=</span> <span class="bp">False</span>

        <span class="k">return</span> <span class="n">user</span><span class="p">,</span> <span class="n">try_next</span>
</pre></div>
</div>
<div class="section" id="conclusion">
<h3>Conclusion</h3>
<p>I've been running this setup for a month now and it is working great. My users
and I are enjoying our shiny new MoinMoin wiki integrated with our Django
powered community website. The single sign-on experience is quite seamless and
eliminates the need for separate accounts.</p>
</div>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>Completing the Enigma Challenge</title>
      <link>http://deathofagremmie.com/2012/07/22/completing-the-enigma-challenge</link>
      <pubDate>Sun, 22 Jul 2012 13:30:00 CDT</pubDate>
      <category><![CDATA[Py-Enigma]]></category>
      <category><![CDATA[Enigma]]></category>
      <category><![CDATA[C++]]></category>
      <category><![CDATA[Cpp-Enigma]]></category>
      <guid isPermaLink="true">http://deathofagremmie.com/2012/07/22/completing-the-enigma-challenge</guid>
      <description>Completing the Enigma Challenge</description>
      <content:encoded><![CDATA[<div class="document">
<p>Since my last <a class="reference external" href="http://deathofagremmie.com/2012/06/06/introducing-py-enigma/">blog post</a>, I have spent
almost all my free time working on <a class="reference external" href="http://users.telenet.be/d.rijmenants/en/challenge.htm">Dirk Rijmenants' Enigma Challenge</a>. I'm very happy to
report that I cracked the last message on the evening of July 10. I thought it
might be interesting to summarize my experiences working on this challenge in a
blog post.</p>
<div class="section" id="the-first-nine">
<h3>The first nine</h3>
<p>I had a lot of fun building <a class="reference external" href="https://bitbucket.org/bgneal/enigma">Py-Enigma</a>, an Enigma machine simulator library
written in <a class="reference external" href="http://www.python.org">Python</a> based on the information I found on Dirk's <a class="reference external" href="http://users.telenet.be/d.rijmenants/en/enigmatech.htm">Technical Details
of the Enigma Machine</a> page. After I had built it and played with it for a
while, I discovered Dirk also had an <a class="reference external" href="http://users.telenet.be/d.rijmenants/en/challenge.htm">Enigma Challenge</a>. I decided this would
be a good test for <a class="reference external" href="https://bitbucket.org/bgneal/enigma">Py-Enigma</a>, and it may give me some ideas on how to improve
the library for breaking messages.</p>
<p>The first nine messages were pretty easy to solve using <a class="reference external" href="https://bitbucket.org/bgneal/enigma">Py-Enigma</a>. Dirk gives
you most of the key information for each problem, and one can then write a small
program to brute force the missing information. I was able to solve the first
nine messages in a weekend. This was very enjoyable, as it did require some
thinking about how to simulate the problem and then executing it. I also learned
about <a class="reference external" href="http://docs.python.org/library/itertools.html">Python's itertools</a>
library, which contains some very handy functions for generating permutations
and combinations for brute forcing a solution.</p>
<p>Dirk did a great job on the messages. They referenced actual events from World
War II and I ended up spending a fair amount of time on Wikipedia reading about
them. Translating the messages from German to English was a bit difficult, but I
relied heavily on <a class="reference external" href="http://translate.google.com">Google Translate</a>.</p>
</div>
<div class="section" id="message-10">
<h3>Message 10</h3>
<p>But then I came to the last message. Here, Dirk doesn't give you any key
information, just ciphertext. Gulp. If you include 2 possible reflectors, the
Enigma machine's key space for message 10 is somewhere around 2 x 10<sup>23</sup> keys, so it is impossible to brute force every possible key, unless
you can afford to wait around for the heat death of the universe.</p>
<p>I then did some research, and learned about a technique for brute-forcing only
the rotor and message settings, and then performing a heuristic technique called
&quot;hill-climbing&quot; on the plugboard settings. I am deeply indepted to Frode Weierud
and Geoff Sullivan, who have published high level descriptions of this
technique. See Frode's <a class="reference external" href="http://cryptocellar.org/Enigma/">The Enigma Collection</a> page and Geoff's <a class="reference external" href="http://www.hut-six.co.uk/">Crypto Barn</a> for more information.</p>
</div>
<div class="section" id="python-is-too-slow-or-is-it">
<h3>Python is too slow, or is it?</h3>
<p>After a week or so of studying and tinkering, I came up with a hill-climbing
algorithm in Python. I then started an attempt to break message 10, but after
running the program for a little over 24 hours, I realized it was too slow. I
did a &quot;back of the envelope&quot; calculation and determined I would need several
hundred years to hill-climb every rotor and message setting. This was a bit
disappointing, but I knew it was a possibility going in.</p>
<p>I then set out, somewhat reluctantly, to port Py-Enigma to C++. These days I
don't do any C++ at home, only at work. However I got much happier when I
decided this was an opportunity to try out some new C++11 features (the embedded
compiler we use at work has no support for C++11). Okay, things are fun again! I
have to say that C++11 is really quite enjoyable, and I made good use of the new
<tt class="docutils literal">auto</tt> style variable declarations, range-based for-loops, and brace-style
initialization for containers like <tt class="docutils literal">vector</tt> and <tt class="docutils literal">map</tt>.</p>
</div>
<div class="section" id="c-is-too-slow-or-is-it">
<h3>C++ is too slow, or is it?</h3>
<p>It took a fair amount of time to re-tool my code to C++11. I ensured all my unit
tests originally written in Python could pass in C++, and that I could solve
some of the previous messages. I then re-implemented my hill-climbing
algorithm in C++ and made another attempt at cracking message 10.</p>
<p>My C++ solution was indeed faster, but only by a factor of 8 or 9. I calculated
I would need about 35 years to hill-climb all rotor and message settings, and I
didn't really want to see if I could out-live my program. My morale was very low
at this point. I wasn't sure if I could ever solve this self-imposed problem.</p>
</div>
<div class="section" id="algorithms-data-structures-are-key">
<h3>Algorithms &amp; Data Structures are key</h3>
<p>I had wanted to test myself with this problem and had avoided looking at anyone
else's source code. However, at this juncture, I needed some help. I turned to
Stephan Krah's <a class="reference external" href="http://www.bytereef.org/m4_project.html">M4 Message Breaking Project</a>. Stephan had started a distributed
computing attack on several 4-rotor naval Enigma machine messages. He had
graciously made his source code available. Perhaps I could get some hints by
looking at his code.</p>
<p>Indeed, Stephen's code provided the break I needed. I discovered a very cool
trick that Stephen was doing right before he started his hill-climb. He
pre-computed every path through the machine for every letter of the alphabet.
Since hill-climbing involves running the message through the machine roughly
600 to 1000 times, this proved to be a huge time saver. After borrowing this
idea, my hill-climbing times for one fixed rotor &amp; message setting went down
from 250 milliseconds to 2!</p>
<p>I immediately stopped looking at Stephen's code at this point; I didn't bother
to compare our hill-climbing algorithms. I believe both of us are influenced by
Weierud &amp; Sullivan here. I was now convinced I had the speed-up I needed to make
a serious attempt at message 10 again.</p>
<p>This showed me how critically important it is to have the right data structure
and algorithm for a problem. However there were two other lessons I needed to
learn before I was successful.</p>
</div>
<div class="section" id="utilize-all-your-computing-resources">
<h3>Utilize all your computing resources</h3>
<p>Up to this point my cracking program was linear. It started at the first rotor
and message setting, then hill-climbed and noted the score I got. Then it
proceeded to the next message setting and hill-climbed, noting the score of that
attempt, and so on. There were two problems with this approach.</p>
<p>I realized if I could do some sort of multi-processing, I could search the key
space faster. I thought about forking off multiple processes or maybe using
threads, but that was over-thinking it. In the end, I added command-line
arguments to the program to tell it where in the key space to start looking. I
could then simply run multiple instances of my program. My development laptop,
which runs Ubuntu, is from 2008, and it has 2 cores in it. My desktop PC (for
gaming), has 4 cores! I next spent a couple nights installing <a class="reference external" href="http://www.mingw.org/">MinGW</a> and getting
my application to build in that environment. I could now run 6 instances of my
cracking program. Hopefully this would pay off and shorten the time further.</p>
<p>(I didn't even attempt to commandeer my wife's and kids' computers. That
wouldn't have gone down so well.)</p>
</div>
<div class="section" id="how-do-you-know-when-you-are-done">
<h3>How do you know when you are done?</h3>
<p>The final problem that I had was determining when my cracking program had in
fact cracked the message. The hill-climbing attempts produced scores for each
key setting. Up to this point, based on running my program on messages 1 through
9, I had noticed that when I got a score divided by the message length of around
10 I had cracked the message. But my tests on messages 1 through 9 were
hill-climbing using the known ring settings. My message cracker was using a
shortcut: I was only searching ring settings on the &quot;fast&quot; rotor to save time.
This would let me get the first part of a message, but if the middle or
left-most rotor stepped at the wrong time the rest of the message would be
unintelligible.</p>
<p>To verify my message cracking program, I ran it on some of the previous
messages. I was shooting for a score divided by message length of 10. Using this
heuristic, I was in fact able to crack some of the previous messages, but not
others. It took me a while to realize that not searching the middle rotor's ring
setting was causing this. The light bulb came on, and I realized that my
heuristic of 10 is only valid when I search all the ring settings. Instead I
should just keep track of the highest scores. When you get close enough, the
score will be significantly higher than average score. Thus I may not know when
I am done until I see a large spike in the score. I would then have to write
another program to refine the solution to search for the middle and left-most
ring setting.</p>
</div>
<div class="section" id="success-at-last">
<h3>Success at last</h3>
<p>It took a little over a month of evenings and weekends to get to this point.
I even had a false start where I ran my program on 6 cores for 1.5 days only to
realize I had a bug in my code and I was only searching ring setting 0 on the
fast ring. But once I had that worked out, I started a search on 6 cores on a
Sunday night. I checked the logs off and on Monday, but no significant spike in
the scores were noted. Before leaving for work on Tuesday I checked again, and
noticed that one instance of my program had found a score twice as high as any
other. Could that be it? I really wanted to stay and find out, but I had to go
to work! Needless to say I was a bit distracted at work that day.</p>
<p>After work, I ran the settings through my Python application and my heart
pounded as I recognized a few German words at the beginning of the message. In
fact I had gotten around 75% of the message, then some garbage, but then the
last few words were recognizable German. I then wrote another application to
search the middle ring setting space. Using the highest score from that program
allowed me to finally see the entire message. I cannot tell you how happy and
relieved I was at the same time!</p>
</div>
<div class="section" id="final-thoughts">
<h3>Final thoughts</h3>
<p>For a while I didn't think I was going to be smart enough or just plain up to
the task of solving message 10. Looking back on it, I see a nice progression of
trying things, experimenting, setbacks, and a few &quot;a-ha&quot; moments that lead to the
breakthrough. I am very grateful to Dirk Rijmenants for creating the challenge,
which was a lot of fun. And I also wish to thank Frode Weierud and Geoff
Sullivan for their hill-climbing algorithm description. Thanks again to Stephan
Krah for the key speedup that made my attempt possible.</p>
<p>For now I have decided not to publish my cracking program, since it is a tiny
bit specific to Dirk's challenge. I don't want to ruin his Enigma Challenge by
giving anything away. I don't believe my broad descriptions here have revealed
too much. Other people need to experience the challenge for themselves to fully
appreciate the thrill and hard work that go into code breaking.</p>
<p>I should also note that there are other ways of solving Dirk's challenge. You
could, with a bit of patience, solve messages 1 through 9 with one of the many
Enigma Machine GUI simulators (Dirk has a fine one). I'm not certain how
you could break message 10 using a GUI simulator and trial and error, however.</p>
<p>It is my understanding that this style of Enigma message breaking was not the
technique used by the allied code-breakers during the war. I believe they used
knowledge of certain key words, or &quot;cribs&quot;, in messages received in weather
reports and other regular messages to find the key for the day. I look forward
to reading more about their efforts now.</p>
<p>Finally, I have published the C++11 port of <a class="reference external" href="https://bitbucket.org/bgneal/enigma">Py-Enigma</a>, which I am calling
(rather unimaginatively) <a class="reference external" href="https://bitbucket.org/bgneal/cpp-enigma">Cpp-Enigma</a> on bitbucket. I hope <a class="reference external" href="https://bitbucket.org/bgneal/cpp-enigma">Cpp-Enigma</a> and
<a class="reference external" href="https://bitbucket.org/bgneal/enigma">Py-Enigma</a> are useful for other people who want to explore the fascinating world
of Enigma codes.</p>
</div>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>Introducing Py-Enigma</title>
      <link>http://deathofagremmie.com/2012/06/06/introducing-py-enigma</link>
      <pubDate>Wed, 06 Jun 2012 18:45:00 CDT</pubDate>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Py-Enigma]]></category>
      <category><![CDATA[Enigma]]></category>
      <guid isPermaLink="true">http://deathofagremmie.com/2012/06/06/introducing-py-enigma</guid>
      <description>Introducing Py-Enigma</description>
      <content:encoded><![CDATA[<div class="document">
<div class="section" id="py-enigma">
<h3>Py-Enigma</h3>
<p>For some strange reason, I don't even remember why or how, I found myself
browsing the <a class="reference external" href="http://en.wikipedia.org/wiki/Enigma_machine">Wikipedia page for the Enigma Machine</a>. I quickly became fascinated and
started surfing around some more. I found several Enigma machine simulators,
some of them even online. It suddenly occured to me that it would be a fun
project to try and write my own in <a class="reference external" href="http://www.python.org">Python</a>. I wanted to challenge myself to see
if I could figure it all without help, so I vowed not to look at anyone else's
source code.</p>
<p>In order to write an Enigma simulator, you need a really good technical
explanation of how it worked, along with numerous details like how the rotors
were wired. Fortunately I very quickly found Dirk Rijmenants' incredible <a class="reference external" href="http://users.telenet.be/d.rijmenants/index.htm">Cipher
Machines and Cryptology website</a>. In particular, his <a class="reference external" href="http://users.telenet.be/d.rijmenants/en/enigmatech.htm">Technical Details of the
Enigma Machine</a> page was exactly what I was looking for, a real gold mine of
information.</p>
<p>I had a long Memorial Day weekend, so I spent many hours in front of the
computer, consuming every word of Dirk's explanations and trying to sort it all
out in my head. And so a very fun marathon hacking session began. In the end I
got it figured out, and you cannot believe how excited I was when I was able to
decode actual Enigma messages from World War II!</p>
<p>And so <a class="reference external" href="https://bitbucket.org/bgneal/enigma">Py-Enigma</a> was born! Py-Enigma is
a historically accurate simulation library for war-time Enigma machines, written
in Python 3. I also included a simple command-line application for doing
scripting or quick commad-line experiments.</p>
</div>
<div class="section" id="lessons-learned">
<h3>Lessons learned</h3>
<p>Since I didn't really know what I was doing at first, I wrote little classes for
each of the components and unit tested them. I'm really glad I did this because
not only did it find bugs, it also made me think harder about the problem and
made me realize I didn't understand everything. When you make a mistake in
cryptography, very often the answer you get is gibberish and there is no way to
tell how close you are to the right answer. This was almost the case here, and I
think I stumbled upon an Enigma weakness that the allied codebreakers must have
seen also. I had a bug in my rotor stepping algorithm, and I got the right
answer up until the point where the right rotor stepped the middle rotor, then
the output went all garbage. Once I noticed this, I was able to focus on the
stepping algorithm and find the bug. I'm sure the allied codebreakers must have
experienced the same thing when they were guessing what rotors were being used
for the message they were cracking.</p>
<p>I also decided to use this little project to really learn <a class="reference external" href="http://sphinx.pocoo.org/">Sphinx</a>. I had dabbled
around in it before when I contributed some documentation patches to <a class="reference external" href="http://www.djangoproject.com/">Django</a>. I
think writing the documentation took almost as long as my research and coding,
but with Sphinx at least it was fun! It is a very useful and powerful package. I
also checked out the awesome <a class="reference external" href="http://readthedocs.org">readthedocs.org</a> and
quickly got my documentation <a class="reference external" href="http://py-enigma.readthedocs.org/">hosted there</a>. What a fantastic service! Now whenever I
push changes to bitbucket my docs are automatically built on readthedocs!</p>
<p>This was also my second project that I put up on PyPI. I'm a little bit more
comfortable with the packaging process, but it is still a bit bewildering given
all the choices.</p>
</div>
<div class="section" id="conclusion">
<h3>Conclusion</h3>
<p>I hope folks who are interested in history, cryptography, World War II, and
Python find Py-Enigma useful and fun! You can get the code from either the
<a class="reference external" href="https://bitbucket.org/bgneal/enigma">Py-Enigma Bitbucket page</a> or from <a class="reference external" href="http://pypi.python.org/pypi/py-enigma/">PyPI</a>. And a big thank-you to Dirk
Rijmenants!  Without his hard work and detailed explanation, Py-Enigma would
have been considerably more difficult.</p>
</div>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>Introducing weighmail</title>
      <link>http://deathofagremmie.com/2012/05/24/introducing-weighmail</link>
      <pubDate>Thu, 24 May 2012 19:30:00 CDT</pubDate>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[weighmail]]></category>
      <category><![CDATA[IMAPClient]]></category>
      <category><![CDATA[Gmail]]></category>
      <guid isPermaLink="true">http://deathofagremmie.com/2012/05/24/introducing-weighmail</guid>
      <description>Introducing weighmail</description>
      <content:encoded><![CDATA[<div class="document">
<p>Recently my wife approached me and told me that Gmail was warning her that she
was using 95% of her (free) quota. This was a bit surprising, but my wife does a
lot of photography, and sends lots of photos through the mail to various people.
So I began helping her trying to find her large messages. It was then that I
learned that Gmail provides no easy way to do this. You can't sort by size. You
can search for specific attachments, for example .psd or .jpg, and that is what
she ended up doing.</p>
<p>Surely I thought there must be an easier way. I thought that perhaps Gmail might
have an API like their other products. A bit of searching turned up that the
only API to Gmail is <a class="reference external" href="http://en.wikipedia.org/wiki/Internet_Message_Access_Protocol">IMAP</a>. I didn't know anything about IMAP, but I do know
some Python. And sure enough, Python has a library for IMAP called <a class="reference external" href="http://docs.python.org/library/imaplib.html">imaplib</a>.
Glancing through imaplib I got the impression it was a very low-level library
and I began to get a bit discouraged.</p>
<p>I continued doing some searching and I quickly found <a class="reference external" href="http://imapclient.freshfoo.com/">IMAPClient</a>, a high-level
and friendlier library for working with IMAP. This looked like it could work
very well for me!</p>
<p>I started thinking about writing an application to find big messages in a Gmail
account. The most obvious and natural way to flag large messages would be to
slap a Gmail label on them. But could IMAPClient do this? It didn't look like
it. It turns out that labels are part of a set of <a class="reference external" href="https://developers.google.com/google-apps/gmail/imap_extensions">custom Gmail IMAP
extensions</a>, and IMAPClient didn't support them. Yet.</p>
<p>I contacted the author of IMAPClient, <a class="reference external" href="http://freshfoo.com/blog/">Menno Smits</a>, and quickly learned he is
a very friendly and encouraging guy. I decided to volunteer a patch, as this
would give me a chance to learn something about IMAP. He readily agreed and I
dove in.</p>
<p>The short version of the story is I learned a heck of a lot from reading the
source to IMAPClient, and was able to contribute a patch for Gmail label support
and even some tests!</p>
<p>After the patch was accepted I went to work on my application, which I have
dubbed <a class="reference external" href="https://bitbucket.org/bgneal/weighmail/">weighmail</a>. I was even able to figure out how to put <a class="reference external" href="http://pypi.python.org/pypi/weighmail/0.1.0">weighmail up on
PyPI</a> thanks to Menno's example.</p>
<p>So if you need a program to categorize your Gmail by message size, I hope
weighmail will meet your needs. Please try it out and feel free to send me
feedback and feature requests on the Bitbucket issue tracker.</p>
<p>I have used it maybe a half-dozen times on my Gmail account now.  My Gmail
account is only about 26% full and I have about 26,300 messages in my &quot;All Mail&quot;
folder. Run times for weighmail have varied from six to 15 minutes when adding 3
label categories for size. I was (and am) kind of worried that Gmail may lock me
out of my account for accessing it too heavily, but knock on wood it hasn't yet.
Perhaps they rate limit the responses and that is why the run times vary so
much.</p>
<p>In any event, I hope you find it useful. A big thank you to Menno Smits for his
IMAPClient library, his advice, and working with me on the patch. Hooray for
open source!</p>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>Fixed pages for Django</title>
      <link>http://deathofagremmie.com/2012/05/13/fixed-pages-for-django</link>
      <pubDate>Sun, 13 May 2012 13:30:00 CDT</pubDate>
      <category><![CDATA[Django]]></category>
      <guid isPermaLink="true">http://deathofagremmie.com/2012/05/13/fixed-pages-for-django</guid>
      <description>Fixed pages for Django</description>
      <content:encoded><![CDATA[<div class="document">
<p>I have been using Django's <a class="reference external" href="https://docs.djangoproject.com/en/1.4/ref/contrib/flatpages/">flatpages app</a> for some simple, static pages that
were supposed to be temporary. I slapped a Javascript editor on the admin page
and it has worked very well. However some of the pages have long outlived their
&quot;temporary&quot; status, and I find myself needing to update them. It is then that I
get angry at the Javascript editor, and there is no way to keep any kind of
history on the page without having to fish through old database backups. I
started to think it would be nice to write the content in a nice markup
language, for example <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a>, which I could then commit to version
control. I would just need a way to generate HTML from the source text to
produce the flatpage content.</p>
<p>Of course I could use the template filters in <a class="reference external" href="https://docs.djangoproject.com/en/1.4/ref/contrib/markup/">django.contrib.markup</a>. But
turning markup into HTML at page request time can be more expensive than I like.
Yes, I could cache the page, but I'd like the process to be more explicit.</p>
<p>In my first attempt at doing this, I wrote a <a class="reference external" href="https://docs.djangoproject.com/en/1.4/howto/custom-management-commands/">custom management command</a> that
used a dictionary in my <tt class="docutils literal">settings.py</tt> file to map reStructuredText files to
flatpage URLs. My management command would open the input file, convert it to
HTML, then find the <tt class="docutils literal">FlatPage</tt> object associated with the URL. It would then
update the object with the new HTML content and save it.</p>
<p>This worked okay, but in the end I decided that the pages I wanted to update
were not temporary, quick &amp; dirty pages, which is kind of how I view flatpages.
So I decided to stop leaning on the flatpages app for these pages.</p>
<p>I then modified the management command to read a given input file, convert it
to an HTML fragment, then save it in my templates directory. Thus, a file stored
in my project directory as <tt class="docutils literal">fixed/about.rst</tt> would get transformed to
<tt class="docutils literal">templates/fixed/about.html</tt>. Here is the source to the command which I saved
as <tt class="docutils literal">make_fixed_page.py</tt>:</p>
<div class="highlight"><pre><span class="kn">import</span> <span class="nn">os.path</span>
<span class="kn">import</span> <span class="nn">glob</span>

<span class="kn">import</span> <span class="nn">docutils.core</span>
<span class="kn">from</span> <span class="nn">django.core.management.base</span> <span class="kn">import</span> <span class="n">LabelCommand</span><span class="p">,</span> <span class="n">CommandError</span>
<span class="kn">from</span> <span class="nn">django.conf</span> <span class="kn">import</span> <span class="n">settings</span>


<span class="k">class</span> <span class="nc">Command</span><span class="p">(</span><span class="n">LabelCommand</span><span class="p">):</span>
    <span class="n">help</span> <span class="o">=</span> <span class="s">&quot;Generate HTML from restructured text files&quot;</span>
    <span class="n">args</span> <span class="o">=</span> <span class="s">&quot;&lt;inputfile1&gt; &lt;inputfile2&gt; ... | all&quot;</span>

    <span class="k">def</span> <span class="nf">handle_label</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Process input file(s)&quot;&quot;&quot;</span>

        <span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">settings</span><span class="p">,</span> <span class="s">&#39;PROJECT_PATH&#39;</span><span class="p">):</span>
            <span class="k">raise</span> <span class="n">CommandError</span><span class="p">(</span><span class="s">&quot;Please add a PROJECT_PATH setting&quot;</span><span class="p">)</span>

        <span class="bp">self</span><span class="o">.</span><span class="n">src_dir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">PROJECT_PATH</span><span class="p">,</span> <span class="s">&#39;fixed&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">dst_dir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">PROJECT_PATH</span><span class="p">,</span> <span class="s">&#39;templates&#39;</span><span class="p">,</span> <span class="s">&#39;fixed&#39;</span><span class="p">)</span>

        <span class="k">if</span> <span class="n">filename</span> <span class="o">==</span> <span class="s">&#39;all&#39;</span><span class="p">:</span>
            <span class="n">files</span> <span class="o">=</span> <span class="n">glob</span><span class="o">.</span><span class="n">glob</span><span class="p">(</span><span class="s">&quot;</span><span class="si">%s%s</span><span class="s">*.rst&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">src_dir</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">sep</span><span class="p">))</span>
            <span class="n">files</span> <span class="o">=</span> <span class="p">[</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">f</span><span class="p">)</span> <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">files</span><span class="p">]</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">files</span> <span class="o">=</span> <span class="p">[</span><span class="n">filename</span><span class="p">]</span>

        <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">files</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">process_page</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">process_page</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filename</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Processes one fixed page&quot;&quot;&quot;</span>

        <span class="c"># retrieve source text</span>
        <span class="n">src_path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">src_dir</span><span class="p">,</span> <span class="n">filename</span><span class="p">)</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">src_path</span><span class="p">,</span> <span class="s">&#39;r&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
                <span class="n">src_text</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
        <span class="k">except</span> <span class="ne">IOError</span><span class="p">,</span> <span class="n">ex</span><span class="p">:</span>
            <span class="k">raise</span> <span class="n">CommandError</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">ex</span><span class="p">))</span>

        <span class="c"># transform text</span>
        <span class="n">content</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">transform_input</span><span class="p">(</span><span class="n">src_text</span><span class="p">)</span>

        <span class="c"># write output</span>
        <span class="n">basename</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">splitext</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">filename</span><span class="p">))[</span><span class="mi">0</span><span class="p">]</span>
        <span class="n">dst_path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dst_dir</span><span class="p">,</span> <span class="s">&#39;</span><span class="si">%s</span><span class="s">.html&#39;</span> <span class="o">%</span> <span class="n">basename</span><span class="p">)</span>

        <span class="k">try</span><span class="p">:</span>
            <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">dst_path</span><span class="p">,</span> <span class="s">&#39;w&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
                <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">content</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">&#39;utf-8&#39;</span><span class="p">))</span>
        <span class="k">except</span> <span class="ne">IOError</span><span class="p">,</span> <span class="n">ex</span><span class="p">:</span>
            <span class="k">raise</span> <span class="n">CommandError</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">ex</span><span class="p">))</span>

        <span class="n">prefix</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">commonprefix</span><span class="p">([</span><span class="n">src_path</span><span class="p">,</span> <span class="n">dst_path</span><span class="p">])</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;</span><span class="si">%s</span><span class="s"> -&gt; </span><span class="si">%s</span><span class="se">\n</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">dst_path</span><span class="p">[</span><span class="nb">len</span><span class="p">(</span><span class="n">prefix</span><span class="p">):]))</span>

    <span class="k">def</span> <span class="nf">transform_input</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">src_text</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Transforms input restructured text to HTML&quot;&quot;&quot;</span>

        <span class="k">return</span> <span class="n">docutils</span><span class="o">.</span><span class="n">core</span><span class="o">.</span><span class="n">publish_parts</span><span class="p">(</span><span class="n">src_text</span><span class="p">,</span> <span class="n">writer_name</span><span class="o">=</span><span class="s">&#39;html&#39;</span><span class="p">,</span>
                <span class="n">settings_overrides</span><span class="o">=</span><span class="p">{</span>
                    <span class="s">&#39;doctitle_xform&#39;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
                    <span class="s">&#39;initial_header_level&#39;</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span>
                    <span class="p">})[</span><span class="s">&#39;html_body&#39;</span><span class="p">]</span>
</pre></div>
<p>Next I would need a template that could render these fragments. I remembered
that the Django <a class="reference external" href="https://docs.djangoproject.com/en/1.4/ref/templates/builtins/#include">include tag</a> could take a variable as an argument. Thus I
could create a single template that could render all of these &quot;fixed&quot; pages.
Here is the template <tt class="docutils literal">templates/fixed/base.html</tt>:</p>
<pre class="literal-block">
{% extends 'base.html' %}
{% block title %}{{ title }}{% endblock %}
{% block content %}
{% include content_template %}
{% endblock %}
</pre>
<p>I just need to pass in <tt class="docutils literal">title</tt> and <tt class="docutils literal">content_template</tt> context variables. The
latter will control which HTML fragment I include.</p>
<p>I then turned to the view function which would render this template. I wanted to
make this as generic and easy to do as possible. Since I was abandoning
flatpages, I would need to wire these up in my <tt class="docutils literal">urls.py</tt>. At first I didn't
think I could use Django's new <a class="reference external" href="https://docs.djangoproject.com/en/1.4/topics/class-based-views/">class-based generic views</a> for this, but after
some fiddling around, I came up with a very nice solution:</p>
<div class="highlight"><pre><span class="kn">from</span> <span class="nn">django.views.generic</span> <span class="kn">import</span> <span class="n">TemplateView</span>

<span class="k">class</span> <span class="nc">FixedView</span><span class="p">(</span><span class="n">TemplateView</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    For displaying our &quot;fixed&quot; views generated with the custom command</span>
<span class="sd">    make_fixed_page.</span>

<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">template_name</span> <span class="o">=</span> <span class="s">&#39;fixed/base.html&#39;</span>
    <span class="n">title</span> <span class="o">=</span> <span class="s">&#39;&#39;</span>
    <span class="n">content_template</span> <span class="o">=</span> <span class="s">&#39;&#39;</span>

    <span class="k">def</span> <span class="nf">get_context_data</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="n">context</span> <span class="o">=</span> <span class="nb">super</span><span class="p">(</span><span class="n">FixedView</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">get_context_data</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
        <span class="n">context</span><span class="p">[</span><span class="s">&#39;title&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">title</span>
        <span class="n">context</span><span class="p">[</span><span class="s">&#39;content_template&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">content_template</span>
        <span class="k">return</span> <span class="n">context</span>
</pre></div>
<p>This allowed me to do the following in my <tt class="docutils literal">urls.py</tt> file:</p>
<div class="highlight"><pre><span class="n">urlpatterns</span> <span class="o">=</span> <span class="n">patterns</span><span class="p">(</span><span class="s">&#39;&#39;</span><span class="p">,</span>
   <span class="c"># ...</span>

   <span class="n">url</span><span class="p">(</span><span class="s">r&#39;^about/$&#39;</span><span class="p">,</span>
       <span class="n">FixedView</span><span class="o">.</span><span class="n">as_view</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="s">&#39;About&#39;</span><span class="p">,</span> <span class="n">content_template</span><span class="o">=</span><span class="s">&#39;fixed/about.html&#39;</span><span class="p">),</span>
       <span class="n">name</span><span class="o">=</span><span class="s">&#39;about&#39;</span><span class="p">),</span>
   <span class="n">url</span><span class="p">(</span><span class="s">r&#39;^colophon/$&#39;</span><span class="p">,</span>
       <span class="n">FixedView</span><span class="o">.</span><span class="n">as_view</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="s">&#39;Colophon&#39;</span><span class="p">,</span> <span class="n">content_template</span><span class="o">=</span><span class="s">&#39;fixed/colophon.html&#39;</span><span class="p">),</span>
       <span class="n">name</span><span class="o">=</span><span class="s">&#39;colophon&#39;</span><span class="p">),</span>

   <span class="c"># ...</span>
</pre></div>
<p>Now I have a way to efficiently serve reStructuredText files as &quot;fixed pages&quot;
that I can put under source code control.</p>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>Mounting a Synology DiskStation on Ubuntu 12.04</title>
      <link>http://deathofagremmie.com/2012/05/01/mounting-a-synology-diskstation-on-ubuntu-12.04</link>
      <pubDate>Tue, 01 May 2012 20:45:00 CDT</pubDate>
      <category><![CDATA[Ubuntu]]></category>
      <category><![CDATA[Synology]]></category>
      <category><![CDATA[Linux]]></category>
      <guid isPermaLink="true">http://deathofagremmie.com/2012/05/01/mounting-a-synology-diskstation-on-ubuntu-12.04</guid>
      <description>Mounting a Synology DiskStation on Ubuntu 12.04</description>
      <content:encoded><![CDATA[<div class="document">
<p>I have a Synology DiskStation that I use for a home NAS. I didn't take good
notes when I got it to work with Ubuntu 10.04, so I had to fumble about when I
upgraded to Ubuntu 12.04 last weekend. So for next time, here is the recipe I
used.</p>
<p>First, you need to install the <strong>cifs-utils</strong> package:</p>
<pre class="literal-block">
$ sudo apt-get install cifs-utils
</pre>
<p>Next, I added the following text to my <tt class="docutils literal">/etc/fstab</tt> file:</p>
<pre class="literal-block">
//192.168.1.2/shared /mnt/syn cifs noauto,iocharset=utf8,uid=1000,gid=1000,credentials=/home/brian/.cifspwd 0 0
</pre>
<p>Take note of the following:</p>
<ul class="simple">
<li>Replace <tt class="docutils literal">//192.168.1.2/</tt> with the IP address or hostname of your
DiskStation. Likewise, <tt class="docutils literal">/shared</tt> is just the path on the DiskStation that I
wanted to mount.</li>
<li><tt class="docutils literal">/mnt/syn</tt> is the mount point where the DiskStation will appear on our local
filesystem.</li>
<li>I didn't want my laptop to mount the DiskStation on bootup, so I used the
<tt class="docutils literal">noauto</tt> parameter.</li>
<li>The <tt class="docutils literal">uid</tt> and <tt class="docutils literal">gid</tt> should match the user and group IDs of your Ubuntu
user. You can find this by grepping your username in <tt class="docutils literal">/etc/passwd</tt>.</li>
<li>The <tt class="docutils literal">credentials</tt> parameter should point to a file you create that contains
the username and password of the DiskStation user you want to impersonate (see
below).</li>
</ul>
<p>Your <tt class="docutils literal">.cifspwd</tt> file should look like the following:</p>
<pre class="literal-block">
username=username
password=password
</pre>
<p>Obviously you'll want to use the real username / password pair of a user on your
DiskStation.</p>
<p>To be paranoid, you should make the file owned by root and readable only by
root. Do this after you get everything working:</p>
<pre class="literal-block">
$ sudo chown root:root .cifspwd
$ sudo chmod 0600 .cifspwd
</pre>
<p>I created the mount point for the DiskStation with:</p>
<pre class="literal-block">
$ sudo mkdir -p /mnt/syn
</pre>
<p>Then, whenever I want to use the DiskStation I use:</p>
<pre class="literal-block">
$ sudo mount /mnt/syn
</pre>
<p>And to unmount it:</p>
<pre class="literal-block">
$ sudo umount /mnt/syn
</pre>
<p>You can avoid the <tt class="docutils literal">mount</tt> and <tt class="docutils literal">umount</tt> commands if you remove the
<tt class="docutils literal">noauto</tt> parameter from the <tt class="docutils literal">/etc/fstab</tt> entry. In that case, Ubuntu will
automatically try to mount the DiskStation at startup.</p>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>Upgrading to Django 1.4</title>
      <link>http://deathofagremmie.com/2012/04/15/upgrading-to-django-1.4</link>
      <pubDate>Sun, 15 Apr 2012 14:50:00 CDT</pubDate>
      <category><![CDATA[Django]]></category>
      <guid isPermaLink="true">http://deathofagremmie.com/2012/04/15/upgrading-to-django-1.4</guid>
      <description>Upgrading to Django 1.4</description>
      <content:encoded><![CDATA[<div class="document">
<p><a class="reference external" href="https://www.djangoproject.com/weblog/2012/mar/23/14/">Django 1.4</a> came out recently, and I took a few hours to upgrade my first site
yesterday. I thought it would be useful for my own reference to write down what
I did. I hope it will be useful to others. I'd love to read what you had to do,
so if you went through this process and blogged about it, please leave a
comment. Please keep in mind these aren't hard and fast steps or a recipe to
follow, as my sites are probably nothing like yours and may use different
features of Django.</p>
<div class="section" id="preparation">
<h3>Preparation</h3>
<p>The first thing I did was to read very carefully the <a class="reference external" href="https://docs.djangoproject.com/en/1.4/releases/1.4/">Django 1.4 release
notes</a>. The Django team does a great job of documenting what has changed, so it
is well worth your time to read the release notes. It is also a good idea to at
least skim the <a class="reference external" href="https://docs.djangoproject.com/en/1.4/internals/deprecation/">Django Deprecation Timeline</a>. After reading these, you should
make a list of the things you want to change, add, or remove.</p>
</div>
<div class="section" id="tips">
<h3>Tips</h3>
<p>After deciding what areas you want or need to change in your code, these tips
may be useful to help you implement the changes.</p>
<ol class="arabic simple">
<li><strong>Run with warnings turned on</strong>. Use this command to run the development
server: <tt class="docutils literal">$ python <span class="pre">-Wall</span> manage.py runserver</tt>. Django makes use of <a class="reference external" href="http://docs.python.org/library/warnings.html">Python's
warning system</a> to flag features that are deprecated. By running Python with
the <tt class="docutils literal"><span class="pre">-Wall</span></tt> switch, you'll see these warnings in the development server
output.</li>
<li><strong>Use the debugger to track down warnings</strong>. Not sure where a pesky warning
is coming from? Just open the Django source code in your editor and put a
<tt class="docutils literal">import pdb; pdb.set_trace()</tt> line right above or below the warning. You
can then use the debugger's <tt class="docutils literal">w</tt> command to get a stack trace and find out
exactly what code is leading to the warning. In my case I kept getting a few
warnings with no idea where they were coming from. I used this technique to
verify the warnings were coming from third party code and not my own. For
more information on using the debugger (and you really <strong>should</strong> know how to
use this invaluable tool), see the <a class="reference external" href="http://docs.python.org/library/pdb.html">Pdb documentation</a>.</li>
</ol>
</div>
<div class="section" id="my-upgrade-experience">
<h3>My upgrade experience</h3>
<p>Here is a list of things that I did during my port. Again, you may not need to
do these, and the next site I upgrade may have a different list. All of these
changes (except for the first) are described in the <a class="reference external" href="https://docs.djangoproject.com/en/1.4/releases/1.4/">Django 1.4 release notes</a>.</p>
<ol class="arabic simple">
<li><strong>Upgrade my Django debug toolbar</strong>. As of this writing, the Django debug
toolbar I got from PyPI was not compatible with Django 1.4. I simply
uninstalled it and grabbed the development version from GitHub with
<tt class="docutils literal">pip install <span class="pre">git+https://github.com/django-debug-toolbar/django-debug-toolbar.git</span></tt>.</li>
<li><strong>Remove the ADMIN_MEDIA_PREFIX setting</strong>. The admin application in
Django 1.4 now relies on the <tt class="docutils literal">staticfiles</tt> application (introduced in
Django 1.3) to handle the serving of static assets.</li>
<li><strong>Remove use of the {% admin_media_prefix %} template tag</strong>. Related to the
above, this tag is now deprecated. I had a custom admin view that used this
template tag, and I simply replaced it with <tt class="docutils literal">{{ STATIC_URL <span class="pre">}}/admin</span></tt>.</li>
<li><strong>Remove verify_exists on URLFields</strong>. The <tt class="docutils literal">verify_exists</tt> option to
the <tt class="docutils literal">URLField</tt> has been removed for performance and security reasons. I had
always set this to <tt class="docutils literal">False</tt>; now I just had to remove it altogether.</li>
<li><strong>Add the require_debug_false filter to logging settings</strong>. As explained in
the release notes, this change prevents admin error emails from being sent
while in <tt class="docutils literal">DEBUG</tt> mode.</li>
<li><strong>django.conf.urls.defaults is deprecated</strong>. I changed my imports in all
<tt class="docutils literal">urls.py</tt> files to use <tt class="docutils literal">django.conf.urls</tt> instead of
<tt class="docutils literal">django.conf.urls.defaults</tt> to access <tt class="docutils literal">include()</tt>, <tt class="docutils literal">patterns()</tt>, and
<tt class="docutils literal">url()</tt>. The Django team had recently moved these functions and updated the
docs and tutorial to stop using the frowned upon <tt class="docutils literal">from
django.conf.urls.defaults import *</tt>.</li>
<li><strong>Enable the new clickjacking protection</strong>. A nice new feature is some new
middleware that adds the <tt class="docutils literal"><span class="pre">X-Frame-Options</span></tt> header to all response headers.
This provides <a class="reference external" href="http://en.wikipedia.org/wiki/Clickjacking">clickjacking</a> protection in modern browsers.</li>
<li><strong>Add an admin password reset feature</strong>. By adding a few new lines to your
<tt class="docutils literal">urlconf</tt> you get a nifty new password reset feature for your admin.</li>
<li><strong>Update to the new manage.py</strong>. This was the biggest change with the most
impact. The Django team has finally removed a long standing wart with its
<tt class="docutils literal">manage.py</tt> utility. Previously, <tt class="docutils literal">manage.py</tt> used to play games with your
<tt class="docutils literal">PYTHONPATH</tt> which led to confusion when migrating to production. It could
also lead to having your settings imported twice. See the next section in
this blog entry for more on what I did here.</li>
</ol>
</div>
<div class="section" id="reorganizing-for-the-new-manage-py">
<h3>Reorganizing for the new manage.py</h3>
<p>The change with the largest impact for me was reorganizing my directory
structure for the new <tt class="docutils literal">manage.py</tt> command. Before this change, I had organized
my directory structure like this:</p>
<pre class="literal-block">
mysite/
   media/
   static/
   mysite/
      myapp1/
         __init__.py
         models.py
         views.py
         urls.py
      myapp2/
         __init__.py
         models.py
         views.py
         urls.py
      settings/
         __init__.py
         base.py
         local.py
         production.py
         test.py
      apache/
         myproject.wsgi
      logs/
      templates/
      manage.py
      urls.py
   LICENSE
   fabfile.py
   requirements.txt
</pre>
<p>After replacing the contents of my old <tt class="docutils literal">manage.py</tt> with the new content, I
then reorganized my directory structure to this:</p>
<pre class="literal-block">
mysite/
   media/
   static/
   myapp1/
      __init__.py
      models.py
      views.py
      urls.py
   myapp2/
      __init__.py
      models.py
      views.py
      urls.py
   myproject/
      settings/
         __init__.py
         base.py
         local.py
         production.py
         test.py
      apache/
         myproject.wsgi
      logs/
      templates/
      urls.py
   LICENSE
   fabfile.py
   manage.py
   requirements.txt
</pre>
<p>It is a subtle change, but I like it. It now makes it clear that my project is
just an application itself, consisting of the top-level <tt class="docutils literal">urls.py</tt>, settings,
templates and logs. The <tt class="docutils literal">manage.py</tt> file is now at the top level directory
also, which seems right.</p>
<p>I had always made my imports as <tt class="docutils literal">from app.models import MyModel</tt> instead of
<tt class="docutils literal">from myproject.app.models</tt>, so I didn't have to update any imports.</p>
<p>Since I use the &quot;settings as a package&quot; scheme, I did have to update the imports
in my settings files. For example, in my <tt class="docutils literal">local.py</tt> I had to change <tt class="docutils literal">from
settings.base import *</tt> to <tt class="docutils literal">myproject.settings.base import *</tt>.</p>
</div>
<div class="section" id="what-i-didn-t-do">
<h3>What I didn't do</h3>
<p>Django 1.4's largest new feature is probably its support for timezones. I
decided for this project not to take advantage of that. It would require a lot
of changes, and it isn't really worth it for this small site. I may use it on
the next site I convert to Django 1.4, and I will definitely be using it on new
projects.</p>
</div>
<div class="section" id="conclusion">
<h3>Conclusion</h3>
<p>The upgrade process went smoother and quicker than I thought thanks to the
excellent release notes and the Django team's use of Python warnings to flag
deprecated features.</p>
</div>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>Installing omniORBpy in a virtualenv</title>
      <link>http://deathofagremmie.com/2012/03/27/installing-omniorbpy-in-a-virtualenv</link>
      <pubDate>Tue, 27 Mar 2012 20:30:00 CDT</pubDate>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[virtualenv]]></category>
      <category><![CDATA[omniORB]]></category>
      <guid isPermaLink="true">http://deathofagremmie.com/2012/03/27/installing-omniorbpy-in-a-virtualenv</guid>
      <description>Installing omniORBpy in a virtualenv</description>
      <content:encoded><![CDATA[<div class="document">
<p>I came across an interesting question on <a class="reference external" href="http://stackoverflow.com/">Stackoverflow</a>, which was essentially
<a class="reference external" href="http://stackoverflow.com/questions/9716611/install-omniorb-python-in-a-virtualenv">How to install omniORBpy in a virtualenv</a>? I've had a lot of experience with
<a class="reference external" href="http://omniorb.sourceforge.net/">omniORB</a>, a high quality, open-source CORBA ORB, at work. omniORB is a C++ ORB,
but it also includes omniORBpy, a thin <a class="reference external" href="http://www.python.org/">Python</a> wrapper around the C++ core.
Despite using omniORBpy extensively, I had never used it in a <a class="reference external" href="http://www.virtualenv.org/">virtualenv</a>.</p>
<p>So I got curious, and gave it a shot. You can read <a class="reference external" href="http://stackoverflow.com/a/9881882/63485">my answer</a>, which the
questioner accepted. I'd love to hear of any better ways of doing it. I worked
it out for Ubuntu, but a Windows solution would be nice to see also.</p>
</div>
]]></content:encoded>
    </item>
  </channel>
</rss>
