Cleaning iTunes track information
I recently downloaded a bunch of old music from the Internet Archive audio archive. It’s a great resource, but on importing the tracks into iTunes, I noticed that a lot of the informational fields in the tracks had a lot of spaces on the back end. This causes weirdness in the iTunes display as it tries to center the text in its marquee.
Since I downloaded over 60 tunes, it wasn’t worth it to go through each one just to fix a minor problem like that. AppleScript seemed the obvious solution, but what I really needed was a “trim” function, and AppleScript doesn’t have one. Python does, however. It’s called “strip” and it is on every string object.
I could, of course, write a trim function in AppleScript, but why, when we have appscript? Especially when ASTranslate is so useful as an appscript AppleScript translator?
The AppleScript to get all tracks in a playlist:
[toggle code]
-
tell application "iTunes"
-
tell playlist "Recently Added"
- get every track
- end tell
-
tell playlist "Recently Added"
- end tell
ASTranslate converts this to:
- app(u'/Applications/iTunes.app').playlists['Recently Added'].tracks.get()
We can thus loop through an arbitrary playlist using:
[toggle code]
- iTunes = appscript.app("iTunes")
-
for track in iTunes.playlists[playlist].tracks.get():
- trim(track.name)
Note that our (as yet unspecified) trim function is being sent the method without parentheses. In Python, this means we’re sending the actual method, not the results of the method (in this case, it’s probably an object, not a method). Because appscript information methods have both a get and a set, this allows our trim function to get the information, trim the spaces off the ends, and then set the correction information:
Here is a trim function that will use Python’s strip method to fix any field that needs to be stripped of white space:
[toggle code]
-
def trim(trackmethod):
- value = trackmethod.get()
- trimmedvalue = value.strip()
-
if value != trimmedvalue:
- trackmethod.set(trimmedvalue)
We can send this function track.name, track.artist, track.album, or any text information field of an iTunes track that appscript has access to. If “trackmethod” is track.artist, then “trackmethod.get()” is equivalent to “track.artist.get()”, and “trackmethod.set()” is equivalent to “track.artist.set()”.
Here’s the full script:
[toggle code]
- #!/usr/bin/pythonw
- import appscript
- import optparse
-
def message(*args):
-
if options.verbose:
- print " ".join(args).encode('utf_8', 'ignore')
-
if options.verbose:
-
def trim(trackmethod):
- value = trackmethod.get()
- trimmedvalue = value.strip()
-
if value != trimmedvalue:
- message("Trimming", trimmedvalue)
-
if not options.dryrun:
- trackmethod.set(trimmedvalue)
- #set up command-line options and help
- usage="%prog [options] <playlist>"
- description="Cleans text fields in iTunes tracks in the specified play list."
- parser = optparse.OptionParser(usage=usage, description=description)
- parser.add_option("-v", "--verbose", dest="verbose", action="store_true", default=False)
- parser.add_option("-d", "--dry-run", dest="dryrun", action="store_true", default=False)
- (options, args) = parser.parse_args()
- #the play list--and only one playlist--is a required argument
-
if len(args)== 1:
- playlist = args[0]
- iTunes = appscript.app("iTunes")
-
for track in iTunes.playlists[playlist].tracks.get():
- trim(track.name)
- trim(track.artist)
- trim(track.album)
- trim(track.comment)
-
else:
- parser.print_help()
I added a few options using optparse: a --verbose option and a --dry-run option. A dry run goes through the playlist but doesn’t make any changes to it.
For example, to clean any recently added tracks (tracks in my “Recently Added” playlist), I might do a verbose dry-run first, and then do the actual clean:
- itunesclean --verbose --dry-run "Recently Added"
- itunesclean "Recently Added"
Now that I have it, I’m sure I’ll end up modifying this script to do all sorts of other batch changes to my playlists.
- appscript
- Appscript is a high-level, user-friendly MacPython to Apple event bridge that allows you to control scriptable Mac OS X applications using ordinary Python scripts. Appscript makes MacPython a serious alternative to Apple’s own AppleScript language for automating your Mac.
- iTunes clean data script (Zip file, 1.4 KB)
- This script implements various functionality I’ve needed to clean my iTunes track data, such as trimming white space off of the ends, removing extra artwork, and dropping specified text from the end of track names.
- Internet Archive Audio Archive
- “This library contains over a hundred thousand free digital recordings ranging from alternative news programming, to Grateful Dead concerts, to Old Time Radio shows, to book and poetry readings, to original music uploaded by our users. Many of these audios are available for download.”
More Python
- Parsing JSKit/Echo XML comments files
- While I’m not a big fan of remote comment systems for privacy reasons, I was willing to use JSKit as a temporary solution because they provide an easy XML dump of posted comments. This weekend, I finally moved my main blog to custom comments; here’s how I parsed JSKit’s XML file.
- Put a relative clock on your Desktop with GeekTool
- There are a lot of desktop clocks that show the absolute time. But sometimes you just want to know if the time is today, or yesterday, or two days ago. Here’s how to do it with Python and GeekTool.
- Multiple tables on the same command
- The way the “random” script currently stands, it does one table at a time. Often, however, you have more than one table you know you’re going to need. Why not use one command to rule them all?
- Easier random tables
- Rather than having to type --table and --count, why not just type the table name and an optional count number?
- Programming for Gamers: Choosing a random item
- If you can understand a roleplaying game’s rules, you can understand programming. Programming is a lot easier.
- 24 more pages with the topic Python, and other related pages
More appscript
- Using appscript with Apple Mail to get emails and attachments
- Python and appscript can be used to get email messages out of Apple’s OS X Mail client, and even to get and save attachments.
- Converting FileMaker to Django
- Appscript and the Django API make it easy to transfer data from Mac OS X scriptable applications into a Django-powered database.
- appscript AppleScript translator
- Those of us who like Applescript but want a solid command-line scripting environment no longer have to muddle through when using appscript. We can write in AppleScript and then translate to appscript.
- Using appscript in Python to control GUI applications
- The appscript module for Python lets you control scriptable applications on the command line without having to coordinate your command-line script with your Applescript applications.
More iTunes
- A present for Palm
- Palm needs a little help understanding XML.
- Getting the selected playlist in iTunes
- It took a while to figure out how to get iTunes’s selected playlist as opposed to the current playlist in AppleScript.
- Play this song backwards in iTunes
- Using AppleScript and Quicktime, you can play any song backwards. Find out what Fred Schneider was saying on “Detour Thru Your Mind”.
- Using appscript in Python to control GUI applications
- The appscript module for Python lets you control scriptable applications on the command line without having to coordinate your command-line script with your Applescript applications.
- Run a script on inserting an audio CD
- You can run a script every time you insert an audio CD to ensure that iTunes is ready for import.
- Three more pages with the topic iTunes, and other related pages

“There were times when I’d laugh at you. But now I’m crying, no use denying, there’s no other gal will do.”