<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Random Musings]]></title>
  <link href="http://muse.net.nz//atom.xml" rel="self"/>
  <link href="http://muse.net.nz//"/>
  <updated>2012-02-05T01:06:25+01:00</updated>
  <id>http://muse.net.nz//</id>
  <author>
    <name><![CDATA[dch]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Putting the Apache back into CouchDB]]></title>
    <link href="http://muse.net.nz//blog/2012/02/04/putting-the-apache-back-into-couchdb/"/>
    <updated>2012-02-04T11:50:00+01:00</updated>
    <id>http://muse.net.nz//blog/2012/02/04/putting-the-apache-back-into-couchdb</id>
    <content type="html"><![CDATA[<p>Over the last year, the Apache CouchDB project feels like it&#8217;s been in a
holding pattern between missing <a href="http://en.wikipedia.org/wiki/Benevolent_Dictator_For_Life">Benevolent Dictator</a> and <a href="http://apache.org/foundation/faq.html">ASF</a>-style
<a href="http://communityovercode.com/over/">meritocracy</a>.</p>

<p>It hasn&#8217;t helped that Damien Katz, the original visionary developer of
CouchDB, has been largely absent in the community since the CouchOne and
MemBase merger. And that&#8217;s a shame - few know CouchDB better than him.</p>

<p>His blog post about the future of <a href="http://blog.couchbase.com/couchbase-commitment-to-open-source-and-couchdb">CouchBase</a> comes as no surprise to
anybody who followed the merger; CouchOne was funded by venture capital,
and as such the owners will be pushing for a return - and there&#8217;s nothing
wrong with following the money.</p>

<h2>Relevance</h2>

<blockquote><p>An important goal is to keep interfaces in CouchDB simple enough that<br/>creating compatible implementations on other platforms is feasible.</p><footer><strong>@DamienKatz</strong> <cite><a href='http://damienkatz.net/2008/01/faq_about_couch.html'>FAQ About CouchDB and It&#8217;s New IBM Overlords</a></cite></footer></blockquote>


<p>Despite that, I still think that Apache CouchDB is not only relevant,
but indeed essential in the increasingly internet-connected world. The
trend is for people to put their personal data into a corporate cloud,
where it is sliced, diced and ultimately resold. For most users, there&#8217;s
simply no alternative, and CouchDB is to my mind the best way to develop
a peer-to-peer internet.</p>

<p>I&#8217;d like to see CouchDB as being the enabler in open data, in breaking
open the web for joe &amp; jane user, and enabling interoperability of large
data sets especially in research and for government. And an
independent replication protocol, with a reference implementation,
well supported and documented, is critical to that end - even if the
back end isn&#8217;t actually CouchDB.</p>

<h2>Community and Commitment</h2>

<p>The points made by both <a href="http://www.mikealrogers.com/posts/apache-considered-harmful.html">Mikeal</a> and <a href="http://damienkatz.net/2012/01/the_future_of_couchdb.html">Damien</a>, and others, are valid, however.
CouchDB needs to have both focus and drive, to keep up its active current
developer base, and to grow the user community. And it needs to happen
this year or it will likely be too late.</p>

<h2>Healing the Wounds</h2>

<p>So where to from here? What&#8217;s really needed? The top IRC peeves are not
too hard to address:</p>

<ul>
<li>Inability to install or build on common platforms such as Ubuntu, Debian</li>
<li>Finding appropriate documentation across the wiki, API, and the
out-of-date Definitive Guide</li>
</ul>


<p>But clearly that&#8217;s not sufficient &#8211; in terms of restoring confidence,
and increasing mind-share, things are not so straightforwards.</p>

<p>Fundamentally the Apache CouchDB community needs to get it together &#8211;
to start demonstrating progress to the wider coder community, and do
so in a way that articulates the project&#8217;s objectives, and restores
faith that the Apache Incubator process really did create a community
around the code, that can survive the clumsy departure of its inventor.
Here&#8217;s a suggestion:</p>

<h2>Communicate the Way Forwards:</h2>

<ul>
<li>Have an objective - what&#8217;s Apache CouchDB all about? Why should I use it?</li>
<li>An awe-inspiring Road Map, and a way for people to influence it</li>
<li>Predictable and reliable release schedule</li>
</ul>


<h2>Make it easy to get started:</h2>

<ul>
<li>Clean up the wiki and main landing page</li>
<li>Pre-built binaries to help people get up and running quickly on common
  platforms like Debian and Ubuntu</li>
<li>Closer links to package maintainers</li>
<li>Bring the Definitive Guide up to date with current CouchDB functionality</li>
</ul>


<h2>Continue to Build the Community:</h2>

<ul>
<li>Tell a story around the rich Couch eco-system</li>
<li>Have a Propaganda Pack to help people evangelise Apache CouchDB</li>
<li>Do a weekly update on what&#8217;s happening in CouchDB world</li>
</ul>


<p>Interestingly enough, there&#8217;s not a lot of code required, but there is
a fair bit required from the community.</p>

<p>This is a great opportunity for people who&#8217;d like to contribute, and
who are keen to learn more about CouchDB along the way.</p>

<p>Are you <a href="mailto:user@couchdb.apache.org">joining me</a>?</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Building Erlang &amp; CouchDB on Windows like a Boss]]></title>
    <link href="http://muse.net.nz//blog/2012/01/10/building-erlang-and-couchdb-on-windows-like-a-boss/"/>
    <updated>2012-01-10T01:00:00+01:00</updated>
    <id>http://muse.net.nz//blog/2012/01/10/building-erlang-and-couchdb-on-windows-like-a-boss</id>
    <content type="html"><![CDATA[<p>For the last 2 years, Ericsson&#8217;s Erlang binaries have been built with a
legacy Visual Studio 2005 compiler, and provided limited instructions
on building Windows Erlang from source. This has made building CouchDB from
source on Windows particularly challenging, as almost all dependencies
such as Mozilla SpiderMonkey and IBM&#8217;s ICU no longer officially support
such an old compiler.</p>

<p>I developed <a href="https://github.com/dch/glazier/">glazier</a> for two reasons, namely document the Erlang
build process on newer compilers with a scripted installation, and to
provide a reference build of CouchDB on Windows by including steps
to build the required dependencies. A fringe benefit of this process
is that I now have debug symbols (.pdb files) available for both Erlang
and CouchDB, and can make use of the Microsoft tools for performance
optimisation in future.</p>

<p>I&#8217;ve developed an AMI (virtual machine on Amazon&#8217;s EC2 infastructure) that
encapsulates the entire build chain, and makes building CouchDB on Windows
as easy as launching it and logging in.</p>

<p>Here&#8217;s how, assuming you&#8217;ve already got an EC2 account:</p>

<ol>
<li>Contact me <code>@davecottlehuber</code> or <code>dch</code> on
<a href="irc://freenode.net/couchdb">irc/#couchdb</a>
to get access to the AMI, as it&#8217;s currently a private build.</li>
<li>Log into the AWS <a href="https://console.aws.amazon.com/ec2/home?region=eu-west-1#s=Images">console</a> for the EU West region, and view available
images - you should see something similar to <code>ami-674d7313</code> listed.</li>
<li>Launch an instance - you have a choice between spot which is what I use
for temporary development work such as generating and testing builds, or
a normal instance where you can shut it down without losing your work.
If you&#8217;re mainly compiling, then the <code>m1.large</code> is a good deal - 2 fast
cores at your service. If you&#8217;re running CouchDB, then pick <code>m2.large</code>
or greater, multiple cores so you get that Erlang SMP goodness. Make sure your
security group has at least 5984, 6984, HTTP and HTTPS, and RDP enabled.</li>
<li>Once your instance has started up, connect over RDP &amp; log in.</li>
<li>Optionally set up dropbox.</li>
<li>Start a <code>SDK 7.1 x86 release</code> console from the prompt.</li>
</ol>


<figure class='code'><figcaption><span>Pulling in a new release of CouchDB </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>pushd d:\relax\couchdb
</span><span class='line'>git clean -fdx && git reset --hard
</span><span class='line'>git checkout -t origin/1.2.0
</span><span class='line'>shell
</span><span class='line'># pick reqd erlang, I'm using R15B now
</span><span class='line'>cd /cygdrive/d/relax/couchdb
</span><span class='line'>./bootstrap
</span><span class='line'>couchdb_config_js185.sh
</span><span class='line'>couchdb_build.sh</span></code></pre></td></tr></table></div></figure>


<p>And that&#8217;s it. Do note that there&#8217;s not a lot of error checking in the
<code>couchdb_*.sh</code> scripts so make sure you&#8217;ve checked the logs thoroughly.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Updating CouchDB Windows build]]></title>
    <link href="http://muse.net.nz//blog/2011/12/27/updating-couchdb-windows-build/"/>
    <updated>2011-12-27T14:29:00+01:00</updated>
    <id>http://muse.net.nz//blog/2011/12/27/updating-couchdb-windows-build</id>
    <content type="html"><![CDATA[<p>I&#8217;ve updated <a href="https://github.com/dch/glazier">glazier</a> to support Microsoft&#8217;s SDK 7.1 and therefore Visual
Studio 2010 SP1 as well. This represents a significant upgrade of most
dependencies for CouchDB and Erlang/OTP, namely:</p>

<h3>Erlang</h3>

<ul>
<li>bump wxWidgets 2.8.11 to 2.8.12</li>
<li>revert OpenSSL 1.0.0e to 0.9.8r to align with OTP R15B release notes</li>
<li>start using OTP/R15B from now on</li>
</ul>


<h3>CouchDB</h3>

<ul>
<li>bump curl to 7.23.1</li>
<li>bump ICU to 4.6.1</li>
<li>use Mozilla SpiderMonkey 1.8.5</li>
</ul>


<p>Feel free to try these out from <a href="http://people.apache.org/~dch/dist/snapshots/">snapshots</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Slurping data back out of CouchDB]]></title>
    <link href="http://muse.net.nz//blog/2011/12/22/slurping-data-back-out-of-couchdb/"/>
    <updated>2011-12-22T16:46:00+01:00</updated>
    <id>http://muse.net.nz//blog/2011/12/22/slurping-data-back-out-of-couchdb</id>
    <content type="html"><![CDATA[<p>While this example is slightly contrived, we can re-use CouchDB to
extract this data again.</p>

<p>There are several ways, so let&#8217;s try each of them.</p>

<p>First, and easiest, is to request a list of all documents in the
DB, and then use <code>xargs wget</code> to pull the data down.</p>

<figure class='code'><figcaption><span>extracting doc UUIDs from CouchDB  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ DB</span><span class="o">=</span>http://localhost:5984/posts
</span><span class='line'><span class="nv">$ </span>curl --silent <span class="nv">$DB</span>/_all_docs |
</span><span class='line'>    sed -nE <span class="s1">&#39;s/{&quot;id&quot;:&quot;([0-9]+)&quot;.*/\1/p&#39;</span>
</span><span class='line'>21298063
</span><span class='line'>21298065
</span><span class='line'>...
</span><span class='line'>31797293
</span><span class='line'>66018817
</span><span class='line'><span class="err">$</span>
</span></code></pre></td></tr></table></div></figure>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Generating YAML from CouchDB docs]]></title>
    <link href="http://muse.net.nz//blog/2011/12/17/generating-yaml-from-couchdb-docs/"/>
    <updated>2011-12-17T01:25:00+01:00</updated>
    <id>http://muse.net.nz//blog/2011/12/17/generating-yaml-from-couchdb-docs</id>
    <content type="html"><![CDATA[<p>Continuing the theme of the last two posts, the old Posterous blog content
is now available as JSON inside CouchDB. I&#8217;m now going to combine a few
pieces that are unique to CouchDB to build up the components that will
become blog fodder for <a href="http://octopress.org/">OctoPress</a>.</p>

<p>Octopress, which is based on <a href="http://jekyllrb.com/">Jekyll</a>, uses a mixture of <a href="http://www.yaml.org/">YAML</a> and
<a href="http://daringfireball.net/projects/markdown/syntax">markdown</a> for pages and posts. We&#8217;ll use a <code>show</code> function, which passes
a JSON document to a JavaScript transformation function, to build this up.</p>

<p>First, the posterous format includes a whole lot of stuff we won&#8217;t need.
For OctoPress we want <code>title</code>, <code>display_date</code>,<code>tags</code>, and <code>body_full</code> only:</p>

<figure class='code'><figcaption><span>Excerpt of typical post as a CouchDB JSON doc  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="p">{</span>
</span><span class='line'>   <span class="s2">&quot;_id&quot;</span><span class="o">:</span> <span class="s2">&quot;21298063&quot;</span><span class="p">,</span>
</span><span class='line'>   <span class="s2">&quot;_rev&quot;</span><span class="o">:</span> <span class="s2">&quot;1-8ba11a44954e3171de4f4fa9d68c3210&quot;</span><span class="p">,</span>
</span><span class='line'>   <span class="s2">&quot;is_owned_by_current_user&quot;</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
</span><span class='line'>   <span class="s2">&quot;slug&quot;</span><span class="o">:</span> <span class="s2">&quot;setting-up-a-shared-photo-library-in-picasa3&quot;</span><span class="p">,</span>
</span><span class='line'>   <span class="s2">&quot;tags&quot;</span><span class="o">:</span> <span class="p">[</span>
</span><span class='line'>   <span class="p">],</span>
</span><span class='line'>   <span class="s2">&quot;title&quot;</span><span class="o">:</span> <span class="s2">&quot;setting up a shared photo library in Picasa3 on MacOS&quot;</span><span class="p">,</span>
</span><span class='line'>   <span class="s2">&quot;display_date&quot;</span><span class="o">:</span> <span class="s2">&quot;2009/01/09 13:49:53 -0800&quot;</span><span class="p">,</span>
</span><span class='line'>   <span class="s2">&quot;body_full&quot;</span><span class="o">:</span> <span class="s2">&quot;setting up a shared photo library for several...&quot;</span><span class="p">,</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Assuming OctoPress can parse the date format, this will be easy. Let&#8217;s
map these to <code>title</code>, <code>date</code>, <code>categories</code>, and <code>content</code> to
build our YAML like this:</p>

<figure class='code'><figcaption><span>Typical OctoPress YAML header  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='yaml'><span class='line'><span class="nn">---</span>
</span><span class='line'><span class="l-Scalar-Plain">layout</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">post</span>
</span><span class='line'><span class="l-Scalar-Plain">title</span><span class="p-Indicator">:</span> <span class="s">&quot;setting</span><span class="nv"> </span><span class="s">up</span><span class="nv"> </span><span class="s">a</span><span class="nv"> </span><span class="s">shared</span><span class="nv"> </span><span class="s">photo</span><span class="nv"> </span><span class="s">library</span><span class="nv"> </span><span class="s">in</span><span class="nv"> </span><span class="s">Picasa3</span><span class="nv"> </span><span class="s">on</span><span class="nv"> </span><span class="s">MacOS&quot;</span>
</span><span class='line'><span class="l-Scalar-Plain">date</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">2009/01/09 13:49:53 -0800</span>
</span><span class='line'><span class="l-Scalar-Plain">comments</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">true</span>
</span><span class='line'><span class="l-Scalar-Plain">categories</span><span class="p-Indicator">:</span> <span class="p-Indicator">[]</span>
</span><span class='line'><span class="nn">---</span>
</span><span class='line'><span class="nn">...</span> <span class="l-Scalar-Plain">body_full goes here ...</span>
</span></code></pre></td></tr></table></div></figure>


<p>The show function is pretty straightforward:</p>

<figure class='code'><figcaption><span>CouchDB show to transform Posterous JSON into YAML  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="kd">function</span><span class="p">(</span><span class="nx">doc</span><span class="p">,</span> <span class="nx">req</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="nx">doc</span><span class="p">.</span><span class="nx">slug</span> <span class="o">&amp;&amp;</span> <span class="nx">doc</span><span class="p">.</span><span class="nx">title</span> <span class="o">&amp;&amp;</span> <span class="nx">doc</span><span class="p">.</span><span class="nx">display_date</span> <span class="o">&amp;&amp;</span> <span class="nx">doc</span><span class="p">.</span><span class="nx">tags</span> <span class="o">&amp;&amp;</span> <span class="nx">doc</span><span class="p">.</span><span class="nx">body_full</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">return</span> <span class="p">{</span>
</span><span class='line'>            <span class="nx">body</span><span class="o">:</span> <span class="s1">&#39;---\nlayout: post\n&#39;</span> <span class="o">+</span>
</span><span class='line'>              <span class="s1">&#39;title: &quot;&#39;</span> <span class="o">+</span> <span class="nx">doc</span><span class="p">.</span><span class="nx">title</span> <span class="o">+</span> <span class="s1">&#39;&quot;\n&#39;</span> <span class="o">+</span>
</span><span class='line'>              <span class="s1">&#39;date: &#39;</span> <span class="o">+</span> <span class="nx">doc</span><span class="p">.</span><span class="nx">display_date</span> <span class="o">+</span> <span class="s1">&#39;\n&#39;</span> <span class="o">+</span>
</span><span class='line'>              <span class="s1">&#39;comments: true\n&#39;</span> <span class="o">+</span>
</span><span class='line'>              <span class="s1">&#39;categories: &#39;</span> <span class="o">+</span> <span class="nx">doc</span><span class="p">.</span><span class="nx">tags</span> <span class="o">+</span> <span class="s1">&#39;\n---\n&#39;</span><span class="p">,</span>
</span><span class='line'>            <span class="nx">headers</span><span class="o">:</span> <span class="p">{</span>
</span><span class='line'>                <span class="s1">&#39;Content-Type&#39;</span><span class="o">:</span> <span class="s1">&#39;application/text&#39;</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Let&#8217;s walk through that line by line.</p>

<ol>
<li>Declare the function, and therefore our scope.</li>
<li>First I check that all the entities we require are present. This avoids
generating an expensive exception in the JavaScript engine if later
on I try to access data that isn&#8217;t actually present.</li>
<li>return an object comprising the body content, and the headers</li>
<li>the body is built up from JSON properties of the supplied doc object.</li>
</ol>


<p>That seems like a good start, so wrap that up into a design document,
drop it into your CouchDB and test it out:</p>

<figure class='code'><figcaption><span>testing our show via cURL  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span> curl --silent --header <span class="s2">&quot;Content-Type: application/text&quot;</span> <span class="se">\</span>
</span><span class='line'>  http://localhost:5984/posts/_design/posts/_show/yaml/31797293
</span><span class='line'>---
</span><span class='line'>layout: post
</span><span class='line'>title: <span class="s2">&quot;ubuntu saves the day&quot;</span>
</span><span class='line'>date: 2010/10/28 04:25:37 -0700
</span><span class='line'>comments: <span class="nb">true</span>
</span><span class='line'>categories:
</span><span class='line'>---
</span></code></pre></td></tr></table></div></figure>


<p>Notice how we needed to query using <code>Content-Type: application/text</code>?
Try that same link in your browser. You&#8217;re prompted for a download
that refers to the <code>_id</code> stored in CouchDB.</p>

<p>It would be nicer to get that with the correct markdown filename
already. Let&#8217;s use <code>doc.slug</code> for the name, prefixed with
the date of the original post. Octopress expects a <code>yyyy-mm-dd</code> format
so I&#8217;ve sprinkled liberally with regex pixie dust.</p>

<p>Finally, an additional HTTP header
<code>Content-Disposition: attachment; filename=&lt;file.ext&gt;</code> is required
to provide the proposed name via our show function.</p>

<p>Now&#8217;s a good time to append the actual blog post content too.</p>

<figure class='code'><figcaption><span>CouchDB show to transform Posterous JSON to OctoPress  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="kd">function</span><span class="p">(</span><span class="nx">doc</span><span class="p">,</span> <span class="nx">req</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="nx">doc</span><span class="p">.</span><span class="nx">slug</span> <span class="o">&amp;&amp;</span> <span class="nx">doc</span><span class="p">.</span><span class="nx">title</span> <span class="o">&amp;&amp;</span> <span class="nx">doc</span><span class="p">.</span><span class="nx">display_date</span> <span class="o">&amp;&amp;</span> <span class="nx">doc</span><span class="p">.</span><span class="nx">tags</span> <span class="o">&amp;&amp;</span> <span class="nx">doc</span><span class="p">.</span><span class="nx">body_full</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="c1">// Replace / with - and trim display_date to yyyy-mm-dd- only</span>
</span><span class='line'>        <span class="c1">// to match the octopress expected post format.</span>
</span><span class='line'>        <span class="c1">// This will be passed as an HTTP header and will be used by</span>
</span><span class='line'>        <span class="c1">// browsers or wget as the proposed filename.</span>
</span><span class='line'>        <span class="kd">var</span> <span class="nx">post_date</span> <span class="o">=</span> <span class="nx">doc</span><span class="p">.</span><span class="nx">display_date</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/\//g</span><span class="p">,</span> <span class="s1">&#39;-&#39;</span><span class="p">).</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/^([-0-9]+).+/</span><span class="p">,</span> <span class="s2">&quot;$1&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="kd">var</span> <span class="nx">post_name</span> <span class="o">=</span> <span class="s1">&#39;attachment; filename=&#39;</span> <span class="o">+</span> <span class="nx">post_date</span> <span class="o">+</span> <span class="s1">&#39;-&#39;</span> <span class="o">+</span> <span class="nx">doc</span><span class="p">.</span><span class="nx">slug</span> <span class="o">+</span> <span class="s1">&#39;.md&#39;</span><span class="p">;</span>
</span><span class='line'>        <span class="k">return</span> <span class="p">{</span>
</span><span class='line'>            <span class="nx">body</span><span class="o">:</span> <span class="s1">&#39;---\nlayout: post\n&#39;</span> <span class="o">+</span>
</span><span class='line'>              <span class="s1">&#39;title: &quot;&#39;</span> <span class="o">+</span> <span class="nx">doc</span><span class="p">.</span><span class="nx">title</span> <span class="o">+</span> <span class="s1">&#39;&quot;\n&#39;</span> <span class="o">+</span>
</span><span class='line'>              <span class="s1">&#39;date: &#39;</span> <span class="o">+</span> <span class="nx">post_date</span> <span class="o">+</span> <span class="s1">&#39;\n&#39;</span> <span class="o">+</span>
</span><span class='line'>              <span class="s1">&#39;comments: true\n&#39;</span> <span class="o">+</span>
</span><span class='line'>              <span class="s1">&#39;categories: &#39;</span> <span class="o">+</span> <span class="nx">doc</span><span class="p">.</span><span class="nx">tags</span> <span class="o">+</span> <span class="s1">&#39;\n---\n&#39;</span> <span class="o">+</span>
</span><span class='line'>              <span class="nx">doc</span><span class="p">.</span><span class="nx">body_full</span> <span class="o">+</span> <span class="s1">&#39;\n&#39;</span><span class="p">,</span>
</span><span class='line'>            <span class="nx">headers</span><span class="o">:</span> <span class="p">{</span>
</span><span class='line'>                <span class="s1">&#39;Content-Type&#39;</span><span class="o">:</span> <span class="s1">&#39;application/text&#39;</span><span class="p">,</span>
</span><span class='line'>                <span class="s1">&#39;Content-Disposition&#39;</span><span class="o">:</span> <span class="nx">post_name</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>I&#8217;ve put this into a separate show function, and this is what comes back:</p>

<figure class='code'><figcaption><span>Results from Octopress show function  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>curl --silent --header <span class="s2">&quot;Content-Type: application/text&quot;</span> <span class="se">\</span>
</span><span class='line'> http://localhost:5984/posts/_design/posts/_show/octo/31797293
</span><span class='line'>* About to connect<span class="o">()</span> to localhost port 5984 <span class="o">(</span><span class="c">#0)</span>
</span><span class='line'>*   Trying 127.0.0.1... connected
</span><span class='line'>* Connected to localhost <span class="o">(</span>127.0.0.1<span class="o">)</span> port 5984 <span class="o">(</span><span class="c">#0)</span>
</span><span class='line'>&gt; GET /posts/_design/posts/_show/octo/31797293 HTTP/1.1
</span><span class='line'>&gt; User-Agent: curl/7.21.4 <span class="o">(</span>universal-apple-darwin11.0<span class="o">)</span> libcurl/7.21.4 <span class="se">\</span>
</span><span class='line'> OpenSSL/0.9.8r zlib/1.2.5
</span><span class='line'>&gt; Host: localhost:5984
</span><span class='line'>&gt; Accept: */*
</span><span class='line'>&gt; Content-Type: application/text
</span><span class='line'>&gt;
</span><span class='line'>&lt; HTTP/1.1 200 OK
</span><span class='line'>&lt; Vary: Accept
</span><span class='line'>&lt; Server: CouchDB/1.1.1 <span class="o">(</span>Erlang OTP/R14B04<span class="o">)</span>
</span><span class='line'>&lt; Etag: <span class="s2">&quot;6PML44SHRNE54M212K0O6BLXZ&quot;</span>
</span><span class='line'>&lt; Date: Thu, 22 Dec 2011 13:02:36 GMT
</span><span class='line'>&lt; Content-Type: application/text
</span><span class='line'>&lt; Content-Length: 1668
</span><span class='line'>&lt; Content-Disposition: attachment; <span class="nv">filename</span><span class="o">=</span>2010-10-28-ubuntu-saves-the-day.md
</span><span class='line'>&lt;
</span><span class='line'><span class="o">{</span> <span class="o">[</span>data not shown<span class="o">]</span>
</span><span class='line'>* Connection <span class="c">#0 to host localhost left intact</span>
</span><span class='line'>* Closing connection <span class="c">#0</span>
</span><span class='line'>---
</span><span class='line'>layout: post
</span><span class='line'>title: <span class="s2">&quot;ubuntu saves the day&quot;</span>
</span><span class='line'>date: 2010-10-28
</span><span class='line'>comments: <span class="nb">true</span>
</span><span class='line'>categories:
</span><span class='line'>---
</span><span class='line'>My work laptop had a BSOD today, which looks like it was caused by bit rot ...
</span><span class='line'>
</span><span class='line'><span class="nv">$ </span>wget http://localhost:5984/posts/_design/posts/_show/octo/31797293 <span class="se">\</span>
</span><span class='line'>  --content-disposition
</span><span class='line'>Resolving localhost... 127.0.0.1, ::1, fe80::1
</span><span class='line'>Connecting to localhost|127.0.0.1|:5984... connected.
</span><span class='line'>HTTP request sent, awaiting response... 200 OK
</span><span class='line'>Length: 1668 <span class="o">(</span>1.6K<span class="o">)</span> <span class="o">[</span>application/text<span class="o">]</span>
</span><span class='line'>100%<span class="o">[======</span>&gt;<span class="o">]</span> 1,668       --.-K/s   in 0s
</span><span class='line'>
</span><span class='line'>2011-12-22 14:04:46 <span class="o">(</span>79.5 MB/s<span class="o">)</span> - <span class="sb">`</span>2010-10-28-ubuntu-saves-the-day.md<span class="err">&#39;</span> saved <span class="o">[</span>1668/1668<span class="o">]</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now we can transform arbitrary Posterous blog entries via CouchDB
into Markdown format. Next time, I&#8217;ll use CouchDB to pull all the
data out in one swoop.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Munging Posterous with CouchDB]]></title>
    <link href="http://muse.net.nz//blog/2011/12/16/munging-posterous-with-couchdb/"/>
    <updated>2011-12-16T16:10:00+01:00</updated>
    <id>http://muse.net.nz//blog/2011/12/16/munging-posterous-with-couchdb</id>
    <content type="html"><![CDATA[<p>Previously I used the Posterous API to retrieve all my blogs posts.
In this post, I&#8217;m going to show how easy it is to use CouchDB&#8217;s
<code>_bulk_docs</code> API to get lots of data in via JSON import. Later on,
I&#8217;ll transform it using CouchDB&#8217;s show, view and list functions.</p>

<p>CouchDB&#8217;s <a href="http://wiki.apache.org/couchdb/HTTP_Bulk_Document_API">bulk loading API</a> requires JSON documents to be
embedded in an array called <code>docs</code> within a parent JSON object
that contains optional parameters to indicate to CouchDB how to
handle the upload. Note that the <code>_id</code> value must be a string.</p>

<!--more-->




<figure class='code'><figcaption><span>CouchDB bulk document load format  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="s2">&quot;all_or_nothing&quot;</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
</span><span class='line'>  <span class="s2">&quot;docs&quot;</span><span class="o">:</span> <span class="p">[</span>
</span><span class='line'>    <span class="p">{</span><span class="s2">&quot;_id&quot;</span><span class="o">:</span> <span class="s2">&quot;1&quot;</span><span class="p">,</span> <span class="p">...</span> <span class="p">},</span>
</span><span class='line'>    <span class="p">{</span><span class="s2">&quot;_id&quot;</span><span class="o">:</span> <span class="s2">&quot;2&quot;</span><span class="p">,</span> <span class="p">...</span> <span class="p">}</span>
</span><span class='line'>  <span class="p">]</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>I&#8217;m going to use the <code>all_or_nothing</code> model and keep munging my data
until it works in one go. You could just as easily keep removing documents
that were successfully uploaded from your parent JSON object, which might
be a better approach if I had a lot of data.</p>

<p>The Posterous data I retrieved last time delivers my posts as a single
JSON array. Here&#8217;s a trimmed sample:</p>

<figure class='code'><figcaption><span>Sample Posterous JSON extract  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="s2">&quot;is_owned_by_current_user&quot;</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
</span><span class='line'>    <span class="s2">&quot;slug&quot;</span><span class="o">:</span> <span class="s2">&quot;motorola-marketing-from-the-munchkin-wrangler&quot;</span><span class="p">,</span>
</span><span class='line'>    <span class="s2">&quot;body_excerpt&quot;</span><span class="o">:</span> <span class="s2">&quot;motorola&#39;s cellphone naming looks to me like ...&quot;</span><span class="p">,</span>
</span><span class='line'>    <span class="s2">&quot;views_count&quot;</span><span class="o">:</span> <span class="mi">77</span><span class="p">,</span>
</span><span class='line'>    <span class="s2">&quot;skip some text&quot;</span> <span class="o">:</span> <span class="s2">&quot;...&quot;</span><span class="p">,</span>
</span><span class='line'>    <span class="s2">&quot;comments_count&quot;</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span>
</span><span class='line'>    <span class="s2">&quot;current_member&quot;</span><span class="o">:</span> <span class="s2">&quot;admin&quot;</span><span class="p">,</span>
</span><span class='line'>    <span class="s2">&quot;id&quot;</span><span class="o">:</span> <span class="mi">21298071</span><span class="p">,</span>
</span><span class='line'>    <span class="s2">&quot;replies_count&quot;</span><span class="o">:</span> <span class="mi">0</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>That <code>id</code> field looks like an ideal choice to map to CouchDB&#8217;s <code>_id</code> field.
It&#8217;s not a string though, so we&#8217;ll need to quote the following value.
As an old-school kinda guy, I did a perl one-liner. I am sure you node.js
ninjas out there can do it in 20 lines of valid js with beautiful
<a href="http://wiki.futuretoby.com/Trampolines_in_Javascript_and_the_Quest_for_Fewer_Nested_Callbacks">nested callbacks</a> though.</p>

<p>The final step is to wrap the documents in the <code>_bulk_docs</code> format we saw
initially - <code>{ "options" :..., "docs": [array]}</code>, and then run it through
<code>jsonlint</code> to confirm that Douglas Crockford is happy. No doubt it would
look prettier in ruby.</p>

<figure class='code'><figcaption><span>preparing and wrapping posts for _bulk_docs  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>perl -pi.dist -e <span class="s1">&#39;s/^    &quot;id&quot;:\s+(\d+)/    &quot;_id&quot;: &quot;\1&quot;/g&#39;</span> posts.json
</span><span class='line'><span class="nv">$ </span>perl -e <span class="se">\</span>
</span><span class='line'>  <span class="s1">&#39;print qq({\n    &quot;all_or_nothing&quot;: true,\n    &quot;docs&quot;:\n); \</span>
</span><span class='line'><span class="s1">  print &lt;stdin&gt;;</span>
</span><span class='line'><span class="s1">  print qq(}\n);&#39;</span> &lt; posts.json &gt; bulk_docs.json
</span><span class='line'><span class="nv">$ </span>jsonlint bulk_docs.json
</span><span class='line'>input text encoding is utf-8
</span></code></pre></td></tr></table></div></figure>


<p>So let&#8217;s push this into a new CouchDB and see what happens. In the worst
case, our upload will be rejected in its entirety and we&#8217;ll simply need to
re-try with improved data.</p>

<figure class='code'><figcaption><span>uploading data via _bulk_docs to CouchDB  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ DB</span><span class="o">=</span>http://admin:passwd@localhost:5984/posts
</span><span class='line'><span class="nv">$ </span>curly -X PUT <span class="nv">$DB</span>
</span><span class='line'><span class="o">{</span>
</span><span class='line'>   <span class="s2">&quot;ok&quot;</span> : <span class="nb">true</span>
</span><span class='line'><span class="o">}</span>
</span><span class='line'><span class="nv">$ </span>curly -vX POST <span class="nv">$DB</span>/_bulk_docs -d @bulk_docs.json
</span><span class='line'>* About to connect<span class="o">()</span> to localhost port 5984 <span class="o">(</span><span class="c">#0)</span>
</span><span class='line'>*   Trying ::1... Connection refused
</span><span class='line'>*   Trying 127.0.0.1... connected
</span><span class='line'>* Connected to localhost <span class="o">(</span>127.0.0.1<span class="o">)</span> port 5984 <span class="o">(</span><span class="c">#0)</span>
</span><span class='line'>* Server auth using Basic with user <span class="s1">&#39;admin&#39;</span>
</span><span class='line'>&gt; POST /posts/_bulk_docs HTTP/1.1
</span><span class='line'>&gt; Authorization: Basic <span class="nv">d3ViOnd1Yg</span><span class="o">==</span>
</span><span class='line'>&gt; User-Agent: curl/7.21.4 <span class="o">(</span>universal-apple-darwin11.0<span class="o">)</span> <span class="se">\</span>
</span><span class='line'>&gt;    libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5
</span><span class='line'>&gt; Host: localhost:5984
</span><span class='line'>&gt; Accept: */*
</span><span class='line'>&gt; Content-Type: application/json
</span><span class='line'>&gt; Content-Length: 151723
</span><span class='line'>&gt; Expect: 100-continue
</span><span class='line'>&gt;
</span><span class='line'>&lt; HTTP/1.1 100 Continue
</span><span class='line'><span class="o">}</span> <span class="o">[</span>data not shown<span class="o">]</span>
</span><span class='line'>&lt; HTTP/1.1 201 Created
</span><span class='line'>&lt; Server: CouchDB/1.1.1 <span class="o">(</span>Erlang OTP/R14B04<span class="o">)</span>
</span><span class='line'>&lt; Date: Sat, 17 Dec 2011 00:08:09 GMT
</span><span class='line'>&lt; Content-Type: text/plain;charset<span class="o">=</span>utf-8
</span><span class='line'>&lt; Content-Length: 1222
</span><span class='line'>&lt; Cache-Control: must-revalidate
</span><span class='line'>&lt;
</span><span class='line'><span class="o">{</span> <span class="o">[</span>data not shown<span class="o">]</span>
</span><span class='line'>* Connection <span class="c">#0 to host localhost left intact</span>
</span><span class='line'>* Closing connection <span class="c">#0</span>
</span><span class='line'><span class="o">[</span>
</span><span class='line'>   <span class="o">{</span>
</span><span class='line'>      <span class="s2">&quot;rev&quot;</span> : <span class="s2">&quot;1-fe25f5fa414e78b90b08959ef6763972&quot;</span>,
</span><span class='line'>      <span class="s2">&quot;id&quot;</span> : <span class="s2">&quot;66018817&quot;</span>
</span><span class='line'>   <span class="o">}</span>,
</span><span class='line'>   <span class="o">{</span> <span class="s2">&quot;trimmed&quot;</span>: <span class="s2">&quot;...&quot;</span> <span class="o">}</span>,
</span><span class='line'>   <span class="o">{</span>
</span><span class='line'>      <span class="s2">&quot;rev&quot;</span> : <span class="s2">&quot;1-f4ee768657f44f87b6774489ceca042f&quot;</span>,
</span><span class='line'>      <span class="s2">&quot;id&quot;</span> : <span class="s2">&quot;21298071&quot;</span>
</span><span class='line'>   <span class="o">}</span>
</span><span class='line'><span class="o">]</span>
</span></code></pre></td></tr></table></div></figure>


<p>In the subsequent post, I&#8217;ll transform it using CouchDB&#8217;s show, view and
list functions to load into <a href="http://www.octopress.org/">octopress</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Using cURL and the Posterous API]]></title>
    <link href="http://muse.net.nz//blog/2011/12/03/using-curl-and-the-posterous-api/"/>
    <updated>2011-12-03T00:11:00+01:00</updated>
    <id>http://muse.net.nz//blog/2011/12/03/using-curl-and-the-posterous-api</id>
    <content type="html"><![CDATA[<p>Posterous has a really neat feature of their API docs - you can use it directly
from the web page. Unfortunately, I only need it to migrate off to Octopress.</p>

<p>Log into Posterous and then open the <a href="http://posterous.com/api">API</a> page. Use the first entry to
obtain your API token. Put this, your login and password below and you should
be able to obtain a list of your Posterous Sites, or Spaces as they&#8217;re now
called. <!--more--></p>

<figure class='code'><figcaption><span>retrieve your posterous site id   </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>curl --silent -vX GET --user you@domain.com:passwd <span class="se">\</span>
</span><span class='line'>  -d <span class="s2">&quot;api_token=your_API_token&quot;</span> http://posterous.com/api/2/sites
</span><span class='line'>
</span><span class='line'>* Connected to posterous.com <span class="o">(</span>184.106.20.99<span class="o">)</span> port 80 <span class="o">(</span><span class="c">#0)</span>
</span><span class='line'>* Server auth using Basic with user <span class="s1">&#39;you@domain.com&#39;</span>
</span><span class='line'>&gt; GET /api/2/sites HTTP/1.1
</span><span class='line'>&gt; Authorization: Basic <span class="nv">BEEFDEADXNlLm5ldC5uejp3dWJ3dWI</span><span class="o">=</span>
</span><span class='line'>&gt; User-Agent: curl/7.21.4 <span class="o">(</span>universal-apple-darwin11.0<span class="o">)</span> libcurl/7.21.4 <span class="se">\</span>
</span><span class='line'>        OpenSSL/0.9.8r zlib/1.2.5
</span><span class='line'>&gt; Host: posterous.com
</span><span class='line'>&gt; Accept: */*
</span><span class='line'>&gt; Content-Length: 42
</span><span class='line'>&gt; Content-Type: application/x-www-form-urlencoded
</span><span class='line'>&gt;
</span><span class='line'><span class="o">}</span> <span class="o">[</span>data not shown<span class="o">]</span>
</span><span class='line'>&lt; HTTP/1.1 200 OK
</span><span class='line'>&lt; Server: nginx/0.7.65
</span><span class='line'>&lt; Date: Tue, 13 Dec 2011 00:49:49 GMT
</span><span class='line'>&lt; Content-Type: application/json; <span class="nv">charset</span><span class="o">=</span>utf-8
</span><span class='line'>&lt; Connection: close
</span><span class='line'>&lt; Status: 200 OK
</span><span class='line'>&lt; X-RateLimit-Limit: 1000000
</span><span class='line'>&lt;
</span><span class='line'><span class="o">{</span> <span class="o">[</span>data not shown<span class="o">]</span>
</span><span class='line'>* Closing connection <span class="c">#0</span>
</span></code></pre></td></tr></table></div></figure>


<p>Lovely. Now that will also provide you with some output, deep inside
that is a <code>site_id</code> field - your site. I&#8217;ve conveniently relabelled
this one as <code>1234567</code>:</p>

<figure class='code'><figcaption><span>posterous sites  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="p">{</span>
</span><span class='line'>      <span class="s2">&quot;is_private&quot;</span> <span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
</span><span class='line'>      <span class="s2">&quot;hostname&quot;</span> <span class="o">:</span> <span class="s2">&quot;your_posterous_site_name&quot;</span><span class="p">,</span>
</span><span class='line'>      <span class="s2">&quot;readers_count&quot;</span> <span class="o">:</span> <span class="mi">1</span><span class="p">,</span>
</span><span class='line'>      <span class="s2">&quot;admins_count&quot;</span> <span class="o">:</span> <span class="mi">1</span><span class="p">,</span>
</span><span class='line'>      <span class="s2">&quot;full_hostname&quot;</span> <span class="o">:</span> <span class="s2">&quot;your_posterous_site_name.posterous.com&quot;</span><span class="p">,</span>
</span><span class='line'>      <span class="s2">&quot;profile_image_35&quot;</span> <span class="o">:</span>
</span><span class='line'>        <span class="s2">&quot;http://files.posterous.com/user_profile_pics/1357443/dch_thumb.jpg&quot;</span><span class="p">,</span>
</span><span class='line'>      <span class="s2">&quot;admins&quot;</span> <span class="o">:</span> <span class="p">[{</span>
</span><span class='line'>            <span class="s2">&quot;current_user_following_info&quot;</span> <span class="o">:</span> <span class="kc">null</span><span class="p">,</span>
</span><span class='line'>            <span class="s2">&quot;firstname&quot;</span> <span class="o">:</span> <span class="s2">&quot;Dave&quot;</span><span class="p">,</span>
</span><span class='line'>            <span class="s2">&quot;nickname&quot;</span> <span class="o">:</span> <span class="s2">&quot;dch&quot;</span><span class="p">,</span>
</span><span class='line'>            <span class="s2">&quot;site_id&quot;</span> <span class="o">:</span> <span class="mi">1234567</span>
</span><span class='line'>        <span class="p">}]</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Take that <code>site_id</code> and bung it into this curly command, and stash your
posterous content to a file. Note how I use the <code>pages=2</code> parameter
to retrieve the subsequent page.</p>

<figure class='code'><figcaption><span>dump posterous content as JSON to file  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>curl --silent -X GET --user user@domain.com:passwd -d <span class="se">\</span>
</span><span class='line'>  <span class="s2">&quot;api_token=DeaDBeeFDogFooducDdoG&quot;</span> <span class="se">\</span>
</span><span class='line'>  http://posterous.com/api/2/sites/1234567/posts &gt; /tmp/posts1.json
</span><span class='line'><span class="nv">$ </span>curl --silent -X GET --user user@domain.com:passwd -d <span class="se">\</span>
</span><span class='line'>  <span class="s2">&quot;api_token=DeaDBeeFDogFooducDdoG&quot;</span> <span class="se">\</span>
</span><span class='line'>  http://posterous.com/api/2/sites/1234567/posts<span class="se">\?</span>pages<span class="se">\=</span>2 &gt; /tmp/posts2.json
</span></code></pre></td></tr></table></div></figure>


<p>In particular, note the headers returned by cURL - this is a simple
validation that we&#8217;re on the right page, and have recovered all
the data. Great!</p>

<figure class='code'><figcaption><span>returned cURL headers </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>&lt; X-Current-Page: 2
</span><span class='line'>&lt; X-Runtime: 29
</span><span class='line'>&lt; Content-Length: 148638
</span><span class='line'>&lt; X-Total-Entries: 31
</span><span class='line'>&lt; X-Per-Page: 20
</span><span class='line'>&lt; X-Total-Pages: 2</span></code></pre></td></tr></table></div></figure>


<p>For bonus points, next time I&#8217;ll use CouchDB&#8217;s awesome powers to convert
this back into octopress format.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Great Intro to jQuery Mobile]]></title>
    <link href="http://muse.net.nz//blog/2011/08/17/great-intro-to-jquery-mobile/"/>
    <updated>2011-08-17T00:00:00+02:00</updated>
    <id>http://muse.net.nz//blog/2011/08/17/great-intro-to-jquery-mobile</id>
    <content type="html"><![CDATA[<p>jQuery Mobile is the latest addition to the reliable and popular jQuery
framework family. It&#8217;s rapidly evolving - just entering 1.0 beta2 as I
write this post. It&#8217;s not a huge book - just 6 chapters - but covers the
main points:</p>

<ol>
<li>overview</li>
<li>paging, dialogs, ajax and history</li>
<li>core UI elements - toolbars, buttons, lists, forms, grids</li>
<li>theming</li>
<li>the new jQM events and methods, and customisation</li>
<li>putting it all together by building a twitter app from scratch</li>
</ol>


<p>There are some good quick tips thrown in throughout the book, bringing
some practical experience to help newcomers, and a few bones for more
experienced people as well. The first third (paging, dialogs, ajax and
history) are straightforwards and anybody already familiar with HTML of
any era, and basic jQuery syntax, should eat this up. At this point a
basic jQM web app is easily within reach of most people, as the author
provides plenty of examples with code and screenshots.</p>

<p>The latter stages of the book pick up the pace quickly, and requires more
than a cursory understanding of HTML and Javascript/jQuery. A number of
tips focus on the underlying event model &amp; while this is of interest, it
is also well covered on the official jQM website now. The author takes
the docs further and shows how to integrate these models into useful
code such as handling changed orientation, or enabling swiping to produce
page transitions. He finishes up with a sample Twitter app, pulling what
was covered in the book nicely.</p>

<p>Overall: If you are not a full-time mobile developer, or have intermediate
HTML and Javascript, ideally jQuery, experience, this book will both get
you started, and give you a head start on applying core mobile jQuery
functionality. It&#8217;s a practical book representing good value at its price
point, and seems to have survived the pre-1.0 changes in jQM well, and
will be something I refer back to for a refresher each time I pull a new
mobile app together.
i
This review was brought to you by the O&#8217;Reilly <a href="http://oreilly.com/bloggers/?cmp=ex-orm-blgr-dave-cottlehuber">blogger programme</a>.</p>

<p><img src="http://cdn.oreilly.com/bloggers/blogger-review-badge-200.png" title="I review for the O'Reilly Blogger Programme" ></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[ubuntu saves the day]]></title>
    <link href="http://muse.net.nz//blog/2010/10/28/ubuntu-saves-the-day/"/>
    <updated>2010-10-28T00:00:00+02:00</updated>
    <id>http://muse.net.nz//blog/2010/10/28/ubuntu-saves-the-day</id>
    <content type="html"><![CDATA[<p>My work laptop had a BSOD today, which looks like it was caused by bit rot
on the root partition. While everything&#8217;s backed up onto S3, restores from
New Zealand of 20GiB of data take a while, so I was kinda hoping to recover
smoothly without getting the IT guys to visit, who probably will just
rebuild it. I&#8217;m pretty sure that&#8217;s fair payment for getting chocolate
inside my laptop&#8217;s fan.</p>

<p>It was a good opportunity to give ubuntu maverick a spinup before it goes
on the big iMac at home as dual-boot. The install is slowly tweaked each
time, and it&#8217;s really clean. I am pretty sure my mum could do this without
any help now, and the fresh look is nice - it&#8217;s truly a class act OS.</p>

<p>One workaround was needed to resolve what is probably a stuck <a href="http://xpapad.wordpress.com/2009/09/09/dealing-with-mouse-and-touchpad-freezes-in-linux/">trackpad</a>
on the loan laptop; with a <code>rmmod psmouse</code> then it was all go. Everything
works which really is an impressive step forward for Canonical, with strong
OEM relations clearly now paying off. Hats off guys!</p>

<p>Anyway long story short, nautilus and brasero to the rescue, and I now have
a bunch of md5 checksummed DVDs stashed before the hired goons come
tomorrow to blow it away. I love the ntfs integration in linux, and the new
maverick Ubuntu gets thumbs up all round - especially as it&#8217;s now got
CouchDB 1.0.1 included - yay!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[LHC meets your hand]]></title>
    <link href="http://muse.net.nz//blog/2010/09/24/lhc-meets-your-hand/"/>
    <updated>2010-09-24T00:00:00+02:00</updated>
    <id>http://muse.net.nz//blog/2010/09/24/lhc-meets-your-hand</id>
    <content type="html"><![CDATA[<p>love it - what happens when you put your hand into the <a href="http://kottke.org/10/09/putting-your-hand-in-the-large-hadron-collider">LHC</a>?
Scientists respond, from the quite reasonable through to the delightfully
absurd. Does help if you have some physics background.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[iPhone vs Android]]></title>
    <link href="http://muse.net.nz//blog/2010/09/20/iphone-vs-android/"/>
    <updated>2010-09-20T00:00:00+02:00</updated>
    <id>http://muse.net.nz//blog/2010/09/20/iphone-vs-android</id>
    <content type="html"><![CDATA[<p>same <a href="http://www.makeuseof.com/tech-fun/the-difference-between-iphone-and-android/">results</a>, different path. I&#8217;m still +1 for the open source approach.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Building CouchDB from source on Windows]]></title>
    <link href="http://muse.net.nz//blog/2010/09/08/building-couchdb-from-source-on-windows/"/>
    <updated>2010-09-08T00:00:00+02:00</updated>
    <id>http://muse.net.nz//blog/2010/09/08/building-couchdb-from-source-on-windows</id>
    <content type="html"><![CDATA[<p>Here&#8217;s the first post of a series on getting CouchDB built from source on
Windows. This one focuses on getting all the compilers sorted out - the
most cumbersome part of the process. Let&#8217;s start with Erlang as it&#8217;s the
core of CouchDB.</p>

<p>Building Erlang &amp; CouchDB on Windows requires a custom build environment,
which is very sensitive to path order amongst the three different compilers
used to build wxWidgets, Erlang, JavaScript, and CouchDB.</p>

<p>This is further complicated by different install locations on 32 vs 64
bit windows versions, and which Microsoft C compiler and Windows SDKs are
installed.</p>

<p>Each component is described via Makefiles in the Cygwin unix/posix
emulation layer, and then handed over to the appropriate compiler to run.</p>

<h2>Cygwin</h2>

<p>The full Cygwin install comprises several GiB of data. Run
<a href="http://www.cygwin.com/setup.exe">setup.exe</a> using defaults, optionally
installing all components if you have the bandwidth, or alternatively with
the following additional modules at a minimum:</p>

<ul>
<li>devel: ALL</li>
<li>editors: vim</li>
<li>utils: file</li>
</ul>


<p>We&#8217;ll be using the new shell icon on a regular basis from here on in.</p>

<h2>>Mozilla Build</h2>

<ul>
<li>The mozilla build toolchain is needed solely for building our javascript engine.</li>
<li>download it from <a href="http://ftp.mozilla.org/pub/mozilla.org/mozilla/libraries/win32/MozillaBuildSetup-Latest.exe">mozilla</a>
and install per defaults.</li>
</ul>


<h2>>Microsoft Visual C++</h2>

<p>Erlang and CouchDB can be built using the free VS2008 Express C++ edition
from <a href="http://msdn.microsoft.com/en-gb/vstudio/">MSDN</a> if you don`t already
have a full VS2008 commercial released install.</li>
You&#8217;ll only need to install Visual C++ 9 only, to the default locations,
either using the [DVD ISO](http://download.microsoft.com/download/E/8/E/E8EEB394-7F42-4963-A2D8-29559B738298/VS2008ExpressWithSP1ENUX1504728.iso&#8221;,
or the smaller [msvc++webstart]. You
can exclude the optional MSSSQL &amp; Silverlight components. I&#8217;ve not tried
compiling CouchDB + components using Visual Studio 2010 yet as the project
file and build tool formats have changed again - but feel free to let me know if
you get it working.</p>

<h2>>Windows 7 SDK</h2>

<p>The (free) windows 7 SDK is required, as the free VS2008 install is missing
the message compiler. Download one of the following version per your
requirements &amp; install.</li>
- <a href="http://download.microsoft.com/download/2/E/9/2E911956-F90F-4BFB-8231-E292A7B6F287/GRMSDK_EN_DVD.iso">intel 32bit</a>
- <a href="http://download.microsoft.com/download/2/E/9/2E911956-F90F-4BFB-8231-E292A7B6F287/GRMSDKX_EN_DVD.iso">amd64</a></p>

<h2>Getting the environment right</h2>

<p>After installing VC++ 2008 Express, there is a new batch file which
correctly sets up the environment for you.
<code>"%vs90comntools%\..\..\vc\vcvarsall.bat" x86</code> will automatically find
the correct path, and set up our 32-bit build environment correctly,
independently if you have installed on 32 or 64bit windows. I set up a
script to do this for me &amp; then launch a cygwin shell directly:</p>

<p>Liquid error: ClassNotFound: no lexer for alias &#8216;cmd&#8217; found
In your new cygwin prompt look at your path <code>echo $PATH | sed 's/:/\n/g'</code>
and check ther&#8217;s nothing missing or unexpected.
In the next post, I&rsquo;ll include getting Erlang/OTP set up ready for compilation&lt;</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[coloured git console on windows]]></title>
    <link href="http://muse.net.nz//blog/2010/09/07/coloured-git-console-on-windows/"/>
    <updated>2010-09-07T00:00:00+02:00</updated>
    <id>http://muse.net.nz//blog/2010/09/07/coloured-git-console-on-windows</id>
    <content type="html"><![CDATA[<p>Tired of plain text output running git on Windows? Missing your unix
<a href="http://asimilatorul.com/index.php/2009/09/20/git-on-windows-with-msysgit/">coloured command-line fu</a>
? add two more environment variables under cygwin:</p>

<pre><code>    LESS=FSRX
    TERM=cygwin
</code></pre>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[cygwin dumps core on Windows 2008 R1SP2 on EC2]]></title>
    <link href="http://muse.net.nz//blog/2010/08/11/cygwin-dumps-core-on-windows-2008-r1sp2-on-ec/"/>
    <updated>2010-08-11T00:00:00+02:00</updated>
    <id>http://muse.net.nz//blog/2010/08/11/cygwin-dumps-core-on-windows-2008-r1sp2-on-ec</id>
    <content type="html"><![CDATA[<p>I have been trying to speed up the process of building CouchDB on Windows
by having a high-speed pre-prepared Amazon EC2 image. Microsoft&#8217;s VC++,
mozilla-build with msys, and cygwin tools are required to build erlang and
then later on, CouchDB which also uses erlang. So, no cygwin = no erlang
= no couchdb = showstopper!</p>

<p>If you are trying to install cygwin or similar tools on Windows 2008 R1SP2
Datacenter Edition, either 32 or 64-bit images, you&rsquo;ll likely not even
be able to complete the installation. bash dies regularly, the cygwin
installer spits out errors faster than an uncapped BP oil well. This bug
affects mozilla build tools, cygwin bash and other tools, such as the
msys/mingw compiler as well. Apply the reg fix from
<a href="http://support.microsoft.com/kb/956607">KB956607</a>, reboot and re-install
any tools to ensure their final installation tweaks complete successfully.
This still hasn&#8217; been sufficient for me but I am getting further than before.</p>

<p>Corinna on the <a href="http://omgili.com/mailinglist/cygwin/cygwin/com/AANLkTi=xgJzA5-pMz2mkg-b0CVf4PwFeYCy3RfA4NHgfmailgmailcom.html">cygwin</a>
 list has confirmed that this issue does not recur on a physical install
- thanks! So this is either an EC2 tweak or a Xen bug. While I&#8217;ve not
tested this, it is possible that the older AMD chipset Xen hosts will run
successfully, vs the newer Intel x86_64 chips which don&#8217;t.</p>

<p>I will be following this up with
<a href="http://developer.amazonwebservices.com/connect/thread.jspa?messageID=190190">Amazon</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Getting started with CouchDB on Windows in 4 easy steps]]></title>
    <link href="http://muse.net.nz//blog/2010/08/03/getting-started-with-couchdb-on-windows-in-4/"/>
    <updated>2010-08-03T00:00:00+02:00</updated>
    <id>http://muse.net.nz//blog/2010/08/03/getting-started-with-couchdb-on-windows-in-4</id>
    <content type="html"><![CDATA[<p>Not only is CouchDB fun &amp; relaxing, it&rsquo;s also really easy to get started. Those nice CouchIO guys are providing free couch hosting to help you get started at <a href="http://couch.io/get">http://couch.io/get</a></p></p>

<h2>Getting into CouchDB on Windows</h2>

<p>So you just can&rsquo;t wait to relax can you? The fastest route is just 4 easy steps to CouchDB zen:</p>

<p>Install the bits; 32-bit versions only</p>

<ul>
<li>install <a href="http://www.slproweb.com/download/Win32OpenSSL-1_0_0a.exe">OpenSSL libraries</a> to your system path</li>
<li><a href="http://curl.haxx.se/download/curl-7.19.5-win32-ssl-sspi.zip">unzip curl</a> and add to your path</li>
<li>run the latest <a href="http://github.com/downloads/couchapp/couchapp/couchapp-0.6.exe">couchapp installer</a></li>
<li>sign up for beta <a href="http://couch.io/get">cloud couch hosting</a> to get your own couch ready to go</li>
</ul>




<h2>relax!</h2>




<ul>
<li>read the <a href="http://github.com/couchapp/couchapp/blob/master/README.md">quick start notes</a> on using <a href="http://wiki.couchapp.org/">CouchApp</a></li>
<li>for more info on CouchDB you can read the <a href="http://books.couchdb.org/relax/">Definitive Guide</a></li>
<li>or check out the wiki with more info on running <a href="http://wiki.apache.org/couchdb/Quirks_on_Windows">CouchDB under Windows</a></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Shared folders using Mac OS X extended ACLs]]></title>
    <link href="http://muse.net.nz//blog/2010/07/31/shared-folders-using-mac-os-x-extended-acls/"/>
    <updated>2010-07-31T00:00:00+02:00</updated>
    <id>http://muse.net.nz//blog/2010/07/31/shared-folders-using-mac-os-x-extended-acls</id>
    <content type="html"><![CDATA[<p>You want to set up a shared folder on the same Mac, like iTunes or
Aperture, so your family can share the same files. Let&#8217;s assume you
have a group called &#8220;staff&#8221;; which everybody is already in, and a
folder called &#8220;common&#8221;. This is a mac, this should be simple, right?
well.. almost with a bit of terminal-fu:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">FOLDER</span><span class="o">=</span>common
</span><span class='line'><span class="nv">GROUP</span><span class="o">=</span>staff
</span><span class='line'>mkdir <span class="nv">$FOLDER</span>
</span><span class='line'>chown -R <span class="nv">$USER</span> <span class="nv">$FOLDER</span>
</span><span class='line'>chown -R :<span class="nv">$GROUP</span> <span class="nv">$FOLDER</span>
</span><span class='line'>chmod -R g+rw <span class="nv">$FOLDER</span>
</span><span class='line'>chmod -RN <span class="nv">$FOLDER</span>
</span><span class='line'>chmod -RI <span class="nv">$FOLDER</span>
</span><span class='line'>chmod -R +a <span class="s1">&#39;$GROUP allow list,add_file,search,delete,\</span>
</span><span class='line'><span class="s1">  add_subdirectory,delete_child,file_inherit,directory_inherit&#39;</span> <span class="se">\</span>
</span><span class='line'>  <span class="nv">$FOLDER</span>
</span><span class='line'>ls -lde <span class="nv">$FOLDER</span>
</span></code></pre></td></tr></table></div></figure>


<p>You can use the slightly more permissive &#8216;$GROUP allow list,add_file,search, \
  delete,add_subdirectory,delete_child,readattr,writeattr,readextattr, \
  writeextattr,readsecurity,file_inherit,directory_inherit&#8217;
which allows that group to change permissions and ACLs as well.</p>

<p>By explanation;</p>

<ul>
<li><code>chown -R :staff</code> changes the standard unix group</li>
<li><code>chmod -RN</code> and <code>-RI</code> remove any inherited and initial ACLs; this is not
needed for new folders but if you are converting an existing folder, this helps
a lot to clean up crap</li>
<li><code>chmod -R +a</code>  this is the permissions-mojo being applied</li>
<li><code>ls -lde</code> displays the extended permissions for a folder
note that the ACLs must <em>not</em> have spaces in them if you are pasting
code from above</li>
</ul>


<p>Further reading:</p>

<ul>
<li>the <a href="http://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/man1/chmod.1.html">manual</a></li>
<li><a href="http://sage.ucsc.edu/~wgscott/xtal/wiki/index.php/ACL:_Access_Control_Lists">sage uni</a></li>
<li><a href="http://arstechnica.com/apple/reviews/2005/04/macosx-10-4.ars/8">ars</a> technica</li>
<li><a href="http://www.ideocentric.com/matt/technology/osx-acl">ideo</a></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Aperture 3.03 unsupported image format]]></title>
    <link href="http://muse.net.nz//blog/2010/07/10/aperture-303-unsupported-image-format/"/>
    <updated>2010-07-10T00:00:00+02:00</updated>
    <id>http://muse.net.nz//blog/2010/07/10/aperture-303-unsupported-image-format</id>
    <content type="html"><![CDATA[<p>After losing my hard drive on my iMac I had a fresh install of Snow
eopard &amp; a spanking new disk too. I installed AP3.03 &amp; opened my old
library. The most recent photo shoot, from our trip to Rarotonga, is
now reporting &#8220;Unsupported Image Format&#8221; for over 180 jpegs. You can
see them on disk, the preview.app can read them &#8211; just AP3.03. Crap.
If I export as a new library, then duplicate, they come right - but I
need a better solution for the remaining 73000 photos. Apple your premier
photo product has had a bad run - is AP3 worm-ridden to the core?</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Building the first CouchDB Release]]></title>
    <link href="http://muse.net.nz//blog/2010/07/09/building-couchdb/"/>
    <updated>2010-07-09T00:00:00+02:00</updated>
    <id>http://muse.net.nz//blog/2010/07/09/building-couchdb</id>
    <content type="html"><![CDATA[<p>Building the first ever CouchDB release coincided nicely with a complete
fresh Snow Leopard install due to a dead disk. So this time I&#8217;ve tried out
<a href="http://github.com/mxcl/homebrew">homebrew</a> instead of macports as recommended by jan@</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>brew install erlang
</span><span class='line'>brew install icu4c
</span><span class='line'>brew link icu4c</span></code></pre></td></tr></table></div></figure>


<p>Then, to install CouchDB normally you&#8217;d just go ahead and
<code>brew install couchdb</code>&#8230; and relax. But for a release it&#8217;s different;
download the <a href="http://people.apache.org/~nslater/dist/">bits</a> and:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>cd /tmp
</span><span class='line'>tar xvzf ~/Downloads/apache-couchdb-1.0.0.tar.gz
</span><span class='line'>cd apache-couchdb-1.0.0.tar.gz
</span><span class='line'>./configure --prefix=/tmp/couchdb
</span><span class='line'>make
</span><span class='line'>make check
</span><span class='line'>make install
</span><span class='line'>pushd /tmp/couchdb/bin
</span><span class='line'>./couchdb &</span></code></pre></td></tr></table></div></figure>


<p>Then go to the browser-based <a href="http://127.0.0.1:5984/_utils/couch_tests.html?script/couch_tests.js">test suite</a> to check its all good.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[A fresh start with Snow Leopard Mac OS X b10.6.4]]></title>
    <link href="http://muse.net.nz//blog/2010/07/09/a-fresh-start-with-snow-leopard-mac-os-x-b106/"/>
    <updated>2010-07-09T00:00:00+02:00</updated>
    <id>http://muse.net.nz//blog/2010/07/09/a-fresh-start-with-snow-leopard-mac-os-x-b106</id>
    <content type="html"><![CDATA[<p>A list of twenty things I forgot the last time from installing Snow Leopard</p>

<h2>Key Apps</h2>

<p>Transmission
Komodo
MailPlane
KeePassX
iTerm
Aperture
Firefox + jsonview + adblock plus + sync + firebug + <code>about:config exportHTML=true</code>
QuickSilver
Growl &amp; GrowlTunes
JungleDisk
EyeTV
vmWare Fusion
Skype
VLC
Colloquy</p>

<h2>Tweaks</h2>

<ul>
<li><a href="http://www.axoniclabs.com/DeepSleep/">Deep Sleep</a></li>
<li>enable disk-based hiberation with <code>sudo pmset -a hibernatemode 1</code></li>
<li>use to find out what slows things down use this: <code>pmset -g log</code></li>
</ul>


<h2>Build Tools</h2>

<ul>
<li>XCode no surprises here</li>
<li>Install brew then <a href="http://wiki.github.com/mxcl/homebrew/gems-eggs-and-perl-modules">sort out</a> perl and gems</li>
<li>brew install git, rsync, python</li>
<li>use pip not easy_install</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[old dog learns new tricks (CouchDB, CouchApp, Evently and Javascript)]]></title>
    <link href="http://muse.net.nz//blog/2010/07/06/old-dog-learns-new-tricks-couchdb-couchapp-ev/"/>
    <updated>2010-07-06T00:00:00+02:00</updated>
    <id>http://muse.net.nz//blog/2010/07/06/old-dog-learns-new-tricks-couchdb-couchapp-ev</id>
    <content type="html"><![CDATA[<p>I&#8217;ve always been interested in scalability and simple solutions. For the last ten years I&#8217;ve worked mainly in managed storage services, for large enterprises and telcos. Nothing could be further from scalability and simplicity in those environments. I&#8217;ve watched as clients poured millions of dollars and euros into badly architected apps, to thrust redundancy and reliability on them through hardware. But it&#8217;s just too late by then to fix anything.</p>
The last serious programming I did was in perl, more than a decade ago - last century even - and it shows. I remember migrating from perl4 to perl5. At the time perl was cutting-edge for web development, with the CGI module rising with the then new apache webserver. Things have moved on again since then, and the new web is based on RESTful APIs, javascript, jquery, presented through web browsers. About 9 months ago I ran into CouchDB serendipitiously. Let&#8217;s just say it caught my fancy. A couple of books later I am wombling through building my own applications, that can scale indefinitely without re-architecting, &amp; won&#8217;t require enterprise-grade compute and storage to run. On top of that it&#8217;s great fun to be learning while working with cool stuff again.</p>
This series of posts is focused on the slow learning curve of teaching this old dog some new tricks. In particular I&#8217;m looking at <a href="http://couchdb.apache.org/" title="CouchDB">CouchDB</a>, using <a href="http://couchapp.org/" title="CouchApp">CouchApp</a>, javascript and later on the rapidly moving <a href="http://couchapp.org/couchapp/_design/couchapp.org/vendor/couchapp/docs.html#/">Evently framework</a>. If like me you are just starting out with all of these, you&#8217;ll be running into a few headaches in just getting some basic things working. Here&#8217;s hoping this helps you out.</p>
If you want a head start &amp; some amusement check out all the relax-ing videos below</p></p>

<ul>
<li>Learning to <a href="http://video.yahoo.com/watch/5019677/13353143">Relax</a></li>
<li><a href="http://techportal.ibuildings.com/2010/01/05/advanced-couchdb/">Advanced CouchDB</a></li>
<li>as well as any videos by J Chris Anderson &#8230;</li>
</ul>


<p>Finally two key couch resources are:</p>

<ul>
<li>the <a href="http://books.couchdb.org/relax">Definitive Guide</a> to CouchDB - some
of the sections (templates, building an app) are a little dated now due
to version creep but it&#8217;s still a great book.</li>
<li>the <a href="http://wiki.apache.org/couchdb/">wiki</a></li>
<li>not to mention the mailing list, as well as the #couchdb irc channel</li>
</ul>

]]></content>
  </entry>
  
</feed>

