Posts Tagged ‘scripting’

Quick email list

Continuing my series of occasional posts on scripting as a way of quickly eliminating the drudgery of computer work, today I’ll describe how I generated a nice-looking list of email addresses from a spreadsheet.

My wife and I are the parent organizers of the water polo team at our neighborhood pool, and this morning I needed to send out an email to the parents of all the kids on the team. I have the team roster in a Numbers spreadsheet,1 with a line for each team member and columns for names, ages, phone numbers, email addresses, and so on.

Now I could have started by just copying the column of email addresses, but I wanted the address list to include the real names of the recipients. When I get mass emails, I always appreciate getting the real names; if I have to send a message to someone on the list, I don’t have to guess who’s who from a list of cryptic addresses. So I added a column to the spreadsheet and used this formula

=CONCATENATE(Mother," ",Last," <",Email,">")

to assemble addresses that looked like this:

Ashley Jones <aljones47@comcast.net>

I used the mothers’ names because they’re the ones who run the family calendars. If Numbers didn’t allow me to use the column headers as variable names (Mother, Last, Email), I would have used A1-style cell addresses to accomplish the same thing.

I get a lot of emails that use this format

"Ashley Jones" <aljones47@comcast.net>

The quotation marks aren’t necessary and seem stupid to me. It’s as if you’re saying her name isn’t really Ashley Jones, that’s just her CIA-supplied alias.

(The example name is sort of a joke. None of the 40-something moms are named Ashley—they have sturdy 60s names like Mary and Vickie and Patty. It’s their daughters who are all named Ashley.)

OK, so that gave me a column with real names and addresses. I copied the column (sans header) and pasted it into TextMate, which gave me a bunch of lines. Then I used the magic of Unix to prune and finalize the format of the list.

There are a lot of siblings on our team, which meant that the raw list of addresses would have duplicates of moms with more than one kid. So I used TextMate’s Filter Through Command… (at the bottom of the Text menu; shorcut ⌥⌘R) to eliminate the repeats.

The sort command gathered all the duplicates together, and uniq2 deleted the repeats. I needed to sort the lines first because, from the uniq man page,

Repeated lines in the input will not be detected if they are not adjacent, so it may be necessary to sort the files first.

The vertical bar piped the output of sort into uniq, just like on the command line.

With the list down to a minimum, it was time to change it into a comma-separated list. This find and replace

did the trick. Note that there’s a space after the comma in the replace string.

Now I had all the addresses, one for each mom, in a format that could be copied and pasted into the To field of an email message. I saved the TextMate file in my Dropbox folder, so it’s available at both of my computers. (Yes, I could have added these people to my Address Book and created a Water Polo group, but at the moment I doubt I’ll need to send more than one or two emails to this group. If I change my mind, it’ll be easy to add contacts to the Address Book from the To field in Mail.)

As is always the case, this took much longer to explain than to do. Because I already knew how sort, uniq, Filter Through Command…, and regular expressions work, the TextMate part was done in less than a minute. The most time-consuming part was generating the email addresses with real names in Numbers, because I wasn’t sure whether it concatenated strings through a function or through an operator like + or &. Even that took only a couple of minutes to figure out.


  1. Let me note here that I dislike spreadsheets in general and have a particular dislike of Numbers, but since the .xls format seems to be the lingua franca of the sales and management types who comprise most of the parental stock of my neighborhood, I have adapted. 

  2. The Unix guys were big on saving keystrokes; see cat


Scripting and the iPad

I’m happy to see that Alex Payne has retracted some of the ill-considered things he said about the iPad back in January. While it would be nice to think that his change of heart came from listening to his elders, the real reasons he no longer thinks of the iPad as the harbinger of a computer dystopia are

  1. he’s a smart guy and willing to question his own views; and
  2. he now has an iPad and likes it.

In fact, this latest post of his has one really good criticism of the iPad:

Apple should lift restrictions on running interpreted code on its mobile devices. Let people run Basic, Python, and Ruby interpreters on iPad and iPhone; we could make amazing tutorial applications for these and other programming languages. Let them run emulators for obsolete devices so intellectual property for them that has passed into the public domain can live on. Given that users can do much of this by virtue of Safari containing a JavaScript interpreter, the restriction seems arbitrary and backwards.

Of course, I say this is a good criticism because it’s my criticism. The apparent inability to script the iPad is the main reason I won’t be getting one—at least for a while.

What do I mean by apparent inability? Well, certainly you can’t use Perl, Python, or Ruby (or Basic or AppleScript or any other language best not to think of on a full stomach), but the iPad is sort of scriptable. As I said in January, the presence of Numbers gives the iPad an interpreter—assuming that IF, AND, and OR are among its 250 predefined mathematical functions.

More important is the JavaScript interpreter. We’ve certainly learned over the past few years how “real” web apps can be. Of course, you need space on a server to deliver web apps, and your iPad needs an internet connection to access them.

Or does it? One of the iPad’s most interesting features is the ability it gives apps to share certain types of files with other apps. Here’s Andy Ihnatko’s description of how it works:

The iPad OS still denies onboard apps the ability to access each others files and data. But there’s a mechanism that lets these apps tell the OS “Here are a list of filetypes that I know how to handle” and also to allow the user to easily steer a file to an app that can edit or view it.

If your boss emails you a Word document and you tap the document icon, Mail will present an “Open In …” button. Tap it to bring up a list of Word-compatible apps on yor iPad. Select the app you want, and the app will launch and import the document.

Any app can implement this and add its known filetypes to the service. A comic book reader can handle .CBR and CBZ files; a photo editor might offer to handle .PSDs … etc.

The feature delivers a lot of solutions in the ongoing problem of moving docs on and off the device. If you use a cloud storage service like Box.net, for example, the Box.net iPad app can present you with a list of all of the desktop documents you’ve saved in the cloud, and allow you to import and edit them into any appropriate iPad app.

One would think, then, that Safari would tell the OS that it knows how to handle HTML files,1 and you could, therefore, run certain web apps—those that are self-contained and don’t require communication with a server—locally. No one has confirmed this, despite my plea on Twitter.

As I learned quite a while ago, you can run self-contained web apps on the iPhone, but not in Safari. You have to use one of the many transfer-and-view applications, like Olive Toast’s Files. Unfortunately, in my limited experience, these apps don’t provide a user experience as good as Safari’s.

So, iPad users: can you answer my Twitter question. Can you transfer HTML files to your iPad and open them in Safari? Because if you can, that opens up a much broader realm for scripting.

Update 4/7/10
In the comments, reader jih mentions data: URLs as a possible workaround if there’s no way to open local HTML files in Safari. These data: URLs work on the iPhone, so I see no reason they wouldn’t work on the iPad. Here’s a simple explanation and example.


  1. And possibly CSS and JavaScript files, too, although it can only handle them in the context of an HTML files. In practice, it’s the ability to handle HTML that counts, because the CSS and JavaScript can always be embedded. 


My script hall of fame

Many of my posts here have been about the writing—or rewriting or rerewriting—of scripts to automate the dull, repetitive, clicky-click tasks so common to computer use. While almost all of these scripts have been worthwhile, a few have proved so useful that I use them on a weekly or even daily basis. These are the member of my personal scripting hall of fame.

Folder labels

I like the project file folders in my office to have crisp laser-printed labels. There are plenty of templates out there for Avery labels and their clones, but they’re usually made for MS Word or some other program I don’t use. Also, there’s a lot of repetitive typing associated with those templates, and I obviously want to avoid that. So I wrote a script called pflabels that takes plain text input in a simple format and generates output for printing on a sheet of 1″×4″ labels (Avery 5261 or the equivalent).

The input looks like this:

#Kernighan Building|4215
Drawings

Contract

Correspondence

Photographs and
videotape

#Ossanna Residence|4332
Report

Correspondence

The headings, which have the project name and number separated by the pipe character (|), are denoted with an initial hash symbol (#), and individual labels are separated by blank lines. If I’m going to make several labels for the same project (which is usually the case), I need only enter the heading once. The script takes two options, -r and -c, which tell it which row and column to start on, so it can print on label sheets that have been partially used.

I generally type up my label input in TextMate and then run pflabels on that input via the Text>Filter Through Command… (⌥⌘R) command.

Screenshot uploader

This script, called snapftp:

  1. Takes a snapshot of some portion of my computer screen.
  2. Names it.
  3. (Optionally) resizes it.
  4. (Optionally) uploads it to my blog.
  5. Puts the URL of the uploaded image on the clipboard for pasting into a post.

I’ve configured FastScripts to run snapftp with the ⌃⌥⌘4 key combination, a minor variation on the Apple-standard ⌘⇧4 key combo.

There are certainly commercial products that do some or all of these things, but none are so perfectly tuned to my way of working. I can’t imagine going back to writing posts like this without it.

Markdown links in TextMate

I write almost everything in Markdown, mainly because I can forget about the formatting and just type, but also because it’s so easy to read. To keep the visual clutter to an absolute minimum, I use reference-style links, which puts all the URLs at the bottom of the document, out of the flow of the text.

I use three TextMate command/snippet/macros to do this:

The first two are described here, and the third is described here. They’re a bit complicated to set up but are wonderfully simple to use. I should probably turn them into a Bundle for easier installation.

URL getters for TextExpander

This started out as a set of scripts for getting the URL (or a shortened version of the URL) of the page showing on the visible tab of the frontmost Safari window, and the scripts were triggered by key combinations defined in FastScripts. Then, after seeing this tip by Jeff Gamet, I turned them into a set of TypeIt4Me snippets. When I switched from TypeIt4Me to TextExpander, I moved the snippet over and that’s what I use today.

The two workhorses are:

I tend to use the first when writing posts like this or email and the second when using links on Twitter. The great advantage is that I can add a link to a page I’ve been reading without having to switch back to Safari to get it.

More recently, I added a few more snippets for getting the URLs of the first, second, third, and fourth Safari tabs, regardless of whether they are frontmost.

BBC Radio recording scripts for Audio Hijack Pro

These scripts, written in Python and AppleScript, differ from those described above in that I never actually run these scripts myself. They’re run automatically on a schedule set in Audio Hijack Pro, and they record and tag certain BBC Radio 2 shows and put them into my iTunes library for syncing with my iPod. In effect, they turn shows that aren’t podcasts into podcasts for me.

The scripts are described here and they’re also available in this GitHub repository.

Library loan tracking

This script, like the set of BBC scripts, is run automatically—in this case, by a launchd process. Every morning, it logs in to my local library and gathers information on all the items my family has checked out or on hold. It then sends that information to my wife and me in a nicely formatted email.

Now it’s true that my library emails us a notice shortly before an item is due, but the advantage of this system is that we see everything at once and can gather up all the books that will be due in the next several days before going to the library to make a return. And we don’t have to remember to sign on to the library’s web site; the information is delivered to us every day.

Suspend and sleep screen

This is a pretty recent script, but I’ve come to love it. Without logging me out, it suspends my user session and puts the display to sleep. Seeing the Desktop swing around in that cube animation (which I’ve been a fan of since Andy Hertzfeld used a simplified version of it in Switcher) has become the visual signal that my day at work is over.