skip main content

Archive for April, 2009

Controlling the spotlights at work with Sinatra and OSC

posted by Duncan at 8:47 pm on April 24th, 2009

Nic bought some spotlights the other week for work, so we could hook them up to our continuous integration server, and they would let us know using the medium of colour, when things had failed!

Before we did that, I thought I’d have a little play. Tristan and Chris having been building a fun new game (Read more via the Radio Labs blog soon) which uses nowplaying data from BBC 6 Music to power it. Knowing when a track is starting and ending is also useful, so as a bit of fun, I wrote a little Ruby script that made the spotlights behave like traffic lights:

  1. Green – when a track started playing
  2. Flashing Amber – when a track was about to finish
  3. Red – when the track finally finished

spotlightPhoto by Tristan

To control the lights we’re using ROSC open sound control for Ruby. It’s very good, but required building to install, and the interface is nice, but not simple enough if all you’re doing is turning a light on or off and changing it’s colour. So in order to make the script even more simple, I thought I’d write a little http proxy so that your could control the lights by just going to a url. It meant even the non-programmers could have fun replicating disco lighting. The urls look like this:

http://spotlights.local/all/green
http://spotlights.local/all/rgb120-12-200
http://spotlights.local/all/off
http://spotlights.local/all/random

The proxy is written using Sinatra. I love Sinatra. If you thought prototyping was simple with Rails, well with Sinatra + Passenger it takes simplicity to a whole new level.

You can download the lightcontroller source from Github as normal, you’ll have to tweak a few settings for your needs. You may even find it a useful template for controlling something else.

RevCanonical 1.2, Customise your link tag plus a little more

posted by Duncan at 10:33 am on April 23rd, 2009

I’ve made a few updates to the RevCanonical WordPress plugin I built. These updates add a bit of extra functionality, and also allowed me to tidy up the documentation, so that people know what they’re getting.

First update, is the ability to customise how the link tag is constructed within the head of your page. This is due to the large amount of people who have contacted me, asking why I choose to use rev=canonical and not rel= shorturl, rel=shorturl or rel=short_url etc. As I told them, the reason I chose rev=canonical was to be honest simply because I liked it, and many of my peers were already using this method on their sites. Simple.

So currently with the plugin you get this out of the box:

<link rev="canonical" type="text/html"  href="http://your-domain.com/p12p" />

but you could customise it to be like this:

<link rel="shorturl" href="http://y-doma.in/p12p" />

The reason for this extra customisation is to try and stop people being distracted by the what attribute should I use conversation, and start getting them hosting their own short links they can use. This at least starts solving one problem. When a general consensus, or in deed a standard appears about the attributes, you can simple update and you’re good-to-go.

At the moment the only place you can see the shortened url is either by looking in the source, or using a bookmarklet like the one Simon wrote. I guess I could of injected the url into the admin interface somewhere, but I generally don’t want to see it. The idea is, it’s there for machines to see if they need to, and if I really need to pass it around I’ll just use the bookmarklet.

If you want more flexibility, I have added a of a couple of tags you can use in your templates. These simply let you display the shortened url for a specific post.

# echo the shortened url to the screen
<?php get_revcanonical_shorturl($post_id); ?>
 
# assign the shortened url to a variable
<?php $url = revcanonical_shorturl($post_id); ?>

Oh and finally, just a reminder that this plugin plays well with the TweetMe plugin I wrote that tweets to Twitter.com when you publish a post, and will check to see if you have the RevCanonical plugin installed. If you do, it will use your own shortened url instead of the bit.ly version.

Revcanonical, a rev=canonical WordPress plugin

posted by Duncan at 11:06 am on April 14th, 2009

UPDATE [15:06 April 14th 2009]

Revcanonical is a WordPress plugin that creates localised shortened urls, and adds support for the rev=canonical link tag.

Revcanonical came about after seeing a post on Mr Willison’s website a few days ago. I’d seen mutterings around the web from Joshua Schachter, Dave Winer and Chris Shiflett about how url shortening services are not great for the web for amongst many reasons, the persistence of the link becomes questionable, because you are relying on that service actually being around in 20 years.

It seems that clever people have taken the conversation further and have actually started to come up with possible solutions. One such solution is rev= canonical, and is the one I liked and hence wanted to implement into my site. In fact, some of the big players have already added rev=canonical to their sites. Flickr, Dopplr and php.net already have pages that use it and there’s even a rev= canonical web service. That’s millions of pages already out there.

By default, once you install the plugin to your WordPress blog, you will get a tag added to the source of your page that will contain a shortened version of the url for the page it sits in.

<link rev="canonical" type="text/html" href="http://whomwah.com/p12p" />

That’s it! You can now, not only use this url in sites like Twitter without having to go via a url shortening service, but services or people that understand the rev=canonical link tag, will be able to use this shortened version over the longer canonical version. For example, Simon has build a great bookmarklet that does just this. You can use it when you are on a url you’d like to share. It will return the shortened version of the url if it’s available, otherwise it will use a shortening service as a last resort. This means that if I go to this page:

http://whomwah.com/2009/04/14/revcanonical-a-revcanonical-wordpress-plugin

And I want to share this link on Twitter for example. The bookmarklet would see I have implemented rev=canonical and would fetch the shortened url.

http://whomwah.com/p136

In fact, you would in reality get this:

http://littl.me/p136

as the plugin allows you to add your own shortened domain (and I bought one). It’s up to you though point this new domain to the right place.

So, this means that I still get a short url to share, that works on my website, but also means that it’s persistence is down to me, and not to a 3rd party. It also means that if people to http://littl.me, it redirects to my website, so hopefully there’s a little more trust in the shortened url final destination.

Some final tech bits. It uses a base36 encoded post ID (made sense and was simple to implement) in the shortened url with the letter p to namespace. It also creates a 301 as the general consensus agreed.

Oh and if you use the TweetMe plugin I wrote then I’m just in the process of deploying a new version that will use your localised shortened link if it’s available.

[UPDATE] I’m getting lots of people asking why I went for rev=canonical and not rel=shortlink etc. The truth is no particular reason, other than more people I knew and trusted have gone for the former. There appears to be no definitive correct way yet as far as I can see, so until there is I’ll have to make an executive choice.

Using Cocoa to keep an app window always on top

posted by Duncan at 4:39 pm on April 11th, 2009

Sometimes you want your application to keep one of it’s windows always-on-top. A chat application like Adium for example, allows you to keep your conversation window always-on-top so you can follow the conversation whilst still using other applications. In the TellyBox application I wrote, this functionality is also very useful, as you can watch tv whilst still working in other applications.

So the basic implementation was fairly simple. You just use the windowDidResignMain notification, and then re-set the window level a more fitting one. Below I have also wrapped around a preference setting:

- (void)windowDidResignMain:(NSNotification *)notification
{
  // It's always nicer if the user has a choice
  if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultAlwaysOnTop"] == YES) {
    [[self window] setLevel:NSFloatingWindowLevel];
  } else {
    [[self window] setLevel:NSNormalWindowLevel];
  }
}

My TellyBox application allows you to go fullscreen via the existing Flash application embedded in a webkit view. Using just the basic implementation meant that when going into fullscreen mode the frame of the original window remained in view. To fix this I added this extra bit of code, which gets used via the firing of another useful notification windowDidBecomeMain :

- (void)windowDidBecomeMain:(NSNotification *)notification
{
  [[self window] setLevel:NSNormalWindowLevel];
}

which sets the window level back to it’s default value of 0 when it becomes the main window i.e when you select it.

I hope this little snippet helps people trying to achieve the same effect in their apps.

Lookup – A simple Mac utility that wraps ldapsearch

posted by Duncan at 11:53 am on April 7th, 2009

I work on a Mac at work, and it has always been a bit slow searching for other staff members in our global address book. Like other big organisations we have some directory services which we can use LDAP to interrogate. The seemingly standard way for apps to poll these services is asynchronously every second or so, so that you’re getting results back quickly in the background. In reality this can be clunky if your network is slow, or the directory is very big.

I wanted something simpler, and a gui that gave me was suited to my work requirements. Lookup displays glance-able contact details straight away, letting you copy, paste and drag this data around. It also has simple shortcuts like double clicking the contact to start a new email to that person.

Lookup does not poll asynchronously, it does one request per search and just looks through some key attributes. It seems to work very well, and has been customised for my workplace, but is generic enough for someone to tweak it to suit their companies needs.

Lookup

It wraps ldapsearch, which is a command line app that comes free on your mac. When I say wraps, it’s not a complete wrapper, but wraps enough to create an app of this kind. Ldapsearch app did everything I wanted in search terms, and gave me a chance to use NSTask and NSPipe which I know will be useful in the future.

You can get the source over at Github. Why not try and tweak it to work for your company. You never know, just compiling it and updating the settings in the preferences menu may be enough.

Just to be clear, this app does NOT give you access to the BBC address book, just incase you thought I’d gone mad.

expires_in Rails FileStore fragment caching in about 6 lines

posted by Duncan at 2:32 pm on April 3rd, 2009

I have been building a Rails app that creates RSS feeds based on a lot of screen scraping behind the scenes. I really needed a way to cache the data object that feeds those specific pages. In rails you can do page, action and fragment caching, using many different methods, and storing that cache data in many different locations.

After deciding I needed Fragment caching, it turns out that if you need your cache data to magically expire over time, you need to be using memcached (I couldn’t), other wise you have to roll you own solution, based on cache sweeping, or in-code testing of whether your content has expired.

I’m using FileStore for caching (cached files live on the file system) and I have no database, and all the feed data comes from external feeds that change over time, so unless I fetch it all again, I don’t know.

What I needed was the ability to have a expires_in parameter whilst using FileStore. So this is what the code below does in surprisingly few lines. The code is an amalgamation of many posts I found doing almost the same thing, but this is what works for me.

First we extend FileStore:

# stick this in a file somewhere in your path e.g lib/fs_extend.rb
class ActiveSupport::Cache::FileStore
  def read(name, options = nil) 
    ttl = 0
    ttl = options[:expires_in] if options.is_a?(Hash) && 
                                         options.has_key?(:expires_in)
    fn = real_file_path(name)
 
    return if ttl > 0 && File.exists?(fn) && (File.mtime(fn) < (Time.now - ttl))
    File.open(fn, 'rb') { |f| Marshal.load(f) } rescue nil
  end
end

And then in your controller I have:

class FooController < ApplicationController 
  def do_stuff
    key = 'someuniquekey'
    expire_fragment(key) unless 
        @data = read_fragment(key, :expires_in => 1.hour) || 
                                  write_fragment(key, some_complex_data)
 
    respond_to do |format|
      format.xml
    end 
  end
end

This has reduced many 5 second requests to 32ms requests, so hurrah!


back to the top