Personalised URL shortener (in Ruby)

Quick one! Bought the domain high.am the other day, vain I know! Anyway, decided one of the must haves for said domain was a decent URL shortener.

Created a shortener based on some PHP code found at http://high.am/rnhyi4, running it on Passenger using Redis for storage.

https://github.com/danhigham/URL-Shortener

Posted in Uncategorized | Leave a comment

Say hello to “Deskimus Prime”

Okay, so for a while now I had heard standing desks were a really good thing and I have had, for quite some time, an IKEA desk more than capable of this.

After seeing @ollylegg transform his office desk with coke cans I decided to take the plunge. So, @first65, I will see your “Megadesk” and raise it (quite literally).

Ladies and Gents, I give you, Deskimus Prime.

Posted in Uncategorized | Leave a comment

Deserializing classes in Ruby using YAML.load

Quick note: when using YAML.load to deserialize an instance of a class that was serialized using to_yaml may end up not working! I have an object called ApplicationProvision, call to_yaml and it looks like this ;

"--- !ruby/object:ApplicationProvision \nconfiguration: \n- !ruby/object:InstantStack::StackConfigurationOption \n default_value: NginX\n possible_values: \n - Apache\n - NginX\n question_key: web_server\n question_text: Do you want to host from Apache or NginX?\n question_type: multiple_choice\n response_value: NginX\n- !ruby/object:InstantStack::StackConfigurationOption \n default_value: MySQL\n possible_values: \n - MySQL\n - SQLite\n question_key: db_server\n question_text: Do you want to host the database from MySQL or SQLite?\n question_type: multiple_choice\n response_value: MySQL\nguid: 993b9956-df61-4612-a8b4-c71937603467\nprevious_stage: 5\nregion: 1\nsize: 4\nstack: 21\nstate: :configured\n"
.. perfect

However deserialized, it looks like this;

#<ApplicationProvision:0x105716000
@class="ApplicationProvision",
@ivars=
{"region"=>1,
"stack"=>21,
"size"=>4,
"previous_stage"=>5,
"guid"=>"993b9956-df61-4612-a8b4-c71937603467",
"configuration"=>
[#<InstantStack::StackConfigurationOption:0x105717540
@default_value="NginX",
@possible_values=["Apache", "NginX"],
@question_key="web_server",
@question_text="Do you want to host from Apache or NginX?",
@question_type="multiple_choice",
@response_value="NginX">,
#<InstantStack::StackConfigurationOption:0x1057169d8
@default_value="MySQL",
@possible_values=["MySQL", "SQLite"],
@question_key="db_server",
@question_text="Do you want to host the database from MySQL or SQLite?",
@question_type="multiple_choice",
@response_value="MySQL">],
"state"=>:configured}>

Not good! Little bit of reading around this problem and I found this post on StackOverflow.

Add a require_dependency at the top of the class in context and everything works fine

#<ApplicationProvision:0x10585aec0
@configuration=
[#<InstantStack::StackConfigurationOption:0x10585c400
@default_value="NginX",
@possible_values=["Apache", "NginX"],
@question_key="web_server",
@question_text="Do you want to host from Apache or NginX?",
@question_type="multiple_choice",
@response_value="NginX">,
#<InstantStack::StackConfigurationOption:0x10585b898
@default_value="MySQL",
@possible_values=["MySQL", "SQLite"],
@question_key="db_server",
@question_text="Do you want to host the database from MySQL or SQLite?",
@question_type="multiple_choice",
@response_value="MySQL">],
@guid="993b9956-df61-4612-a8b4-c71937603467",
@previous_stage=5,
@region=1,
@size=4,
@stack=21,
@state=:configured>

et voila!

Posted in Uncategorized | Leave a comment

Vimeo “Watch Later” RSS feeds

I am a big fan of Vimeo, the content is great and the site is really nice too. Having bought a Boxee box a few months ago I have been getting more and more in to watching online content on my TV at home. Last night I started to add some RSS feeds from Vimeo, I started off by adding one particular person and then a group etc.

What I really wanted to do was to mark stuff for viewing at home in the evening, during the day, the watch later feature in Vimeo is perfect for this. To my horror there was no way of consuming these on the boxee as there is no RSS feed for “watch later”, at that point the only alternative was to like a video and then use the “likes” RSS feed, but that seemed a bit backwards, liking a video before I had even watched it, no thanks!

So, having the afternoon free today I knocked up a simple app using Sinatra to do the oauth dance with Vimeo and then make your watch later album publicly available forever more as RSS. Head on over to http://vimeowatchlater.heroku.com and follow the instructions, it’s pretty simple. Check out my watch later feed at http://vimeowatchlater.heroku.com/danhigham.

NOTE: This is hosted on heroku and I have been forced to store data in /tmp! You may have to re-auth against vimeo with a browser every once in a while or maybe not!

Thanks goes to matthooks for his gem at https://github.com/matthooks/vimeo.

Posted in Uncategorized | 3 Comments

Managing CoffeeScript in Sinatra / Ruby

Over the last couple of weeks I have been working on a project for a client that involved building a couple of small applications in Sinatra (a light web framework for Ruby). Both applications have a RESTful interface, as is the nature of Sinatra, and a javascript frontend using jQuery to make asynchronous requests. I made the decision to run with CoffeeScript as it makes creating js classes a doddle and keeps the client side code readable and uniform in style.

Originally I had stuck to one big coffee script file, but this began to grow a little out of control as the functionality of the app expanded, so I decided to break things up. Using the coffee-script gem, I just added a couple more coffee script files, one for my classes and one for general utility type functions. Two problems quickly made themselves apparent;

1. Coffeescript, by default, generates javascript files inside a closed scope. Not sure this is the correct way to phrase it, but I will show you what I mean. All the javascript it generates is enclosed in this (function() { ... }).call(this);, this effectively places everything inside its own scope, which means if you define a class for use by the application it won’t be accessible by anything unless its defined in the same .coffeescript file. The coffeescript compiler has an option to remove these called –bare, I needed to make sure that is run for class type coffeescript files.

2. I found that for some reason (at least in OS X) when Ruby tried to compile more than one coffeescript at a time, it would choke. I was using the “therubyracer” gem along with “coffee-script”, so I assume the coffee-script gem was using V8 to compile the javascript. As you can imagine, when the page was initially loaded several requests were made for .js files that were actually the compiled output of a coffeescript file, the Ruby process would end up at 100%, choked!

Whats more, there is really no real need to have the coffee-script compiler involved at all in a production environment, so here is what I wanted to do. When the application was run in development, generate and cache the javascript files, that way I could deploy those to live and when it was run in production skip the coffee-script part of the application all together. I started off by swapping out just using the coffee-script gem and opted if for a Rack filter called rack-coffee, git repo is here and my fork of it is here. This gem, rather than compiling the coffeescript from the Sinatra application itself, will do it when Rack is handling the initial request for the .js file, it’s a pretty straight forward class and does the job very nicely, handing compilation of the coffeescript off to the command line compiler itself.

At that point, rack-coffee never actually compiled the script to the filesystem, just to STDOUT when it was out of date or returned a 304 (Not Modified) if it was in date. So, first step, cache to the filesystem. Below you can see the changes I made to rack-coffee;

The main two changes to notice are firstly the brew function, that now waits for the coffee-script command to finish running and the changes to the call function that add the –bare parameter if its compiling a file in the set class_urls path and also read the compiled .js file and return it as the output for the Rack request.

So from then on, every time the app compiled a coffee-script file it would leave a compile .js file in the path set by the output_path setting. To use this in a sinatra application we would include it like so;

use Rack::Coffee, {
    :root => File.dirname(__FILE__) + '/coffee',
    :urls => '/app_scripts',
    :class_urls => '/app_scripts/classes',
    :output_path => '/public'
  }

Assuming that coffee-script and indeed the rack-coffee library is referenced correctly, every time a .js file is requested from either /app_scripts or /app_scripts/classes it compiles and stores a javascript file to the output_path without or with the –bare flag respectively. The :root parameter shows the library where to find the actual coffee-script source.

So all that is left now is to tell Sinatra to skip this Rack filter when in production mode, this is easy! I use bundler, so my Gemfile looks like this;

source 'http://rubygems.org'

group :development do
  gem 'coffee-script'
  gem 'rack-coffee'
  gem 'therubyracer'
end

group :default do
  gem 'sinatra'
  gem 'json'
  gem 'oauth'
  gem 'mechanize'
  gem 'multipart-post'
end

So, here we can see all the coffeescript libs are only required in a development environment. As for the application itself, just pop an if statement round your call to use the Rack filter, like this;

if ENV['RACK_ENV'].to_sym == :development
  puts "This is development, all coffeescripts are generated..."

  require 'coffee-script'
  require File.dirname(__FILE__) + '/lib/coffee'

  use Rack::Coffee, {
    :root => File.dirname(__FILE__) + '/coffee',
    :urls => '/app_scripts',
    :class_urls => '/app_scripts/classes',
    :output_path => '/public'
  }
end

There we have it, a simple set up to compile coffeescript in development but fallback to the cached js output in production. This of course is just my solution, if you have an even better one, then please feel free to let me know.

UPDATE : Having spoken on Twitter with the creator of CoffeeScript, @jashkenas, I learnt that rather than using –bare to expose my classes to the Global scope, its better just to expose the interface by declaring them using the browser ‘window’ object. Like this;

class window.MyClass

  say_hello: () ->
    alert 'hello'

This would still be referable in javascript as simply ‘MyClass’, much better!

Posted in Uncategorized | Leave a comment

First jQuery extension method, in CoffeeScript!

I have never been one to write extension methods in jQuery, I suppose that’s because I have not written anything that hasn’t already been done already or it’s just not useful!

I have been getting in to using CoffeeScript recently and having written a quick extension for Radiant to allow its use, and also integrating the wonderful Ace editor I decided to do a quick post just to show how effective it can be. CoffeeScript is mark down for Javascript, two advantages to using it;

It reduces the overall amount of code you have to write,
it increases the consistency of the resulting javascript code although there is still an onus on the author to keep things tidy.

I wanted to write a small extension method to find divs with a certain class, date parse the content of the div, change the content to just the day and then apply a style based on the month.

Here is the CoffeeScript;

# jQuery function to change a div with a date in it in to a calendar
jQuery.fn.calendarify = () ->
  month_names = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec']

  for cal_span in this
    do (cal_span) ->
      if !$(cal_span).hasClass 'mini-calendar'

        # assign generic calendar css class to span
        $(cal_span).addClass 'mini-calendar'

        date = new Date cal_span.innerText
        month = date.getMonth()
        day = date.getDate()

        $(cal_span).addClass month_names[month]
        cal_span.innerText = day</pre></code>

And now for the generated javascript;

jQuery.fn.calendarify = function() {
    var cal_span, month_names, _i, _len, _results;
    month_names = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'];
    _results = [];
    for (_i = 0, _len = this.length; _i < _len; _i++) {
      cal_span = this[_i];
      _results.push((function(cal_span) {
        var date, day, month;
        if (!$(cal_span).hasClass('mini-calendar')) {
          $(cal_span).addClass('mini-calendar');
          date = new Date(cal_span.innerText);
          month = date.getMonth();
          day = date.getDate();
          $(cal_span).addClass(month_names[month]);
          return cal_span.innerText = day;
        }
      })(cal_span));
    }
    return _results;
  };

I certainly prefer the former, obviously there is the occasional problem that markdown languages present but even then you can fallback and place normal javascript blocks inline with your coffeescript.

CoffeeScript lives here.

Posted in Uncategorized | Leave a comment

Database backed DNS server in Ruby

Wether you want to be able to register silly domain names like check.out.this.silly.domain.iamhigham.com or you wish to create domain entries programmatically, the following handy piece of Ruby is for you.

One of the reasons I enjoy using Ruby so much is the wider community’s passion for creating just about anything in this awesome language, for example RubyDNS by OrionTransfer. Looking at the example on the aforementioned link you can see a a fully daemonised DNS server which can resolve anything you can throw at it.

It doesn’t take a total genius (me!) to then integrate a very simple collection queried from MongoDB using the “mongo” gem and add a few more “transaction.respond!” statements…

db = Connection.new.db('dnsstore')
entries = db.collection('dnsentries')

entries.find().each do |entry|
    puts "Matching entry #{entry['domain']}"

    match(entry["domain"], :A) do |transaction|
        transaction.respond!(entry["host"])
    end
end

Add this to the code on the examples page to form a DNS server that loads records from a database on start-up!

Add an entry to my servers IP tables for UDP:53 and were done. All I need to do now is wait for my registrar to register ns1.tactusworks.com as a name server! Let me check…. nope, nothing :-(

Go ahead though, try it, open up bash, run nslookup tell it which nameserver to use;

server www.tactusworks.com

and then just type in a domain to check, any old domain name is from my datacenter’s DNS server and dev.rackableapps.com is from the Ruby DNS server!

Posted in Uncategorized | 1 Comment

Heroku: I was a little slow on the bandwagon, but I like, a lot!

Seems I have been a little slow to pick up on just how awesome Heroku is. I have been aware of it for a while but was never really bothered enough to take a proper look. Having done so, I am glad I have!

I decided to just do a quick app to host a piece of code I put in to a Radiant extension a few weeks back to make previews of image collections, photo album style. I created the application locally, committing merrily to my local Git repo and occasionally pushing to GitHub as normal, signed in to Heroku and created an application, which was too easy!

After creating the application on Heroku itself, it’s a case of installing the Heroku gem and adding Heroku as a Git remote node. All thats left is to push to Heroku, that’s it, nothing else, the application is deployed! Heroku even has a post push hook in Git to make sure it detects any new gems you may have added to your Gemfile file since your last push.

So, my original concern with Heroku, was the lack of oomph with only one Dyno (this is Heroku’s term for a web process) but actually it seems pretty good. So, go ahead and take a look at what I built in just a couple of hours, nothing amazing but given how easy this was to get up and running I can’t grumble.

http://magickmosaic.heroku.com/

Posted in Uncategorized | 1 Comment

Generate website headers using RMagick

I needed to generate some headers in a particular font for a client and rather than do the task using the GIMP I decided to write a ruby script to do it instead.

The following code creates separate images with the phrases from the array rendered in a particular font.

#!/usr/bin/ruby
require 'rubygems'
require 'rmagick'

include Magick

words = ["Cupcakes", "Prices", "Workshops", "Special Occassions", "Gallery", "Corporate", "Kind Words", "Any Questions?", "Contact"]

words.each do |x|
  canvas = Image.new(300, 40).transparent('white')
  canvas.background_color = 'white'

  gc = Draw.new

  gc.font("'/Users/danhigham/Projects/scripts/font.ttf'")
  gc.pointsize(40)
  gc.stroke("transparent")
  gc.fill("#87256F")
  gc.text_align(CenterAlign)
  gc.text_undercolor("transparent")
  gc.text(150,30, x)

  gc.draw(canvas)
  filename = x.gsub(/\s/,'_').gsub(/\?/,'')
  canvas.write("#{filename}.png")
end
Posted in Uncategorized | Leave a comment

Customising an embedded google calendar

A recent client requested a calendar she could use on her website to display events, immediately my thoughts turned to Google calendar. After creating and embedding the Google calendar in an iframe I noticed the style didn’t quite fit with the rest of the site, it looked ok but just didn’t follow suit.

I was surprised to find that adding CSS rules to the parent document didn’t work, even when adding an !important directive to each rule. The reason for this became obvious and actually two-fold;

1. The host document and the document in the iframe are completely separate. This seems an obvious statement to make but quite easy to overlook none the less.

2. The document in the iframe is on a separate domain (google.com in fact) which of course means that most browsers will block any attempt made from another domain to modify content within that document.

After trying all sorts of techniques to circumvent this issue, even proxying the content via my server I actually stumbled on a rather simple solution. Looking at the settings for a Google calendar you are given an snippet of code for embedding it in an iframe, that snippet has a URL in it which looks like this;

http://www.google.com/calendar/embed?src=p58tvijpfqoe83deo2prnd6pqg%40group.calendar.google.com&ctz=Europe/London

This is where you point your iframe to and is the location of the base document for your calendar, take this URL and grab the source (I used wget). Create a new page on your site with the markup retrieved from the aforementioned URL, there are two lines in the code that need updating and they look something like this;

<link type="text/css" rel="stylesheet" href="969ff39784188d8d017a0c60c8f2558aembedcompiled_fastui.css">

<script type="text/javascript" src="969ff39784188d8d017a0c60c8f2558aembedcompiled__en_gb.js"></script>

As you can see, both tags contain relative urls, they need prefixing with “https://www.google.com/calendar/” so they look like this;

<link type="text/css" rel="stylesheet" href="https://www.google.com/calendar/969ff39784188d8d017a0c60c8f2558aembedcompiled_fastui.css">

<script type="text/javascript" src="https://www.google.com/calendar/969ff39784188d8d017a0c60c8f2558aembedcompiled__en_gb.js"></script>

Now you are able to point your iframe to the new page on YOUR domain and not Google’s, add custom CSS declarations to the new document to override elements in the Google calendar.. job done!

One of the changes this has allowed me to make is the ability to wrap the title of a calendar item in the month view, a feature that has been requested to Google by a lot of people!

Posted in Uncategorized | 21 Comments