Index: trunk/MusicBrainz.pm
===================================================================
--- trunk/MusicBrainz.pm	(revision 10)
+++ 	(revision )
@@ -1,249 +1,0 @@
-package MusicBrainz;
-
-use strict;
-use warnings;
-
-our @ISA    = qw{Exporter};
-our @EXPORT = qw{get_musicbrainz_info lookup_release};
-
-#use WebService::MusicBrainz;
-use LWP;
-use XML::XPath;
-use XML::XPath::XMLParser;
-
-sub lookup_release {
-    my ($discid) = @_;
-    my $ua = LWP::UserAgent->new;
-
-    #my $uri = URI->new('http://musicbrainz.org/ws/1/release/');
-    #$uri->query_form(type => 'xml', discid => $discid);
-    my $uri = URI->new("http://musicbrainz.org/ws/2/discid/$discid");
-    $uri->query_form(inc => 'artists+labels+recordings+release-groups+artist-credits');
-
-    my $res = $ua->get($uri);
-    # pause for a second, so we don't run afoul of the MusicBrainz API TOS
-    sleep 1;
-
-    warn $res->status_line, "\n" if $res->code != 200;
-    return if $res->code >= 400;
-    #TODO: if we get a 5xx error, retry?
-
-    return $res->decoded_content;
-}
-
-sub get_musicbrainz_info {
-    my ($discid) = @_;
-    my %info;
-
-    #TODO: deprecate the old MBZ tag name
-    $info{MBZ_DISCID} = $discid;
-    $info{MUSICBRAINZ_DISCID} = $discid;
-
-    my $xpath = XML::XPath->new();
-    my $xml = lookup_release($discid) || return;
-    
-    $xpath->set_xml($xml);
-
-    # get the release; if there is more than one, take the first one
-    my $release_count = $xpath->findvalue('count(//release)');
-    my @releases = $xpath->findnodes('//release');
-    my $base = 'http://musicbrainz.org/release/';
-
-    my $i = 1;
-    #TODO: use this as the basis for an interactive menu to pick the correct release ID
-    warn "$release_count release(s) found matching $discid\n";
-    for my $release (@releases) {
-        warn sprintf "%2d) $base%s %s %s (%s)\n", 
-            $i++,
-            $xpath->findvalue('@id', $release)->value,
-            $xpath->findvalue('.//label-info/label/name', $release)->value,
-            $xpath->findvalue('.//label-info/catalog-number', $release)->value,
-            $xpath->findvalue('barcode', $release)->value;
-    }
-
-    # use the VorbisComment names from here http://musicbrainz.org/doc/MusicBrainz_Picard/Tags/Mapping
-
-    # use the first release by default
-    # TODO: configurable release selection criteria
-    my $release = $releases[0];
-
-    $info{MUSICBRAINZ_ALBUMID} = $xpath->findvalue('@id', $release)->value;
-    $info{ALBUM}               = $xpath->findvalue('title', $release)->value;
-    @info{qw{ALBUMARTIST ALBUMARTISTSORT}} = get_artist_credits($xpath, $release);
-    $info{DATE}                = $xpath->findvalue('date', $release)->value;
-    $info{ORIGINALDATE}        = $xpath->findvalue('release-group/first-release-date', $release)->value;
-
-    # select the proper medium (important for multidisc releases)
-    my ($medium) = $xpath->findnodes("medium-list/medium[disc-list/disc/\@id='$discid']", $release);
-
-    # disc position info
-    $info{DISCNUMBER} = $xpath->findvalue('position', $medium)->value;
-    $info{DISCTOTAL}  = $xpath->findvalue('../@count', $medium)->value;
-
-    #my $ua = LWP::UserAgent->new;
-    my $tracknum = 1;
-    for my $track_node ($xpath->findnodes('track-list/track', $medium)) {
-        my $prefix = sprintf('TRACK%02d', $tracknum);
-
-        $info{"$prefix.MUSICBRAINZ_TRACKID"} = $xpath->findvalue('@id', $track_node)->value;
-
-        my ($recording) = $xpath->findnodes('recording', $track_node);
-        $info{"$prefix.MUSICBRAINZ_RECORDINGID"} = $xpath->findvalue('@id', $recording)->value;
-        $info{"$prefix.TITLE"} = $xpath->findvalue('title', $recording)->value;
-        @info{"$prefix.ARTIST", "$prefix.ARTISTSORT"} = get_artist_credits($xpath, $recording);
-
-        $info{TRACKS}[$tracknum]{TITLE} = $info{"$prefix.TITLE"};
-        $info{TRACKS}[$tracknum]{ARTIST} = $info{"$prefix.ARTIST"};
-        $info{TRACKS}[$tracknum]{ARTISTSORT} = $info{"$prefix.ARTISTSORT"};
-
-        #my $uri = URI->new("http://musicbrainz.org/ws/2/recording/$recording_mbid");
-        #$uri->query_form(inc => 'artists');
-        #my $res = $ua->get($uri);
-        #die $res->decoded_content;
-
-        #TODO: get track relations (Covers, etc.)
-
-        $tracknum++;
-    }
-
-    return \%info;
-}
-
-sub get_artist_credits {
-    my ($xpath, $context_node) = @_;
-
-    # use the MusicBrainz join phrase to build up the multiple artist credits
-    my ($credit, $sort_credit) = ('', '');
-    for my $credit_node ($xpath->findnodes('artist-credit/name-credit', $context_node)) {
-        $credit      .= $xpath->findvalue('concat(artist/name, @joinphrase)', $credit_node)->value;
-        $sort_credit .= $xpath->findvalue('concat(artist/sort-name, @joinphrase)', $credit_node)->value;
-    }
-
-    return ($credit, $sort_credit);
-}
-
-# module return
-1;
-
-=begin MBZ API version 1
-
-sub lookup_release {
-    my ($discid) = @_;
-    my $ua = LWP::UserAgent->new;
-
-    my $uri = URI->new('http://musicbrainz.org/ws/1/release/');
-    $uri->query_form(type => 'xml', discid => $discid);
-
-    my $res = $ua->get($uri);
-    return $res->decoded_content;
-}
-
-sub get_musicbrainz_info {
-    my ($discid) = @_;
-    my %info;
-
-    $info{MBZ_DISCID} = $discid;
-
-    my $xpath = XML::XPath->new();
-
-    $xpath->set_xml(lookup_release($discid));
-
-    # TODO: check for more than 1 release?
-
-    $info{MB_RELEASE_ID} = $xpath->findvalue('//release/@id');
-    $info{ALBUM}         = $xpath->findvalue('//release/title');
-    $info{ARTIST}        = $xpath->findvalue('//release/artist/name');
-    $info{TRACKS}        = [];
-
-    # TODO: get release date
-
-    my $tracknum = 1;
-    for my $track_node ($xpath->findnodes('//track-list/track')) {
-        $info{TRACKS}[$tracknum]{MB_TRACKID} = $xpath->findvalue('@id', $track_node);
-        $info{TRACKS}[$tracknum]{TITLE}      = $xpath->findvalue('title', $track_node);
-        $info{TRACKS}[$tracknum]{ARTIST}     = $xpath->findvalue('artist/name', $track_node) || $info{ARTIST};
-        $tracknum++;
-    }
-
-    return %info;
-}
-
-=cut
-
-=begin WebService::MusicBrainz code
-
-    my $ws_artists = WebService::MusicBrainz->new_artist;
-    my $ws_releases = WebService::MusicBrainz->new_release;
-    my $ws_tracks = WebService::MusicBrainz->new_track;
-
-    # search on the discid
-    my $response = $ws_releases->search({ DISCID => $discid });
-
-    # save this object, since WS::MBZ deletes it when you fetch it
-    # TODO: bug report to WS::MBZ?
-    my $release = $response->release;
-
-    # return undef if there is no matching release for this DiscID
-    return unless defined $release;
-
-    # search again, using the MBID of the first release found
-    # TODO: deal with multiple releases found?
-    # include tracks and artist info
-    $response = $ws_releases->search({
-        MBID => $release->id, 
-        INC => 'discs tracks artist release-events counts',
-    });
-
-    # get the fully filled out Release object (that represents the disc)
-    $release = $response->release;
-
-    if (defined $release->artist) {
-        $info{ARTIST} = $release->artist->name;
-    }
-    if (defined $release->title) {
-        $info{ALBUM} = $release->title;
-    }
-
-    # this is ID3v2:TDRL = Release Date
-    # (for now we just take the first date)
-    my $release_date = eval { @{ $release->release_event_list->events }[0]->date };
-    $release_date = '' if $@;
-
-    $info{DATE} = $release_date;
-
-    # get full info on each of the tracks
-    my @tracks;
-    my $track_num = 1;
-    for my $track_id (map { $_->id } @{ $release->track_list->tracks }) {
-        my $response = $ws_tracks->search({ 
-            MBID => $track_id,
-            INC => 'artist track-rels',
-        });
-        my $track = $response->track;
-        my $prefix = sprintf('TRACK%02d', $track_num);
-        $info{"$prefix.TITLE"} = $track->title;
-        #if (defined $track->artist && $track->artist->name ne $release->artist->name) {
-            $info{"$prefix.ARTIST"} = $track->artist->name;
-            $info{"$prefix.DATE"} = $release_date;
-        #}
-        push @tracks, $track;
-
-
-        if (defined $track->relation_list) {
-            for my $relation (@{ $track->relation_list->relations }) {
-                #warn $relation->type, $relation->target;
-                my $response = $ws_tracks->search({
-                    MBID => $relation->target,
-                    INC => 'artist releases',
-                });
-                my $track = $response->track;
-                $info{"$prefix.ORIGINAL_ARTIST"} = $track->artist->name;
-                $info{"$prefix.ORIGINAL_ALBUM"} = 
-                    ( (@{ $track->release_list->releases })[0]->title );
-            }
-        }
-
-        $track_num++;
-    }
-
-=cut
Index: trunk/flactrack
===================================================================
--- trunk/flactrack	(revision 10)
+++ trunk/flactrack	(revision 11)
@@ -7,10 +7,11 @@
 # TODO: separate sox filter for each track!
 
+use FindBin;
+use lib "$FindBin::RealBin/lib";
+
 use Getopt::Long qw{:config no_ignore_case};
 use File::Spec::Functions qw{catfile splitpath};
 use File::Path;
 use Audio::FLAC::Header;
-#TODO: put the MusicBrainz lib in a more common location
-use lib qw{/home/peter/projects/flacrip};
 use MusicBrainz;
 
Index: trunk/lib/MusicBrainz.pm
===================================================================
--- trunk/lib/MusicBrainz.pm	(revision 11)
+++ trunk/lib/MusicBrainz.pm	(revision 11)
@@ -0,0 +1,249 @@
+package MusicBrainz;
+
+use strict;
+use warnings;
+
+our @ISA    = qw{Exporter};
+our @EXPORT = qw{get_musicbrainz_info lookup_release};
+
+#use WebService::MusicBrainz;
+use LWP;
+use XML::XPath;
+use XML::XPath::XMLParser;
+
+sub lookup_release {
+    my ($discid) = @_;
+    my $ua = LWP::UserAgent->new;
+
+    #my $uri = URI->new('http://musicbrainz.org/ws/1/release/');
+    #$uri->query_form(type => 'xml', discid => $discid);
+    my $uri = URI->new("http://musicbrainz.org/ws/2/discid/$discid");
+    $uri->query_form(inc => 'artists+labels+recordings+release-groups+artist-credits');
+
+    my $res = $ua->get($uri);
+    # pause for a second, so we don't run afoul of the MusicBrainz API TOS
+    sleep 1;
+
+    warn $res->status_line, "\n" if $res->code != 200;
+    return if $res->code >= 400;
+    #TODO: if we get a 5xx error, retry?
+
+    return $res->decoded_content;
+}
+
+sub get_musicbrainz_info {
+    my ($discid) = @_;
+    my %info;
+
+    #TODO: deprecate the old MBZ tag name
+    $info{MBZ_DISCID} = $discid;
+    $info{MUSICBRAINZ_DISCID} = $discid;
+
+    my $xpath = XML::XPath->new();
+    my $xml = lookup_release($discid) || return;
+    
+    $xpath->set_xml($xml);
+
+    # get the release; if there is more than one, take the first one
+    my $release_count = $xpath->findvalue('count(//release)');
+    my @releases = $xpath->findnodes('//release');
+    my $base = 'http://musicbrainz.org/release/';
+
+    my $i = 1;
+    #TODO: use this as the basis for an interactive menu to pick the correct release ID
+    warn "$release_count release(s) found matching $discid\n";
+    for my $release (@releases) {
+        warn sprintf "%2d) $base%s %s %s (%s)\n", 
+            $i++,
+            $xpath->findvalue('@id', $release)->value,
+            $xpath->findvalue('.//label-info/label/name', $release)->value,
+            $xpath->findvalue('.//label-info/catalog-number', $release)->value,
+            $xpath->findvalue('barcode', $release)->value;
+    }
+
+    # use the VorbisComment names from here http://musicbrainz.org/doc/MusicBrainz_Picard/Tags/Mapping
+
+    # use the first release by default
+    # TODO: configurable release selection criteria
+    my $release = $releases[0];
+
+    $info{MUSICBRAINZ_ALBUMID} = $xpath->findvalue('@id', $release)->value;
+    $info{ALBUM}               = $xpath->findvalue('title', $release)->value;
+    @info{qw{ALBUMARTIST ALBUMARTISTSORT}} = get_artist_credits($xpath, $release);
+    $info{DATE}                = $xpath->findvalue('date', $release)->value;
+    $info{ORIGINALDATE}        = $xpath->findvalue('release-group/first-release-date', $release)->value;
+
+    # select the proper medium (important for multidisc releases)
+    my ($medium) = $xpath->findnodes("medium-list/medium[disc-list/disc/\@id='$discid']", $release);
+
+    # disc position info
+    $info{DISCNUMBER} = $xpath->findvalue('position', $medium)->value;
+    $info{DISCTOTAL}  = $xpath->findvalue('../@count', $medium)->value;
+
+    #my $ua = LWP::UserAgent->new;
+    my $tracknum = 1;
+    for my $track_node ($xpath->findnodes('track-list/track', $medium)) {
+        my $prefix = sprintf('TRACK%02d', $tracknum);
+
+        $info{"$prefix.MUSICBRAINZ_TRACKID"} = $xpath->findvalue('@id', $track_node)->value;
+
+        my ($recording) = $xpath->findnodes('recording', $track_node);
+        $info{"$prefix.MUSICBRAINZ_RECORDINGID"} = $xpath->findvalue('@id', $recording)->value;
+        $info{"$prefix.TITLE"} = $xpath->findvalue('title', $recording)->value;
+        @info{"$prefix.ARTIST", "$prefix.ARTISTSORT"} = get_artist_credits($xpath, $recording);
+
+        $info{TRACKS}[$tracknum]{TITLE} = $info{"$prefix.TITLE"};
+        $info{TRACKS}[$tracknum]{ARTIST} = $info{"$prefix.ARTIST"};
+        $info{TRACKS}[$tracknum]{ARTISTSORT} = $info{"$prefix.ARTISTSORT"};
+
+        #my $uri = URI->new("http://musicbrainz.org/ws/2/recording/$recording_mbid");
+        #$uri->query_form(inc => 'artists');
+        #my $res = $ua->get($uri);
+        #die $res->decoded_content;
+
+        #TODO: get track relations (Covers, etc.)
+
+        $tracknum++;
+    }
+
+    return \%info;
+}
+
+sub get_artist_credits {
+    my ($xpath, $context_node) = @_;
+
+    # use the MusicBrainz join phrase to build up the multiple artist credits
+    my ($credit, $sort_credit) = ('', '');
+    for my $credit_node ($xpath->findnodes('artist-credit/name-credit', $context_node)) {
+        $credit      .= $xpath->findvalue('concat(artist/name, @joinphrase)', $credit_node)->value;
+        $sort_credit .= $xpath->findvalue('concat(artist/sort-name, @joinphrase)', $credit_node)->value;
+    }
+
+    return ($credit, $sort_credit);
+}
+
+# module return
+1;
+
+=begin MBZ API version 1
+
+sub lookup_release {
+    my ($discid) = @_;
+    my $ua = LWP::UserAgent->new;
+
+    my $uri = URI->new('http://musicbrainz.org/ws/1/release/');
+    $uri->query_form(type => 'xml', discid => $discid);
+
+    my $res = $ua->get($uri);
+    return $res->decoded_content;
+}
+
+sub get_musicbrainz_info {
+    my ($discid) = @_;
+    my %info;
+
+    $info{MBZ_DISCID} = $discid;
+
+    my $xpath = XML::XPath->new();
+
+    $xpath->set_xml(lookup_release($discid));
+
+    # TODO: check for more than 1 release?
+
+    $info{MB_RELEASE_ID} = $xpath->findvalue('//release/@id');
+    $info{ALBUM}         = $xpath->findvalue('//release/title');
+    $info{ARTIST}        = $xpath->findvalue('//release/artist/name');
+    $info{TRACKS}        = [];
+
+    # TODO: get release date
+
+    my $tracknum = 1;
+    for my $track_node ($xpath->findnodes('//track-list/track')) {
+        $info{TRACKS}[$tracknum]{MB_TRACKID} = $xpath->findvalue('@id', $track_node);
+        $info{TRACKS}[$tracknum]{TITLE}      = $xpath->findvalue('title', $track_node);
+        $info{TRACKS}[$tracknum]{ARTIST}     = $xpath->findvalue('artist/name', $track_node) || $info{ARTIST};
+        $tracknum++;
+    }
+
+    return %info;
+}
+
+=cut
+
+=begin WebService::MusicBrainz code
+
+    my $ws_artists = WebService::MusicBrainz->new_artist;
+    my $ws_releases = WebService::MusicBrainz->new_release;
+    my $ws_tracks = WebService::MusicBrainz->new_track;
+
+    # search on the discid
+    my $response = $ws_releases->search({ DISCID => $discid });
+
+    # save this object, since WS::MBZ deletes it when you fetch it
+    # TODO: bug report to WS::MBZ?
+    my $release = $response->release;
+
+    # return undef if there is no matching release for this DiscID
+    return unless defined $release;
+
+    # search again, using the MBID of the first release found
+    # TODO: deal with multiple releases found?
+    # include tracks and artist info
+    $response = $ws_releases->search({
+        MBID => $release->id, 
+        INC => 'discs tracks artist release-events counts',
+    });
+
+    # get the fully filled out Release object (that represents the disc)
+    $release = $response->release;
+
+    if (defined $release->artist) {
+        $info{ARTIST} = $release->artist->name;
+    }
+    if (defined $release->title) {
+        $info{ALBUM} = $release->title;
+    }
+
+    # this is ID3v2:TDRL = Release Date
+    # (for now we just take the first date)
+    my $release_date = eval { @{ $release->release_event_list->events }[0]->date };
+    $release_date = '' if $@;
+
+    $info{DATE} = $release_date;
+
+    # get full info on each of the tracks
+    my @tracks;
+    my $track_num = 1;
+    for my $track_id (map { $_->id } @{ $release->track_list->tracks }) {
+        my $response = $ws_tracks->search({ 
+            MBID => $track_id,
+            INC => 'artist track-rels',
+        });
+        my $track = $response->track;
+        my $prefix = sprintf('TRACK%02d', $track_num);
+        $info{"$prefix.TITLE"} = $track->title;
+        #if (defined $track->artist && $track->artist->name ne $release->artist->name) {
+            $info{"$prefix.ARTIST"} = $track->artist->name;
+            $info{"$prefix.DATE"} = $release_date;
+        #}
+        push @tracks, $track;
+
+
+        if (defined $track->relation_list) {
+            for my $relation (@{ $track->relation_list->relations }) {
+                #warn $relation->type, $relation->target;
+                my $response = $ws_tracks->search({
+                    MBID => $relation->target,
+                    INC => 'artist releases',
+                });
+                my $track = $response->track;
+                $info{"$prefix.ORIGINAL_ARTIST"} = $track->artist->name;
+                $info{"$prefix.ORIGINAL_ALBUM"} = 
+                    ( (@{ $track->release_list->releases })[0]->title );
+            }
+        }
+
+        $track_num++;
+    }
+
+=cut
Index: trunk/mbz
===================================================================
--- trunk/mbz	(revision 10)
+++ trunk/mbz	(revision 11)
@@ -3,4 +3,7 @@
 
 # one use case: for f in ~/cds/*.flac; do mbid=`./mbz --flac $f --get-release-id`; echo $f $mbid; done;
+
+use FindBin;
+use lib "$FindBin::RealBin/lib";
 
 use Getopt::Long;
