<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Paul Gross's Blog</title>
	
	<link>http://www.pgrs.net</link>
	<description />
	<lastBuildDate>Fri, 23 Dec 2011 21:14:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/pgrs" /><feedburner:info uri="pgrs" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Setting up a Zotac ZBOX with XBMC as a home theater PC</title>
		<link>http://feedproxy.google.com/~r/pgrs/~3/qS3OdxZlbiQ/</link>
		<comments>http://www.pgrs.net/2011/12/23/setting-up-a-zotac-zbox-with-xbmc-as-a-home-theater-pc/#comments</comments>
		<pubDate>Fri, 23 Dec 2011 21:14:20 +0000</pubDate>
		<dc:creator>Paul Gross</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.pgrs.net/?p=22427</guid>
		<description><![CDATA[I have wanted a Home theater PC for awhile to play movies, music, Hulu, and more through my TV. I thought briefly about buying a prebuilt device (like a Roku), but I decided to hack one together myself. My main motivation was flexibility and the fact that I like to tinker. Furthermore, I wanted a <a href='http://www.pgrs.net/2011/12/23/setting-up-a-zotac-zbox-with-xbmc-as-a-home-theater-pc/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>I have wanted a <a href="http://en.wikipedia.org/wiki/Home_theater_PC">Home theater PC</a> for awhile to play movies, music, <a href="http://www.hulu.com">Hulu</a>, and more through my TV. I thought briefly about buying a prebuilt device (like a <a href="http://www.roku.com/">Roku</a>), but I decided to hack one together myself. My main motivation was flexibility and the fact that I like to tinker. Furthermore, I wanted a device with a hard drive that I could load up with files and play directly to a TV.</p>
<p>I asked around for recommendations, and several of my coworkers recommended <a href="http://www.zotac.com">Zotac</a>. After looking through their options, I decided on a <a href="http://www.zotac.com/index.php?page=shop.product_details&#038;flypage=flypage_images-SRW.tpl&#038;product_id=336&#038;category_id=118&#038;option=com_virtuemart&#038;Itemid=100170&#038;lang=en">Zotac ZBOX ID41</a> (here it is on <a href="www.amazon.com/ZOTAC-ZBOX-Intel-Mini-PC-ZBOX-ID41-PLUS-U/dp/B004WO8OBC">Amazon</a>).</p>
<h3>Setting up Ubuntu</h3>
<p>I decided to run <a href="https://wiki.ubuntu.com/OneiricOcelot">Ubuntu 11.10 Oneiric Ocelot</a> for the operating system. The Zotac ZBOX has no CD drive, so I downloaded the Ubuntu ISO from the website, and I used <a href="http://unetbootin.sourceforge.net">UNetbootin</a> to make a bootable USB drive. </p>
<p>I plugged an HDMI cable from the Zotac into my TV, and I plugged a wired USB keyboard and mouse in the Zotac. I inserted the USB drive and booted it up. It automatically booted from the drive, and I selected Install.</p>
<p>Once the installation was finished, I had to go to Settings -> Sound and choose the HDMI output. Then, sound correctly played through my TV.</p>
<h3>Setting up XMBC</h3>
<p>There is a lot of software for home theater PCs. I chose <a href="http://xbmc.org">XBMC</a> since it seems very polished and has a lot of plugins for different video sources (such as <a href="http://www.youtube.com">Youtube</a>). It&#8217;s also optimized for a remote instead of requiring a full keyboard.</p>
<p>I had to add an extra apt repository in order to install the latest version of XMBC (11.0 beta1). Here are the commands I ran:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> add-apt-repository ppa:nathan-renniewaldock<span style="color: #000000; font-weight: bold;">/</span>xbmc-stable
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> update
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> xbmc</pre></div></div>

<p>Then, I launched XBMC from Ubuntu. I was greeted with a screen that looked like:</p>
<p><a href="http://www.pgrs.net/wp-content/uploads/2011/12/xbmc-eden.jpg"><img src="http://www.pgrs.net/wp-content/uploads/2011/12/xbmc-eden-300x179.jpg" alt="" title="xbmc-eden" width="300" height="179" class="alignnone size-medium wp-image-22442" /></a></p>
<p>I went to Settings and changed my region to where I live. I also told XBMC to update my library on start. Then, I went to Weather and entered my zip code to get local weather. Next I went to Videos -> Add ons and installed a bunch of video add ons (such as Youtube, HGTV, etc).</p>
<p>At this point, I had to manually run XBMC whenever I restarted the computer. There are many strategies to boot directly into XBMC. I decided to just add XBMC as a Startup Item in Ubuntu. I also allowed Ubuntu to boot without a password. So Ubuntu boots up and then runs XBMC when it&#8217;s finished. If I need to go back to Ubuntu, I can just exit from XBMC.</p>
<h3>Uploading media</h3>
<p>XMBC uses filenames to figure out which movie or TV show a file represents. For example, with default settings, episodes of a TV show need to be named in one of the following formats:</p>
<pre>
foo.s01e01.*
foo.s01.e01.*
foo.s01_e01.*
foo_[s01]_[e01]_*
foo.1x01.*
foo.101.*
</pre>
<p>These files should be in a folder with the name of the show. The full set of instructions can be found on the XBMC website at <a href="http://wiki.xbmc.org/?title=TV_Shows_%28Video_Library%29">TV Shows (Video Library)</a>.</p>
<p>I created a Movies directory and a TV Shows directory under /home/paul/Videos and uploaded my media. Then, I added these directories to XMBC and set the content type to Movies and TV Shows respectively (see <a href="http://wiki.xbmc.org/index.php?title=Media_sources">Media Sources</a>).</p>
<p>Finally, I quit XBMC and restarted it. It scanned my directories and added the movies and TV shows to the library.</p>
<h3>Hulu</h3>
<p>Unfortunately, there are no officially supported Hulu plugins for XBMC. I managed to get an unoffical plugin working with some extra effort using <a href="http://forum.xbmc.org/showthread.php?t=79148">Bluecop&#8217;s beta video plugin repository</a>.</p>
<p>I downloaded the zip file from the site above and saved it to the Zotac. Then, in XBMC, I went to Settings -> Add ons and chose to install add ons from a zip file. At this point, the Hulu plugin appeared in the list of available plugins to install. I installed the plugin, but it still didn&#8217;t work.</p>
<p>By looking in the XBMC log (~/.xbmc/temp/xbmc.log), I discovered that Hulu requires a newer version of <a href="http://rtmpdump.mplayerhq.hu">rtmpdump</a> than Ubuntu ships with.</p>
<p>I built the latest rtmpdump from source with the following commands:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> libssl-dev
<span style="color: #c20cb9; font-weight: bold;">git</span> clone <span style="color: #c20cb9; font-weight: bold;">git</span>:<span style="color: #000000; font-weight: bold;">//</span>git.ffmpeg.org<span style="color: #000000; font-weight: bold;">/</span>rtmpdump
<span style="color: #7a0874; font-weight: bold;">cd</span> rtmpdump
<span style="color: #c20cb9; font-weight: bold;">make</span> <span style="color: #007800;">sys</span>=posix
<span style="color: #c20cb9; font-weight: bold;">cp</span> librtmp<span style="color: #000000; font-weight: bold;">/</span>librtmp.so.0 <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>i386-linux-gnu<span style="color: #000000; font-weight: bold;">/</span>librtmp.so.0</pre></div></div>

<p>The last step copies the new librtmp on top of the existing one, which isn&#8217;t great. Unfortunately, XBMC runs with a specified library path, so I couldn&#8217;t find an easy way to add a different directory to the path.</p>
<p>Now, Hulu works. Unfortunately, I have to browse for videos to play. If I search for a video, and then play it, I get the following error in the xbmc.log:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">ERROR: Error Type: <span style="color: #66cc66;">&lt;</span>type <span style="color: #483d8b;">'exceptions.AttributeError'</span><span style="color: #66cc66;">&gt;</span>
ERROR: Error Contents: _Info instance has no attribute <span style="color: #483d8b;">'videoid'</span>
ERROR: Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:
                      File <span style="color: #483d8b;">&quot;/home/paul/.xbmc/addons/plugin.video.hulu/default.py&quot;</span>, line <span style="color: #ff4500;">56</span>, <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #66cc66;">&lt;</span>module<span style="color: #66cc66;">&gt;</span>
                        modes <span style="color: black;">&#40;</span> <span style="color: black;">&#41;</span>
                      File <span style="color: #483d8b;">&quot;/home/paul/.xbmc/addons/plugin.video.hulu/default.py&quot;</span>, line <span style="color: #ff4500;">36</span>, <span style="color: #ff7700;font-weight:bold;">in</span> modes
                        stream_media.<span style="color: black;">Main</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
                      File <span style="color: #483d8b;">&quot;/home/paul/.xbmc/addons/plugin.video.hulu/resources/lib/stream_hulu.py&quot;</span>, line <span style="color: #ff4500;">148</span>, <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #0000cd;">__init__</span>
                        <span style="color: #008000;">self</span>.<span style="color: black;">queueAD</span><span style="color: black;">&#40;</span>video_id,<span style="color: #ff4500;">2</span>,<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
                      File <span style="color: #483d8b;">&quot;/home/paul/.xbmc/addons/plugin.video.hulu/resources/lib/stream_hulu.py&quot;</span>, line <span style="color: #ff4500;">420</span>, <span style="color: #ff7700;font-weight:bold;">in</span> queueAD
                        u += <span style="color: #483d8b;">'&amp;videoid=&quot;'</span>+<span style="color: #dc143c;">urllib</span>.<span style="color: black;">quote_plus</span><span style="color: black;">&#40;</span>common.<span style="color: black;">args</span>.<span style="color: black;">videoid</span><span style="color: black;">&#41;</span>+<span style="color: #483d8b;">'&quot;'</span>
                    <span style="color: #008000;">AttributeError</span>: _Info instance has no attribute <span style="color: #483d8b;">'videoid'</span></pre></div></div>

<p>Browsing works just fine, though, so I only browse for videos.</p>
<h3>Next Steps</h3>
<p>I&#8217;m still using a wired USB keyboard and mouse, but I&#8217;m planning to get a home theater friendly wireless keyboard/mouse combo. Something along the lines of a <a href="http://www.amazon.com/Wireless-Keyboard-Built-TouchPad-Pointer/dp/B003UE52ME">Rii Mini Wireless Keyboard</a>.</p>
<p>There are also hundreds of XBMC plugins I haven&#8217;t checked out yet, as well as other ways to customize XBMC.</p>
<img src="http://feeds.feedburner.com/~r/pgrs/~4/qS3OdxZlbiQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.pgrs.net/2011/12/23/setting-up-a-zotac-zbox-with-xbmc-as-a-home-theater-pc/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.pgrs.net/2011/12/23/setting-up-a-zotac-zbox-with-xbmc-as-a-home-theater-pc/</feedburner:origLink></item>
		<item>
		<title>Running multiple ruby projects with foreman and subcontractor</title>
		<link>http://feedproxy.google.com/~r/pgrs/~3/Mcrqk6OJNs0/</link>
		<comments>http://www.pgrs.net/2011/12/15/running-multiple-ruby-projects-with-foreman-and-subcontractor/#comments</comments>
		<pubDate>Fri, 16 Dec 2011 03:11:50 +0000</pubDate>
		<dc:creator>Paul Gross</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.pgrs.net/?p=22422</guid>
		<description><![CDATA[We have a suite of ruby applications at Braintree. There are many times when we need to run more than one of these apps at the same time. For example, we might need to run our login app in addition to whichever app we are working on. We use foreman as our process launcher, but <a href='http://www.pgrs.net/2011/12/15/running-multiple-ruby-projects-with-foreman-and-subcontractor/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>We have a suite of ruby applications at <a href="http://www.braintreepayments.com">Braintree</a>. There are many times when we need to run more than one of these apps at the same time. For example, we might need to run our login app in addition to whichever app we are working on.</p>
<p>We use <a href="https://github.com/ddollar/foreman">foreman</a> as our process launcher, but foreman does not handle running other projects in other rvm gemsets (and possibly ruby versions). One of my fellow developers, <a href="http://tony.pitluga.com">Tony Pitluga</a>, released a gem called <a href="https://github.com/pitluga/subcontractor">subcontractor</a> that handles these cases.</p>
<p>For example, our Procfile looks like:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">app: rails server
login: subcontract <span style="color:#006600; font-weight:bold;">--</span>rvm <span style="color:#996600;">&quot;--with-rubies rvmrc&quot;</span> <span style="color:#006600; font-weight:bold;">--</span>chdir ..<span style="color:#006600; font-weight:bold;">/</span>login <span style="color:#006600; font-weight:bold;">--</span>signal INT <span style="color:#006600; font-weight:bold;">--</span> rails server <span style="color:#006600; font-weight:bold;">-</span><span style="color:#CC0066; font-weight:bold;">p</span> <span style="color:#006666;">4000</span></pre></div></div>

<p>This runs the current app on port 3000 and the login app on port 4000 with a different home folder, ruby and gemset. The login line is roughly equivalent to running <code>cd ../login &#038;&#038; rvm --with-rubies rvmrc exec rails server -p 4000</code> The option <code>--with-rubies rvmrc</code> tells rvm to use the .rvmrc file to load the correct ruby and gemset. If a project doesn&#8217;t have an .rvmrc file, you can specify the ruby version:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">another_app: subcontract <span style="color:#006600; font-weight:bold;">--</span>rvm ruby<span style="color:#006600; font-weight:bold;">-</span>1.8.7<span style="color:#006600; font-weight:bold;">-</span>p249@another_app <span style="color:#006600; font-weight:bold;">--</span>chdir ..<span style="color:#006600; font-weight:bold;">/</span>another_app <span style="color:#006600; font-weight:bold;">--</span>signal INT <span style="color:#006600; font-weight:bold;">--</span> rails server <span style="color:#006600; font-weight:bold;">-</span><span style="color:#CC0066; font-weight:bold;">p</span> <span style="color:#006666;">4000</span></pre></div></div>

<img src="http://feeds.feedburner.com/~r/pgrs/~4/Mcrqk6OJNs0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.pgrs.net/2011/12/15/running-multiple-ruby-projects-with-foreman-and-subcontractor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.pgrs.net/2011/12/15/running-multiple-ruby-projects-with-foreman-and-subcontractor/</feedburner:origLink></item>
		<item>
		<title>speclj-growl 1.0 released</title>
		<link>http://feedproxy.google.com/~r/pgrs/~3/bhRRkdwUfRQ/</link>
		<comments>http://www.pgrs.net/2011/12/06/speclj-growl-1-0-released/#comments</comments>
		<pubDate>Wed, 07 Dec 2011 05:46:27 +0000</pubDate>
		<dc:creator>Paul Gross</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.pgrs.net/?p=22389</guid>
		<description><![CDATA[I just released version 1.0 of speclj-growl. This is a plugin for the speclj test framework for clojure which adds Growl popups for each spec run. For those unfamiliar with Growl, it is a notification system for Mac OS X which allows applications to show custom messages in system popups. speclj comes with autotest built <a href='http://www.pgrs.net/2011/12/06/speclj-growl-1-0-released/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>I just released version 1.0 of <a href="https://github.com/pgr0ss/speclj-growl">speclj-growl</a>. This is a plugin for the <a href="https://github.com/slagyr/speclj">speclj</a> test framework for clojure which adds <a href="http://growl.info">Growl</a> popups for each spec run. For those unfamiliar with <a href="http://growl.info">Growl</a>, it is a notification system for Mac OS X which allows applications to show custom messages in system popups.</p>
<p><a href="https://github.com/slagyr/speclj">speclj</a> comes with autotest built in. You can start an autotest process which will monitor the filesystem for changes. When tests or code change, the tests will be automatically run again. <a href="https://github.com/pgr0ss/speclj-growl">speclj-growl</a> adds to this process by showing the test results in a growl popup, so you can stay within your editor, glance at the corner of the screen, and see whether your tests passed or failed.</p>
<p>For example, say you have a clojure project using both speclj and speclj-growl (in my example, the speclj-growl project itself). The command <code>lein spec -a -f growl</code> will start autotest <code>(-a)</code> and add the growl formatter <code>(-f growl)</code>:</p>
<pre>
% lein spec -a -f growl

----- Tue Dec 06 23:03:32 CST 2011 -------------------------------------------------------------------
took 0.89041 seconds to determine file statuses.
reloading files:
  /Users/paul/speclj-growl/spec/speclj/report/growl_spec.clj

Growl Reporter
  report-runs
  - growls summary information for no test runs
  - growls a successful run
  - growls an unsuccessful run

Finished in 0.02542 seconds
3 examples, 0 failures
</pre>
<p>A growl message also appears on screen when the specs finish:</p>
<p><a href="http://www.pgrs.net/wp-content/uploads/2011/12/growl_success.png"><img src="http://www.pgrs.net/wp-content/uploads/2011/12/growl_success-300x95.png" alt="" title="growl_success" width="300" height="95" class="alignnone size-medium wp-image-22402" /></a></p>
<p>Now, if I change a spec to intentionally break it, the terminal automatically updates with the new spec output and a new growl message appears:</p>
<pre>
----- Tue Dec 06 23:04:58 CST 2011 -------------------------------------------------------------------
took 0.00414 seconds to determine file statuses.
reloading files:
  /Users/paul/speclj-growl/spec/speclj/report/growl_spec.clj

Growl Reporter
  report-runs  - growls summary information for no test runs (FAILED)
  - growls a successful run
  - growls an unsuccessful run

Failures:

  1) Growl Reporter report-runs growls summary information for no test runs     Expected: <"Failure">
          got: <"Success"> (using =)
     /Users/paul/speclj-growl/spec/speclj/report/growl_spec.clj:28

Finished in 0.00705 seconds
3 examples, 1 failures
</pre>
<p><a href="http://www.pgrs.net/wp-content/uploads/2011/12/growl_failure.png"><img src="http://www.pgrs.net/wp-content/uploads/2011/12/growl_failure-300x95.png" alt="" title="growl_failure" width="300" height="95" class="alignnone size-medium wp-image-22396" /></a></p>
<p>This cycle continues every time the source or spec files change.</p>
<p>Check out the code and installation instructions on github: <a href="https://github.com/pgr0ss/speclj-growl">https://github.com/pgr0ss/speclj-growl</a></p>
<p>Thanks to <a href="https://github.com/slagyr">Micah Martin</a> for both speclj and help with speclj-growl.</p>
<img src="http://feeds.feedburner.com/~r/pgrs/~4/bhRRkdwUfRQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.pgrs.net/2011/12/06/speclj-growl-1-0-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.pgrs.net/2011/12/06/speclj-growl-1-0-released/</feedburner:origLink></item>
		<item>
		<title>Using local jars with leiningen</title>
		<link>http://feedproxy.google.com/~r/pgrs/~3/IuIGAiBRmlA/</link>
		<comments>http://www.pgrs.net/2011/10/30/using-local-jars-with-leiningen/#comments</comments>
		<pubDate>Sun, 30 Oct 2011 23:18:11 +0000</pubDate>
		<dc:creator>Paul Gross</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.pgrs.net/?p=22374</guid>
		<description><![CDATA[Leiningen uses Maven to make dependency management of clojure projects much simpler. However, if you need to depend on jars that are not in a Maven repository, things get a little more complicated. For example, the Jukebox2 project depends on a bunch of java audio libraries like Jaad that do not live in a Maven <a href='http://www.pgrs.net/2011/10/30/using-local-jars-with-leiningen/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p><a href="https://github.com/technomancy/leiningen">Leiningen</a> uses <a href="http://maven.apache.org/">Maven</a> to make dependency management of clojure projects much simpler. However, if you need to depend on jars that are not in a Maven repository, things get a little more complicated.</p>
<p>For example, the <a href="https://github.com/thehammer/jukebox2">Jukebox2</a> project depends on a bunch of java audio libraries like <a href="http://jaadec.sourceforge.net">Jaad</a> that do not live in a Maven repository. We tried checking these jars directly into the lib directory, but leiningen would delete these jars whenever we ran &#8220;lein deps.&#8221;</p>
<p>The solution we came up with was to make a local Maven repository within the project. Then, anyone can clone the project and run &#8220;lein deps&#8221; and get all of the dependencies, including the local jars. Here are the steps:</p>
<ol>
<li>
    Create a directory in the project</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">mkdir</span> maven_repository</pre></div></div>

</li>
<li>
    Add local jars to this repository</p>
<p>    For example, this command adds the jaad-0.8.3.jar file to the maven repository.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">mvn <span style="color: #c20cb9; font-weight: bold;">install</span>:install-file <span style="color: #660033;">-Dfile</span>=jaad-0.8.3.jar <span style="color: #660033;">-DartifactId</span>=jaad <span style="color: #660033;">-Dversion</span>=0.8.3 <span style="color: #660033;">-DgroupId</span>=jaad <span style="color: #660033;">-Dpackaging</span>=jar <span style="color: #660033;">-DlocalRepositoryPath</span>=maven_repository</pre></div></div>

</li>
<li>
    Add the following to project.clj</p>

<div class="wp_syntax"><div class="code"><pre class="clojure" style="font-family:monospace;">:<span style="color: #555;">repositories</span> <span style="color: #66cc66;">&#123;</span><span style="color: #ff0000;">&quot;local&quot;</span> ~<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">str</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">.</span>toURI <span style="color: #66cc66;">&#40;</span>java<span style="color: #66cc66;">.</span>io<span style="color: #66cc66;">.</span>File<span style="color: #66cc66;">.</span> <span style="color: #ff0000;">&quot;maven_repository&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#125;</span></pre></div></div>

</li>
<li>
    Now a regular lein deps should work</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">lein deps
&nbsp;
Downloading: jaad<span style="color: #000000; font-weight: bold;">/</span>jaad<span style="color: #000000; font-weight: bold;">/</span>0.8.3<span style="color: #000000; font-weight: bold;">/</span>jaad-0.8.3.pom from <span style="color: #7a0874; font-weight: bold;">local</span>
Transferring 0K from <span style="color: #7a0874; font-weight: bold;">local</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span>WARNING<span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #000000; font-weight: bold;">***</span> CHECKSUM FAILED - Error retrieving checksum <span style="color: #c20cb9; font-weight: bold;">file</span> <span style="color: #000000; font-weight: bold;">for</span> jaad<span style="color: #000000; font-weight: bold;">/</span>jaad<span style="color: #000000; font-weight: bold;">/</span>0.8.3<span style="color: #000000; font-weight: bold;">/</span>jaad-0.8.3.pom - IGNORING</pre></div></div>

<p>    The warning can be ignored, since the jar will be checked into the project and not downloaded from the internet.
  </li>
</ol>
<p>The final results can be seen in the <a href="https://github.com/thehammer/jukebox2">Jukebox2</a> project.</p>
<p>Thanks to Matjaz on the <a href="http://groups.google.com/group/leiningen/browse_thread/thread/edd90c2285e7a413">Leiningen mailing list</a> for helping me figure out the right syntax for project.clj.</p>
<img src="http://feeds.feedburner.com/~r/pgrs/~4/IuIGAiBRmlA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.pgrs.net/2011/10/30/using-local-jars-with-leiningen/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://www.pgrs.net/2011/10/30/using-local-jars-with-leiningen/</feedburner:origLink></item>
		<item>
		<title>Why I don’t like feature branches</title>
		<link>http://feedproxy.google.com/~r/pgrs/~3/_CV2tb-szvg/</link>
		<comments>http://www.pgrs.net/2011/08/29/why-i-dont-like-feature-branches/#comments</comments>
		<pubDate>Tue, 30 Aug 2011 04:15:55 +0000</pubDate>
		<dc:creator>Paul Gross</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.pgrs.net/?p=22336</guid>
		<description><![CDATA[Before I dive into my main arguments, I do believe feature branches make sense for open source development. Generally, developers will work on branches dedicated to given features. This way, when they are done, they can present the branches to the community, get feedback, and make changes. Often times, they will not even have commit <a href='http://www.pgrs.net/2011/08/29/why-i-dont-like-feature-branches/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Before I dive into my main arguments, I do believe feature branches make sense for open source development.  Generally, developers will work on branches dedicated to given features. This way, when they are done, they can present the branches to the community, get feedback, and make changes. Often times, they will not even have commit rights, so a committer will have to take the branch and merge it in. This is much harder if the work was a collection of commits and not a cohesive feature branch. It is also common in open source for features to get rejected, so it&#8217;s helpful if these commits don&#8217;t clutter up the git history. Open source projects also tend to have more sporadic development as opposed to lots of developers all working in the code full time.</p>
<p>The problem is that most work done at companies do not have the same flow. For example, at <a href="braintreepayments.com">Braintree Payments</a>, we have about six developer pairs all working on different stories, all committing at the same time, and all with commit rights to our project. We trust that if a pair wrote the code, it&#8217;s good and is going into the project. In 99% of cases, if we are working on a feature, it is going to get released.</p>
<p>Given this kind of working environment, here is why I do not like feature branches:</p>
<h3>Feature branches make for nasty commit history</h3>
<p>Feature branching as a practice encourages lots of small commits, often before tests are passing or the code is in a useable state. Since these commits are on a branch, most people think it&#8217;s ok as long as the final merge commit back into master passes all of the tests.</p>
<p>The problem with this practice is that the commit history of the project is now full of broken work and non-passing code. I often use git history to get an idea of why a feature was done, or what other code was changed at the same time. I will &#8220;git blame&#8221; a method name to see when it was added, and what the code looked like at that point. With feature branches, I can no longer trust that commit. It may have been done on a branch, it may have broken half of the tests, and it may have been completely scrapped before the code went into master.</p>
<p>Furthermore, If feature branches are deleted once they are merged into master, where do bug fixes go? On a new feature branch or on master? There will no longer be an easy way to find a list of the commits that went into a feature. If feature branches are not deleted right away, the repository will likely end up with a huge number of branches.</p>
<h3>Feature branches generally have no builds</h3>
<p>We use <a href="http://jenkins-ci.org/">Jenkins</a> to continually test our application. We run numerous builds on every commit, including integration builds that call out to external dependencies.</p>
<p>When we do work on feature branches, we no longer have these builds. Developers will run the main suite of tests before they check in, but no one is going to run the full suite of integration tests on every commit. Furthermore, setting up new builds can be annoying, so we&#8217;re unlikely to do it unless we are going to maintain a branch for a long time.</p>
<h3>Lots of branches become cumbersome</h3>
<p>The lack of builds is one aspect of where lots of branches become cumbersome. Another is user testing. It is common to want the product owner or someone else to take a look at the feature before it&#8217;s done to get feedback. If you have a testing environment, they might want to deploy your code there to take a look (rather than looking over your shoulder on the workstation). But if you have feature branches, then they have to deploy your branch, which means they can no longer test other features at the same time. If they are in the middle of testing another feature that requires specific data, they may not be able to deploy your branch (e.g., if it has different database migrations that would require the database to be rebuilt).</p>
<h3>Feature branches make refactoring harder</h3>
<p>Modern version control tools like git make branching and merging much easier, but they are far from perfect. If we do large refactorings (especially refactorings that take numerous commits), it can become really hard to merge in feature branches. For example, if we rename methods, shift code between classes, or even reorder the methods in a class, the feature branch will likely get tons of conflicts on the merge. Then, someone has to go through each conflict and figure out where the code went. The longer the feature branch lives, the worse the merge becomes.</p>
<p>To take a specific example, say we want to switch our tests from one factory pattern to another. With feature branching, we would create a branch, and spend a few days porting over our tests. Then, when we merge back, we are going to run into conflicts with any tests that were changed by other feature branches. Even worse, while we are porting tests, other developers are still writing tests on their feature branches in the old style.</p>
<p>If we decide to make the test changes on master, but still have feature branches, all of the currently running feature branches have to continually merge from master in order to get the new tests. If they forget, and start modifying tests that have not been ported yet, they are still going to get conflicts when they merge back.</p>
<p>In contrast, if everyone is working in master, the people doing the refactoring can pull, make the changes, and commit frequently. As long as other developers also pull frequently (since everyone is making small, frequent commits), they automatically get the changes.</p>
<h3>My preferences</h3>
<p>Given that I don&#8217;t like feature branches, here is what I prefer:</p>
<p>All developers work in the master branch. When we are ready to release code to production, we merge master into a release branch, which gets some extra regression testing. We then tag from release and deploy the tag.</p>
<p>We use descriptive commit messages to signify what feature we are working on. For example, we use messages like &#8220;#card &#8211; message.&#8221; If we need to see all of the commits for a given feature, we can grep the git history for the card number. Likewise, if &#8220;git blame&#8221; a line of code, you can get back to the original story card and see why the feature was developed.</p>
<p>Commits only get pushed if they pass all of the tests. If a developer wants to make temp commits, that&#8217;s fine as long as they get squashed into a decent commit before pushing. Spike branches are fine for playing around, but the real work should be done on master once the approach is finalized.</p>
<p>On my last few projects, we have used a tool called <a href="https://github.com/pgr0ss/rake_commit">rake_commit</a> to do much of this work for us. It will prompt for a pair, story, and commit message, squash unpushed changes, run &#8220;git pull &#8211;rebase&#8221; (if working in git), run tests, and then push if the tests pass. This tool ensures a clean, linear git history.</p>
<p>For long running features, I prefer <a href="http://paulhammant.com/blog/branch_by_abstraction.html">Branch by Abstraction</a> and feature switches. This way, the features can be developed in master along side other development with the full suite of builds, but not necessarily impact the end user until the work is complete. If we have to release early for some reason (feature X just has to go out today), then we can release without the new features in use.</p>
<img src="http://feeds.feedburner.com/~r/pgrs/~4/_CV2tb-szvg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.pgrs.net/2011/08/29/why-i-dont-like-feature-branches/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://www.pgrs.net/2011/08/29/why-i-dont-like-feature-branches/</feedburner:origLink></item>
		<item>
		<title>Useful unix tricks – part 4</title>
		<link>http://feedproxy.google.com/~r/pgrs/~3/qe9a7chOtoo/</link>
		<comments>http://www.pgrs.net/2011/08/16/useful-unix-tricks-part-4/#comments</comments>
		<pubDate>Tue, 16 Aug 2011 16:40:56 +0000</pubDate>
		<dc:creator>Paul Gross</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.pgrs.net/?p=22302</guid>
		<description><![CDATA[Here is part 4 of my useful unix tricks series: Useful unix tricks Useful unix tricks &#8211; part 2 Useful unix tricks &#8211; part 3 Use mount -o bind to remount a filesystem When you mount a filesystem in linux, anything that was in the existing directory is now hidden and out of reach. For <a href='http://www.pgrs.net/2011/08/16/useful-unix-tricks-part-4/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Here is part 4 of my useful unix tricks series:</p>
<ul>
<li><a href="http://www.pgrs.net/2007/9/6/useful-unix-tricks">Useful unix tricks</a></li>
<li><a href="http://www.pgrs.net/2007/10/8/useful-unix-tricks-part-2">Useful unix tricks &#8211; part 2</a></li>
<li><a href="http://www.pgrs.net/2009/02/20/useful-unix-tricks-part-3">Useful unix tricks &#8211; part 3</a></li>
</ul>
<h3>Use mount -o bind to remount a filesystem</h3>
<p>When you mount a filesystem in linux, anything that was in the existing directory is now hidden and out of reach. For example:</p>
<pre>% touch /mnt/foo
% ls /mnt
./  ../  foo

% sudo mount /dev/sdb1 /mnt
% ls /mnt
./  ../</pre>
<p>If you want access to those files again, you can remount / using mount -o bind:</p>
<pre>% sudo mkdir /mnt2
% sudo mount -o bind / /mnt2
% ls /mnt2/mnt/foo
./  ../  foo</pre>
<p>This command remounts / under /mnt2, so you can access any file through /mnt2.</p>
<h3>less -R shows colors for control characters</h3>
<p>Programs like Rails write log output with terminal coloring information. If you open these files in less, you&#8217;ll see something like:</p>
<pre>% less development.log

ESC[4;36;1mSQL (0.2ms)ESC[0m   ESC[0;1mSET client_min_messages TO 'panic'ESC[0m
ESC[4;35;1mSQL (0.1ms)ESC[0m   ESC[0mSET client_min_messages TO 'notice'ESC[0m</pre>
<p>If you add the -R flag to less, it tells less to output raw control characters, which will color your terminal:</p>
<pre>% less -R development.log
SQL (0.2ms)   SET client_min_messages TO 'panic'
SQL (0.1ms)   SET client_min_messages TO 'notice'</pre>
<h3>Pressing alt+. will put in the previous command's last argument</h3>
<p>Pressing alt+. (the alt key and period) will drop the argument from the previous command into the terminal. For example:</p>
<pre>% mv foo.txt bar.txt
% cat &lt;press alt and .&gt;

# this becomes
% cat bar.txt
</pre>
<p>This is especially useful for combo commands, such as unstaging and checking out a file in git:</p>
<pre>
% git st
# On branch master
# Changes to be committed:
#   (use "git reset HEAD ..." to unstage)
#
#       modified:   foo
#

% git reset HEAD foo
Unstaged changes after reset:
M       foo

% git co &lt;alt+.&gt;
</pre>
<p>This is part of the emacs key bindings, and you can read more about them on stack overflow: <a href="http://stackoverflow.com/questions/4009412/bash-first-argument-of-the-previous-command">bash - first argument of the previous command</a></p>
<h3>Show git branch info in the prompt with coloring</h3>
<p>I do a lot of development with git, and I have a lot of different git repositories. It's handy to show git info in the prompt when I cd into a repo directory. At a minimum, I like seeing the current branch I have checked out.</p>
<p>For example, my prompt looks like:</p>
<pre>host:~% cd repo
host:~/repo (master)%
host:~/repo (master)% git co -b some_branch
Switched to a new branch 'some_branch'
host:~/repo (some_branch)%</pre>
<p>In zsh, getting a prompt like this is as simple as adding this to your .zshrc (or .zshenv) file:</p>
<pre>git_prompt_info() {
  ref=$(/usr/local/bin/git symbolic-ref HEAD 2&gt; /dev/null) || return
  echo " (${ref#refs/heads/})"
}

export PROMPT='%m:%~$(git_prompt_info)%# '</pre>
<p>I like colors in my prompt as well, so my .zshenv looks like:</p>
<pre>autoload -U colors
colors

git_prompt_info() {
  ref=$(/usr/local/bin/git symbolic-ref HEAD 2&gt; /dev/null) || return
  echo " (${ref#refs/heads/})"
}

export PROMPT='%{$fg_bold[green]%}%m:%{$fg_bold[blue]%}%~%{$fg_bold[green]%}$(git_prompt_info)%{$reset_color%}%# '</pre>
<p>After I load colors, I can use %{$fg_bold[color_name]} to change the following text to that color.</p>
<h3>Use tmux instead of screen</h3>
<p>For those that aren&#8217;t familiar with <a href="http://www.gnu.org/software/screen/">screen</a> or <a href="http://tmux.sourceforge.net/">tmux</a>, here is the description from the tmux website:</p>
<blockquote><p>
tmux is a terminal multiplexer: it enables a number of terminals (or windows), each running a separate program, to be created, accessed, and controlled from a single screen. tmux may be detached from a screen and continue running in the background, then later reattached.
</p></blockquote>
<p>Being able to detach and reattach is really nice when working on remote servers. You can ssh to a server, start tmux, run a long running process and then detach. Hours later, you can ssh to the server again and reattach to the tmux window. The program continued running after you detached, and you can see the output as if you never left.</p>
<p>tmux is also great for working with others remotely. Everyone can ssh into one server and connect to the same tmux. Then, everyone can see the same file, commands, etc. This is often how we work together on deploys at <a href="http://www.braintreepayments.com/">Braintree Payments</a>.</p>
<p>If you currently use screen, considering switching to tmux. They are very similar (both support everything I mentioned above), but tmux adds a few nice features:</p>
<ol>
<li>
tmux allows you to split the screen vertically so you can have two windows side by side. This is great for working on servers. You can tail the log in one split, and work in the other so you can keep an eye on the logs. Screen lets you split horizontally, but I find vertical splits more useful on widescreen monitors since there is not as much vertical real estate.
</li>
<li>
tmux adds a customizable status bar to the bottom of the terminal with information like which server you are on, the current time, tabs, etc.
</li>
<li>
If different people all connect to the same tmux, it will adjust the viewable area to be the smallest window size. Larger monitors will see a grayed out background filling in the extra space. In contrast, screen might put output where the smaller windows cannot see it.
</li>
</ol>
<h3>column -t will reformat input into columns</h3>
<p>Use column -t when printing tabular output where the columns do not align. For example:</p>
<pre>% print "one two\nthree four"
one two
three four

% print "one two\nthree four" | column -t
one    two
three  four</pre>
<p>I use this all the time with the program pg_lsclusters, which prints out postgresql cluster information:</p>
<pre>% pg_lsclusters
Version Cluster   Port Status Owner    Data directory                     Log file
8.4     backup_main 5433 down   postgres /var/lib/postgresql/8.4/backup_main /var/log/postgresql/postgresql-8.4-backup_main.log
8.4     main      5432 online postgres /var/lib/postgresql/8.4/main       /var/log/postgresql/postgresql-8.4-main.log

% pg_lsclusters | column -t
Version  Cluster      Port  Status  Owner     Data                                 directory                                           Log  file
8.4      backup_main  5433  down    postgres  /var/lib/postgresql/8.4/backup_main  /var/log/postgresql/postgresql-8.4-backup_main.log
8.4      main         5432  online  postgres  /var/lib/postgresql/8.4/main         /var/log/postgresql/postgresql-8.4-main.log</pre>
<h3>ctrl+p and ctrl+n cycle through terminal history</h3>
<p>If you want to run a previous command in terminal, it&#8217;s common to press the up and down arrows to cycle through old commands. You can also use ctrl+p for previous and ctrl+n for next. I prefer these keys since it leaves my hands near the home row rather than having to reach for the arrow keys.</p>
<img src="http://feeds.feedburner.com/~r/pgrs/~4/qe9a7chOtoo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.pgrs.net/2011/08/16/useful-unix-tricks-part-4/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://www.pgrs.net/2011/08/16/useful-unix-tricks-part-4/</feedburner:origLink></item>
		<item>
		<title>Migrated blog from Mephisto to WordPress</title>
		<link>http://feedproxy.google.com/~r/pgrs/~3/YCC4Ll2bOIA/</link>
		<comments>http://www.pgrs.net/2011/07/15/migrated-blog-from-mephisto-to-wordpress/#comments</comments>
		<pubDate>Fri, 15 Jul 2011 21:25:58 +0000</pubDate>
		<dc:creator>Paul Gross</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://wordpress.pgrs.net/?p=22227</guid>
		<description><![CDATA[I used to host my blog with Mephisto. Mephisto is blogging software written in Ruby on Rails, and I really enjoyed it. Unfortunately, the Mephisto project has been abandoned: http://techno-weenie.net/2010/6/23/you-can-let-go-now While it was still running fine for me, I wanted to make changes to my blog, and I figured it was time to move to <a href='http://www.pgrs.net/2011/07/15/migrated-blog-from-mephisto-to-wordpress/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>I used to host my blog with <a href="https://github.com/technoweenie/mephisto">Mephisto</a>. Mephisto is blogging software written in Ruby on Rails, and I really enjoyed it. Unfortunately, the Mephisto project has been abandoned: <a href="http://techno-weenie.net/2010/6/23/you-can-let-go-now">http://techno-weenie.net/2010/6/23/you-can-let-go-now</a></p>
<p>While it was still running fine for me, I wanted to make changes to my blog, and I figured it was time to move to software that is still active.</p>
<p>After searching around, I decided to move to <a href="http://wordpress.com">WordPress</a>. My main reasons were:</p>
<ol>
<li>Existing script to migrate all of my posts and comments from Mephisto.</li>
<li>Lots and lots of useful plugins.</li>
<li>Widely used and actively developed.</li>
</ol>
<p>I used a project on github called <a href="https://github.com/iamruinous/mephisto-to-wxr">mephisto-to-wxr</a> to export my Mephisto content as a WordPress export file. The script was a little outdated, so I forked and got it working with with my setup. You can check out my fork at: <a href="https://github.com/pgr0ss/mephisto-to-wxr">https://github.com/pgr0ss/mephisto-to-wxr</a></p>
<p>The syntax highlighting plugin I used with Mephisto required tags around code that looked like:</p>
<pre>
&lt;pre&gt;&lt;code class="ruby"&gt;
&lt;/code&gt;&lt;/pre&gt;
</pre>
<p>In WordPress, I&#8217;m using a plugin called <a href="http://wordpress.org/extend/plugins/wp-syntax/">WP-Syntax</a> which requires tags like:</p>
<pre>
&lt;pre lang="ruby"&gt;
&lt;/pre&gt;
</pre>
<p>To get the required output, I ran the WordPress export (which is xml) through the following sed command:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #ff0000;">'s/&lt;pre&gt;&lt;code class=/&lt;pre lang=/g'</span> pgrs.net.wxr <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #ff0000;">'s/&lt;\/code&gt;&lt;\/pre&gt;/&lt;\/pre&gt;/g'</span> <span style="color: #000000; font-weight: bold;">&gt;</span> pgrs.net.syntax_fix.wxr</pre></div></div>

<p>For those interested, here is my current setup in WordPress:</p>
<ul>
<li><a href="http://aquoid.com/news/themes/suffusion/">Suffusion</a> theme</li>
<li>Plugins:
<ul>
<li><a href="http://wordpress.org/extend/plugins/wordpress-importer/">WordPress Importer</a> to import the exported wxr file</li>
<li><a href="http://wordpress.org/extend/plugins/akismet/">Akismet</a> to prevent comment spam</li>
<li><a href="http://wordpress.org/extend/plugins/about-me-3000/">About Me 3000</a> for the About Me in the upper right</li>
<li><a href="http://wordpress.org/extend/plugins/wp-super-cache/">WP Super Cache</a> for page caching</li>
<li><a href="http://wordpress.org/extend/plugins/wp-syntax/">WP Syntax</a> for syntax highlighting</li>
</ul>
</li>
</ul>
<img src="http://feeds.feedburner.com/~r/pgrs/~4/YCC4Ll2bOIA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.pgrs.net/2011/07/15/migrated-blog-from-mephisto-to-wordpress/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.pgrs.net/2011/07/15/migrated-blog-from-mephisto-to-wordpress/</feedburner:origLink></item>
		<item>
		<title>Migrating from MySQL to PostgreSQL Slides</title>
		<link>http://feedproxy.google.com/~r/pgrs/~3/FBcfiHK0lxg/</link>
		<comments>http://www.pgrs.net/2011/03/25/migrating-from-mysql-to-postgresql-slides/#comments</comments>
		<pubDate>Fri, 25 Mar 2011 19:34:00 +0000</pubDate>
		<dc:creator>Paul Gross</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false" />
		<description><![CDATA[The slides from my PgEast talk are now online: Migrating from MySQL to PostgreSQL. The slides were generated using showoff.]]></description>
			<content:encoded><![CDATA[<p>The slides from my <a href="https://www.postgresqlconference.org/">PgEast</a> talk are now online: <a href="/wp-content/uploads/2011/03/pgeast_presentation.pdf">Migrating from MySQL to PostgreSQL</a>.</p>
<p>The slides were generated using <a href="https://github.com/schacon/showoff">showoff</a>.</p>
<img src="http://feeds.feedburner.com/~r/pgrs/~4/FBcfiHK0lxg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.pgrs.net/2011/03/25/migrating-from-mysql-to-postgresql-slides/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.pgrs.net/2011/03/25/migrating-from-mysql-to-postgresql-slides/</feedburner:origLink></item>
		<item>
		<title>PgEast Talk</title>
		<link>http://feedproxy.google.com/~r/pgrs/~3/na3_rLxAo0c/</link>
		<comments>http://www.pgrs.net/2011/03/15/pgeast-talk/#comments</comments>
		<pubDate>Tue, 15 Mar 2011 08:10:00 +0000</pubDate>
		<dc:creator>Paul Gross</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false" />
		<description><![CDATA[I&#8217;m giving a talk at the PgEast conference next week in NYC titled Migrating from MySQL to PostgreSQL. This talk will cover how Braintree migrated our credit card payment gateway, a Ruby on Rails application with millions of rows of data, from MySQL to PostgreSQL. The talk will be in three main parts: Why we <a href='http://www.pgrs.net/2011/03/15/pgeast-talk/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m giving a talk at the <a href="https://www.postgresqlconference.org/">PgEast</a> conference next week in <span class="caps">NYC</span> titled <a href="https://www.postgresqlconference.org/content/migrating-mysql-postgresql">Migrating from MySQL to PostgreSQL</a>.</p>
<p>This talk will cover how Braintree migrated our credit card payment gateway, a Ruby on Rails application with millions of rows of data, from MySQL to PostgreSQL. The talk will be in three main parts:</p>
<ol>
<li>Why we decided to switch and the benefits of PostgreSQL over MySQL</li>
<li>The tools and process we used to cut over with only a couple of minutes of downtime</li>
<li>The aftermath of the switch, rewriting parts of our code, and optimizing our application for PostgreSQL</li>
</ol>
<img src="http://feeds.feedburner.com/~r/pgrs/~4/na3_rLxAo0c" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.pgrs.net/2011/03/15/pgeast-talk/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.pgrs.net/2011/03/15/pgeast-talk/</feedburner:origLink></item>
		<item>
		<title>select_or_label with custom form builder</title>
		<link>http://feedproxy.google.com/~r/pgrs/~3/STjQLrVmOzA/</link>
		<comments>http://www.pgrs.net/2010/03/28/select_or_label-with-custom-form-builder/#comments</comments>
		<pubDate>Mon, 29 Mar 2010 02:17:00 +0000</pubDate>
		<dc:creator>Paul Gross</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false" />
		<description><![CDATA[In our web app, we have a common UI pattern: replacing select lists (eg. drop downs) with a label if there is only one item in the list. For example, when creating a subscription, the user must choose a plan. Normally, there is a list of plans to choose from. However, if there is only <a href='http://www.pgrs.net/2010/03/28/select_or_label-with-custom-form-builder/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>In our web app, we have a common UI pattern: replacing select lists (eg. drop downs) with a label if there is only one item in the list.  For example, when creating a subscription, the user must choose a plan.  Normally, there is a list of plans to choose from.  However, if there is only one plan that the user can choose, we show a label specifying the one plan they&#8217;re getting instead of showing them a list of one.</p>
<p>We implemented this with a custom form builder and a method called select_or_label.  It takes the same arguments as select, but only creates the select list if the list of choices has more than one element.</p>
<p>The view looks like:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">&lt;%</span> form_for <span style="color:#ff3333; font-weight:bold;">:subscription</span>, <span style="color:#ff3333; font-weight:bold;">:builder</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> SelectFormBuilder, <span style="color:#ff3333; font-weight:bold;">:url</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:controller</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:subscriptions</span>, <span style="color:#ff3333; font-weight:bold;">:action</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:create</span> <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>form<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#006600; font-weight:bold;">-%&gt;</span>
  <span style="color:#006600; font-weight:bold;">&lt;%</span>= form.<span style="color:#9900CC;">label</span> <span style="color:#ff3333; font-weight:bold;">:plan</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
  <span style="color:#006600; font-weight:bold;">&lt;%</span>= form.<span style="color:#9900CC;">select_or_label</span> <span style="color:#ff3333; font-weight:bold;">:plan_id</span>, Plan.<span style="color:#9900CC;">all</span>.<span style="color:#9900CC;">collect</span> <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>p<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#CC0066; font-weight:bold;">p</span>.<span style="color:#9900CC;">name</span>, <span style="color:#CC0066; font-weight:bold;">p</span>.<span style="color:#9900CC;">id</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">-%&gt;</span></pre></div></div>

<p>The form builder creates a span and a hidden_field if the size of the choices is 1:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> SelectFormBuilder <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActionView::Helpers::FormBuilder</span>
  <span style="color:#9966CC; font-weight:bold;">include</span> <span style="color:#6666ff; font-weight:bold;">ActionView::Helpers::TagHelper</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> select_or_label<span style="color:#006600; font-weight:bold;">&#40;</span>method, choices, options = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> choices.<span style="color:#9900CC;">size</span> == <span style="color:#006666;">1</span>
      content_tag<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:span</span>, choices.<span style="color:#9900CC;">first</span>.<span style="color:#9900CC;">first</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">+</span>
        hidden_field<span style="color:#006600; font-weight:bold;">&#40;</span>method, <span style="color:#ff3333; font-weight:bold;">:value</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> choices.<span style="color:#9900CC;">first</span>.<span style="color:#9900CC;">last</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">else</span>
      <span style="color:#CC0066; font-weight:bold;">select</span><span style="color:#006600; font-weight:bold;">&#40;</span>method, choices, options<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>And the spec:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">dirname</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF; font-weight:bold;">__FILE__</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">'/../spec_helper'</span>
&nbsp;
describe SelectFormBuilder, <span style="color:#ff3333; font-weight:bold;">:type</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:helper</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  describe <span style="color:#996600;">&quot;select_or_label&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    before <span style="color:#9966CC; font-weight:bold;">do</span>
      helper = <span style="color:#9966CC; font-weight:bold;">Class</span>.<span style="color:#9900CC;">new</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#9966CC; font-weight:bold;">include</span> <span style="color:#6666ff; font-weight:bold;">ActionView::Helpers</span> <span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">new</span>
      <span style="color:#0066ff; font-weight:bold;">@builder</span> = SelectFormBuilder.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:subscription</span>, Subscription.<span style="color:#9900CC;">new</span>, helper, <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span>, <span style="color:#0000FF; font-weight:bold;">nil</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    it <span style="color:#996600;">&quot;returns a span and hidden field if the size of the choices array is only one&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      html = <span style="color:#0066ff; font-weight:bold;">@builder</span>.<span style="color:#9900CC;">select_or_label</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:plan_id</span>, <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;name&quot;</span>, <span style="color:#996600;">&quot;id&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      html.<span style="color:#9900CC;">should_not</span> have_tag<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;select&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
      html.<span style="color:#9900CC;">should</span> have_tag<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;span&quot;</span>, <span style="color:#996600;">&quot;name&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      html.<span style="color:#9900CC;">should</span> have_tag<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;input[type=hidden][name=?][value=?]&quot;</span>, <span style="color:#996600;">&quot;subscription[plan_id]&quot;</span>, <span style="color:#996600;">&quot;id&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    it <span style="color:#996600;">&quot;returns a select if the size of the choices array is greater than one&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      html = <span style="color:#0066ff; font-weight:bold;">@builder</span>.<span style="color:#9900CC;">select_or_label</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:plan_id</span>, <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;name&quot;</span>, <span style="color:#996600;">&quot;id&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;other name&quot;</span>, <span style="color:#996600;">&quot;other_id&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      html.<span style="color:#9900CC;">should_not</span> have_tag<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;input&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
      html.<span style="color:#9900CC;">should</span> have_tag<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;select[name=?]&quot;</span>, <span style="color:#996600;">&quot;subscription[plan_id]&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
        with_tag<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;option[value=?]&quot;</span>, <span style="color:#996600;">&quot;id&quot;</span>, <span style="color:#996600;">&quot;name&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        with_tag<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;option[value=?]&quot;</span>, <span style="color:#996600;">&quot;other_id&quot;</span>, <span style="color:#996600;">&quot;other name&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<img src="http://feeds.feedburner.com/~r/pgrs/~4/STjQLrVmOzA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.pgrs.net/2010/03/28/select_or_label-with-custom-form-builder/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.pgrs.net/2010/03/28/select_or_label-with-custom-form-builder/</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic page generated in 0.754 seconds. --><!-- Cached page generated by WP-Super-Cache on 2012-01-30 21:26:03 --><!-- Compression = gzip -->

