LWA Webcam Revamp

We set up the first webcam for the Lake Wentworth Association (LWA) web site at least seven or eight years ago. It started with one of those old, beige eyeball webcams, which soon gave way to our old tape-based video camera hooked up through a TV tuner card. It didn’t take long for the stress of running constantly to turn the image output into a giant pink blob. After that, we did some looking and found that Canon digital cameras offered a remote capture functionality, turning cheap, readily-available still cameras into great webcams. We picked up a used Canon A20 and a power adapter up on eBay for something under $150. That camera did its duty for a couple of years before giving up the ghost. We went back to eBay and found a Canon A520, which is a great 4.0 megapixel camera with 4x optical zoom. Several years later, that same camera is still clicking away, taking a new picture every 15 minutes.

While the hardware has changed a bit, the software behind the scenes hasn’t. Our first couple of cameras just uploaded over the same set of four images; we didn’t keep an archive like we do now. Eventually, we realized what a great resource the camera could be for documenting the state of the lake for visitors near and far. The original archive pages I wrote to store daily photos were very crude PHP and they haven’t changed much since then. The archive sits nested inside of an outdated Mambo installation, which is in dire need of replacement. On the camera side, I wrote a BASH script that combines Capture, ImageMagick, and several other command line utilities to capture an image from the camera, test for the amount of daylight, resize to the appropriate dimensions, create a timestamp/temperature image, and upload the group of images to the LWA web site. The script has evolved over the years and it’s still quite functional, but the time has come for an upgrade. That’s where WordPress comes in.

I’ve been involved in a lot of WordPress development over the past couple of years at work and in my own time, and I’ve grown to love the platform. Plugins and widgets make it easy to build a system to do just about anything content-related. It’s that flexibility that recently got me thinking about developing a webcam plugin for WordPress. The code I developed years ago is simply too messy and customized for general consumption. The WordPress plugin I’m working on now will let anyone with a webcam and a bit of technical knowledge set up an archive of photos without much effort. WordPress’ XML-RPC API provides a simple base for uploading photos programmatically. I’ll also be creating a simple Python client that will handle the blog interaction on the camera side. Both projects are going to take some time, but I’m aiming for March to have working versions running. This timeline is intended to coincide with a re-launch of the LWA site in WordPress. For now, progress of the webcam projects can be tracked on GitHub: WordPress plugin and XML-RPC client.

SeacoastOnline.com’s Broken Pay Wall

Dear SeacoastOnline.com,

If you want to make money with your new payment model, consider hiring a web developer who could create a real login system to protect your content. All it takes is a few lines of JavaScript (four to be exact) in a bookmarklet to disable the current content “protections” and read an article. The system uses jQuery to hide content and show the pay wall, but the problem is that the full article content is delivered to the browser even for anonymous visitors. A complete login solution would do a server-side check to make sure the visitor is logged in before returning complete content. It can’t be that hard to do it the right way.

Update: The great Readability bookmarklet also makes the full article content visible with the bonus of removing ads.

Buy This Beer

BuyThisBeer.com is a little project I started to keep track of what beers I’ve tried, what beers I liked and didn’t, and what beers I’m seeking out. Right now there’s not much to it, but it gives me an opportunity to play with new technologies and techniques (there’s no fun in repetition, but there is in self-improvement).


I have a few goals I want to accomplish with this project:

  • Work with larger data sets and the programming challenges that brings, including finding efficient ways to traverse the data on the UI side as well as search it.
  • Make a usable mobile interface, with a light footprint and easy-to-navigate page elements.
  • Get to know Git for version control and Capistrano for easy deployment of changes (already set up).
  • Create a social sharing aspect of the site to let people network, share recommendations with friends, and receive recommendations based on their own ratings.
  • As time allows, experiment with opening a basic API to make the data accessible beyond the site. My main pet peeve with existing beer rating sites is their closed nature. I’ve been forced to write a page scraper for BeerAdvocate for the time being.
A long way to go on design...

Why Mockups Matter

I’m not a web designer. I’ll admit that. I do, however, appreciate how a good design can aid the development process. When I’m slicing a site, I’m often working with Photoshop files of the home page and a sample inner page, assuming the two layouts are different. The problem comes when there’s special functionality that needs to be implemented on the site. What if the client wants a quick quote form? What if there’s a one page order form? What if we need a custom search page? All of these pages will exist only as text in a project specification document. I could certainly throw something together in code and build it out as I go, but the odds are pretty great that what I build will not be what was expected. This is where mockups come in.

I was put on to Balsamiq by a co-worker. Balsamiq is an Adobe AIR desktop application for creating web mockups. It’s full of tons of common elements used on web pages: headings, text paragraphs and lists, input forms, layout elements. You name it, it’s probably in there. One of the nice additional items is an iPhone layout. I don’t care so much about phone apps, but this makes it really easy to do some layouts for mobile web applications. I’ve been using this functionality to lay out a simple mobile beer rating web application I’m working on. Below are a couple of the mockups I’m working from. On the left, the brewer page lists all beers for a given brewer. On the right, the beer page lets you rate the beer (in case your memory is… impaired).

There are some pieces of functionality that are left to be implemented like user account management and wish lists, but the nice thing about Balsamiq is that the output files are XML and, therefore, can be versioned (I’m now using Git). As I make updates, I can save new versions and still look back to see the progress of my mockups as the site specifications expand.

When In Doubt, rm -rf build

With Django 1.2 being released a couple months ago now, I figured it was the perfect time to upgrade and check out the new features. Nothing is ever that easy. After spending too many hours last weekend chasing a mysterious attribute exception with my application and finding no Google results on it, I finally traced it back to a dirty build directory in my Django checkout. After deleting the build directory and installing again, I was back in business.


'DatabaseFeatures' object has no attribute 'uses_custom_query_class'


rm -rf build


Don’t GET Destructive On Me

When building sites that handle dynamic data, it’s important to make sure that all HTTP requests are both intentional and authentic. Addressing the first issue is the easier of the two: requests that retrieve data should use the GET method while requests that modify data should use the POST method. For example, a request for a page that views the database record of an image should be passed using the GET method. This design approach can avoid unintended results when something like a browser plugin may “pre-fetch” pages by following links before the user clicks them. Think of the consequences if the plugin followed every deletion link… Fortunately, these plugins won’t follow form action URLs.

Here’s a code snippet taken from a sample display of an image record:

<div class="image">
  <a class="delete" href="/image/1/delete/">Delete image</a>
  <form action="/image/1/delete/" method="post"></form>

The user will see a link that, on its own, would bring her to a deletion confirmation page where a POST form would be displayed. By adding a form and a small piece of JavaScript (like the jQuery code below), we can skip the confirmation page and delete the record in one step.

  if (confirm('Are you sure you want to delete this image?'))

This method also follows best practices in that it functions without a need for JavaScript (a practice often referred to as progressive enhancement or graceful degradation).

Handling the second situation of ensuring that destructive requests are authentic can be quite a bit more difficult depending on your development environment. You need to include a special, one-time-use token (sometimes referred to as a nonce) in the request to ensure that it came from the authorized user (see cross-site request forgery. I’m often developing new sites in Django, a Python-based web framework, which inclues automatic CSRF protection for forms.