Tagging and iTunes: a roundup

As someone whose digital music collection keeps growing (now filling, despite my previous pledge, all but 15 GB on a 270 GB drive), I am always alert for new ways of managing the mountain of music. One trick that has been productive has been putting track metadata, including lists of musicians, actual recording dates, and keywords like “cover” or “remix,” in the Comments field of each track. This is a more staggering task than even I imagined, for a couple of reasons.

The first reason is the domain: even rock bands usually have north of four people involved in a given song, and when you look to jazz tracks, the task of manual data entry becomes huge. Also, unlike with iPhoto (or Flickr or del.icio.us), there is no concept of a discrete “tag” for a music track—in iTunes or anywhere else, as far as I can tell. Everything must live inside an unstructured comments field. So each item must be added manually, and God forbid you want to remove a tag from more than one item.

I had created an AppleScript to cope with the first challenge, a simple script that puts a user-defined keyword at the end of the comments block. But in a recent MacOSXHints article and its comments, I was exposed to a host of other solutions and am convinced it will be easier for me just to adopt someone else’s approach.

I’m tempted by the approach of managing iTunes tagging with Quicksilver, but I have actually given up using Quicksilver as it tends to slow to a crawl on my 1GHz G4 PowerBook. The approach of Common Tater looks good, but I’d rather have a small atomic script than a monolithic application, and it hasn’t been updated in quite a while. TuneTags has the same objection, plus the fact that its XML-like markup is too big to fit comfortably inside the meager 255 characters given for comments on a track.

I look forward to checking out Christopholis’s TuneTag (no relation) and the Add/Remove Tags scripts from dwipal. But ultimately the AppleScript solutions will need to yield to either a cross-platform iTunes plugin with a consistent tag separator methodology (semicolons? asterisks? XML? <T>?) or to a dedicated tag feature implemented by Apple. I’ve never understood why iTunes never got tags and iPhoto has had them since the beginning.

New iTunes script: Increment Playcount

I’ve uploaded a bare bones AppleScript that I’ve found useful over the past few weeks. The script, Increment Playcount, does what it says: it bumps the playcount of a track in iTunes by 1 and sets the Last Played date to the current date and time. It’s been helpful to me because many of my smart playlists rely on knowing if I’ve heard a track or not, but unfortunately sometimes my iPod doesn’t sync playcounts—and sometimes my iTunes library gets blown away, losing all playcount information.

To use the script, unzip it, drop the script in your Library/iTunes/Scripts folder, go to iTunes, select one or more tracks, then select Increment Playcount from the scripts menu.

More detail about this and my other AppleScripts on my Software page.

massDeleteManila: AppleScript for mass spam deletion

After the carpal tunnel moment earlier today, I decided to look on the bright side of spam. I updated my hoary old ManilaHandler AppleScript to add support for the Manila.message.delete method (and at the same time bundled the support script SOAPXMLRPCHandler into the body of the script). And I wrote a simple AppleScript, massDeleteManila, that takes a comma delimited list of message IDs and deletes them.

The UI isn’t elegant. You need to type or paste a comma delimited list into a dialog box. Plus no progress bar. But it works, and it is a lot faster than deleting spam through the web UI.

My suggested workflow for using this on your own Manila blog:

  1. Copy and paste the table for your discussion group topic listing page showing the spam messages into Excel.
  2. Copy just the message IDs and paste them into BBEdit (or another word processor).
  3. Search and replace: replace paragraphs with commas.
  4. Run the massDeleteManila script and paste the comma-delimited list of message IDs into the first dialog box.
  5. If you haven’t filled out your blog URL yet, type it in, along with your username and password.
  6. The script runs silently until all the messages have been deleted.

The massDeleteManila script is available for download. I provide it so that other Manila users, such as the Berkman bloggers, can benefit. Please use it carefully—there’s no easy way to undelete messages in Manila, and I cannot provide support if you accidentally delete important content. Note that you may need Tiger to run the script—I haven’t been able to test it under Panther.

In defense of plain ol’ SQL

Philip Greenspun Weblog: How long is the average Internet discussion forum posting?. I’m less interested in Philip’s answer than I am in the methodology: simple SQL select statements that give you very important product design data.

People talk about “data mining” and “business intelligence” as though they’re complicated, new skill sets, but really all you need sometimes to make the right call is a simple SQL query. And the right data set, of course…

Integrating Google Maps

Mac OS X Hints: Map Address Book addresses via Google Maps. This is the sort of low tech URL-based hack that is perfect for AppleScript, and very easy to debug.

An older Mac OS X Hints article discusses the plug-in capability and provides another sample script. From that, it looks like you capture the field to which you’re adding the contextual menu using an “on action property” handler; the title can be set with “on action title”; and the actual code is in the “on perform action” block.

Other address book plug-ins:

  • iCal Scripts (Apple): schedule a call, create a “birthday event” (reminder), or create an event associated with the person
  • Dates and SMS Scripts (Daniel Browne): send an SMS message via a Bluetooth phone, email, or AIM
  • Skype call (bertlmike): open a Skype call

The plug-ins can also be written in Cocoa or Carbon.


First Panther note: some of my scripts don’t seem to work under Mac OS X 10.3. Specifically, Look Up Current Track in iTunes doesn’t work and iTunes2Manila fails because it can’t connect to the Internet. Wonder if Apple changed how SOAP calls work…

Update: Changed or more precisely broke, it looks like, based on evidence from this MacScripter thread. Stay tuned…

Fetching blog updates from Weblogs.com using Applescript

As I mentioned earlier this week, I’m running an AppleScript once an hour to download data from Weblogs.com. For anyone who may be interested in seeing how it’s done, the code is below and is easily adaptable to other scripting languages, including DOS Batch (I know, I’ve done it). This is first pass code, not optimized, warts and all. Enjoy.

copy getWeblogsChanges() to {success, theFile}

if not success then
display dialog "Could not get the changes file from Weblogs.com."
end if


on getWeblogsChanges()
set changesSource to "http://www.weblogs.com/changes.xml"
set theDate to current date
set theYear to year of theDate as string
set theMonth to month of theDate as string
set theDay to day of theDate as string
set theTime to time of theDate as string
-- need to prompt for the user's directory instead
set theFileName to "~/" & theYear & theMonth & theDay & theTime & "_changes.xml"
set theShellCommand to "curl " & changesSource & " > " & theFileName
--need error handling
do shell script theShellCommand
return {true, theFileName}
end getWeblogsChanges

on processWeblogsChanges(theFile)
set theShellCommand to "gzip -c " & theFile & " >>changesxml.gz"
do shell script theShellCommand
end processWeblogsChanges

Better weblogs.com usage data?

I noted that I had let a new high water mark go by last week; the weblogs.com data watch has been updated and you can download the new data set here. The new high water mark is amazing, too: out of nowhere, it jumped from under 3000 to above 4000 weblogs in a three-hour period. Anyone know what was happening on Friday to drive that much traffic???

Anyway, this was the kick in the butt I needed to look at my cron script that I set up to download the Weblogs.com changes file. I had set cron to run a custom AppleScript (source to be shared shortly) to download changes.xml every two hours and gzip it, or so I thought. Looking at it today, the first day I left the machine on overnight since adding the cron setting, I realized I had asked it to download the file once a minute during the 2 am hour instead. Oops. Sorry about the bandwidth, Userland.

So why is this important? As I’ve been saying for a bit, I want to understand the dynamics of a day and a week in terms of blog posting frequency. Which are the high traffic days? What percentage of blog users post more than once a day? More than once every few days? Just how many unique blogs ping Weblogs.com in a two week period?

Starting today, I’ll be working on finding out. My cron script is now working (it’s amazing the difference between * 2 * * and * /2 * *). My machine won’t be sleeping or shut down for the next two weeks. I’ll make my summary data available at the end of the experiment and see if I can draw some conclusions about the meaning of the high water marks we’ve been seeing. Hopefully, if I’m successful with the project, this can be a longer term study. But for that to be true, I’ll have to automate the process of importing the data file and aggregating the statistics, and that may be too much to get done right now.

Is anyone else engaging with the changes data in this way? Are there any questions about the weblog population that two weeks of granular update data would provide?

Working with AmazonHandler

As I promised a few weeks ago, I’ve spent a little more time working on AmazonHandler. The biggest problems people have had with it are that

  1. it requires a supporting script which has to be loaded from a fixed location on your hard disk, and
  2. there wasn’t an example of how to parse the output.

Number one is fairly trivial: you can either put the supporting script, SOAPXMLRPCHandler.scpt, in the standard location, which is in the computer’s /Library/Scripts directory—the one for all users, not your local version, though it should probably check both—or you can edit the InitSOAP subroutine to tell it to look for the script elsewhere.

Number two is harder, and I spent some time working through it last night. The trick is in knowing that various parts of the return have to be explicitly transformed either to lists or records before their parameters can be read. Once you do that, it’s fairly simple to parse the output.

I’ve hacked a quick demo script that is actually somewhat useful. Until I work out all the bugs, it will be available as a separate download; after that, I’ll probably bundle it with AmazonHandler. The script, Look Up Current Track in Amazon, talks to iTunes to get information about the currently playing track, then looks up the track’s album (or artist, if no album title is available) at Amazon, tells you what Amazon’s current price is, and offers you the option to go to Amazon’s page for the product should you wish to consider the option of purchasing it. So (buzzword version) this script integrates iTunes and Amazon using SOAP-based web services.

The script is available for download on my Scripts page.

AmazonHandler acting up

I’ve had no less than four people contact me within the last few weeks to tell me that AmazonHandler, my AppleScript glue to allow calling the Amazon Web Services API, isn’t working for them. The most common error is “Can’t make ‘http://soap.amazon.com/onca/soap’ into a record” but others have been reported as well, including problems with finding and loading the support scripts to do SOAP.

I think the first problem is caused by some code I put into SOAPXMLRPCHandler to work around a bug Apple introduced in the underlying SOAP layer sometime in the late 10.1.x/10.2 timeframe. The support script problem is tricky. The point of scripts is that they’re supposed to be quick and easy, so making the user install support scripts seems dumb. But it’s quicker and easier for me to release scripts that use common technologies (including the Manila API and SOAP generally) if I keep the scripts separate.

I promise I’m looking at it, if only because having this script would allow me to automate some of the workflow around “Current Listening” and “Current Reading.” But be patient—I have a day job, after all.

Eating one’s own dogfood—with the customer

Dave continues to explore the joys of getting Userland’s flagship workgroup blogging solution, Manila, up and functional at Harvard. Today’s story captures him learning about a potential conflict between Frontier’s built-in web server and Microsoft IIS, if both are running on the same box.

This is exactly the sort of thing that more software developers, and CEOs, should do—get out into the wild, outside the company IT environment, on the other coast or in another part of the world, and try to install and operate your product. Does it work like you expected? Uh oh, it doesn’t! Have you documented the problem? Is it a bug or a compatibility issue? Has anyone else had the same problem? Is your website any help? Kudos to Dave for using his new job as a way to improve Userland’s products and support.

As you can probably tell…

…I got iTunes2Manila working again. The problems appear to be rooted in changes to Apple’s implementation of XML-RPC and SOAP in Jaguar:

  1. Passing HTML tags such as italics and anchor tags in text that is a parameter to an XML-RPC or SOAP call causes an error. You can deal with this by escaping the opening bracket as &lt and a semicolon…
  2. AppleScript now passes all text parameters as Unicode by default. This might be a good thing in most places, but Manila’s RPC handler wants plain text and posts a message with an empty body if it’s passed Unicode. The fix is to coerce the text variable to plain text: set s to (s as record)'s «class ktxt»

I am testing my other scripts with these fixes (which reach into the supporting library scripts ManilaHandler and SOAPXMLRPCHandler) and will post fixes soon.