<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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/"
	>

<channel>
	<title>Alson Kemp</title>
	<atom:link href="http://www.alsonkemp.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.alsonkemp.com</link>
	<description>Hackfoofery</description>
	<lastBuildDate>Thu, 03 Dec 2009 17:21:12 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>HighCharts, Bluff, gRaphael &#8211; Javascript charting libraries</title>
		<link>http://www.alsonkemp.com/tools/highcharts-javascript-charting-library/</link>
		<comments>http://www.alsonkemp.com/tools/highcharts-javascript-charting-library/#comments</comments>
		<pubDate>Thu, 03 Dec 2009 00:49:43 +0000</pubDate>
		<dc:creator>alson</dc:creator>
				<category><![CDATA[Geekery]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://www.alsonkemp.com/?p=342</guid>
		<description><![CDATA[Bumped into HighCharts today.  See here: http://highcharts.com Very nice library for embedding charts into your HTML.  Nice to see that browsers are finally getting to the point that HighCharts can be written.   Also, it&#8217;s nice to think about being able to dump Flash charting solutions in favor of a simple Javascript library.  Worth the $80 [...]]]></description>
			<content:encoded><![CDATA[<p>Bumped into HighCharts today.  See here: <a href="http://highcharts.com" target="_blank">http://highcharts.com</a> Very nice library for embedding charts into your HTML.  Nice to see that browsers are finally getting to the point that HighCharts can be written.   Also, it&#8217;s nice to think about being able to dump Flash charting solutions in favor of a simple Javascript library.  Worth the $80 for commercial use (I don&#8217;t know about you, but I&#8217;ve spent well more than $80 of my time wrestling with an open source Flash charting library).</p>

<hr />

<p>[Updating post to add more libs.]</p>

<p>Okay.  I got called out for not poking around a bit more.  There are nice open-source, liberally licensed JS chart libs.</p>

<h3>Open Source</h3>

<p><a href="http://bluff.jcoglan.com" target="_blank">Bluff</a> : Ruby&#8217;s <a href="http://nubyonrails.com/pages/gruff" target="_blank">Gruff</a> ported to JS.  Looks pretty straightforward.</p>

<p><a href="http://g.raphaeljs.com/" target="_blank">gRaphael</a> : built on the awesome Raphael JS vector graphics library.  Limited functionality, but that&#8217;ll change.</p>

<p><a href="http://dragan.yourtree.org/code/canvas-3d-graph/" target="_blank">Canvas3D</a> : super cool, but not sure if it&#8217;s ready for a production site&#8230;</p>

<p><a href="http://www.jqplot.com" target="_blank">jqPlot</a> : charting for jQuery.  I&#8217;m neither pro- nor con-jQuery, so I&#8217;m not sure that I&#8217;d pick a jQuery-centric library.</p>

<p><a href="http://www.liquidx.net/plotkit/" target="_blank">PlotKit</a> : dependent on MochiKit.</p>

<p><a href="http://code.google.com/p/flot/" target="_blank">Flot</a> : charting for jQuery.  Again, since I use different JS libraries in different circumstances/apps, I&#8217;m not excited about having to pull in jQuery, but Flot looks nice.</p>

<h3>Commercial License</h3>

<p><a href="http://www.jscharts.com/" target="_blank">JSCharts</a> : HighCharts looks prettier&#8230;  $129 for a license for all of your sites (vs. $360 for <a href="http://highcharts.com" target="_blank">HighCharts</a>)</p>

<p><a href="http://www.ejschart.com" target="_blank">Emprise Charts</a> : Very nice.  Pricing is inline with JSCharts and HighCharts.</p>

<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 113px; width: 1px; height: 1px;">http://www.liquidx.net/plotkit/</div>
]]></content:encoded>
			<wfw:commentRss>http://www.alsonkemp.com/tools/highcharts-javascript-charting-library/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Ruby vs. JRuby: URI.parse fails with percent signs</title>
		<link>http://www.alsonkemp.com/turbinado/ruby-vs-jruby-uri-parse-fails-with-percent-signs/</link>
		<comments>http://www.alsonkemp.com/turbinado/ruby-vs-jruby-uri-parse-fails-with-percent-signs/#comments</comments>
		<pubDate>Fri, 27 Nov 2009 20:21:23 +0000</pubDate>
		<dc:creator>alson</dc:creator>
				<category><![CDATA[Turbinado]]></category>

		<guid isPermaLink="false">http://www.alsonkemp.com/?p=337</guid>
		<description><![CDATA[Ran into a nasty issue with URL parsing a while ago in a Rails app.  I was pulling URLs in from Amazon&#8217;s shopping APIs and started receiving occasional InvalidURIError exceptions.  Tracked it down to percent signs in the URLs passed from Amazon.  Percent signs are kinda reserved for escaping/encoding some characters in URLs, but, while [...]]]></description>
			<content:encoded><![CDATA[<p>Ran into a nasty issue with URL parsing a while ago in a Rails app.  I was pulling URLs in from Amazon&#8217;s shopping APIs and started receiving occasional InvalidURIError exceptions.  Tracked it down to percent signs in the URLs passed from Amazon.  Percent signs are kinda reserved for escaping/encoding some characters in URLs, but, while I&#8217;m not sure that the Amazon URLs are truly legal, the parsing function shouldn&#8217;t fail on a non-standard usages.  After all, the web is a messy place and failing-safe on parsing messy data seems a better behavior&#8230;    Examples:
<pre>irb(main):001:0&gt; require 'uri'
=&gt; true
irb(main):002:0&gt; u = URI.parse("http://www.yahoo.com/test?string=thing%ding") # questionable
URI::InvalidURIError: bad URI(is not URI?): http://www.yahoo.com/test?string=thing%ding
 from /home/alson/bin/../apps/jruby-1.4.0/lib/ruby/1.8/uri/common.rb:436:in <code>split'
 from /home/alson/bin/../apps/jruby-1.4.0/lib/ruby/1.8/uri/common.rb:484:in</code>parse'
 from (irb):3</p>

<p>irb(main):003:0&gt; u = URI.parse("http://www.yahoo.com/abba?test%20text")  # legal usage
=&gt; #&lt;URI::HTTP:0x164cbde URL:http://www.yahoo.com/abba?test%20text&gt;</p>

<p>irb(main):004:0&gt; u = URI.parse("http://www.yahoo.com/abba?test%u2020text") # quasi-legal usage
URI::InvalidURIError: bad URI(is not URI?): http://www.yahoo.com/abba?test%u2020text
 from /home/alson/bin/../apps/jruby-1.4.0/lib/ruby/1.8/uri/common.rb:436:in <code>split'
 from /home/alson/bin/../apps/jruby-1.4.0/lib/ruby/1.8/uri/common.rb:484:in</code>parse'
 from (irb):5</pre></p>

<h3>Enter JRuby</h3>

<p>Been thinking about checking out JRuby since I would then have access to the universe of Java libraries.  So Ruby&#8217;s URI.parse method is not very robust and I should have caught the exception, tried an alternate parser, etc, but what if I used the Java URL decoder on these URLs?  Works as expected:
<pre>irb(main):001:0&gt; include_class "java.net.URLDecoder"
=&gt; ["java.net.URLDecoder"]</p>

<p>irb(main):014:0&gt; u = URL.new("http://www.yahoo.com/test?string=thing%ding")                       
=&gt; #&lt;Java::JavaNet::URL:0x13e4a5a&gt;                                                                
irb(main):015:0&gt; u.getQuery                                                                       
=&gt; "string=thing%ding"                            </p>

<p>irb(main):013:0&gt; u = URL.new("http://www.yahoo.com/test%u2020tring")
=&gt; #&lt;Java::JavaNet::URL:0x3aef16&gt;
irb(main):014:0&gt; u.path
=&gt; "/test%u2020tring"</pre></p>

<h3>Lesson</h3>

<p>Ruby&#8217;s a great little language; Java&#8217;s a great big library =&gt; JRuby&#8217;s a great little language with a great big library.</p>

<p>Also, an interesting article on <a href="http://daringfireball.net/2009/11/liberal_regex_for_matching_urls" target="_blank">URL parsing</a> from DaringFireball.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.alsonkemp.com/turbinado/ruby-vs-jruby-uri-parse-fails-with-percent-signs/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Announce: Turbinado V0.7</title>
		<link>http://www.alsonkemp.com/turbinado/announce-turbinado-v07/</link>
		<comments>http://www.alsonkemp.com/turbinado/announce-turbinado-v07/#comments</comments>
		<pubDate>Sun, 14 Jun 2009 04:15:45 +0000</pubDate>
		<dc:creator>alson</dc:creator>
				<category><![CDATA[Turbinado]]></category>

		<guid isPermaLink="false">http://www.alsonkemp.com/?p=330</guid>
		<description><![CDATA[Turbinado has been making solid progress.  See the GitHub repo.

Added a couple of big new features:

HAML and XHTML Templates

While Turbinado used XHTML for templates before, the HSX library (an amazing piece of work) was a real pain to use and threw very strange errors. 

HSX (and its associated libraries) has been torn out of Turbinado and [...]]]></description>
			<content:encoded><![CDATA[<p>Turbinado has been making solid progress.  See <a href="http://github.com/turbinado/turbinado">the GitHub repo</a>.</p>

<p>Added a couple of big new features:</p>

<h3>HAML and XHTML Templates</h3>

<p>While Turbinado used XHTML for templates before, the HSX library (an amazing piece of work) was a real pain to use and threw very strange errors. </p>

<p>HSX (and its associated libraries) has been torn out of Turbinado and has been replaced by a custom preprocessor called &#8216;trturbinado&#8217;.  The preprocessor is run by the webserver over any templates (or views) before they&#8217;re compiled and loaded. The preprocessor handles XHTML and a limited version of HAML (to be enhanced).</p>

<p>See the example below.  After preprocessing, the &#8217;someHtml&#8217; and &#8217;someHAML&#8217; functions will yield the exact sasme code as the &#8217;someTextXHTML&#8217; function.</p>

<p><b>Note:</b> I&#8217;m not great at writing parsers, so I wouldn&#8217;t doubt that there are bugs in the preprocessor!</p>


<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;">markup <span style="color: #339933; font-weight: bold;">::</span> VHtml
markup<span style="color: #339933; font-weight: bold;">=</span>
  <span style="color: #339933; font-weight: bold;">&lt;</span>div<span style="color: #339933; font-weight: bold;">&gt;</span>
    <span style="color: #339933; font-weight: bold;">&lt;%</span> someTextXHtml <span style="color: #339933; font-weight: bold;">%&gt;</span>
    <span style="color: #339933; font-weight: bold;">&lt;%</span> someHtml <span style="color: #339933; font-weight: bold;">%&gt;</span>
    <span style="color: #339933; font-weight: bold;">&lt;%</span> someHAML <span style="color: #339933; font-weight: bold;">%&gt;</span>
  <span style="color: #339933; font-weight: bold;">&lt;/</span>div<span style="color: #339933; font-weight: bold;">&gt;</span>
&nbsp;
<span style="color: #5d478b; font-style: italic;">-- | These are the raw Turbinado.View.Html style tags</span>
someTextXHtml <span style="color: #339933; font-weight: bold;">::</span> VHtml
someTextXHtml <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span> s <span style="color: #339933; font-weight: bold;">&lt;-</span> getViewDataValue<span style="color: #339933; font-weight: bold;">_</span>u <span style="background-color: #3cb371;">&quot;sample_value&quot;</span> <span style="color: #339933; font-weight: bold;">::</span> View <span style="color: #cccc00; font-weight: bold;">String</span>
                   <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>tag <span style="background-color: #3cb371;">&quot;div&quot;</span><span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>
                    <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>tag <span style="background-color: #3cb371;">&quot;i&quot;</span><span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>stringToVHtml s<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">+++</span>
                    <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>tag <span style="background-color: #3cb371;">&quot;b&quot;</span><span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>stringToVHtml <span style="background-color: #3cb371;">&quot;some text in Turbinado.View.Html style&quot;</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
                    <span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
&nbsp;
someHtml <span style="color: #339933; font-weight: bold;">::</span> VHtml
someHtml <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span> s <span style="color: #339933; font-weight: bold;">&lt;-</span> getViewDataValue<span style="color: #339933; font-weight: bold;">_</span>u <span style="background-color: #3cb371;">&quot;sample_value&quot;</span> <span style="color: #339933; font-weight: bold;">::</span> View <span style="color: #cccc00; font-weight: bold;">String</span>
              <span style="color: #339933; font-weight: bold;">&lt;</span>div<span style="color: #339933; font-weight: bold;">&gt;</span>
                <span style="color: #339933; font-weight: bold;">&lt;</span>i<span style="color: #339933; font-weight: bold;">&gt;&lt;%=</span> s <span style="color: #339933; font-weight: bold;">%&gt;&lt;/</span>i<span style="color: #339933; font-weight: bold;">&gt;</span>
                <span style="color: #339933; font-weight: bold;">&lt;</span>b<span style="color: #339933; font-weight: bold;">&gt;</span>some text <span style="color: #06c; font-weight: bold;">in</span> XHtml style<span style="color: #339933; font-weight: bold;">&lt;/</span>b<span style="color: #339933; font-weight: bold;">&gt;</span>
              <span style="color: #339933; font-weight: bold;">&lt;/</span>div<span style="color: #339933; font-weight: bold;">&gt;</span>
&nbsp;
someHAML <span style="color: #339933; font-weight: bold;">::</span> VHtml
someHAML <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span> s <span style="color: #339933; font-weight: bold;">&lt;-</span> getViewDataValue<span style="color: #339933; font-weight: bold;">_</span>u <span style="background-color: #3cb371;">&quot;sample_value&quot;</span> <span style="color: #339933; font-weight: bold;">::</span> View <span style="color: #cccc00; font-weight: bold;">String</span>
              <span style="color: #339933; font-weight: bold;">%</span><span style="font-weight: bold;">div</span>
                <span style="color: #339933; font-weight: bold;">%</span>i<span style="color: #339933; font-weight: bold;">=</span> s
                <span style="color: #339933; font-weight: bold;">%</span>b some text <span style="color: #06c; font-weight: bold;">in</span> HAML style</pre></div></div>


<h3>FastCGI Support</h3>

<p>FastCGI has been an often requested feature, so I rewrote the CGI handling and added FastCGI support, too.  Much as with CGI, using FastCGI is very simple.  Just tell Apache to use &#8216;dispatch.fcgi&#8217; to handle requests.</p>

<p><pre>
<VirtualHost *>
  DocumentRoot /home/alson/projects/turbinado/static
  <Directory "/home/alson/projects/turbinado/static">
    Options +FollowSymLinks +ExecCGI +Includes
    AddHandler cgi-script cgi
    AddHandler fastcgi-script fcgi
    AllowOverride None
    Order allow,deny
    Allow from all
  </Directory>
  RewriteEngine On
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f
  RewriteRule (.<em>) $1 [L]
  # Use FCGI
  RewriteRule ^(.</em>)$ %{DOCUMENT_ROOT}/dispatch.fcgi [QSA,L]
  # Use CGI
  # RewriteRule ^(.*)$ %{DOCUMENT_ROOT}/dispatch.fcgi [QSA,L]
</VirtualHost>
</pre></p>

<p>Performance of Turbinado&#8217;s FastCGI interface is pretty good, but is well short of Turbinado&#8217;s HTTP interface, so, if you can live without the benefits of FastCGI, HTTP, which is simpler and faster, is the way to go.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.alsonkemp.com/turbinado/announce-turbinado-v07/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Turbinado V0.6.5</title>
		<link>http://www.alsonkemp.com/haskell/turbinado-v065/</link>
		<comments>http://www.alsonkemp.com/haskell/turbinado-v065/#comments</comments>
		<pubDate>Wed, 03 Jun 2009 06:24:05 +0000</pubDate>
		<dc:creator>alson</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Turbinado]]></category>

		<guid isPermaLink="false">http://www.alsonkemp.com/?p=323</guid>
		<description><![CDATA[Been a long silent few months (blog cliche, anyone?), but Turbinado is cranking along again.  Bodo (http://www.naumann.cc/) is using Turbinado for a school project so we&#8217;ve been working together to advance Turbinado.  So what&#8217;s new?  Mostly touch ups:

HTTP 4k Support

The HTTP 3000 package seems to be slowing down while HTTP 4000 seems [...]]]></description>
			<content:encoded><![CDATA[<p>Been a long silent few months (blog cliche, anyone?), but Turbinado is cranking along again.  Bodo (http://www.naumann.cc/) is using Turbinado for a school project so we&#8217;ve been working together to advance Turbinado.  So what&#8217;s new?  Mostly touch ups:</p>

<h3>HTTP 4k Support</h3>

<p>The <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HTTP-3001.1.5" target="_blank">HTTP 3000 package</a> seems to be slowing down while <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HTTP-4000.0.7" target="_blank">HTTP 4000</a> seems to be taking over.  Makes sense to update Turbinado to the latest version.  Done.</p>

<h3>Better Forms Support</h3>

<p>Added in support for multipart forms, so now you can upload files to Turbinado.  Note: there is currently no limit on the size of the upload, though.  (See Turbinado.Environment.Files for how to access uploaded files.)</p>

<h3>Improved ORM</h3>

<p>The PostgreSQL ORM is pretty sweet and now it&#8217;s even better.  Improved error handling, quoting of tables names, etc.  Next step is to build the MySQL ORM.</p>

<h3>Summary</h3>

<p>We&#8217;re moving again.  Note: <a href="http://github.com/alsonkemp/turbinado-website" target="_blank">turbinado-website</a> is currently updated, but <a href="http://github.com/alsonkemp/turbinado" target="_blank">turbinado</a> isn&#8217;t (it&#8217;ll be fixed by June 4th).</p>

<p>Would love your feedback on what could be done to improve Turbinado.  Although I made a point of running <a href="http://turbinado.org" target="_blank">turbinado.org</a> on Turbinado, it may be time to switch to a CMS that allows people to contribute to the project more easily.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.alsonkemp.com/haskell/turbinado-v065/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>SERPEngine : Charting SERP rankings</title>
		<link>http://www.alsonkemp.com/seo/serpengine-charting-serp-rankings/</link>
		<comments>http://www.alsonkemp.com/seo/serpengine-charting-serp-rankings/#comments</comments>
		<pubDate>Wed, 01 Apr 2009 02:13:37 +0000</pubDate>
		<dc:creator>alson</dc:creator>
				<category><![CDATA[SEO]]></category>

		<guid isPermaLink="false">http://www.alsonkemp.com/?p=320</guid>
		<description><![CDATA[Taking a bit of a break from Haskell stuff for the moment.  1000 pardons.



Had a bit of spare time on my hands and had an observation that at Angie&#8217;s List we have a peon who&#8217;s job it is to do daily Google searches for key search terms and then record the rank of each [...]]]></description>
			<content:encoded><![CDATA[<p>Taking a bit of a break from Haskell stuff for the moment.  1000 pardons.</p>

<hr />

<p>Had a bit of spare time on my hands and had an observation that at Angie&#8217;s List we have a peon who&#8217;s job it is to do daily Google searches for key search terms and then record the rank of each term into a spreadsheet.  It&#8217;s just as efficient and as career-enhancing as you imagine it might be.</p>

<p>Gotta be a better way to do it&#8230; we have machines for this, right?</p>

<p>So I pulled <a href="http://www.rubyonrails.org" target="_blank">Rails</a> and <a href="http://www.postgresql.org" target="_blank">PostgreSQL</a> out of the tool belt.  Started hacking.  Added a bit of <a href="http://teethgrinder.co.uk/open-flash-chart-2/" target="_blank">OpenFlashChart</a>.  Hacked a bit more.  <em>et voila!</em></p>

<p style="text-align: center;"><a href="http://serpengine.com"><img class="aligncenter" title="SERP Engine Logo" src="http://serpengine.com/images/logo.png" alt="" width="341" height="104" /></a></p>

<p><a href="http://serpengine.com">SERP Engine</a> is pretty simple.  If you have a website, you&#8217;ve probably thought a bit about fighting for some natural search terms.  Throw those search terms into <a href="http://serpengine.com" target="_blank">SERP Engine</a> and chart your website&#8217;s SERP rank for those terms.</p>

<p>Sound useless?  It&#8217;s actually pretty cool.  Check out the results for:</p>

<ul>
    <li><a href="http://serpengine.com/terms/xbox%20games" target="_blank">xbox games</a></li>
    <li><a href="http://serpengine.com/terms/peanut butter" target="_blank">peanut butter</a> &#8211; seriously, how did peanutbutter.com lose it?!</li>
    <li><a href="http://serpengine.com/terms/angies list" target="_blank">angies list</a></li>
</ul>

<p>Would love feedback.  alson at alsonkemp dot com.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.alsonkemp.com/seo/serpengine-charting-serp-rankings/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ANNOUNCE: Turbinado V0.6</title>
		<link>http://www.alsonkemp.com/haskell/announce-turbinado-v06/</link>
		<comments>http://www.alsonkemp.com/haskell/announce-turbinado-v06/#comments</comments>
		<pubDate>Fri, 13 Mar 2009 02:20:18 +0000</pubDate>
		<dc:creator>alson</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Turbinado]]></category>

		<guid isPermaLink="false">http://www.alsonkemp.com/?p=307</guid>
		<description><![CDATA[It&#8217;s been long enough since Turbinado V0.4 that I figured I&#8217;d skip V0.5 and go straight to announcing Turbinado V0.6.  Lots of new excellent features:


    By popular demand, support for CGI serving.  Apparently some web hosts don&#8217;t support HTTP proxying, so some folks requested CGI support.
    Statically compiled [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been long enough since Turbinado V0.4 that I figured I&#8217;d skip V0.5 and go straight to announcing Turbinado V0.6.  Lots of new excellent features:</p>

<ul>
    <li>By popular demand, support for CGI serving.  Apparently some web hosts don&#8217;t support HTTP proxying, so some folks requested CGI support.</li>
    <li>Statically compiled Layouts, Views, Controllers.</li>
    <li>Support for &#8220;.format&#8221; in routes.  If a request path is &#8220;/User/List.xml&#8221;, then the following View will be called: /App/Views/User/List<strong>Xml</strong>.hs.</li>
        <li>Lower case paths.
    <li>Support for cookies (see <a href="http://github.com/alsonkemp/turbinado-website/blob/master/App/Controllers/TestCookies.hs" target="_blank">here</a> for examples).</li>
    <li>Encrypted cookie sessions (see <a href="http://github.com/alsonkemp/turbinado-website/blob/master/App/Controllers/TestSession.hs" target="_blank">here</a> to see how to use them).</li>
    <li>Much easier installs using cabal-install.</li>
    <li>Support for GHC 6.10.  GHC 6.8 is no longer supported.</li>
</ul>

<p>Turbinado V0.7 will be all about:</p>

<ul>
    <li>Documentation. (seriously.)</li>
    <li>User authentication.</li>
    <li>Tutorials.</li>
</ul>

<h2>Installation</h2>

<p>Installation is pretty painless if you use <a href="http://hackage.haskell.org/trac/hackage/wiki/CabalInstall" target="_blank">cabal-install,</a> so make sure that you have cabal-install installed first.  See here: <a href="http://hackage.haskell.org/trac/hackage/wiki/CabalInstall" target="_blank">http://hackage.haskell.org/trac/hackage/wiki/CabalInstall</a>.</p>

<p>To install Turbinado:</p>

<blockquote><code>git clone git@github.com:alsonkemp/turbinado-website.git
cd turbinado-website
cabal install
[This might fail, saying that "trhsx" can't be found.  However, "trhsx" was built during the install and is probably at ~/.cabal/bin/trhsx, so copy "trhsx" to your path and re-run "cabal install".]</code></blockquote>

<h2>CGI Configuration</h2>

<p><strong><em>[Note: you don't want to use CGI without statically compiling in some Controllers, Layouts and Views.  See below.]</em></strong></p>

<p>Usually, Turbinado is called with &#8220;-p&#8221; to specify the port the process should listen on (e.g. &#8220;turbinado -p 8080&#8243;).  When called with the &#8220;-c&#8221; flag, Turbinado will handle CGI requests.  However, because of the process setup and tear down times, responding to CGI requests takes about 250ms, which is considerably slower than responding to HTTP requests (about 1ms).</p>

<p>Again following Rails, Turbinado includes a CGI script called &#8220;dispatch.cgi&#8221; in the /static directory.</p>

<h3>Apache Configuration</h3>

<p>In order to use Turbinado&#8217;s CGI functionality with Apache, you&#8217;ll need to something like the following in order to tell Apache to allow CGI scripts in your Turbinado /static directory and to send all requests (e.g. &#8220;^(.&#42;)$&#8221;) to the &#8220;dispatch.cgi&#8221; script.
<pre>  DocumentRoot /home/alson/turbinado-website/static
  &lt;Directory "/home/alson/turbinado-website/static"&gt;
     Options +FollowSymLinks +ExecCGI +Includes
     AddHandler cgi-script .cgi
     AllowOverride None
     Order allow,deny
     Allow from all
  &lt;/Directory&gt;
  RewriteRule ^(.*)$ %{DOCUMENT_ROOT}/dispatch.cgi [QSA,L]</pre></p>

<h2>Static Compilation Of Resources</h2>

<p>Turbinado is designed to dynamically compile and link in the various resources (Controllers, Layouts, Views) needed to serve a request.  However, it can take up to 15 seconds to complete that process the first time a particular page is requested (subsequent requests are very fast).  With CGI, the server only ever sees the first request, so Turbinado would never be able to serve a CGI request faster than 10-20 seconds.</p>

<p>To fix this, you can now compile into the server particular resources.  See Config/Routes.hs <a href="http://github.com/alsonkemp/turbinado-website/tree/master/Config/Routes.hs">here</a>.  Turbinado stores a function along with the file path and function name in a tuple, so you just give Turbinado that information in the Routes.hs file and it&#8217;ll load those functions into the CodeStore at startup:</p>


<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;">staticLayouts <span style="color: #339933; font-weight: bold;">=</span>
    <span style="color: green;">&#91;</span> <span style="color: green;">&#40;</span><span style="background-color: #3cb371;">&quot;App/Layouts/Default.hs&quot;</span><span style="color: #339933; font-weight: bold;">,</span> <span style="background-color: #3cb371;">&quot;markup&quot;</span><span style="color: #339933; font-weight: bold;">,</span> App<span style="color: #339933; font-weight: bold;">.</span>Layouts<span style="color: #339933; font-weight: bold;">.</span>Default<span style="color: #339933; font-weight: bold;">.</span>markup<span style="color: green;">&#41;</span>
    <span style="color: green;">&#93;</span></pre></div></div>


<h2>Support for &#8220;formats&#8221;</h2>

<p>Rails has great support for file formats.  Turbinado is trying to follow that lead.  The system will try to figure out the MIME type based on the extension.  According to the standard routes (Config/Routes.hs), the following path=>View mappings will occur:
<pre>
/abba/ding => /App/Views/Abba/Ding.hs
/abba/ding.xml => /App/Views/Abba/DingXml.hs
/bloof/snort/1.csv => /App/Views/Bloof/SnortCsv.hs
</pre></p>

<p>The same Controller handles all formats; only the View will change.  Also, usage of a format causes a blank Layout to be used (on the assumption that you don&#8217;t want a Layout used with a CSV, XML, etc output).</p>

<h2>Lower case paths</h2>

<p>Turbinado now defaults to using lower case paths (configured in Config/App.hs), so the following paths get mapped to Controllers and Views as follows:
<pre>
/abba/ding_fling => /App/Controllers/Abba.hs : dingFling
                 => /App/Views/Abba/DingFling.hs
</pre></p>

<h2>Cookies</h2>

<p>Cookies are now supported.  Examples <a href="http://github.com/alsonkemp/turbinado-website/blob/master/App/Controllers/TestCookies.hs">here</a>.
<pre>
setCookie $ mkCookie "counter" (show 0)
v <- getCookieValue "counter"
deleteCookie "counter"
</pre></p>

<h2>Cookie Sessions</h2>

<p>Session data is encrypted and stuffed into a cookie.  The encryption key is set in Config/App.hs.  Session usage examples are <a href="http://github.com/alsonkemp/turbinado-website/blob/master/App/Controllers/TestSession.hs">here</a>.
<pre>
setSessionValue "counter" "0"
v <- setSessionValue "counter"
deleteSessionKey "counter"
abandonSession
</pre></p>
]]></content:encoded>
			<wfw:commentRss>http://www.alsonkemp.com/haskell/announce-turbinado-v06/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>PS3 + Linux Media Serving (MythTV?  GMediaServer?  MediaTomb?)</title>
		<link>http://www.alsonkemp.com/geekery/ps3-linux-media-serving-mythtv-gmediaserver-mediatomb/</link>
		<comments>http://www.alsonkemp.com/geekery/ps3-linux-media-serving-mythtv-gmediaserver-mediatomb/#comments</comments>
		<pubDate>Mon, 09 Mar 2009 19:19:38 +0000</pubDate>
		<dc:creator>alson</dc:creator>
				<category><![CDATA[Geekery]]></category>
		<category><![CDATA[ps3 mediatomb]]></category>

		<guid isPermaLink="false">http://www.alsonkemp.com/?p=305</guid>
		<description><![CDATA[I recently got a PS3 (which is a lovely piece of hardware and software) and, given our collections of MP3s, WMAs and AVIs (a bunch of ripped children&#8217;s DVDs so that my son is free to physically shred up the actual DVDs), have been trying to figure out how to serve media to it over [...]]]></description>
			<content:encoded><![CDATA[<p>I recently got a PS3 (which is a lovely piece of hardware and software) and, given our collections of MP3s, WMAs and AVIs (a bunch of ripped children&#8217;s DVDs so that my son is free to physically shred up the actual DVDs), have been trying to figure out how to serve media to it over the network.</p>

<p>Serving from Windows is ludicrously simple using <a href="http://www.microsoft.com/windows/windowsmedia/player/11/default.aspx" target="_blank">Windows Media Player 11</a> or <a href="http://www.tversity.com" target="_blank">TVersity</a>, but I have a small, super-old-school Linux file server used for backups-and-such and I wanted to use it to serve media.  Turns out to be very simple to do so.</p>

<p>MythTV is the big guy in this space, but it had a number of issues for me:</p>

<ul>
    <li>Not particularly straightforward to set up (considering the very simple use case I had for it).</li>
    <li>Tons of functionality that I didn&#8217;t need, including a heavy front-end app (though there is a lighter weight web app I could have installed).</li>
    <li>I couldn&#8217;t figure out how to get it to serve WMAs and, since I&#8217;ve ripped a bunch of CDs to WMA, this was a killer.</li>
</ul>

<p>None of this is to say that MythTV is not a great piece of software; it was just way more than I needed.</p>

<p><a href="http://www.gnu.org/software/gmediaserver/" target="_blank">GMediaServer</a> is a GNU uPNP media server and it looked pretty good, but I wasn&#8217;t sure that it would serve video.  Documentation is a also bit lacking.</p>

<p>Enter <a href="http://mediatomb.cc/" target="_blank">MediaTomb</a>.  Simple, lightweight, basic media serving.  &#8220;apt-get install mediatomb&#8221; and I was pretty much there.  A slight, very well documented modification to the configuration file and I popped open a web browser, browsed to the built-in web interface and told MediaTomb to server my /share/media directory.  Walked over to my PS3 (on which the MediaTomb server was already listed) and started browsing my media files.</p>

<p>The only issue I had was when I updated the media files on the server.  Sometimes MediaTomb wouldn&#8217;t see the modifications and would send to the PS3 out-of-date data, probably because I was using inotify rather than just time-based refresh.  I switched to the time-based refresh and deleted the MediaTomb SQLite database and all was right with the world.</p>

<p>Useful links:</p>

<ul>
    <li>http://www.mediatomb.cc</li>
    <li>http://ubuntuforums.org/showthread.php?t=650020</li>
    <li>http://www.freesoftwaremagazine.com/columns/upnp_mediatomb_ps3_and_me</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.alsonkemp.com/geekery/ps3-linux-media-serving-mythtv-gmediaserver-mediatomb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Kudos to Bodo</title>
		<link>http://www.alsonkemp.com/haskell/kudos-to-bodo/</link>
		<comments>http://www.alsonkemp.com/haskell/kudos-to-bodo/#comments</comments>
		<pubDate>Tue, 10 Feb 2009 18:28:27 +0000</pubDate>
		<dc:creator>alson</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Turbinado]]></category>

		<guid isPermaLink="false">http://www.alsonkemp.com/?p=298</guid>
		<description><![CDATA[Bodo Nauman (http://www.naumann.cc/) got Turbinado to build with GHC 6.10 (after forcing me to fix a bunch of recently added bugs&#8230;).  Details are here.  There&#8217;s currently an issue with the crypto Hackage package which doesn&#8217;t build with GHC 6.10**.  Fortunately, the darcs version of crypto builds fine.

Bodo beat me by a couple of days to [...]]]></description>
			<content:encoded><![CDATA[<p>Bodo Nauman (<a href="http://www.naumann.cc/" target="_blank">http://www.naumann.cc/</a>) got <a href="http://www.turbinado.org" target="_blank">Turbinado </a>to build with GHC 6.10 (after forcing me to fix a bunch of recently added bugs&#8230;).  Details are <a href="http://www.naumann.cc/?p=9" target="_blank">here</a>.  There&#8217;s currently an issue with the <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Crypto" target="_blank">crypto</a> Hackage package which doesn&#8217;t build with GHC 6.10**.  Fortunately, the <a href="http://code.haskell.org/crypto/" target="_blank">darcs</a> version of crypto builds fine.</p>

<p>Bodo beat me by a couple of days to an updated &#8220;How to install Turbinado&#8221; post.  Since v0.5 is freshly minted (ahem&#8230; and debugged) (and includes cookies, cookie sessions (lifted from Michael Snoyman&#8217;s <a href="http://snoyman.com/hweb/" target="_blank">hweb</a>), a Rails-like <em>respondTo</em> function, &#8230;), I&#8217;ll post an update in a day or two.</p>

<p>Adolfo Builes also has started to replicate a Rails tutorial in Turbinado, so I hope I can point you to his results soon.</p>

<hr />

<p>** The crypto build fails when building some test applications.  What&#8217;s weird is that &#8220;cabal install&#8221; installs the <em>test</em> applications into the bin directory.  Why would I want test applications in /usr/local/bin?  I don&#8217;t see a Cabal flag for &#8220;just build the libraries&#8221;&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.alsonkemp.com/haskell/kudos-to-bodo/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Turbinado is &#8220;not nearly as innovative&#8221;</title>
		<link>http://www.alsonkemp.com/haskell/turbinado-is-not-nearly-as-innovative/</link>
		<comments>http://www.alsonkemp.com/haskell/turbinado-is-not-nearly-as-innovative/#comments</comments>
		<pubDate>Tue, 03 Feb 2009 18:28:24 +0000</pubDate>
		<dc:creator>alson</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Turbinado]]></category>

		<guid isPermaLink="false">http://www.alsonkemp.com/?p=282</guid>
		<description><![CDATA[From Happstack:

&#8220;[If HApps doesn't do anything...] the project will eventually be superceded by other Haskell frameworks like Turbinado which are not nearly as innovative&#8221;

Woohoo!  People are talking about Turbinado!

err&#8230; Wait! Turbinado is being dissed!

Turbinado vs. HApps

Each project is valid and valuable, so I&#8217;m hesitant to get to far into a X vs. Y discussion, but [...]]]></description>
			<content:encoded><![CDATA[<p>From <a href="http://blog.happstack.com/2009/01/21/announcing-happstack-a-fork-of-happs/" target="_blank">Happstack</a>:</p>

<p>&#8220;[If HApps doesn't do anything...] the project will eventually be superceded by other Haskell frameworks like Turbinado which are not nearly as innovative&#8221;</p>

<p><strong>Woohoo</strong>!  People are talking about <a href="http://www.turbinado.org" target="_blank">Turbinado</a>!</p>

<p><strong>err&#8230; Wait</strong>! Turbinado is being dissed!</p>

<h3>Turbinado vs. HApps</h3>

<p>Each project is valid and valuable, so I&#8217;m hesitant to get to far into a X vs. Y discussion, but here are some aspects that I thought about when evaluating HApps and developing Turbinado:</p>

<ul>
    <li>Turbinado is built on top of <a href="http://www.cs.chalmers.se/~d00nibro/" target="_blank">Nicklas Broberg</a>&#8217;s <a href="http://www.cs.chalmers.se/~d00nibro/hsp/" target="_blank">HSP/HSPR</a>, which I consider to be an innovative-port of ASP to Haskell&#8230;</li>
    <li>HApps is a much bigger project with many more features; <a href="http://www.turbinado.org" target="_blank">Turbinado</a> is small and needs your help [shameless plug: help <a href="http://github.com/alsonkemp/turbinado-website" target="_blank">here</a>].</li>
    <li>HApps seems more like a library of really useful functions which is very flexible; Turbinado is more like a web app framework and provides a web server along with defined mechanisms for adding <a href="http://turbinado.org/Architecture/Show/architecture-5-controllers" target="_blank">Controller</a>, <a href="http://turbinado.org/Architecture/Show/architecture-7-views" target="_blank">Views</a> and <a href="http://turbinado.org/Architecture/Show/architecture-8-components" target="_blank">Components</a>.  <a href="http://en.wikipedia.org/wiki/Convention_over_Configuration" target="_blank">Convention over Configuration</a> = different styles, not better styles.</li>
    <li>HApps seems less than simple (see <a href="http://happs.org/repos/happs.org/src/Main.hs" target="_blank">here</a>); Turbinado is all about simple (see <a href="http://github.com/alsonkemp/turbinado-website/blob/master/App/Controllers/Home.hs" target="_blank">here</a>)</li>
    <li>HApps has an aversion to relational databases; Turbinado observes that lots of people use relational databases and supports them.</li>
</ul>

<h3>Turbinado vs. HApps, again</h3>

<p>To me, it seems as though the choice between HApps and Turbinado depends more on orientation than on functionality.  If you are interested in: opposing RDMBSs, but are into something like <a href="http://www.sinatrarb.com/intro.html" target="_blank">Sinatra</a>, then HApps is probably the best choice; if you&#8217;re interested in writing web apps in the style of <a href="http://www.rubyonrails.org" target="_blank">Ruby On Rails</a>, then Turbinado (though young and pretty) may be the best choice, especially given the simplicity of building Turbinado<em> (newly cabal installable!  to be described in a forthcoming post with tutorials, install details, singing, dancing, high kicks, etc)</em>.</p>

<h3>Here&#8217;s To Success</h3>

<p>Most successful languages have more than one web framework, so I hope for success for both HApps and for Turbinado.  They&#8217;re very different frameworks and serve very different needs.  The Haskell community would be well served if both frameworks survived and <em>thrived</em>.  As Merb and Rails have demonstrated, cross-pollination is excellent; the stronger HApps and Turbinado are, the more they can benefit each other.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.alsonkemp.com/haskell/turbinado-is-not-nearly-as-innovative/feed/</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
		<item>
		<title>Cabal-install is awesome</title>
		<link>http://www.alsonkemp.com/haskell/cabal-install-is-awesome/</link>
		<comments>http://www.alsonkemp.com/haskell/cabal-install-is-awesome/#comments</comments>
		<pubDate>Sun, 01 Feb 2009 01:15:26 +0000</pubDate>
		<dc:creator>alson</dc:creator>
				<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://www.alsonkemp.com/?p=263</guid>
		<description><![CDATA[See also: 2009-The Year Of Hackage and A Plea For Cabal-install



I&#8217;m finally getting Turbinado updated for GHC 6.10 and I owe a huge debt to the cabal-install team (my preferred currency for debt payment is beer).  Turbinado is a bitch to install by hand because it depends on specific version of various packages.  One minor [...]]]></description>
			<content:encoded><![CDATA[<p>See also: <a href="http://www.alsonkemp.com/haskell/2009-the-year-of-hackage/" target="_blank">2009-The Year Of Hackage</a> and <a href="http://www.alsonkemp.com/haskell/a-plea-for-cabal-install/" target="_blank">A Plea For Cabal-install</a></p>

<hr />

<p>I&#8217;m finally getting <a href="http://www.turbinado.org">Turbinado</a> updated for GHC 6.10 and I owe a huge debt to the <a href="http://hackage.haskell.org/trac/hackage/wiki/CabalInstall">cabal-install</a> team (my preferred currency for debt payment is <em>beer</em>).  Turbinado is a bitch to install by hand because it depends on specific version of various packages.  One minor rev off and everything explodes.</p>

<p>So I&#8217;ve been bouncing between 3 machines working on Turbinado and trying to get the build cleaned up.  Once cabal-install is installed, it&#8217;s a simple &#8220;cabal install&#8221; to get all dependencies downloaded and built.  Much better than setting up a local packages directory, downloading 10 packages, trying to get the install order figured out and trying to remember which of the 10 packages is installed or not.</p>

<p>It&#8217;s fantastic that GHC is finally getting a package and build manager.</p>

<p>If you haven&#8217;t played with cabal-install, you should:
<pre>darcs get --partial http://darcs.haskell.org/cabal-install/
cd cabal-install
sh bootstrap.sh
ln -s ~/.cabal/bin/cabal ~/bin/cabal  ### or somewhere else useful</p>

<h2>cabal update</pre></h2>

<p>My only want for cabal-install is for it to install executables somewhere more useful than ~/.cabal.  But that&#8217;s a minor gripe&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.alsonkemp.com/haskell/cabal-install-is-awesome/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>
