<?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>MorganGoose.com</title>
    <link>http://morgangoose.com/blog</link>
    <description>notes about various technical subjects</description>
    <pubDate>Thu, 08 Dec 2016 01:14:37 GMT</pubDate>
    <generator>Blogofile</generator>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Using the parallel branch of Fabric</title>
      <link>http://morgangoose.com/blog/2011/01/06/using-the-parallel-branch-of-fabric</link>
      <pubDate>Thu, 06 Jan 2011 18:50:48 PST</pubDate>
      <category><![CDATA[Programming]]></category>
      <guid isPermaLink="true">http://morgangoose.com/blog/2011/01/06/using-the-parallel-branch-of-fabric</guid>
      <description>Using the parallel branch of Fabric</description>
      <content:encoded><![CDATA[<div class="document" id="changes-and-notes">
<h1 class="title">Changes and Notes</h1>
<p>So I've updated the branch to add in a useful bit for the parallel decorator.
I also need to talk out a few things related to it's use in the environment
and some bugs or hiccups one might run into trying to use it. Hopefully I'll
be hitting this up some more soon, and pulling some more of the crazy cool
updates that people have been making to fabric trunk. I have a to-do list,
let me know if you want me to add anything to it!</p>
<div class="section" id="additional-feature">
<h1>Additional feature</h1>
<p>So there's always been a flag to make the pool size of the bubble, and that was
nice, but I wanted a way to make these more permanent as well as simpler to
remember. So it's now an option in the runs_parallel decorator. To use it you'd
just simply give it a size to use:</p>
<div class="highlight"><pre><span class="c">#!/usr/bin/env python</span>

<span class="kn">from</span> <span class="nn">fabric.api</span> <span class="kn">import</span> <span class="o">*</span>

<span class="n">env</span><span class="o">.</span><span class="n">hosts</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;host</span><span class="si">%2d</span><span class="s">.com&#39;</span> <span class="o">%</span> <span class="n">x</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">20</span><span class="p">)]</span>

<span class="nd">@runs_parallel</span><span class="p">(</span><span class="n">with_bubble_of</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">poke</span><span class="p">():</span>
    <span class="n">run</span><span class="p">(</span><span class="s">&#39;uptime&#39;</span><span class="p">)</span>
</pre></div>
<p>This I feel makes a cleaner fabfile, and puts this information where it should
be, in the code, and out of the writer's head.</p>
</div>
<div class="section" id="how-to-use-both-ways-or-just-one">
<h1>How to use both ways, or just one</h1>
<p>A big thing to note in using parallel tasks, is that anything put into shared
variables, like env, is <strong>forgotten</strong> outside the execution of the one instance of
the task. So if you don't add a &#64;runs_once or &#64;runs_sequential decorator to a
task that say sets the env.hosts before an actual parallel task, the work done
inside the env setting task is forgotten.</p>
<p>The reason adding these decorators addresses this, is that by adding them, the
task isn't executed using the parallel bits. It is instead run inside the main
fab process, and isn't creating a fork pool of size 1 and forgetting about it
when the fork is finished executing.</p>
<p>So as an example, if one were to try and run a fabfile w/o setting up
decorators for their functions, and running: <em>fab -P set_hosts uptime</em></p>
<div class="highlight"><pre><span class="c">#!/usr/bin/env python</span>

<span class="kn">from</span> <span class="nn">fabric.api</span> <span class="kn">import</span> <span class="n">env</span><span class="p">,</span> <span class="n">local</span><span class="p">,</span> <span class="n">run</span><span class="p">,</span> <span class="n">sudo</span>

<span class="n">env</span><span class="o">.</span><span class="n">hosts</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;somehost.com&#39;</span><span class="p">]</span>

<span class="k">def</span> <span class="nf">set_hosts</span><span class="p">():</span>
    <span class="n">env</span><span class="o">.</span><span class="n">hosts</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;web-0&#39;</span><span class="p">,</span> <span class="s">&#39;web-1&#39;</span><span class="p">]</span>

<span class="k">def</span> <span class="nf">uptime</span><span class="p">():</span>
    <span class="n">run</span><span class="p">(</span><span class="s">&#39;uptime&#39;</span><span class="p">)</span>
</pre></div>
<p>They'd get into an issue where the set_hosts not being specifically set to run
sequential or once, would have the settings it made to the env.hosts var only
apply inside the task, since it's been forked out. Which would cause the uptime
to only run on somehost.com, and not both web-0 and web-1 as expected.</p>
<div class="section" id="fixing-it">
<h2>Fixing it</h2>
<p>To get around this the tasks that need to set variable globally, and affect
other tasks later will need to be decorated to not use forking. Below is the
same fabfile tweaked to do so, as well as explicitly state how functions should
behave.</p>
<p>Note that setting up a task to <em>&#64;runs_once</em> will be backwards compatible,
but <em>&#64;runs_parallel</em> isn't. The added benefit to this being that one can drop
using the <em>-P</em> flag, as neither task in this example can switch hit.</p>
<div class="highlight"><pre><span class="c">#!/usr/bin/env python</span>

<span class="kn">from</span> <span class="nn">fabric.api</span> <span class="kn">import</span> <span class="o">*</span>

<span class="c">#thanks to Eric who pointed this out, visit his site, it&#39;s neat</span>
<span class="n">env</span><span class="o">.</span><span class="n">hosts</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;ericholscher.com&#39;</span><span class="p">]</span>

<span class="nd">@runs_once</span>
<span class="k">def</span> <span class="nf">set_hosts</span><span class="p">():</span>
    <span class="n">env</span><span class="o">.</span><span class="n">hosts</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;web-0&#39;</span><span class="p">,</span> <span class="s">&#39;web-1&#39;</span><span class="p">]</span>

<span class="nd">@runs_parallel</span>
<span class="k">def</span> <span class="nf">uptime</span><span class="p">():</span>
    <span class="n">run</span><span class="p">(</span><span class="s">&#39;uptime&#39;</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="maybe-it-ll-help">
<h1>Maybe it'll help</h1>
<p>As a boon to people using both the parallel branch and Trunk, on a single
fabfile, note that which one is being used can be determined at runtime using
some silly introspection:</p>
<div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="kn">from</span> <span class="nn">fabric</span> <span class="kn">import</span> <span class="n">decorators</span>
<span class="o">&gt;&gt;&gt;</span> <span class="nb">dir</span><span class="p">(</span><span class="n">decorators</span><span class="p">)</span>
<span class="p">[</span><span class="s">&#39;StringTypes&#39;</span><span class="p">,</span> <span class="s">&#39;__builtins__&#39;</span><span class="p">,</span> <span class="s">&#39;__doc__&#39;</span><span class="p">,</span> <span class="s">&#39;__file__&#39;</span><span class="p">,</span> <span class="s">&#39;__name__&#39;</span><span class="p">,</span>
<span class="s">&#39;__package__&#39;</span><span class="p">,</span> <span class="s">&#39;_parallel&#39;</span><span class="p">,</span> <span class="s">&#39;_sequential&#39;</span><span class="p">,</span> <span class="s">&#39;hosts&#39;</span><span class="p">,</span> <span class="s">&#39;is_parallel&#39;</span><span class="p">,</span>
<span class="s">&#39;is_sequential&#39;</span><span class="p">,</span> <span class="s">&#39;needs_multiprocessing&#39;</span><span class="p">,</span> <span class="s">&#39;roles&#39;</span><span class="p">,</span> <span class="s">&#39;runs_once&#39;</span><span class="p">,</span>
<span class="s">&#39;runs_parallel&#39;</span><span class="p">,</span> <span class="s">&#39;runs_sequential&#39;</span><span class="p">,</span> <span class="s">&#39;wraps&#39;</span><span class="p">]</span>
<span class="o">&gt;&gt;&gt;</span> <span class="s">&quot;runs_once&quot;</span> <span class="ow">in</span> <span class="nb">dir</span><span class="p">(</span><span class="n">decorators</span><span class="p">)</span>
<span class="bp">True</span>
</pre></div>
<p>So one could just flip a Boolean and decorate/use things accordingly. Though I
suggest using &#64;runs_once on any tasks that are just that, single shots that do
stuff local, or set vars for the fabfile, and to reserve using &#64;runs_sequential
for tasks that still need to have multiple hosts, but need to not run side by
side.</p>
</div>
<div class="section" id="bug-outstanding">
<h1>Bug outstanding</h1>
<p>Finally there is a outstanding bug with use of this branch on windows,
<a class="reference external" href="https://github.com/goosemo/fabric/issues#issue/5">https://github.com/goosemo/fabric/issues#issue/5</a>, that'll bite people. I'll try
and work this out, but I'm a bad developer and am dragging my feet on having to
install windows to debug this. But it's the new year so I'll make it a
resolution, and we all know people never drop those.</p>
<p><strong>I've updated this a bit since the first push of the post</strong></p>
</div>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>Parallel execution with fabric</title>
      <link>http://morgangoose.com/blog/2010/10/08/parallel-execution-with-fabric</link>
      <pubDate>Fri, 08 Oct 2010 19:00:15 PDT</pubDate>
      <category><![CDATA[Programming]]></category>
      <guid isPermaLink="true">http://morgangoose.com/blog/2010/10/08/parallel-execution-with-fabric</guid>
      <description>Parallel execution with fabric</description>
      <content:encoded><![CDATA[<div class="document">
<div class="section" id="it-s-been-a-wish-for-some-for-a-long-time">
<h1>It's been a wish for some for a long time</h1>
<p>Since at least <a class="reference external" href="http://code.fabfile.org/issues/show/19">07/21/2009</a> the
desire to have fully parallel execution across hosts, or something similar to
that.  I stumbled upon the thread around March of this year.  Being that I'd
been using <a class="reference external" href="http://docs.fabfile.org">Fabric</a> for a number of months at this point, and had recently made
a script set for work stuff that leveraged <a class="reference external" href="http://docs.python.org/library/multiprocessing.html">multiprocessing</a> I decided to give
the issue a go.</p>
</div>
<div class="section" id="what-i-implemented-and-why">
<h1>What I implemented, and why</h1>
<p>The short of it being that I made a data structure, <a class="reference external" href="http://github.com/goosemo/job_queue">Job_Queue</a> that I feed fab
tasks into and it will keep a running 'bubble' (works like a pool) of
multiprocessing Processes going executing the <a class="reference external" href="http://docs.fabfile.org">Fabric</a> tasks as they are able
to do so. The job queue having a pool size as set by the user, or 1/2 the size
of the host list if not specified, or if the pool size is larger than the host
list size, it will match the host list size.</p>
<div class="section" id="why-not-threads">
<h2>Why not threads?</h2>
<p>Because they won't do what I want parallel execution in <a class="reference external" href="http://docs.fabfile.org">Fabric</a> to accomplish.
Namely</p>
<ul class="simple">
<li>I can't be sure that the task is only IO bound as users can call anything
as it 'just python', and the GIL will trip up fully parallel tasks.</li>
<li>With threads there is an issue noted in the docs about <a class="reference external" href="http://docs.python.org/library/threading.html#importing-in-threaded-code">importing in threaded
code</a> which is something a user of <a class="reference external" href="http://docs.fabfile.org">Fabric</a> is more than welcome to do.</li>
<li>The need for inter-process communication isn't there. Tasks are by their
nature encapsulated, and don't talk to one another when being run.</li>
</ul>
</div>
<div class="section" id="ok-so-why-not-x-instead">
<h2>OK so why not X instead?</h2>
<p>There seems to have been a glut of good work done recently in the python
ecosystem on getting around the issues people are having with the GIL. Some
names that I can recall being <a class="reference external" href="http://twistedmatrix.com/documents/current/core/howto/threading.html">Twisted</a>, <a class="reference external" href="http://www.tornadoweb.org/documentation#low-level-modules">Tornado</a>, <a class="reference external" href="http://www.boddie.org.uk/python/pprocess.html">pprocess</a>, and <a class="reference external" href="http://www.parallelpython.com/">PP</a>. I am
sure there are a lot more. There also the neat looking <a class="reference external" href="http://codespeak.net/execnet/">execnet</a> project that
offers direct communication to a python interpreter over an open socket.</p>
<p>Those got tossed out because they each have something that causes them to not
fit some or all three requirements I gave modules to use.</p>
<ul class="simple">
<li>Cross platform Win/Mac/Linux</li>
<li>Works on Python 2.5+</li>
<li>Is in the stdlib</li>
</ul>
<p>All of those fail the last requirement, and granted it perhaps wouldn't be hard
to get users to install yet another dep, but it is best to avoid things like
that if at all possible. Keeps the moving parts down, and the issues you have
to debug less foreign. Note though that the other two criteria I set could
actually be met by any in list above, I am writing this much removed from my
initial decision process.</p>
</div>
<div class="section" id="so-forks-why-create-a-new-queue-pool">
<h2>So forks, why create a new Queue/Pool?</h2>
<p>Trickery.</p>
<p>The <a class="reference external" href="http://docs.python.org/library/multiprocessing.html">multiprocessing</a> module has a lot of really nice builtins that I attempted
to leverage, but there really just wasn't a way to do what I needed to do with
them. Queue was nice for having a list of Processes, but I needed a worker
pool. Pool provided this, but then the workers were anonymous, and I wasn't
able to set names as a cheap way to keep track of which host it was to run on.</p>
<p>So I had to make something up. That's what <a class="reference external" href="http://github.com/goosemo/job_queue">Job_Queue</a> is for. All it does if
take a load of Processes and then when the job queue is closed, one starts it,
and off it goes. It'll make a bubble of a certain size that it will keep the
number of currently running forks under, and will just move that bubble along
the internal queue it had from the loading.</p>
<p>So it looks a bit like this:</p>
<pre class="literal-block">
---------------------------
[-----]--------------------
---[-----]-----------------
---------[-----]-----------
------------------[-----]--
--------------------[-----]
---------------------------
</pre>
<p>The trickery comes in when in the fabric job_queue.py I set the job.name of the
Process to the host, and inside the queue I leverage this with:</p>
<pre class="literal-block">
env.host_string = env.host = job.name
job.start()
self._running.append(job)
</pre>
<p>Which will set the host for the task at run time, since otherwise <a class="reference external" href="http://docs.fabfile.org">Fabric</a> would
have gotten confused. It would have continued to iterate the same host, because
of the shared state env and it's host list isn't really able to be progressed,
because the forks aren't sharing it anymore, and are instead working in
isolation from one another.</p>
<p>While that could have been a reason to use threads, or something like the
Manager that <a class="reference external" href="http://docs.python.org/library/multiprocessing.html">multiprocessing</a> offers, it's really the only time it comes up,
and it keeps things a lot simper at the moment. Not to say that if someone is
convincing enough I'd probably get behind a more robust solution.</p>
</div>
</div>
<div class="section" id="what-this-branch-adds-to-fabric">
<h1>What this branch adds to Fabric</h1>
<p>There are new command flags for fab:</p>
<pre class="literal-block">
-P, --parallel        use the multiprocessing module to fork by hosts
-z FORKS, --pool-size=FORKS Set the number of forks to use in the pool.
</pre>
<p>I have also added two decorators:</p>
<pre class="literal-block">
&#64;runs_parallel
&#64;runs_sequential
</pre>
<p>These will allow a fab file command to be set to be run either in parallel or
sequentially regardless of the fab command flag. Without these commands switch
when the flag is set.</p>
<p>What that means is that any tasks that are decorated are always run as either
parallel or sequential. Tasks that omit these decorators though, are going to
be able to switch back and forth between running parallel or running
sequentially. Something the user would be specifying at run time with the -P
flag.</p>
</div>
<div class="section" id="with-the-new-stuff-comes-a-few-caveats">
<h1>With the new stuff comes a few caveats</h1>
<p>If you are interested in the guts, the implementation is in the main.py file,
and uses the Job_Queue class in the job_queue.py file. Note that this is only
implemented in the fab command, as there is no way to determine how one will
execute functions if they are using Fabric as a helper library.</p>
<p>If the runs_once decorator is being used on a function that is called from
inside a fabric task, it won't be able to be honored. Because the states in the
forks are separate, and every fork will think it's the first one to run the
function. Simple solution being to make the call it's own task call.</p>
</div>
<div class="section" id="now-to-see-it-in-use">
<h1>Now to see it in use</h1>
<p>Here is a little example of a fab file that is running some command on the
server that will take 10 seconds to run. Yeah sleep is a bit of cheat for this,
but it's good enough to show the benefit of forking out tasks that'd take a
crap ton of time otherwise</p>
<div class="highlight"><pre><span class="kn">from</span> <span class="nn">fabric.api</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">from</span> <span class="nn">server_list</span> <span class="kn">import</span> <span class="n">servers</span>

<span class="n">env</span><span class="o">.</span><span class="n">roledefs</span> <span class="o">=</span> <span class="n">servers</span><span class="o">.</span><span class="n">server_classes</span>

<span class="nd">@roles</span><span class="p">(</span><span class="s">&#39;servers&#39;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">poke</span><span class="p">():</span>
    <span class="n">run</span><span class="p">(</span><span class="s">&quot;sleep 10&quot;</span><span class="p">)</span>
</pre></div>
<div class="section" id="running-it">
<h2>Running it</h2>
<p>In parallel, as specified on the cli. Note that this is an example of not in
using the decorators to set this in the code, so it as a task/function can
toggle between being run in parallel or sequentially. There are 49 servers in
the 'servers' list that I'm applying to this task.</p>
<div class="highlight"><pre><span class="nv">$ </span><span class="nb">time </span>fab poke -P -z 20
...

real   0m45.868s
user   1m7.928s
sys    0m8.425s
</pre></div>
<p>Now the long runner. It takes ... forever.</p>
<div class="highlight"><pre><span class="nv">$ </span><span class="nb">time </span>fab poke
...

real   8m51.477s
user   6m3.239s
sys    1m26.637s
</pre></div>
<p>The difference is pretty dramatic. We get a 8 min fab task dropped down to less
than one min.</p>
</div>
<div class="section" id="just-cause-i-though-it-was-neat">
<h2>Just cause I though it was neat</h2>
<p>This is a glimpse of what it'll look like in the process tree. Those are the
forks running their tasks, and the children under them are the threads that
<a class="reference external" href="http://github.com/bitprophet">bitprophet</a> added into <a class="reference external" href="http://docs.fabfile.org">Fabric</a> core for greatly improved stream handling.</p>
<div class="highlight"><pre><span class="nv">$ </span>pstree -paul
...
│   ├─bash,20062
│   │   └─fab,21455 /home/mgoose/.virtualenvs/fabric-merge/bin/fab poke -P -z 20
│   │       ├─fab,21462 /home/mgoose/.virtualenvs/fabric-merge/bin/fab poke -P -z 20
│   │       │   └─<span class="o">{</span>fab<span class="o">}</span>,21493
│   │       ├─fab,21463 /home/mgoose/.virtualenvs/fabric-merge/bin/fab poke -P -z 20
│   │       │   ├─<span class="o">{</span>fab<span class="o">}</span>,21484
│   │       │   ├─<span class="o">{</span>fab<span class="o">}</span>,21505
│   │       │   ├─<span class="o">{</span>fab<span class="o">}</span>,21511
│   │       │   └─<span class="o">{</span>fab<span class="o">}</span>,21517
│   │       ├─fab,21464 /home/mgoose/.virtualenvs/fabric-merge/bin/fab poke -P -z 20
│   │       │   └─<span class="o">{</span>fab<span class="o">}</span>,21487
│   │       ├─fab,21465 /home/mgoose/.virtualenvs/fabric-merge/bin/fab poke -P -z 20
│   │       │   ├─<span class="o">{</span>fab<span class="o">}</span>,21483
│   │       │   ├─<span class="o">{</span>fab<span class="o">}</span>,21502
│   │       │   ├─<span class="o">{</span>fab<span class="o">}</span>,21503
│   │       │   └─<span class="o">{</span>fab<span class="o">}</span>,21504
...
<span class="o">(</span>16 more fab lines<span class="o">)</span>
</pre></div>
</div>
</div>
<div class="section" id="use-it-and-let-me-know">
<h1>Use it and let me know</h1>
<p>I'd love to hear how people are using this, and if they find any holes in my
implementation. I've got a few more things I want/need to add into this, and
I've got them listed in the <a class="reference external" href="http://github.com/goosemo/fabric/issues">github issues</a> just until this gets integrated
into the <a class="reference external" href="http://docs.fabfile.org">Fabric</a> mainline.</p>
</div>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>Github project list</title>
      <link>http://morgangoose.com/blog/2010/09/29/github-project-list</link>
      <pubDate>Wed, 29 Sep 2010 22:24:00 PDT</pubDate>
      <category><![CDATA[Website]]></category>
      <category><![CDATA[Version Control]]></category>
      <guid isPermaLink="true">http://morgangoose.com/blog/2010/09/29/github-project-list</guid>
      <description>Github project list</description>
      <content:encoded><![CDATA[<div class="document">
<div class="section" id="adding-in-more-stuff">
<h1>Adding in more stuff</h1>
<p>It's mostly what I am working on atm for the blog. After using <a class="reference external" href="http://blogofile.com">blogofile</a> for a
few days now I've really gotten accustomed to writing up new things for it. It
is only python after all. So that helps. My newest idea was to have a listing of
my github projects in the sidebar.</p>
</div>
<div class="section" id="seems-simple-enough">
<h1>Seems simple enough</h1>
<p>Found a <a class="reference external" href="http://github.com/ask/python-github2">good api in python</a> for this.
There was one that used javascript that would have also done the job, but I
decided this could be slow and updated when the site was built, instead of
needing to be updated real time.</p>
<p>After installing the <a class="reference external" href="http://github.com/ask/python-github2">github2</a> module, I got right to it and started making a
controller for the widget. And I ended up with something like this:</p>
<div class="section" id="github-py">
<h2>github.py</h2>
<div class="highlight"><pre><span class="kn">import</span> <span class="nn">logging</span>

<span class="kn">from</span> <span class="nn">blogofile.cache</span> <span class="kn">import</span> <span class="n">bf</span>
<span class="n">github</span> <span class="o">=</span> <span class="n">bf</span><span class="o">.</span><span class="n">config</span><span class="o">.</span><span class="n">controllers</span><span class="o">.</span><span class="n">github</span>

<span class="kn">from</span> <span class="nn">github2.client</span> <span class="kn">import</span> <span class="n">Github</span>
<span class="n">github_api</span> <span class="o">=</span> <span class="n">Github</span><span class="p">()</span>

<span class="n">config</span> <span class="o">=</span> <span class="p">{</span>
    <span class="s">&quot;name&quot;</span><span class="p">:</span> <span class="s">&quot;Github&quot;</span><span class="p">,</span>
    <span class="s">&quot;description&quot;</span><span class="p">:</span> <span class="s">&quot;Makes a nice github project listing for the sidebar&quot;</span><span class="p">,</span>
    <span class="s">&quot;priority&quot;</span><span class="p">:</span> <span class="mf">90.0</span><span class="p">,</span>
    <span class="p">}</span>

<span class="k">def</span> <span class="nf">get_list</span><span class="p">(</span><span class="n">user</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Each item in the list has:</span>
<span class="sd">    name, url, description, forks, watchers, homepage, open_issues</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">return</span> <span class="p">[</span><span class="n">g</span> <span class="k">for</span> <span class="n">g</span> <span class="ow">in</span> <span class="n">github_api</span><span class="o">.</span><span class="n">repos</span><span class="o">.</span><span class="n">list</span><span class="p">(</span><span class="n">user</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">g</span><span class="o">.</span><span class="n">fork</span><span class="p">]</span>


<span class="k">def</span> <span class="nf">run</span><span class="p">():</span>
    <span class="n">github</span><span class="o">.</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">config</span><span class="p">[</span><span class="s">&#39;name&#39;</span><span class="p">])</span>
    <span class="n">github</span><span class="o">.</span><span class="n">repo_list</span> <span class="o">=</span> <span class="n">get_list</span><span class="p">(</span><span class="n">github</span><span class="o">.</span><span class="n">user</span><span class="p">)</span>
</pre></div>
<p>With a configuration in _config.py like this:</p>
<div class="highlight"><pre><span class="c">#### github projects ####</span>
<span class="n">controllers</span><span class="o">.</span><span class="n">github</span><span class="o">.</span><span class="n">enabled</span> <span class="o">=</span> <span class="bp">True</span>
<span class="n">github</span> <span class="o">=</span> <span class="n">controllers</span><span class="o">.</span><span class="n">github</span>
<span class="n">github</span><span class="o">.</span><span class="n">user</span> <span class="o">=</span> <span class="s">&quot;goosemo&quot;</span>
</pre></div>
<p>And a simple github.mako file that I used mako's <a class="reference external" href="http://www.makotemplates.org/docs/syntax.html#syntax_tags_include">include</a> function for:</p>
<div class="highlight"><pre><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;sidebar_item&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;h3&gt;</span>Github Projects<span class="nt">&lt;/h3&gt;</span>
<span class="nt">&lt;ul&gt;</span>
% for project in bf.config.controllers.github.repo_list:
    <span class="nt">&lt;li&gt;&lt;a</span> <span class="na">href=</span><span class="s">&quot;${project.url}&quot;</span> <span class="na">title=</span><span class="s">&quot;${project.name}&quot;</span><span class="nt">&gt;</span>
    ${project.name}<span class="nt">&lt;/a&gt;</span><span class="ni">&amp;nbsp;</span>${project.description}<span class="nt">&lt;/li&gt;</span>
    <span class="nt">&lt;br/&gt;</span>
% endfor
<span class="nt">&lt;/ul&gt;</span>
<span class="nt">&lt;/div&gt;</span>
<span class="nt">&lt;br</span> <span class="nt">/&gt;</span>
</pre></div>
</div>
</div>
<div class="section" id="i-did-run-into-an-issue">
<h1>I did run into an issue</h1>
<p>After getting this all down the site was acting strange. The frontage had the
listing of my git repos just as it was supposed to be. But I found that on
every other page the github section was blank.</p>
<p>After tweaking and getting a bit frustrated, I read the <a class="reference external" href="http://blogofile.com">blogofile</a> code a bit
more for the controller sections, and got the idea to up the priority from 70
to 90.</p>
<p>This did the trick, and I figure it was because the permalinks and other page
creation work was being done before the github.repo_list could be populated.</p>
</div>
<div class="section" id="thoughts-so-far">
<h1>Thoughts so far</h1>
<p>Overall the process from idea to working in <a class="reference external" href="http://blogofile.com">blogofile</a> is straightforward,
since it's nothing new in form of coding. Mako and python go well together.</p>
<p>Now I just need to get down a coherent way to publish these little bits I keep
adding, and to also make them completely configurable via the _config.py and
isolated into their own units so that installation/use is a simple procedure.</p>
</div>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>Github and Bitbucket hooks</title>
      <link>http://morgangoose.com/blog/2010/09/29/github-and-bitbucket-hooks</link>
      <pubDate>Wed, 29 Sep 2010 17:40:10 PDT</pubDate>
      <category><![CDATA[Version Control]]></category>
      <guid isPermaLink="true">http://morgangoose.com/blog/2010/09/29/github-and-bitbucket-hooks</guid>
      <description>Github and Bitbucket hooks</description>
      <content:encoded><![CDATA[<div class="document">
<div class="section" id="i-use-hg-but-like-github">
<h1>I use hg but like github</h1>
<p>I also dislike unevenness. Having recently read about the <a class="reference external" href="http://hg-git.github.com/">hg-git</a> plugin and
read about a <a class="reference external" href="http://hgtip.com/tips/advanced/2009-11-09-create-a-git-mirror/">setup</a> that uses the paths definitions for <a class="reference external" href="http://hgbook.red-bean.com/index.html">hg</a> to make simple
names to push to, and decided to combine them all together. I ended up with a
~/.hgrc that I had this:</p>
<div class="highlight"><pre><span class="k">[extensions]</span>
<span class="na">hgext.bookmarks</span> <span class="o">=</span>
<span class="na">hggit</span> <span class="o">=</span>
</pre></div>
<p>And then in the repo's .hg/hgrc I'd add something like this:</p>
<div class="highlight"><pre><span class="k">[paths]</span>
<span class="na">github</span> <span class="o">=</span> <span class="s">git+ssh://git@github.com:goosemo/hooks.git</span>
<span class="na">bitbucket</span> <span class="o">=</span> <span class="s">ssh://hg@bitbucket.org/morgan_goose/hooks</span>
</pre></div>
</div>
<div class="section" id="that-worked-well">
<h1>That worked well</h1>
<p>But I had to remember to push to both, and that was annoying. Then I dug into
<a class="reference external" href="http://www.selenic.com/mercurial/hgrc.5.html#hooks">hooks</a> and found that I could easily make a shell script to push to both for
me. What I ended up with was a bash script that would determine which path I
had pushes to, and then push to the other:</p>
<div class="highlight"><pre><span class="c">#!/bin/bash</span>

<span class="c"># This script takes in the args that a hg push is given and checks for the paths</span>
<span class="c"># that I&#39;ve defined in my hg repos for either a push to bitbucket or github,</span>
<span class="c"># and then does the other, so that regardless of which of these sites I push to</span>
<span class="c"># the other also get pushed to.</span>

<span class="c">#post-push to bitbucket</span>
<span class="k">if</span> <span class="o">[[</span> <span class="nv">$HG_ARGS</span> <span class="o">=</span>~ <span class="s2">&quot;push bitbucket&quot;</span> <span class="o">]]</span>
<span class="k">then</span>
<span class="k">    </span>hg push github --quiet
<span class="k">fi</span>

<span class="c">#post-push to github</span>
<span class="k">if</span> <span class="o">[[</span> <span class="nv">$HG_ARGS</span> <span class="o">=</span>~ <span class="s2">&quot;push github&quot;</span> <span class="o">]]</span>
<span class="k">then</span>
<span class="k">    </span>hg push bitbucket --quiet
<span class="k">fi</span>
</pre></div>
<p>Note that the quiet flags or similar must be employed, otherwise you'll get
caught in an infinite loop. After that I added this line into my ~/.hgrc</p>
<div class="highlight"><pre><span class="k">[hooks]</span>
<span class="na">post-push</span> <span class="o">=</span> <span class="s">$HOME/workspace/hooks/github.sh</span>
</pre></div>
</div>
<div class="section" id="success">
<h1>Success</h1>
<p>Now regardless of where I push the other will get the update:</p>
<div class="highlight"><pre>~/workspace/hooks<span class="nv">$ </span>hg push bitbucket
pushing to ssh://hg@bitbucket.org/morgan_goose/hooks
searching <span class="k">for </span>changes
no changes found


~/workspace/hooks<span class="nv">$ </span>hg push github
pushing to git+ssh://git@github.com:goosemo/hooks.git
importing Hg objects into Git
creating and sending data
github::refs/heads/master <span class="o">=</span>&gt; GIT:b4fb4c58
</pre></div>
</div>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>Getting twitter feed running for Blogofile</title>
      <link>http://morgangoose.com/blog/2010/09/28/getting-twitter-feed-running-for-blogofile</link>
      <pubDate>Tue, 28 Sep 2010 19:21:05 PDT</pubDate>
      <category><![CDATA[Website]]></category>
      <category><![CDATA[Programming]]></category>
      <guid isPermaLink="true">http://morgangoose.com/blog/2010/09/28/getting-twitter-feed-running-for-blogofile</guid>
      <description>Getting twitter feed running for Blogofile</description>
      <content:encoded><![CDATA[<div class="document">
<div class="section" id="a-small-part-to-making-it-match">
<h1>A small part to making it match</h1>
<p><a class="reference external" href="http://wordpress.org">Wordpress</a> has plugins, lots and lots of plugins. In my conversion from it to
<a class="reference external" href="http://www.blogofile.com">blogofile</a> I wanted to make it match my old site as closely as I could. Having
a twitter feed of my latest tweets was something I'd have to get on the site.</p>
</div>
<div class="section" id="fails">
<h1>Fails</h1>
<p>I though I might make a python api call and then pipe that into my sidebar.
This worked. But it sucked because I'd have to rebuild the page every tweet. I
don't mind static content for my posts and navigation and the like. That's just
good caching I feel.</p>
<p>Tweets though are a constantly, or would be for anyone else but me, updating
service.</p>
</div>
<div class="section" id="in-comes-the-javascript">
<h1>In comes the JavaScript</h1>
<p>So in looking for simple things to give me a twitter feed I found Remy Sharp's
site and his <a class="reference external" href="http://remysharp.com/2007/05/18/add-twitter-to-your-blog-step-by-step/">directions</a> on how to put a javascript based feed into a site.</p>
<p>It was simple as could be, and I had a base, but hard coded feed up an running
in short order.</p>
</div>
<div class="section" id="making-it-better-for-blogofile-users">
<h1>Making it better for blogofile users</h1>
<p>Part of open source is giving back. Something I really want to do more of, and I
feel am getting into the swing of it a bit more. But that's whatever, I found
the useful and perfect plugin, and got it working in <a class="reference external" href="http://www.blogofile.com">blogofile</a> without much
trouble.</p>
<p>I now started thinking about how others might like to use this and would not
really want to hard code it too much. So I made it into a controller, and
configurable by the <strong>_config.py</strong> file. I made it kinda simple, but a bit
overkilled with the folder and an __init__.py, but I was aiming for it to be
more work.</p>
<div class="section" id="controllers-tweets-init-py">
<h2>_controllers/tweets/__init__.py</h2>
<div class="highlight"><pre><span class="kn">import</span> <span class="nn">logging</span>

<span class="kn">from</span> <span class="nn">blogofile.cache</span> <span class="kn">import</span> <span class="n">bf</span>

<span class="n">config</span> <span class="o">=</span> <span class="p">{</span>
    <span class="s">&quot;name&quot;</span><span class="p">:</span> <span class="s">&quot;Twitter&quot;</span><span class="p">,</span>
    <span class="s">&quot;description&quot;</span><span class="p">:</span> <span class="s">&quot;Makes a sidebar widget for twitter&quot;</span><span class="p">,</span>
    <span class="s">&quot;priority&quot;</span><span class="p">:</span> <span class="mf">70.0</span><span class="p">,</span>
    <span class="p">}</span>

<span class="k">def</span> <span class="nf">run</span><span class="p">():</span>
    <span class="n">tweets</span> <span class="o">=</span> <span class="n">bf</span><span class="o">.</span><span class="n">config</span><span class="o">.</span><span class="n">controllers</span><span class="o">.</span><span class="n">tweets</span>
    <span class="n">tweets</span><span class="o">.</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">config</span><span class="p">[</span><span class="s">&#39;name&#39;</span><span class="p">])</span>
</pre></div>
<p>After making it a controller then we're able to put in config vars and set them
as we want. Which makes it nice for me later i want to change some things,
since all configs are in this one file.</p>
</div>
<div class="section" id="configure-py">
<h2>_configure.py</h2>
<div class="highlight"><pre><span class="c">### Twitter Settings ###</span>
<span class="n">controllers</span><span class="o">.</span><span class="n">tweets</span><span class="o">.</span><span class="n">enabled</span> <span class="o">=</span> <span class="bp">True</span>
<span class="n">tweets</span> <span class="o">=</span> <span class="n">controllers</span><span class="o">.</span><span class="n">tweets</span>
<span class="n">tweets</span><span class="o">.</span><span class="n">username</span> <span class="o">=</span> <span class="s">&quot;morganiangoose&quot;</span>
<span class="n">tweets</span><span class="o">.</span><span class="n">count</span> <span class="o">=</span> <span class="mi">3</span>
<span class="n">tweets</span><span class="o">.</span><span class="n">enable_links</span> <span class="o">=</span> <span class="s">&#39;true&#39;</span>
<span class="n">tweets</span><span class="o">.</span><span class="n">ignore_replies</span> <span class="o">=</span> <span class="s">&#39;false&#39;</span>
<span class="n">tweets</span><span class="o">.</span><span class="n">template</span> <span class="o">=</span> <span class="p">(</span><span class="s">&#39;&lt;li&gt;&lt;div class=&quot;item&quot;&gt;%text% &lt;a href=&quot;http://twitter.c&#39;</span>
        <span class="s">&#39;om/</span><span class="si">%u</span><span class="s">ser_screen_name%/statuses/</span><span class="si">%i</span><span class="s">d%/&quot;&gt;%time%&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;br/&gt;&#39;</span><span class="p">)</span>
</pre></div>
<p>I then threw this, which is pretty much directly from remy's <a class="reference external" href="http://remysharp.com/2007/05/18/add-twitter-to-your-blog-step-by-step/">directions</a> with
mako var, into my sidebar template.</p>
</div>
<div class="section" id="templates-sidebar-mako">
<h2>_templates/sidebar.mako</h2>
<div class="highlight"><pre><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;sidebar_item&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;h3&gt;</span>Twitter<span class="nt">&lt;/h3&gt;</span>
    <span class="nt">&lt;script </span><span class="na">src=</span><span class="s">&quot;http://twitterjs.googlecode.com/svn/trunk/src/twitter.min.js&quot;</span>
    <span class="na">type=</span><span class="s">&quot;text/javascript&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>
    <span class="nt">&lt;script </span><span class="na">type=</span><span class="s">&quot;text/javascript&quot;</span> <span class="na">charset=</span><span class="s">&quot;utf-8&quot;</span><span class="nt">&gt;</span>
        <span class="nx">getTwitters</span><span class="p">(</span><span class="s1">&#39;tweet&#39;</span><span class="p">,</span> <span class="p">{</span>
            <span class="nx">id</span><span class="o">:</span> <span class="s1">&#39;${bf.config.tweets.username}&#39;</span><span class="p">,</span>
            <span class="nx">count</span><span class="o">:</span> <span class="nx">$</span><span class="p">{</span><span class="nx">bf</span><span class="p">.</span><span class="nx">config</span><span class="p">.</span><span class="nx">tweets</span><span class="p">.</span><span class="nx">count</span><span class="p">},</span>
            <span class="nx">enableLinks</span><span class="o">:</span> <span class="nx">$</span><span class="p">{</span><span class="nx">bf</span><span class="p">.</span><span class="nx">config</span><span class="p">.</span><span class="nx">tweets</span><span class="p">.</span><span class="nx">enable_links</span><span class="p">},</span>
            <span class="nx">ignoreReplies</span><span class="o">:</span> <span class="nx">$</span><span class="p">{</span><span class="nx">bf</span><span class="p">.</span><span class="nx">config</span><span class="p">.</span><span class="nx">tweets</span><span class="p">.</span><span class="nx">ignore_replies</span><span class="p">},</span>
            <span class="nx">clearContents</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
            <span class="nx">template</span><span class="o">:</span> <span class="s1">&#39;${bf.config.tweets.template}&#39;</span><span class="p">,</span>
            <span class="p">});</span>
    <span class="nt">&lt;/script&gt;</span>
    <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;tweet&quot;</span><span class="nt">&gt;</span>
    <span class="nt">&lt;/div&gt;</span>
<span class="nt">&lt;/div&gt;</span>
<span class="nt">&lt;br</span> <span class="nt">/&gt;</span>
</pre></div>
<p>Now when I compile the site it'll just throw all this into the sidebar, which
will load up my twitter feed as I described in the template. And I won't have
to have a twitter trigger or the like for updating my blog, which is I feel the
best of both worlds.</p>
</div>
</div>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>Switching to Blogofile</title>
      <link>http://morgangoose.com/blog/2010/09/28/switching-to-blogofile</link>
      <pubDate>Tue, 28 Sep 2010 13:03:00 PDT</pubDate>
      <category><![CDATA[Website]]></category>
      <category><![CDATA[Programming]]></category>
      <guid isPermaLink="true">http://morgangoose.com/blog/2010/09/28/switching-to-blogofile</guid>
      <description>Switching to Blogofile</description>
      <content:encoded><![CDATA[<div class="document">
<div class="section" id="so-wordpress-is-out">
<h1>So wordpress is out</h1>
<p>It had a nice run, and really did a lot of things I liked, highest among those
being that it worked. But even with my vim plugin for posting to the site, I
never really found myself happy with the whole setup. Then I stumbled upon
<a class="reference external" href="http://www.blogofile.com">blogofile</a> via a fork I spied in my github feed. After inspecting the project
and reading though the docs a bit I decided to give it a try.</p>
</div>
<div class="section" id="conversion-process">
<h1>Conversion process</h1>
<p>It was criminal how simple this was. I added <a class="reference external" href="http://disqus.com/">Disqus</a> comments (should have done
that ages ago) and imported all my old comments to the account. After that I
followed the <a class="reference external" href="http://www.blogofile.com/documentation/migrating_blogs.html#wordpress">directions</a> to switch from wordpress and used the two scripts they
provided. After a few mysql hickups (dumped the db to a machine that had
python-mysql), the scripts worked flawlessly.</p>
<p>I now had all of my posts, not a lot granted, in html <a class="reference external" href="http://www.blogofile.com">blogofile</a> form. Now I
mainly switched so that I could write up my posts in <a class="reference external" href="http://docutils.sourceforge.net/rst.html">rst</a> which I like a lot,
and use in other <a class="reference external" href="http://morgangoose.com/blog/2010/02/gnu-tools-presentation/">projects</a>. So now I had some conversions to make by hand to
get these posts into rst form.</p>
</div>
<div class="section" id="after-some-hand-editing">
<h1>After some hand editing</h1>
<p>I go to publish the site, and it's not liking my code directives. I use
these in other presentations and forgot that I'd made some changes to use the
directive, which I go into more depth about in a previous <a class="reference internal" href="#post">post</a>, but needed to
now retrofit into this project.</p>
<p id="post">The simple blog template had some helpers, but I had to pull the
rst_template.py filter from the blogofile.com template and edit it to give me the
highlighting control that I wanted.</p>
<div class="section" id="rst-template-py-changes">
<h2>rst_template.py changes</h2>
<div class="highlight"><pre><span class="c"># Set to True if you want inline CSS styles instead of classes</span>
<span class="n">INLINESTYLES</span> <span class="o">=</span> <span class="bp">False</span>
<span class="n">STYLE</span> <span class="o">=</span> <span class="s">&quot;fruity&quot;</span>

<span class="kn">from</span> <span class="nn">pygments.formatters</span> <span class="kn">import</span> <span class="n">HtmlFormatter</span>

<span class="c"># The default formatter</span>
<span class="n">DEFAULT</span> <span class="o">=</span> <span class="n">HtmlFormatter</span><span class="p">(</span><span class="n">noclasses</span><span class="o">=</span><span class="n">INLINESTYLES</span><span class="p">,</span> <span class="n">style</span><span class="o">=</span><span class="n">STYLE</span><span class="p">)</span>

<span class="c"># Add name -&gt; formatter pairs for every variant you want to use</span>
<span class="n">VARIANTS</span> <span class="o">=</span> <span class="p">{</span>
        <span class="s">&#39;linenos&#39;</span><span class="p">:</span> <span class="n">HtmlFormatter</span><span class="p">(</span><span class="n">noclasses</span><span class="o">=</span><span class="n">INLINESTYLES</span><span class="p">,</span> <span class="n">linenos</span><span class="o">=</span><span class="bp">False</span><span class="p">),</span>
    <span class="p">}</span>


<span class="kn">from</span> <span class="nn">docutils</span> <span class="kn">import</span> <span class="n">nodes</span>
<span class="kn">from</span> <span class="nn">docutils.parsers.rst</span> <span class="kn">import</span> <span class="n">directives</span><span class="p">,</span> <span class="n">Directive</span>
<span class="kn">from</span> <span class="nn">docutils.core</span> <span class="kn">import</span> <span class="n">publish_parts</span><span class="p">,</span> <span class="n">default_description</span>

<span class="kn">from</span> <span class="nn">pygments</span> <span class="kn">import</span> <span class="n">highlight</span>
<span class="kn">from</span> <span class="nn">pygments.lexers</span> <span class="kn">import</span> <span class="n">get_lexer_by_name</span><span class="p">,</span> <span class="n">TextLexer</span>


<span class="k">class</span> <span class="nc">Pygments</span><span class="p">(</span><span class="n">Directive</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot; Source code execution.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">required_arguments</span> <span class="o">=</span> <span class="mi">1</span>
    <span class="n">optional_arguments</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="n">final_argument_whitespace</span> <span class="o">=</span> <span class="bp">True</span>
    <span class="n">option_spec</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">([(</span><span class="n">key</span><span class="p">,</span> <span class="n">directives</span><span class="o">.</span><span class="n">flag</span><span class="p">)</span> <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">VARIANTS</span><span class="p">])</span>
    <span class="n">has_content</span> <span class="o">=</span> <span class="bp">True</span>

    <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">assert_has_content</span><span class="p">()</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">lexer</span> <span class="o">=</span> <span class="n">get_lexer_by_name</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">arguments</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
        <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
            <span class="c"># no lexer found - use the text one instead of an exception</span>
            <span class="n">lexer</span> <span class="o">=</span> <span class="n">TextLexer</span><span class="p">()</span>
        <span class="c"># take an arbitrary option if more than one is given</span>
        <span class="n">formatter</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">options</span> <span class="ow">and</span> <span class="n">VARIANTS</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">options</span><span class="o">.</span><span class="n">keys</span><span class="p">()[</span><span class="mi">0</span><span class="p">]]</span> <span class="ow">or</span> <span class="n">DEFAULT</span>

        <span class="k">print</span> <span class="o">&gt;&gt;</span><span class="nb">open</span><span class="p">(</span><span class="s">&#39;css/pygments_fruity.css&#39;</span><span class="p">,</span> <span class="s">&#39;w&#39;</span><span class="p">),</span> <span class="n">formatter</span><span class="o">.</span><span class="n">get_style_defs</span><span class="p">(</span>
                <span class="s">&#39;.highlight&#39;</span><span class="p">)</span>
        <span class="n">parsed</span> <span class="o">=</span> <span class="n">highlight</span><span class="p">(</span><span class="s">u&#39;</span><span class="se">\n</span><span class="s">&#39;</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">content</span><span class="p">),</span> <span class="n">lexer</span><span class="p">,</span> <span class="n">formatter</span><span class="p">)</span>
        <span class="k">return</span> <span class="p">[</span><span class="n">nodes</span><span class="o">.</span><span class="n">raw</span><span class="p">(</span><span class="s">&#39;&#39;</span><span class="p">,</span> <span class="n">parsed</span><span class="p">,</span> <span class="n">format</span><span class="o">=</span><span class="s">&#39;html&#39;</span><span class="p">)]</span>


<span class="n">config</span> <span class="o">=</span> <span class="p">{</span>
    <span class="s">&#39;name&#39;</span> <span class="p">:</span> <span class="s">&quot;reStructuredText&quot;</span><span class="p">,</span>
    <span class="s">&#39;description&#39;</span> <span class="p">:</span> <span class="s">&quot;Renders reStructuredText formatted text to HTML&quot;</span><span class="p">,</span>
    <span class="s">&#39;aliases&#39;</span> <span class="p">:</span> <span class="p">[</span><span class="s">&#39;rst&#39;</span><span class="p">]</span>
<span class="p">}</span>

<span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="n">content</span><span class="p">):</span>
    <span class="n">directives</span><span class="o">.</span><span class="n">register_directive</span><span class="p">(</span><span class="s">&#39;sourcecode&#39;</span><span class="p">,</span> <span class="n">Pygments</span><span class="p">)</span>
    <span class="n">directives</span><span class="o">.</span><span class="n">register_directive</span><span class="p">(</span><span class="s">&#39;code&#39;</span><span class="p">,</span> <span class="n">Pygments</span><span class="p">)</span>
    <span class="n">directives</span><span class="o">.</span><span class="n">register_directive</span><span class="p">(</span><span class="s">&#39;code&#39;</span><span class="p">,</span> <span class="n">Pygments</span><span class="p">)</span>

    <span class="n">description</span> <span class="o">=</span> <span class="p">(</span><span class="s">&#39;Generates S5 (X)HTML slideshow documents from standalone &#39;</span>
            <span class="s">&#39;reStructuredText sources.  &#39;</span> <span class="o">+</span> <span class="n">default_description</span><span class="p">)</span>

    <span class="k">return</span> <span class="n">publish_parts</span><span class="p">(</span><span class="n">content</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="s">&#39;html_body&#39;</span><span class="p">]</span>
</pre></div>
<p>So I added a lot into my site, and put in the theme I wanted to use in the css/
folder so that the style would publish when I build the site.</p>
</div>
</div>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>Using rst for presentations</title>
      <link>http://morgangoose.com/blog/2010/09/12/using-rst-for-presentations</link>
      <pubDate>Sun, 12 Sep 2010 18:03:00 PDT</pubDate>
      <category><![CDATA[Programming]]></category>
      <guid isPermaLink="true">http://morgangoose.com/blog/2010/09/12/using-rst-for-presentations</guid>
      <description>Using rst for presentations</description>
      <content:encoded><![CDATA[<div class="document">
<div class="section" id="presentations-are-hard">
<h1>Presentations are hard</h1>
<p>Not even just giving them, but the process of taking an idea and putting it
down in a concise and clear manner, that will be simple to show and distribute.</p>
<p>I am not going to make a claim that I am good at giving or writing up
presentations, but I do think I have a pretty slick setup going for making them
simple to show and distribute with minimal effort.</p>
</div>
<div class="section" id="restructuredtext">
<h1>reStructuredText</h1>
<p>People may be familiar with it already, but it's a markup language that's well
supported in python and used in the <a class="reference external" href="http://sphinx.pocoo.org/">Sphinx</a> project. It fits my brain well (in
most places) and only requires a text editor.</p>
<p>Since it comes with some tools to take a simple plain text document and
transform it into other well known formats (latex, html, and pdf), caused me
to use it in a number of projects and for notes without much friction.</p>
</div>
<div class="section" id="how-i-use-rest">
<h1>How I use reST</h1>
<p>I mentioned in a previous <a class="reference external" href="http://morgangoose.com/blog/2010/02/how-fabric-gets-it-right/">post</a> about my setup and how I leverage <a class="reference external" href="http://docs.fabfile.org">fabric</a> to
build and post my presentations, but I didn't really get too much into the
specifics of how the <a class="reference external" href="http://docutils.sourceforge.net/rst.html">rst</a> document was formatted, and built.</p>
<p>I write a presentation in rst just like I would write any other document in
rst. The goal I had was to write once, and have that document change into other
formats without an issue. I do leverage a few classes and directives that
aren't in the normal rst toolbox, to get my presentations just so. But these
aren't out of line, and after a tweak or two in my pipeline don't break the
other formats I build to.</p>
</div>
<div class="section" id="s5">
<h1>s5</h1>
<blockquote>
S5 is a slide show format based entirely on XHTML, CSS, and JavaScript.</blockquote>
<p>And rst2s5 takes a reStructuredText document and complies it into the
corresponding s5 representation. Giving back a plain html page with some
JavaScript magic that is simple to post and host.</p>
<p>No need for server side scripting, or fancy Apache/lighttpd/nginx setups or any
need for proxies or their kin. So using <a class="reference external" href="http://meyerweb.com/eric/tools/s5/">s5</a> alone will give me the goal of
simple to show, since I can post a presentation and have accesses to it
anywhere there is internet and a browser. I can even keep a copy on a
thumb drive in case the internet dies, and browse the slides locally.</p>
</div>
<div class="section" id="rest-with-s5">
<h1>reST with s5</h1>
<p>To meet the last part of my goal, I have to have a simple distribution medium.
For a presentation that is a pdf. It's akin to a paper, even though it is much
more broken down and split up into slides. Leveraging the <em>handout</em> class that
the s5 and pdf converters from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">rst</a> know, I am able to have parts of the
presentation invisible in slide form, and show up only when the presentation
is expanded, or complied into a pdf.</p>
<div class="section" id="eg">
<h2>eg</h2>
<div class="highlight"><pre><span class="gh">=========</span>
<span class="gh">GNU tools</span>
<span class="gh">=========</span>
<span class="gh">----------------------------</span>
<span class="gh">*mostly for text processing*</span>
<span class="gh">----------------------------</span>

<span class="p">..</span> <span class="ow">class</span><span class="p">::</span> right

    <span class="nv">`Morgan Goose http://morgangoose.com`</span>
    January 2010

<span class="p">..</span> <span class="ow">class</span><span class="p">::</span> handout

    This work is licensed under the Creative Commons
    Attribution-Noncommercial-Share Alike 3.0 United States License.
    To view a copy of this license, visit
    http://creativecommons.org/licenses/by-nc-sa/3.0/us/ or send a letter
    to Creative Commons, 171 Second Street, Suite 300, San Francisco,
    California, 94105, USA.
</pre></div>
<p>So the above will show my name on the first slide, but not the license. In the
pdf though that will all be on the first page. More tips on the s5 rst meshing
can be found on the docutils site's section for <a class="reference external" href="http://docutils.sourceforge.net/docs/user/slide-shows.html">slide-shows</a></p>
</div>
</div>
<div class="section" id="code-blocks">
<h1>Code blocks</h1>
<p>Normal reST had code directives that will differentiate the code, and in most
instances (Sphinx/Trac) will attempt to highlight the code accordingly. I ran
into issues here because rst2pdf and rst2s5 had different ideas on what these
should be named and neither really was highlighting the code. After searching a
bit I found that pygments, a code highlighter in python, already had some
docutils hooks that they <a class="reference external" href="http://pygments.org/docs/rstdirective/">mention on their site</a>.</p>
<p>Using that as a stepping stone I added in code, code, and source code,
directives to use pygments for the code they contained. In my presentations
though I made sure to only use code because this is the directive that
rst2pdf is expecting when it goes to format the document.</p>
<p>After that my code goes through the ringer as shown in the <a class="reference external" href="http://morgangoose.com/blog/2010/02/how-fabric-gets-it-right/">post</a> I gave
for fabric, in the line executing the rst-directive.py file and passing in the
pygments css for the theme that I prefer.</p>
<p>the final rst-directive.py looks like this though:</p>
<div class="highlight"><pre><span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    The Pygments reStructuredText directive</span>
<span class="sd">    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</span>

<span class="sd">    This fragment is a Docutils_ 0.5 directive that renders source code</span>
<span class="sd">    (to HTML only, currently) via Pygments.</span>

<span class="sd">    To use it, adjust the options below and copy the code into a module</span>
<span class="sd">    that you import on initialization.  The code then automatically</span>
<span class="sd">    registers a ``sourcecode`` directive that you can use instead of</span>
<span class="sd">    normal code blocks like this::</span>

<span class="sd">        .. sourcecode-block:: python</span>

<span class="sd">            My code goes here.</span>

<span class="sd">    If you want to have different code styles, e.g. one with line numbers</span>
<span class="sd">    and one without, add formatters with their names in the VARIANTS dict</span>
<span class="sd">    below.  You can invoke them instead of the DEFAULT one by using a</span>
<span class="sd">    directive option::</span>

<span class="sd">        .. sourcecode-block:: python</span>
<span class="sd">            :linenos:</span>

<span class="sd">            My code goes here.</span>

<span class="sd">    Look at the `directive documentation`_ to get all the gory details.</span>

<span class="sd">    .. _Docutils: http://docutils.sf.net/</span>
<span class="sd">    .. _directive documentation:</span>
<span class="sd">       http://docutils.sourceforge.net/docs/howto/rst-directives.html</span>

<span class="sd">    :copyright: Copyright 2006-2009 by the Pygments team, see AUTHORS.</span>
<span class="sd">    :license: BSD, see LICENSE for details.</span>
<span class="sd">&quot;&quot;&quot;</span>

<span class="c"># Options</span>
<span class="c"># ~~~~~~~</span>

<span class="c"># Set to True if you want inline CSS styles instead of classes</span>
<span class="n">INLINESTYLES</span> <span class="o">=</span> <span class="bp">False</span>
<span class="n">STYLE</span> <span class="o">=</span> <span class="s">&quot;fruity&quot;</span>

<span class="kn">from</span> <span class="nn">pygments.formatters</span> <span class="kn">import</span> <span class="n">HtmlFormatter</span>

<span class="c"># The default formatter</span>
<span class="n">DEFAULT</span> <span class="o">=</span> <span class="n">HtmlFormatter</span><span class="p">(</span><span class="n">noclasses</span><span class="o">=</span><span class="n">INLINESTYLES</span><span class="p">,</span> <span class="n">style</span><span class="o">=</span><span class="n">STYLE</span><span class="p">)</span>

<span class="c"># Add name -&gt; formatter pairs for every variant you want to use</span>
<span class="n">VARIANTS</span> <span class="o">=</span> <span class="p">{</span>
    <span class="s">&#39;linenos&#39;</span><span class="p">:</span> <span class="n">HtmlFormatter</span><span class="p">(</span><span class="n">noclasses</span><span class="o">=</span><span class="n">INLINESTYLES</span><span class="p">,</span> <span class="n">linenos</span><span class="o">=</span><span class="bp">False</span><span class="p">),</span>
<span class="p">}</span>


<span class="kn">from</span> <span class="nn">docutils</span> <span class="kn">import</span> <span class="n">nodes</span>
<span class="kn">from</span> <span class="nn">docutils.parsers.rst</span> <span class="kn">import</span> <span class="n">directives</span><span class="p">,</span> <span class="n">Directive</span>

<span class="kn">from</span> <span class="nn">pygments</span> <span class="kn">import</span> <span class="n">highlight</span>
<span class="kn">from</span> <span class="nn">pygments.lexers</span> <span class="kn">import</span> <span class="n">get_lexer_by_name</span><span class="p">,</span> <span class="n">TextLexer</span>

<span class="k">class</span> <span class="nc">Pygments</span><span class="p">(</span><span class="n">Directive</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot; Source code execution.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">required_arguments</span> <span class="o">=</span> <span class="mi">1</span>
    <span class="n">optional_arguments</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="n">final_argument_whitespace</span> <span class="o">=</span> <span class="bp">True</span>
    <span class="n">option_spec</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">([(</span><span class="n">key</span><span class="p">,</span> <span class="n">directives</span><span class="o">.</span><span class="n">flag</span><span class="p">)</span> <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">VARIANTS</span><span class="p">])</span>
    <span class="n">has_content</span> <span class="o">=</span> <span class="bp">True</span>

    <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">assert_has_content</span><span class="p">()</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">lexer</span> <span class="o">=</span> <span class="n">get_lexer_by_name</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">arguments</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
        <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
            <span class="c"># no lexer found - use the text one instead of an exception</span>
            <span class="n">lexer</span> <span class="o">=</span> <span class="n">TextLexer</span><span class="p">()</span>
        <span class="c"># take an arbitrary option if more than one is given</span>
        <span class="n">formatter</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">options</span> <span class="ow">and</span> <span class="n">VARIANTS</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">options</span><span class="o">.</span><span class="n">keys</span><span class="p">()[</span><span class="mi">0</span><span class="p">]]</span> <span class="ow">or</span> <span class="n">DEFAULT</span>

        <span class="k">print</span> <span class="o">&gt;&gt;</span><span class="nb">open</span><span class="p">(</span><span class="s">&#39;pygments.css&#39;</span><span class="p">,</span> <span class="s">&#39;w&#39;</span><span class="p">),</span> <span class="n">formatter</span><span class="o">.</span><span class="n">get_style_defs</span><span class="p">(</span><span class="s">&#39;.highlight&#39;</span><span class="p">)</span>
        <span class="n">parsed</span> <span class="o">=</span> <span class="n">highlight</span><span class="p">(</span><span class="s">u&#39;</span><span class="se">\n</span><span class="s">&#39;</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">content</span><span class="p">),</span> <span class="n">lexer</span><span class="p">,</span> <span class="n">formatter</span><span class="p">)</span>
        <span class="k">return</span> <span class="p">[</span><span class="n">nodes</span><span class="o">.</span><span class="n">raw</span><span class="p">(</span><span class="s">&#39;&#39;</span><span class="p">,</span> <span class="n">parsed</span><span class="p">,</span> <span class="n">format</span><span class="o">=</span><span class="s">&#39;html&#39;</span><span class="p">)]</span>

<span class="n">directives</span><span class="o">.</span><span class="n">register_directive</span><span class="p">(</span><span class="s">&#39;sourcecode&#39;</span><span class="p">,</span> <span class="n">Pygments</span><span class="p">)</span>
<span class="n">directives</span><span class="o">.</span><span class="n">register_directive</span><span class="p">(</span><span class="s">&#39;code&#39;</span><span class="p">,</span> <span class="n">Pygments</span><span class="p">)</span>
<span class="n">directives</span><span class="o">.</span><span class="n">register_directive</span><span class="p">(</span><span class="s">&#39;code&#39;</span><span class="p">,</span> <span class="n">Pygments</span><span class="p">)</span>

<span class="kn">from</span> <span class="nn">docutils.core</span> <span class="kn">import</span> <span class="n">publish_cmdline</span><span class="p">,</span> <span class="n">default_description</span>

<span class="n">description</span> <span class="o">=</span> <span class="p">(</span><span class="s">&#39;Generates S5 (X)HTML slideshow documents from standalone &#39;</span>
               <span class="s">&#39;reStructuredText sources.  &#39;</span> <span class="o">+</span> <span class="n">default_description</span><span class="p">)</span>

<span class="n">publish_cmdline</span><span class="p">(</span><span class="n">writer_name</span><span class="o">=</span><span class="s">&#39;s5&#39;</span><span class="p">,</span> <span class="n">description</span><span class="o">=</span><span class="n">description</span><span class="p">)</span>
</pre></div>
<p>And in combination with my <a class="reference external" href="http://morgangoose.com/blog/2010/02/how-fabric-gets-it-right/">fabric setup</a>
I can make new posts, publish to html and pdf, and republish with relative ease:</p>
<div class="highlight"><pre><span class="nv">$ </span>fab new:new_stuff
<span class="nv">$ </span>vim new_stuff/new_stuff.rst
<span class="nv">$ </span>fab upload:new_stuff
</pre></div>
</div>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>Fedora KVM with simple network forwards</title>
      <link>http://morgangoose.com/blog/2010/06/fedora-kvm-with-simple-network-forwards/</link>
      <pubDate>Wed, 02 Jun 2010 22:52:43 PDT</pubDate>
      <category><![CDATA[Servers]]></category>
      <category><![CDATA[Linux]]></category>
      <guid>http://morgangoose.com/blog/2010/06/fedora-kvm-with-simple-netowrk-forward/</guid>
      <description>Fedora KVM with simple network forwards</description>
      <content:encoded><![CDATA[<div class="document">
<p>Recently I've been teaching python to some high school students. It has been going well, but the development environment we had access to left a little bit to be desired. We were working with ages old solaris, vi only, and no real access to newer gnu (or other) tools. So a new setup was required, I went off to investigate.</p>
<p>I started with chroot, since a buddy, Daniel Thau, had used it extensively for running <a class="reference external" href="http://opensource.osu.edu/sites/default/files/chroottalk_0.pdf">multiple operating systems side by side</a>. He'd pointed me in the directions of <a class="reference external" href="http://people.redhat.com/~rjones/febootstrap/">febootstrap</a> and that seemed like it'd work fine. I was able to make a sandbox, get ssh running on 2022 and then have my dlink route that to my box. Success!</p>
<p>But I found that a bit messy, and a bit limited. I wanted to lock down how much of my resources they could use, and I didn't want to have to give access to some of my root file systems directly; /proc, /dev, etc. So I looked around a bit more, and stumbled on using KVM indirectly via the new virt-manager toolset that fedora 12 and 13 provide. Installation was as simple as:</p>
<div class="highlight"><pre><span class="nv">$ </span>yum install qemu-kvm virt-manager virt-viewer python-virtinst
</pre></div>
<p>But it also seems that from the <a class="reference external" href="http://www.techotopia.com/index.php/Installing_and_Configuring_Fedora_KVM_Virtualization">techotopia article</a> I followed for some of this that one could also just do:</p>
<div class="highlight"><pre><span class="nv">$ </span>yum groupinstall <span class="s1">&#39;Virtualization&#39;</span>
</pre></div>
<p>I have to say it's a pretty swank set of tools. It's free, it works on KVM or Xen. KVM usage requires no special kernel and as such, no reboot. The setup was simple, and gave out a vnc port to connect to from the get go. It is also trivial to connect to a setup on machine A with virt-manager on machine B over ssh. If you want more information, <a class="reference external" href="http://fedoraproject.org/wiki/Virtualization_Quick_Start">fedora has a nice writeup</a>, and libvirt has a more <a class="reference external" href="http://wiki.libvirt.org/page/Main_Page">distro agnostic set of docs</a>.</p>
<p>Problem was though that the networking was virtual, and didn't pull an IP address from my router, so it wasn't public. There were a few sections here and there describing how to switch to bridged, and I tried them. They didn't work for me, either I suck at following directions, or they just won't work how I expect them to. You can see for yourself <a class="reference external" href="http://wiki.libvirt.org/page/Networking#Fedora.2FRHEL_Bridging">here</a> at how I attempted network bridging.</p>
<p>What I did was much more in my realm of knowledge, is simpler than all the other options, and is something I can make changes to w/o killing my network connectivity. iptables! I just used NAT forwarding. It was 2 lines, put in my pre-existing firewall script. So to get my local box 192.168.1.199 on port 2022 to forward to its internal virtual network of 192.168.100.2 at port 22 was as plain as this:</p>
<div class="highlight"><pre><span class="nv">$ </span>iptables -t nat -I PREROUTING -p tcp --dport 2022 -j DNAT<span class="se">\</span>
    --to-destination 192.168.100.2:22
<span class="nv">$ </span>iptables -I FORWARD -p tcp --dport 22 -d 192.168.100.2 -j ACCEPT
</pre></div>
<p>One preroute rule to grab the port incoming, and one forward rule to pass said packets along. Now I have connectivity into my class virtual machine, and I don't have to do much to add more ports as needed. I am pretty happy with the setup so far. It's really nice to be able to connect remotely, vnc or ssh now, as well as know that I've limited the ram and cpu time the class can use on my box. I am interested to hear if anyone else is doing similar things with virtualization on their desktops.</p>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>Fedora with awesome window manager</title>
      <link>http://morgangoose.com/blog/2010/05/fedora-with-awesome-window-manager/</link>
      <pubDate>Sat, 29 May 2010 11:57:56 PDT</pubDate>
      <category><![CDATA[Linux]]></category>
      <guid>http://morgangoose.com/blog/2010/05/fedora-with-awesome-window-manager/</guid>
      <description>Fedora with awesome window manager</description>
      <content:encoded><![CDATA[<div class="document">
<p>I have recently gotten into tiling window managers. Awesome being the one I've found I like to use the most. There are others and they all have their merits, I just settled on this one, and then got comfortable. I also am a bit of a mutt in what distro's I use. Work they put ubuntu on my box, home I have usually used fedora but now it's fedora on the desktop and arch on the laptop.</p>
<p>So the issue was arch and ubuntu both had awesome in the package repos, and fedora did not. There is discussion out there as to why this was, and you might be interested in it. Me, I just wanted to use awesome. So using the directions from the awesome wiki and grabbing the required source rpms cairo-1.8.8-3.fc12.src.rpm and awesome-3.4.4-1.fc12.src.rpm, I now have awesome on my desktop.</p>
<p><strong>Here are some of the docs and sources I used:</strong></p>
<blockquote>
<ul class="simple">
<li><a class="reference external" href="http://awesome.naquadah.org/wiki/Awesome-3-fedora">directions from awesome's wiki</a></li>
<li><a class="reference external" href="http://mnowak.fedorapeople.org/awesome/">awesome src.rpms for fedora</a></li>
<li><a class="reference external" href="http://rpm.pbone.net/index.php3/stat/26/dist/69/size/6660576/name/cairo-1.8.8-3.fc12.src.rpm">the cario src.rpm</a></li>
<li><a class="reference external" href="https://bugzilla.redhat.com/show_bug.cgi?id=452427">discussion on package inclusion</a></li>
</ul>
</blockquote>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>How fabric gets it right</title>
      <link>http://morgangoose.com/blog/2010/02/how-fabric-gets-it-right/</link>
      <pubDate>Thu, 11 Feb 2010 00:56:33 PST</pubDate>
      <category><![CDATA[Tools]]></category>
      <category><![CDATA[Programming]]></category>
      <category><![CDATA[Linux]]></category>
      <guid>http://morgangoose.com/blog/?p=76</guid>
      <description>How fabric gets it right</description>
      <content:encoded><![CDATA[<div class="document">
<div class="section" id="i-like-fabric-a-lot">
<h1>I like <a class="reference external" href="http://docs.fabfile.org">fabric</a>. A lot.</h1>
<p>Its a easy to use tool that continually makes my life simpler, and my projects smarter and more automated. Not much out there can really say that. At least nothing I use daily, without noticing, and dependably.</p>
<p>I used to use vellum, and that did what I needed. But fabric being under active development, and getting new features each version it seems is a huge plus. That and it does the network stuff for you, along with the nitty gritty.</p>
<p>Recently I have been giving presentations to the <a class="reference external" href="http://opensource.osu.edu/">Ohio State University's Open Source Club</a> about <a class="reference external" href="http://morgangoose.com/p/gnu_tools/">gnu tools</a>, <a class="reference external" href="http://morgangoose.com/p/tool_oriented_python/">python tools</a>, and soon some cli apps. Fabric really helped make this simple for me to get a whole system down for making and uploading these.</p>
<p>I made all of those presentations in restrctured text, and compiled them into their final formats. All of which was scripted in fabric. I became really attached to ReST after getting introduced to it watching <a class="reference external" href="http://catherinedevlin.pythoneers.com/">Catherine Devlin</a> give a <a class="reference external" href="ahref=&quot;http://catherinedevlin.pythoneers.com/presentations/rst/olf.html">talk about restructured text</a> at Ohio Linux Fest. I ended up finding a cool rst2s5 command that makes nice presentations and with a little tweaking it now also has syntax highlighted code blocks, and can make nice pdfs.</p>
<p>In starting to use fabric you'll notice the basic idea is that you'd make a fabfile that works a lot like a Makefile or a SConstruct file would, with make and scons respectively. You'll make calls with the fab command in the directory the fabfile is located and it will supply the targets.</p>
<p>Below in this example, two targets are made, pack and deploy. The pack target will just makes a tarball, using the local function fabric provides. The deploy target calls pack to make this tarball, then using the put function will place the tarball into the tmp directory, then change into the web dir provided, and extract the archive. It knows automaticly to do this to both hosts I provided, and since I am using an ssh key does all this trickery autonomously.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">fabfile.py:</th><td class="field-body"></td>
</tr>
</tbody>
</table>
<div class="highlight"><pre><span class="kn">from</span> <span class="nn">fabric.api</span> <span class="kn">import</span> <span class="o">*</span>

<span class="n">env</span><span class="o">.</span><span class="n">user</span> <span class="o">=</span> <span class="s">&#39;username&#39;</span>
<span class="n">env</span><span class="o">.</span><span class="n">hosts</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;host1.com&#39;</span><span class="p">,</span> <span class="s">&#39;host2.com&#39;</span><span class="p">]</span>

<span class="k">def</span> <span class="nf">pack</span><span class="p">():</span>
    <span class="n">local</span><span class="p">(</span><span class="s">&#39;tar czf /tmp/project_foo.tgz project_foo/&#39;</span><span class="p">,</span> <span class="n">capture</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">deploy</span><span class="p">():</span>
    <span class="n">pack</span><span class="p">()</span>
    <span class="n">put</span><span class="p">(</span><span class="s">&#39;/tmp/project_foo.tgz&#39;</span><span class="p">,</span> <span class="s">&#39;/tmp/&#39;</span><span class="p">)</span>

    <span class="k">with</span> <span class="n">cd</span><span class="p">(</span><span class="s">&#39;/var/www/foo/&#39;</span><span class="p">):</span>
        <span class="n">run</span><span class="p">(</span><span class="s">&#39;tar xzf /tmp/project_foo.tgz&#39;</span><span class="p">)</span>
</pre></div>
</div>
<div class="section" id="fabric-can-do-a-lot-more-than-just-deploy">
<h1>Fabric can do a lot more than just deploy</h1>
<p>It's <a class="reference external" href="http://docs.fabfile.org">docs</a> have a lot of detail, and explain most everything well. A last example of some a cool fabric config would be the one I use to publish my presentations to this site.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">fabfile.py:</th><td class="field-body"></td>
</tr>
</tbody>
</table>
<div class="highlight"><pre><span class="kn">from</span> <span class="nn">fabric.api</span> <span class="kn">import</span> <span class="o">*</span>

<span class="n">env</span><span class="o">.</span><span class="n">roledefs</span> <span class="o">=</span> <span class="p">{</span>
    <span class="s">&#39;production&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s">&quot;morgangoose.com&quot;</span><span class="p">],</span>
    <span class="p">}</span>


<span class="k">def</span> <span class="nf">setup_vars</span><span class="p">(</span><span class="n">project</span><span class="p">):</span>
    <span class="k">global</span> <span class="n">presentation</span>
    <span class="k">global</span> <span class="n">presentation_archive</span>
    <span class="k">global</span> <span class="n">rst_source</span>
    <span class="k">global</span> <span class="n">pdf</span>

    <span class="n">project</span> <span class="o">=</span> <span class="n">project</span><span class="o">.</span><span class="n">strip</span><span class="p">(</span><span class="s">&quot;/&quot;</span><span class="p">)</span>
    <span class="n">presentation</span> <span class="o">=</span> <span class="n">project</span>
    <span class="n">presentation_archive</span> <span class="o">=</span> <span class="s">&quot;</span><span class="si">%s</span><span class="s">.tar.gz&quot;</span> <span class="o">%</span> <span class="n">presentation</span>
    <span class="n">rst_source</span> <span class="o">=</span> <span class="s">&quot;</span><span class="si">%s</span><span class="s">.rst&quot;</span> <span class="o">%</span> <span class="n">presentation</span>
    <span class="n">pdf</span> <span class="o">=</span> <span class="s">&quot;</span><span class="si">%s</span><span class="s">.pdf&quot;</span> <span class="o">%</span> <span class="n">presentation</span>

<span class="nd">@roles</span><span class="p">(</span><span class="s">&#39;production&#39;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">upload</span><span class="p">(</span><span class="n">project</span><span class="p">):</span>
    <span class="n">env</span><span class="o">.</span><span class="n">user</span> <span class="o">=</span> <span class="s">&quot;username&quot;</span>
    <span class="n">p_dir</span> <span class="o">=</span> <span class="s">&quot;/var/www/html/p/&quot;</span>

    <span class="n">package</span><span class="p">(</span><span class="n">project</span><span class="p">)</span>
    <span class="n">put</span><span class="p">(</span><span class="n">presentation_archive</span><span class="p">,</span> <span class="n">p_dir</span><span class="p">)</span>
    <span class="n">put</span><span class="p">(</span><span class="s">&quot;</span><span class="si">%s</span><span class="s">/</span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">presentation</span><span class="p">,</span> <span class="n">pdf</span><span class="p">),</span> <span class="n">p_dir</span><span class="p">)</span>
    <span class="k">with</span> <span class="n">cd</span><span class="p">(</span><span class="n">p_dir</span><span class="p">):</span>
        <span class="n">run</span><span class="p">(</span><span class="s">&quot;rm -rf </span><span class="si">%s</span><span class="s">/&quot;</span> <span class="o">%</span> <span class="n">presentation</span><span class="p">)</span>
        <span class="n">run</span><span class="p">(</span><span class="s">&quot;tar zxvf </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">presentation_archive</span><span class="p">)</span>

    <span class="n">local</span><span class="p">(</span><span class="s">&quot;rm -f </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">presentation_archive</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">package</span><span class="p">(</span><span class="n">project</span><span class="p">):</span>
    <span class="n">setup_vars</span><span class="p">(</span><span class="n">project</span><span class="p">)</span>
    <span class="n">make_presentation</span><span class="p">()</span>
    <span class="n">local</span><span class="p">(</span><span class="s">&quot;tar zcvf </span><span class="si">%s</span><span class="s"> </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">presentation_archive</span><span class="p">,</span> <span class="n">presentation</span><span class="p">))</span>

<span class="k">def</span> <span class="nf">make_presentation</span><span class="p">():</span>
    <span class="c">#PDF first</span>
    <span class="n">local</span><span class="p">(</span><span class="s">&quot;rst2pdf </span><span class="si">%s</span><span class="s">/</span><span class="si">%s</span><span class="s"> -o </span><span class="si">%s</span><span class="s">/</span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span>
        <span class="n">presentation</span><span class="p">,</span> <span class="n">rst_source</span><span class="p">,</span> <span class="n">presentation</span><span class="p">,</span> <span class="n">pdf</span><span class="p">,</span> <span class="p">))</span>

    <span class="c">#Then s5 html presentation</span>
    <span class="n">local</span><span class="p">(</span><span class="s">&quot;python rst-directive.py </span><span class="se">\</span>
<span class="s">            --stylesheet=pygments.css </span><span class="se">\</span>
<span class="s">            --theme=small-black </span><span class="se">\</span>
<span class="s">            --quiet </span><span class="se">\</span>
<span class="s">            </span><span class="si">%s</span><span class="s">/</span><span class="si">%s</span><span class="s"> &gt; </span><span class="si">%s</span><span class="s">/index.html&quot;</span> <span class="o">%</span> <span class="p">(</span>
                <span class="n">presentation</span><span class="p">,</span> <span class="n">rst_source</span><span class="p">,</span> <span class="n">presentation</span><span class="p">,</span> <span class="p">))</span>

<span class="k">def</span> <span class="nf">new</span><span class="p">(</span><span class="n">project</span><span class="p">):</span>
    <span class="n">setup_vars</span><span class="p">(</span><span class="n">project</span><span class="p">)</span>
    <span class="n">local</span><span class="p">(</span><span class="s">&quot;mkdir -p </span><span class="si">%s</span><span class="s">/{,files}&quot;</span> <span class="o">%</span> <span class="n">presentation</span><span class="p">)</span>
    <span class="n">local</span><span class="p">(</span><span class="s">&quot;cp -R ui </span><span class="si">%s</span><span class="s">/&quot;</span> <span class="o">%</span> <span class="n">presentation</span><span class="p">)</span>
    <span class="n">local</span><span class="p">(</span><span class="s">&quot;touch </span><span class="si">%s</span><span class="s">/</span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">presentation</span><span class="p">,</span> <span class="n">rst_source</span><span class="p">))</span>
</pre></div>
<p>This has some more complicated bits, where it uses the role decorator to specify only to use the hosts listed in the production role definitions.</p>
<p>It also takes advantage of an awesome feature I didn't know fabric had where, one can send arguments to a fabric target. So the project parameter in the targets here can be, and is, supplied via the command line.</p>
</div>
<div class="section" id="for-example">
<h1>For example</h1>
<p>I used this to deploy the updates to my most recent presentation:</p>
<div class="highlight"><pre><span class="nv">$ </span>fab upload:tool_oriented_python
</pre></div>
<p>That's telling fabric to run the upload target, and send the string &quot;tool_oriented_python&quot; as an argument to the function.</p>
<p>If you forget the targets you have just do:</p>
<div class="highlight"><pre><span class="nv">$ </span>fab -l
</pre></div>
</div>
</div>
]]></content:encoded>
    </item>
  </channel>
</rss>
