iTunes Library Organization and Cleanup
Posted by ark, ,

I’ve been organizing my iTunes library a little bit recently and it’s led to some useful utilities that I’m sharing here.

First up I had a bunch of files that had the artist name inside the song name (as ARTIST - TITLE) and no artist in the artist field. Making a smart playlist where artist was empty and name had a - in allowed me to then make a manual playlist of the results. The I could go through it and remove the ones that wouldn’t be fixed with a simple regex looking for the first dash. Mostly Jay-Z songs or ones where the artist was second.

I used what I learned from the imdb_movie_ratings_adder and held my nose and using Ruby I wrote update_itunes_selection.

If you look at the end you’ll see all the useful options and many of them use a RegexMatcher to take the name and find other fields in it. This ended up being super powerful and I find the --artist-name and --season-episode flags to be the most useful. It’s nice that you can try it out on one or two songs before doing a whole bunch automatically. --url-unescape was useful for some songs which were filled with %20 in the name.

I also had a few songs that I had downloaded off YouTube with youtube-dl before I knew about the --add-metadata flag. BTW I have an alias called ytmp3 that does this:

youtube-dl -w -i -x -o "%(playlist_index)02d-%(title)s.%(ext)s" --add-metadata --audio-format mp3

I find this very useful. Anyway if you don’t do the --add-metadata flag then you end up with the youtube ID at the end of the song name. Now I had a regex I could fix this with but I needed to find all the songs. There’s no nice way to find all the songs that end with - and eleven letters so I took another approach.

Using my iTunes MySQL loader itdb I wrote a little utility to take random SQL and it would make a playlist in iTunes with the tracks from the SQL. This time I didn’t want to write any Ruby since I had my database stuff already done in Python. So I used the Python version of appscript. But of course my old stuff was in Python2.x and that’s deprecated and I always have a nightmare with the MySQLdb driver so I just used 2to3 to convert my scripts over to python3 and then fiddled with it to make it all work. The end result is sql_to_playlist and you use it like this:

./sql_to_playlist --playlist YouTube --sql="SELECT name, Persistent_ID FROM tracks WHERE name REGEXP '-[a-z0-9_-]{11}$';"

Next up was to find tracks that had the artist name in the track name. I first had to make a temp table of artists.

CREATE TABLE artists (
	id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
	name VARCHAR(1024) DEFAULT '',
	count INTEGER(4) DEFAULT 0
);

INSERT INTO artists (name, count) SELECT Artist, COUNT(*) FROM tracks WHERE LENGTH(artist) > 3 GROUP BY artist;

Then I could join it with the tracks table and find all the songs. Then I could manually clean up that new playlist for songs that I could easily automatically fix with update_itunes_selection.

./sql_to_playlist --playlist "name with artist" --sql "SELECT t1.Persistent_id as Persistent_ID, t1.name, t1.artist FROM tracks AS t1 JOIN artists AS t2 ON t2.name = t1.artist AND LOCATE(t2.name, t1.name) > 0;"

Now that I’ve seen I can do everything in Python appscript that I could do in Ruby appscript I plan to reimplement those other two scripts so I never have to look at Ruby again.