Lock straps



I love my Soma Porteur Rack and I love how it helps me take weight off of my body and onto my bike.

However, my small u-lock didn’t securely fit on the rack with a single bungee chord.

So, I sewed these straps out of 1 1/2″ velcro.

I’m interested in seeing if the velcro makes lock-ups more annoying and how the velcro holds up to getting wet and dirty.

Rewriting URLs for static files using PHP’s built-in webserver

I don’t particularly like coding in PHP, but I do think WordPress works well for building websites for small organizations in certain use cases. PHPs built-in webserver, which was added in recent versions of PHP helps make PHP web development feel closer to my flow using other languages and frameworks. In particular, it removes the overhead and context switch for having to configure instances of a webserver like Apache or Nginx for local development.

One feature of the the built-in webserver is that you can define a “router” script to segment out serving of static assets or to direct certain paths to a CMS’ main PHP file.

There are lots of examples of making a router script that will work for one’s particular environment. I used this one for WordPress, because it’s just what came up first in my Google search.

However, I ran into trouble when I was trying to develop locally on a multi-site WordPress instance that used path prefixes rather than subdomains to identify certain blogs. For instance, /blog-1/ would go to one blog while /blog-2/ would go to another. I needed to replicate the functionality of these Apache rewrite rules that would remove the blog prefix from the path:

RewriteRule  ^([_0-9a-zA-Z-]+/)?(wp-.*) $2 [L]
RewriteRule  ^([_0-9a-zA-Z-]+/)?(.*.php)$ $2 [L]

The first rule caused the most problems since I needed to return a static file at a path different than the one reflected in the request URL. I found the answer in this example from the built-in server docs of handling unsupported file types.

To rewrite the path of a static file, you need to:

  • Use a regex to update the path.
  • Figure out the mime type of the file and set the appropriate header.
  • Read the contents of the file and return them.

My finished router.php looks like this:

$path = '/'.ltrim(parse_url($_SERVER['REQUEST_URI'])['path'],'/');

// Do some URL rewriting
if (preg_match('/\/([_0-9a-zA-Z-]+\/)?(wp-.*)/', $path, $matches)) {
  $path = '/' . $matches[2];
  if (file_exists($root . $path) && !strpos($path, ".php")) {
    // The rewritten path is to a non-PHP file.  It's probably a static asset
    // or theme asset.  Load the file and return it.
    header("Content-Type: " . mime_content_type($path));
    return readfile($root . $path);

if (preg_match('/\/([_0-9a-zA-Z-]+\/)?(.*\.php)$/', $path, $matches)) {
  // The path is to some PHP file.  Remove the leading blog prefix.
  // Logic below will load this PHP file.
  $path = '/' . $matches[2];

if (file_exists($root.$path)) {
  if (is_dir($root.$path) && substr($path,strlen($path) - 1, 1) !== '/')
    $path = rtrim($path,'/').'/index.php';
  if (strpos($path,'.php') === false)
    return false;
  else {
    require_once $root.$path;
} else include_once 'index.php';

Hack for storing pot lids

I’m not particularly averse to clutter, but getting met with a landslide of pot lids when I’m trying to make food quickly can be really frustrating.  I’ve lived in a different house or apartment almost every year I’ve lived in Chicago, so the space often dictates where furniture goes and where items go on the furniture.  It’s not possible to buy furniture that matches the space and optimizes storage with every move, so things often end up on shelves in an inelegant way.


I bought a used, simple wire dish rack at the thrift store for a dollar and zip-tied it to the shelf for a little added stability.  It doesn’t look any uglier than the old pile, and cleans things up nicely.


Installing CyanogenMod 10.1 on an HTC One V (CDMA) phone

My weekend project was installing CyanogenMod 10.1 on an HTC One V phone that I got from my housemate. The phone is made for Virgin Mobile, which uses a CDMA network. The codename I’ve seen for the phone is primoc, though I don’t quite understand how the naming convention works.  The process took me about a day and a half, though it would have only been a couple of hours if I would have realized I needed to activate the phone before I installed the custom ROM and if my backup would have worked correctly.

I’m not quite sure how to write up my experience, but I wanted to share a few warnings or things that would have saved me time and weren’t included in many of the guides.

The ROM zipfiles are hundreds of MBs

Take this into account when planning the time that you need.

Think of the process as multiple steps

A lot of guides combine these into one guide, or gloss over components. I found it helpful to research and understand each task, and also for time-boxing the process.

  1. Unlock bootloader
  2. Install custom recovery image. In this case, this was ClockworkMod Recovery (CWM)
  3. Copy the CyanogenMod and Google Apps distributions (zip files) to the SD card
  4. Install CyanogenMod and Google Apps from the zip files using CWM
  5. Flash the CyanogenMod boot image using fastboot

You don’t have to install any special drivers when using Ubuntu

To run the platform tools on Ubuntu, you need to run then using sudo, e.g.:

sudo ./fastboot flash boot boot.img

Activate the phone first!

The biggest time suck of the process is that I forgot to activate the phone before flashing CyanogenMod. The backup I made didn’t work.  In order to activate the phone (or switch it to your number), you need to use Virgin’s Activate app and this is only available on the stock ROM.  Save some pain and activate the phone using the default ROM before messing around with flashing custom ROMs. Luckily, I found this ROM based on the stock ROM which included the activate app.

There isn’t a RUU for newer versions of this phone

RUU stands for ROM Update Utility. It’s a windows executable used to restore the phone to a default install.

Useful resources

I used these as references during my install:

Replacing hinge in plastic-framed glasses

Broken glasses hinge

I’ve broken numerous pairs of sunglasses at the hinge where the temples connect to the rest of the frame.  As frustrating as it was to just toss the otherwise useful glasses, it just seemed like too much hassle and expense to try to fix them.  The surfaces seemed too rough and small to solder the broken hinge pieces back together, and how could you replace the entire hinge when it’s embedded in plastic? A friend really liked the look of a cheap pair of sunglasses, so she had them converted to eyeglasses by an optician, an operation that was cheaper than normal frames, but expensive enough to warrant trying a little harder to break the broken hinges.

It turns out it was relatively painless to replace the broken hinge with one from an inexpensive pair of sunglasses.

What you’ll need

  • A broken or cheap pair of sunglasses from a thrift store, gas station, or a broken pair you have lying around.  Make sure that the way the hinges mount match the glasses you want to repair and that the size of the hinge matches the connector on temple piece.
  • Soldering iron machine
  • Metal tweezers
  • Small screwdriver

Step 1: Remove the temples from the donor glasses

Using the small screwdriver, remove the temple pieces from each side of the donor sunglasses. This will make it easier remove the hinges.  When doing this, try sliding the temple piece of the glasses you’re going to fix onto the hinge of the donor glasses, to make sure they’re compatible.

Step 2: Remove hinges from the donor glasses

We’ll repeat this process to remove the broken hinge from the glasses we want to fix, so this is a good chance to practice being steady with the soldering iron, applying the right amount of heat, and removing the hinge with minimum damage to the frame, before working with our good frames.  Hold the tip of the soldering iron to the hinge piece, being careful not to touch the plastic. With your other hand, grip the hinge with tweezers.  As the plastic around the hinge melts from the heat transfer, gently pull the hinge up and out of the frame, trying to pull as straight as possible.  I didn’t have to heat the hinge very long to melt the plastic enough to extract the hinge.

Removing the hinge from the donor glasses

Repeat this process with the other hinge to practice your technique and to have an extra part in case you drop and lose one hinge.

Step 3: Remove the hinge from the glasses you’re repairing

Remove the broken hinge from the glasses you’re repairing, using the same process that you used to remove the hinge from the donor glasses.


Removing hinge from glasses to be repaired

Broken glasses with hinge removed

Step 4: Replace the broken hinge

Grip one of the hinges from the donor glasses with the tweezers and position it in the hole left where the broken hinge was removed.  Try to hold it as straight and flush with the rest of the frame as possible.

Inserting the replacement hinge

With your other hand, touch the hinge with the tip of the soldering iron until the plastic of the frame melts around the replacement hinge.  Be careful not to melt the plastic too much or push the hinge too deep into the frame. If needed, use the tweezers or the soldering iron tip to adjust the position of the hinge.

Positioning the replacement hinge

Step 5: Reattach the temple pieces

Using the small screwdriver, replace the temple piece. You’re done! You’ve just saved your favorite pair of glasses from the landfill.

Escaping attribute selectors in LESS

I had a really rough time finding any documentation about how to do this.  To escape attribute selectors in LESS, you have to escape the selector and wrap the escaped string in parenthesis:

(~"[data-wysihtml5-command]") {
  text-decoration: none;

Offline map tiles in QGIS

Participatory Mapping Station

I was invited to run a station at a DiscoTech event sponsored by the Detroit Digital Justice Coalition (DDJC). DiscoTechs are community technology fairs, and are a really great model for sharing tech knowledge within and across communities. The DDJC has released a zine with stories and bootstrap practices so other groups can run their own DiscoTech events. While previous events had been held in somewhat central locations, this DiscoTech was held at a community center in the 48217 neighborhood at the edge of Detroit and home to a strong community of environmental justice activists who are part of the DDJC.

However, the recreation center where the event was located didn’t have Internet access. This posed a bit of a problem for our station, as we wanted to have people both create analog maps of their community using paper and transparency sheets with dry-erase markers, and digital ones. I chose Quantum GIS (QGIS) as the tool to make digital maps, because it could work on my notebook without any Internet connection. I’ve used the excellent OpenLayers QGIS Plugin to provide slippy map tiles from Open Street Map as a layer in QGIS, but this wouldn’t work without an Internet connection. My solution was to essentially run a full mapping stack on my notebook computer. This was surprisingly straightforward, and helped me better understand how the pieces of a modern custom mapping stack work together.

Make your tiles

First, I had to get the raw data from which to generate my tiles. I grabbed an extract of the Detroit Metro Area from the OpenStreetMap Metro Extracts page since we were just making maps of Detroit and selecting a subset of the map data would save a lot of time when rendering the tiles.

There are lots of ways to make map tiles, but TileMill is pretty easy to use, and very powerful. MapBox, the makers of TileMill also provide a template project called OSM Bright, which they describe as “a sensible starting point for quickly making beautiful maps in TileMill based on an OpenStreetMap database.” To get a basic set of tiles for Detroit, I just followed the OSM Bright quickstart tutorial to generate the tiles I needed.

TileMill lets you export your tiles in a number of different formats, but I chose the MBTiles format because I liked the idea of all of my tiles being packaged in a single file. It just seemed more portable in case I wanted to move my project to a separate machine.

Serve your tiles

There are also many different ways to serve your custom tiles. This tutorial provides a good rundown of one method of building a server, using Mapnik to generate the tiles. However, I wanted something really lightweight, and something that would use tiles in the MBTiles format. I found TileStache, which I liked because it was written in Python, had its own built-in webserver, and supported MBTiles. Because it supports a wide variety of datasources, the configuration seemed a bit daunting at first, but was ultimately pretty simple, at least for using an MBTiles tileset.


This is what my tilestache.xml looked like:


And this is what my tilestache.cfg (the file that configures the datasource) looked like:

  "cache": {"name": "Test"},
  "layers": {
    "detroit": {
      "provider": {
        "name": "mbtiles",
        "tileset": "detroit2.mbtiles"

Add your tiles as a layer in QGIS

Update: I originally hacked the OpenLayers plugin as described below, but Nathan and David Forest pointed out in the comments that there’s a less hacky way.

GDAL > 1.7.0 supports the Tiled Map Service (TMS) format that we’re serving using to serve our tiles in Tilestache.  You can create a VRT file as described in this blog post, How to display OpenStreetMap data tiles with no plugin inside Qgis and add your tiles as a raster layer.

Hack the OpenLayers QGIS Plugin

The last step is to get the QGIS OpenLayers Plugin to use my local tileserver instead of grabbing them from the OSM tile server over the web. There’s definitely more elegant ways of doing this, but I needed to get this to work fast, so I simply edited the osm.html file that is part of the plugin. On my system, this file was located at ~/.qgis/python/plugins/openlayers/html/osm.html. I edited the file so that around line 33 of the file

, I replaced the tile URL string “http://tile.openstreetmap.org/${z}/${x}/${y}.png” with “${z}/${x}/${y}.png”, the ServerUrl directive from my tilestache.xml.

After editing this file and starting QGIS, I was able to choose “Add OpenStreetMap layer” from the “Plugins > OpenLayers plugin” menu in QGIS to add a base layer of my custom tileset.

Installing VMware Server 2.0.2 with Linux Kernel 2.6.31-*-rt Ubuntu Studio 10.04

I’m working on a virtualized environment to run scalable instances of the Public Mapping Project app.

While the project offers an EC2 AMI, my boss wanted to run this on our own hardware, so we’re going to use VMware.  To develop the instance images, I wanted to install VMware Server 2.0.2-203138 on my notebook which is running Ubuntu Studio 10.04 with a 2.6.31-11-rt kernel.

The installer provided by VMware doesn’t work out of the box for Ubuntu Systems.  So, I followed the instructions in the Ubuntu Community VMware Server Documentation which instructs users to use a patching system developed by Radu Cotescu.  While this was easy to use and clearly documented, it didn’t work for me.  This is what happened:

ghing@geoffsnotebook:~/Downloads$ sudo ./raducotescu-vmware-server-linux-2.6.3x-kernel-71f8b66/vmware-server-2.0.x-kernel-2.6.3x-install.sh .You have VMware Server archive: 	VMware-server-2.0.2-203138.i386.tar.gzChecking for needed packages on UbuntuYou do have the linux-headers-2.6.31-11-rt package...You do have the build-essential package...You do have the patch package...Extracting the contents of VMware-server-2.0.2-203138.i386.tar.gzFound .tar file for vsock moduleFound .tar file for vmci moduleFound .tar file for vmmon moduleFound .tar file for vmnet moduleExtracting .tar files in order to apply the patch...Untarring ./vmware-server-distrib/lib/modules/source/vsock.tarUntarring ./vmware-server-distrib/lib/modules/source/vmci.tarUntarring ./vmware-server-distrib/lib/modules/source/vmmon.tarUntarring ./vmware-server-distrib/lib/modules/source/vmnet.tarTesting patch...Creating some simlinks for the newer kernels...ln: creating symbolic link `/usr/src/linux-headers-2.6.31-11-rt/include/linux/autoconf.h': File existsln: creating symbolic link `/usr/src/linux-headers-2.6.31-11-rt/include/linux/utsrelease.h': File existsApplying patch...Preparing new tar file for vsock modulePreparing new tar file for vmci modulePreparing new tar file for vmmon modulePreparing new tar file for vmnet moduleChecking that the compiling will succeed...Trying to compile vmci module to see if it worksPerforming make in ./vmware-server-distrib/lib/modules/source/vmci-onlyUsing 2.6.x kernel build system./home/ghing/Downloads/vmware-server-distrib/lib/modules/source/vmci-only/linux/driver.c: In function ‘LinuxDriver_Open’:/home/ghing/Downloads/vmware-server-distrib/lib/modules/source/vmci-only/linux/driver.c:363: error: implicit declaration of function ‘init_MUTEX’make[2]: *** [/home/ghing/Downloads/vmware-server-distrib/lib/modules/source/vmci-only/linux/driver.o] Error 1make[1]: *** [_module_/home/ghing/Downloads/vmware-server-distrib/lib/modules/source/vmci-only] Error 2make: *** [vmci.ko] Error 2There is a problem compiling the vmci module after it was patched. :(

I began to suspect that my problem could be related to the realtime kernel used by Ubuntu Studio. Googling, I found that other realtime kernel users were having problems installing VMware products.

This thread offers a description of the problem and a patch for another VMware project. Based on this I was able to create my own patch for the VMware server kernel module sources. I then modified Radu’s patch and was able to run his shell script to successfully install VMware server.

Relevant files:

To use, simply download my updated version of Radu’s patch and save it in the directory where you unarchived Radu’s installer scripts.

Visualizing Defiance, Ohio Shows

I won a free O’Reilly ebook from a hackathon I participated in a while ago.  I chose Visualizing Data and I’ve been working through the book.  I always find that its more helpful to work on a project of my own that approximates the examples in a technical book instead of just reading or copying and pasting the example code.  It forces me to learn new things, gets me more excited about the project and makes me re-read portions of the book in detail.

For a useful time series, I chose one that was close to my life, the list of past Defiance, Ohio shows.  It was also useful because I was trying to set expectations for a new job and wanted to let them know how much time I had spent away from home in the past.  The original version of this list was pretty messy, so I had to clean it up a lot with Google Refine before visualizing it using processing.

<br /> No Java 2 SDK, Standard Edition v 1.4.1 support for APPLET!!<br />

Most striking, you can see how our activity has become more sparse in the last few years. If you’re interested in the code, you can download the processing code.

Creating a video CD (VCD) from a YouTube video

As a Christmas gift for my father, I transferred a YouTube video of a public service announcement that he remembered fondly from his childhood to optical media so he could watch it on the television instead of on the computer.

There were some unique sets of constraints that made this an interesting project. First, I came to my parents’ house with only a Dell Mini netbook (with no optical drive) running Ubuntu Linux.  None of the computers had DVD writeable optical drives, but they could burn CDs.  My parents’ DVD player can play video CDs (VCDs) so I decided this would be a good option.

Capturing the video

I downloaded the YouTube video using the UnPlug extension for Firefox.  I chose to save the MP4 version of the video.

Transcoding the video

Since I would be burning the video on my mom’s notebook, I read the help documentation for the CD writing software to determine which video format the software needed to create a VCD.

VLC is usually my go-to tool for working with video, but I got errors about not having the correct codecs.  Rather than messing around, I wanted to just get the project done.  So, my next choice was FFmpeg.   It was a good choice because the software, though a command-line utility, has a preset for creating an mpeg file suitable for burning a VCD.

ffmpeg -i High\ Flight\ \(John\ Gillespie\ Magee\ Jr\ Poem\).mp4 -target ntsc-vcd high_flight.mpg

I was able to do this with the version of ffmpeg included with Ubuntu 10.04, but as ffmpeg is cross-platform it should be straightforward to do this on other platforms.

Burning the VCD

I copied the file to my Dropbox and downloaded it to my Mom’s computer using the services web interface.  Her burning software allowed me to just drag-and-drop the file into the burning program’s window.