Wednesday, July 23, 2008
Few things are better than spending time in a creative haze, consumed by ideas, watching your work come to life, going to bed eager to wake up quickly and go try things out. I am not suggesting that excessive hours are needed or even advisable; a sane schedule is a must except for occasional binges. The point is that programming is an intense creative pleasure, a perfect mixture of puzzles, writing, and craftsmanship. Lucky to be a programmer indeed. From Gustavo Duarte, via Gus Mueller.
Sunday, July 6, 2008
[Flash 9 is required to listen to audio.]

tuneage:

Lilofee - “Lock and Key”

We don’t know much about Lilofee, except that they make excellent electro pop, listing their influences as 60s girl bands, 80s dark pop, and 90s industrial.

Don’t just check out this sweet tune from lilofree, but also head over to tuneage for regular doses of new, interesting music!

Saturday, June 28, 2008

Mum's Savoury Mince Pockets

These guys are easy to make and taste excellent, and are also good cold or reheated the next day! Thanks, Mum.

  • 1 kg good (beef) mince
  • 2 carrots, peeled and diced
  • 1 onion, diced
  • 1 tsp garlic
  • 2 tsp curry powder
  • 1 cup frozen peas and corn
  • Tomato sauce
  • Sweet chilli sauce
  • 2 cups cooked rice
  • Lebanese bread, around 3-4 pieces
  1. Fry the mince with the garlic and curry powder.
  2. Once the mince is getting close to done, add the peas and corn.
  3. Add tomato sauce and sweet chilli sauce to taste.
  4. Add the cooked rice and mix it all up.
  5. Cut the lebanese bread in half to form pockets and fill with the mince and rice mixture.
  6. Put the filled pockets in an oven at 180°C for 5-10 minutes, or until crisp.
Friday, June 27, 2008

Displaying both local and HTTP remote images in Prince XML generated PDFs

In our Rails apps, we use the awesome Prince XML to generate PDFs. We interact with the prince command line application using the Ruby library and Rails helper from the guys over at subimage interactive.

When using their helper to generate a PDF from a Rails template, all image tags have the src attribute altered so they point to paths that are relative to the local filesystem, not just the root of your application.

However, this breaks any images that you are loading from remote locations over HTTP. For us, this ended up breaking the static Google Maps that we were generating.

So here’s an updated make_pdf helper that only modifies the image paths if they are local. This lets us use both local and HTTP-hosted images on the same PDF!

# We use this chunk of controller code all over to generate PDF files.
#
# To stay DRY we placed it here instead of repeating it all over the place.
#
module PdfHelper
  require 'prince'

  private
    # Makes a pdf, returns it as data...
    def make_pdf(template_path, pdf_name, landscape=false)
      prince = Prince.new()
      # Sets style sheets on PDF renderer.
      prince.add_style_sheets(
        "#{RAILS_ROOT}/public/stylesheets/application.css",
        "#{RAILS_ROOT}/public/stylesheets/print.css",
        "#{RAILS_ROOT}/public/stylesheets/prince.css"
      )
      prince.add_style_sheets("#{RAILS_ROOT}/public/stylesheets/prince_landscape.css") if landscape
      # Render the estimate to a big html string.
      # Set RAILS_ASSET_ID to blank string or rails appends some time after
      # to prevent file caching, and messing up local-disk requests.
      ENV["RAILS_ASSET_ID"] = ''
      html_string = render_to_string(:template => template_path, :layout => 'document')
      # Make all paths relative to the file systemm, but only if they don't have http(s):// at the start.
      html_string.gsub!(%r{(src=")([^h][^t][^t][^p][^s]?[^:][^/]*)}, "src=\"#{RAILS_ROOT}/public\\2")
      # Send the generated PDF file from our html string.
      return prince.pdf_from_string(html_string)
    end

    # Makes and sends a pdf to the browser
    #
    def make_and_send_pdf(template_path, pdf_name, landscape=false)
      send_data(
        make_pdf(template_path, pdf_name, landscape),
        :filename => pdf_name,
        :type => 'application/pdf'
      ) 
    end
end

And just to be precise, here is the diff between the helpers:

--- pdf_helper.rb	2008-06-27 15:05:44.000000000 +1000
+++ new_pdf_helper.rb	2008-06-27 15:05:54.000000000 +1000
@@ -18,11 +18,11 @@
       prince.add_style_sheets("#{RAILS_ROOT}/public/stylesheets/prince_landscape.css") if landscape
       # Render the estimate to a big html string.
       # Set RAILS_ASSET_ID to blank string or rails appends some time after
-      # to prevent file caching, fucking up local - disk requests.
+      # to prevent file caching, and messing up local-disk requests.
       ENV["RAILS_ASSET_ID"] = ''
       html_string = render_to_string(:template => template_path, :layout => 'document')
-      # Make all paths relative, on disk paths...
-      html_string.gsub!("src=\"", "src=\"#{RAILS_ROOT}/public")
+      # Make all paths relative to the file systemm, but only if they don't have http(s):// at the start.
+      html_string.gsub!(%r{(src=")([^h][^t][^t][^p][^s]?[^:][^/]*)}, "src=\"#{RAILS_ROOT}/public\\2")
       # Send the generated PDF file from our html string.
       return prince.pdf_from_string(html_string)
     end

I’d also love it if you could propose a better way to handle the regular expression inside the gsub! call. Leave a comment!

Thursday, June 26, 2008
Very excited about my second trip to China that will come later this year.
Very excited about my second trip to China that will come later this year.
Wednesday, June 18, 2008

Loading the ActiveRecord SQL Server adapter in a Rails 2.1 app

It’s pretty simple. In your config/environment.rb:
  config.gem 'activerecord-sqlserver-adapter', :source => 'http://gems.rubyonrails.org', :lib => 'active_record/connection_adapters/sqlserver_adapter'
Then run rake gems:install and away you go. Hugh has some more tips about the packages and configuration required to connect to an SQL Server from a Linux platform.
Thursday, June 12, 2008

Enabling a non-interactive install of Blackdown's j2re1.4 on Ubuntu or Debian

When you `apt-get install` the j2re1.4 Java package in Debian or Ubuntu, it displays a few ncurses-style dialogs to configure the software and to require your acceptance of the license agreement. Working with these dialogs is fine if you are installing the software with apt-get in a typical interactive shell session. If you are installing without this capacity to interact (like in a script), you will run into problems. Here’s how to fix it.

If you install the package with the noninteractive frontend for dpkg, then you’ll get an error like this:

# DEBIAN_FRONTEND=noninteractive /usr/bin/apt-get --yes --force-yes install j2re1.4


Reading package lists... Done
Building dependency tree       
Reading state information... Done
Suggested packages:
  mozilla-browser mozilla-firefox galeon ttf-kochi-gothic ttf-kochi-mincho
Recommended packages:
  gsfonts-x11 libx11-6 libxext6 libxi6
The following NEW packages will be installed:
  j2re1.4
0 upgraded, 1 newly installed, 0 to remove and 23 not upgraded.
Need to get 0B/22.5MB of archives.
After unpacking 60.3MB of additional disk space will be used.
Preconfiguring packages ...
j2re1.4 failed to preconfigure, with exit status 10
Selecting previously deselected package j2re1.4.
(Reading database ... 26639 files and directories currently installed.)
Unpacking j2re1.4 (from .../j2re1.4_1.4.2.02-1ubuntu3_i386.deb) ...
dpkg: error processing /var/cache/apt/archives/j2re1.4_1.4.2.02-1ubuntu3_i386.deb (--unpack):
 subprocess pre-installation script returned error exit status 10
Errors were encountered while processing:
 /var/cache/apt/archives/j2re1.4_1.4.2.02-1ubuntu3_i386.deb
E: Sub-process /usr/bin/dpkg returned an error code (1)

The package fails to install because it requires the acceptance of the licence agreement, which it will only allow in an interactive installation.

The typical way to fix this is to pre-seed the debconf database (using `debconf-set-selections`) with the answers to the questions that the j2re1.4 package requires. However, this doesn’t seem to satisfy j2re1.4, and the package still displays the dialog or fails in non-interactive mode. Why is it java that always gives me these hairy problems?

Anyway, here is the way to fix it. If you manually append the values directly to the debconf database file, it will work:

cp /var/cache/debconf/config.dat /var/cache/debconf/config.dat-old

cat << E_O_DEBCONF >> /var/cache/debconf/config.dat


Name: j2re1.4/jcepolicy
Template: j2re1.4/jcepolicy
Value:
Owners: j2re1.4
Flags: seen


Name: j2re1.4/license
Template: j2re1.4/license
Value: true
Owners: j2re1.4
Flags: seen


Name: j2re1.4/stopthread
Template: j2re1.4/stopthread
Value: true
Owners: j2re1.4
Flags: seen


E_O_DEBCONF

(For reference, I found these values by making a copy of the config.dat file, running `dpkg-preconfigure` on the j2re1.4 package, and then running a diff between the updated config.dat file and my copy.)

Now you’ll be able to successfully install the package in noninteractive mode. This means, for us, one step closer to fully automating our Xen builds!

Tuesday, June 10, 2008

Automatic Saving Of Invalid Resources in Rails While Maintaining a Clean RESTful Interface

or

How To Change Your World In One Line Of Code

One of the cool things that we’re doing at the AMC is building a large collection of loosely coupled Rails applications that communicate using REST. This is slightly unusual, as rails is predominantly used to build single apps that operate in isolation. In our experiences, we’ve picked up a number of tricks that we’d like to share. Here’s the first, on how a single this single line of code has saved us weeks of time and effort. Here’s the line in question:

if @bank_transaction.save && @bank_transaction.valid?

Read on to find out how this helps!

RESTful Resources

This line is part of a new Rails app we’re developing to centrally handle all online payments for our software systems at the AMC. In this payments application, we expose two key resources over REST: (1) line items, which the other apps create with the details of the items to purchase, and (2) bank transactions, which are passed line item IDs and credit card details for the purchase.

Naturally, the models behind these resources have a bunch of validation rules that ensure certain conditions are met before they can be saved successfully. If any of these requirements are not met, then the model fails to save and the error hash is returned to the client app.

For most resources, these error hashes are returned in the usual Rails-like way. Let’s look at how LineItemsController does it:

class LineItemsController < ApplicationController
  # POST /line_items.xml
  def create
    @line_item = LineItem.new params[:line_item]
    respond_to do |format|
      if @line_item.save
        format.xml  { render :xml => @line_item, :status => :created, :location => @line_item }
      else
        format.xml  { render :xml => @line_item.errors, :status => :unprocessable_entity }
      end
    end
  end
end

To paraphrase: if the items save successfully, return success and the line item in XML, otherwise return the error hash. Nice and predictable, nothing exciting here.

Saving Invalid Resources

One of the resources in the payments app is different. These are the BankTransactions, which are about as “mission critical” as we get. Let’s talk about the successful case first: during the creation of the BankTransaction model, if all the validations have passed, a before_create callback is triggered that will talk to the bank (using ActiveMerchant, of course) and ask to make the transaction there. If this succeeds, the model is saved to the database and an XML representation of the saved model is passed back to the client application with a success code.

However, if the transaction with the bank fails, this is still information we care about. A failed transaction could be an indication of a larger problem, and also needs to be recorded for customer service purposes. It makes sense to save every failed transaction as well as every successful one. To this end, the callback that communicates with the bank always returns true, which allows the save continue, and records for both successful and unsuccessful transactions to be kept in the database.

(Another approach to this problem would be to create a separate “TransactionLog” model to store the transaction data, but this approach requires extra work. Having the BankTransactions save every time is essentially free. Excellent.)

Keeping the REST API Simple

While the payments app is saving unsuccessful transactions, the client apps do not want to keep these records around: all they care about is if a transaction is successful or not. The easiest way to make it simple for the clients is to make the creation of a bank transaction resource behave the same way as creating any other resource over REST in rails. This means that if a transaction with the bank fails, then it should *appear* to the clients as if the save also failed.

This will require the controller to generate an errors hash if the transaction fails. This means that the model should be invalid at this point. Given that we save to the database even for failed transactions, the model should therefore be invalid after the save:

class BankTransaction < ActiveRecord::Base  
  validate :must_be_successful_if_saved
  before_create :transact
  
  private
  
  def transact
    # talk to the bank here, and set self.success to true or false pending the results
    # return true to make sure a save always occurs
    true
  end
  
  def must_be_successful_if_saved
    errors.add_to_base("failed to transact successfully with the bank") if !new_record? && !success?
  end
end

And then, in the BankTransactionsController, that one magic line:

class BankTransactionsController < ApplicationController
  # POST /bank_transactions.xml
  def create
    @bank_transaction = BankTransaction.new params[:bank_transaction]
    respond_to do |format|            
      if @bank_transaction.save && @bank_transaction.valid?
        format.xml  { render :xml => @bank_transaction, :status => :created, :location => @bank_transaction }
      else
        format.xml  { render :xml => @bank_transaction.errors, :status => :unprocessable_entity }
      end
    end
  end
end

Unlike the standard behaviour shown in the LineItemsController above, we only return a successfully created model if the save is successful AND it is still valid afterwards. A saved model for a failed transaction with the bank will be invalid at this point, so it will return the errors hash. To the client app, this looks like the same resource it tried to create initially, and so it can proceed as usual to display the errors, ask for corrections if necessary, and try to save again. In the background, the payments app has saved every failed transaction for safe keeping.

Monday, June 2, 2008
FYI: the plumber used the tea towels in the kitchen to mop up the floor, use at your own risk. This is why I bring my own cutlery to work.
Tuesday, May 27, 2008

God init script for Debian/Ubuntu systems

To compliment the Red Hat init script that is available on the net, here’s the init script we use to launch god on our Ubuntu systems. To use, save as /etc/init.d/god, make the file executable, then run `update-rc.d god defaults`. You’re done.
#!/bin/sh


### BEGIN INIT INFO
# Provides:             god
# Required-Start:       $all
# Required-Stop:        $all
# Default-Start:        2 3 4 5
# Default-Stop:         0 1 6
# Short-Description:    God
### END INIT INFO


NAME=god
DESC=god


set -e


# Make sure the binary and the config file are present before proceeding
test -x /usr/bin/god || exit 0


# Create this file and put in a variable called GOD_CONFIG, pointing to
# your God configuration file
test -f /etc/default/god && . /etc/default/god
[ $GOD_CONFIG ] || exit 0


. /lib/lsb/init-functions


RETVAL=0


case "$1" in
  start)
    echo -n "Starting $DESC: "
    /usr/bin/god -c $GOD_CONFIG -P /var/run/god.pid -l /var/log/god.log
    RETVAL=$?
    echo "$NAME."
    ;;
  stop)
    echo -n "Stopping $DESC: "
    kill `cat /var/run/god.pid`
    RETVAL=$?
    echo "$NAME."
    ;;
  restart)
    echo -n "Restarting $DESC: "
    kill `cat /var/run/god.pid`
    /usr/bin/god -c $GOD_CONFIG -P /var/run/god.pid -l /var/log/god.log
    RETVAL=$?
    echo "$NAME."
    ;;
  status)
    /usr/bin/god status
    RETVAL=$?
    ;;
  *)
    echo "Usage: god {start|stop|restart|status}"
    exit 1
    ;;
esac


exit $RETVAL