#!/usr/bin/pythonw2.5 # Author: David Blackman (david-at-whizziwig.com) # Public Domain, use this as you see fit, no warranty, etc. import appscript import os # It seems like the mere act of checking this makes iTunes realize # the file is missing, so the location.url check fails. But, let's # be safe and check if the file is missing def find_library(iTunes): """Get the library playlist.""" # Why would there be more than one? I have no idea, but library_playlist # claims to only return "the master music library playlist" and it doesn't # exist, but library_playlists is the plural of it and does exist libraries = iTunes.library_playlists() if len(libraries): return libraries[0] print "Couldn't find library" return None def has_location(track): """Check if the location of the track is defined.""" location = track.location() if location is None: return False try: u = location.url except: return False return True def is_local(track): """Check if this track is on-disk.""" return track.location().url.startswith('file://') def is_missing(track): """Check if the file associated with this track is missing.""" return not os.path.exists(track.location().path) def process_track(track): """If the track is on-disk, check if it has a location and it exists, if not, delete the track (from the main library).""" # Podcasts don't have locations? Skip them, let iTunes deal with it. if track.podcast(): return if not has_location(track): print "Missing location: ", track.name().encode('ascii', 'replace') track.delete() return if not is_local(track): return if is_missing(track): print "Missing file: ", location.path track.delete() return def process_library(library): """Loop through each file in the given playlist/library and hand it off to process_track. Will delete missing tracks.""" for track in library.tracks(): process_track(track) def main(): iTunes = appscript.app('iTunes') library = find_library(iTunes) if library is not None: process_library(library) if __name__ == "__main__": main()