Changeset 3 in flacrip


Ignore:
Timestamp:
01/27/12 21:58:19 (12 years ago)
Author:
peter
Message:

moved the MusicBrainz info lookup code into a common MusicBrainz.pm module, to be used by both the mbz and flactrack scripts

Location:
trunk
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/flactrack

    r1 r3  
    88 
    99use Getopt::Long; 
     10use MusicBrainz; 
    1011 
    1112GetOptions( 
     
    2122 
    2223# for getting track metadata from MusicBrainz 
    23 my %info; 
     24my $info; 
    2425if ($TYPE eq 'mp3') { 
    2526    require Audio::FLAC::Header; 
     
    3233    #TODO: calculate TOC and DISCID from cuesheet if there is no MBZ_DISCID tag present 
    3334 
    34     #TODO: use the functions in mbz instead of repeating them here) 
    35     %info = get_musicbrainz_info($discid); 
     35    $info = get_musicbrainz_info($discid); 
    3636} 
    3737 
     
    5454        $cmd .= qq{| lame -b 192}; 
    5555        # if there is track info, add it as ID3 tags 
    56         if (%info) { 
    57             my $track = $info{TRACKS}[$tracknum]; 
     56        if ($info) { 
     57            my $track = $info->{TRACKS}[$tracknum]; 
    5858            $cmd .= sprintf q{ --tt %s --ta %s --tl %s --tn %d}, 
    59                 quote($$track{TITLE}), 
    60                 quote($$track{ARTIST}), 
    61                 quote($info{ALBUM}), 
     59                quote($track->{TITLE}), 
     60                quote($track->{ARTIST}), 
     61                quote($info->{ALBUM}), 
    6262                $tracknum; 
    6363        } 
     
    7979    return qq{"$string"}; 
    8080} 
    81  
    82  
    83 # make the output terminal handle UTF-8 characters 
    84 #binmode STDOUT, ':utf8'; 
    85 #my $info = get_musicbrainz_info($discid); 
    86 #for my $key (sort keys %{ $info }) { 
    87 #    print "$key=$$info{$key}\n"; 
    88 #} 
    89  
    90 sub lookup_release { 
    91     my ($discid) = @_; 
    92     my $ua = LWP::UserAgent->new; 
    93  
    94     my $uri = URI->new('http://musicbrainz.org/ws/1/release/'); 
    95     $uri->query_form(type => 'xml', discid => $discid); 
    96  
    97     my $res = $ua->get($uri); 
    98     return $res->decoded_content; 
    99 } 
    100  
    101 sub get_musicbrainz_info { 
    102     my ($discid) = @_; 
    103     my %info; 
    104  
    105     $info{MBZ_DISCID} = $discid; 
    106  
    107     my $xpath = XML::XPath->new(); 
    108  
    109     $xpath->set_xml(lookup_release($discid)); 
    110  
    111     # TODO: check for more than 1 release? 
    112  
    113     $info{MB_RELEASE_ID} = $xpath->findvalue('//release/@id'); 
    114     $info{ALBUM}         = $xpath->findvalue('//release/title'); 
    115     $info{ARTIST}        = $xpath->findvalue('//release/artist/name'); 
    116     $info{TRACKS}        = []; 
    117  
    118     # TODO: get release date 
    119  
    120     my $tracknum = 1; 
    121     for my $track_node ($xpath->findnodes('//track-list/track')) { 
    122         $info{TRACKS}[$tracknum]{MB_TRACKID} = $xpath->findvalue('@id', $track_node); 
    123         $info{TRACKS}[$tracknum]{TITLE}      = $xpath->findvalue('title', $track_node); 
    124         $info{TRACKS}[$tracknum]{ARTIST}     = $xpath->findvalue('artist/name', $track_node) || $info{ARTIST}; 
    125         $tracknum++; 
    126     } 
    127  
    128     return %info; 
    129 } 
  • trunk/mbz

    r1 r3  
    55 
    66use Getopt::Long; 
    7 #use WebService::MusicBrainz; 
    8  
    9 use LWP; 
    10 use XML::XPath; 
    11 use XML::XPath::XMLParser; 
     7use MusicBrainz; 
    128 
    139GetOptions( 
     
    3026binmode STDOUT, ':utf8'; 
    3127 
     28# just dump the XML, if requested 
     29if ($GET_XML) { 
     30    print lookup_release($discid); 
     31    exit; 
     32} 
     33 
     34# otherwise, do the full parsing of the data 
    3235my $info = get_musicbrainz_info($discid); 
    3336 
     
    4144    } 
    4245} 
    43  
    44 sub lookup_release { 
    45     my ($discid) = @_; 
    46     my $ua = LWP::UserAgent->new; 
    47  
    48     #my $uri = URI->new('http://musicbrainz.org/ws/1/release/'); 
    49     #$uri->query_form(type => 'xml', discid => $discid); 
    50     my $uri = URI->new("http://musicbrainz.org/ws/2/discid/$discid"); 
    51     $uri->query_form(inc => 'artists+labels+recordings+release-groups+artist-credits'); 
    52  
    53     my $res = $ua->get($uri); 
    54     # pause for a second, so we don't run afoul of the MusicBrainz API TOS 
    55     sleep 1; 
    56  
    57     warn $res->status_line, "\n" if $res->code != 200; 
    58     return if $res->code >= 400; 
    59     #TODO: if we get a 5xx error, retry? 
    60  
    61     return $res->decoded_content; 
    62 } 
    63  
    64 sub get_musicbrainz_info { 
    65     my ($discid) = @_; 
    66     my %info; 
    67  
    68     $info{MBZ_DISCID} = $discid; 
    69  
    70     my $xpath = XML::XPath->new(); 
    71     my $xml = lookup_release($discid) || return; 
    72      
    73     # just dump the XML, if requested 
    74     if ($GET_XML) { 
    75         print $xml; 
    76         exit; 
    77     } 
    78  
    79     $xpath->set_xml($xml); 
    80  
    81     # get the release; if there is more than one, take the first one 
    82     # TODO: configurable release selection criteria 
    83     my $release_count = $xpath->findvalue('count(//release)'); 
    84     my ($release) = $xpath->findnodes('//release[1]'); 
    85     $info{RELEASE_MBID} = $xpath->findvalue('@id', $release); 
    86     $info{ALBUM}        = $xpath->findvalue('title', $release); 
    87     $info{ARTIST}       = $xpath->findvalue('artist-credit/name-credit/artist/name', $release); 
    88  
    89     # TODO: get release date 
    90  
    91     my $ua = LWP::UserAgent->new; 
    92     my $tracknum = 1; 
    93     for my $track_node ($xpath->findnodes('.//track-list/track', $release)) { 
    94         my $prefix = sprintf('TRACK%02d', $tracknum); 
    95         #$info{"$prefix.MB_TRACKID"} = $xpath->findvalue('@id', $track_node); 
    96         my $recording_mbid = $info{"$prefix.RECORDING_MBID"} = $xpath->findvalue('recording/@id', $track_node); 
    97         $info{"$prefix.TITLE"}          = $xpath->findvalue('recording/title', $track_node); 
    98         $info{"$prefix.ARTIST"}         = $xpath->findvalue('recording/artist-credit/name-credit/artist/name', $track_node) || $info{ARTIST}; 
    99         #my $uri = URI->new("http://musicbrainz.org/ws/2/recording/$recording_mbid"); 
    100         #$uri->query_form(inc => 'artists'); 
    101         #my $res = $ua->get($uri); 
    102         #die $res->decoded_content; 
    103  
    104         #TODO: get track relations (Covers, etc.) 
    105  
    106         $tracknum++; 
    107     } 
    108  
    109 =begin 
    110  
    111     my $ws_artists = WebService::MusicBrainz->new_artist; 
    112     my $ws_releases = WebService::MusicBrainz->new_release; 
    113     my $ws_tracks = WebService::MusicBrainz->new_track; 
    114  
    115     # search on the discid 
    116     my $response = $ws_releases->search({ DISCID => $discid }); 
    117  
    118     # save this object, since WS::MBZ deletes it when you fetch it 
    119     # TODO: bug report to WS::MBZ? 
    120     my $release = $response->release; 
    121  
    122     # return undef if there is no matching release for this DiscID 
    123     return unless defined $release; 
    124  
    125     # search again, using the MBID of the first release found 
    126     # TODO: deal with multiple releases found? 
    127     # include tracks and artist info 
    128     $response = $ws_releases->search({ 
    129         MBID => $release->id,  
    130         INC => 'discs tracks artist release-events counts', 
    131     }); 
    132  
    133     # get the fully filled out Release object (that represents the disc) 
    134     $release = $response->release; 
    135  
    136     if (defined $release->artist) { 
    137         $info{ARTIST} = $release->artist->name; 
    138     } 
    139     if (defined $release->title) { 
    140         $info{ALBUM} = $release->title; 
    141     } 
    142  
    143     # this is ID3v2:TDRL = Release Date 
    144     # (for now we just take the first date) 
    145     my $release_date = eval { @{ $release->release_event_list->events }[0]->date }; 
    146     $release_date = '' if $@; 
    147  
    148     $info{DATE} = $release_date; 
    149  
    150     # get full info on each of the tracks 
    151     my @tracks; 
    152     my $track_num = 1; 
    153     for my $track_id (map { $_->id } @{ $release->track_list->tracks }) { 
    154         my $response = $ws_tracks->search({  
    155             MBID => $track_id, 
    156             INC => 'artist track-rels', 
    157         }); 
    158         my $track = $response->track; 
    159         my $prefix = sprintf('TRACK%02d', $track_num); 
    160         $info{"$prefix.TITLE"} = $track->title; 
    161         #if (defined $track->artist && $track->artist->name ne $release->artist->name) { 
    162             $info{"$prefix.ARTIST"} = $track->artist->name; 
    163             $info{"$prefix.DATE"} = $release_date; 
    164         #} 
    165         push @tracks, $track; 
    166  
    167  
    168         if (defined $track->relation_list) { 
    169             for my $relation (@{ $track->relation_list->relations }) { 
    170                 #warn $relation->type, $relation->target; 
    171                 my $response = $ws_tracks->search({ 
    172                     MBID => $relation->target, 
    173                     INC => 'artist releases', 
    174                 }); 
    175                 my $track = $response->track; 
    176                 $info{"$prefix.ORIGINAL_ARTIST"} = $track->artist->name; 
    177                 $info{"$prefix.ORIGINAL_ALBUM"} =  
    178                     ( (@{ $track->release_list->releases })[0]->title ); 
    179             } 
    180         } 
    181  
    182         $track_num++; 
    183     } 
    184  
    185 =cut 
    186  
    187     return \%info; 
    188 } 
Note: See TracChangeset for help on using the changeset viewer.