Not until you appreciate what a jerk I am!

The Roman Empire, 125 AD
Dat-daaaah-dah-daht! (baht baht) Dat-daaaah-dah-daht! (baht baht)
The lesson to take from this is to never date a musician. When you break up she will write a super passive-aggressive song that tugs at the heartstrings of everyone in Sweden and you’ll look like a total dick even though it’s her airing the dirty laundry.
Just for giggles, this new web app I’m working on is in Pylons. So much of it is dependent on configuration (the paster creation script installs all kinds of code all over the project directory). I think I’m impatient enough at this point of my life that I actually prefer the shrink-wrapped bumper lanes of Django to this approach.

via Batman (1966, dir. Leslie Martinson)
Shell script I saved as ~/bin/m4rify to convert arbitrary audio files to iPhone ringtones:
#! /bin/bash
if [ $1p == 'p' ]
then
echo USAGE: $0 filename.mp3
exit
fi
out_file=${1%%.*}.m4r
tmp_file=$1.converttemp
mplayer -ao pcm $1 -ao pcm:file=$tmp_file
faac $tmp_file -o $out_file -w
rm $tmp_file
Works fine in Ubuntu.
I rather enjoyed Barcamp Blackpool this weekend. I've been to a lot of conferences and Barcamps this year, but I did particularly enjoy a Barcamp on my home soil.
I made an effort this weekend to spend less time in talks, and more time talking to people, and I think it paid off. Along with giving my (now rather tired) session on pitching, I had some very rewarding one-to-ones with a some very smart people - so if I cornered you and wouldn't stop talking, take it as a compliment!
I did, however spend time in some talks. @timhastings talk on TagWalk was very interesting, though I would have enjoyed more detail on the code running the site, but then I always like to skip ahead.
@walterja, whose talks have become the highlight of the last few Barcamp events I've attended, presented a predictably fascinating look at sociometry, which I've had some experience with before, though with a very different intention. I think this talk brought together the most diverse members of the audience, it was great to see so many teachers in the audience.
The evening was a lot of fun, and talking to people I was pleased with how many were talking about their own projects, startups and ideas for what is next; very invigorating.
Most blog posts end with thanks for the sponsors, which I would like to echo, but I think someone needs to call out the excellent work of @ruby_gem, who seems to have the ability to pull together these events, run them flawlessly and make it look incredibly easy. You are an asset to us all. Thank very much for your work.
Oh, and I won the PadRacer tournament ;-)
Daaaaaaaaanielllllllllllllllllllll
I've a few projects coming up for 84labs which required location awareness. Location awareness works great with any recent phone, but for traditional clients, I needed to fall-back to obtaining the location from the client's IP address.
There is an excellent free IP location database hosted on datatables.org, which offered the easiest way to get the data which I needed. This meant using YQL, which I haven't used before; YQL is "an expressive SQL-like language that lets you query, filter, and join data across Web services".
So here is the code. I was using Python, Django and Python YQL module, but the same query presumably works with any language you choose. I've removed a lot of exception handling for clarity.
# Get the current user's IP address.
client_ip_address = request.META['REMOTE_ADDR']
# Create a YQL public query object.
y = yql.Public()
# Build the query.
query = 'USE "http://www.datatables.org/iplocation/ip.location.xml" AS ip.location; select * from geo.places where woeid in (select place.woeid from flickr.places where (lat,lon) in(select Latitude,Longitude from ip.location where ip="%s"))' % client_ip_address;
# Execute the query.
result = y.execute(query)
# ... et voila.
ip_place_name = result.rows['locality1']['content']
ip_location = result.rows['centroid']
That's it. The query just performs a simple select against the 'iplocation' database, then retrieves the latitude and longitude from the flickr.places database (flickr.places is part of the standard YQL set of databases, which is why we don't need a specific USE statement to be able to access it).
Yesterday, I wrote asbo.org.uk, a site which provides really basic visualisation of the UK's anti-social behaviour order data from 1999-2007. This data was recently released by data.gov.uk.
I wrote the whole site, wrangled the data, and deployed it yesterday afternoon, in about six hours. I've got some contract work coming up using CakePHP, so I wanted to try it out, and I wanted to see what I could do in such a short space of time. I'm quite pleased with the results. There's no analysis of the data, just presentation, but I was trying to see what I could do in the time I had, rather than develop features.
Originally, I wanted to write a 'how safe am I' sort of application, which could offer data about the types of crime most likely to occur in a given area, but this idea was pretty much killed by the time I saw the actual data available. Maybe I don't know enough about Excel-scraping, but I considerably reduced the scope of this project because the data was such a mess - it's just not worth the time to extract information from arbitrarily formatted spreadsheets. Formatting the single table of data used on asbo.org.uk took about three hours, which seems like a waste.
I was generally quite impressed with CakePHP; it's laid out in a sane way, though coming from Python some of the automatic discovery of models in the controllers feels a little bit magic, and I'm not sure I'm comfortable passing around arrays of data rather than data objects themselves, but it's not a deal breaker. I do like the layout system, something I commonly implement with blocks in Django, but seeing it formalised as part of the recommended approach to application templating is nice.
I put the source on Github,if anyone is interested.
There's quite a lot of buzz around Project Sikuli at the moment, so I spent time today playing with it.
Sikuli is a GUI automation engine which uses a vision engine to identify elements on screen. In practise, it works well as a quick way to script repetitive desktop actions, without having to learn the AppleScript actions an application provides, or how to hook into a desktop accessibility framework to manipulate applications. Instead, you tell the Sikuli engine how you expect regions of the screen to look, and then how to further manipulate them with clicks, key-presses and so on.
That is quite an abstract explanation, so here is a practical example.
Every morning, when I sit down at my desk, I do two things: I do some basic maintenance on my Mac, and I print out my day planner sheet. This only takes maybe 5 minutes, but I need to wait in front of the screen and click the right buttons at the right time. That's pretty dull, so here's how I'm using Sikuli to automate that.
First of all, the maintenance script. I use CleanMyMac to perform one big system clean every morning, which requires a few steps; launching the application, scanning for files to clean, approving the list of files, running the cleaning process, then closing the application.
My Sikuli script for doing this looks like this:

The script is fairly self-explanatory. First, it switches to (or opens) the CleanMyMac application, then runs the scan process. The script sleeps for five seconds, the searches for the 'scan finished' message, and goes to sleep again until that message is displayed. Then it performs the clean operation, and again waits for the 'clean finished' message. After this, it closes the application.
At no point is this script passing events directly to the application, nor is it querying the application to get information about its state; it's just examining the frame-buffer and looking for patterns which are similar to those specified in the script. On the Sikuli website, they claim their vision engine is smart enough to still work even if an application slightly changes it's visual style, but I haven't been able to test this.
This is the script for printing my day planner:

First, it closes then re-opens Pages so that it is in a predictable state. Then, the script manipulates the 'recent documents' drop-down, to open my 'Day Sheet 2' document. Notice that the script uses the 'wait' function frequently so that the vision engine isn't searching for an image before it has been drawn by the operating system. Once the document is open, we pass the operating system the ⌘P keyboard shortcut to open the print dialogue, then click 'print'. Finally, Pages is closed, and I check my printer tray. Here's a screen-cast of this in action. Note that I use the 'Run and show each action' button to start the script. This way, you can see the vision engine matching and highlighting each element on the screen:
Sikuli does have some limitations; You can't copy and paste between scripts, which I think is due to how the IDE stores image region data on the filesystem. Also, scripts seem wedded to the IDE, so you can't launch a script without needing to click the 'run' button in the IDE, but as the IDE is really just a thin wrapper over an underlying Jython instance, I'm sure this would be possible with a little more digging.
The obvious next step is to properly test how well Sikuli does deal with visual changes; using Sikuli to test web applications would be a great addition to the toolbox (and it would eliminate the problems with brittle tools like Selenium), and the IDE and language is simple enough for non-programmers to take some of the burden of writing tests.
I'm quite looking forward to the future of Sikuli. I'd like to see this visual search technology make it into more traditional scripting environments like AppleScript, though I'm not sure that'll happen any time soon, but anything which reduces reliance on bending traditional accessibility frameworks to perform in this role is a step forward.
"This is my project base. There are many like it, but this one is mine."
Today I finally got around to putting my Django project base on Github. I've been using this base for about six months now, and after a lot of rewrites and different approaches, it's now reasonably stable. I've been starting a lot of new projects recently, and repeatedly fixing the same small bugs in this project template, so I decided to spend a few hours this afternoon cleaning it up and making it public.
I'm not totally satisfied with my use of shell scripts to do some of the bootstrap actions (ideally I'd use Fabric for all of these tasks), and longer-term I want to make it easier to rename the django project rather than using search/replace in TextMate.
I know there are a lot of similar projects to this on Github, but none of them worked exactly like I wanted (I think too many depend on zc.buildout and similar), and while I'm not crazy about re-inventing the wheel, I hope there are enough other people out there who share my preferences who will find this useful.
Powered by Planet!
Last updated: August 11, 2010 04:52 PM
Planet Cleanstick is a content aggregator. It collects and displays posts from some of the greatest internet superheroes who have ever existed.
Jon Atkinson was born in Anchorage, Alaska in 1883. He was abandoned as a child and raised by local natives, who also subsequently abandoned him. After nearly starving in the harsh tundra, he discovered a special affinity with nature and began his lifelong quest to destroy civilization.
Isaac Cohen, te plus oculis meis amarem, Isaace iucundissime, munere isto odissem te odio Vatiniano: nam quid feci ego quidue sum locutus, cur me tot male perderes poetis?
Happy, or as you may remember him from his folk singing days, El Sonríe, retired from performing his unique brand of Tex-Mex folk/mariachi/country fusion in 1978. He is now quite active in his local church and has abandoned his corn liquor bootlegging ways.
Jason Scheirer has many faces, but none of them housewife. beginning in the late 1700s, he built a modest publishing empire that eventually, at its peak, incorporated every citizen in the Austro-Hungarian empire as an employee. He lost his fortunes on less-than-shrewd dogfight bets.
Sam Thursfield is obsessively paranoid and will charge if subjected to extended periods of staring. Please do not feed the Sam. If you would like, we have postcards in the gift shop after the tour. There are only 12 Sam Thursfields left in the wild, making it one of the most endagered species in the world. What you see here is a rare and wonderful opportunity to see a Sam Thursfield, which may not be available to later generations.