May 2009 Archives

This past week I purchased for myself a mini laptop. I wanted something nice and portable that I could use for personal use on trips and do hobby projects on. This thing is great. I got Ubuntu installed and started playing around since it’s been a couple years since I had a Linux desktop, and even then I usually had a Mac OS X laptop I used with it. As such, when it came to copy over my music and such, I needed to convert to a new music player. I’ve settled on Banshee for the moment.

Problem: There’s no import tool out there to go from iTunes to the current version of Banshee.

Solution: However, the process turned out to be not so hard for me. Here’s what I did:

  1. Copied the iTunes music folder from my Mac to the music folder on my new laptop.
  2. Started up Banshee and used Media > Import Media… to tell Banshee where to find all the files and let it do it’s thing.
  3. Went back into iTunes on my old machine and used File > Library > Export Library… to generate a Library.xml file, which I copied to the new laptop
  4. Ran a Perl script I wrote to pull out the play lists, song play counts, last play date, and ratings and push them into the Banshee database

Fortunately the Library.xml file output by iTunes is in a standard format that is pretty easy to understand. Also, Banshee keeps much of the information about your music and such in a SQLite database. So, I could very easily automatically copy over all the ratings and other information I’ve been assembling for the past several years.

Here’s the conversion script, itunes-to-banshee.pl that I wrote for download:

Download itunes-to-banshee.pl

Update (thanks to Rolo): You will need to install a few dependencies as well. On Debian or Ubuntu, this is done by installing:

  • libdatetime-perl
  • libdatetime-format-iso8601-perl
  • libclass-dbi-sqlite-perl
  • libxml-twig-perl
  • libmime-base64-perl

This can be done from Synaptics or by running this on the command-line:

sudo apt-get install libdatetime-perl libdatetime-format-iso8601-perl \
    libclass-dbi-sqlite-perl libxml-twig-perl libmime-base64-perl

Once Banshee has finished adding your song files to its music library, close Banshee. Make a backup copy of banshee.db to somewhere in case something goes wrong (which can be found at ~/.config/banshee-1/banshee.db). Then run:

perl itunes-to-banshee.pl Library.xml ~/.config/banshee-1/banshee.db

This may take a few minutes, depending on how many songs you have. It might show you some warnings if your Library.xml is weird (remember I wrote this just for me). It may also tell you if it can’t find some songs in Banshee that it found in your Library.xml. (It did for me because I’d deleted some songs from the disk and iTunes never figured it out.)

Once it finishes, start Banshee back up and it should have the play lists, ratings, play counts, and last played date set for all the songs that had such information in iTunes.

There are a couple things you might want to know about how the program works. First, it does not touch smart play lists. I don’t know and don’t particularly care how to read the smart playlist configuration from iTunes. I was able to recreate the smart play lists I had in a few minutes.

Second, the import script uses the song title and song file size to match songs from the iTunes library in the Banshee library. This is probably safe since I’ve never seen two CDs with the same songs on them end up being the same size, but it’s theoretically possible it could be a problem.

Third, if you have duplicates in your library, this script will only change one of them. I’d recommend weeding those out first.

I’m not interested in maintaining the script, but I’ll answer questions about it. If you ask really nicely and I’m in a good mood and the change you want is very small, I might be willing to make it, but that’s a lot of “ifs” to line up.

Cheers.

With my work on qublog.net continuing to progress toward hosting this service on the qublog.net web site. I’ve been using the silk icon set for the icons, but recently decided to switch over to the fugue icons. In the process, I rethought how I added icons to the system, which I subsequently chose to try on some work things as well. There’s no magic here, nothing to patent (at least I hope not), but it’s worked pretty well, so I’ll share. I suppose this might not be “The Best Way”, but it’s certainly now “My Best Way.”

First, these icons are all being added without IMG-tags. This keeps my content less cluttered and allows me to very quickly switch icons if I change my mind later just be changing my stylesheet. Typically, these are added to buttons, links, and spans like so:

<span class="icon o-time">12:44 PM</span>
<a class="icon v-add o-task">Create Task</a>
<input type="submit" class="icon v-save o-time" name="op" value="Save"/>

The first class “icon” performs the work of making sure the icon itself is attached to the element properly. This looks like:

.icon {
    padding-left: 18px;
    background-repeat: no-repeat;
    background-position: 1px 1px;
    min-height: 18px;
}

This basically makes sure that my 16 pixel icon has 1 pixel of space around it and makes sure the element is at least tall enough not to cut anything off.

Then, the icon itself is chosen by examining the other associated classes. I’ve divided the classes into nouns (with an “o-” prefix), adjectives (with an “a-” prefix), verbs (with a “v-” prefix), and adverbs (with a “r-” prefix). I define these classes within the style sheet in that order so that adjectives will override nouns, verbs override both nouns and adjectives, and adverbs will override everything. So, now my style sheet looks something like this:

.o-task { background-image: url(ticket.png) }
.o-time { background-image: url(clock.png) }

.a-group { background-image: url(folder.png) }
.o-task.a-project { background-image: url(briefcase.png) }

.v-add { background-image: url(plus.png) }
.v-add.o-task { background-image: url(ticket__plus.png) }
.v-add.o-task.a-project { background-image: url(briefcase__plus.png) }

By setting up the style sheet this way, a regular task reference shows up with a ticket icon. However, a project (which is a kind of task in Qublog) shows up as a briefcase. In case I need a generic add link, I can use a lone plus sign, but if I want a specific add link for tasks I can have a ticket with a plus sign. Finally, I can add a new project with a briefcase with a plus sign.

Later, if I want to modify the icons used, I can do so by just adding another class or something. It’s pretty flexible and if I make sure and include enough information on every link, span, or button that might have icon, I can make my icons more or less particular later just be adding a line or two to my style sheet. (For example, if my icon set lacked a briefcase with a plus next to it and then added one or I created one, then I could add that last rule later and rely on the ticket with a plus sign in the meantime.)

Some final varations I also use are things like having the icon only and ignoring the text itself:

.icon.only {
    display: inline-block;
    overflow: hidden;
    white-space: nowrap;
    width: 0;
}

Now I can add the “only” class to my spans and links and the text becomes hidden. I combine this with a jQuery code similar to this:

jQuery(document).ready(function() { 
    jQuery('.icon.only').each(function(){
        jQuery(this).attr('title', jQuery(this).text());
    });
});

This causes the text of the element itself to show up as a tooltip when you hover your mouse over the icon. Generally speaking, though, I usually try to do this on the server side when I use the “icon only” classes.

I have a few other “icon” class variants for changing the position of the icon, dealing with small 9-pixel icons, and making sure buttons and specific other things look good with the icons, but I’ll leave these as exercises for the reader.

Cheers.

About this Archive

This page is an archive of entries from May 2009 listed from newest to oldest.

March 2009 is the previous archive.

June 2009 is the next archive.

Find recent content on the main index or look in the archives to find all content.