Scan to Evernote with Rasberry Pi

scanner

I’ve had long time a plan to scan all receipts and documents and save them to Evernote in order to find what I need quickly, even when mobile.

Problem

I’ve been lazy scanning because there are so many steps:

  1. Connect scanner to a computer
  2. Open scanning software
  3. Place the document inside the scanner
  4. Click scan in the software
  5. Enhance contrast
  6. Copy the image to Evernote

While it should be simple as:

  1. Place the document inside the scanner
  2. Click email button from the scanner

Solution

Plug the scanner to a Rasberry PI (connected to internet) and keep it always on. Have the physical scanner buttons scan and send to different targets (Evernote, Dropbox, printer, email).

Requirements

  • Scanner (Canon CanoScan Lide 110)
  • Rasberry PI Model B
  • 4GB SD
  • USB stick with Raspbian installer

Steps

  1. Install Raspbian
  2. Install scanner software: apt-get install sane
  3. Install scanbd to control scanner buttons:
    apt-get install libconfuse-dev libhal-dev libsane-dev
    wget http://downloads.sourceforge.net/project/scanbd/releases/scanbd-1.4.1.tgz
    tar zxvf scanbd.tar.gz
    ./configure
    make
    make install
    
  4. Install mutt mail client: sudo apt-get install mutt
  5. Configure smtp for mutt (place the configuration under /root):
  6. Install imagemagick: sudo aptitude install imagemagick
  7. Take control of one of the Rasberry PI’s led:
    echo 1 > /sys/class/leds/led0/brightness
    echo 0 > /sys/class/leds/led0/brightness
    
  8. Set up Dropbox commandline client
  9. Configure scanbd:
    echo 1 >/sys/class/leds/led0/brightness 
    DIR=`dirname $0`
    scan_dir=/var/spool/scan
    datetime=`date +%F_%H%M%S`
    filename=scan-$datetime
    case $SCANBD_ACTION in
    pdf)
    # Not working
    ;;
    scan)
    # Upload to dropbox, used for photos
    scanimage --mode Color --depth 32 | convert - $scan_dir/$filename.jpg
    dropbox_uploader.sh upload $scan_dir/$filename.jpg  /
    ;;
    copy)
    # Print with default printer
    scanimage --depth 16 | convert - $scan_dir/$filename.jpg
    lp $scan_dir/$filename.jpg
    ;;
    email)
    # Send to Evernote via email
    scanimage --mode Color --depth 16 | convert - -normalize -level 10%,90% -sharpen 0x1 $scan_dir/$filename.jpg 
    echo "" | mutt username.secret@m.evernote.com -a $scan_dir/$filename.jpg -s "$filename" -d 5
    ;;
    esac
    rm $scan_dir/$filename.jpg
    echo 0 >/sys/class/leds/led0/brightness 
    exit 0
    

Find and track frontend bugs using Google Analytics

Find your Frontend bugs and stop guessing ROI for a bug fix.

This post describes how to use Google Analytics with requirejs to track errors in frontend.

Google Analytics events

GA events are grouped by Category, Action and Label. All JavaScript errors can be captured using window.onerror -handler.
As end result GA looks like this in case of a frontend bug:

event-stats

Setting things up with Google Analytics

  • Create a GA account and two properties: one for testing purposes (handy also for integration tests) and one for production.
  • Configure your local web server to serve pages you are developing singe GA will not accept file protocol.
  • GA is always disabled for localhost. In order to test locally use IP address 127.0.0.1 or some custom domain name. With Mac you can just use computer_name.local.

Basic setup

window._gaq = window._gaq || []
window._gaq.push(['_setAccount', (isProduction ? productionAccountId : testAccountId)])
window._gaq.push(['_trackPageview'])
require(['http://www.google-analytics.com/ga.js'])

Tracking JavaScript errors

window.onerror(function(e) {
  var category = 'JavaScript error'
  var action = e.message
  var label = e.filename + ':' + e.lineno
  _gaq.push(['_trackEvent', category, action, label]);
}

Tracking ajax errors

function ajaxErrorHandler(e) {
  var category = 'Ajax error'
  var action = e.status + ' - ' + e.statusText
  var label = e.responseText
  _gaq.push(['_trackEvent', category, action, label]);
}

$.get('nonExistingUrl.com', $.noop).fail(ajaxErrorHandler)

Debugging

In order to make debugging easier Google provides http://www.google-analytics.com/u/ga_debug.js instead of http://www.google-analytics.com/ga.js to log to console all tracking events.

Here’s the code for requiring proper GA bootstrap file:

function getGaUrl(isDebug) {
  var isHttps = 'https:' === document.location.protocol
  return (isHttps ? 'https://ssl' : 'http://www') + '.google-analytics.com/' + 
    (isDebug ? 'u/ga_debug.js' : 'ga.js')
}
require([getGaUrl(true)])

With this configuration GA will show following information in console for different tracking events.

ga-debug

Try out a Live Demo.

Full example can be found in Github

Organizing frontend code of a single page app

Asset-based directory structure

Most Front-End projects I have seen use asset based directory structure: Styles are in one folder, scripts in another and so on.

/index.html
/assets/
     images/
          awesomePlugin-sprite.png
          SearchBg.png
          SummaryBg.png
     scripts/
          lib/
              awesomePlugin.js
              jquery-1.8.0.js
              require.js
          model/
               SearchModel.js
               SummaryModel.js
          view/
               SearchView.js
               SummaryView.js
     styles/
          main.scss
          search.scss
          summary.scss
          awesomePlugin.css
     templates/
          SearchPanel.html
          Summary.html
          SummaryRow.html

This is probably a habit from times before single page apps existed and there were no modules for front end code. In Java world it’s like putting all exception classes under exception package and all controllers under controller package instead of having component based grouping.

Component-based directory structure

The idea is to put everything related to a component under same folder – images, templates, scripts and so on.

/index.html
/app/
     search/
          SearchModel.js
          SearchView.js
          SearchPanel.html
          SearchBg.png
          search.scss
     summary/
          SummaryView.js
          SummaryModel.js
          Summary.html
          SummaryRow.html
          SummaryBg.png
          summary.scss
vendor/
     jquery-1.8.0.js
     require.js
     awesomePlugin/
          awesomePlugin.css
          awesomePlugin.js
          awesomePlugin-sprite.png

Benefits of component based directory structure

  • When making changes to a component all the modifications take place in the same folder
  • When using require.js (or similar) template imports can have relative paths instead of absolute
  • Getting an overview of a component and searching related code is easy
  • Deleting a component without leaving dead code behind is easy: Just delete the folder
  • Structure of 3rd party components is consistent and they can be copied to project with their original structure
  • Filtering by assets is still possible using file extension
  • No need to repeat same folder name for different assets when grouping becomes necessary
  • Re-organizing code is easier

Best and worst UI for subway ticket system

Case 1: Singapore

  1. Click your destination directly from the subway map (Outram Park)
  2. Insert coins until price is zero
  3. Take the ticket

singapore_subway

Case 2: San Francisco

  1. Select payment method (Credit card)
  2. Find your stop from subway map
  3. Find your stop from a list (Montgomery)
  4. Look for one way price and remember it ($1,75)
  5. Calculate how many full integers can be subtracted from 20
  6. Click Subtract $1 for 18 times
  7. Calculate how many 0.05 decimals can be subtracted from 2
  8. Click Subtract 5 cent for 5 times
  9. Click Print $1.75 ticket
  10. Click to confirm
  11. Take the ticket

metro-blog

Comparison

Case 1 required 1 click when case 2 required 26 clicks plus some math, searching from a list and keeping numbers in mind. Is it that hard to simulate most typical use cases before implementing them?

Partial application for JavaScript

Let’s write a unit test for DateTime.getDayInYear()

var yearSizes = [366, 365, 365, 365, 366, 365, 365, 365, 366, 365, 365]

expect(_.map(_.range(2000, 2010), function(year) { 
  return DateTime.getDayInYear(year, 11, 31)
})).toEqual(yearSizes)

This looks quite verbose and unreadable, so let’s refactor it to look like this

expect(_.map(_.range(2000, 2010), toLastDateOfYear)).toEqual(yearSizes)

function toLastDateOfYear(year) { return DateTime.getDayInYear(year, 11, 31)}

But this feels silly if we need that function only once.
The solution is to use partial application, which allows any of the arguments to be left undefined by returning a function which takes in the remaining arguments.

expect(_.map(_.range(2000, 2010), DateTime.getDayInYear.papply(__, 11, 31)))
  .toEqual(yearSizes)

Isn’t that beautiful! Here’s some more examples of how partial application can be used


//EXAMPLE
function sum(a, b, c, d) { return a + b + c + d}

//All following examples return 'abcd'
sum.papply('a', 'b', 'c', 'd')
sum.papply('a', 'b')('c', 'd')
sum.papply('a')('b')('c')('d')
var ab = sum.papply('a', 'b')
ab('c','d')
ab('c','d')
ab('c')('d')
sum.papply('a', __, 'c', __)('b','d') 
sum.curry('a', __, 'c', __)('b')('d') 

And finally, here’s the implementation

var __ = {}
function papply(func, givenArguments) {
  var indexOf = givenArguments.indexOf(__)
  var givenArgsSize = givenArguments.length
  var requiredArgsSize = func.length
  if(givenArgsSize >= requiredArgsSize && (indexOf < 0 || indexOf >= requiredArgsSize))
    return func.apply(func, givenArguments)
  else
    return function() {
      return (function(givenArguments, remainingArguments) {
        for(var i = 0; i < givenArguments.length; i++)
          if(givenArguments[i] === __) givenArguments[i] = remainingArguments.shift()
        return papply(func, givenArguments.concat(remainingArguments))
      })(givenArguments.slice(0), Array.prototype.slice.call(arguments))
    }
}

Function.prototype.papply = function() {
  return papply(this, Array.prototype.slice.call(arguments))
}

The code can be found also as Gist in Github