six colors

by Jason Snell & Dan Moren

This week's sponsor

Protect your privacy and decipher iOS 11 network features with a new book by Glenn Fleishman. Get 25% off with code SIXCOLORS.

By Jason Snell

Bad AppleScript: Shell scripting and Automator

I know a lot of people who write software for a living. Marco Arment is one of those people. He’s the developer of Overcast, but he’s also a podcaster—and since he likes to scratch his own itch, he’s used his developer skills to write tools that help him produce his podcast. Tools that non-developery people like me, who also produce podcasts, can potentially benefit from.

Unfortunately, developery people tend to like things like shell scripts and other stuff that lives on the command line. The stuff they build for regular humans has beautiful interfaces and is made with users in mind; the stuff they build for themselves is often quick and dirty and purpose-built for an audience that’s comfortable with the very technical.

I write and talk about technology for a living, but I consider opening Terminal to be a last resort. That’s where AppleScript and Automator come in.

This all started when Marco tweeted about the shell script he uses to encode ATP’s episodes, complete with a link to GitHub:

Marco’s script is great, in that it uses a command-line tool to encode and tag a podcast MP3. And since he’s doing one podcast, with one episode per week, editing the script before every episode seems reasonable. As you might know, I do many podcasts, so I wanted something a bit more flexible—and ideally something that I didn’t need to dip into Terminal to use.

What I did was wrap Marco’s shell script in AppleScript code, and embed it in an Automator service, so that I can select the AIFF file that’s output by Logic Pro and watch as a fully encoded and tagged podcast episode appears on my Desktop.

The start of the Automator action accepts audio files from the Finder.

Now, most of you don’t run podcast networks, so the specifics of my needs aren’t as important as the general concept: I used AppleScript to step through a series of conditional statements and ask for some user interaction, and from all of that, it reconstructs the final output of Marco’s shell script as an AppleScript string and executes it.

The names of the files I send to this script have meaning, so the script matches the name of the file that I selected in the Finder using the satimage osax I mentioned in a previous Macworld piece about AppleScript.

on run {inputFile, parameters}

set theFile to inputFile as text

set theSlug to (find text "\\:([A-Za-z]+)[0-9]{1,3}.aif" in theFile using "\\1" with regexp and   string result)

set theNumber to (find text "\\:[A-Za-z]+([0-9]{1,3}).aif" in theFile using "\\1" with regexp and string result)

set theResultPath to (find text "(.*?).aif" in theFile using "\\1" with regexp and string result)

Now I’ve got the variable theSlug set to the short name of the podcast in question and theNumber set to the episode number. Once this is done, I ask for user input, using the filename as hints:

 set theSuggestion to "Enter Podcast Name"

 if theSlug is "theincomparable" then set theSuggestion to "The Incomparable"

 if theSlug is "tpk" then set theSuggestion to "Total Party Kill"

 if theSlug is "tvtm" then set theSuggestion to "TV Talk Machine"

 if theSlug is "teevee" then set theSuggestion to "TeeVee"

 set theShow to text returned of (display dialog "What show?" default answer theSuggestion) as string

 set theShowNumber to text returned of (display dialog "What episode?" default answer theNumber) as string

 set theEpisodeTitle to text returned of (display dialog "What episode title?" default answer "Episode Title") as string

 set theEpisodeSummary to text returned of (display dialog "What's the description?" default answer "Enter Description") as string

Now I’ve got the most important variables: The show’s name, its episode number, the episode title, and a summary of the episode’s contents. With this I can build Marco’s shell script myself, but first I have one more tweak…

 if theSlug is "tpk" then

 set monomode to "s"

 set quality to "128"

 else

 set monomode to "m"

 set quality to "64"

 end if

Total Party Kill, our Dungeons & Dragons podcast, is produced in stereo. So here I’m creating two variables, monomode and quality and setting them to 128kbps stereo for TPK and 64kbps mono for everything else.

With that done, it’s time to build something based on Marco’s shell script.

That’s a giant chunk of code. Most of it should make sense if you walk through it slowly and realize what variables are being dropped in where. You’ll see that I’m also embedding a show logo with each file, and since my show logos are stored in a particular folder with a consistent file naming scheme, the script knows it can use the show’s slug to select the right one.

Once that’s done, it’s time to make the donuts.

 do shell script theLameCommand

 end run

Now I can select an audio file in the Finder, right-click on it, choose Services > Make Podcast MP3, answer a few questions, and in a couple of minutes my file is ready. No visits to iTunes, no altering of encode settings based on which podcast I’m working on… all of that is gone.

My point here is not to expect other people to do exactly what I’ve done, but to see how you can adapt a shell script and turn it into something you can just use from the Finder.

Here’s a slightly simplified version of my final script, for the super curious. This goes in a Run AppleScript block in the Automator service file, and that’s it.

I’ve used this same method to script a (not yet publicly released, alas) utility that syncs multiple podcast audio files with a single reference audio track from Skype via a command-line utility. I can now select all those files (provided they’re properly named and placed in my Logic project folder) and with a couple of clicks, eliminate a whole lot of typing and dragging files into a Terminal window.

[If you appreciate articles like this one, help us continue doing Six Colors (and get some fun benefits) by becoming a Six Colors subscriber.]