oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button

Grabbing iTMS Preview Tracks the Geek Way
Pages: 1, 2, 3

Automation Tips

Now that you've seen how to manually download and add each song to iTunes, consider how much easier it would be to automate the process. Perl offers a great match to the challenges involved in the process. The steps you need to automate are: iterating through each track, locating the URL, downloading the data and naming the file, loading it to iTunes, and adding the proper metadata. Here are a few thoughts about each of these challenges.

Iterating Through the Tracks

The Preview text playlist created by iTunes consists of a header line with the categories for each column (Name, Artist, Composer, etc.) followed by one line per track. You can easily read in the track list and split it into individual lines by looking for the new line delimiter. This lets you create a foreach loop that iterates through the lines of the playlist file and processes each line that contains a URL.

#! /usr/bin/perl
# Fetch Preview Files from Playlist

use warnings;
use strict;

if ($#ARGV < 0) {die "Usage: $0 filename\n";}

# Read Playlist Text (Save as Plain Text!)
my $intext = "";
open(XFILE, $ARGV[0]);
while (<XFILE>)
  $_ =~ tr/\r/\n/;
  $intext .= $_;
my @playlist = split("\n", $intext);
foreach my $item (@playlist) 
  if ($item =~ /http/)
      # Put the download & process parts here

Locating the URL

Each line in the playlist file consists of 25 tab-delimited columns. The URL appears as the 25th item on each line. You can either split the line into fields (e.g., my @ilist = split('\t', $item);) and select the 25th item (i.e., $xurl = $ilist[24];), or you can just kill everything that appears before the start of the URL ($xurl =~ s/^.*http/http/;).

Downloading the Data and Naming the File

Once you've identified the URL of the file you want to retrieve, you can use any number of Perl libraries to download the data. I prefer to use the Unix curl command because it's universally available on Macs and doesn't require anyone to download and install CPAN Perl libraries. Here, I store the downloaded files in a folder named preview_files.

# Store recovered file to Desktop as DRM'ed m4p or m4v.
my $doit = qq{curl -s "$xurl" > ~/Desktop/preview_files/$xt.$xlast};

Deciding how to name your files introduces something of a challenge. You can't use colons (":") and many other characters. Therefore I limit my names to characters and numbers taken from the actual name of the track. As you'll see, I do something similar (but adding spaces and parentheses) for the iTunes metadata.

# Create file name from the file extension and the track title
my $xlast = ($xurl =~ /m4v/)?"m4v":"m4p";
my $xt = $ilist[0];
$xt =~ s/[^A-Za-z0-9]*//g;

Loading to iTunes

I use osascript to automate application scripting. It's a handy way to control iApps from the command line. Here's how you can direct iTunes to create a new playlist. Always make sure to launch and/or activate an application before trying to send it directives.

# Activate iTunes and create a playlist named "iPreviews"
my $doit = qq{osascript -e 'tell application "iTunes" to launch'};
$doit = qq{osascript -e 'tell application "iTunes" to set name of (make new playlist) to "iPreviews"'};

Next, you need to add your new file to the iTunes playlist you just created. Here's the osascript call. Depending on how you've set up your iTunes preferences (iTunes Preferences -> Advanced -> General -> Copy files to iTunes Music folder when adding to library) this will either just add your new file to iTunes or copy it to the iTunes library.

# Add file to iTunes playlist
$doit = qq{osascript -e 'tell application "iTunes" to add ((((path to desktop) as string) \& "preview_files:" \& "$xt.$xlast") as alias) to playlist "iPreviews"'};

Adding the Proper Metadata

The final downloading step involves recovering the specific track information lost in the download process. You can re-add all 24 items (the 25th, the URL is not properly part of the track info), or you can select just those items that are important, such as the name, artist, album, and genre. Once again osascript comes to the rescue.

# Filter unwanted characters
$item =~ s/[^A-Za-z0-9 ()\t]*//g;
my @ilist = split('\t', $item);

# Add the info for the file.
my $xx = qq{$ilist[1]};
$doit = qq{osascript -e 'tell application "iTunes" to set artist of track $xt" of playlist "iPreviews" to "$xx"'};
$xx = qq{$ilist[3]};
$doit = qq{osascript -e 'tell application "iTunes" to set album of track "$xt" of playlist "iPreviews" to "$xx"'};

# Update Title
$xx = qq{$ilist[0]};
$doit = qq{osascript -e 'tell application "iTunes" to set name of track "$xt" of playlist "iPreviews" to "$xx"'};

Download the Sample Code

You can grab a copy of the automated free preview download script here. As with any software I make public, caveat emptor. Use at your own risk. Please don't sue me. Also please note that I take no precautions regarding duplicate names. If you download three items named "Finale" or "Conclusion" or whatever, they will overwrite each other. To fix this, either edit the playlist text file by hand or rename the tracks in iTunes. iTunes is smart enough to retain the proper preview URL when you edit the track name, and the playlist text file will use the track name you select, such as "Finale 1," "Finale 2," and "Finale 3."

Erica Sadun has written, co-written, and contributed to almost two dozen books about technology, particularly in the areas of programming, digital video, and digital photography.

Return to the Mac DevCenter