Per Project RVM Selection

I work on Rails as a contractor as well as my own projects.  My main contract uses rails 2.x and ruby ree 1.8.7.  Naturally, I like to use the bleeding edge on my own projects.  This causes me problems going back and forth.  I found that you can create an .rvmrc file that will set the environment for you when you run ruby in that directory.

You just put the same command you would normally type at the prompt to switch RVM environments in the .rvmrc file and it works!

echo "rvm ree@global" > .rvmrc

This will enable you to simply change directories and not have to think about which version of ruby and gemset you are using. cd into that directory, type ruby –version to verify it loading the right ruby version.

Rails Rumble 2010

Wow, that was incredible fun.  Andrew Kavanaugh and I holed up in a Vegas hotel for the entire weekend to crank out a Rails application www.transcriptify.com for Rails Rumble. We were http://railsrumble.com/teams/double-down. We were so busy, we still haven’t put one penny in a slot machine yet.  This was also my very first rails application.  We created an application where you will be able to upload a podcast, video, or whatever and get a transcript back.  The user pastes the youtube URL or uploads a video and then we create a bunch of “HIT”s on Amazon’s Mechanical Turk system.  A HIT is a Human Intelligence Task where people log into amazon and fulfill these tasks and get paid.  We break up a 30min video into 60 chunks and have several people per 30 second clip transcribe it.  We then create other HITs to review the transcriptions.  Once all 60 chunks of video/audio have been transcribed and reviewed, we assemble them all into one big transcript that can be downloaded to your website .

We were literally down to the last minute trying to get paypal to work and therefore didn’t have much testing.  I hope it works ;)  Due to time constraints, we have only implemented youtube so far.  there are so many things that would need to be done in order to make this an app I’m proud to charge for, but overall I’m quite proud of what we accomplished in 48 hours.  We overcame a crippled laptop that had to be exchanged at the Apple Store only to find out that it is a software problem because my new one has the same issue.  I had to operate in safe mode the whole weekend which meant no audio.  That made it really hard to create a service based on transcribing audio.  We had one team member who was unable to devote the time we had hoped for the contest which was also a disappointment.

Only got a few hours of sleep over the last 48 hours, havent eaten all day, but it was an awesome experience with a fellow coder and friend who also loves to code just for the enjoyment of it.  It was an experience I would recommend and hope to repeat next year.

blenderfarmers.com

My brother Doug went to Full Sail film school and has recently gotten me into the hobby of making shorts in our fun time (www.simplemindedstudios.com).  Currently, we are making a short using my children as the actors.  We don’t have access to very many interesting places to film so we decided to create most of the sets in the computer.   He likes to experiment mixing 3d graphics in live action movies.  We are really at the beginner stage of learning how to make it look good.  If it weren’t my own children starring in the movie, I might even think they look laughably bad.  Not only is it challenging to make it look good artistically, it is challenging on the technical side as well.

The reason it is challenging on the technical side is that it takes a LOT of computer horse power to render usable video footage for any sizable project.  Due to the work-flow, you sometimes have to render a scene several times to get it right.  Just last night, we finally got to take a look at a render and we noticed a flickering problem in our render.  When you render a single frame, you don’t notice because each individual frame looks “correct”.  It isn’t until you string all the frames together to make a video that you can notice the subtle changes in the intensities of the light.  Also, when you are animating characters, you can’t really know what they look like until you do the render because the preview capability isn’t smooth.

Let me try and explain the magnitude of the problem that I am trying to solve.  For every second of a movie, there are 24 frames.  So, for a 15 minute movie, we will need to do a final render on 21,600 frames.  Let’s assume that it takes us 5 attempts at rendering to get a scene right.  that brings the number of frames we need to render to 108,000 frames.  Now, on my brother’s dual core iMac, it takes about 10 minutes to render a single frame.  If we were to render this entire movie on his computer, it would take 1,080,000 minutes to render.  That is 750 days 24/7, non-stop, rendering.  This is where the interesting challenge comes in.

The solution is to get a LOT of CPUs attacking the problem.  You can solve it by buying bigger beefier machines.  I purchased a new iMac i7 with true quad core processing that shows the OS that it has 8 CPUs.  The new machine enables us to render a frame 4 times faster.  I also built a PC with similar specs so we can have two machines rendering frames 24/7.  So just buying a much faster machine brought the time required for our movie down to three months.  This is good, but not good enough.  That’s where a render farm comes in.

A render farm is simply a lot of computers working together on a single movie sequence or even a single image.  There is typically a controlling computer that manages all the renders.  It tells each computer which scene and frame to render and then assembles all those images back together into a movie scene.  When a computer gets done with one frame, it asks that computer which frame it should render next.  So, you submit your animation to one computer, and that computer distributes the workload to everyone else.  When it is done, you go back to that same computer and see your results.  This is how Pixar gets things done but they have thousands of computers.

I’ve done a lot of looking for a render farm solution that I can use with Blender (the free 3d package we use).  There are quite a few solutions I looked at:  Farmer Joe, Dr. Queue, Res Power, renderfarm.fi, BURP, vSwarm.  None of these were appealing to me for various reasons.  Some only supported computers on a common network, others didn’t support creating your own farm if you have lots of machines.  The community ones, you are at the mercy of getting render time, so it could be hours before the computers even begin working on your render.  I need a sort of hybrid where you can use your own computers, your friends computers, and even rent servers if you are approaching a deadline.  I have several good machines not really doing anything useful right now.  I also have several machines that don’t have much usage during the day.  All of my machines could work on rendering scenes at night.  These machines run Windows, Mac, and Linux, so I need it to be cross-platform.  I also have friends that would be willing to render frames for me too.    The conclusion I reached is that I need/want to build my own render farm.

Since I need the client to run on the big 3 OS, I decided it was a perfect opportunity to enhance my skills with Ruby.  Not only can I build the server in Ruby on Rails, I can build a native looking client using Ruby with wxRuby.

I want to give back to the OS community that I’ve taken so much from.  I am going to use this project to contribute to the Ruby community by hopefully being able to work on wxRuby by either coding bug fixes or perhaps writing tutorials.  I also want to give back to the Blender community by making my render farming code open source so anyone can run their own server.

I secured the domain blenderfarmers.com for this project.

Ruby ‘here document’

Ruby has a cool feature that allows you to embed a document inside your source code.  This is known as a ‘here document’.  The traditional way of defining a string is to assign a variable as follows:

def myfunc
  mystring = "Here's a great quote: nn"We hold these truths to be self-evident, that all men are created equal, that they are endowed by their Creator with certain unalienable Rights, that among these are Life, Liberty and the pursuit of Happiness."nn - Declaration of independence.n"
end

The here document feature allows for syntax like the following:

def myfun
  mystring = <<MYDELIMITOR
Here's a great quote: 

"We hold these truths to be self-evident, that all men are created equal, that they are endowed by their Creator with certain unalienable Rights, that among these are Life, Liberty and the pursuit of Happiness." 

- Declaration of independence.

MYDELIMITOR
end

The MYDELIMITOR can be anything that you want, just make sure that it won’t exist in your “here document” text. Also, the MYDELIMITOR must be the first token on a new line unless you use the following syntax:

mystring = <<-MYDELIMITOR

If you use that syntax, then you can indent it. Important to note that your string will have all line breaks and indentations. So, if you have nested code, it might look a little ugly but it sure is nice to not have to escape everything.

Compiling wxruby on Snow Leopard

I am trying to compile wxruby on Snow Leopard.  I am running into issues because wxwidgets 2.8 which wxruby 2.0.1 is based upon only compiles in 32bit mode.  I can compile wxwidgets 2.8.11 using 32 bit mode.  When I try to compile wxruby, I get errors.  I’m not quite sure what I need to do to resolve this yet.  Once (If) I do, I’ll update this post.

compile wxMac

# Download, compile, install the 2.8.11 version of wxMac
mkdir osx-build
cd osx-build
arch_flags="-arch i386"
../configure  CFLAGS="$arch_flags" CXXFLAGS="$arch_flags" CPPFLAGS="$arch_flags" LDFLAGS="$arch_flags" OBJCFLAGS="$arch_flags" OBJCXXFLAGS="$arch_flags" --enable-universal_binary --with-macosx-sdk=/Developer/SDKs/MacOSX10.4u.sdk --with-macosx-version-min=10.4 --disable-shared --enable-unicode --enable-static --disable-debug --enable-catch_segvs --enable-graphics_ctx --enable-mediactrl --with-opengl --with-libjpeg=builtin --with-libpng=builtin --with-libtiff=builtin --with-expat=builtin --enable-gui --enable-xrc --enable-mdi --enable-gif --enable-pcx --enable-iff --enable-pnm --enable-xpm --with-macosx-sdk=/Developer/SDKs/MacOSX10.6.sdk --with-macosx-version-min=10.6
make
sudo make install

compile SWIG

# Download, compile, install SWIG 1.3.38
cd /usr/local/swig-1.3.38
sudo ./configure --disable-ccache #--disable-ccache is because I do not have yodl2man installed
sudo make
sudo make install

compile wxruby

# Downloaded the trunk versin of wxRuby
svn checkout svn://rubyforge.org/var/svn/wxruby
cd wxruby/trunk
rake

Error!

# ---------------- ERROR
I get the following error:
lipo: can't figure out the architecture type of: /var/folders/pI/pIyyNf1MGiaa6DODFaul2U+++TI/-Tmp-//ccmdge2D.out
lipo: can't open input file: /var/folders/pI/pIyyNf1MGiaa6DODFaul2U+++TI/-Tmp-//ccsraXTA.out (No such file or directory)
rake aborted!
Command failed with status (1): [g++ -c  -I/usr/local/lib/wx/include/mac-un...]

Native Looking Mac App with Ruby

Ruby is really popular to make websites because of Rails, but I want to write a native looking application using Ruby.  I’ve discovered wxruby which is a really cool cross platform GUI library for use with Ruby.  It is built on wxWidgets which is a C++ library for making cross platform GUIs that appear native because they are built on the underlying native libraries of each platform (linux, OSX, and Windows).  Right now, I’m interested in Mac, but I plan on testing this on Windows and Linux too.

Installation

wxWidgets

You have to download the source and compile it yourself for Snow Leopard.  This means, you need to install the developer toolset that comes with your Snow Leopard DVD.  Just install everything, hard drives are cheap.  I don’t know if you have to actually run “./configure”, “make” or not.  My guess is you don’t, but I did.  Snow Leopard has some special challenges and you have to do the following:

$ set arch_flags="-arch x86_64"
$ ./configure CFLAGS="$arch_flags" CXXFLAGS="$arch_flags" CPPFLAGS="$arch_flags" LDFLAGS="$arch_flags" OBJCFLAGS="$arch_flags" OBJCXXFLAGS="$arch_flags"
$ make

DialogBlocks

After you download, Open the DMG image and copy the contents to wherever you want.  I copied mine to /Developer/Applications.  When you run this for the first time, it asks you to select the location of wxWidgets.

wxruby

The latest stable version is 2.0.1.  If you try to install wxruby through gems, it will install 1.9.3.  I don’t know what’s different between the two, but 2.0.1 is a year old so I want to use it.

wx_sugar

$ gem install wx_sugar

Ruby

You should already have a version of Ruby installed.  I list it here because the latest version as I write this is 1.9.2.  Unfortunately, one of the tools we will use to generate ruby classes does not support 1.9.2.  If you really want to use 1.9.2, you can follow the directions here.  I haven’t tried it so I don’t know if it will work or not.  I just switched to mine to the system version “rvm  –default system”

Making a simple app

There is a great tutorial on the wxruby website.  It shows you how all these tools work together to create an application. I created my frame using DialogBlocks.  I created my ruby file using xrcise.  I completed the tutorial.  Now if you forget that wxruby is 32bit only and you just try to run the app, you may see an error like this:

/Library/Ruby/Gems/1.8/gems/wxruby-2.0.1-universal-darwin-9/lib/wxruby2.bundle: dlopen(/Library/Ruby/Gems/1.8/gems/wxruby-2.0.1-universal-darwin-9/lib/wxruby2.bundle, 9): no suitable image found.  Did find: (LoadError)
/Library/Ruby/Gems/1.8/gems/wxruby-2.0.1-universal-darwin-9/lib/wxruby2.bundle: no matching architecture in universal wrapper - /Library/Ruby/Gems/1.8/gems/wxruby-2.0.1-universal-darwin-9/lib/wxruby2.bundle
from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `require'
from /Library/Ruby/Gems/1.8/gems/wxruby-2.0.1-universal-darwin-9/lib/wx.rb:12
from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems/custom_require.rb:36:in `gem_original_require'
from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems/custom_require.rb:36:in `require'
from main.rb:3

To run the app, you need to run ruby in 32 bit mode like this:

env arch -i386 ruby -rubygems main.rb

Here is the screen shot of my app running on a mac.

Ruby on Rails Plugins

Not sure if this is worth doing or not since these ruby plugins change so frequently, but here are a list of plugins that I find interesting as a java guy coming up to speed in ruby on rails.

Referential Integrity

script/plugin install http://svn.hasmanythrough.com/public/plugins/validates_existence/

From “Learning Rails” by O’Reilly.  Page 149

Scaffolding

ActiveScaffold.com

Geo Coding

http://geokit.rubyforge.org/

Image Processing

attachment_fu

ImageScience

http://seattlerb.rubyforge.org/ImageScience.html

HTML Dom in Ruby with Nokogiri

I recently needed to do a screen scrape of a website.  The page I’m trying to parse is marked as an “XHTML 1.0 Transitional”.  XHTML?  Should be easy.  Parse the doc, use XPath and I’ll be done.

If you search “xml parser ruby”, the first result you will get is REXML.   I’ve read comparisons that point out that libxml is several of orders of magnitude faster.  My first attempt used REXML.  I failed miserably in this attempt because the web page I was parsing was not actually valid XHTML.  After I learned it was broken, I ran it through W3C’s validation service and discovered the site had over 100 errors.  XML Parsing is out.

That led me to a search for HTML Dom ruby which led me to hpricot.  I actually didn’t even try this parser because Andrew Kavanaugh pointed me to Nokogiri.  Nokogiri is interesting because it provides two different ways to find the elements you are interested in.  It lets you find an element using XPath or CSS selectors.  Lately, I’ve been doing a lot of CSS selectors so I went that route.  The document I was searching through had something like the following HTML:

...
<div class="section">
<h4>Section 1</h4>
<p>
  <sup class="requirement">1</sup>Requirement 1 descriptive sentence.
  <sup class="requirement">2</sup>Requirement 2 descriptive sentence.
  <sup class="footnote"><a href="#footnote1">footnote 1</a></sup>
    &nbsp;&nbsp;&nbsp;
    More descriptive text.
  <sup class="requirement">3</sup>Requirement 3 descriptive sentence.</div>
</p>
</div>

I needed to translate this into a format I could insert into my database.  I don’t care about footnotes, or spacing or anything other than the raw text.  I need it to look something like:

Section 1.1, Requirement 1 descriptive sentence.
Section 1.2, Requirement 2 descriptive sentence. More descriptive text.
Section 1.3, Requirement 3 descriptive sentence.

I used the following code to get the section number I was after:

@section = doc.at('div.section h4').inner_html

I then used the following code to get the subsection number and the text associated with it:

doc.css('div.section sup.requirement').each do |element|
  # Get the requirement subsection number
  @requirement = element.to_s.strip

  # Since we are interested in all the text between each of the subs
  # We need to get every text node until we run into the start of the next
  # sub class='requirement' node
  @node = element.next
  @text = ""
  while @node != nil && (@node['class'] != 'requirement') do
    if (@node.text?) then
      @text = @text + " " + @node.to_s.strip
    end
    @text = @text.strip
    @node = @node.next
  end
  puts  @section + "." + num.inner_html + ", " + @text
end

Man I love these “whatever.each do |element|” style blocks.  Very powerful.  When I ran this for the first time, I encountered an oddity I didn’t quite understand.  Even though I was calling strip to eliminate the white space, I was getting a row that looked like:

Section 1.2, Requirement 2 descriptive sentence.    More descriptive text.

It turns out that when calling to_s on a node, it converts &nbsp; into something that is whitespace but not stripped out by the normal strip function.  I modified the strip function of the String class and all worked well.

class String
  alias_method :strip_old, :strip
  def strip
    self.gsub(/^[302240|s]*|[302240|s]*$/, '')
  end

  def strip!
    before = self.reverse.reverse
    self.gsub!(/^[302240|s]*|[302240|s]*$/, '')
    before == self ? nil : self
  end
end

In the past, this would have been something I’d have just thrown together in Java.  If I ever need to do something like this again in Java, I’m going to try out this HTML parser called Cobra.  It even handles javascript calls in the page (like document.write).

Simulating a slow network on a Mac

I ran across these very handy commands to simulate a connection of only 4kbps.  This is helpful when developing mobile applications in particular because some cell connections are horrible.

sudo ipfw pipe 1 config bw 4KByte/s
sudo ipfw add 100 pipe 1 tcp from any to me 3000

There are several interesting parts to these commands.

The 4KByte/s which can be whatever speed you want.  This is the bandwidth, measured in [K|M]{bit/s|Byte/s}.

The other interesting part is 3000.  This is the port that will be slowed.  Port 3000 is the default port on which Ruby on Rails listens.  If you are doing Java, you would probably want to use 8080.

The 100 is the rule number.  Useful when it comes time to delete this rule.

To clear out this pipe, simply type the following when finished:

sudo ipfw delete 100

To clear all custom rules, you could type:

sudo ipfw flush

Ruby on Rails Nested Resources, Namespaces, and RESTful

I am working on a website where I have an admin section to add data and public read only sections.  I like to have a clean hierarchy of URLs.  I first implemented it using the standard generator code.  I had a /restaurants and a /locations url for both.  Locations doesn’t make sense as a top level URL because Restaurants have locations.  I’d rather see things like /restaurants/1/locations.  In fact, that isn’t quite right either.  I only want to show the restaurants for the logged in user.  I really want it to look like /admin/restaurants/1/locations.

Nested Resources

So the first thing I did was to make locations be a resource of restaurants. In my config/routes.rb file, I did the following:

map.resources :restaurants, :has_many => [ :locations ]

In the app/controllers/locations_controller.rb, I created a before_filter to set the @restaurant reference.  Every place where I used Location.find, I changed it to @restaurants.locations.find.  This only gets the locations for the restaurant from the restaurant’s locations attribute.

class LocationsController < ApplicationController
  before_filter :get_restaurant      

  def index
    @locations = @restaurant.locations
    ...
  end

private
  def get_restaurant
    @restaurant = Restaurant.find(params[:restaurant_id])
  end

end

Now my URLs look like /restaurants/1/locations.

You will need to change the form_for on your new.html.erb and edit.html.erb.  If you are using partials for both of these (you should be) then edit that file.  Change the form_for tag to

<% form_for([@restaurant, @location]) do |f| %>

Namespace

Now, I’d like to move these into the /admin url.  I do this by modifying the config.routes.rb file again.

  map.namespace :admin do |admin|
    admin.resources :restaurants, :has_many => [ :locations ]
  end

This creates the admin namespace with URLs that look like /admin/restaurants/1/locations.  When you add this namespace, Rails will then look for your controllers inside the module Admin.  So you will need to create the app/controllers/admin directory and move the restaurants_controller.rb and locations_controller.rb inside it.  Do the same for the app/views/admin directory.  Move the locations and restaurants folder inside it.  You will need to modify the /app/controllers/admin/restaurants_controller.rb and the /app/controllers/admin/locations_controller.rb files.  Add Admin:: in front of the class name like follows:

class Admin::LocationsController < ApplicationController

When I opened up /admin/restaurants/1/locations in my browser, I got errors saying things like restaurant_location_path is invalid.  To correct this, I had to modify the views to prepend “admin_” to all the path functions and add the location parameter.  A safe guess is that Ruby on Rails dynamically generates these functions.

<td><%= link_to 'Show', admin_restaurant_location_path(@restaurant, location) %></td>
<td><%= link_to 'Edit', edit_admin_restaurant_location_path(@restaurant, location) %></td>
<td><%= link_to 'Destroy', admin_restaurant_location_path(@restaurant, location), :confirm => 'Are you sure?', :method => :delete %></td>

I really don’t like embedding the “admin” into the code because I could change my mind and want it all to live inside /administration.  I don’t want to have to change all my code just because of where it lives.  Too tightly coupled.  so, I am not going to use the function created for me.  Instead, I’ll build the URL myself.  If you do not specify the controller or namespace, it uses the current one. Change

<td><%= link_to 'Show', url_for(:action => 'show', :id => location) %></td>
<td><%= link_to 'Edit', url_for(:action => 'edit', :id => location) %></td>
<td><%= link_to 'Destroy', url_for(:action => 'destroy',:id => location), :confirm => 'Are you sure?', :method => :delete %></td>

This will build the same URLs as using the “admin_” functions but without hardcoding the admin path.  You need to do the same thing inside the controllers.  For the link back to the parent, you will need to add the controller as a parameter.

<%= link_to 'Back', admin_restaurant_path(@restaurant) %>

Change to

<%= link_to 'Back', url_for(:controller => 'restaurants', :action => 'show', :id => @restaurant) %>

The next thing you will need to change is the form edit.

<% form_for( :location, @location, :url => { :action => "create"} ) do |f| %>