home / blog

See which packages you’ve installed Ubuntu 13.10

grep "Commandline: apt-get install" /var/log/apt/history.log
Commandline: apt-get install emacs
Commandline: apt-get install aptitude
Commandline: apt-get install openjdk-7-jdk
Commandline: apt-get install libxss1
Commandline: apt-get install gradle
Commandline: apt-get install ruby
Commandline: apt-get install nodejs
Commandline: apt-get install gimp imagemagick
Commandline: apt-get install git
Commandline: apt-get install ruby-bundler
Commandline: apt-get install libproj-dev
Commandline: apt-get install libmagickwand-dev
Commandline: apt-get install apache2 libapache2-mod-php5
Commandline: apt-get install yui-compressor
Commandline: apt-get install optipng
Commandline: apt-get install libimage-exiftool-perl
Commandline: apt-get install etherwake
Commandline: apt-get install pdftk
Commandline: apt-get install sendmail
Commandline: apt-get install nmap
Commandline: apt-get install sharutils
Commandline: apt-get install php5-curl
Commandline: apt-get install android-tools-adb android-tools-fastboot
Commandline: apt-get install ruby2.0
Commandline: apt-get install ruby-bundler
Commandline: apt-get install libssl-dev
Commandline: apt-get install libreadline6-dev
Commandline: apt-get install curl
Commandline: apt-get install libpq-dev
Commandline: apt-get install gource

… and which ones you’ve removed…

grep "Commandline: apt-get remove" /var/log/apt/history.log

Commandline: apt-get remove unity-lens-video unity-lens-photos unity-lens-music unity-lens-friends unity-lens-files
Commandline: apt-get remove ubuntuone-client
Commandline: apt-get remove cups
Commandline: apt-get remove telepathy-indicator
Commandline: apt-get remove unity-scope-home
Commandline: apt-get remove cups-browsed
Commandline: apt-get remove modemmanager
Commandline: apt-get remove indicator-bluetooth indicator-keyboard indicator-messages indicator-power
Commandline: apt-get remove evolution-data-server
Commandline: apt-get remove colord
Commandline: apt-get remove zeitgeist
Posted in geek | Tagged , | Leave a comment

Trackpad crashing on Samsung NC10 [Workaround]

In Ubuntu 13.10 I notice the trackpad freezes on occasion. This is my hacky solution for getting it going again without a reboot

sudo rmmod psmouse
sudo modprobe psmouse
Posted in geek | Tagged , | Leave a comment

HTTP compression of static content with .htaccess

I was originally using mod_deflate however I had the following issues

  • Content-length was not populated which meant I couldn’t implement an AJAX progress bar
  • Weird error net::ERR_INVALID_CHUNKED_ENCODING on OS X with Chrome on transfers bigger than 1MB – I couldn’t find any other platforms effected by this.
  • Unnecessary server load

Things to note. The header content-encoding gzip is only set if the environment variable GZIP is set true. The check however is made against REDIRECT_GZIP. This is just how environment variables work within rewrite conditions – set a variable called FOO and then check against the variable with a REDIRECT_ prefix, i.e. REDIRECT_FOO.

ForceType application/json
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteCond %{REQUEST_FILENAME}.gz -f 
RewriteRule ^(.+)$ $1.gz [L,E=GZIP:true]
Header set Content-Encoding gzip env=REDIRECT_GZIP
</IfModule>

Also important is the Vary: Accept-Encoding. This means that different clients going through the same proxy will behave correctly. Some might support gzip, some might not.

<IfModule mod_headers.c>
Header append Vary: Accept-Encoding
</IfModule>
Posted in geek | Tagged , | Leave a comment

Jasmine 2.0 + RequireJS + Blanket + Backbone

Jasmine 2.0 provides a JavaScript unit test framework, RequireJS provides a dependency modelling/loading and Blanket provides native in-browser JavaScript code coverage – no need for a coverage server etc. So why not use all three together, well, it’s kind of tricky and kept me busy all evening.

I’m going to provide a small but scalable standalone example rather than getting bogged down in the details of my current project

Directory structure

First job is to setup the project structure. There are many possible approaches. I think the most important things are – have both development and minified third party libraries, keep third party libraries in a separate tree and have the same “package” structure for both code and tests.

.
./js
./js/main.js   <== Entry point
./js/app.js    <== Application main class
./js/config.js <== RequireJS config
./js/model     <== Application code
./js/model/bar.js
./js/view
./js/view/foo-view.js
./templates    <== Underscore templates
./templates/foo-view.html
./js/third-party
./js/third-party/underscore-min.map
./js/third-party/jquery-2.1.0.js
./js/third-party/backbone-1.1.0.js
./js/third-party/require-2.1.11.js
./js/third-party/require-2.1.11.min.js
./js/third-party/backbone-1.1.0.min.js
./js/third-party/jasmine-blanket-1.1.5.js
./js/third-party/underscore-1.6.0.min.js
./js/third-party/blanket-1.1.5.js
./js/third-party/blanket-1.1.5.min.js
./js/third-party/backbone-min.map
./js/third-party/jquery-2.1.0.min.js
./js/third-party/underscore-1.6.0.js
./js/text.js   <== RequireJS plugin for templates. Needs to be at the top level
./test
./test/spec
./test/spec/model
./test/spec/model/bar-test.js
./test/spec/view
./test/spec/view/foo-view-test.js
./test/spec-runner.js
./test/jasmine-2.0.0  <== Jasmine 2.0.0 release
./test/jasmine-2.0.0/jasmine.js
./test/jasmine-2.0.0/boot.js
./test/jasmine-2.0.0/console.js
./test/jasmine-2.0.0/jasmine_favicon.png
./test/jasmine-2.0.0/jasmine-html.js
./test/jasmine-2.0.0/jasmine.css
./css
./img
./spec-runner.html   
./index.html

RequireJS configuration

I placed the RequireJS configuration in a single file to allow it to be reused between the main application page and the jasmine tests. This would also allow reuse between multiple pages if you needed.

define([], function() {
  requirejs.config({
    baseUrl : 'js',
    paths : {
      jquery : 'third-party/jquery-2.1.0.min',
      underscore : 'third-party/underscore-1.6.0.min',
      backbone : 'third-party/backbone-1.1.0.min',
      templates : '../templates'
    },
    shim : {
      backbone : {
        deps : [ 'underscore', 'jquery' ],
        exports : 'Backbone'
      },
      underscore : {
        exports : '_'
      }
    }
  });
});

Application entry point

The application entry point main.js has a require on the config.js file and then initializes the application class. Note the use of nested requires. If you’re building with node.js you’ll need to use the findNestedDependencies = true option.

requirejs.config({
  baseUrl : 'js',
});

require([ 'config' ], function() {
  require([ 'app', 'jquery'], function(App, $) {
    $(document).ready(function() {
      new App().initialize();
    });
  });
});

HTML page

The main HTML is very simple, just a script with src of require.js with the data-main attribute pointing to the entry point file.

<!DOCTYPE html>
<html>
<head>
<title>Jasmine 2.0 + RequireJS + Blanket example</title>
<meta charset="UTF-8" />
<script data-main="js/main" src="js/third-party/require-2.1.11.min.js"></script>
</head>
<body>

</body>
</html>

Spec runner – entry point JavaScript

The jasmine spec runner uses the same config.js as the main application, this reduces any copy-and-paste and ensures the tests run with the same set of third-party libraries as the main application.

Note again the nested require() as with the main entry point.

requirejs.config({
  baseUrl : 'js'
});
require([ 'config' ], function() {
  requirejs.config( ... );
  require([ 'jquery', 'jasmine-boot', 'jasmine-blanket' ], function($, jasmine, blanket) {
    ....
  });
});

The spec runner then adds more test specific configuration to requirejs, this does not overwrite the requirejs.config() call in config.js, it simply merges with it.

  requirejs.config({
    paths : {
      'jasmine' : '../test/jasmine-2.0.0/jasmine',
      'jasmine-html' : '../test/jasmine-2.0.0/jasmine-html',
      'jasmine-boot' : '../test/jasmine-2.0.0/boot',
      'spec' : '../test/spec',
      'blanket' : 'third-party/blanket-1.1.5.min',
      'jasmine-blanket' : 'third-party/jasmine-blanket-1.1.5',
    },

Jasmine 2.0 uses a bootstrap file called boot.js. Note the shim config to setup the correct dependencies.

    shim : {
      'jasmine-boot' : {
        deps : [ 'jasmine', 'jasmine-html' ],
        exports : 'jasmine'
      },
      'jasmine-html' : {
        deps : [ 'jasmine' ]
      },
      'jasmine-blanket' : {
        deps : [ 'jasmine-boot', 'blanket' ],
        exports : 'blanket'
      }
    }

Setting up blanket is usually straightforward using attributes data-cover and data-cover-only on the script tags. However since we’re loading all our dependencies via requirejs we don’t have that option. Instead we configure blanket programatically using blanket.config() calls.

The blanket-jasmine adapter at time of writing does not quite support jasmine 2.0 due to some API changes. I used the patch from stackoverflow.com/questions/21420291/blanketjs-jasmine-2-0-not-working to fix it up.

  require([ 'jquery', 'jasmine-boot', 'jasmine-blanket' ], function($, jasmine, blanket) {

    // blanket.options('debug', true);

    // include filter
    blanket.options('filter', 'js/');
    // exclude filter
    blanket.options('antifilter', [ 'js/third-party', '../test/spec/', 'js/text.js' ]);
    blanket.options('branchTracking', true); 

Another funny issue with jasmine 2.0 is the use of the window.onload callback in boot.js to kick the tests off. Therefore we call it manually, wrapped with a jQuery document ready callback to ensure the DOM is loaded.

Loading the individual spec js files is easy, we just push them into an array and require() that first

    var specs = [];

    specs.push('spec/view/foo-view-test');
    specs.push('spec/model/bar-test');

    $(document).ready(function() {
      require(specs, function(spec) {
        window.onload();
      });
    });

Putting it all together…

requirejs.config({
  baseUrl : 'js'
});
require([ 'config' ], function() {

  requirejs.config({
    paths : {
      'jasmine' : '../test/jasmine-2.0.0/jasmine',
      'jasmine-html' : '../test/jasmine-2.0.0/jasmine-html',
      'jasmine-boot' : '../test/jasmine-2.0.0/boot',
      'spec' : '../test/spec',
      'blanket' : 'third-party/blanket-1.1.5.min',
      'jasmine-blanket' : 'third-party/jasmine-blanket-1.1.5',
    },
    shim : {
      'jasmine-boot' : {
        deps : [ 'jasmine', 'jasmine-html' ],
        exports : 'jasmine'
      },
      'jasmine-html' : {
        deps : [ 'jasmine' ]
      },
      'jasmine-blanket' : {
        deps : [ 'jasmine-boot', 'blanket' ],
        exports : 'blanket'
      }
    }
  });

  require([ 'jquery', 'jasmine-boot', 'jasmine-blanket' ], function($, jasmine, blanket) {

    // blanket.options('debug', true);

    // include filter
    blanket.options('filter', 'js/');
    // exclude filter
    blanket.options('antifilter', [ 'js/third-party', '../test/spec/', 'js/text.js' ]);
    blanket.options('branchTracking', true); 

    var jasmineEnv = jasmine.getEnv();
    jasmineEnv.addReporter(new jasmine.BlanketReporter());

    jasmineEnv.updateInterval = 1000;

    var specs = [];

    specs.push('spec/view/foo-view-test');
    specs.push('spec/model/bar-test');

    $(document).ready(function() {
      require(specs, function(spec) {
        window.onload();
      });
    });
  });
});

Spec runner – HTML

This is simple, just require.js and a pointer to the spec runner entry point

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Jasmine Spec Runner v2.0.0</title>

<link rel="shortcut icon" type="image/png"
	href="test/jasmine-2.0.0/jasmine_favicon.png">

<link rel="stylesheet" type="text/css"
	href="test/jasmine-2.0.0/jasmine.css">

<script data-main="test/spec-runner"
	src="js/third-party/require-2.1.11.min.js"></script>

</head>

<body>
</body>
</html>

The tests

The tests each use require() to load the classes they wish to test.

define([ 'model/bar' ], function(Bar) {
  describe("data access", function() {
    var model = {};
    beforeEach(function() {
      model = new Bar([ {
        type : 'cow',
        size : 1
      }, {
        type : 'horse',
        size : 2
      } ]);
    });
    it("can search by type", function() {
      expect(model.findByType('horse')[0].get('size')).toBe(2);
    });
  });
});
Posted in geek | Tagged , , , | Leave a comment

Enabling Wake On Lan on an O2 wireless router (TG587n v2)

To enable wake on lan (WOL) magic packets with an O2 wireless router you need to change the routing table entry from dynamic to static, this means the entry is always present so the router recognises the IP even when the target machine is switched off. This is true for pretty much all consumer DSL routers.

Login using SuperUser and password printed on the O2 router

telnet 192.168.1.254
Trying 192.168.1.254...
Connected to o2wirelessbox.lan.
Escape character is '^]'.
Username : SuperUser
Password : < password from label on router >

Now use the IP tool to delete and re-add the routing table entry

{SuperUser}=>ip
{SuperUser}[ip]=>arplist
{SuperUser}[ip]=>:ip arplist
Interface           IP-address             HW-address        Type
2   LocalNetwork    192.168.1.51           12:34:56:78:9a:bc DYNAMIC   < this is one we want to make static
2   LocalNetwork    192.168.1.60           12:34:56:78:9a:bd DYNAMIC

Now physically disconnect the machine you wish to make static, otherwise it will keep getting added as dynamic.

{SuperUser}[ip]=>arpdelete
intf = LocalNetwork
ip = 192.168.1.51
[hwaddr] = 12:34:56:78:9a:bc
:ip arpdelete intf=LocalNetwork ip=192.168.1.51 hwaddr=12:34:56:78:9a:bc                                                                              
{SuperUser}[ip]=>arplist
Interface           IP-address             HW-address        Type
2   LocalNetwork    192.168.1.60           12:34:56:78:9a:bd DYNAMIC

Now add again using same details

{SuperUser}[ip]=>arpadd
intf = LocalNetwork
ip = 192.168.1.51
[hwaddr] = 12:34:56:78:9a:bc
:ip arpadd intf=LocalNetwork ip=192.168.1.51 hwaddr=12:34:56:78:9a:bc
{SuperUser}[ip]=>arplist
Interface           IP-address             HW-address        Type
2   LocalNetwork    192.168.1.51           12:34:56:78:9a:bc STATIC   < now static :)
2   LocalNetwork    192.168.1.60           12:34:56:78:9a:bd DYNAMIC
Posted in geek | Tagged , | Leave a comment

Ruby – latitude/longitude from start point, bearing and distance

class CoordinatesCalc

  def CoordinatesCalc.offset_coordinate(lat_deg, lon_deg, distance_m, bearing_deg)
    r = 6371000.0;
    lat = lat_deg * Math::PI / 180
    lon = lon_deg * Math::PI / 180
    bearing = bearing_deg * Math::PI / 180
    distance_by_r = distance_m / r
    lat2 = Math.asin( Math.sin(lat) * Math.cos(distance_by_r) +
                      Math.cos(lat) * Math.sin(distance_by_r) *
                      Math.cos(bearing) )

    lon2 = lon + Math.atan2(Math.sin(bearing) * Math.sin(distance_by_r) * Math.cos(lat),
                            Math.cos(distance_by_r) - Math.sin(lat) * Math.sin(lat2))
    [180.0 * lat2 / Math::PI, 180.0 * lon2 / Math::PI]
  end

  def CoordinatesCalc.dms(d, m, s)
    d + m / 60.0 + s / 3600.0
  end

  def CoordinatesCalc.dms_to_s(dms)
    d = dms.floor
    m = (60 * (dms - d)).floor
    dm = d + (m / 60.0)
    s = (3600.0 * (dms - dm)).floor
    d.to_s + " " + m.to_s + " " + s.to_s
  end

end

r = CoordinatesCalc.offset_coordinate(CoordinatesCalc.dms(53,19,14),
                                      CoordinatesCalc.dms(-1, -43, -47),
                                      124800.0,
                                      CoordinatesCalc.dms(96, 1, 18))
puts CoordinatesCalc.dms_to_s(r[0])
puts CoordinatesCalc.dms_to_s(r[1])
Posted in geek | Tagged | Leave a comment

Rails 4.0.0 with Ruby 2.0 on a Dreamhost shared server

Build ruby from source. RVM won’t work out of the box because it tries to use sudo. It’s quite easy.

cd
mkdir build
cd build
http://cache.ruby-lang.org/pub/ruby/2.0/ruby-2.0.0-p247.tar.gz
tar xzf ruby-2.0.0-p247.tar.gz
cd ruby-2.0.0-p247
 ./configure --prefix /home/adamish/ruby   # <=== make sure you install to your own home directory
make install

Make your custom ruby default. Add the following to your ~/.bash_profile

export GEM_HOME="$HOME/.gems"
export GEM_PATH="$GEM_HOME"
export PATH=~/ruby/bin:$PATH

Install rails

gem install rails --no-document

Create dummy site for testing

rails new HorseApp
mv HorseApp/* . # move to top level

Add following lines to Gemfile

# required for JS runtime
gem 'therubyracer'
# required for FCGI wrapper
gem 'fcgi'

Install the new gems

bundle install

Create FCGI wrapper script – public/dispatch.fcgi

#!/home/adamish/ruby/bin/ruby

ENV['RAILS_ENV'] = 'development'
ENV['HOME'] ||= `echo ~`.strip
ENV['GEM_HOME'] = File.expand_path('~/.gems')
ENV['GEM_PATH'] = File.expand_path('~/.gems')

require 'fcgi' 
require File.join(File.dirname(__FILE__), '../config/environment.rb')

class Rack::PathInfoRewriter
  def initialize(app)
    @app = app
  end
  def call(env)
    env.delete('SCRIPT_NAME')
    parts = env['REQUEST_URI'].split('?')
    env['PATH_INFO'] = parts[0]
    env['QUERY_STRING'] = parts[1].to_s
    @app.call(env)
  end
end
Rack::Handler::FastCGI.run  Rack::PathInfoRewriter.new(HorseApp::Application) 

Add following to .htaccess

<IfModule mod_fastcgi.c>
AddHandler fastcgi-script .fcgi
</IfModule>
<IfModule mod_fcgid.c>
AddHandler fcgid-script .fcgi
</IfModule>

Options +FollowSymLinks +ExecCGI 

RewriteEngine On 

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ public/dispatch.fcgi/$1 [QSA,L] 
 
ErrorDocument 500 "Rails application failed to start properly"

Try it out! You should see the standard “Welcome aboard – You’re riding Ruby on Rails!” development starter page.

Posted in geek | Tagged , | Leave a comment

Zoneminder with Logitech C310

Bus 001 Device 002: ID 046d:081b Logitech, Inc. Webcam C310
# Add following line to /usr/bin/zmdc.pl
$ENV{LD_PRELOAD} = '/usr/lib/x86_64-linux-gnu/libv4l/v4l1compat.so';
sudo service zoneminder restart
  • Capture method: V4Lv2
  • Format: PAL
  • Palette: YUYV
  • Width/Height: 640/480
Posted in geek | Tagged , | Leave a comment

JavaScript debug with Chrome / Eclipse

 /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome  --user-data-dir=$(mktemp -d /tmp/chrome-profile-XXXXX)  --remote-debugging-port=9222

Add this update site http://chromedevtools.googlecode.com/svn/update/dev/

Posted in geek | Tagged , | Leave a comment

Flash in Chrome/Ubuntu 13.04 – could not load plugin [solved]

rm -rf ~/.config/google-chrome/
Posted in geek | Tagged , | Leave a comment