Gotta love *those* recruiters

Posted almost 7 years back at work.rowanhick.com

From a blanket spam email I (and probably a good portion of the rails community just received) "I have a direct client who is seeking a strong Programmer who posses experience with Rudy on Rails. If you are qualified and interested, please send me your most current resume in a word.doc format to.." Yes, Rudy was actually put in bold, just to place even more emphasis on the spelling error.

Blog Updates

Posted almost 7 years back at zerosum dirt(nap) - Home

So I finally got around to migrating the blog site over to Mephisto. I’ve only been planning on doing that for like 9 months. Horray for progress!

Links For 10.30.07

Posted almost 7 years back at zerosum dirt(nap) - Home

Not-so-random things you need to know about:

Startupping Contests

Posted almost 7 years back at zerosum dirt(nap) - Home

So Ty and I submitted our startup project’s pitch to the Amazon Startup Challenge last night. Wish us luck!

The idea (currently implemented as a working prototype, albeit with a number of rough edges) has to do with micropatronage, a concept that is near and dear to my heart. In a nutshell we believe that content authors should be rewarded for their efforts, and we think we’re on to a way to make that fun and rewarding for patrons too.

It’s something we’ve been developing on and off for months now, in between various other client gigs and open source initiatives. We have no illusions about being chosen (although it sure would be nice if we were!), but if nothing else the contest has given us the kick in the butt that we needed to get back on track with it and formalize a number of principles in writing. Writing things down, and trying to explain them to people whom you’ve never met before, always helps to clarify your vision. It’s quite amazing, really.

Anyway, I love seeing contests like this, even when I don’t win (which is most of the time). I thoroughly enjoyed my role as an organizer of the Rails Rumble event we ran in September, and I look forward to similarly-minded events like the upcoming BlitzWeekend (hi Heri!), and even the more VC-involved “contests” like Seedcamp and of course Y Combinator.

I particularly enjoy following startup contests and events where creativity is a key factor; where instead of just implementing a common spec to see who can do it fastest or “best”, teams are actually challenged to invent something totally new, implement it, throw it against a wall and see if it sticks. Hey, now that’s entrepreneurial; it’s brave, it’s somewhat reckless (in it’s purest form, anyway), and it’s a great way to hatch new disruptive ideas in front of a live audience.

Some of the projects will be great, most of them will suck, but everyone will learn something. It’s important to remember, too, that the “winning” team won’t necessarily be the long term winner — it’s a distance running event, not a short sprint. In the end, it’s all about development — and I mean that in the personal growth sense, not in the geeks-behind-glass sense.

Of course, you don’t need a contest or money or really anything at all to go invent something new, especially these days when launching a company doesn’t cost anything more than the skills, free time, and a VPS. But sometimes a little extra motivation goes a long way.

Some thoughts on Leopard

Posted almost 7 years back at Luke Redpath - Home

In case you missed the memo, Apple unleashed Leopard on Friday. I headed down to the Regent Street Apple Store to see if I could snag a copy; unfortunately, by 6pm the queue had reached epic proportions (at least a 45 minute wait) and I promptly left and instead chose to pick up a copy from Brent Cross on Saturday (I feel sorry for anybody who did bother queueing all evening – the Brent Cross store was no more busy than usual come Saturday afternoon).

Rather than spending time discussing Leopard’s much discussed new major features, I thought it would be interesting to point out some of the smaller, minor but useful updates that I have picked up on so far. I will update this list over the next week or two as I discover new things, good and bad:

  • Installation didn’t go too smoothly for me; there appears to be a bug in the install process affecting some machines that means that my hard drive wasn’t showing up in the “Select a destination” panel. Fortunately I was able to find out from the Apple discussion forums that after waiting 10 to 15 minutes your available drives will appear. One cup of tea later, and the install routine was back on track. I opted to perform an “Erase and Install” on my MacBook Pro to get rid of the sheer amount of crap that I had accumulated over the last 18 months which went as smoothly as I’d expected. I am yet to try the upgrade option on my Mac Mini so YMMV here.
  • My first impressions were that Leopard seemed faster and given that it was probably hard at work indexing my hard drive for Spotlight this was pretty impressive. My Airport problems in Tiger (the connection would frequently just stop responding or lose packets making it incredibly frustrating to do anything useful) appear to be resolved, at least, when running on mains power. When running on battery I still seem to be suffering from random disconnections although Leopard at least shows that it has lost its connection and reconnects pretty fast. This may be a problem with my router and still requires further investigation on my part.
  • The new dock is not as bad as everybody has made out and I have left it at the bottom for now even though I’m traditionally a dock-on-the-side person. The new Stacks functionality is useful and looks great although the cool “fan” effect only works when the dock is on the bottom. I imagine the novelty will wear off quite quickly and I will be back to having my dock on the side soon enough.
  • I’m sure that most Rails developers have been aware for a while now that Leopard will ship with Rails. The new Ruby/Rails stack in Leopard is well thought out and organised and comes with Ruby 1.8.6, Rails 1.2.3 and and a host of other useful gems. Rails itself is simply bundled as a gem and is easily updated. A good overview of the changes to Ruby in Leopard is available.
  • One utility that anybody who frequently uses SSH and public/private keys would not be without is SSHKeychain which integrates with Apple Keychain and acts as an SSH agent. In my experience SSHKeychain could be flaky and would sometimes silently crash for no apparent reason; good news then because as of Leopard, OSX maintains its own Keychain-integrated ssh-agent making passphrase-protected keys painless to use out of the box.
  • Speaking of which, the new Leopard Terminal finally supports tabs and is much easier to customize thanks to built-in themes. Despite some niggles (like not being able to jump to a specific tab using Cmd+number) I think that it is finally time to say goodbye to iTerm.
  • Connecting to your mail server over SSL using a self-signed certificate in Mail.app is no longer a pain in the arse. Before, Mail would prompt you that the server certificate was not from a trusted source every time you tried to connect unless you manually dragged the certificate to the desktop and added it to your keychain. In Leopard, Mail finally has an option to “always trust this certificate” as well as a number of other fine-grained trust options.
  • The new version of Front Row, based on the Apple TV software, seems like a regression to me. The new interface doesn’t seem as slick and suffers from some annoying bugs like not being able to view album artwork on a shared library and most annoying of all: there doesn’t seem to be any way to get Front Row to open on a second monitor. In Tiger, Front Row would always open on the primary display – this was documented behavior and in Leopard this behavior seems to have disappeared. I like to hook my MBP up to my plasma TV but now Front Row will only open on my MBP screen, even if its not the primary display, severely limiting its usefulness.
  • On the plus-side, Quicktime now has some useful full-screen options including options to stretch or fill a widescreen display when viewing videos in a 4:3 aspect ratio. Quicktime does work on a second display and allows you to select which screen it will display on in full-screen mode independently of your primary display settings.

Update 1: Airport Woes

When running in battery mode, Airport performance is horrendous, even after installing the latest keychain fix. The signal will go up and down and the transmit rate will jump up and down wildly between 0 and 54 before eventually just disconnecting – it seems to disconnect every couple of minutes.

The question is, is this a) a continuation of the connection stability problems I was having in Tiger but manifesting itself with different symptoms (or simply that Leopard is more responsive to Airport connection status changes than Tiger), b) an entirely new problem created by the latest Airport drivers, c) a hardware issue (dodgy Airport cards?) or d) a problem with my router.

Until I can test out Airport performance on my Mac Mini in Leopard, I can’t rule out D although the fact that many other people are having the same problem seems to suggests this is not the case. Airport performance seems reliable when connected to the mains, so maybe its an issue of power consumption by the Airport card?

Something else that I just noticed: there appears to be a rather nasty looking, if ultimately harmless, rendering bug when scrolling in Finder when in column mode:

More Airport updates

I’m beginning to become more and more convinced that the problem with Airport is a power issue. My Airport connection seems to be very stable with no disconnections when running on mains power but in battery mode the disconnections come very frequently. I’ve also managed to perform the following test with reliable results: plug in the power adapter and wait a few minutes to confirm a stable Airport connection. Now remove the power adapter – in my observations, about 80% of the time the Airport connection will drop within 10 seconds. This would indicate to me that the problem lies in the Airport card not being able to draw enough power to operate in a stable manner whilst running in battery mode.

Yet another update

I mentioned earlier that I was having trouble getting Front Row to display on my TV even though it was set as the primary monitor. Last night I gave it another try and et voila; Front Row was displaying on my TV. Further investigation led me to this post on the Apple discussion forums:

“Not sure if this is related to the bugs you are having, but one I’ve noticed and reported to apple is this: When you first start front row it appears on your primary display, it also remembers which display it first started on. So, if you exit but don’t kill the front row process (in activity manager), front row will always display on that initial primary monitor, even if you swap your primary/secondary in sys pref. I haven’t tried mirroring the displays. " cmendill, Apple Discussion Board

I haven’t had the change to verify this (yet) but it makes sense – if exiting Front Row doesn’t actually kill the process, then Front Row will not pick up changes to your primary display settings until you do. I still consider this to be a bug but at least it’s an explanation!

Leopard reviews:

Episode 77: Destroy Without JavaScript

Posted almost 7 years back at Railscasts

If the user has JavaScript disabled, the "Destroy" link might not work properly. In this episode I will explore a number of ways to work around this issue.

YouCast: White-label video sharing site

Posted almost 7 years back at Shane's Brain Extension

YouCast? is a Ruby on Rails video sharing application that you host on your own servers. It can be rebranded easily for your company or used as is.

Main features:

  • Upload videos, images, and music via web or mobile phone via SMS/MMS attachment
  • Create a playlist of your videos, images, and music
  • Play your media in a Flash player
  • Get the code for the player to embed in any site (myspace, blog, etc)
  • Generates thumbnails for videos
  • Multi-user support with user login and user management
  • Export your playlist in XSPF/Spiff format

Tech specs:

  • Ruby on Rails application designed with RESTful methodology
  • Supports all major video and image formats, and mp3 for music
  • Encodes all video to Flash
  • Uses MMS2R for mobile media processing
  • XSPF/Spiff format used for playlists for maximum portability

What you get:

  • Full source code
  • 10 hours of free consulting, including help with installation and migration
  • Option to hire me for additional consulting

What can you do with YouCast??

  • Create an internal video sharing site for your company or small business
  • Use it as a base for your own video-related site
  • Merge it with your existing site to add video and mobile media support
  • Re-create YouTube to impress your friends

How much does it cost?

  • YouCast? will cost a yet-to-be-determined one-time fee, which includes free updates to that version. I will determine the cost once I get a better idea of demand.

Email me at the address in the About Me page if you are interested in seeing a demo and/or purchase.

YouCast: White-label video sharing site

Posted almost 7 years back at Shane's Brain Extension

YouCast? is a Ruby on Rails video sharing application that you host on your own servers. It can be rebranded easily for your company or used as is.

Main features:

  • Upload videos, images, and music via web or mobile phone via SMS/MMS attachment
  • Create a playlist of your videos, images, and music
  • Play your media in a Flash player
  • Get the code for the player to embed in any site (myspace, blog, etc)
  • Generates thumbnails for videos
  • Multi-user support with user login and user management
  • Export your playlist in XSPF/Spiff format

Tech specs:

  • Ruby on Rails application designed with RESTful methodology
  • Supports all major video and image formats, and mp3 for music
  • Encodes all video to Flash
  • Uses MMS2R for mobile media processing
  • XSPF/Spiff format used for playlists for maximum portability

What you get:

  • Full source code
  • 10 hours of free consulting, including help with installation and migration
  • Option to hire me for additional consulting

What can you do with YouCast??

  • Create an internal video sharing site for your company or small business
  • Use it as a base for your own video-related site
  • Merge it with your existing site to add video and mobile media support
  • Re-create YouTube to impress your friends

How much does it cost?

  • YouCast? will cost a yet-to-be-determined one-time fee, which includes free updates to that version. I will determine the cost once I get a better idea of demand.

Email me at the address in the About Me page if you are interested in seeing a demo and/or purchase.

Rob McKinnon: TheyWorkForYou.co.nz - Ruby on Rails Podcast

Posted almost 7 years back at Ruby on Rails Podcast

A London-based developer talks about keeping government accountable in New Zealand and around the world.
Also mentioned:

wrapping processes in IO.popen and festivaltts4r

Posted almost 7 years back at Mike Mondragon

There is a cool gem called Festival TTS for Ruby . What it does is take text, pass it into the The Festival Speech Synthesis System , then transform the WAV from Festival into an MP3. festivaltts4r provides a programming interface to use its functionality in an application. The project includes a Flash media player so that you can use festivaltts4r easily in a Rails application. Listen to their example Rails application. To use the Flash player you need to check out the project as a plugin to your Rails app like so:

wrapping processes in IO.popen and festivaltts4r

Posted almost 7 years back at Mike Mondragon

There is a cool gem called Festival TTS for Ruby . What it does is take text, pass it into the The Festival Speech Synthesis System , then transform the WAV from Festival into an MP3. festivaltts4r provides a programming interface to use its functionality in an application. The project includes a Flash media player so that you can use festivaltts4r easily in a Rails application. Listen to their example Rails application. To use the Flash player you need to check out the project as a plugin to your Rails app like so:

ruby script/plugin install svn+ssh://rubyforge.org/var/svn/festivaltts4r/plugins/festivaltts_on_rails

festival4r.rb adds #to_speech and #to_mp3 methods to String and each make a simple call to Kernel#system to execute their programs. That is a quick and easy approach as #system returns false on failure, true on success, and the exit status of the process in $?

However, many processes output text as the they are being executed such as status or error messages. Before I came across festivaltts4r I had actually written my own kind of festivaltts4r for a Rails project. My approach is to capture all of the output of the process and if there is an error returned from the process use the output as the message for an Exception. The process is executed by IO.popen which also captures the text of the process. Process.wait is then called to ensure to wait for the process to finish (beware of hung processes!). Eric Hodel suggested the use of IO.popen in this manner.

Here is the model I used for my implementation of festivaltts4r. The model uses Single Table Inheritance, look at the schema annotation for clues about the overall strategy/pattern of my MediaTransform model. Also note that MediaTransformError is just a custom Exception my application raises and catches as a part of its behavior for transforming text to mp3. btw LAME is used to encode the WAV from Festival to MP3

# == Schema Information
# Schema version: 12
#
# Table name: media_transforms
#
#  id                :integer(11)   not null, primary key
#  type              :string(255)   
#  media_bot_id      :integer(11)   
#  text2wave_program :string(255)   default("/usr/bin/text2wave -scale 7 -o \"OUTWAV\" \"INTEXT\" 2>&1")
#  wav2mp3_program   :string(255)   default("/usr/bin/lame -h \"INWAV\" \"OUTMP3\" 2>&1")
#  watermark         :string(255)   
#  watermark_program :string(255)   default("/usr/bin/composite -gravity southeast -watermark 25 \"WMIMAGE\" \"INIMAGE\" \"OUTIMAGE\" 2>&1")
#  created_at        :datetime      
#  updated_at        :datetime      
#

class RobotTransform < MediaTransform

  def self.transform_mime_type
    'text/plain'
  end

  def transform(text)

    # get a unique temp dir to output text2wav to
    tmp_dir = Media.create_tmp_dir(text.id)

    # set up names and paths for processing
    name = File.basename(text.filename)
    wav_file = File.expand_path(File.join(tmp_dir, name.sub(/\.[^.]+$/, ".wav")))
    mp3_file = File.expand_path(File.join(tmp_dir, name.sub(/\.[^.]+$/, ".mp3")))

    # run the text2wave program
    program = text2wave_program.gsub('INTEXT', text.full_filename)
    program.gsub!('OUTWAV', wav_file)
    begin
      out = IO.popen("#{program}")
      Process.wait
      e = $?.exitstatus
    rescue StandardError => err
      raise MediaTransformError.new(err)
    else
      raise MediaTransformError.new("0 not returned:\n#{program}\n#{out.readlines}"
        ) unless e.eql?(0)
    end

    # run the wav2mp3 program
    program = wav2mp3_program.gsub('INWAV', wav_file)
    program.gsub!('OUTMP3', mp3_file)
    begin
      out = IO.popen("#{program}")
      Process.wait
      e = $?.exitstatus
    rescue StandardError => err
      raise MediaTransformError.new(err)
    else
      raise MediaTransformError.new("0 not returned:\n#{program}\n#{out.readlines}"
        ) unless e.eql?(0)
    end

    fu = FuFile.new('audio/mpeg', mp3_file)
    mp3 = FileSystemMedia.new
    mp3.uploaded_data = fu
    mp3.save!

    FileUtils.rm_rf(tmp_dir)
    mp3
  end
end

JQueryCamp Is Tomorrow!

Posted almost 7 years back at zerosum dirt(nap) - Home

For anyone who’s registered (and presumably in or around the greater Boston area), don’t forget that JQueryCamp is tomorrow! I’ll be there, and looking forward to talks by John Resig, Yehuda Katz (whom I probably owe a beer), and many others.

Cookie Session Store for Facebook Applications

Posted almost 7 years back at Darwinweb

I was recently recruited to build a “facebook”:http://facebook.com application on top of an existing Rails codebase running on edge. Having been on edge with my previous project for at least 6 months, I’ve gotten used to all the Rails 2.0 goodness.

One of my favorite features is the “cookie session store”:http://ryandaigle.com/articles/2007/2/21/what-s… which is a huge slam dunk for scalability and general maintainenance—that is to say, no maintenance.

Unfortunately facebook does not store cookies (as far as I can tell), and there is really no documentation of this to speak of out there on the web. If you are using the cookie session store, nothing blows up, you just don’t have a session. It’s pretty obvious when you think about it, but I spent a couple hours figuring out why my flash messages weren’t coming through. If this post saves one person 20 minutes, then it was time well spent.

Cookie Session Store for Facebook Applications

Posted almost 7 years back at Darwinweb

I was recently recruited to build a facebook application on top of an existing Rails codebase running on edge. Having been on edge with my previous project for at least 6 months, I’ve gotten used to all the Rails 2.0 goodness.

One of my favorite features is the cookie session store which is a huge slam dunk for scalability and general maintainenance—that is to say, no maintenance.

Unfortunately facebook does not store cookies (as far as I can tell), and there is really no documentation of this to speak of out there on the web. If you are using the cookie session store, nothing blows up, you just don’t have a session. It’s pretty obvious when you think about it, but I spent a couple hours figuring out why my flash messages weren’t coming through. If this post saves one person 20 minutes, then it was time well spent.

Revisiting date localization for Ruby 1.8.6

Posted almost 7 years back at poocs.net - Home

Welcome to my yearly post about a revised version of a simple way to localize Ruby’s Time#strftime method (after my original post in ‘05 and the update in ‘06).

What’s changed?

In my original methodology, the arrays in the Date class containing the actual day and month names in clear text had to be replaced by strings wrapped in the infamous _() call of GetText in order to spit out their localized versions when requested from the modified Time#strftime call.

When Ruby 1.8.6 came along, it had its Date array constants frozen. While I agree it’s generally not a good idea to modify the contents of a constant (it’s a constant after all, mind you), the implementation I came up with 2 years ago worked fine up to and including today.

Since, also, most of the sites I’m working on require multiple languages (as opposed to, say, a single language set at application boot time), the contents of those Date arrays truly need to be modified at runtime and having those arrays frozen meant jumping through all sorts of hoops to address a supposedly simple issue.

What now?

Well, I had to come up with a way to actually execute the gettext functionality in the context of an object that has the current GetText locale bound to it. The most obvious object with that kind of property is ApplicationController.

But this still leaves us with the issue that we cannot modify the frozen Date constants and that everything we put into these constants is evaluated right away instead of at a point where we have the desired locale set.

What I came up with was a proxy object derived from the Array class that would basically just wrap the cleartext contents that are already in each of the Date arrays but not before they’re actually accessed/output.


    # lib/date_localization.rb
    class GetTextDateProxy < Array

      cattr_accessor :gettext_proxy

      def [](key)
        _(at(key))
      end

      def _(string)
        return string unless gettext_proxy
        gettext_proxy.instance_eval { gettext(string) }
      end

    end

As you can see, the proxy object is pretty simple after all. It just overwrites the default of Array#[] to look up the requested key and then wrap the output in _().

Since I couldn’t actually be bothered to include the whole of Ruby-GetText into my poor little proxy object, I then made room for it to hold a pointer to an instance of ApplicationController in a class attribute called gettext_proxy. The local underscore method of my proxy class then wraps around the actual gettext implementation available to the gettext proxy (read: ApplicationController), returning the string unchanged if there is no gettext proxy and if there is, run the string through the proxy’s gettext method.

Dealing with a state of not having a gettext proxy available is actually necessary in cases where there are calls to these arrays before ApplicationController gets to hook itself up to GetTextDateProxy.

But how does this actually hook into the Date class now? Let’s take a look:


    # lib/date_localization.rb
    class Date

      silence_warnings do
        %w(
          MONTHNAMES DAYNAMES ABBR_MONTHNAMES ABBR_DAYNAMES
        ).each do |array|
          class_eval %( #{array} = GetTextDateProxy.new(#{array}) )
        end
      end

    end

While this still looks a little tedious, it’s far less tedious than repeating the arrays’ contents simply wrapped in _() all over the place, like we had to do in previous incarnations of this methodology.

Basically, now every array is hooked up with their very own instance of GetTextDateProxy which then takes care of running the strings through gettext in the appropriate moments.

Wiring it all up

For the last part, we need to get ApplicationController to hook itself into GetTextDateProxy after having received the appropriate locale for the request it’s dealing with.

The best fit for this is the after_init_gettext hook provided by Ruby-GetText. Adding this code to ApplicationController will take care of the last required step.


    # app/controllers/application.rb
    after_init_gettext { GetTextDateProxy.gettext_proxy = self }    

Here you go, working (albeit hackish) localization for Ruby’s Time#strftime working up to and including the most recent version of Ruby, which is 1.8.6 as of this writing.

Enjoy.