# Refactoring my IPod

**URL:** <https://www.ruby-forum.com/t/refactoring-my-ipod/94105>\
**Category:** Ruby\
**Created:** [April 20, 2006, 11:46pm UTC](https://www.ruby-forum.com/t/refactoring-my-ipod/94105 "2006-04-20T23:46:26Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![MolitorS\_Stephen\_L](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e480ec/32.png) [@MolitorS\_Stephen\_L](https://www.ruby-forum.com/u/MolitorS_Stephen_L)\
**Post date:** [April 20, 2006, 11:46pm UTC](https://www.ruby-forum.com/t/refactoring-my-ipod/94105/1 "2006-04-20T23:46:26Z")

</div>

OK I’m getting waaaayyy off topic now:

I just bought an IPod and plan on burning my classical music collection  
to it. I’ve heard there are some issues categorizing and labeling  
classic music on ITunes. Are there any good Ruby libraries for dealing  
with Itunes catalogs? I’m using a Mac so Ruby AppleScript wrappers  
would work too.

Steve

---

<div class="post-metadata">

**Author:** ![MolitorS\_Stephen\_L](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e480ec/32.png) [@MolitorS\_Stephen\_L](https://www.ruby-forum.com/u/MolitorS_Stephen_L)\
**Post date:** [April 24, 2006, 12:17am UTC](https://www.ruby-forum.com/t/refactoring-my-ipod/94105/2 "2006-04-24T00:17:34Z")

</div>

On Apr 20, 2006, at 14:45, Molitor, Stephen L wrote:

> OK I’m getting waaaayyy off topic now:
> 
> I just bought an IPod and plan on burning my classical music collection  
> to it. I’ve heard there are some issues categorizing and labeling  
> classic music on ITunes. Are there any good Ruby libraries for dealing  
> with Itunes catalogs? I’m using a Mac so Ruby AppleScript wrappers  
> would work too.

> There are a lot of different ways to sort based on the various kinds of  
> meta-data, and it would be a pain to have to code a special method to  
> sort on each type of meta-data:
> 
> list.sort\_by\_artist, list.sort\_by\_title, etc.

If one were satisfied with a one-key sort, this would work. I, alas,  
wasn’t willing to have all the tracks randomly listed within each  
artist or whatever.

I created a ruby program that would allow me to do quite a bit of  
processing on my iTunes library. First, I had to (re)create the  
information from iTunes about/for each Track.

class Track  
attr\_reader :dbid  
attr\_accessor :name, :album, :artist, :tracknumber, :trackcount  
attr\_accessor :location, :genre, :year, :rating, :enabled, :playeddate  
attr\_accessor :playedcount, :start, :finish, :duration, :EQ,  
:composer, :dateadded

```
def initialize(id)
	@dbid = id
	self
end

```

end

iTunes has a unique id number for a track which is reuses as it  
reappears in various playlists and whatnot.

The rest of the information was added to each track with the method  
‘bulkload’, usually, although it could be done one attribute at a  
time…

```
def bulkLoad(params)
	@location = params[1]
	@location.downcase! if @location
	@name = params[2]
	@album = params[3]
	@artist = params[4]
	@tracknumber = params[5]
	@trackcount = params[6]
	@genre = params[7]
	@year = params[8]
	@rating = params[9]
	@enabled = params[10]
	@playeddate = params[11]
	@playedcount = params[12]
	@start = params[13]
	@finish = params[14]
	@duration = params[15]
	@EQ = params[16]
	@composer = params[17]
	@dateadded = params[18]
	self
end

```

That, naturally, depends on feeding in the parameters in the correct  
order after getting them from iTunes. I used AppleScript to get the  
data from iTunes.

```
	applescript = %{tell application "iTunes"
	with timeout of 1200 seconds
	set trackData to {database id, location, name, album, artist, track

```

number, track count, genre, year, rating, enabled, played date, played  
count, start, finish, duration, EQ, composer, date added, disc number}  
of } + @trackSource + ’  
end  
end  
repeat with I from 1 to count of item 2 of trackData  
try  
set item I of item 2 of trackData to (POSIX path of item I of item  
2 of trackData)  
end  
end repeat  
get trackData’  
itunesdata = OSX.do\_osascript applescript

What’s returned isn’t a Ruby Object at first, so AppleScript lists must  
be turned into Ruby Arrays, as well as their contents…

```
	tracklist = itunesdata.to_rbobj.map!{|list| list.to_rbobj.map{|i|

```

i.to\_rbobj}}

Then the array of Tracks is built…

```
	@tracks = Array.new
	tracklist.transpose.each do |track|
		newTrack = Track.new(track[0]) # first item is the database id
		newTrack.bulkLoad(track) # dump all the rest of the stuff into the

```

new track  
@tracks.push(newTrack)  
end

All of the above is to illustrate the methodology I used for sorting  
iTunes tracks.

class Track  
def \<=\>(other)  
answer = self.artist \<=\> other.artist  
answer = self.album \<=\> other.album if answer == 0  
answer = self.name \<=\> other.name if answer == 0  
answer = self.dbid \<=\> other.dbid if answer == 0  
return answer  
end  
end

(Yes, it could be made shorter. It’s plenty fast as it is, and nice and  
clear.)

Now, all I have to do is something like @tracks.sort! and they’ll be  
sorted by artist, then by album, then by name, and if there are  
multiple tracks on an album with the same name, they’re arbitrarily  
sorted by their iTunes ID. I’m not personally all that interested in  
the order they appeared on my CD, so I didn’t use that as a sort key.

_IF_ I have the track’s metadata correct then I find iTunes itself is  
perfectly capable of handling classical music. Unfortunately, 95% of  
what CDDB has is garbage, alas, with the composer listed as the artist,  
or the movement in the title and the title as the performer, or all  
sorts of corrupted or incomplete information. So my iTunes ruby scripts  
(and applescripts) were created mostly for mass library maintenance, to  
get the metadata in better shape.

If your metadata includes proper use of “Composer” and “Grouping”  
(which I see my current script doesn’t, oops), then I don’t know what  
“issues” there might be remaining with how iTunes handles classical  
music.
