Bulk-queueing photo posts on Tumblr

Let’s suppose you have a folder full of images and you want to queue
each image as a unique post
in Tumblr. You spend a few minutes manually
uploading each one as a queued post in your browser before exclaiming,
“Argh! This is terrible! There must be a better way…”

Several minutes of googling later you proclaim, “Argh! I can’t believe no one has made a tool to do this!”. Time to pour yourself a drink and break out some python.

  1. Install python-tumblpy
  2. Register an app for yourself on Tumblr – you’ll need this to get a valid oauth token for uploading
  3. Download and run this script

It will authorize your app and generate an oauth token. Pass it a list of images on the command line and each one will be uploaded and queued as a unique post. Each image that is successfully uploaded has “_done” added to its filename.


$7 USB Cloudwatch Notifier

Cloudwatch rocks and we have a ton of alarms to let us know when something breaks (or is about to break!). The only downside is that you can start getting a lot of emails or text messages and if you try not to chronically check your email, you might miss something.

If only there was some way to know something was broken without having to check your mail… luckily there is! For $7 you’ll never have to wonder about the state of your cloudwatch alarms again.

Step 1: Buy this USB mail notifier ($7)

Step 2: Grab this zip file to control the device. It contains compiled version of usbnotifierosx_cli for controlling the device and a very simple PHP script for checking if you have any active cloudwatch alarms.

Step 3: Run the script via crontab every minute. Light is green? No alarms… Red? Alarm!

You can now get back to work and never worry about missing a cloudwatch alarm again.

Thanks to Eric Betts for creating usbnotifier_cli!


Signing your SES mail with DKIM using PHPMailer and Route 53

If you use Amazon’s Simple Email Service to send email you might have noticed your messages have an unfortunate via listing in gmail – email-bounces.amazonses.com. To fix this, you need to sign your mail with DKIM before you send it.

To deliver mail, I was using PHPMailer with a custom SES delivery method. To start signing messages, I followed these steps:

Generate a key

I started by using the form here. The nice thing about the form is that it generates the keys and gives you a zip file that contains the keys, instructions on what to set your DNS txt entry to plus some sample PHP code for use with PHPMailer.

Unfortunately the key is 1024 bits which didn’t work when I tried to add a txt entry in Route 53 using the AWS management console, I kept getting a TXTRDATATooLong error. There seems to be a 255 character limit for TXT entries. Switching to a 768 bit key solved the problem. Here’s the code to generate the key:

openssl genrsa -des3 -passout pass:<change-me> -out .htkeyprivate 768
openssl rsa -in .htkeyprivate -passin pass:<change-me> -pubout -out .htkeypublic

(change the <change-me> password)

Add an entry to Route53

Add the following TXT entry to your domain in Route 53:

Name: mailer._domainkey
Type: TXT - Text
Value: "v=DKIM1; k=rsa; g=*; s=email; h=sha1; t=s; p=<key from .htkeypublic>;"

Sign and send a test email to yourself

You’re now ready to send yourself a test email to see if it has worked. Make sure you cc check-auth@verifier.port25.com in your message – port25.com runs a handy verifier that will reply to you with details about what worked (or didn’t work) in your message.

// blah blah blah, normal PHPMailer setup
$mail->DKIM_domain = 'yourdomain.com';
$mail->DKIM_private = 'path/to/dkim.key.private';
$mail->DKIM_selector = 'mailer';
$mail->DKIM_passphrase = '<change-me>';
// and then you send the email...

Hopefully everything worked and your via text in gmail no longer includes email-bounces!

Your sandbox is violating my security

Let’s suppose you come across the following error while debugging your AIR app:

*** Security Sandbox Violation ***
SecurityDomain 'file://.../art.swf' tried to access incompatible context 'app:/myapp.swf'

Let’s also suppose that you’re loading some artwork from art.swf – you’ve created some clips that you’re exporting for actionscript and you’re importing them in your app by using applicationDomain.getDefinition to get their class in to mypp. At some point in myapp you add some bits of that artwork to the stage you add some MouseEvents to a clip containing that artwork.

Suddenly when you try to interact with that clip, you start getting a whack of Security Sandbox Violations. Google to the rescue? Unfortunately, no. You will get a lot of Error #2048, 2122 posts but our simple art.swf doesn’t contain any code and isn’t trying to do anything funny. If you search for “*** Security Sandbox Violation ***” you’ll come across this stack overflow post which might give you an idea.

Perhaps Flash is trying to give the clip you imported from art.swf some kind of focus? A quick artwork.mouseEnabled = false, artwork.mouseChildren = false later and problem solved!

Some pseudocode to better demonstrate the solution:

// Load art.swf
// import class "Art" from art.swf
var my_art:Art = new art();
var my_clip:MovieClip = new MovieClip();
// Listeners that do mouse things...
// At this point, you may get your sandbox violated.. The solution?
my_art.mouseChildren = false;
my_art.mouseEnabled = false;
// Yay! Your security is safe

Flash Player Bugs – so much fun!

Public Advisory: If you have Flash Player version installed, upgrade it! There are some strange issues in that release that can cause MouseEvents to not report… perhaps in connection to masking or scrollRects.

What follows is the -vvv story of how I discovered the issue and a recommended solution.

Over the weekend mysterious bug reports began surfacing. Coinciding with a major update on our site it seemed like we must have introduced a new strange bug.  I couldn’t believe we didn’t catch it sooner, but it was uncommon enough that it could wait until Monday. On Monday morning I began testing against older versions of our code and no matter how far back I would go, I could still reproduce the bug.  At this point, I was losing my mind – how could code that was working perfectly for more than a year suddenly stop working? I began testing other browsers, other operating systems and eventually saw the pattern: if you were using Flash Player version you would encounter the bug. Annoyingly, isn’t listed Adobe’s list of archived flash versions – if it had been it would have saved much debugging.

So, what to do? When you use swfobject you can specify the minimum flash version required for your swf. I didn’t want to force everyone to upgrade to 11.1 (our tools work in flash 10 and above), so I added an extra check before embedding our swfs. If your flash version matches exactly, our minimum version is 11.1, otherwise it is 10.0. We get to take advantage of Flash’s streamlined expressInstall update process while allowing older users to stay put.

    var version = swfobject.getFlashPlayerVersion();
    v_check = '10.0.45';
    if (version.major == 11 && version.minor == 0 && version.release == 1) {
        v_check = '11.1.0';
    swfobject.embedSWF(swf, id, width, height, v_check, ...);

Hopefully this information helps someone else who can’t understand why working code suddenly broke…