the further adventures of

Mike Pirnat

a leaf on the wind

343/365: Hello Kitty Loves Christmas Lights

343/365: Hello Kitty Loves Christmas Lights

The inspiration for today's photo experiment comes from Zac Paladino, who sent me a link that illustrated how change the shape of the circles of confusion in photographs. To achieve this shot, I cut a disc of construction paper the same size as the front of my lens, then used an X-acto knife to cut out a tiny heart in the center. I attached the disc to the front of the lens with scotch tape, opened the aperture way up so that I wouldn't see any of the inside of the paper, and went outside to shoot. The size of the modified circles of confusion can be controlled by altering the focus--the more out of focus, the larger the "circles" (or in this case, hearts). So for this, I took one photo of Hello Kitty and the lights waaaay out of focus to get the nice, big hearts, and one from the same vantage point but in focus. I then combined the two shots in Photoshop to produce the final image.

I also experimented with a star cutout.

This is a fun technique and super-easy; well worth playing around with for the novelty value if nothing else.

22 days to go...

Read and Post Comments

251/365: Friend Me

251/365: Friend Me

We always try to mix up something fun for the grown-ups who come to Claire's birthday parties, and this year is no exception. I really had to scour through the Mixology app to find something that fit with the "Lego Friends" theme that was also delicious, but in the end, I think that the "Friend Me" will be a winner.

So what's involved?

  • 2 parts reposado tequila
  • 1 part pomegranate liqueur
  • 1 part lime juice
  • 1 part simple syrup

Mix, shake, strain into a chilled glass, and garnish with lime. We tried adding a splash of tonic water in some experimental tastings and enjoyed what it did, but didn't mix it into the big batch for the party. Your mileage may vary, as they say.

Read and Post Comments

Unhijacking Alfred's Google Searches

My ISP hijacking a Google search

I'm pretty much in love with Alfred; it's usually the first thing I install on a Mac. For whatever reason, though, I rarely use it to fire off Google searches, usually going straight to my browser. But today I fired off a search from Alfred and was aghast to see a crappy hijacked results page from my ISP, who I'd previously praised for having a fairly mature attitude toward all things internet and not requiring me to have TV service with them. I think I invented at least three new, wildly-offensive swear words when I realized what was happening.

Now, my ISP hides a tiny little opt-out link in an area of the page that, is virtually invisible due to its proximity to what my brain perceives as pure garbage. (In fact I'd written most of this before I even noticed it was there at all!) But you might not be so lucky, or, depending on the way the opt-out is implemented, you might not stay opted-out, and anyway, isn't a clever DIY solution more fun?

Since Alfred just makes a URL and hands off to the OS's preferred browser, I fired up Charles to see what was going on. Sure enough, they're intercepting GETs to and throwing back a 302 to their own, crappy search, and I was able to quickly duplicate the behavior in my browser by cooking up the same form of URLs.

But why hadn't I noticed this before, using the search box in Safari, or by going straight to Google first? The reason is that my ISP's pattern-matching is delightfully naïve, so it doesn't catch the richer URLs that Google or Safari construct. This gives us the key we need to craft a workaround for Alfred: a custom search!

Custom searches are the cat's pajamas--I've rigged up a bunch for work to quickly drop me into our wiki, issue tracker, and so forth. Rather than waiting for the Alfred developers to provide a fix for the search hijacking, we can make our own custom search quickly and easily.

First, start by disabling the default Google search in Alfred. Open up its preferences, navigate into "Features", then "Web Searches", and then uncheck the Google checkbox:

Turning off Google search in Alfred preferences

Next, select "Custom Searches" and click the "+" to create a new one. You can then monkey with the URL to slip past The Man--for example, a simple alteration to the query string like{query} can do it. In my case, I chose to make the simple switch from HTTP to HTTPS, as it's likely to be more robust and gives me a nice, encrypted channel.

Creating a custom Google search for Alfred

To get the same nice logo that Alfred's default has, we can go get the icon out of the app itself. Right-click (or control-click) in your Applications folder and select "Show Package Contents". Then open the "Contents" and "Resources" folders and you'll find all of the icons. Find the "google.png" image and drag it over into the icon drop zone in your custom search.

Finally, we need to wire our new search into Alfred's "Fallback Searches". Pop open the one that's currently set to "Search Google for '...'" and scroll down to the bottom, where you'll find the custom search below a separator:

Replacing Alfred's fallback Google search

And that's all there is! Alfred is restored to full Google-searching glory. I'd like to say a huge thank you to the developers of Alfred for providing the flexibility that made this not only doable but easy. Huzzah!

Alfred searches Google, as it should be

Read and Post Comments

Get on a Winning Streak in 2012

Want to build a winning streak? Already on one that you don't want to see disrupted by the holidays, or--an even lamer excuse--broken by running out of calendar?

Never fear! I've whipped up a convenient one page 2012 calendar, and I'm publishing it early to make sure you've got plenty of time to get it into place.

Not sure what this is about? No problem--check out my original post. The short version is that having a highly visible calendar that I can check gives me a daily jolt to do do what I need to do to establish better habits. I transform the game from being about putting off what I know I need to do and focus it on building the longest winning streak I can.

My advice:

  1. Keep it simple--your criteria for success on any given day should be straightforward and easy to achieve. "I flossed today."
  2. Put it somewhere visible--you should not be able to evade a daily confrontation with how you're doing. After just a few days in a row, this will be something you're excited to see.
  3. Keep a pen or marker nearby and don't let it get out of range--if you don't mark your wins, you won't have the visual reinforcement.
  4. Have lots of extra calendar available--you don't want your streak to die just because it's a new month.
  5. Don't freak out if a long streak gets broken; now you have a new high score to try to beat!

You can download my 2012 one-page calendar and start your winning streak today.

What are you waiting for?

Read and Post Comments

My DIY Photo Lightbox


It all started with the Legos.

I love building Lego kits, and have for many, many years. And I've found that for the bigger kits, like the Star Destroyer, it's a lot of fun to shoot photos as I go, so that I can look back at the building process in time-lapse fashion. So when my daughter and I started assembling the Death Star together, it was only natural that I'd take pictures every few steps so that we could have a record of our achievement.

That, of course, led to silly pictures of Stormtroopers busily assembling the dreaded space station under the stern supervision of Duplo Jessie.

And that led to the inspiration to use silly photos of minifigs in a Keynote deck for work. What better way to highlight the dangers of SQL injection attacks than Han Solo and Luke Skywalker infiltrating a group of Stormtroopers and wreaking havoc?


And that was the kick in the pants I needed to build my own little lightbox for macro photography. It's basically the same as the recipe from Strobist, WikiHow, and others--a cardboard box, some tissue paper, and a sheet of white posterboard. I spent about seven dollars in all, and most of that was on the box. Assembly pretty much goes like this:

Try not to cut yourself on the box cutters or X-Acto knife you use for slicing out sections of the box (luckily my experience in life-size cardboard ninja preparation had prepared me for this, but that's another story).

When you're all set up to shoot, it might look something like this:

I can't tell you how exciting that moment is, as an amateur photographer, when you do something that looks like that. You really feel empowered, and there's a wonderful feeling that you know what the hell you're doing. It's great!

Here's how my first test shot (the cyborg-versus-alien scene shown in the photo above) turned out:

Gun Fight
Gun Fight
Originally uploaded by mikepirnat

Lessons Learned

I learned several key lessons that are worth passing on:

  1. Brighter, Whiter Lights

    I grabbed whatever was handy (the reading lights from my bedroom, in this case) to provide lighting. Great idea in terms of directionality and ability to get lights close to the box, but a seriously bad move overall because they were loaded up with low-wattage "soft white" CFL bulbs. You really have to up the exposure to compensate for the lack of brightness, but with a tripod and a remote shutter release, that's no big deal. What really sucks is the sheer, awful yellowness of the "soft white" bulbs, which guarantees that you'll be spending a lot of time doing color correction in post. I had to do quite a lot with temperature, exposure, color balance, lightening of shadows, etc. in order to get acceptable colors. Halogen work lights ought to do it, as long as I keep them far enough back from the box to keep from lighting the tissue paper on fire.

  2. Start Small on Tissue Paper

    Like a good engineer, I decided to evenly allocate all of my tissue paper so that I was able to use the maximum amount out of the eight sheets in the package I bought. (Waste not, want not, right?) Well, it turns out to be a dumb maneuver because it's easier to add more layers of tissue paper than it is to remove them once they're taped into place. I had three layers on mine; I think two would have done the job (or mabye just one?).

  3. Clean Your Lens, Clean Your Sensor

    Given the tripod and remote shutter release, I figured I could narrow down my aperture to F22 and beyond and thereby maximize my depth of field, thereby ensuring that i didn't have characters (or parts of characters) that were inappropriately out of focus. Turns out that when you do this, every piece of dust on your lens or sensor (I suspect the latter may be the worst of my problems at this point) comes into sharp relief, and once again you're spending a ton of time in post. Retouching the dust spots out late isn't too bad... until you're doing it to a full batch of 150 or so images. At that point, you've entered a whole new world of pain.

  4. Tripod and Remote Shutter Release

    This kind of work is impossible (or next to impossible) without a stable platform and a way to shoot without jiggling the camera, because you will be taking shots that may need a half second or a second (or more!) to capture. It would be a shame to set all this up and not have the camera equipment you need.

  5. Low ISO

    I went with ISO 400, which is okay when I'm shooting hand-held indoors, but if you've already got the luxury of the tripod and remote release, you might as well go with longer exposures that yield less noise. I was frustrated by the amount of noise I picked up at 400, though it may be due in some degree to shooting in JPEG (where the all-white background leads to poor-looking compression artifacts).

The most important lesson, of course, is that this is fun and that you can do it too. It's cheap, doesn't require much skill, and leads to highly satisfying results.

I'll post some of my Star Wars minifig shots next time. Promise.

Read and Post Comments

Get on a Winning Streak

There are things I want to do, that I need to do, that I should do, but that are so very, very easy to postpone. Oh, I'm so tired, I'll just floss tomorrow. Oh, I don't feel like working out today, I'll start up again next week. Before I know it, months have passed and I have to deal with the fallout from my continuing procrastination.

The best way I've found to combat this is to change the rules of the game. I put up a calendar in a place that I'm going to have no choice but to see every day, and every day that I do what I ought to, I put a mark on the calendar. Now the game isn't about "omg floss or die", it's about making the largest unbroken run of marks on the calendar that I can. The longer the streak, the better--and the more pressure there is to not break the streak.

The first time I tried this, I printed out a blank month from Google Calendar and taped it up to the wall by my bathroom sink. It worked great until the end of the month--at which point I started procrastinating about printing the next month's calendar. Oh, it just takes a minute, I'll deal with it tomorrow. So this time, I've made myself a one-page calendar for the whole year, so I have no excuse as March flips over into April--I can just keep on building an epic winning streak.

So here's my advice:

  1. Keep it simple--your criteria for success on any given day should be straightforward and easy to achieve. "I flossed today."
  2. Put it somewhere visible--you should not be able to evade a daily confrontation with how you're doing. After just a few days in a row, this will be something you're excited to see.
  3. Keep a pen or marker nearby and don't let it get out of range--if you don't mark your wins, you won't have the visual reinforcement.
  4. Have lots of extra calendar available--you don't want your streak to die just because it's a new month.

You can download my 2011 one-page calendar and start your winning streak today.

What are you waiting for?

Read and Post Comments

How I Deploy My Blogofile Blog on Webfaction

This is partly to help anyone else, but mostly so I don't forget...

Installing Git

Before you do anything, you'll need some git binaries, since they aren't yet installed by default on Webfaction. See Webfaction's git setup docs for how to do this.

Make a Webapp

Use Webfaction's panel to create a new static html web app (assume we'll call it "my_blog").

Making Directories

A little directory setup will be nice:

mkdir $HOME/src
mkdir $HOME/src/my_blog.git
mkdir $HOME/tmp
mkdir $HOME/tmp/my_blog

Getting & Installing Blogofile

I'm a nerd/Blogofile contributor, so I like to roll with the head of the repo.

In my case, I'm getting my own personal fork:

git clone $HOME/src/blogofile
cd $HOME/src/blogofile
python2.6 develop

You'll want to do this on Webfaction and on your local machine (so that you can do offline builds to test).

Initializing the Repo

cd $HOME/src/my_blog.git
git init --bare

Clone it Down

On your local machine:

git clone ssh://username@yourdomain/~/src/my_blog.git

On Webfaction:

git clone ~/src/my_blog.git ~/tmp/my_blog

(After all, we need somewhere to automatically freshen and build from!)

Init the Blog


cd my_blog
blogofile init simple_blog
git add _controllers _filters index.html.mako _posts _templates
git commit -m "Initial checkin of new blog"

First Push

Git really wants a branch to push into, and we don't have one of those yet. Just doing git push will cause git to shit its pants. So instead we have to do the oh-so-obvious:

git push origin master

Did that work?

Create Post-Receive Hook

On Webfaction:

cd $HOME/src/my_blog.git/hooks
vim post-receive

My (very basic!) post-receive hook looks like this:



unset GIT_DIR
git pull
blogofile build -v && rsync -a --delete-after $SITE_DIR $DEPLOY_DIR

This makes sure that:

  1. We get a fresh copy of the blog source
  2. We don't build inside our live site (in case anything goes wrong!)
  3. We don't rsync if the build died
  4. We sync all our changes into place and remove anything that we shouldn't have any more

TODO: I really, really, really need to rearrange this so that we don't do the build at all if the build area's checkout (in ~/tmp/my_blog) was up to date/didn't get any changes. Maybe not a big deal for everybody, but I've got like 1400 blog entries and it takes a while to regenerate all that HTML. I mostly dislike shell scripting, so I will probably write a small amount of Python here at some point.

Also it would probably be good to check any new/changed _posts items to see if they are drafts, because again it sucks to do a bunch of work that we don't have to. Hmm...

Compose a New Post


cd my_blog
vim _posts/hello-world.markdown

Push It!


git add _posts/hello-world.markdown
git commit -m "First post, woot"
git push

And hopefully it all Just Works!

  1. git pushes to remote repo
  2. post-receive hook fires
  3. tmp checkout is freshened
  4. blog is rebuilt
  5. blog is rsynced into place

Write Compelling Content

Now it's time to crank out that undying prose that will forever change the world... get to it!

Read and Post Comments

Configuring Wordpress SSL Login and Admin on Webfaction

image: bike covered in bike locks

I finally got fed up with not having SSL for my Wordpress instance on Webfaction and decided to rectify it today. I ran into a couple of surprises along the way that were really irritating, so once I sorted them out I figured I owed the internet an explanation so that things would be easier for anyone else wanting to do the same thing.


I'm going to assume that you already have a Webfaction account with a Wordpress instance running on it. If not, the control panel screencast is an oldie-but-goodie that'll get you started. I'm also going to assume that you're on one of the basic, shared hosting plans, and that you'll be running your secure stuff on the same box as your non-secure site. And I'm also assuming that you'll be okay using Webfaction's default SSL certificate rather than your own--this will throw warnings in many browsers, but saves you the cost of purchasing your own cert and the time required to request a private IP from Webfaction. And this only applies to Wordpress 2.6 and above. (You really should upgrade, you know.)

Create a secure site

In the Webfaction world, a single "site" can only be non-secure or secure, so you need to create a new site that will largely mirror your existing, non-secure site. To do this:

  1. Log into the Webfaction control panel.
  2. From the Domains/websites menu, pick Websites.
  3. Click the little green + icon at the bottom-right of the websites panel to begin creating a new site.
  4. Give your new site a meaningful name (I like it to be the same as the non-secure site, but with "_secure" or something similar tacked onto the end).
  5. Choose the same IP as the non-secure site that you're adding SSL to. Unless you are fancy enough to have multiple IPs, this shouldn't really be a choice at all.
  6. Check the HTTPS checkbox. (This is important.)
  7. Choose the same subdomains as the non-secure site that you're adding SSL to--so if your site is at, you might want to make sure that you select and subdomains so that both will be connected to this configuration.
  8. In the Site apps section, add your existing Wordpress instance with the same URL path that it has in your non-secure site. If you've got an app called my_blog at /blog, make sure you do the same thing here.
  9. Click Create.

Fix your Wordpress URL configuration

If you visit your blog now (in non-secure/http mode), depending on your browser, you might see a complete and total failure to load your stylesheets--meaning that your site is now probably fairly ugly. If you view source, you'll see that, even though you aren't loading your page from over HTTPS, Wordpress is generating HTTPS links for all your content--stylesheets, images, everything.

To fix this:

  1. Log into your Wordpress instance and go into the Dashboard.
  2. Go to the General Settings page.
  3. Change the WordPress address (URL) and Blog address (URL) fields to begin with http instead of https.
  4. Don't forget to Save Changes.

Now try your site on its non-secure/http link. When you view source, all your resources should be coming from URLs that start with http.

Update your wp-config.php

Edit your wp-config.php. Depending on what you want to do, you'll add one or the other of the following two lines.

To require only login to be secured:

define('FORCE_SSL_LOGIN', true);

To require login and admin pages (my preference) to be secured:

define('FORCE_SSL_ADMIN', true);


Log out of your Wordpress instance, then hit your login link. You should now see that your login and registration pages are served up via https links. If you chose to use FORCE_SSL_ADMIN, you should also see https in all of the URLs as you navigate around your Wordpress admin area.

Things should be hunky-dory now. I hope it worked out all right for you!

Read and Post Comments