A simple app to monitor Google Chrome on OS X

I was on-site with Vigill one day before Christmas and I mentioned to Oisin an idea I had for an app.

I was sick of having endless tabs open in Chrome, hogging memory, each one some seeming important enough at the time that I read it but now just a contextless enigma.

If I at least knew how many tabs I had open, it would be a step in the right direction I thought. There’s got to be an app for that, right? Not that I could see. Opportunity knocks.

Enter AppleScript

I knew that AppleScript would likely give me the functionality I was after so that night in the hotel I installed the Ruby version of the easier to use though now abandoned AppScript and was eventually able to get some details out of a running instance of Chrome concerning it’s open tabs.

Over the Christmas holidays I spent an evening playing with the NSAppleScript class and figuring out how to add an item into the OS X status bar. Huzzah!

Give it a name

Naming things and cache invalidation, 2 notoriously hard things. Inspiration soon struck though and I stumbled upon a catchy name for the app which corresponded to an available dot com domain. I didn’t register it straight away but later in a moment of entusiasm I whipped out a card card and starting piecing together a single page site with Bootstrap to give the app somewhere to live online.

Oisin and myself have been using Bootstrap a lot these last few months as we’ve been building out the Vigill platform and it’s truely a godsend for those of use with the natural tendency to produce apps which look like they’ve been designed by a programmer. I recommended it highly.

The Future

To date the app doesn’t do much, it sits in you status bar, displaying the number of open tabs in Chrome. You can click on the number and choose to quit the app. Fits a need but it’s nothing fancy.

Suggestions have included to show how long the oldest tab has been open, how much memory is being used and even an idea to apply some gamification and have an online leaderboard of tab fetishists.

As with all my personal projects I never know if I’ll ever come back to them after the initial buzz of motivation has passed. In the early days of this blog, nearly 6 years ago now, I was hacking on desktop apps and I can feel myself being drawn back to the world of compilers and executables so chances are good I’ll revisit this app in order to sharpen my skills with Objective-C and Cocoa. Suggestions on a postcard please.

Get It

The app is available to download from chromitor.com and the code is available on GitHub, hopefully you’ll find it useful.

My also-ran Markdown Editor for OS X

Quite often I feel the need to learn something new for the sake of learning something new. Covey aficionados would know this as sharpening the saw.

I usually struggle deciding upon something however as there are so many areas to choose from in the software world and it isn’t everyday I feel drawn enough to something to put time and effort into it on top of holding down a day job.

Five years ago it was Rails, two years ago it was testing that I wanted to improve my skills with and I’m now waiting on whatever will be the next major piece of technology or practice I feel I need to push myself towards.

Before the web

When I started out teaching myself to write code I didn’t have access to the Internet and the web as we know it didn’t exist. My output was to evolve from simple CLI programs to games to desktop apps.

These past years a lot of my work life has involved developing web software with scripting languages. Compilers, graphics routines and assembly language have all started to become lost in the mists of time.

Returning to desktop software development seemed like both an interesting challenge and a break from dealing with the web. As I’ve little interest in cross-platform toolkits this meant Objective-C and Cocoa, technologies which I pick up every once in a while but haven’t produced much with. But what exactly to develop?

Eating my own dog food

In May I was working on-site with a client in Dublin and had to produce some documentation for the analytics platform I was building at the time. As usual I chose Markdown and put up with the workflow of editing the content in Vi and running it through the supplied Perl script to see what the HTML, which was eventually to handed over to the client, looked like.

It struck me that here was repeated effort I could automate with software and there didn’t appear to be a widespread, simple Markdown editor for OS X. An opportunity at last to start work on a first offering from my software company I thought.

The possible beginnings of a product-based business

Over the course of a few months I added a bit of code here and an interface tweak there, mostly while staying in hotel rooms in Dublin. Any time I wanted to edit some Markdown I used the app and it suited my purposes fine.

I toyed with the idea of publishing what I had on the Mac App Store. I shared the binary with a couple of people to see what they made of it and was extremely pleased when one asked if it was ok to pass the app on. I could see a possible path opening before me allowing me to start stepping away from a consultancy business model to one centred on selling products.

Beaten to it

Life moved on though, I started a new contract which gave me a lot of new technology to play with and development of this side project was put on hold.

About a month ago I spotted Mou. Not only was it more complete than my effort but it was better designed than I could hope for considering the limitations on my time and Cocoa experience. “Fair play” I thought, I wasn’t quick or decisive enough and as a result, if I’m to build this planned business it will have to be on the back of a different product.

Today I spotted Marked and a quick search turns up a number of other apps and text-editor plugins. Such is life.

Open source

As of today it’s been over 3 months since the last commit to the repo and many superior alternatives exist so I thought I may as well give it away.

The app suits my needs though it would be even better if it could saving/load files from the local filesystem. I may well tinker with it for my own learning purposes but who knows what side-project my interests will wander to next.

The code is available on Github and compiles with Xcode 4.1. Enjoy.

An iOS client for my UK inflation app

After last week’s great Xcake meet I felt a fresh surge to take on new challenges and bend some less-familiar pieces of technology to my will.


The first product of this enthusiasm was a prototype web app built to get a bit more experience with Python and Google App Engine. A few days later it got an API.

The resulting rapid feedback loop led me to pick up my copy of Beginning iPhone Development which had been sitting gathering dust for the last couple of years and get stuck back into following the examples.

Revisting Cocoa

I first dabbled with developing for Cocoa when I first started using a Mac and managed a range of “Hello World” apps, simple calculators and embedded WebKit views, but nothing substantial came of it. Thankfully a few of the concepts seemed to have stuck and after working through the first few chapters of the book again I felt confident enough to get started on something of my own and an iOS client for ukinflation.appspot.com seemed a logical choice.

This is the result:
UK Inflation App - Screenshot

What I Learnt

Even though this is a trivial app there have been a few aspects which have been useful from a learning perspective:

  • accessing an external API
  • decoding JSON
  • local data persistence with a plist file
  • interacting with view elements

These are all things which could make for useful reference material in the future.

Moving on

I’m not part of the paid iOS developer program at this time so I haven’t been able to test the app on actual hardware, which would have been nice. I may stump up the 99 bucks to get my hands on Xcode 4 and have the ability to run my code on a device. I may decide to have a crack at developing a desktop Mac app. Who knows.

The topic of push notifications was mentioned at the last Xcake so there’s another potential area of investigation involving both server and client technologies.

Stay tuned!

Keeping an eye on UK inflation with Google App Engine

For a long time now whenever I’m on the search for something interesting to work on that could potentially be of value to myself and others my attention is brought to topics like machine learning, data mining and natural language processing.

These are all areas within computer science which are not particularly easy and have a higher barrier of entry compared to building a typical web application for instance. Yet, if implemented correctly they can provide great insight and fame and fortune are bound to be near.

Joking aside. I studied artificial intelligence at university and my undergraduate dissertation was focussed on expert systems so I’ve a bit of exposure to these topics but nothing decidedly practical nor within the past decade.

Interesting Books

Some searching on Amazon turned up a couple of books which looked to be talking about the type of tasks I was interested in performing.

One thing these books have in common is that they use code examples in Python.

For nearly half a decade now a lot of my interest has been with Ruby and related technologies and so I’ve largely avoided Python considering the similarity of the space the two languages sit in. A look through the most popular AI books revealed none using examples written in Ruby however.

The other day I came across a copy of another book using Python so I thought I may as well get a bit of hands on experience with the language and take it from there.

Something Practical

In the past I’ve tried to teach myself many languages from books but it has never been until I’ve needed to use the language for something practical that the know-how stuck.

Thankfully I didn’t have to wait long until inspiration struck. As a private investor in the current economic climate, a topic that has been in my mind has been the rate of inflation. Every time I want to check how quickly my assets are being eroded by inflation I have to unleash Google and hope I land on the correct page and from there find the current rate amongst all the other information. This seemed like the perfect fit for yet another single serving web app.

My starting point was to write a Python script to scrape the Office for National Statistics for the current value for the Retail Price Index.

Next up was creating a basic web-app with App Engine. I’d tinkering with App Engine a bit previously so it was relatively straight-forward to follow the tutorials and piece together a single page app. Slightly more complicated was reading up on the Datastore and Memcache APIs but there were plenty of examples to follow.


The end result is ukinflation.appspot.com. It’s basic but deals with the job at hand. It’s also been a good introduction to various components of the App Engine environment: Datastore, Memcache, Cron, templates and the built-in webapp framework.

I’ve used in all of these types of technologies in other forms over the years and it’s amazing that you get so much functionality out of the box and as long as you embrace the constraints, scaling out comes for free.

I’ve still to make my mind up about Python though, maybe I’m just too accustomed to Ruby. Still, I’m glad to have another tool in the toolbox and to not be restricted to any one set of tech.

Share the Love

As always the code is available on GitHub, fork away!

A minimal Rack app to lookup your external IP address

I think I first heard the term “Rack-app” when I started using Heroku to host a couple of projects. I didn’t know an awful lot about Rack but I did know that it helped a great deal when it came to getting my Rails and Sinatra apps off my workstation and onto the web.

Tonight I thought I’d have another quick look at how it works, what it takes to build a Rack-app and what information about the request is available to the handler.

The result was the following, an object which responds to call and returns a HTTP response code, headers and a body:

ip = lambda do |env| 
  [200, {"Content-Type" => "text/plain"}, [env["REMOTE_ADDR"]]]
run ip

I have this running on ip.stevenwilkin.com and it provides the same useful function as whatismyip.com but without the ads :)

The code is available on GitHub as always.

Backing up Delicious bookmarks to CouchDB

Last year I started researching how CouchDB could be used for the BodyGuard web-app QA platform. Unfortunately I had to put my tinkerings to one side when some extra freelance work came in; contracting during the day and freelancing in the evenings quickly put an end to any spare time and my fitness efforts took a hit but I was only self-employed for a short while and it seemed the thing to do.

Since the urgency of the freelance work died down I’ve been looking for a small project to help me get back up to speed with Couch again and when the rumours of Delicious being shutdown surfaced I saw the opportunity.

The code is quite simple but it served to refresh my memory and has an actual practical aspect which is a bonus :) It’s available on GitHub as usual and the instructions below should get you up and running.


  • a pre-Yahoo Delicious account (they use HTTP Basic Auth for authentication)
  • CouchDB running on port 5984 on your local machine, I recommend the binary distributions from CouchOne
  • nokogiri and couchrest gems must be installed:
    sudo gem install nokogiri couchrest

Clone the code from GitHub

git clone https://github.com/stevenwilkin/delicious-couch
cd delicious-couch

Run the import script to fetch your saved bookmarks

USER=username PASS=password ./import.rb

Substitute your Delicious username and password on the command line

Create the design document


Querying the data

Now that the database had been populated and the views created, the contents can be queried

View all urls


View all tags along with their count


View all urls with a specific tag

./urls_by_tag.rb git

Views all bookmarks tagged with “git”

This set of scripts is only scraping the surface of what is possible with CouchDB but it demonstrates the immense power of MapReduce along with the basics of interacting with CouchDB using Ruby. Clone the code and enjoy!

Minder – a simple web-app monitoring tool written in Ruby


A few months ago I was tasked with migrating and maintaining a bunch of legacy Rails apps and a couple of them were misbehaving. Requests were hanging which was tying-up the front-end Apache child processes and resulting in all the web-apps on the server becoming unresponsive

At the time I didn’t know what was causing the hanging requests, it wasn’t happening in a predictable manner and on the surface I had all the apps dependencies in place.

Seeing as this was a job I was doing on the side I had very limited time to investigate the underlying issue and decided I would have to make do with just knowing when the apps went down so I could ssh in and manually kill off the offending processes.

My initial thought was to use Nagios for monitoring but it seemed excessively heavy-weight for the task at hand so I seized the opportunity to quickly develop a tool perfectly tailored to my needs.

The resulting script, minder, checks a list of domains and if the root of each can’t be read within 10 seconds a notication is sent via XMPP. Nothing more, nothing less. Simple.

Minder proved effective and I was bombarded with instant messages whenever any of the apps went under. Thankfully I found to bit more time to investigate more thoroughly and tracked the issue down to a missing TrueType font used by ImageMagick.

The first iteration of minder was very simple but I thought I’d put a bit of extra effort in to make it easier to customise and share it with the internet-at-large, hopefully someone will get some use out of it.


  • Two XMPP accounts:

    • one to send notifications from, and
    • a second to receive notifications

    Google Talk or any regular Jabber/XMPP accounts will suffice

  • Blaine‘s xmpp4r-simple gem must be installed:

    sudo gem install xmpp4r-simple


  • copy minder.yaml.sample to minder.yaml
  • edit minder.yaml to specify the username and password of the sending XMPP account
  • specify your own personal XMPP account (xmpp_to)
  • modify the list of domains to monitor
  • run the script
    $ ./minder.rb
  • Optionally run the script from a Cron job, the following will run every hour:

    0 * * * * /path/to/minder.rb > /dev/null 2>&1

Get the code

Clone the repo from GitHub. Fire any queries to @stevebiscuit.

Is it raining in Belfast? Redux

Last year I created a nano-app which attempted to answer the question, is it raining in Belfast?

I was never completely pleased with it but the objective was to get something done and get it done fast, which was achieved.

This weekend I’ve been tinkering with another project and hit a bit of a stumbling block getting various pieces of software to co-exist.

I decided a break from the problem would be beneficial but I still wanted to have some sense of achievement from the weekend and redeveloping this app seemed a good idea.

Some quick research showed that the Yahoo! weather report for Belfast could provide the necessary information so I hacked up an RSS processing script and converted the old PHP front-end to a quick and simple Sinatra app.

The app now operates as originally envisioned: it answers the question with a straightforward yes or no. Hopefully it will be accurate as well :)

The app is hosted at isitraininginbelfast.com and the code is on GitHub

An experimental lifestream app

Some time ago DW and myself had an enthusiastic conversation about logging various aspects of our electronic lives: emails sent and received, RSS feeds read, incoming and outgoing phone calls, the list goes on.

At that time I’d already started tinkering with apps to track my efforts in the gym and changes in my bodyweight, I’ve used notebooks for this for years and thought it’d be interesting to have this information in electronic form.

Sharpening skills

While I was on the bench waiting for my current contract to start I was sharpening my skills through developing some small projects with the technologies I’d be using. One of those technologies was SQLite which I knew of but didn’t have much hands on experience with.

I started by playing with the Ruby interface to SQLite, using it to insert and retrieve data from a simple database. I’ve since grown to love the simplicity and flexibility of SQLite and will no doubt use it again in the future.

I needed a practical application and thought back to my intentions to track my online activities. Now was as good a time as any to to tick this off the list of potential projects.

When I’d glued together some Ruby to parse the RSS feed of this blog I knew the basics were in place so I started on a simple Sinatra app to act as a web interface.

Stumbling block

I scoured the web for design inspiration and got a good start to the visual aspect of this project but couldn’t make my mind up over a few subtle items. Next thing my agent called: the purchase order finally came through and my contract was to start the next day.

The demands of adjusting to a new work environment meant I felt little motivation to work on anything on my own time and I became more interested in funneling my excess income into the stockmarket. The project joined those other half-finished unfortunates.

A fresh jolt of motivation

After a couple of months on the contract I started feeling a renewed motivation to get something of my own out there. I couldn’t bare the thought of starting another project to not finish it so I set out to to whip this latest app into shape and release it as soon as possible and no later.

I dug through the uncommited changes in my working copy and made some arbitrary decisions which resulted in a design I felt was “good enough.” I modified my RSS parsing script to feed into SQLite and extended it to process my Delicious bookmarks and loved tracks on Last.fm. I created pagination links, wrote a README and sorted out the hosting and cron jobs. Bingo.

Check it out

My original intention was to track much more of my online life and there’s some details I’d like to change but I love releasing code and I’m pleased with this first iteration.

The app is hosted at life.stevenwilkin.com and the code is available on GitHub, I hope you like it.

Rails 3 Hello World

The past while I’ve been busy providing technical consultancy to BT and haven’t had much drive to work on anything on my own time. The itch has returned the past couple of weeks though so I thought I’d see what I’ve been missing in the Rails world and in what better way than getting a basic Rails 3 app up and running.

My environment was already setup for Rails 2.3.* and Yehuda Katz’ post served as a guide to get me up to speed with the beta loveliness.

RubyGems 1.3.7 along with Thor and Bundler gems required

My installed version of RubyGems was a couple of point releases behind, so I updated that and installed the necessary gems

sudo gem update --system
sudo gem install thor bundler

Clone Edge Rails from GitHub

mkdir -p ~/code/rails/rails
git clone http://github.com/rails/rails.git ~/code/rails/rails

Generate a fresh app and install dependencies with Bundler

mkdir ~/code/rails/rails-3-demo
cd !$
ruby ~/code/rails/rails/bin/rails new . --dev
bundle install

Launch the web server

./script/rails server

Browse to and you’re done!