Skip Menu |

This queue is for tickets about the WebService-MusicBrainz CPAN distribution.

Report information
The Basics
Id: 21755
Status: resolved
Priority: 0/
Queue: WebService-MusicBrainz

People
Owner: bfaist [...] cpan.org
Requestors: glitch241 [...] comcast.net
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: Bug fix for track_list sub-element of release
Date: Wed, 27 Sep 2006 19:12:09 -0500
To: bug-WebService-MusicBrainz [...] rt.cpan.org
From: Powder <glitch241 [...] comcast.net>
Version: WebService-MusicBrainz-0.02 Perl Version: 5.8.7 Running with MusicBrainz version: unknown date: Sept 27, 2006 On a query for a Release with mbid and an inc of tracks, the Release has an undefined array as the track list; eventhough, the response XML has the track-list. An example of the response is: <?xml version="1.0" encoding="UTF-8"?> <metadata xmlns="http://musicbrainz.org/ns/mmd-1.0#" xmlns:ext="http://musicbrainz.org/ns/ext-1.0#"> <release id="7279b0f3-7bf8-459a-8cbf-35f526f33d21" type="Live Official" > <title>Live at the El Mocambo</title> <track-list> <track id="c531d718-dad7-4038-9e31-777874dbcc7f"><title>Mystery Dance</title><duration>139000</duration></track> ... </track-list> </release> It appears that the code in Response.pm expects to receive only a track-list as the root element and not a sub-element of release. Attached to this email is a copy of the Response.pm that has been updated to correct the problem.
package WebService::MusicBrainz::Response; use strict; use XML::Twig; our $VERSION = '0.02'; =head1 NAME WebService::MusicBrainz::Response =head1 SYNOPSIS =head1 DESCRIPTION This module will hide the details of the XML web service response and provide an API to query the XML data which has been returned. This module is responsible for parsing the XML web service response and instantiating objects to provide access to the details of the response. =head1 METHODS =head2 new() This method is the constructor and it will call for initialization. =cut sub new { my $class = shift; my %params = @_; my $self = {}; bless $self, $class; $self->{_xml} = $params{XML} || die "XML parameter required"; $self->_get_twig(); $self->_init(); return $self; } =head2 _get_twig() This method will create an XML::Twig object and parse the XML response which is then stored in the XML::Twig object. =cut sub _get_twig { my $self = shift; my $xTwig = XML::Twig->new(); $xTwig->safe_parse($self->{_xml}) or die "Failure to parse XML"; my $xRoot = $xTwig->root(); $self->{_xmltwig} = $xRoot; return; } =head2 as_xml() This method returns the raw XML from the MusicBrainz web service response. =cut sub as_xml { my $self = shift; return $self->{_xml}; } =head2 _init() This method will parse the XML response and act as a factory to generate the collection of WebService::MusicBrainz::Response::* objects that represent the XML data. =cut sub _init { my $self = shift; my $xRoot = $self->{_xmltwig} || return; require WebService::MusicBrainz::Response::Metadata; my $metadata = WebService::MusicBrainz::Response::Metadata->new(); $metadata->generator( $xRoot->att('generator') ) if $xRoot->att('generator'); $metadata->created( $xRoot->att('created') ) if $xRoot->att('created'); my @artist_list; my @release_list; my @track_list; if($xRoot->first_child('artist')) { my $xArtist = $xRoot->first_child('artist'); my $artist = _create_artist( $xArtist ); push @artist_list, $artist; } elsif($xRoot->first_child('artist-list')) { foreach my $xArtist ($xRoot->get_xpath('artist-list/artist')) { my $artist = _create_artist( $xArtist ); push @artist_list, $artist; } } elsif($xRoot->first_child('release')) { my $xRelease = $xRoot->first_child('release'); my $release = _create_release( $xRelease ); push @release_list, $release; } elsif($xRoot->first_child('release-list')) { foreach my $xRelease ($xRoot->get_xpath('release-list/release')) { my $release = _create_release( $xRelease ); push @release_list, $release; } } elsif($xRoot->first_child('track')) { my $xTrack = $xRoot->first_child('track'); my $track = _create_track( $xTrack ); push @track_list, $track; } elsif($xRoot->first_child('track-list')) { foreach my $xTrack ($xRoot->get_xpath('track-list/track')) { my $track = _create_track( $xTrack ); push @track_list, $track; } } $metadata->artist_list(\@artist_list); $metadata->track_list(\@track_list); $metadata->release_list(\@release_list); $self->{_metadata_cache} = $metadata; } =head2 artist() This method will return the first artist object from the artist list. =cut sub artist { my $self = shift; my $metadata = $self->{_metadata_cache}; my $artist_list = $metadata->artist_list(); return shift @{ $artist_list }; } =head2 release() This method will return the first release object from the release list. =cut sub release { my $self = shift; my $metadata = $self->{_metadata_cache}; my $release_list = $metadata->release_list(); return shift @{ $release_list }; } =head2 track() This method will return the first track object from the track list. =cut sub track { my $self = shift; my $metadata = $self->{_metadata_cache}; my $track_list = $metadata->track_list(); return shift @{ $track_list }; } =head2 artist_list() This method will return the artist list. =cut sub artist_list { my $self = shift; my $metadata = $self->{_metadata_cache}; my $artist_list = $metadata->artist_list(); return wantarray ? @$artist_list : $artist_list; } =head2 release_list() This method will return the release list. =cut sub release_list { my $self = shift; my $metadata = $self->{_metadata_cache}; my $release_list = $metadata->release_list(); return wantarray ? @$release_list : $release_list; } =head2 track_list() This method will return the track list. =cut sub track_list { my $self = shift; my $metadata = $self->{_metadata_cache}; my $track_list = $metadata->track_list(); return wantarray ? @$track_list : $track_list; } =head2 _create_artist() Helper function to create a WebService::MusicBrainz::Response::Artist object and to populate it with data. Internal use only. =cut sub _create_artist { my $xArtist = shift; require WebService::MusicBrainz::Response::Artist; my $artist = WebService::MusicBrainz::Response::Artist->new(); $artist->id( $xArtist->att('id') ) if $xArtist->att('id'); $artist->type( $xArtist->att('type') ) if $xArtist->att('type'); $artist->name( $xArtist->first_child('name')->text() ) if $xArtist->first_child('name'); $artist->sort_name( $xArtist->first_child('sort-name')->text() ) if $xArtist->first_child('sort-name'); $artist->disambiguation( $xArtist->first_child('disambiguation')->text() ) if $xArtist->first_child('disambiguation'); $artist->life_span_begin( $xArtist->first_child('life-span')->att('begin') ) if $xArtist->first_child('life-span') && $xArtist->first_child('life-span')->att('begin'); $artist->life_span_end( $xArtist->first_child('life-span')->att('end') ) if $xArtist->first_child('life-span') && $xArtist->first_child('life-span')->att('end'); if($xArtist->first_child('alias-list')) { my @alias_list; foreach my $xAlias ($xArtist->get_xpath('alias-list/alias')) { my $alias = _create_alias($xAlias); push @alias_list, $alias; } $artist->alias_list( \@alias_list ); } if($xArtist->first_child('relation-list')) { my @relation_list; foreach my $xRelation ($xArtist->get_xpath('relation-list/relation')) { my $relation = _create_relation($xRelation); push @relation_list, $relation; } $artist->relation_list( \@relation_list ); } if($xArtist->first_child('release-list')) { my @release_list; foreach my $xRelease ($xArtist->get_xpath('release-list/release')) { my $release = _create_release($xRelease); push @release_list, $release; } $artist->release_list( \@release_list ); } return $artist; } =head2 _create_release() Helper function to create a WebService::MusicBrainz::Response::Release object and to populate it with data. Internal use only. =cut sub _create_release { my $xRelease = shift; require WebService::MusicBrainz::Response::Release; my $release = WebService::MusicBrainz::Response::Release->new(); $release->id( $xRelease->att('id') ) if $xRelease->att('id'); $release->type( $xRelease->att('type') ) if $xRelease->att('type'); $release->title( $xRelease->first_child('title')->text() ) if $xRelease->first_child('title'); $release->text_rep_language( $xRelease->first_child('text-representation')->att('language') ) if $xRelease->first_child('text-representation') && $xRelease->first_child('text-representation')->att('language'); $release->text_rep_script( $xRelease->first_child('text-representation')->att('script') ) if $xRelease->first_child('text-representation') && $xRelease->first_child('text-representation')->att('script'); $release->asin( $xRelease->first_child('asin')->text() ) if $xRelease->first_child('asin'); my $xArtist = $xRelease->first_child('artist'); if(defined($xArtist)) { my $artist = _create_artist($xArtist); $release->artist($artist); } my @track_list; if ($xRelease->first_child('track-list')) { foreach my $xTrack ($xRelease->get_xpath('track-list/track')) { my $track = _create_track( $xTrack ); push @track_list, $track; } } $release->track_list(\@track_list); return $release; } =head2 _create_track() Helper function to create a WebService::MusicBrainz::Response::Track object and to populate it with data. Internal use only. =cut sub _create_track { my $xTrack = shift; require WebService::MusicBrainz::Response::Track; my $track= WebService::MusicBrainz::Response::Track->new(); $track->id( $xTrack->att('id') ) if $xTrack->att('id'); $track->title( $xTrack->first_child('title')->text() ) if $xTrack->first_child('title'); $track->duration( $xTrack->first_child('duration')->text() ) if $xTrack->first_child('duration'); my $xArtist = $xTrack->first_child('artist'); if(defined($xArtist)) { my $artist = _create_artist($xArtist); $track->artist($artist); } my @release_list; foreach my $xRelease ($xTrack->get_xpath('release-list/release')) { my $release = _create_release($xRelease); push @release_list, $release; } $track->release_list(\@release_list); return $track; } =head2 _create_alias() Helper function to create a WebService::MusicBrainz::Response::Alias object and to populate it with data. Internal use only. =cut sub _create_alias { my $xAlias = shift; require WebService::MusicBrainz::Response::Alias; my $alias = WebService::MusicBrainz::Response::Alias->new(); $alias->type( $xAlias->att('type') ) if $xAlias->att('type'); $alias->script( $xAlias->att('script') ) if $xAlias->att('script'); $alias->text( $xAlias->text() ) if $xAlias->text(); return $alias; } =head2 _create_relation() Helper function to create a WebService::MusicBrainz::Response::Relation object and to populate it with data. Internal use only. =cut sub _create_relation { my $xRelation = shift; require WebService::MusicBrainz::Response::Relation; my $relation = WebService::MusicBrainz::Response::Relation->new(); $relation->type( $xRelation->att('type') ) if $xRelation->att('type'); $relation->target( $xRelation->att('target') ) if $xRelation->att('target'); $relation->direction( $xRelation->att('direction') ) if $xRelation->att('direction'); $relation->attributes( $xRelation->att('attributes') ) if $xRelation->att('attributes'); $relation->begin( $xRelation->att('begin') ) if $xRelation->att('begin'); $relation->end( $xRelation->att('end') ) if $xRelation->att('end'); if($xRelation->first_child('artist')) { my $artist = _create_artist($xRelation->first_child('artist')); $relation->artist($artist); } elsif($xRelation->first_child('release')) { my $release = _create_release($xRelation->first_child('release')); $relation->release($release); } elsif($xRelation->first_child('track')) { my $track = _create_track($xRelation->first_child('track')); $relation->track($track); } return $relation; } =head1 AUTHOR =over 4 =item Bob Faist <bob.faist@gmail.com> =back =head1 COPYRIGHT AND LICENSE Copyright 2006 by Bob Faist This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 SEE ALSO http://wiki.musicbrainz.org/XMLWebService =cut 1;