Find tracks not in iTunes library

I’ve written a python script that walks through a path tree, checking to see if each file in the tree is a track in the current user’s iTunes Music Library.xml file.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
    import os, re
    
    startpath = "/Volumes/Media/Music/"
    prefix = "file://localhost"
    library = os.path.expanduser("~")+"/Music/iTunes/iTunes Music Library.xml"
    
    def eachpath(arg, path, tracks):
        for track in tracks:
            if os.path.isfile(os.path.abspath(path)+'/'+track):
                trackpath = os.path.join(os.path.abspath(path),track)
                grepstr = prefix+trackpath.replace(" ","%20")
                if grepstr not in data:
                    arg.append(grepstr)
    
    data = open(library).read()
    missing = []
    os.path.walk(startpath, eachpath, missing)
    
    print missing

It’s not flawless - on my machine it eats up over 11 meg of memory, and takes ages to run, but as a proof of concept, it works okay. The memory it uses is mostly because is stores the whole iTunes library file in memory, so that’s 9 meg on my system already. The main loop is doing a string1 not in string2, which is probably not optimal, but it was easy to code, for now. I’m still waiting to see how long it takes to do my whole library, but I’m getting bored with waiting. Edit: to reduce the time taken, I used the following code in the final if clause in the function:

1
2
3
4
5
6
try:
    if not re.search(grepstr, data):
        arg.append(grepstr)
except:
    if grepstr not in data:
        arg.append(grepstr)

The re one is much faster, but fails in some cases: the second one, while slower, is a fallback. There are also some other issues, at this stage I have not cared that much about escaped characters, which iTunes uses when storing the information. But, I came up with a quicker method than python’s os.path.walk(). Using the find command is much quicker:

1
    find /Volumes/Media/Music -type f -not -name .aacgained -not -name ._* -not -name .DS_Store

takes between 12-36 seconds for my 5700+ library stored on my NSLU2. If I telnet into the NSLU2 and run the equivalent command:

1
    find ~media/Music -type f -not -name .aacgained -not -name ._* -not -name .DS_Store

it takes on average less than one second to complete. So, that’s more than an order of magnitude, even if the network traffic is low. Oh, and it compares very favourably with the python version, which takes at least one minute to run.

iTunes Shared Library

Jaq and I share two computers, an iMac G4, and a Dell PC. I also bought a Linksys NSLU2 and a large USB Hard Drive, so that all of our music and videos can be stored on a server, and accessed from either computer (or the Xbox) without having to make sure the iMac was on. (That was the main computer, and the one we fight to get onto). Of course, the NSLU2 helped remove clutter from the iMac’s hard drive, not to mention freeing up a heap of space. Anyway, because we have a rather large music collection, it’s meaningless and wasteful to have copies of music stored in two places - I set up an SMB share on the NSLU2, wrote a small AppleScript to mount this on bootup, and pointed iTunes towards this location. This has the feature of storing one copy of all of our music, in the one location. There are some drawbacks, however:

  1. If I import music, it doesn’t appear in Jaq’s library by default. Similarly, if she imports, I don’t see it. Every now and then you need to drag the Music folder onto iTunes, and wait for it to update the library. Both of us need to do this, incase both of us have imported music.
  2. If one of us edits a track’s artist, title or album, iTunes for the other user sometimes cannot find the track. If you then re-import you wind up with two copies of the track, one of them (the one with the rating, and playcount) is a ‘dead track’.
  3. Sometimes a re-import causes a track to appear twice in the library. Sometimes it creates a second copy of the file in the directory.
  4. There is a lot of music in our library that one or other of us doesn’t really like that much. For instance, I listen to a lot of Classical music, but don’t like Red Hot Chilli Peppers. Even if you remove a track from your library, it gets re-added when you do a re-import.

Of course, there are some great benefits, too:

  1. Each person gets to have their own rating and playcount for each track. Initially we had a shared iTunes library file (both of us had read/write access to it), which worked well when only one user could run iTunes at a time, but fails dismally when multi-user is taken into account.
  2. Our iTunes library only takes up half of the space.
  3. I can modify the tags belonging to a track, and it gets propogated to her library.

I’m fairly confident the benefits outweigh the costs, but I’m still keen to come up with a better solution. Here are some ideas I have had to resolve some of the issues. iTunes stores a copy of it’s library in an XML file - it should be a trivial task to scan this and get some information that might be useful. For instance, compare the location field of each track to the directory structure, and work out if there are tracks that need to be added, or the path they have needs to be updated.

This requires a couple of things:

  • A decent XML parser (in some cases just a simple grep will do the trick - for instance seeing if a filename exists in the XML file).
  • An interface (AppleScript) to iTunes, to tell it to add/remove/re-locate files.

iPod Rating

I have been using Jaq’s iPod the last couple of days - mainly because when I am waiting at the Adelaide Railway Station, and at Lynton Station, I cannot get good enough radio reception on my phone’s radio. So, I copied all of my Classical music onto the iPod, and I’ve been listening away. I’d like to be able to rate tracks on the iPod, but I don’t really want to, for one big reason. I would only be able to rate them at 0-5 stars, not using the 0-100% ratings I use from iTunesRater. I wonder if it’s possible to hack the iPod firmware so that rating occurs by a finer gradient?

Funny Ha Ha?

Funny or interesting things I’ve seen, thought of or heard during the last day or so.

  1. I misread the colour of something in the hardware store yesterday - I thought it said Missing Brown.
  2. I thought I was going to be waiting for ages for the train this morning, as when I got to the crossing, I could still see the back of the last one. When I got to the platform, the next one was coming. If only the trains came that often all of the time. Oh, and the one I ended up catching was virtually empty. Not surprisingly.
  3. When my train was going through Keswick station this morning, there was a conjunction of trains, where all four were at nearly the same place at the same time. Different tracks, obviously.
  4. I misread fortune cookie as fortune wookie. Okay, that one isn’t that funny either.

Word Crapness

Microsoft Wordâ„¢ 2002 (10.2627.2625) has an extremely crap ’new feature’. When you press the Delete key with a block of text selected, nothing happens. If you notice down in the bottom left corner, Word asks if you want to delete the block, requiring you to press the Y key. Talk about crap interface design. Having to press two keys to delete a block of text, when there is a perfectly good undo system in place if you accidentally delete the wrong text. How often do you accidentally delete a block of text, anyway? And why not make the consistency of having to press ‘y’ when you go to overtype a block of text? Or press Enter when a block of text is selected? I’m now going to have to use the latter, rather than delete. Microsoft, you guys suck.

Bizarre Blogsome Behaviour

I just posted an update on what I’ve done to to make Connections work on Blogsome. When I did so, it crapped out my stylesheet and layout. Just having the info in a post that is normally only in the template files caused WordPress Multi-User to wigg out. And I didn’t just have the text, it was all escaped and >’d (I think I just created a new term, >’d!!) I’ll have to just have the files hosted somewhere else, and linked to again, I guess. Update: It was actually the Smarty Tags that were wigging out, or more correctly, the CSS code that Smarty thought were Smarty Tags.

Competitive Living

I was thinking tonight of how we used to live - specifically, how my first share house ‘worked’. There were four of us, originally, living at 81 Alabama Avenue, Prospect. All four had been at school together (to some extent) at Naracoorte. Derek and I had been good mates, and apparently Heath and Bruce had “Gotten on okay.” The best way for us to live together in relative co-operation was to be somewhat competitive. For instance, if you wanted to do a load of washing, you had to do your own. The trick was, if there wasn’t room on the line for your clothes, too bad. That meant that we used to actually get up earlier than expected on weekends to do a load of washing. Of course, Uni was not all day every day, so you would often have time to do a wash during the week. But the rule still held. I remember a clash between Bruce and someone (it was always between Bruce and someone else…) to do with the moving of clothes on the line. Nasty stuff. The other way we used to compete was with cooking/dishes. We were in ’teams’, Derek and myself, Heath and Bruce (poor Heath), and each team took it in turns cooking. Co-operative. Washing up was another matter. Each team took it in turns to wash up, with ideally the team who had not cooked having to wash up. But if they left it a day, then they had to wash up tomorrow, and do both days washing. Whilst sometimes we went a few days with a sink full of dirty dishes, the teamwork that your team-mate would coerce you into washing up, or you would them. Everything ran pretty smoothly for the first year, but eventually we got sick of Bruce, and kicked him out. Instead we got Derek’s younger brother, Dane (or Moper, as he was called) as our new house-mate. I seem to recall the system breaking down somewhat then.

Front Wall

When we sanded the floor of the front (non-main) bedroom, a water mark appeared on the floor, near the front wall of the house. As far as I can tell, the water has come through the damaged timbers surrounding the asbestos sheeting under the windows. Some pieces of the timber, and the quad that is ’trim’ had rotted away - either because the vine that was there had allowed the water to remain there, or because the paint had cracked. Dsc00012-1 Dsc00013 I pulled some parts off, and then found that the main bottom timber had been repaired at least once before. Since removing the whole beam was out of the question, I just patched it up again…but it isn’t quite finished yet. So now, our house has sheets of plastic across the front, just incase it rains tonight. Dsc00009-1 Dsc00011 Dsc00012-2

Duplicate Songs in iTunes

I have got (at last count) 5715 tracks in my iTunes library. I have rated 1988 of these, or around 35%. Show Duplicate Songs tells me I have 409 duplicates. (Maths tells me I have at least one triple!). I have 225 unrated duplicates, so I have rated nearly half of the duplicate songs. Whilst some of the duplicates are live versions, and I may not like one or other version quite as much, it’s a fair bet the ratings would be similar, if for instance the tracks were the same, but were from best-of albums, compliations and the like. So, it might be nice to have a program that gets all of the tracks that are duplicates, but at least one of them has a rating (and at least one of them doesn’t), and apply the rating from the rated one to those that don’t have ratings. Of course, you could have it that if there were three songs, and two of them were rated, that the third gets the average rating of the other two. I may write an AppleScript that does this. Rag Doll • Songs About Jane • Maroon 5

iTunesRater 0.7

I’ve included the ability to rate the previously playing song in 0.7 When iTunesRater knows the current song, and the previous song, it will activate a checkbox: Show Previous. Clicking this button will open a drawer with the details of the previous played song, which can be rated. I seem to have made the whole thing run a bit slower now, I’m going to refactor everything at some stage. But not right now… Edit: Whoops! Big bug there - if a track doesn’t have artwork, iTunesRater spits it bigtime…fixed now though. Get 0.75 from iTunesRater0.75.zip.