Photobox photo downloader/backup tool

Photobox Downloader V2 is now available, even easier to download all your photos. Blog post below refers to the original (V1) version.

During the week I found out that my wife had a bunch (over 2.4K!) of photos on PhotoBox.ie that were not part of our family archive. This weekend I dug around PhotoBox website and could no way to download an entire album, it was only possible to download photos individually! With 2.4K+ of photos, that is a lot of clicking!

As Larry Wall said the, a good developer, is a lazy developer! Thus I created a NodeJS module (photobox-downloader) that makes it easy to access an download individual photos or an entire album (or everything!) easily. With the module I was able to backup all of my wife’s photos in about 5 minutes, no clicking needed!

Photobox Downloader will auto scan your album list and then can automatically downloaded every photo. Optionally you can download only specific files or albums.

Built with Request for making the HTTP requests, Cheerio for parsing of the HTML, Async for managing the asynchronous control flow, as well as Progress for showing a fancy progress bar.

I have open sourced the code and it is available on GitHub, I also published it as a NodeJS module, so you can find it in the NPM registry.

Installation

$ npm install photobox-downloader

Usage

Screenshot

photobox-downloader

 

If you run into any issues running the module just give me a shout!


SSL by default

As part of the site redesign I have added a SSL cert, all HTTP traffic will now automatically be redirect to HTTPS version. The SSL is thanks to StartSSL.  All existing links/bookmarks should automatically redirect to the equivalent HTTPS version. The new look and feel is based on BootStrap V3 and scales well on small devices & resolutions. Finally, fixed a few of the issues that bugged me on the old theme (like the content area being too small, comments not showing a hierarchy). It is not super flashy, with the emphasis on content and readability. No distracting patterns or UI elements.

Change Log:

  • SSL now enabled by default
  • New “Responsive Design” based on Bootstrap V3
  • Switched to Gists for code snippets
  • Comments show nesting/hierarchy
  • Author comments highlighted
  • A few other minor tweaks

If you find any issues please let me know.


Cordova 3.0 – Getting Started Guide / Tutorial

With the launch of Cordova 3.0 and the significant changes it introduces I thought some people might like a Getting Started Guide/ Tutorial for Windows, as the existing Cordova Document is not the greatest. Lets get to it.

Prerequisites

The biggest problem with Cordova is it doesn’t explain properly the prerequisites for Windows, nor how to install

  1. Android SDK (with 1 AVD already created and previuosly started)
  2. Java JDK
  3. Ant
  4. NodeJS
  5. Git

NOTE: You should always install command line software to directory without spaces (i.e. do not install to “C:\Program Files (x86)\“). I always install such tools to: c:\devapps\

The 5 prerequisites must exist on your PATH. That is to say you must be able to run the following commands in a command/console window:

android list sdk
javac -version
ant -version
node -v

 

cmd-prereq

 

Once you meet the prerequisites it is easy to install Cordova, just run,

npm install cordova

A few minutes later Cordova will now be installed! To confirm run,

cordova -v

To create a sample project run the following

cordova create MyProject
cd MyProject
cordova platform add android
cordova emulate android

All done! The emulator will take a few minutes to start. It is usually better to start the emulator (using: android avd) before running cordova emulate android command.


Fixing “ERROR [config]: Config file must export a function!”

If you use AngularJS and install Karma (>0.10) and then run into the error ERROR [config]: Config file must export a function! here is a quick fix. The problem is caused by a recent change how Karma reads config files, but it’s an easy fix.

config/karma.conf.js

Open this file, it should look something like this,

// Contents of: config/karma.conf.js
basePath = '../';

files = [
  JASMINE,
  JASMINE_ADAPTER,
  'app/lib/angular/angular.js',
  'app/lib/angular/angular-*.js',
  'test/lib/angular/angular-mocks.js',
  'app/js/**/*.js',
  'test/unit/**/*.js'
];

autoWatch = true;

browsers = ['Chrome'];

junitReporter = {
  outputFile: 'test_out/unit.xml',
  suite: 'unit'
};

Replace these lines with the following,

// Contents of: config/karma.conf.js
module.exports = function (config) {
  config.set({
    basePath : '../',

    // Fix for "JASMINE is not supported anymore" warning
    frameworks : ["jasmine"],

    files : [
      'app/lib/angular/angular.js',
      'app/lib/angular/angular-*.js',
      'test/lib/angular/angular-mocks.js',
      'app/js/**/*.js',
      'test/unit/**/*.js'
    ],

    autoWatch : true,

    browsers : ['Chrome'],

    junitReporter : {
      outputFile : 'test_out/unit.xml',
      suite      : 'unit'
      //...
    }
  });
}

Job done! Try running your tests again, everything should work again.

Update: Thanks to a comment from Clare, the above code has now been modified further to remove the “WARN [config]: JASMINE is not supported anymore.” warning as well.


jQuery Mobile – Dynamic Navigation Menu

Worked a small mobile centric pet project recently that involved jQuery Mobile. Usually I would have use Sencha Touch, but I wanted to test out a different framework. Having used Sencha Touch / ExtJS I was used to being very programmatic, building all the boiler plate html took some getting used to. The main problem I ran into was my navigation menu, it had to be hard coded on every page. After investigating alternatives approaches and not finding any thing that suited my needs. Even the jQuery Mobile Demo Site uses a static menu on every page, not encouraging!

I started building a dynamic menu just like I would have on any jQuery site, using $(document).ready(). It wasn’t long before I ran into problems. I won’t go into detail about all the issues caused by JQM’s progresive enhancement, but it certainly caused a few hours of head scratching. Below is solution I came up with.

The HTML

This is all standard HTML taken directly from jQuer Mobile examples.

<body>
<div data-role="page" id="page1">
  <div data-theme="a" data-role="header">
    <!-- The #menu is the ID of the navigation panel element -->
    <a href="#menu" data-role="button" data-theme="c" data-rel="back" data-inline="true" data-icon="bars">
      Menu
    </a>
    <h3>
      Simple Dynamic Menu :: Page A
    </h3>
  </div>
  <!-- This is the navigation panel that opens to show the menu -->
  <div data-role="panel" id="menu" data-display="push">
    <div class="ui-panel-inner">
      <!-- This UL is the menu, where the items will be added -->
      <!-- Make sure you don't add any <li> or any other content inside it! -->
      <ul data-role="listview" class="mainMenu"></ul>
    </div>
  </div>
  <!-- /panel -->
  <div data-role="content">
    <h3>Page A (Cats)</h3>
    This simple implementation shows the simplest possible implementation of a dynamic menu.
    <p>
      <img src="img/cat.jpg">
    </p>
  </div>
</div>
</body>

Important things to note:

  1. The placement of this HTML is important. It must be inside the “page” div, but not inside the “content” div (i.e. it is a sibbling of “content”, not a child).
  2. To make the menu appear we add a button to the header. The href for the link is just a hash with the ID of the hidden panel that holds the menu.
  3. This mainMenu <ul> must be completely empty.

The Javascript

For this “simple” demo, the Javascript is very straight forward.

// The Menu items and links
var menu = [
  {
    title: "Page A (Cats)",
    url  : "simple-page-a.html"
  },
  {
    title: "Page B (Dogs)",
    url  : "simple-page-b.html"
  },
  {
    title: "Page C (Elephants)",
    url  : "simple-page-c.html"
  }
];

// For this "simple demo" we can change event to "pageinit", but for the more advanced features, it has to be bound to "pageshow"
$(document).on("pageshow", function (event) {

  var items = '', // menu items list
    ul = $(".mainMenu:empty");  // get "every" mainMenu that has not yet been processed

  for (var i = 0; i < menu.length; i++) {
    items += '<li><a href="' + menu[i].url + '">' + menu[i].title + '</a></li>';
  }

  ul.append(items);
  ul.listview('refresh'); // use cache, as ".mainMenu:empty" will no longer work (append called!)

});

Important things to note:

  1. The most important thing to note is the $(".mainMenu:empty") selector. This is the most efficient one possible, as it works only on unprocessed menus.
  2. JQM preloads pages using Ajax (in order to have nice transitions), this is why a page will usually have two menus, thus have to use a CSS class not a CSS id.

 

Follow the link below to see a live demo

View Live Demo

Checkout out the full source code on GitHub.

Fork on GitHub

The GitHub project also includes a more advanced demo that shows how you could use Ajax and JSON to load the menu from a remote source.


Be reckless, use Git!

Like many experienced devs I have used many different version control systems (CSV, Subversion. Perforce, etc…). Three years ago, after using Subversion for 5+ years, I switched to Git. Initially I didn’t see much difference between Subversion and Git, many people raved about its distributed architecture, bisecting or rebasing, etc… All of these are nice features, but honestly, who uses Git a a truly distributed manner? The other features I have only used a handful of times.

No, the real advantage of Git didn’t sink in until I went back to Subversion. The advantage of Git is, it allows Developers to be reckless. And I mean that in the positive sense, Git allows Developers to try out new ideas/solutions without the “down time” of changing configuration files/paths that you would have to do with Subversion.

In Subversion, if I wanted to try something radical (while keeping my trunk intact – for bug fixing) I would have to create a whole new branch/folder and thus a brand new development install. This barrier slows down development and punishes “gut feeling” or radical/reckless ideas. But with Git, if an idea hit me, I could stash my current changes, branch and be working on the new idea in under 10 seconds.

So be reckless, use Git!


Everything that is wrong with Backbone.js, in 1 image

I have been playing around with Backbone on and off for a month or two now, but I just can’t seem to like it! The image below is from a project I just come aboard on and I think it clearly shows the problem with Backbone.js.

Backbone.js parameter problem

12 Parameters, come on! Backbone.js is just too generic, it is not a Web framework. Too much boiler plate code has to be written, too many “standard” features are not included and have to be manually included as 3rd party dependencies. I mean, in 2013, why, o why does Backbone not ship with a full suite of tests and a starter / seed app?? I spend more time trying to get stuff working in Backbone.js (and reading out-of-date documentation) than I do actually writing Backbone code!

Maybe someone will fork Backbone.js and include a full Web centric stack, provide proper documentation and working examples (that actually work with the current version!!), I can hope at least.


10 Tips for Completing Interview Coding Assignments/Exercises

Many companies ask perspective Software Engineers to complete a programming challenge as part of the hiring process. I am not a big fan of timed / in-person challenges for 2 reasons; First, they are a little too artificial and don’t reflect what would happen on the actual job. Second, and most importantly, they don’t offer the chance for the candidate to shine / go above and beyond.

Being a technical person I am often asked by some manager to review an applicants submission even if they aren’t joining my team, almost all applicants make “simple” mistakes. So here are 10 tip tips to help you get that job!

 

Tip 1: Do what is asked!

First and foremost, do what is asked of you!! In the last 5 days I have reviewed 2 potential candidates submissions for Senior Software Engineering positions. However, both of them failed to follow the instructions! Pretty much if you can’t follow basic instructions you are finished.

This is the 2nd question, it’s easy to make them feel comfortable and has multiple right answers,

Q2. Create a function that can take any number of parameters and returns a String that is a comma separated string
e.g. myFunction(“car”, “bus”, “airplane”); // returns “car, bus, airplane”

However, both applicants failed to answer this correctly! One of the them used alert() to print out “carbusairplane” and the other looped through, alerting for each iteration! Heck, if they had created a function to statically return “car, bus, airplane” I would have given them full points for being ballsie! The question clearly says to return a string, no mention of alert(). Neither got the job.

Moral of the story, follow the instructions!

 

Tip 2: Be expressive, add comments

As it is written, the reviewer will not know what you are thinking unless you write it down. If you are asked to rewrite an inefficient function, don’t just rewrite it, tell me why it was inefficient! How many issues did you see? Is there any inbuilt functionality of the language that provides the same functionality?

 

Tip 3: It is an opportunity to show off!

Go above and beyond, when appropriate.  If a question asks you to create a small application, do everything that is asked of you (most important requirement), then add additional functionality  It doesn’t have to be extensive, but show some enthusiasm and passion.  If you are asked to implement a REST API that would allow the Listing (GET) and Adding (POST) of products, then go a step further and add Edit (PUT) and Delete (DELETE) functionality.  Just remember, on simple questions, keep your answers simple, this tip only applies to the larger/longer questions.

 

Tip 4: Read between the lines, of the job description.

At least in my examinations I never ask candidates to write Unit Tests, this is intentional. While I won’t fail you for not doing something I haven’t specifically asked for, every person who went above and beyond and included unit tests in their work I’ve given the thumbs up to. If the original job posting made multiple references to TDD, BDD, Unit testing etc… it is a good idea to include them (at least for the larger/longer questions). While I won’t fail you, I know some of my colleagues would.

 

Tip 5: Include the question with your answer!

I don’t know how many times I’ve had to open zip files with folders, that contain numbered text files which in-turn only have the solution text. We have multiple tests for different jobs/positions, I don’t always have the test text in front of me. Make my life easier, include the question text as well. It will give a great first impression.

 

Tip 6: It is perfectly ok to ask for coding standards/rules before you start.

Idiomatic code is important for large projects, it is always a good sign if a candidate asks for this. If you don’t feel comfortable asking, then why not use an existing standard and mention it in your comments.

 

Tip 7: Demo, if possible.

If one of the questions was to build a small Web application, then host it somewhere! Let me see it in action. One candidate I reviewed got the job solely on this point, as it clearly separated him from the others. If you are building a Windows application it is also a good idea to include screen shots, just in-case the reviewers computer does not have some dependence needed to run your app.

 

Tip 8: GitHub.

I always like getting GitHub links, it shows you are active and participate. Just remember, if the Repo is public, do not host the questions, only the answers, otherwise you could upset the company (it takes a lot of effort to make a good test).

 

Tip 9: Get your code reviewed before submitting.

Unless your exam explicitly states otherwise, ask a colleague or college buddy to review your code before you submit it. In a real job all your code would be reviewed, so why should this be any different? It shows maturity and openness, which are critical for members of a high performing team. Just don’t be foolish enough to ask someone else to do the test for you, you’ll easily be found out and have burnt a bridge.

 

Tip 10: Reviews are people as well!

The people who are reviewing your code/submission are people as well. It is ok to use to some light humor, but keep this restricted to the data rather than the code. It will probably put a smile on the reviewer and make you stand out more, just don’t go over board.

 

var inputData = ["Han Solo", "Luke Skywalker", "Chewbacca", "Lando"]; // Data set is nerdy 
var result = sort(inputData); // The function name and variable names are relevant and well named, excellent!

If you start messing with the code, you’ll be dumped on the spot:

var rebelScum = ["Han Solo", "Luke Skywalker", "Chewbacca", "Lando"];
var result = starWarsSort(rebelScum); // This is unacceptable!

Fix for PhoneGap: Connection to server was unsuccessful

Tip for anyone building HTML 5 apps using PhoneGap (now called Cordova). If you are seeing inconsistent/transient error messages saying something like [Connection to server was unsuccessful to “www/assets/index.html”] when starting up your app. This is caused by your App timing out. You can either increase the time-out time, but will only reduce the frequency of the issue, or you can:

  1. Rename your index.html to “main.html”
  2. Create a new “index.html” and put the following content into it:
    <!doctype html>
    <html>
      <head>
       <title>tittle</title>
       <script>
         window.location='./main.html';
       </script>
      <body>
      </body>
    </html>
  3. Rebuild your app! No more errors!

Another good idea is to give your application a “splash screen”, so that the user gets instant feedback that your app is loading/working, before it is fully ready.