<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" version="2.0">
  <channel>
    <title>HickoryTech</title>
    <link>http://tech.hickorywind.org/articles.rss</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>The Geekier Side of Twang</description>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/Hickorytech" type="application/rss+xml" /><item>
      <title>Larry vs. the Git Rebase Merge Conflict</title>
      <description>&lt;p&gt;While doing a "git svn rebase", if you have merge conflicts here are some things to remember:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;While doing a rebase, if anything bad happens, you end up on a "(no-branch)" branch.&lt;/li&gt;
&lt;li&gt;When doing a "git status", you'll see a ".dotest" file in your working directory.  Just ignore it.&lt;/li&gt;
&lt;li&gt;If you want to bail, do a "git rebase --abort".  (Note there is no "git svn rebase --abort".)&lt;/li&gt;
&lt;li&gt;Fix the merge conflict file manually, then do a "git add [file]".&lt;/li&gt;
&lt;li&gt;Next do a "git rebase --continue".  (Note there's no "svn" version of this either.)&lt;/li&gt;
&lt;li&gt;If it complains about "did you forget to call 'git add'?", then evidently your edit turned the conflict into a no-op change.  Do a "git rebase --skip" to skip it. (Very weird, but true.)&lt;/li&gt;
&lt;li&gt;Rinse and repeat until the lather is gone, your scalp silky smooth, and the rebase is complete.  At any time you can "git rebase --abort" to bail.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What happened to me?  Well, I didn't realize what was going on, continued to work on the "not a branch" branch, commited changes, even dcommited changes back to Subversion.  It was ugly, but not insurmountable.  A buddy clued me into the "not a branch" situation, I was able to get back to my real branch and resurrect my code.  It took a few "git rebase --continue" commands, and a tense moment around a "git rebase --skip", but now everything's hunky dory.&lt;/p&gt;

&lt;p&gt;This &lt;a href="http://kerneltrap.org/mailarchive/git/2007/10/31/373985"&gt;very odd email&lt;/a&gt; really helped me a lot.  You might be interested at some point.&lt;/p&gt;</description>
      <pubDate>Tue, 10 Jun 2008 08:30:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:bdece0c0-d3f7-4385-b4c2-485952ccfe4d</guid>
      <comments>http://tech.hickorywind.org/articles/2008/06/10/larry-vs-the-git-rebase-merge-conflict#comments</comments>
      <category>git</category>
      <link>http://tech.hickorywind.org/articles/2008/06/10/larry-vs-the-git-rebase-merge-conflict</link>
    </item>
    <item>
      <title>Relevance @ RailsConf 2008</title>
      <description>&lt;p&gt;Today I'm attending my first &lt;a href="http://en.oreilly.com/rails2008"&gt;RailsConf&lt;/a&gt; and coincidentally my first conference as a &lt;a href="http://www.thinkrelevance.com/"&gt;Relevance&lt;/a&gt; employee.  Let me tell you, Relevance does conferences differently than anywhere else I've worked.  I'll argue that they do them &lt;em&gt;right&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;First off, we put 80% of the company on one plane yesterday. (Hmm, okay, maybe that was a little scary.)  We took up several rows on the plane, and we definitely made an impression on the passengers and staff.  Several rows of geeks all sitting with MacBook Pros passing airplane power cords up and down the rows was a sight to see!  Much hacking got done, for sure.&lt;/p&gt;

&lt;p&gt;Secondly, pretty much the entire company is giving a tutorial together later this afternoon.  Technically, the talk is being given by the company's founders, Stu Halloway and Justin Gehtland, and two of the principals, &lt;a href="http://robsanheim.com"&gt;Rob Sanheim&lt;/a&gt; and &lt;a href="http://jasonrudolph.com/blog/"&gt;Jason Rudolph&lt;/a&gt;, but in reality we're all pitching in.  The session itself is a bit different -- it's a hands-on walk-through of how to approach a Ruby open source project and contribute.  It's metric-tool heavy and really gives your average Ruby/Rails programmer a firm grasp of how to take a four hour coding session and turn it into useful patches for a real open source project.  It's one of the most innovative and interesting tutorials I've seen in my several years as an open source guy, and I'm proud to be a part of it.&lt;/p&gt;

&lt;p&gt;I hope y'all will stop by our tutorial today if you're in the conference.  If you can't make it, be sure to stop one of the Relevance guys to say hello.  You'll see us in our "think relevance" t-shirts all up and down the halls.  Relevance is &lt;em&gt;all-in&lt;/em&gt; at RailsConf.&lt;/p&gt;</description>
      <pubDate>Thu, 29 May 2008 11:43:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:8bdbeee5-8c19-4be7-9450-91212263c9cc</guid>
      <comments>http://tech.hickorywind.org/articles/2008/05/29/relevance-railsconf-2008#comments</comments>
      <link>http://tech.hickorywind.org/articles/2008/05/29/relevance-railsconf-2008</link>
    </item>
    <item>
      <title>Content-Length (Mostly) Does Not Matter: The Reverse Bob Barker Rule</title>
      <description>&lt;p&gt;Your webapp user needs to download a file, but you don't know the exact size of this file ahead of time.  So what do you send as the content-length?  Is an incorrect content-length okay?  Do you even need a content-length?  The Internet is pretty silent on the subject.&lt;/p&gt;

&lt;p&gt;For example, my webapp users want to download several files as one zip file, but I don't want to create the zip file ahead of time just to know the content-length.  I'd rather create the zip file on the fly and stream it to the user a chunk at a time, as it's created.  This saves me time, process memory, code to clean up temporary zip files, etc.  However, the problem here is -- how big will this zip file be?  What do I send as the content-length?&lt;/p&gt;

&lt;p&gt;More importantly, what does content length really do?  Is it important?  What happens if you don't set it?&lt;/p&gt;

&lt;h3&gt;Effects of Content Length&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The web browser will NOT read more bytes than the content-length value. If you accidentally set your content-length too low, the download is halted prematurely and the downloaded file will most likely be corrupt. &lt;strong&gt;Do NOT set it too low.&lt;/strong&gt;  This is the only case where content-length can really hurt you.&lt;/li&gt;
&lt;li&gt;If the content-length is set the web browser will show a progress bar while downloading.  This is a very important usability feature for medium and large files, and you really want it.  You want your user to know how far along they are, so they don't cancel the download and start it over,  or worse just abandon your site.&lt;/li&gt;
&lt;li&gt;If the content-length is not set, then the user gets an "Unknown Size" message while downloading, and they won't get a progress bar.  Avoid this if possible, but it is sometimes okay for very small files that get downloaded so fast the user won't care they didn't see a progress bar.  (Still, you want to avoid this.)&lt;/li&gt;
&lt;li&gt;If you set the content-length to zero (usually only by accident), then your web browser will usually gleefully say they downloaded the file successfully, and save a zero-length empty file.  &lt;strong&gt;Do not set the content length to zero.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;The Reverse Bob Barker Rule&lt;/h3&gt;

&lt;p&gt;That first effect is the most important:  Don't set the content-length too low, or your users will suffer corrupted files. So this brings us to the &lt;em&gt;reverse-Bob-Barker rule&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;&lt;strong&gt;"Get as close to the real content-length as possible without going UNDER."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;Why Not Go WAY Over?&lt;/h3&gt;

&lt;p&gt;Okay, so we know not to go under, but why not just go way over?  Why not, for example, just double our estimated size?  Well, nothing terrible will happen.  The browser will keep trying to read content, and when the server says "no more," the browser will safely finish the file and say done, even if it thought there was more content coming.&lt;/p&gt;

&lt;p&gt;The only negative is that you want the user to get the best download experience possible.  So if you guessed your content-length to be 100 MB, but the real download is actually 50 MB, the user will see a progress bar showing they are 50% of the way done, with probably another minute to download, and then suddenly the browser goes from 50% to 100%, from one minute left to &lt;em&gt;done&lt;/em&gt;!  The user will be confused.  &lt;/p&gt;

&lt;p&gt;We call this the "Goldilocks Effect" in usability.  In this case, the porridge was too hot -- the user will be left wondering why the download dramatically sped up at the last minute.  Did the file download successfully?  Did the download really fail but the browser didn't tell us?  Although nothing bad &lt;em&gt;actually&lt;/em&gt; happened, the user is still left with a sense of unease.  We definitely want to avoid this.&lt;/p&gt;

&lt;h3&gt;How Close is Close Enough?&lt;/h3&gt;

&lt;p&gt;So, all this boils down to:  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you don't know the exact content-length ahead of time, determine a good cheating algorithm and pad for safety.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But how much padding do you need?  How much is enough?  What's too much?  My experience is this: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Aim for a padding of 1%.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here's my scale:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Padding over 10% is so inaccurate that the user won't believe the progress bar.  "We jumped from 90% to done immediately?  Is this thing broken? Is my file corrupt?"&lt;/li&gt;
&lt;li&gt;Padding of between 3% to 10% is less fantastic, but still pretty bad.&lt;/li&gt;
&lt;li&gt;Padding of between 1% and 3% is the best you can expect in most cases.  Depending on the size of the file, the download percentage usually jumps in 2-5% increments anyway.  This is only unacceptable for the largest of files, where web browsers are showing download percentages in 1% increments.  (And even there this is sometimes the best you can do.)&lt;/li&gt;
&lt;li&gt;Padding under 1% is a bit dangerous unless you have a lot of confidence in your guessing algorithm.  Remember, the only way to &lt;em&gt;really&lt;/em&gt; lose here is to guess under the real content-length.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So this brings us to 1% padding.  In most cases, this should be fairly easy to predict, and the web browser will show a 99% to 100% download progress, which is what the user wants to see anyway.&lt;/p&gt;

&lt;h3&gt;Where Does This Work?&lt;/h3&gt;

&lt;p&gt;I've tested this "extra content-length" technique on the following platforms, all with success:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Internet Explorer 6 on Windows XP (on VMWare on my Mac)&lt;/li&gt;
&lt;li&gt;Internet Explorer 7 on Windows XP (on VMWare on my Mac)&lt;/li&gt;
&lt;li&gt;Firefox 2 on Macintosh&lt;/li&gt;
&lt;li&gt;Firefox 3 RC1 on Macintosh&lt;/li&gt;
&lt;li&gt;Safari 3.1.1&lt;/li&gt;
&lt;/ul&gt;</description>
      <pubDate>Fri, 23 May 2008 11:30:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:be170240-4007-4a10-a77e-774f1d8e1e9f</guid>
      <comments>http://tech.hickorywind.org/articles/2008/05/23/content-length-mostly-does-not-matter-the-reverse-bob-barker-rule#comments</comments>
      <link>http://tech.hickorywind.org/articles/2008/05/23/content-length-mostly-does-not-matter-the-reverse-bob-barker-rule</link>
    </item>
    <item>
      <title>Installing id3lib-ruby gem on Leopard</title>
      <description>&lt;p&gt;Took me a bit to figure this out (big thanks to Sam U!), but it's actually pretty easy.&lt;/p&gt;

&lt;p&gt;Install &lt;a href="http://id3lib.sourceforge.net/"&gt;id3lib&lt;/a&gt; using &lt;a href=http://www.macports.org/""&gt;MacPorts&lt;/a&gt; like so:&lt;/p&gt;

&lt;pre&gt;
$ sudo port install id3lib
&lt;/pre&gt;

&lt;p&gt;Then the harder part, install the &lt;a href="http://id3lib-ruby.rubyforge.org/"&gt;id3lib-ruby&lt;/a&gt; gem as so:&lt;/p&gt;

&lt;pre&gt;
$ sudo env ARCHFLAGS="-arch i386" gem install id3lib-ruby  -- --build-flags --with-opt-dir=/opt/local
&lt;/pre&gt;

&lt;p&gt;Note that you change the ARCHFLAGS to "-arch ppc" if you're using an older PowerPC Macintosh.  Using the "/opt/local" build flag tells RubyGems to look in the MacPorts include directory for necessary headers (like id3.h).&lt;/p&gt;</description>
      <pubDate>Thu, 27 Mar 2008 20:26:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:6c8bcc0e-bb30-4880-b1a6-f05076095e2e</guid>
      <comments>http://tech.hickorywind.org/articles/2008/03/27/installing-id3lib-ruby-gem-on-leopard#comments</comments>
      <link>http://tech.hickorywind.org/articles/2008/03/27/installing-id3lib-ruby-gem-on-leopard</link>
    </item>
    <item>
      <title>Recurring Dates in Ruby iCalendar Using Runt, Ep. 1</title>
      <description>&lt;p&gt;What began as my "learn to write Ruby" project almost a year ago is finally taking shape thanks to &lt;a href="http://thinkrelevance.com/open-source"&gt;Open Source Fridays&lt;/a&gt; at my new place of gainful employment -- &lt;a href="http://thinkrelevance.com/"&gt;Relevance&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.ietf.org/rfc/rfc2445.txt"&gt;iCalendar&lt;/a&gt; is the open standard for those ubiquitous &lt;strong&gt;*.ics&lt;/strong&gt; files.  These are the files we read and write with &lt;a href="http://www.apple.com/ical/"&gt;Apple's iCal&lt;/a&gt;, &lt;a href="http://calendar.google.com/"&gt;Google Calendars&lt;/a&gt;, and other standards-based calendaring programs.  (Read that as "all calendars except Outlook.")  &lt;/p&gt;

&lt;p&gt;Ruby has a partial implementation of the specification at the &lt;a href="http://icalendar.rubyforge.org/"&gt;Rubyforge iCalendar&lt;/a&gt; project.  However, it's missing one important feature -- recurring dates.&lt;/p&gt;

&lt;p&gt;For example, that 1pm Monday meeting that you have every week?  The Ruby iCalendar project doesn't support it.  Now, don't give the iCalendar folks a hard time -- recurring rules are &lt;strong&gt;damn&lt;/strong&gt; hard to implement, and they've spent their time doing the most important stuff -- reading and writing the *.ics files.  Also, since most webapps nowadays just export important dates as one-off dates anyway -- the Ruby implementation of iCalendar just hasn't really needed a recurring date implementation. (But we really &lt;strong&gt;want&lt;/strong&gt; one!)&lt;/p&gt;

&lt;p&gt;I started by brute forcing my way through the massive list of examples in the &lt;a href="http://www.ietf.org/rfc/rfc2445.txt"&gt;RFC 2445&lt;/a&gt;.  I foolishly thought it was just a matter of hacking out an example using TDD and then refactoring all previous examples.  No... I've found out it's just not that simple.  (And let's face it, if that's all it took then the Ruby iCalendar folks would've added it ages ago!  Poor, naive Larry.)&lt;/p&gt;

&lt;p&gt;Then at one of the &lt;a href="http://ruby.meetup.com/3/"&gt;Raleigh.rb&lt;/a&gt; hack nights, &lt;a href="http://terralien.com/"&gt;Nathaniel Talbott&lt;/a&gt; recommended that I look at a little-known Ruby toolkit called &lt;a href="http://runt.rubyforge.org/"&gt;Runt&lt;/a&gt;.  This toolkit implements something called &lt;strong&gt;temporal expressions&lt;/strong&gt;.  You remember that weekly 1pm Monday meeting you have?  Come to find out that with Runt they look like this:&lt;/p&gt;

&lt;pre&gt;
  DIWeek.new(Mon) &amp; REDay.new(13, 00,14, 00)
&lt;/pre&gt;

&lt;p&gt;You read this as: "day in week: Monday, and range each day: from 1pm to 2pm".  You can use this &lt;strong&gt;temporal expression&lt;/strong&gt; either to generate a list of matching DateTimes or to check if a given DateTime matches.  Very powerful stuff, incredibly powerful.  (By the way, this all comes from an idea by &lt;a href="http://martinfowler.com/ap2/timeNarrative.html"&gt;Martin Fowler&lt;/a&gt; and implemented by &lt;a href="http://www.digitalclash.com/"&gt;Matthew Lipper&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;So, now my problem looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Take the iCalendar recurring rule (called a RRULE) syntax and convert it into an appropriate Runt temporal expression.&lt;/li&gt;
&lt;li&gt;Let Runt do all the work.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm home free!  Or... well, I'm not.  Come to find out, Runt only implemented about 60% of what I needed to implement the full iCalendar spec.  The biggest missing piece was the ability to handle dates at a "week precision".  That is, I need to be able to know if a given day and another given day are in the same week.  I finally got that feature in today!&lt;/p&gt;

&lt;p&gt;So now with the weekly precision and a few other temporal expressions I added, I now have all but 14 of the 41 examples working as Test::Unit tests in Runt!  That 65% may sound a little low, but it is actually something like 80% of the total iCalendar functionality.  It's definitely all the key features.  It definitely supports recurring rules based on a given day and month (mark November 15th on your calendar!  it's my birthday!), and it definitely supports week-based recurring rules like the 1pm Monday meeting above.  What else do you need?&lt;/p&gt;

&lt;p&gt;Here's the &lt;a href="/files/add_week_precision.patch"&gt;patch&lt;/a&gt; for Runt's current Subversion trunk.  I'm now working on my old iCalendar code.  I'm going to do the same trick of using the RFC examples as Test::Unit tests.&lt;/p&gt;

&lt;p&gt;I'm hoping to have more next week!&lt;/p&gt;</description>
      <pubDate>Fri, 14 Mar 2008 16:00:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:b8aa2c99-ec91-4623-9c4f-5f65a791ceb1</guid>
      <comments>http://tech.hickorywind.org/articles/2008/03/14/adding-support-for-recurring-dates-in-ruby-icalendar-using-runt#comments</comments>
      <category>ruby</category>
      <category>temporal_expressions</category>
      <category>calendar</category>
      <category>runt</category>
      <category>icalendar</category>
      <category>ical</category>
      <category>patch</category>
      <link>http://tech.hickorywind.org/articles/2008/03/14/adding-support-for-recurring-dates-in-ruby-icalendar-using-runt</link>
    </item>
    <item>
      <title>Playing MP3s with Rails! (SoundManager2 Rails Plugin)</title>
      <description>&lt;p&gt;So you want to play MP3s from your web application?  The best tool I've found for that is Scott Schill's &lt;a href="http://www.schillmania.com/projects/soundmanager2/"&gt;SoundManager2&lt;/a&gt; Javascript API.  It invisibly uses a very small Flash object to play the MP3s, and the whole thing is &lt;em&gt;very&lt;/em&gt; scriptable through Javascript.  Getting it set up is not difficult, but it's a little bit of a pain --  so I wrote a Rails plugin!&lt;/p&gt;

&lt;p&gt;Here's what you do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Install the Rails plugin like this:
&lt;code&gt;./script/plugin install http://soundmanager2.rubyforge.org/svn/soundmanager2&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Then run the generator to get the SoundManager2 files in your app:
&lt;code&gt;./script/generate sound_manager2&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You'll notice the following files are created:
&lt;code&gt;  public/soundmanager2.swf&lt;br/&gt;
public/javascripts/soundmanager2.js&lt;br/&gt;
public/javascripts/soundmanager2-jsmin.js&lt;br/&gt;
public/javascripts/soundmanager2-rails.js&lt;br/&gt;
public/images/SoundManager2/pause-control.gif&lt;br/&gt;
public/images/SoundManager2/play-control.gif&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Then, to add basic play/stop functionality to your view, add the following to your ERB file:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;pre&gt;
&lt;%= &lt;span class="method"&gt;javascript_include_tag&lt;/span&gt; &lt;span class="symbol"&gt;:defaults&lt;/span&gt; %&gt;

&lt;%= 
  &lt;span class="ident"&gt;sounds&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;
      &lt;span class="punct"&gt;["&lt;/span&gt;&lt;span class="string"&gt;sound1&lt;/span&gt;&lt;span class="punct"&gt;",&lt;/span&gt; &lt;span class="punct"&gt;"&lt;/span&gt;&lt;span class="string"&gt;http://url/to/sound1.mp3&lt;/span&gt;&lt;span class="punct"&gt;"],&lt;/span&gt;
      &lt;span class="punct"&gt;["&lt;/span&gt;&lt;span class="string"&gt;sound2&lt;/span&gt;&lt;span class="punct"&gt;",&lt;/span&gt; &lt;span class="method"&gt;url_for&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:controller&lt;/span&gt; &lt;span class="punct"&gt;=&gt;&lt;/span&gt; &lt;span class="punct"&gt;"&lt;/span&gt;&lt;span class="string"&gt;sounds&lt;/span&gt;&lt;span class="punct"&gt;",&lt;/span&gt; &lt;span class="symbol"&gt;:action&lt;/span&gt; &lt;span class="punct"&gt;=&gt;&lt;/span&gt; &lt;span class="punct"&gt;"&lt;/span&gt;&lt;span class="string"&gt;listen&lt;/span&gt;&lt;span class="punct"&gt;",&lt;/span&gt; &lt;span class="symbol"&gt;:id&lt;/span&gt; &lt;span class="punct"&gt;=&gt;&lt;/span&gt; &lt;span class="punct"&gt;"&lt;/span&gt;&lt;span class="string"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;")],&lt;/span&gt;
  &lt;span class="punct"&gt;]&lt;/span&gt;
%&gt;  

&lt;%= &lt;span class="method"&gt;initialize_sounds&lt;/span&gt;(&lt;span class="ident"&gt;sounds&lt;/span&gt;) %&gt;

&amp;lt;div&amp;gt;Play sound 1: &lt;%= &lt;span class="method"&gt;toggle_sound&lt;/span&gt; "&lt;span class="string"&gt;sound1&lt;/span&gt;" %&gt;&amp;lt;/div&amp;gt; 
&amp;lt;div&amp;gt;Play sound 2: &lt;%= &lt;span class="method"&gt;toggle_sound&lt;/span&gt; "&lt;span class="string"&gt;sound2&lt;/span&gt;" %&gt;&amp;lt;/div&amp;gt;  
&lt;/pre&gt;

&lt;ul&gt;
&lt;li&gt;Or, if you want more functionality, start calling the SoundManager2 Javascript APIs directly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here are some screenshots of this plugin in action.  Here you're looking at part of a table with MP3s ready to play...&lt;/p&gt;

&lt;p&gt;&lt;img src="http://tech.hickorywind.org/images/blog/soundmanager-waiting.png"/&gt;&lt;/p&gt;

&lt;p&gt;And then here you've clicked on the middle song.  Note the MP3 will start playing immediately, even while it's downloading!&lt;/p&gt;

&lt;p&gt;&lt;img src="http://tech.hickorywind.org/images/blog/soundmanager-playing.png"/&gt;&lt;/p&gt;

&lt;p&gt;Clicking the "pause" button will stop the playback.&lt;/p&gt;

&lt;p&gt;Here are the project links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://soundmanager2.rubyforge.org/"&gt;SoundManager2 Rails Plugin Home Page (RDoc)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://rubyforge.org/projects/soundmanager2"&gt;RubyForge Project Page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.schillmania.com/projects/soundmanager2/"&gt;SoundManager2 Javascript API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Oh, and by the way, both the Javascript API and Rails plugins are released with BSD/MIT licenses!&lt;/p&gt;

&lt;p&gt;I'm definitely wanting to put more "off-the-shelf" behavior in this plugin, but for now the simple play/stop behavior is all my application needs.  If you need something else, or want to send me some patches, please shoot me an email!&lt;/p&gt;</description>
      <pubDate>Fri, 07 Mar 2008 09:55:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:2275d9d6-8795-4f33-90e8-a58116e6d358</guid>
      <comments>http://tech.hickorywind.org/articles/2008/03/07/soundmanager2-rails-plugin#comments</comments>
      <category>mp3</category>
      <category>soundmanager2</category>
      <category>ruby</category>
      <category>rails</category>
      <category>plugin</category>
      <category>rubyforge</category>
      <link>http://tech.hickorywind.org/articles/2008/03/07/soundmanager2-rails-plugin</link>
    </item>
    <item>
      <title>Way Past Due, But Better Late Than Never</title>
      <description>&lt;p&gt;My name is Larry Karnowski, and I've been blogging about twangy and traditional music over at &lt;a href="http://www.hickorywind.org/"&gt;Hickory Wind&lt;/a&gt; for over five years now.  Hickory Wind has been a great outlet for my musical passion, and I've met some of my best friends through that site.   (You can also indirectly trace my meeting of my fiancé-soon-wife through that site too, so it's been a great experience!)  However, Hickory Wind has a music audience, not a technical one.  I've never been able to wax geek over there, talking about how tired I was of Java, how cool Ruby and Rails are, etc.  &lt;/p&gt;

&lt;p&gt;Now I'm making a change in my career.  Instead of being at a product-based company like I have for the past eight years, I'm starting at a contract-based custom software company called &lt;a href="http://www.thinkrelevance.com"&gt;Relevance&lt;/a&gt; next Monday.  I'm crazy excited about it, and I can't wait to immerse myself into their geeky, open-source-heavy culture!  &lt;/p&gt;

&lt;p&gt;As part of this change in my career, job, and geeky culture, I've decided it's definitely time to launch this geeky blog to service my other passion -- technology.  Here I'll talk about software development, user interface design, and other geeky tangents like Tolkien books, World of Warcraft, and an occasional D&amp;amp;D analogy.&lt;/p&gt;

&lt;p&gt;Hickory Wind will be my manic music side, and Hickory Tech will be my manic geek side.  (Here's a tip -- I'm all Hulk and no Bruce Banner, baby.)&lt;/p&gt;

&lt;p&gt;So, if you're interested in talking Typo versus Mephisto, MovableType versus WordPress, Rails versus Spring, anything versus Java, Rogues vs Bards, and phat l00tz versus role-playing, well then you're probably at the right place. &lt;/p&gt;

&lt;p&gt;Welcome!&lt;/p&gt;</description>
      <pubDate>Mon, 03 Mar 2008 11:45:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:8b807821-daef-49f7-8982-de8be65d8df3</guid>
      <comments>http://tech.hickorywind.org/articles/2008/03/03/way-past-due-but-better-late-than-never#comments</comments>
      <category>blog</category>
      <category>technology</category>
      <category>geek</category>
      <link>http://tech.hickorywind.org/articles/2008/03/03/way-past-due-but-better-late-than-never</link>
    </item>
  </channel>
</rss>
