James Brooks

Now with pants included

Rails Currency Conversion Plugin - Cash handler

Looking at the state and how the current currency conversion gems and plugins for Rails work, I decided to roll my own very small and niche solution to currency conversion, named Cash Handler. The core functionality it provides is to convert a value from one currency to another (there are only 23 currencies listed, values are updated from scrapped data from x-rates.com). The  plugin also incorporates a simple time-expiry cache for exchanges rates.

Here’s an example of Cash Handler in operation:

c = CashHandler::Base.new

# Get the current exchange rate of the AUD against the USD (currency code strings are case in-sensitive, can also be symbols)
c.get('AUD')
=> 0.619099

# Get the current exchange rate of the AUD against the GBP
c.get('AUD', :against => 'GBP')
=> 0.418621272567449

# Convert
c.convert(10, :aud, :usd)
=> 6.19099

# Force the converstion rates cache to reload currencies
c.cache.expire

# The CashHandler::Cache has a default cache life of one day, this can be overridden in one of two ways
# Upon creation
c = CashHandler::Base.new(30.minutes)

# During operation
c.cache.ttl = 30.minutes

Play simultaneous sounds using AVAudioPlayer

I’ve recently been playing around with the new AVFoundation stuff for the iPhone, esp. AVAudioPlayer (to be fair it’s the only thing in AVFoundation at the current time :P). Using the AVAudioPlayer stuff is pretty nice (the code here shows how easy it is to get it up and running).

I ran into a problem quickly playing sounds at the same time (simultaneously) using AVAudioPlayer. The idiom for doing this is to create a new AVAudioPlayer instance for each individual sounds you’ll be using, preload the sound using prepareToPlay and call play whenever you want to play the sound, it’s that easy!.. or it should be. I spend a day trying to debug why I was un-able to play simultaneous sounds (prepareToPlay also caused a problem too, even though I wasn’t playing anything).

My problem was that my sounds were MP3 formatted sounds, and after a bit of digging it appears the core audio stuff doesn’t allow simultaneous MP3 playback. The best way I found to get around this was to convert the MP3 files to the Core Audio Format (IMA4 worked good for me, and only ended up being slightly larger then the original MP3), which can be done as follows (using afconvert, built into Leopard afaik):

/usr/bin/afconvert -f caff -d ima4 sound.mp3 sound.caf

And that’s it, you should now be able to play multiple sounds at the same time.

Countries, States and Cities for MySQL

Looking around the internet, I couldn’t find any good (free) database dumps for MySQL of all global cities by states by countries for MySQL. I’ve put my own together using free data from MaxMind. This database doesn’t have a lot of excess data (read: it fits the purpose that I was after, and that’s purely finding names by state/country).

The database contains three tables: countries (id, name, code), states (id, country_id, name, code) and cities (id, state_id, name, code). The database is using MaxMind’s city data of cities with a population of 15,000 of greater (they have data sets for cities of 1,000/5,000 or greater as well). I didn’t require that intense fidelity for this database.

Download the database (188kb, sql.bz2)

If anyone spots any obvious problems, please let me know. Also, if anyone is interested in the SQL and files used to construct this database I can clean them up and make them also available (the SQL file used to build the database works directly with the raw data files from MaxMind, so updating should be easy enough).

Zebra stripe tables using jQuery

I’ve just noticed that the way I was zebra striping tables in jQuery didn’t handle multiple tables on the same page correctly (for an odd number of rows). Here’s the previous (problematic) snippet:

$(document).ready(function() {
  $('table tbody tr:odd').addClass('odd');
});

The issue was that the use of the jQuery :odd nthChild selector would carry over to multiple tables (they wouldn’t all be striped the same way). This should had been obvious but obviously not until I saw the result rendered, here’s the corrected snippet:

$(document).ready(function() {
  $('table').each(function() { $(this).find('tbody tr:odd').addClass('odd') });
});

Update:
Here’s an improved snippet (thanks to a suggestion from Karl Swedberg).

$(document).ready(function() {
  $('table tbody tr:nth-child(even)').addClass('odd');
});

Make DOM elements hoverable using jQuery

following up the post from earlier today, Make DOM elements hoverable using Prototype, here’s the equivalent javascript code using jQuery instead of Prototype (Uses the same example as in the previous post [a list]).

$(document).ready(function() {
  $('.hoverable > *')
    .mouseover(function() { $(this).addClass('hover') })
    .mouseout(function() { $(this).removeClass('hover') })
});

Make DOM elements hoverable using Prototype

Here’s a small snippet I use when I want to change style based off of the :hover state of the element. Usually we could just use the :hover pseudo-class (apart from the fact that IE6 will only acknowledge :hover on link tags only). The solution is to use some javascript to add/remove a .hover class on the elements we want to hover over (I mostly use this for lists).

Event.observe(window, 'load', function() {
  $$('.hoverable > *').each(function (e) {
    Event.observe(e, 'mouseover', function() {
      Element.addClassName(e, 'hover');
    });  

    Event.observe(e, 'mouseout', function() {
      Element.removeClassName(e, 'hover');
    });
  });
});

To use the above script, you need to mark any parent elements as .hoverable to have any of it’s direct children gain and lose .hover on :hover, such as the follow:

<ul id="menu" class="hoverable">
  <li><a href="#">First Item</a></li>
  <li><a href="#">Second Item</a></li>
  <li><a href="#">Last Item</a></li>
</ul>

This is also easily written using jQuery, though as I mostly deal with Rails applications without an explicit need to use jQuery, this is the Prototype version I use. A jQuery version of this snippet can be found in the post, Make DOM elements hoverable using jQuery.

Slug generation in rails

Just recently I made a very minor update to my slugify method I use in rails (which I add to String via a monkey-patch).

It’s pretty much like your stock-standard slugification method, this one produces a URL-friendly slug containing only letters and numbers, dashes seperate elements in the string and a few other nice things (single quotation marks are just stripped and not made spaces, and ‘&’ is replaced with ‘and’).

class String
  def slugify
    self.downcase.gsub(/&/, ' and ').gsub(/[^a-z0-9']+/, '-').gsub(/^-|-$|'/, '')
  end
end

Hush CMS

Today I began development on a in-house content management system (dubbed Hush CMS), a Ruby on Rails plugin to extend a rails application with CMS functionality (both static [pages] and dynamic [news, blog posts]) as unobtrusively as possible to the application.

So far I’ve got a GitHub Repository setup with some initial code in. At the moment Hush can generate migrations for it’s required entities, and hook into ApplicationController to handle and serve out pages from the database, as well as a custom method for use in config/routes.rb to designate what routes the CMS pages should respond to.

I won’t bother writing up a how-to to get it going for now, bare instructions are in the README. The only thing missing in the repository to view a page is the page view itself, which by default should be a template in global/page. The content of my global/page currently looks like this (html.erb)

<%= hush_cms_breadcrumbs @hush_cms_page %>

<h2><%= @hush_cms_page.title %></h2>
<p><%= @hush_cms_page.content %></p>

My git workflow

Recently I’ve been trying to get my head around git, I think my head has been tainted by excess subversion usage. Thanks to the help of close friend Joel Stanley I’ve got to the stage where I’m fairly happy with how I can use git to accommodate my workflow with multiple developers.

The following workflow is what I use at work when working on projects with frequent pushes by multiple developers. Perform all work on local branches, and then when ready to push we push (I now tend to have a branch for random working called ‘working’ and specific feature branches called whatever).

# switch to working branch
git checkout working

# hack hack hack then git add, etc
git commit -m"awesome change"
# hack hack hack then git add, etc
git commit -m"another awesome change"

# when I want to push these changes to the upstream master:
# first pull the latest master from upstream
git checkout master
git pull

# rebase those changes into my branch (put my commits on-top of the master's commits)
git checkout working
git rebase master

# after any conflicts are resolved, merge my working branch into master
git checkout master
git merge working

# push the changes upstream
git push

This workflow is similar for feature branches as well (working is essentually my feature branch for misc work, quick fixes, whatever). With this workflow I can easily change back to the master branch and pull the latest upstream changes in without impacting anything I’m currently working on (which is handy), as well as rebase as often as I want to (less conflcits to resolve, the better!).

Please let me know of any improvements or things I should watch out for, thanks!

Getting around to it

Writing on a blog was always going to be one of those things I was going to get around to it, but I never did because I didn’t think I found anything that warrented a decent sized post. I think I’m going to have to bite the bullet and just post the damn things without concern to post length or over-all ‘academic’ quality.

So here’s the first post, to say I’m going to do just that ;).