All posts by Jason Playne

About Jason Playne

I am a computer guy who originally hails from Albany. Growing up in the South West of WA was a blast but I moved to the big smoke to further my IT career after the dot com bust. These days I am a System Administrator and Senior Programmer at Titan Interactive in Osborne Park, a father of two beautiful girls (Tiana and Sophie), a Photography Enthusiast and a Musician playing First Violin at the Churchlands Community Orchestra.

Writing to the Android Log

So I just figured out how to get my log messages from a system Golang program into the android log without the need for logwrapper.

It is a side effect of importing the “app” mobile package. so…

import (
	_ ""

The downside is that *everything* written via stdout will go to the system log – even flag.Usage()

If you want to go a little more serious, here is a nice chunk of code

package main

#cgo LDFLAGS: -llog
import "C"
import "unsafe"

func writeAndroidLogInfo(tag, message string) {
	ctag := C.CString(tag)
	cstr := C.CString(message)
	C.__android_log_write(C.ANDROID_LOG_INFO, ctag, cstr)

You can use it like so

writeAndroidLogInfo("MyIdentifier", "My Message")

and the output in logcat will be

I/MyIdentifier( 4444): My Message

How To: Cross compile Golang for Android

To build for the android platform (GOOS=android) you need to do the following:

I placed all the downloads into ~/dev

  1. Get a copy of Golang >= version 1.4 from
    • Unpack it into ~/dev
  2. Grab the latest copy of the Android NDK from
    • Make it executable and run it (it unpacks into the current folder, so ~/dev)
  3. Time to get a copy of our platform NDK.
    export NDK_ROOT=~/dev/ndk-toolchain
    ./android-ndk-r10c/build/tools/ --platform=android-16 --install-dir=$NDK_ROOT
  4. Now we need to build the Golang toolchain, cd into ~/dev/go/src
    export NDK_CC=~/dev/ndk-toolchain/bin/arm-linux-androideabi-gcc
    CC_FOR_TARGET=$NDK_CC GOOS=android GOARCH=arm GOARM=7 ./make.bash
  5. Now we can cross compile
    • You can put the following into a file
    • export NDK_TOOLCHAIN=~/dev/ndk-toolchain
      export CC=$NDK_TOOLCHAIN/bin/arm-linux-androideabi-gcc
      export GOROOT=~/dev/go
      export GOPATH=`pwd`
      export GOOS=android
      export GOARCH=arm
      export GOARM=7
      export CGO_ENABLED=1
      $GO build -x main.go
    • Once you have made it executable (chmod +x you can ./ to build your app.

Cross Compile Golang on Ubuntu 14.04

So today I needed to cross compile a basic Golang app from linux/amd64 to linux/arm (for android) on my Ubuntu 14.04 box.

It is actually kinda easy

sudo apt-get install golang-go-linux-arm

because I am running the latest 1.3 golang i needed to run an extra step:

cd /usr/local/go/src/
sudo GOARCH=arm ./make.bash

Once you have that setup, it is as simple as:

you@host:~/golang/src/yourrepohost/yourrepos/repo$ GOARCH=arm go build

rails generate Could not find <gem> in any of the sources

So with my latest project I am using Rails 4.1 – this is all well and good, but here is a gotcha. there is a thing called spring that is supposed to make things faster – except when it gets in the way!

tl;dr – killall spring

So – here are the symptoms

$ rails g
Could not find bcrypt-3.1.7 in any of the sources
Run `bundle install` to install missing gems.

Now bcrypt is the only thing having the issue (other gems worked) i think this is because it has a compiled binary component to it.

The fix? Kill all the springs!

$ ps aux | grep spring
jason     8361  0.0  0.2 426464 21380 ?        Sl   Apr22   0:01 spring server | wholesale | started 22 hours ago                                                                
jason    11730  1.0  0.2 225632 22276 ?        Ssl  11:46   0:00 spring app    | wholesale | started 55 secs ago | development mode

$ kill 8361

… and now rails generate plays nicely again!

Rails, CanCan and Best In Place editing

So here is a little gotcha and solution when using CanCan and Best In Place. With the default setup, if CanCan auth fails on a best in place edit you get a redirect to your default “Auth Failed” path and that page then tries to render as javascript.

that does not work all that well!

So here is my simple solution, if we get an auth denied on a XHR request, just return a generic error!

class ApplicationController < ActionController::Base

	rescue_from CanCan::AccessDenied do |exception|
		if request.xhr?
			render :json => ['You are not authorised to do that.'], :status => :unprocessable_entity
			redirect_to '/', :alert => exception.message

has_many :through and the case of the missing include

tl;dr – you need to specify the “inverse_of” option on your has_many/belongs_to relationship to get your children fully populated

So I came across an interesting situation the other day, where my includes() statement was preloading data, but then when accessing it I would see another SQL query.

require 'active_record'

class Parent < ActiveRecord::Base
attr_accessible :name
has_many :parent_children, inverse_of: :children
has_many :children, through: :parent_children

default_scope includes(:parent_children)

class ParentChildren < ActiveRecord::Base
attr_accessible :parent_id, :child_id
belongs_to :parents, inverse_of: :parent_children
belongs_to :children

default_scope includes(:children)

class Child < ActiveRecord::Base
attr_accessible :name
has_many :parent_children
has_many :parents, through: :parent_children

Parent.all.each {|p| p.children.each {|c| puts}}

Without the :inverse_of here, each call to write the childs name will result in a new SQL query to get the data, even though this data has already been prefetched (eager loaded).

Hacking a Cisco/Linksys NSS6000

So I was given a Cisco/Linksys NSS6000 to upgrade and root.  Luckily I have was also provisioned with the instructions to root this machine.

Thanks to some hacker types that had already been and done this the process was relatively straight forward.

  1. Create User
  2. Insert USB Key
  3. Backup Configuration onto USB Key
  4. Unmount USB Key
  5. Dive into the tar ball (which is simply /etc) and:
    1. Change the root password in etc/password – I just copied my new users password!
    2. Added the following line to etc/cron.d/root
      */5 * * * * /usr/sbin/
  6. Tar the extracted files
  7. Put the tarball back on the USB drive
  8. Mount it in the NAS and Restore from backup
  9. Profit, Right!?

Well,  nearly. I had a couple of issues:

Incorrect tarball Permissions

So, my first derp was when I tar’d the etc folder back up and well… instead of root owning everything, you get the picture.

What happens is that you get an error like this:

Warning: touch(): Unable to create file /etc/nas/ran_wizard because Permission denied in /www/html/index.php on line 48

And you end up getting into a loop with dialog boxes and never ending redirects to the same page.

The down side of this is that you cannot get to any other pages in the administration to even consider doing a factory reset. Luckily you *can* post to it still

curl --data "p=admin&s=maintenance&restore_all=Restore+ALL+Settings+to+Factory+Defaults" http://admin:admin@

This command will reset the device to factory defaults – you should change the IP address and user/pass to what you need it to be. It obviously uses cURL so you will need that too 🙂

We also tried to overwrite the start of the one disk we had (using dd if=/dev/zero…) in the machine to see if that would work – but alas it did not. We were able to go through the setup wizard again, but ended back at the loop we had before.

SSH Connection Closed

The second problem I had was ssh’ing to the box. We discovered that if we used an older version of openSSH we could connect to it, but newer versions of openSSH would just not connect.

Pro Tip: Putty connects fine 🙂

To be able to connect to older dropbear’s with newer openSSH clients – try this in your ssh_config file

jason@workstation:~$ cat ~/.ssh/config 
	Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc

I hope this information saves someone a few hours of frustrations.

sprintf, floats and rounding

So I had some fun figuring out why my Spec tests were failing today.

tl;dr – do not use floats for currency (BigDecimal will sort you out in Ruby)

I was starting to question my highschool math today as I was seeing things like this:

php > echo sprintf("%0.2f\n", 1.045);


irb(main):003:0> '%0.2f' % 1.045
=> "1.04"

now for those playing at home, this needs to be 1.05 – and since both Ruby and PHP where doing the same, it pointed to an underlying library problem.

A Quick Google later and I found what I needed. 1.045 would be stored in floating point form as 1.04999999999999 – therefore – rounding would be busted.

In Ruby I am using BigDecimal to solve my problem and therefore make my spec tests pass!

Adventures with Google Content API and OAuth

So recently I have had the opportunity to play with Google’s Content API and their OAuth API.

I have needed to use it in “offline” mode, as I want to interact with Google when the authorising user is not present (cron jobs and such).

Here are my lessons learnt.

  • You can Indeed use OAuth on a website that wants to use it in the background. You just need to persistently store the tokens (especially the refresh token!)
  • The refresh token ONLY appears when the user is asked for permission. it does *not* appear when access is auto approved. This means when you generate the authorise url – you need to specify the “approval=force” option!
  • Their testing facilities are not that good, trying to sort out a sandbox site is like pulling teeth. Their account signup pages were busted 🙁
  • Their API is pretty good!

Google Content API Class

Below is a simple class stub to interact with Google. The PersistentKeyValueStore class is fairly self explanitory and you can implement your own (I persist my data in a simple table with the columns “key” and “value” with “key” being a primary key).

When implementing this class you will need

  • A user to initially interact with a web page
  • Your code to call the Google_Content_Client->doAuthorise() function so the user can interact with the OAuth page.
  • <?php
    client = new GSC_Client($options->merchantId);
    		$this->options = $options;
    		$this->authToken = new GSC_OAuth2Token(
    		$token = PersistentKeyValueStore::get(self::TOKEN_KEY);
    		if (!$token) {
    			return false;
    	 * handles the user interaction for the authorising
    	public function doAuthorise($revoke, $force = false) {
    		if ($revoke) {
    			// do we have a refresh token to revoke?
    			$bits = explode('|',PersistentKeyValueStore::get(self::TOKEN_KEY));
    			if ($bits[4]) {
    		} else {
    			$code = @$_GET['code'];
    			$approvalPrompt = $force ? 'force' : 'auto';
    			$authorizeUrl = $this->authToken->generateAuthorizeUrl($this->options->redirectUri, $approvalPrompt);
    			if ('' == $code) {
    				header("Location: $authorizeUrl");
    			} else {
    	/** your functions to wrap Google's **/