qr4r – Generate QRCode PNGs in Ruby

One of our ongoing projects has been using QRCodes as page identifiers on promo materials. Up to this point, we’ve been using online QRCode generators (of which there are plenty: QR-Code Generator, Create QR Code, Google Url Shortener to name a few).

We were tired of cutting and pasting urls. Could we build QRCodes for urls directly in the app? Some of the services mentioned above have APIs, which we could use to generate QRCode images. But instead of adding 3rd party web API calls to my app, I wanted to see how hard it’d be to own that QRCode generation logic.

A quick search revealed a few projects on github that all seem to start with rQRCode as a base. This gem generates the QRCode data, but not a png; it should be a great place to start. I also found a couple libraries that use rQRCode plus Chunky_PNG to construct PNGs. But, since we’ve done a bunch of work with ImageMagick and mojo_magick, I thought I might leverage those tools instead.

After releasing mojo_magick on rubygems, I built the qr4r gem. It uses rQRCode to generate the QRCode data, then some simple ImageMagick commands via mojo_magick to write out the image.

How can you use this awesomeness, you ask?

Add qr4r gem to your Gemfile
gem "qr4r"
Update your bundle
bundle install
Fire up a console and …

bundle exec irb
ruby> require 'qr4r'
ruby> Qr4r::encode('this is a qr code, yo', 'my_qrcode.png', :border => 10)

you get this:

Go get your QRCode on!

Docs/Code On Github: qr4r

Advertisements

Fauxtaux Booth – our Mashup-o-rama

We’ve been noticing that writing software for the web is becoming more and more like playing with lego blocks. We are currently working on projects using Ruby + Rails and Node.js + Express. For both of these technology stacks we have a lot of conversations like these:

“You need a library that does <this special thing>?”
“Oh yeah, it’s on github.”

“You need a javascript plugin that does <whatever>?”
“Sure, start from that thing on jQuery plugins and you’re 95% there.”

Such is the nature of participating in and taking advantage of the open source community.

We wanted to share our latest lego-block project. We called it

Fauxtaux Booth

A photographer friend was setting up a photobooth at a conference. She wanted to have the pictures sent directly to the subjects as they were being taken.

The blocks we used for this system were:

The basic setup was as follows:

The photographer was on the net at the conference, her camera tethered to the laptop. As photos were taken, they were written to a folder that sat under a shared Dropbox folder.

On a separate server, also sharing that same Dropbox folder, we setup a watch on that folder using Guard. When we saw a change, we sent an http request (basically a ping) to the Rails app. When the app caught that http request, it would look at the directory and figure out what had changed. If there were new images, it would run several image processing steps and finally email the current customer by way of Sendgrid.

The app also served as a customer signup form. So at the conference, the photographer’s laptop also had a browser window open to the app. As customers stepped up to the booth, they filled out a simple form on the laptop with name and email which we used to send the photos.

For each sitting, the final emailed image was a photostrip with the conference’s branding/data on it.

The majority of the special coding in the app was custom image processing. The rest was basically wiring a bunch of moving parts together.

At the event, our photographer took about 80 photos and we sent out about 400 emails.

This was the setup at the conference.

Adventures with ImageMagick in Ruby: MojoMagick vs RMagick

I was already using MojoMagick in a project. I needed to add some functionality that would resize an image to fill a given space. That is, given width and height, resize the image so that it maximally fills the box (and maybe hangs over the edge). Clearly, this is a job for ImageMagick, so I thought I should be able to access this functionality through MojoMagick. Sadly, MojoMagick doesn’t expose this resizing functionality.

I decided to try moving to RMagick. RMagick seems to be all the hotness based on google searches for ImageMagick and ruby so it seemed like the way to go. And while I was upgrading, I thought I should also get on to the latest version of ImageMagick (from ~6.3 to 6.7).

Thus, I ran down a rat hole that was not terribly pleasant. Issues included:

  • ImageMagick rpm required building from source (old machine, old OS)
  • Much fighting with bundler and rvm versions and ldconfig to get the machine’s head on straight.
  • Finally, ruby/rake segfaulting with every run – which after some reading seemed to be related to RMagick + ImageMagick upgrades that left old bits of ImageMagick around on the system. (read more at stack overflow.)

Yuk.

The fix? Simple: go back to MojoMagick — the dirt simple ImageMagick-Ruby library. I pulled the source from the svn repo, added enough stuff to get a bundler gem built, added the functionality I needed (which was about a 2 line change), and stuck it up on github.

Granted, RMagick is very slick and ruby-ish and has much more of ImageMagick mapped into it’s API. And on a more current system the install can be easier, though not necessarily painless (see rmagick on ubuntu at stackoverflow). But if you don’t need too many bells and whistles, the bare bones ImageMagick functionality that you get with MojoMagick might save you some trouble.

MojoMagick: by Steve Midgley
Updated on github: by Mr Rogers

Put it in your Gemfile with

gem 'mojo_magick', :git => 'git://github.com/rcode5/mojo_magick.git'

Mock the web – OpenURI

On one of our projects, we fetch several blog and twitter entries and build a little sidebar of this content. To do this, we have a controller endpoint that makes several http calls to remote services that grab these feeds. After requiring ‘open-uri’ in our controller, we can simply call open(url) and pass a block to process the feed provided at that url.

While writing my tests around this functionality, I realized that the test code was calling out to twitter and fetching data. That’s no good. So we need to stub out that call. Easy right? We can just stub the open() method and return some dummy data.

Not so fast. Where is the open function? Because we’ve required ‘open-uri’, the Kernel.open method has been aliased away and re-written to handle url inputs.  In our code, we’re using a block to process the results of open().  This block calls ‘read’ on those results.

class MyController  [{:channel => {:title => 'this is the channel title'}].to_json )
      Kernel.stubs(:open).yields( mock_readable )
      get :fetch_feed, :url => 'http://that_blog.blogspot.com/feeds/posts/default?alt=rss'
    end
    it 'assigns feed data to @feed_result' do
      assigns(:feed_result).channel.title.should == 'this is the channel title'
    end
  end
end

This spec fails. As it turns out, ‘open’, though defined on the Kernel module, is mixed in to our controller and we need to stub the call at that level to get the test to work. A quick mod makes this do the right thing:

describe MyController do
  context '#fetch_feed' do
    before do
      #stub out http calls
      mock_readable = stub(:read => [{:channel => {:title => 'this is the channel title'}].to_json )
      MyController.stubs(:open).yields( mock_readable )
      get :fetch_feed, :url => 'http://twitter.com/humblebrag'
    end
    it 'assigns feed data to @feed_result' do
      assigns(:feed_result).should include 'this is a feed entry'
    end
  end
end

And we’re off to the races. Apart from testing the parsing logic in our controller method, we now have a spec that is no longer calling out to an external service. Tests that require internet connectivity are not only slow and unreliable, they are just a bad idea. We trust that OpenURI has been properly tested and knows how to talk to the net. We should only test the functionality we are writing: namely the method that processes the results of our call to open(). We shouldn’t make our specs dependent on the implementation of open() nor a connection to an external URL.

The take-away lesson for me was: once a method is mixed in, the module it came from is unimportant. The mixed-in methods live on the class in which they’ve been mixed. Therefore, when testing, we should stub methods in this top-level class, not the base module where the method is defined.

As a little postscript, FakeWeb is, perhaps, an easier way to stub out the web when trying to write these tests. When it’s time to refactor, I’m going to take a look at putting that gem in my test bundle.