Steve Good

Photographer, Developer, Human

Moving Forward and a Tiny Planet

Moving Forward

For the last two years I have been a full time contractor at KaiNexus serving as their Principal Architect. During this that time I made new friends and had the opportunity to work on a project that could leave a great positive mark on the world. However, as with all things, this chapter has come to a close. Starting this month I will be transitioning from KaiNexus to Cisco Systems. While I'm not a big fan of the corporate machine, the team I'll be working with is small and has that startup feel about it. I'll still be working with Flex but I'll be focusing much less on the server-side of the application, which is a big shift for me.

In addition to a change in career, I've moved my site, as you may have noticed. Last May I moved my site from Posterous to a custom built Grails application running on Jelastic. A few months later I moved the application again from Jelastic to AppFog as an experiment. Sadly, that experiment never quite met my expectations. During my time hosting the application on AppFog I experienced many outages, difficulties in deployment and had to make significant changes to the app just to get it to run. This was a very different experience from Jelastic where deployment was a no brainer, was always up and required no code changes to make it compatible. I've raved about Jelastic in the past and I still do, however, as my time becomes more limited and I spend more free time persuing photography I find myself letting the Grails app I built fall behind. I just don't have the drive to maintain it anymore. As a result, I've moved my site off of my home brew application and over to Squarespace. So far, the experience has been pleasant. My only issue has been with migrating comments (if you know how I can do this please let me know!) and as a result I've left some posts off the new site.

So far June has been an exciting month of change. I'm looking forward to seeing what else is on the horizon!

A Tiny Planet

A few weeks ago I decided to try my hand at a quirky form of panoramic photography. The process involves shooting a series of overlapping photos 360 degrees around a fixed point, just like with a typical panorama. The fun part comes into play when you take the stitched photos into Photoshop and turn them into a sphere. The result is a tiny planet with giant landscape and buildings. After shooting a few of these it seems like the most successful shots are of scenes with little skyline clutter and only a few tall points of interest. Here's one of my favorites of a simple parking lot in Fort Worth.

Simple URL Monitor Using Groovy and Twilio

Recently, the need arose for me to monitor a URL so that notifications could be sent out if the site was suddenly unavailable. Later on down the road this will need to evolve into a more proactive system rather than reactive but for now I am just focusing on site down notifications.

To start, I set some minimal requirements for myself.

  • Needs to be easy to write, can't take more than an hour to build
  • Needs to be easy to maintain, problems should be easy to find and fix
  • Needs to be able to send SMS messages in case of outages
  • Needs to be able to run standalone or on a server under cron

When looking at the requirements I had to think about what kind of scripting environment would be best served for the task. I had several options available to me each with pros and cons.

  • bash
    • Pros
      • Runs natively on any *nix based system
    • Cons
      • Extremely verbose
      • Will not run on non *nix based systems
  • Perl
    • Pros
      • I would be able to drudge up ancient knowledge that I had buried deep in the catacombs of my mind
    • Cons
      • I don't have enough time to drudge up my ancient, and dusty, knowledge of Perl
      • I would spend too much time trying to figure out how to do everything in a single line of code
  • Groovy
    • Pros
      • I work with Groovy every day at work
      • I can use Grape to supply dependencies using the @Grab annotation
      • Code tends to be clean and simple
      • Can be run on any system that has Groovy installed
    • Cons
      • Must have Groovy installed
      • It is a little slow to startup

It should be no surprise that I chose to use Groovy for this project. For me, Groovy just fits the bill better in terms of code verbosity and features available.

Building the script was a snap. One of the cool things about shell scripting is that you are able to specify the binary that you want to use to execute your script. So by adding a single line of declaration I was able to create a script that can run as if it was a native executable.

#!/usr/bin/env groovy

After that it's just a matter of writing the code that does the work! Lets start with the dependent libraries.

First I needed to make sure I had the HTTP-Builder library. Grape makes this a snap to get by letting me take advantage of the @Grab annotation. I just place the following towards the top of my script and like magic everything I need is available.

@Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.5.2')

I also need to make sure I have the Apache commons httpclient libraries. I use another @Grab to do this.


Grape is actually going out to the maven repositories and downloading the jars I requested and adding them to my classpath. Pretty slick eh?

I'll skip the imports (but you can check out the full source if those kinds of things excite you) and just straight to the guts of the script.

Next, among other things, I wanted to make sure that the script was configurable enough that I could add a list of phone numbers and be able to easily specify the url to monitor. To do that I created a nice little HashMap of key value pairs.

def options = [
        server: "",
        intervalSeconds: 600,
        sid: "",
        authToken: "",
        fromPhone: "",
        toPhone: "",
        smsOnStart: false,
        smsOnStartMessage: "Site monitoring script started at ${new Date().format('H:mm:ss')} on ${new Date().format('yyyy-MM-dd')}"

Ok, so options are great, but without some functionality they really mean nothing. Next I define two functions.

Here's the method that sends the SMS.

def sendSMS(def message, def opts){
    if (opts.sid != "" && opts.authToken != "" && message != ""){
        String twilioHost = ""
        String sid = opts.sid
        String authToken = opts.authToken

        def hc = new HostConfiguration()
        hc.setHost(twilioHost, 443, "https")
        def url = "/2010-04-01/Accounts/$sid/SMS/Messages"

        def client = new HttpClient()
        Credentials defaultcreds = new UsernamePasswordCredentials(sid, authToken)
        client.getState().setCredentials(null, null, defaultcreds)

        opts.toPhone.split(',')?.each { toPhn ->
            PostMethod postMethod = new PostMethod(url)

            client.executeMethod(hc, postMethod)


And here's the method that checks the status of the url.

def doPing(def opts) {
    if (opts.server != ""){
        try {
            new HTTPBuilder( opts.server ).get( path:'' ) { response ->
                def msg = ""
                if (response.statusLine.statusCode == 200){
                    msg = "${new Date()} :: UP!"
                    println msg
                } else {
                    msg = "${new Date()} :: There might be a production problem! -> ${response.statusLine.statusCode}"
                    println msg
        } catch( e ){
            println "${new Date()}"
            sendSMS("There was an error when connecting to the production server, it might be down.",opts)

        if (opts.intervalSeconds > 0){
            def then = new Date()
            then.seconds += opts.intervalSeconds
            println "Checking again at ${then}"
            while (new Date() <= then){
                // do nothing

            doPing( opts )

Since these are both method declarations and they won't just call themselves we need to do one last thing, call the doPing method.

if (options.smsOnStart){

doPing( options )

That's the whole script! If you are interested in looking at or using the script Github's going to be the best place to do that. With comments and code the whole thing come to a mere 106 lines of code! Not bad for something that monitors a URL and then sends an SMS when there is a problem.

I know I glossed over how the methods actually work but I felt they were pretty self explanatory. Feel free to ask questions in the comments if you would like further explanation.

Thanks for reading!

New KaiNexus Video

KaiNexus, the company where I am the Principal Architect, has just released our latest "Explainer" video. The new video includes 3 use cases and a bunch of screen grabs from the actual software. This video is quite exciting as I think it really shows what kinds of problems our software solves. Check it out!

The Way Out

SmugMug Grails Plugin Update

A few weeks ago I mentioned that I was building a Grails plugin that aimed to wrap the SmugMug API. As of today, I am about 80% done with the coding and will be giving it a through test phase and creating docs soon. Once done, it will be available through the normal Grails plugin channels and be completely open source.

The Way Out

Sometimes it is so easy to ignore the things around us that we see on a daily basis. The subject of this photo was no exception. This is a walkway at the office complex where I work 5 days a week and I never once thought to bring my camera and shoot it. A few days ago I decided to change that. Here are the results.

The Hallway

Living in a Hospital

I've spent the last five days pretty much living at UT Southwestern Medical Center. My step daughter has been unable to eat more than a few bites of food without throwing up for about three months. After many tests and even a surgery to remove her gall bladder, doctors finally admitted her to the hospital for observation and even more tests. As a result, my wife and I have spent nearly the whole time living I the hospital room with her. I ask, for those comfortable with it, for prayers for her health and that the doctors would be able find the problem and come up with a solution.

The Hallway

There is a really interesting hallway at UT Southwestern Medical Center that just screamed "spooky" at me. I wanted to grab my camera and shoot some of the interesting angles and lines but I was a bit worried about offending patients and staff by walking around the hotel with camera and tripod in hand. As an alternative, I used my iPhone and captured the following video. I processed it a little bit in iMovie.

Stone, Steel and Glass


I saw a post on Google+ where someone posted a collage with the brackets used to make up one of their HDRs. I thought this was pretty cool and decided to do one of my own using Diptic for Mac. What do ya' think?

Stone, Steel and Glass

This is the finished product of the image above. It was taken in downtown Fort Worth on my last photowalk research day. I was fascinated by the combination of glass, metal and concrete and the lines they formed. Normally, this is filled with flowing water but I got there just shortly after they turned everything off. I really dig the way everything looks even without the water.

What Big Teeth You Have

The Repository Visualized

A while back I found a really interesting utility for visualizing the activity of a Git repository. Here's a cool little video of the repo for this site as visualized by Gource. Enjoy!

What Big Teeth You Have

I have been experimenting with a number of different photography techniques, one of those is the invisible black backdrop. Using this technique, I decided to follow my chihuahua around and generally annoy him with my flash. The result was a yawn captured at just the right moment. Isn't he just so vicious?

Sundance Court

Father's Day

To all the father's out there, including my own, happy Father's Day! Kids, if you know what's good for you you'll wait on dad hand and foot! No, really.

Sundance Court

I grabbed this shot while doing research for a future photowalk around Fort Worth. It was a little bit of a surprise for me since I found this on a street that was more of an alley. It is located behind Risky's BBQ at Sundance Square.

The Milk Silo

Grunge + Portraits = Hours of Fun

I started messing around with some techniques to add a feeling of grunge to a couple of the portraits in my library (nothing worth sharing yet) and found that I can't get enough. I found a pretty good, if not fast, tutorial (below) on the basics of applying grunge to a photo. One thing to note, I don't have one of the plugins this video uses but I was able to get the same effect by creating a new layer and desaurating it completely and messing around with the levels, curves and exposure. It's not as easy as the plugin filters but it costs way less.

The Milk Silo

I stopped on my way home from the office about a week ago and took a few shots of a park that I pass everyday. It is amazing how many power lines and other modern things there are in almost every frame I want to capture. This was one of those rare shots where I was able to avoid the power lines and hide the pesky water towers and street lights. All-in-all, I like the final result.