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 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
- Catalina vs. Mojave for Scripters
- More detail about the issues I ran into updating the scripts from 42 Astounding Scripts for Catalina.
- Catalina: iTunes Library XML
- What does Catalina mean for 42 Astounding Scripts?
- 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”.
- Five more pages with the topic iTunes, and other related pages
More Python
- Quick-and-dirty old-school island script
- Here’s a Python-based island generator using the tables from the Judges Guild Island Book 1.
- Astounding Scripts on Monterey
- Monterey removes Python 2, which means that you’ll need to replace it if you’re still using any Python 2 scripts; there’s also a minor change with Layer Windows and GraphicConverter.
- Goodreads: What books did I read last week and last month?
- I occasionally want to look in Goodreads for what I read last month or last week, and that currently means sorting by date read and counting down to the beginning and end of the period in question. This Python script will do that search on an exported Goodreads csv file.
- Test classes and objects in python
- One of the advantages of object-oriented programming is that objects can masquerade as each other.
- Timeout class with retry in Python
- In Paramiko’s ssh client, timeouts don’t seem to work; a signal can handle this—and then can also perform a retry.
- 30 more pages with the topic Python, 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.”