It’s time to migrate away from Outlook Express

Outlook Express is obsolete, so you need to migrate if you’re still using it. This post is a quick guide to saving your local data so that you can jump ship.

If you are keen on desktop-based email, then there are only two real contenders for a replacement mail client:

  • Mozilla Thunderbird (suggested).
  • Windows Mail.

So where is all my data?

The script below is a Windows bat script for backing up an Outlook Express setup. Just fill in the Identity variable and run it from anywhere to produce a folder containing the Outlook saved emails and contacts.

You can find your identity string as a folder name in your profile path, under Local Settings\Application Data\Identities\. The profile path for a user called bob would usually be in a folder like C:\Documents and Settings\bob or C:\Users\bob.

These files can be read by both of the suggested replacements, so a good transition might be:

  1. Make a backup.
  2. Install an alternative & set it up.
  3. Try to import as much as you can.
  4. Once you’re happy, uninstall Outlook Express, or at least delete the shortcuts to it.
@echo off
ECHO -------------------------------------------------------------------------------
SET BACKUPDIR="%username% - Outlook Backup"
SET IDENTITY={AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA}
ECHO Backing up outlook files to: %backupdir%
ECHO --------------------------------------------------------------------------------

ECHO - Clearing backup location... (1 of 3) 
DEL /F /S /Q %backupdir% > NUL 2>&1
MKDIR %backupdir% 2> NUL
ECHO - - Done

ECHO - Copying emails... (2 of 3) 
MKDIR %backupdir%\Emails 2> NUL
XCOPY /E /H /C /R /Y "%userprofile%\Local Settings\Application Data\Identities\%IDENTITY%\Microsoft\Outlook Express" %backupdir%\Emails > NUL
ECHO - - Done

ECHO - Copying address book... (3 of 3)
MKDIR %backupdir%\AddressBook 2> NUL
XCOPY /E /H /C /R /Y "%appdata%\Microsoft\Address Book" %backupdir%\AddressBook > NUL
ECHO - - Done

ECHO - Completed 3 of 3 tasks.
ECHO -------------------------------------------------------------------------------
ECHO The backup is complete.
ECHO Please copy %BACKUPDIR% to external storage.
ECHO --------------------------------------------------------------------------------
PAUSE

How to create an animated GIF from a series of images

Sometimes, you end up with a folder full of images, which you want to animate. With the open source ImageMagick tool, this is easy on the command line:

animate *.png

This will show you all of the PNG files in the folder in quick succession, like a flip book.

ImageMagick works on just about any OS. For Linux users, the package is generally imagemagick or ImageMagick:

sudo apt-get install imagemagick
yum install ImageMagick

But this blog post is about animated GIFs, so lets make one of those. This is a compact way to combine images (here and here for examples in context), gives you a re-usable at-a-glance illustration of something that changes over time.

Example from an older post:

2015-04-tetris

The steps to make a good conversion command are:

  1. Check that alphabetically, your images are in order. If not, rename them:
    echo *
  2. Convert them to a GIF a few times, and find the delay that suits you (hundredths of a second between frames)
    convert -delay 80 *.png animated.gif
  3. Choose an output size (width x height):
    convert -resize 415x -delay 80 *.png animated.gif
  4. Compress with -Layers Optimize for a smaller file:
    convert -resize 415x -delay 80 *.png -layers Optimize animated.gif

Notes

  • Generated thumbnails usually take the first frame only, which is why we ask Imagemagick to resize it (WordPress users: Choose “Full Size”).
  • To pause at the start of the loop for a moment, just copy the first image a few times.

How to install KA Lite on the Raspberry Pi

KA Lite is an open source, web-based learning package. Today I’ll run through a simple setup which will allow a Raspberry Pi to provide a wireless learning resource server for a classroom, without the Internet.

dia

The Raspberry Pi 2 is a surprisingly powerful single-board computer. You can use it for anything which a computer can do, in a relatively cheap circuit board the size of a credit card:

2015-06-rpi-2b

This setup takes around two hours.

Materials

You will need:

  • Raspberry Pi (The Raspberry Pi 2 Model B was used here), with micro SD card, mouse, keyboard, monitor with HDMI.
  • A good Micro USB power supply – Many Android phone chargers will be suitable.
  • A computer which can write to micro SD cards. If your computer has an SD card slot, get an SD-to-Micro-SD adapter for it.
  • A wired network with Internet for the setup
  • A USB wireless network adapter such as WiPi for deployment.
  • Any WiFi-enabled device for testing.

Install Raspbian

Raspbian is an operating system for the Pi, and is the perfect choice for embedded server setups like this. You need to write the image to the Micro SD card.

  1. Obtain the image from https://www.raspberrypi.org/downloads/
  2. This is zipped, so extract it to get the real image file.
  3. Write the disk image to the SD card:
    • Windows: Fetch a copy of “Win32 Disk Imager” to write this file to the SD card.
    • Linux or Mac: Use dd (found in the terminal) to write to the card — guide available here
  4. Boot the Pi, with mouse, keyboard, HDMI, and wired network. If it doesn’t work, remove any cable converters (use HDMI direct to monitor), and if it still doesn’t work, then the SD card was not correctly imaged.
  5. Expand root filesystem, set your password, and enable “boot to desktop”.
  6. After reboot, you should have a desktop. Click the black terminal icon to get to work.

Install some things

From the terminal, run these commands:

sudo apt-get update
sudo apt-get dist-upgrade
sudo apt-get install chromium python-m2crypto

This checks for new software (update), upgrades anything necessary (dist-upgrade), and then installs two packages:

  • python-m2crypto — this will help speed up KA Lite a bit by helping out with encryption.
  • chromium — this is Google Chrome’s open source cousin, and it’s worth installing so that you can Google things as you go, and test things locally.

If everything goes to plan, you should now be able to find Chrome on the menu and navigate the web.

2015-06-kalite-rpi-chrome

Install KA Lite

These steps are a shortened version of the official guide

Once Raspbian is running, these commands will download & install KA Lite:

git clone https://github.com/learningequality/ka-lite.git
cd ka-lite/
./setup_unix.sh

The download is 150MB, so allow a few minutes. The installer then prompts for a few questions, like:

  • “Do you wish to download the assessment package now?” — Say yes, it fetches another 500MB.
  • “Do you wish to set the KA Lite server to run in the background automatically when you start this computer?” — say “y”.

At the end, you will be given a command to start the server, which you should type in as well:

/home/pi/ka-lite/bin/kalite start

Once it starts (it will take a while!), it will give you two web addresses. One of them is local to the computer (127.x), and the other will work from other computers on the network. Write both of them down!

The install & start-up together will look like a this:

2015-06-03-kalite-install

Test it out locally

Open up Chromium, and navigate to one of the addresses that the installer suggested.

2015-06-03-kalite-1

Log in, using the details provided during the installation.

2015-06-03-kalite-2

Click on “Manage”, then “Videos”

2015-06-03-kalite-3

KA Lite will prompt for registration, which lets you download content. Use the “One click registration” on the left, then wait for it to connect.

2015-06-03-kalite-4
2015-06-03-kalite-5

Use the Videos section to fetch something. Here we fetch something from the ancient art & culture section:

2015-06-03-kalite-6

Wait a few minutes before moving to the next section: The video downloads in the background.

Access over the network

From some other device which is on the same network, enter the web address that was given at the end of the installer (ignore the address which starts with 127.x — it wont work between two computers):

http://(IP address):8008/

From the browser, let’s test it out. Click over to Learn, and navigate to the video you just downloaded. It should display, so we can learn about those Egyptian artifacts:

2015-06-03-kalite-7

This setup would be complete if you want to run on a wired network – you can simply bookmark this address on each computer which needs to use it, and manage it through the web.

Howto: QRCodes on receipts with escpos-php

ESC/POS is a binary protocol for speaking to receipt printers. It contains a command for printing QR Codes on compatible printers. The PHP library escpos-php is used for generating these commands in PHP. This post will show you how to use it to generate QR codes on your receipt printer.

For printers which don’t support this command, a second option is available: sending the QR code as an image.

Getting started

First up, you need your receipt printer to be working with escpos-php. Here are some resources about how to go about that:

Option 1: Direct printing

This method sends QR codes directly. From the documentation, the syntax for this command is:

qrCode($content, $ec, $size, $model)

Print the given data as a QR code on the printer.

  • string $content: The content of the code. Numeric data will be more efficiently compacted.
  • int $ec Error-correction level to use. One of Escpos::QR_ECLEVEL_L (default), Escpos::QR_ECLEVEL_M, Escpos::QR_ECLEVEL_Q or Escpos::QR_ECLEVEL_H. Higher error correction results in a less compact code.
  • int $size: Pixel size to use. Must be 1-16 (default 3)
  • int $model: QR code model to use. Must be one of Escpos::QR_MODEL_1, Escpos::QR_MODEL_2 (default) or Escpos::QR_MICRO (not supported by all printers).

The below code snippets are directly from the QR code printing demo, showing how the output changes with the options given.

Simple example

This is the simplest use, with all default options. QR codes can be aligned in the same way as text or images on the page:

2015-04-escposqr-01-demo
// Most simple example
title($printer, "QR code demo\n");
$testStr = "Testing 123";
$printer -> qrCode($testStr);
$printer -> text("Most simple example\n");
$printer -> feed();

// Demo that alignment is the same as text
$printer -> setJustification(Escpos::JUSTIFY_CENTER);
$printer -> qrCode($testStr);
$printer -> text("Same example, centred\n");
$printer -> setJustification();
$printer -> feed();

Data encoding

This is a demonstration of saving different types of data in a code. Numeric data is packed more efficiently than text. Binary data can also be stored.

2015-04-escposqr-02-dataencoding
// Demo of numeric data being packed more densly
title($printer, "Data encoding\n");
$test = array(
	"Numeric"      => "0123456789012345678901234567890123456789",
	"Alphanumeric" => "abcdefghijklmnopqrstuvwxyzabcdefghijklmn",
	"Binary"       => str_repeat("\0", 40));
foreach($test as $type => $data) {
	$printer -> qrCode($data);
	$printer -> text("$type\n");
	$printer -> feed();
}

Error correction levels

QR codes support fout levels of error correction. More error correction results in larger, but more durable codes:

2015-04-escposqr-03-errorcorrection
// Demo of error correction
title($printer, "Error correction\n");
$ec = array(
	Escpos::QR_ECLEVEL_L => "L",
	Escpos::QR_ECLEVEL_M => "M",
	Escpos::QR_ECLEVEL_Q => "Q",
	Escpos::QR_ECLEVEL_H => "H");
foreach($ec as $level => $name) {
	$printer -> qrCode($testStr, $level);
	$printer -> text("Error correction $name\n");
	$printer -> feed();
}

Code size

The defauly codes are quite small. Each pixel can be blown up, up to 16x, using the size option:

2015-04-escposqr-04-pizelsize
// Change size
title($printer, "Pixel size\n");
$sizes = array(
	1 => "(minimum)",
	2 => "",
	3 => "(default)",
	4 => "",
	5 => "",
	10 => "",
	16 => "(maximum)");
foreach($sizes as $size => $label) {
	$printer -> qrCode($testStr, Escpos::QR_ECLEVEL_L, $size);
	$printer -> text("Pixel size $size $label\n");
	$printer -> feed();
}

QR models

QR models have different appearances, storage parameters and physical sizes. The default (Model 2) is most common. The printer used here does not support micro QR codes, and used Model 2 as a fallback.

2015-04-escposqr-05-qrmodel
// Change model
title($printer, "QR model\n");
$models = array(
	Escpos::QR_MODEL_1 => "QR Model 1",
	Escpos::QR_MODEL_2 => "QR Model 2 (default)",
	Escpos::QR_MICRO => "Micro QR code\n(not supported on all printers)");
foreach($models as $model => $name) {
	$printer -> qrCode($testStr, Escpos::QR_ECLEVEL_L, 3, $model);
	$printer -> text("$name\n");
	$printer -> feed();
}

Note

To run the snippets, you need to initialise the printer, and define a title() function to print headings, like so:

<?php
/* Demonstration of available options on the qrCode() command */
require_once(dirname(__FILE__) . "/escpos-php/Escpos.php");
$printer = new Escpos();

// ....

// Cut & close
$printer -> cut();
$printer -> close();

function title(Escpos $printer, $str) {
	$printer -> selectPrintMode(Escpos::MODE_DOUBLE_HEIGHT | Escpos::MODE_DOUBLE_WIDTH);
	$printer -> text($str);
	$printer -> selectPrintMode();
}

Option 2: Printing codes as images

Not all printers can generate QR codes natively. The work-around is to generate a QR code as an image on the computer, and then send that image to the printer. This is slightly slower, so if you print a lot of codes, you should consider upgrading your printer.

First up, fetch a copy of phpqrcode and generate some codes. I wont attempt to document the whole library here, but in short, it supports most of the same features as the native QR command. To generate a code, you simply use QRcode::png:

require_once("phpqrcode/qrlib.php");
QRcode::png("testing123", "test.png", 'L', 10, 0);

To print a PNG image, use the bitImage() command (the graphics command is also only available on newer printers):

require_once("escpos-php/Escpos.php");
$img = new EscposImage("test.png"); // Load image
$connector = ... // Add connector to your printer here
$printer = new Escpos($connector);
$printer -> bitImage($img);
$printer -> feed();
$printer -> text("Code printed from image\n");

$printer -> cut();
$printer -> close();

A more sophisticated way to hack in phpqrcode would be to add this new code as a different implementaton of the qrCode function. Other improvements are:

  • Use temporary files to avoid concurrency issues:
  • Where possible, expand the code on the printer, to send less data
<?php
require_once("escpos-php/Escpos.php");
require_once("phpqrcode/qrlib.php");

class EscposQrImgPrinter extends Escpos {
	function qrCode($content, $ec = self::QR_ECLEVEL_L, $size = 3, $model = self::QR_MODEL_2) {
		// Validate inputs
		self::validateString($content, __FUNCTION__);
		self::validateInteger($ec, 0, 3, __FUNCTION__);
		self::validateInteger($size, 1, 16, __FUNCTION__);
		$model = self::QR_MODEL_2; // Only Model 2 supported in phpqrcode, change back to it.
		$sizeMod = 0;
		if($size % 2 == 0) { // Optimisation to enlarge codes on the priner, sending 1/4 of the data.
			$size /= 2;
			$sizeMod = self::IMG_DOUBLE_HEIGHT | self::IMG_DOUBLE_WIDTH;
		}
		// Map error-correction to phpqrcode levels
		$ecMap = array(QR_ECLEVEL_L => 'L',
			QR_ECLEVEL_M => 'M',
			QR_ECLEVEL_Q => 'Q',
			QR_ECLEVEL_H => 'H');
		// Create QR code in temp file, and print it.
		$tmpfname = tempnam(sys_get_temp_dir(), "escpos-php");
		QRcode::png("testing123", $tmpfname, $ecMap[$ec], $size, 0);
		$img = new EscposImage($tmpfname);
		$this -> bitImage($img, $sizeMod);
		unlink($tmpfname);
	}
}

This new class uses phpqrcode in the background instead, and can be accessed with the same function calls as the parent class:

$printer = new EscposQrImgPrinter();

$testStr = "Testing 123";
$printer -> qrCode($testStr);
$printer -> text("Most simple example\n");
$printer -> feed();
$printer -> cut();

$printer -> close();

The only visible difference between the implementations is a few pixels of spacing below the image.

Deprecated Google API’s: What you need to know

In less than a day, a whole series of old Google API’s are being switched off.

If you are running any of those API’s, then whilst this is bad news, you’ve had several years to upgrade (for example, the Provisioning API features have now been replaced by the Admin SDK). However, one of the API’s not mentioned on the linked page is the old ClientLogin API, which will also stop working on April 20.

ClientLogin involves directly sending a username and password to Google, and then receiving a login token back. There are two main categories of people who use the ClientLogin API which this post is targeted at:

  • People who haven’t figured out OAuth yet.
  • People using client libraries for the Google Data API’s, which are not deprecated, but often use this login.

If your use case involves users actually entering their username and password, then this post wont help (but this page will), but if you have an installed script which runs administrative functions on your domain, then read on, as it’s quite easy to retrofit your scripts with an OAuth2 service account.

Setting up a service account

Service accounts are designed for server-side use (ie, no browser), and replace using ClientLogin to authenticate as a super-admin for the domain.

First, log in to the developer console (console.developers.google.com), and create a new project, then jump to the credentials menu. Create and download a p12 private key.

2015-04-01google-cred

2015-04-02google-generate

Now under “Manage this Domain”, locate the advanced security options, and add a delegation for your new service account for one or more scopes. This allows the service account to access to a given API and act on behalf of users. As an example, the next section uses the Email Settings API, which has this scope:

https://apps-apis.google.com/a/feeds/emailsettings/2.0/

And it’s added like so:

2015-04-03security

2015-04-04advanced

2015-04-05-api

2015-04-06addscope

Example: How to retro-fit a PHP app with OAuth 2

Assuming you already have code which sends requests to an API, all we need to change is the Authorize: header. A ClientLogin request looks like this:

Authorize: GoogleLogin auth=<ClientLogin token>

But an OAuth2 request looks like this:

Authorize: Bearer <OAuth token>

You can generate a new token for yourself at the OAuth 2.0 Playground from Google to make sure your old API’s work with the new tokens (they will- any issues are probably permission or user problems).

So how do you generate one of these tokens for a service account? The best way is to use client libraries for this. In PHP, this is the google-api-php-client.

This library also has support for newer API’s (not older Google Data API’s), which you can use to replace your implementation where applicable. For this example, we’ll just be getting an access token.

First up, we need to do some structuring. I’ve wrapped old signature code into an abstract EmailSignatureUpdater class so that I can write two versions: The old ClientLoginEmailSignatureUpdater, and the new OAuthEmailSignatureUpdater, differing only by login method and Authorize: header.

So here is some ClientLogin code:

/**
 * Functions dependent on ClientLogin, which will stop working after 2015-04-20.
 */
class ClientLoginEmailSignatureUpdater extends EmailSignatureUpdater {
	/**
	 * @param array $conf Configuration for the Google login.
	 */
	protected function __construct(array $conf) {
		/* Getting account */
		$account = array(
				'accountType' => 'GOOGLE',
				'Email' => $conf['user']."@".$conf['domain'],
				'Passwd' => $conf['password'],
				'service' => 'apps');

		/* Log in */
		$login = $this -> login($account);
		if(!isset($login['Auth'])) {
			if(isset($login['Error'])) {
				throw new Exception("Google returned ".$login['Error']);
			} else {
				throw new Exception("Google login failed");
			}
		}
		$this -> token = $login['Auth'];
	}

	/**
	 * Perform Google ClientLogin authentication
	 *
	 * @param array:string $account Account details (see top for components)
	 * @return string Response, including login token.
	 */
	private function login($account){
		/* Log in to google apps */
		$tk_ch = curl_init();
		curl_setopt($tk_ch, CURLOPT_URL, "https://www.google.com/accounts/ClientLogin");
		curl_setopt($tk_ch, CURLOPT_POST, true);
		curl_setopt($tk_ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($tk_ch, CURLOPT_POSTFIELDS, $account);
		$responseTxt = curl_exec($tk_ch);
		curl_close($tk_ch);

		/* Parse response (very hack-y but works) */
		$responseLines = split('=', $responseTxt);
		$lastkey = false;
		for($i = 0; $i < count($responseLines); $i++) {
			$line = $responseLines[$i];
			if($i == 0) {
				/* First line is just a key */
				$lastkey = $line;
			} else {
				$vals = split("\n", $line);
				if($i != count($responseLines) - 1) {
					/* Split into value and next key */
					$nextkey = $vals[count($vals) - 1];
					unset($vals[count($vals) - 1]);
				} else {
					$nextkey = false;
				}
				$response[$lastkey] = implode("\n", $vals);
				$lastkey = $nextkey;
			}
		}
		return $response;
	}
	
	protected function authorize() {
		return 'Authorization: GoogleLogin auth='.trim($this -> token);
	}
}

And the part you’re probably searching for: how to get an access token out of the google-api-php-client:

/**
 * New OAuth2 authentication using google-api-php-client to get us logged in instead.
 */
class OAuthEmailSignatureUpdater extends EmailSignatureUpdater {
	protected function __construct(array $conf) {
		$this -> token = $this -> login($conf);
	}
	
	private function login(array $conf) {
		require_once(dirname(__FILE__) . "/vendor/google-api-php-client/src/Google/autoload.php");

		// Start client
		$client = new Google_Client();
		$client -> setApplicationName("Test Application");
		
		// Load key
		$key = file_get_contents($conf['key_file']);
		if(!$key) {
			throw new Exception("Key could not be loaded from file " .$conf['key_file']);
		}
	
		// Set up auth with scopes
		$gauth = new Google_Auth_AssertionCredentials(
				$conf['service_account'],
				array('https://apps-apis.google.com/a/feeds/emailsettings/2.0/'),
				$key);
		// sub- pretend to be a user
		// Should probably be the same as the user you logged in as with ClientLogin
		if(isset($conf['sub'])) {
			$gauth -> sub = $conf['sub'];
		}
		$client -> setAssertionCredentials($gauth);
		if($client -> getAuth() -> isAccessTokenExpired()) {
			$client -> getAuth() -> refreshTokenWithAssertion($gauth);
		}
		$client -> setClientId($conf['client_id']);
	
		/* Save token for later use */
		$token = $client -> getAccessToken();
		if (!$token) {
			throw new Exception("Google apps login failed!");
		}
		$arr = json_decode($token);
		if(!isset($arr -> access_token)) {
			throw new Exception("Google apps login did not return access token!");
		}
		return $arr -> access_token;
	}
	
	protected function authorize() {
		return 'Authorization: Bearer ' . $this -> token;
	}
}

In the superclass, we provide a getUpdater() function to dish out an old or new updater based on the configuration. In future releases, you could just throw an Exception instead of logging in with ClientLogin, as you know it will fail!

/**
 * Contains email signature updater methods, with no login method
 */
abstract class EmailSignatureUpdater {
	/**
	 * @var string The login token.
	 */
	protected $token;

	/**
	 * @param array $conf The configuration to use.
	 */
	protected abstract function __construct(array $conf);

	/**
	 * Return authorization header
	 */
	protected abstract function authorize();

	// A series of methods which make raw HTTP requests
	// to https://apps-apis.google.com/a/feeds/emailsettings/2.0/ were
	// located here, and are not relevant to this post.
	
	/**
	 * Based on the configuration, return a signature updater which logs in using the correct API.
	 * 
	 * @param array $conf
	 */
	static function getUpdater(array $conf) {
		if(isset($conf['user']) && isset($conf['domain']) && isset($conf['password'])) {
			return new ClientLoginEmailSignatureUpdater($conf);
		} else if(isset($conf['service_account']) && isset($conf['client_id']) && isset($conf['key_file'])) {
			return new OAuthEmailSignatureUpdater($conf);
		}
		throw new Exception("Configuration insufficient for loading email signatures. See config.php.example.");
	}
}

To utilise this, you need to change HTTP methods to care less about where their headers come from. I was using cURL for this, but on any library, you need to set the header using the new authorize() function before you send off the request:

curl_setopt($ch, CURLOPT_HTTPHEADER, array($this -> authorize(), ..., ...);

The idea is that users can simply alter their configuration to pick up the newly supported OAuth, allowing you to shift it from a software problem to an administrative/configuration problem:

/* Google apps domain config */
/* Old style ClientLogin usage (deprecated) */
//$config['google']['user'] = "admin";
//$config['google']['domain'] = "example.com";
//$config['google']['password'] = "...";

/* New login details for OAuth */
$config['google']['service_account'] = '...@developer.gserviceaccount.com';
$config['google']['client_id'] = '....apps.googleusercontent.com';
$config['google']['key_file'] = dirname(__FILE__) . '/google-key.p12';
$config['google']['sub'] = "admin@example.com"; // optional

Within your application, you then construct a new any-authentication object based on the configuration, and call its old methods as normal:

$updater = EmailSignatureUpdater::getUpdater($config['google']);
$updater -> doThing('param1', 'param2', etc);

Good luck!

How to use a Raspberry Pi as a print server

This post is designed for people who want to share a simple USB printer, such as this receipt printer, over the network.

Usually, you just connect up the printer to the computer like this:

2015-04-rpi-printer1

But if you are sending the print jobs from a central server, you would instead follow these steps, and hook up a Raspberry Pi near the printer to pass on the print-outs for you:

2015-04-rpi-printer2

This post will show you a very fuss-free way to do this. Because of its simplicity, if you have multiple computers printing (read: you need a server that can spool), or need two-way communication with the printer, then this setup will not be sufficient for your use case.

One-off setup

If your printer is /dev/usb/lp0, then the command to run is:

nohup nc -klp 9100 > /dev/usb/lp0 2> /dev/null&

There is quite a lot going on in this command, so I’m going to break it down into parts and explain what each one does.

nohup
Lets the command keep running after you log-out.
nc -klp 9100
Listens on port 9100 (-lp), and returns to listening after each connection (-k)
> /dev/usb/lp0
Redirects any incoming data to the printer device
2> /dev/null
Suppresses errors by sending them to /dev/null
&
Runs the command in the background so that you can keep using the terminal.

Run every boot

Simply schedule the command in cron as a @reboot task.

crontab -e

And add the line:

@reboot nohup nc -klp 9100 > /dev/usb/lp0 2> /dev/null&

Note that if you reboot the printer, you will also need to reboot the raspberry pi to get it to reconnect without logging in!

Send some tests

From a computer somewhere else on the network, send a test print-out:

echo "Hello world" | nc 10.x.x.x 9100

If the target printer is a thermal receipt printer, then you could also use escpos-php to send it more elaborate commands:

<?php
$fp = fsockopen("10.x.x.x", 9100);
/* Print a "Hello world" receipt" */
$printer = new Escpos($fp);
$printer -> text("Hello World!\n");
$printer -> cut();
fclose($fp);

How to run Tetris on your Raspberry Pi

This is a simple walkthrough on how to install my Tetris clone, Blocks, on a Raspberry Pi.

On most computers running Debian (or Raspbian in the case of the Raspberry Pi), it’s as simple as clone, compile, run:

sudo apt-get install libncurses5-dev doxygen
git clone https://github.com/mike42/blocks
cd blocks
make
./bin/blocks

If you have any issues running this, then you need to fetch a newer version of GCC, as this needs C++11 support to compule (see last section for instructuins).

But if all goes to plan, you will get something like this in your terminal:

2015-04-tetris

Use the keyboard to control the game:

Move
Right, down, left
Rotate
Up
Drop
Spacebar
Quit
q

Get a screen

Basically any project with graphics can benefit from one of these. Simply add on a TFT shield, such as PiTFT to create a tiny console:

2015-04-tetris

Of course, this is still keyboard-controlled, but with some hacking, I’m sure you could map touch events to keyboard actions.

Troubleshooting: Update GCC

The Raspbian spftware image which many Raspberry Pi’s have is slightly too old to compile Blocks, which requires C++11 support.

Luckily, it’s very easy to upgrade from wheezy to jessie to add it. You know you need to do this if you get this error compiling:

$ git clone https://github.com/mike42/blocks
$ make
mkdir -p bin
g++ src/main.cpp src/blocks_game.cpp src/blocks_shape.cpp -o bin/blocks -lcurses -lrt -std=c++11 -Wall
cc1plus: error: unrecognized command line option ‘-std=c++11’
cc1plus: error: unrecognized command line option ‘-std=c++11’
cc1plus: error: unrecognized command line option ‘-std=c++11’
Makefile:2: recipe for target 'default' failed
make: *** [default] Error 1

Generally this means you don’t have GCC 4.8, which is not available in wheezy edition of Raspian.

$ g++ --version
g++ (Debian 4.6.3-14+rpi1) 4.6.3
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

So to summarise this thread, you need to:

nano /etc/apt/sources.list

Find this line:

deb http://mirrordirector.raspbian.org/raspbian/ wheezy main contrib non-free rpi

And change the word “wheezy” to “jessie”:

deb http://mirrordirector.raspbian.org/raspbian/ jessie main contrib non-free rpi

You can then update everything with:

sudo apt-get update && sudo apt-get dist-upgrade

You are now running the newer jessie release, which gives you access to the GCC 4.8 package we need:

apt-get install g++-4.8

So we can pick up where we left off, and compile the game:

make
./bin/blocks

Getting a USB receipt printer working on Windows

Note:This post is a Windows adaptation of an earlier post, Getting a USB receipt printer working on Linux, mainly in response to these questions.

In this post, I’ll step through how to get a USB thermal receipt printer appearing on Windows. The aim of this is to be able to send raw text to the printer, so that we can point a driver such as escpos-php at it. The printer tested here is once again this Epson TM-T20:

2015-03-printer-back
2015-03-printer-top

The directions below are for Windows 7, so your mileage may vary if you are on an older or newer version.

If you have issues following these steps, make sure you can locate your printer in Device Manager, and that it has “USB Print Support”.

Add the printer

Find Devices and Printers and click Add a Printer.
2015-04-windowsusb-01

2015-04-windowsusb-02

Add it as a Local printer, using the USB virtual port, probably USB0001:

2015-04-windowsusb-03
2015-04-windowsusb-04

Use the Generic / Text Only driver.

2015-04-windowsusb-05

Name the printer whatever you like, and then share it under the same name:

2015-04-windowsusb-06
2015-04-windowsusb-07

At this point, it should pop up in the window in the background, and also prompt you to Print a test page.

2015-04-windowsusb-08
2015-04-windowsusb-09

The test print is plain-text, and depending on your printer, will look something like this:

2015-04-windowsusb-10

Finally, you need to verify that your printer can be accessed locally, by typing \\localhost into Windows Explorer. If all goes to plan, you will see the new printer there too:

2015-04-windowsusb-11

Run a command-line test print

We now know that your printer is working, and can be accessed via its share name (even locally).

Test printing from the command-line. Fire up cmd.exe and try to send it some text to verify that it’s working:

echo "Hello World" > testfile
print /D:"\\%COMPUTERNAME%\Receipt Printer" testfile
del testfile

Printing something useful

This is where you start to see real results. Receipt printers are not just for printing plain-text. Many of them support a standard called ESC/POS, which contains formatting commands.

The snippet below, from this earlier post, generates some basic ESC/POS commands.

Install PHP if you don’t have it already, and call the below code foo.php:

<?php
/* ASCII constants */
const ESC = "\x1b";
const GS="\x1d";
const NUL="\x00";

/* Output an example receipt */
echo ESC."@"; // Reset to defaults
echo ESC."E".chr(1); // Bold
echo "FOO CORP Ltd.\n"; // Company
echo ESC."E".chr(0); // Not Bold
echo ESC."d".chr(1); // Blank line
echo "Receipt for whatever\n"; // Print text
echo ESC."d".chr(4); // 4 Blank lines

/* Bar-code at the end */
echo ESC."a".chr(1); // Centered printing
echo GS."k".chr(4)."987654321".NUL; // Print barcode
echo ESC."d".chr(1); // Blank line
echo "987654321\n"; // Print number
echo GS."V\x41".chr(3); // Cut
exit(0);

You would send generated commands to the printer like this:

php foo.php > testfile
print /D:"\\%COMPUTERNAME%\Receipt Printer" testfile
rm testfile

Scaling this up

The correct ESC/POS codes are quite tricky to generate with manually, which is why I put together the escpos-php driver. You can find more information on that at:

A simple “Hello World” receipt to your Windows shared printer would be scripted as (call this one foo2.php):

<?php
require_once(dirname(__FILE__) . "/Escpos.php");
try {
	// Enter the share name for your USB printer here
	$connector = new WindowsPrintConnector("Receipt Printer");

	/* Print a "Hello world" receipt" */
	$printer = new Escpos($connector);
	$printer -> text("Hello World!\n");
	$printer -> cut();
	
	/* Close printer */
	$printer -> close();
} catch(Exception $e) {
	echo "Couldn't print to this printer: " . $e -> getMessage() . "\n";
}

This would be sent to the printer by loading it from the web, or running the script on the command-line:

php foo2.php

The full ESC/POS snippet with formatting, coded up with escpos-php, would look like this (call this one foo3.php):

<?php
require_once(dirname(__FILE__) . "/Escpos.php");
try {
	// Enter the share name for your USB printer here
	$connector = new WindowsPrintConnector("Receipt Printer");

	/* Print some bold text */
	$printer -> setEmphasis(true);
	$printer -> text("FOO CORP Ltd.\n");
	$printer -> setEmphasis(false);
	$printer -> feed();
	$printer -> text("Receipt for whatever\n");
	$printer -> feed(4);

	/* Bar-code at the end */
	$printer -> setJustification(Escpos::JUSTIFY_CENTER);
	$printer -> barcode("987654321");
	
	/* Close printer */
	$printer -> close();
} catch(Exception $e) {
	echo "Couldn't print to this printer: " . $e -> getMessage() . "\n";
}

And again, this could be executed by loading the page through the web, or invoking the command directly:

php foo3.php

How to empty your local user account

If you’re not going to use a user account on your computer again, but can’t delete it for some reason, then emptying it is the next best thing to do.

Note: Save anything you want to keep before you start deleting things. These are destructive commands which delete all of the files and settings in the current user’s profile. If you are at all unsure, consider using a file browser to clear out the profile instead.

Windows:

cd %USERPROFILE%
del /A / F /Q /S .

Linux or Mac:

cd ~
rm -Rf .

This will make sure that the disused account no-longer wastes any disk space.