Fred Kelly

I occasionally write things.

Dec 27, 2012

This Christmas I was lucky enough to be given a Nike+ FuelBand by Alice.

My shiney Nike+ FuelBand

If you're not familiar with the FuelBand, the basic idea is to track your movement throughout the day, and collect 'Fuel' (Nike's own internal currency). You can compete with your friends to see who can collect the most etc (points can also be collected via other means such as the Nike+ running app for iOS).

Nike+ Dashboard

Hacking it!

So having played with the FuelBand for a few hours, I stumbled across this:

Based on the findings of Tom Pohl in this video I was able to put together some simple Ruby code (with the aid of HTTParty):

I've also posted the required accompanying files in this repository (also to store any future development).

To get it working you'll need a config.yml file with the following:

In order to get hold of these values you'll need to sniff the traffic between the FuelBand app and api.nike.com. To do this I used an intercepting Proxy on my Mac (try Burp Suite).

Once you've got everything in place you should be good to go. You can pull out ALL THE DATA :) as well as some nice summary stuff:

I can haz data

As this site currently runs on PHP, I also whipped up the same code in PHP using cURL:

Please feel free to fork and work on this, there are a ton of different method calls that I'm yet to include (see the video ^^).

Oct 28, 2012

Hack Manchester is a 24 hour coding event held at the Museum of Science & Industry (MOSI) in the heart of Manchester.

Getting setup at Hack Manchester

The event gave myself and @dannyprout the perfect opportunity to develop an idea we'd been batting around for a while. The plan was to create an app that would hook into GitHub and allow users to get valuable peer reviews on their coding style etc. The idea sprouted from seeing how Facebook's own Phabricator project allows developers to 'ok' each other's code before pushing live.

We build the app using a basic Rails/PostgreSQL backend. I mainly worked on setting up the oauth connection with Github and building out the design and basic functionality. Meanwhile Dan concentrated on the mamouth task of parsing code into 'Snippets' (individual functions/methods) which would be easily digestible for reivewing.

Dispite hitting a serious sleep deprivation wall around 5am, we managed to build a pretty decent working prototype:

Brogram, the early prototype

Introducing Brogram!

So I've had the domain http://brogr.am/ for a while since finding this hilarious Quora article and kinda becoming a self-proclaimed Brogrammer.

As you can see the UI is dead simple, you login via GitHub, pick from a list of you repositories and hit submit. From there, our application parses each of the files contained within your repo and creates 'Snippets' each containing independent logical blocks (well, that's the idea). From there users can review each of these codes earning themselves credit, which they can then in turn use to get their code reviewed. The end product gives you an overview of your project and which areas need most attention etc.

Future expansion

Although we managed to get a basic working version running. We still have a ton to do:

  • Push everything live to Heroku
  • Improve the parsing, add other common languages
  • ML elements: learn which users give the best reviews for language X, i.e. work who has pushed most code in C or Java, and rate their reviews for those languages accordingly.
  • Better sharing of snippets, short urls etc.
  • More review options, per-line commenting, flags, highlighting etc.

Wrap up…

Overall I'm pretty pleased with what we managed to achieve (in about 12 hours - Dan tapped out around 5am!). I think the idea has quite a bit of scope and would definitely like to take it a bit further and implement a couple of the ideas above.

Happy Hacking :)

Aug 24, 2012

So I made a Gem. Recently I've been working on a couple of Rails apps in which I have needed to add Open Graph meta tags in order to map objects within my app onto Facebook's social graph. This is done by simply adding <meta> tags to your document defining specific properties such as title, image, date etc. Here is an example taken from Facebook's tutorial:

<meta property="fb:app_id" content="[YOUR_APP_ID]" /> 
<meta property="og:type" content="[YOUR_APP_NAMESPACE]:recipe" /> 
<meta property="og:title" content="Stuffed Cookies" /> 
<meta property="og:image" content="http://fbwerks.com:8000/zhen/cookie.jpg" /> 
<meta property="og:description" content="The Turducken of Cookies" /> 
<meta property="og:url" content="http://fbwerks.com:8000/zhen/cookie.html">

This is quite a simple example, there are many more options for custom properties and object types, each requiring specific property names, some in the og and fb namespaces, some in your app's custom namespace. There are also different data types: strings, integers, arrays etc. I played with a few Gems including meta-tags and acts_as_opengraph, both offer useful helpers to make the job of adding these meta tags easier. After trying different combinations I was still findinig it hard to find a tidy way to map attributes straight from my models to meta tags in my RESTful views.

Enter acts_as_graph_object

My first venture into the Gem world, the gem is intended to allow such model to view mappings to be super easy.

I started the project with the following goals:

1. Find a way to provide model URLs using the url_for view/controller helpers.

2. Map common attribute names to og meta tags (e.g. title, description, image etc).

3. Provide helpers that allow resulting meta tags to be easily added to global layout in a standar Rails REST architecture. i.e. for all /show actions, add meta tags to head if object has open graph attributes.

4. Allow for easy configuration for constants such as fb:app_id & fb:admins as well as an app namespace to be used in og:type and any custom attributes.

5. Automatically handle arrays, i.e. :cast => ['Tom Cruise', 'Kelly McGillis', 'Val Kilmer'] becomes:

<meta property="my-app:cast" content="Tom Cruise" />
<meta property="my-app:cast" content="Kelly McGillis" />
<meta property="my-app:cast" content="Val Kilmer" />

6. Keep it unobtrusive! no heavy configuration in models, something simple, e.g.

class Movie < ActiveRecord::Base
  acts_as_graph_object :custom => [:director, :writer, :cast]
end

This would map all standard properties title, description, image, app_id etc along with the custom properties director, writer & cast.

7. Write proper tests and documentation!

Putting it to use..

So I recently released v0.0.9 and it's starting to look pretty much there (minus that last point :O).. Here's how to add it to your Rails app:

gem install acts_as_graph_object

Then just add the dependancy to your Gemfile.

Usage

Configuration

# app/config/initializers/acts_as_graph_object.rb
ActsAsGraphObject.configure do |config|
  config.namespace = 'my-app'
  config.app_id = 12345
  config.admins = [1245, 6789]
end

Default URL Method

In order to use the built in @model.url method you need to set the following config option:

# app/config/environments/production.rb
routes.default_url_options[:host] = 'my-app.com'

Add acts_as_graph_object...

# app/models/movie.rb
class Movie < ActiveRecord::Base
  acts_as_graph_object :custom => [:director, :writer, :cast]

  def cast
    ...
  end
end

Outputting meta tags

Use the graph_object_tags_for(@movie) helper to output the resulting <meta> tags. You can use this in combination with content_for to push the results into your <head>:

# app/views/layouts/application.html.erb    
<head>
    <%= yield :meta_tags %>
</head>

# app/views/movies/show.html.erb
<% content_for :meta_tags, graph_object_tags_for(@movie) %>

Overriding from view

If you want to override a value from the view (for example to use a url_for helper):

# app/views/movies/show.html.erb
<% content_for :meta_tags, graph_object_tags_for(@movie, :url => movie_url(@movie)) %>

Alternative attribute names (v0.0.7)

You can now use non-default names for the standard Open Graph properties and the Gem will attempt to pick these up. Here are the properties and their alternative names:

# standard object properties & alternative names
default_properties = {
  :title           => [:name, :label],
  :type            => [:kind, :group, :class],
  :image           => [:picture, :photo],
  :url             => [:permalink, :link],
  :description     => [:info, :details],
  :site_name       => [:site],
  :latitude        => [:lat],
  :longitude       => [:long],
  :street_address  => [:address],
  :locality        => [:locale, :area],
  :region          => [:province, :territory],
  :postal_code     => [:post_code, :zip_code, :zip],
  :country_name    => [:country],
  :email           => [:email_address],
  :phone_number    => [:phone],
  :fax_number      => [:fax]
}

And there you have it! Check out the code on GitHub, fix/fork/improve! :)

Nov 2, 2010

If you’re not familiar with cache busting it is basically the idea of preventing browsers from caching your site’s CSS/JS. This is normally achieved by assigning a meaningless query string to your <link> tags:

<link rel="stylesheet" type="text/css" href="mystyle.css?v=12345" />

By adding a random string, i.e. 12345 the browser is tricked into downloading a fresh copy of the file each time the page loads instead caching it.

Whilst this works, it means that the file is downloaded EVERY single time the user visits the site, removing any possible performance gained from caching.

So, instead of re-downloading the file every time the page loads why not just load it every time the file is modified? This PHP snippet lets you do just that:

<?php
  /*
   * Simple helper for linking to CSS/JS
   * Uses the files last modified date
   * to create a 'cache-busting' URL.
   */
    function link_file($path)
    {
        if (file_exists($path))
        {
            // get the file's timestamp
            $time = filemtime($path);
            // return a 'cache-busting' URL
            return $path . '?v=' . $time;
        }
    }
?>

Using the filemtime() function, this code grabs the UNIX timestamp of the file’s last modified time, and appends it as a cache-busting query-string. This can then be put to use using something like this:

<link rel="stylesheet" type="text/css" href="<?=link_file('mystyle.css')?>" />

No more wasted downloading!

Jul 7, 2010

Recently, I’ve been working on a project that features a three column ordered list in its main content area. Previously I would have probably built this as three separate <ol> tags floated left.

This solution is far from ideal as it throws up all sorts of issues: numbering, positioning, scaling etc. I wanted to be able to achieve the same effect using a single list. After a couple of minutes of Googling I found this on ALA. The solution in this article looks something like this:

<ol>
    <li class="column1">Item #1</li>
    <li class="column1">Item #2</li>
    <li class="column1">Item #3</li>
    <li class="column2 reset">Item #4</li>
    <li class="column2">Item #5</li>
    <li class="column2">Item #6</li>
    <li class="column3 reset">Item #7</li>
    <li class="column3">Item #8</li>
    <li class="column3">Item #9</li>
</ol>

This is combined with some dodgy CSS to produce the desired outcome. Not only is this pretty ugly, it’s also unscalable: if I want to add or remove items from the list I have to completely rewrite the CSS – not so good.

Tidying up with some jQuery.

As a better alternative, I set about porting this same technique into a jQuery plugin. This way all the logic calculations (margins, widths etc.) can be calculated and applied automatically, allowing unlimited expansion.

The code is mega simple, it just loops through the list applying negative margins based on how many columns you want. For example:

$(document).ready(function() {
    $('#mylist').multilists({ cols: 3 });
});

All done!