summaryrefslogtreecommitdiff
path: root/lib/gcstar/GCPlugins/GCmusics
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gcstar/GCPlugins/GCmusics')
-rw-r--r--lib/gcstar/GCPlugins/GCmusics/GCDiscogs.pm333
-rw-r--r--lib/gcstar/GCPlugins/GCmusics/GCDoubanmusic.pm238
-rw-r--r--lib/gcstar/GCPlugins/GCmusics/GCMusicBrainz.pm309
-rw-r--r--lib/gcstar/GCPlugins/GCmusics/GCmusicsCommon.pm62
4 files changed, 942 insertions, 0 deletions
diff --git a/lib/gcstar/GCPlugins/GCmusics/GCDiscogs.pm b/lib/gcstar/GCPlugins/GCmusics/GCDiscogs.pm
new file mode 100644
index 0000000..c6e0c87
--- /dev/null
+++ b/lib/gcstar/GCPlugins/GCmusics/GCDiscogs.pm
@@ -0,0 +1,333 @@
+package GCPlugins::GCmusics::GCDiscogs;
+
+###################################################
+#
+# Copyright 2005-2010 Christian Jodar
+#
+# This file is part of GCstar.
+#
+# GCstar is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GCstar is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCstar; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+#
+###################################################
+
+use strict;
+use utf8;
+
+use GCPlugins::GCmusics::GCmusicsCommon;
+
+{
+ package GCPlugins::GCmusics::GCPluginDiscogs;
+
+ use base 'GCPlugins::GCmusics::GCmusicsPluginsBase';
+ use XML::Simple;
+
+ sub parse
+ {
+ my ($self, $page) = @_;
+ return if $page =~ /^<!DOCTYPE html/;
+ my $xml;
+ my $xs = XML::Simple->new;
+ my $key = $self->{searchField};
+ if ($self->{parsingList})
+ {
+ if ( $key eq 'artist' )
+ {
+ $xml = $xs->XMLin($page);
+ my $artist = $xml -> {'artist'} -> {'name'};
+ my $release;
+ foreach $release ( keys( %{ $xml -> {'artist'} -> {'releases'} -> {'release'} } ) )
+ {
+ $self->{itemIdx}++;
+ my $title = $xml -> {'artist'} -> {'releases'} -> {'release'} -> {$release} -> {'title'};
+ $self->{itemsList}[$self->{itemIdx}]->{url} = "http://api.discogs.com/release/".$release."?f=xml&api_key=e8f5ae8ba2";
+ $self->{itemsList}[$self->{itemIdx}]->{title} = $title;
+ # Enleve les blancs en debut de chaine
+ $self->{itemsList}[$self->{itemIdx}]->{title} =~ s/^\s+//;
+
+ $self->{itemsList}[$self->{itemIdx}]->{artist} = $artist;
+ # Enleve les blancs en fin de chaine
+ $self->{itemsList}[$self->{itemIdx}]->{artist} =~ s/\s+$//;
+ }
+ }
+ elsif ( $key eq 'label' )
+ {
+ $xml = $xs->XMLin($page);
+ my $release;
+ foreach $release ( keys( %{ $xml -> {'label'} -> {'releases'} -> {'release'} } ) )
+ {
+ $self->{itemIdx}++;
+ my $title = $xml -> {'label'} -> {'releases'} -> {'release'} -> {$release} -> {'title'};
+ my $artist = $xml -> {'label'} -> {'releases'} -> {'release'} -> {$release} -> {'artist'};
+ $self->{itemsList}[$self->{itemIdx}]->{url} = "http://api.discogs.com/release/".$release."?f=xml&api_key=e8f5ae8ba2";
+ $self->{itemsList}[$self->{itemIdx}]->{title} = $title;
+ # Enleve les blancs en debut de chaine
+ $self->{itemsList}[$self->{itemIdx}]->{title} =~ s/^\s+//;
+
+ $self->{itemsList}[$self->{itemIdx}]->{artist} = $artist;
+ # Enleve les blancs en fin de chaine
+ $self->{itemsList}[$self->{itemIdx}]->{artist} =~ s/\s+$//;
+ }
+ }
+ else
+ {
+ $xml = $xs->XMLin($page,
+ ForceArray => ['result', 'event'],
+ KeyAttr => {'release' => ''});
+ my $release;
+ foreach $release ( @{ $xml->{'searchresults'}->{result} } )
+ {
+ if ($release->{type} eq 'release')
+ {
+ $self->{itemIdx}++;
+ $self->{itemsList}[$self->{itemIdx}]->{url} = $release->{uri};
+ $self->{itemsList}[$self->{itemIdx}]->{release} = $release->{summary};
+
+ my $found = index($release->{title},"-");
+ if ( $found >= 0 )
+ {
+
+ $self->{itemsList}[$self->{itemIdx}]->{title} = substr($release->{title}, $found +length('-'),length($release->{title})- $found -length('-'));
+ # Enleve les blancs en debut de chaine
+ $self->{itemsList}[$self->{itemIdx}]->{title} =~ s/^\s+//;
+
+ $self->{itemsList}[$self->{itemIdx}]->{artist} = substr($release->{title}, 0, $found);
+ # Enleve les blancs en fin de chaine
+ $self->{itemsList}[$self->{itemIdx}]->{artist} =~ s/\s+$//;
+
+ # Clean up release summary
+ my $tmpTitle = $release->{title};
+ $tmpTitle =~ s/\- //;
+
+ # Unsure about this line, seems to not be required anymore, and is breaking parsing
+ # of search results. EG - searching for "raw animals"
+ # $self->{itemsList}[$self->{itemIdx}]->{release} =~ s/^$tmpTitle //;
+ }
+ else
+ {
+ $self->{itemsList}[$self->{itemIdx}]->{title} = $release->{title};
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ $xml = $xs->XMLin($page,
+ ForceArray => ['track', 'artist', 'image', 'label', 'genre', 'format'],
+ KeyAttr => {'track' => ''});
+ $self->{curInfo}->{title} = $xml->{release}->{title};
+ $self->{curInfo}->{artist} = '';
+ for my $art (@{$xml->{release}->{artists}->{artist}})
+ {
+ $self->{curInfo}->{artist} .= $art->{name}.', ';
+ }
+ $self->{curInfo}->{artist} =~ s/, $//;
+ $self->{curInfo}->{producer} = '';
+ $self->{curInfo}->{composer} = '';
+ for my $rel (@{$xml->{release}->{extraartists}->{artist}})
+ {
+ $self->{curInfo}->{producer} .= $rel->{name}.', '
+ if $rel->{role} eq 'Producer';
+ $self->{curInfo}->{composer} .= $rel->{name}.', '
+ if (($rel->{role} eq 'Composed By') || ($rel->{role} eq 'Score') || ($rel->{role} eq 'Songwriter') || ($rel->{role} eq 'Written-By'));
+ }
+ $self->{curInfo}->{producer} =~ s/, $//;
+ $self->{curInfo}->{composer} =~ s/, $//;
+ $self->{curInfo}->{release} = $xml->{release}->{released};
+ for my $track(@{$xml->{release}->{'tracklist'}->{track}})
+ {
+ my $duree = $track->{duration};
+ $duree =~ /([0-9]+):([0-9]+)/;
+ my $duree2 = int($1*60 + $2);
+ my $position = "";
+ # Sometimes the position is missing, which causes it to be an array
+ if (!ref($track->{position}))
+ {
+ $position = $track->{position};
+ }
+ $self->addTrack($track->{title}, $duree2, $position);
+ }
+ $self->{curInfo}->{tracks} = $self->getTracks;
+ $self->{curInfo}->{running} = $self->getTotalTime;
+ for my $cover(@{$xml->{release}->{images}->{image}})
+ {
+ if ($self->{curInfo}->{cover} eq '')
+ {
+ if ($self->{bigPics})
+ {
+ $self->{curInfo}->{cover} = $cover->{uri};
+ }
+ else
+ {
+ $self->{curInfo}->{cover} = $cover->{uri};
+ # Change to small res cover
+ $self->{curInfo}->{cover} =~ s/image\/R-/image\/R-150-/;
+ }
+ }
+
+ }
+ $self->{curInfo}->{label} = '';
+ for my $label (@{$xml->{release}->{labels}->{label}})
+ {
+ $self->{curInfo}->{label} .= $label->{name}.', ';
+ }
+ $self->{curInfo}->{label} =~ s/, $//;
+ $self->{curInfo}->{genre} = '';
+ for my $genre (@{$xml->{release}->{genres}->{genre}})
+ {
+ $self->{curInfo}->{genre} .= $genre.',';
+ }
+ $self->{curInfo}->{genre} =~ s/,$//;
+ $self->{curInfo}->{origin} = $xml->{release}->{country};
+ $self->{curInfo}->{origin} =~ s/,$//;
+ for my $format(@{$xml->{release}->{formats}->{format}})
+ {
+ if ( $self->{curInfo}->{format} eq '')
+ {
+ $self->{curInfo}->{format} = $format->{name};
+ $self->{curInfo}->{format} =~ s/,$//;
+ }
+ }
+ $self->{curInfo}->{web} = 'http://www.discogs.com/release/' . $xml->{release}->{id};
+ }
+ }
+
+ sub new
+ {
+ my $proto = shift;
+ my $class = ref($proto) || $proto;
+ my $self = $class->SUPER::new();
+ bless ($self, $class);
+
+ $self->{hasField} = {
+ title => 1,
+ artist => 1,
+ release => 1
+ };
+
+ return $self;
+ }
+
+ sub preProcess
+ {
+ my ($self, $html) = @_;
+
+ return $html;
+ }
+
+ sub decodeEntitiesWanted
+ {
+ return 0;
+ }
+
+ sub getSearchUrl
+ {
+ my ($self, $word) = @_;
+
+ my $key = $self->{searchField};
+ my $url;
+ if ( $key eq 'title' )
+ {
+ $url = "http://api.discogs.com/search?type=all&q=". $word ."&f=xml&api_key=e8f5ae8ba2";
+ }
+ elsif ( $key eq 'artist' )
+ {
+ $url = "http://api.discogs.com/". $key ."/". $word ."?f=xml&api_key=e8f5ae8ba2";
+ }
+ elsif ( $key eq 'label' )
+ {
+ $url = "http://api.discogs.com/". $key ."/". $word ."?f=xml&api_key=e8f5ae8ba2";
+ }
+
+ return $url;
+# return "http://api.discogs.com/search?type=all&q=". $word ."&f=xml&api_key=e8f5ae8ba2";
+ }
+
+ sub getItemUrl
+ {
+ my ($self, $url) = @_;
+ if (!$url)
+ {
+ # If we're not passed a url, return a hint so that gcstar knows what type
+ # of addresses this plugin handles
+ $url = "http://www.discogs.com";
+ }
+ elsif (index($url,"api_key") < 0)
+ {
+ # Url isn't for the discogs api, so we need to find the release id
+ # and return a url corresponding to the api page for this release
+ $url =~ /release\/([0-9]+)/;
+ my $id = $1;
+ $url = "http://api.discogs.com/release/". $id ."?f=xml&api_key=e8f5ae8ba2";
+ }
+ return $url;
+ }
+
+ sub changeUrl
+ {
+ my ($self, $url) = @_;
+
+ return $self->getItemUrl($url);
+ }
+
+ sub getName
+ {
+ return 'Discogs';
+ }
+
+ sub getAuthor
+ {
+ return 'TPF';
+ }
+
+ sub getLang
+ {
+ return 'EN';
+ }
+
+ sub getCharset
+ {
+ my $self = shift;
+
+ return "UTF-8";
+ }
+
+ sub getSearchCharset
+ {
+ my $self = shift;
+
+ # Need urls to be double character encoded
+ return "utf8";
+ }
+
+ sub convertCharset
+ {
+ my ($self, $value) = @_;
+ return $value;
+ }
+
+ sub getNotConverted
+ {
+ my $self = shift;
+ return [];
+ }
+
+ sub getSearchFieldsArray
+ {
+ return ['title', 'artist', 'label'];
+ }
+}
+
+1;
diff --git a/lib/gcstar/GCPlugins/GCmusics/GCDoubanmusic.pm b/lib/gcstar/GCPlugins/GCmusics/GCDoubanmusic.pm
new file mode 100644
index 0000000..b2d7873
--- /dev/null
+++ b/lib/gcstar/GCPlugins/GCmusics/GCDoubanmusic.pm
@@ -0,0 +1,238 @@
+package GCPlugins::GCmusics::GCDoubanmusic;
+
+###################################################
+#
+# Copyright 2005-2010 Bai Wensimi
+#
+# This file is part of GCstar.
+#
+# GCstar is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GCstar is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCstar; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+#
+###################################################
+
+use strict;
+use utf8;
+
+use GCPlugins::GCmusics::GCmusicsCommon;
+
+{
+ package GCPlugins::GCmusics::GCPluginDoubanmusic;
+
+ use base qw(GCPlugins::GCmusics::GCmusicsPluginsBase);
+ use XML::Simple;
+ use Encode;
+ use LWP::Simple qw($ua);
+
+ sub parse
+ {
+ my ($self, $page) = @_;
+ return if (($page =~ /^bad isbn/) & ($page =~ /^The/));
+ my $xml;
+ my $xs = XML::Simple->new;
+
+ if ($self->{parsingList})
+ {
+ if ($page =~ /feed>$/)
+ {
+ $xml = $xs->XMLin(
+ $page,
+ forceArray=>['author'],
+ KeyAttr => ['']
+ );
+ foreach my $ItemMusic ( @{$xml->{'entry'}}){
+ $self->{itemIdx}++;
+ $self->{itemsList}[ $self->{itemIdx} ]->{'url'} = $ItemMusic->{'id'};
+ $self->{itemsList}[ $self->{itemIdx} ]->{'title'} = $ItemMusic->{'title'};
+ foreach my $tmp_author (@{$ItemMusic->{'author'}}){
+ {($self->{itemsList}[ $self->{itemIdx} ]->{'artist'} ne '' ) and $self->{itemsList}[ $self->{itemIdx} ]->{'artist'}.=',';}
+ $self->{itemsList}[ $self->{itemIdx} ]->{'artist'}.=$tmp_author->{'name'};
+ }
+ }
+ }
+ else
+ {
+ $xml = $xs->XMLin(
+ $page,
+ forceArray=>['author'],
+ KeyAttr => ['']
+ );
+ $self->{itemIdx}++;
+ $self->{itemsList}[ $self->{itemIdx} ]->{'url'} = $xml->{'id'};
+ $self->{itemsList}[ $self->{itemIdx} ]->{'title'} = $xml->{'title'};
+ foreach my $tmp_author (@{$xml->{'author'}}){
+ $self->{itemsList}[ $self->{itemIdx} ]->{'artist'}.=$tmp_author->{'name'};
+ $self->{itemsList}[ $self->{itemIdx} ]->{'artist'}.=',';
+ }
+ }
+ }
+ else
+ {
+ $xml =$xs->XMLin($page,
+ ForceArray => [ 'author' ],
+ KeyAttr => {'db:tag'=>'name','link'=>'rel'});
+ foreach my $tmp_author (@{$xml->{'author'}}){
+ {($self->{curInfo}->{artist} ne '' ) and $self->{curInfo}->{artist}.=','; }
+ $self->{curInfo}->{artist}.=$tmp_author->{'name'};
+ }
+ $self->{curInfo}->{title}=$xml->{'title'};
+ $self->{curInfo}->{web}=$xml->{'link'}->{'alternate'}->{'href'};
+ foreach my $check(@{$xml->{'db:attribute'}}){
+ my $db_attr=$check->{'name'};
+ SWITCH: {
+ $db_attr eq 'publisher' and $self->{curInfo}->{producer}=$check->{'content'} ,last;
+ $db_attr eq 'pubdate' and $self->{curInfo}->{release}=$check->{'content'} ,last;
+ $db_attr eq 'ean' and $self->{curInfo}->{unique}=$check->{'content'} ,last;
+ $db_attr eq 'media' and $self->{curInfo}->{format}=$check->{'content'} ,last;
+ if ($db_attr eq 'tracks') { my @chains = split(/(?=\d+\.)/, $check->{'content'});
+ foreach my $track ( @chains ){
+ my $num=$track;my $name=$track;
+ $num=~ s/(^\d+).*/$1/;
+ $num=~ s/\n//g;
+ $name =~ s/^\d+\.(.*)/$1/;
+ $name=~s/\n//g;
+ $num=encode("utf8",$num);
+ $name=encode("utf8",$name);
+ $self->addTrack($name,0,$num);
+ }
+ last SWITCH;}
+ ;
+ }
+ }
+ $self->{curInfo}->{tracks} = $self->getTracks;
+ my $tmp_image=$xml->{'link'}->{'image'}->{'href'};
+ $tmp_image =~ s/spic/lpic/;
+ $self->{curInfo}->{cover}=$tmp_image;
+ }
+ }
+
+ sub new
+ {
+ my $proto = shift;
+ my $class = ref($proto) || $proto;
+ my $self = $class->SUPER::new();
+ bless ($self, $class);
+
+ $self->{hasField} = {
+ title => 1,
+ artist => 1,
+ publication => 0,
+ };
+ return $self;
+ }
+
+ sub preProcess
+ {
+ my ($self, $html) = @_;
+
+ return $html;
+ }
+
+ sub getSearchUrl
+ {
+ my ($self, $word) = @_;
+ return "http://api.douban.com/music/subjects?q=" .$word;
+ }
+
+ sub getItemUrl
+ {
+ my ($self, $url) = @_;
+ return $url;
+ }
+
+ sub changeUrl
+ {
+ my ($self, $url) = @_;
+ # Make sure the url is for the api, not the main movie page
+ return $self->getItemUrl($url);
+ }
+
+ sub getNumberPasses
+ {
+ return 1;
+ }
+
+ sub getName
+ {
+ return "豆瓣";
+ }
+
+
+ sub testURL
+ {
+ my ($self, $url) = @_;
+ $url =~ /[\?&]lid=([0-9]+)*/;
+ my $id = $1;
+ return ($id == $self->siteLanguageCode());
+ }
+
+ sub getReturnedFields
+ {
+ my $self = shift;
+
+ $self->{hasField} = {
+ title => 1,
+ artist => 1,
+ };
+ }
+
+ sub getAuthor
+ {
+ return 'BW';
+ }
+
+ sub getLang
+ {
+ return 'ZH';
+ }
+
+ sub isPreferred
+ {
+ return 1;
+ }
+
+ sub getSearchCharset
+ {
+ my $self = shift;
+
+ # Need urls to be double character encoded
+ return "UTF-8";
+ }
+ sub getSearchFieldsArray
+ {
+ return ['isbn', 'title'];
+ }
+
+ sub getCharset
+ {
+ my $self = shift;
+
+ return "UTF-8";
+ }
+
+ sub decodeEntitiesWanted
+ {
+ return 0;
+ }
+
+ sub siteLanguage
+ {
+ my $self = shift;
+
+ return 'ZH';
+ }
+
+}
+
+1;
diff --git a/lib/gcstar/GCPlugins/GCmusics/GCMusicBrainz.pm b/lib/gcstar/GCPlugins/GCmusics/GCMusicBrainz.pm
new file mode 100644
index 0000000..f91027f
--- /dev/null
+++ b/lib/gcstar/GCPlugins/GCmusics/GCMusicBrainz.pm
@@ -0,0 +1,309 @@
+package GCPlugins::GCmusics::GCMusicBrainz;
+
+###################################################
+#
+# Copyright 2005-2010 Christian Jodar
+#
+# This file is part of GCstar.
+#
+# GCstar is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GCstar is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCstar; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+#
+###################################################
+
+use strict;
+use utf8;
+
+use GCPlugins::GCmusics::GCmusicsCommon;
+
+{
+ package GCPlugins::GCmusics::GCPluginMusicBrainz;
+
+ use base 'GCPlugins::GCmusics::GCmusicsPluginsBase';
+ use XML::Simple;
+ use Locale::Country;
+
+ sub parse
+ {
+ my ($self, $page) = @_;
+ my $xml;
+ my $xs = XML::Simple->new;
+ if ($self->{parsingList})
+ {
+ $xml = $xs->XMLin($page,
+ ForceArray => ['release', 'event'],
+ KeyAttr => {'release' => ''});
+ my $release;
+ foreach $release ( @{ $xml->{'release-list'}->{release} } )
+ {
+ $self->{itemIdx}++;
+ $self->{itemsList}[$self->{itemIdx}]->{url} = 'http://musicbrainz.org/album/'.$release->{id}.'.html';
+ $self->{itemsList}[$self->{itemIdx}]->{title} = $release->{title};
+ $self->{itemsList}[$self->{itemIdx}]->{artist} = $release->{artist}->{name};
+
+ my $releaseDate='9999-12-31';
+ for my $releaseEvent (@{$release->{'release-event-list'}->{event}})
+ {
+ if ($releaseEvent->{date} lt $releaseDate)
+ {
+ # Find the earliest release event
+ $releaseDate = $releaseEvent->{date};
+ }
+ }
+
+ $self->{itemsList}[$self->{itemIdx}]->{release} = $releaseDate
+ if $releaseDate ne '9999-12-31';
+ }
+ }
+ else
+ {
+ $xml = $xs->XMLin($page,
+ ForceArray => ['track', 'event', 'relation', 'relation-list','tag'],
+ KeyAttr => {'track' => ''});
+ $self->{curInfo}->{title} = $xml->{release}->{title};
+ $self->{curInfo}->{web} = 'http://musicbrainz.org/release/'.$xml->{release}->{id}.'.html';
+ $self->{curInfo}->{artist} = $xml->{release}->{artist}->{name};
+ $self->{curInfo}->{ratingpress} = int($xml->{release}->{rating}->{content}) * 2;
+ $self->{curInfo}->{producer} = '';
+ $self->{curInfo}->{composer} = '';
+
+ # Step through the relations
+ for my $relation (@{$xml->{release}->{'relation-list'}})
+ {
+ if ($relation->{'target-type'} eq 'Artist')
+ {
+ # Artist type relations
+ for my $rel (@{$relation->{relation}})
+ {
+ # Search for producer or composer relations
+ $self->{curInfo}->{producer} .= $rel->{artist}->{name}.', '
+ if $rel->{type} eq 'Producer';
+ $self->{curInfo}->{composer} .= $rel->{artist}->{name}.', '
+ if $rel->{type} eq 'Composer';
+ }
+ }
+ elsif ($relation->{'target-type'} eq 'Url')
+ {
+ # Look for url type relations. Currently only jamendo works, but we should also cover the archive.org
+ # relations
+ for my $rel (@{$relation->{relation}})
+ {
+ # Alternate cover art sites
+ if (($rel->{target} =~ m/jamendo.com/) && (!$self->{curInfo}->{cover}))
+ {
+ # Cover art should be on jamendo
+ $rel->{target} =~ /\/([0-9]+)$/;
+ my $id = $1;
+ if ($self->{bigPics})
+ {
+ $self->{curInfo}->{cover} = "http://img.jamendo.com/albums/$id/covers/1.0.jpg";
+ }
+ else
+ {
+ $self->{curInfo}->{cover} = "http://img.jamendo.com/albums/$id/covers/1.200.jpg";
+ }
+ }
+ }
+ }
+ }
+
+ $self->{curInfo}->{producer} =~ s/, $//;
+ $self->{curInfo}->{composer} =~ s/, $//;
+
+ my $releaseDate;
+ my $releaseLabel;
+ my $releaseCountry;
+ my $releaseFormat;
+ my $releaseDateFromCompare='9999-12-12';
+ for my $releaseEvent (@{$xml->{release}->{'release-event-list'}->{event}})
+ {
+ my $releaseDateToCompare;
+ # Check if musicbrainz only has the year, if so, set things up so we'll prefer
+ # releases with the month & day over year-only releases
+ if (length($releaseEvent->{date}) == 4)
+ {
+ $releaseDateToCompare = $releaseEvent->{date}."-12-31";
+ }
+ else
+ {
+ $releaseDateToCompare = $releaseEvent->{date};
+ }
+
+ if (($releaseDateToCompare lt $releaseDateFromCompare) ||
+ (($releaseDateToCompare eq $releaseDateFromCompare) &&
+ (($releaseEvent->{country} eq 'US') || ($releaseEvent->{country} eq 'GB'))))
+ {
+ # Find the earliest release event, which has a month & day
+ # Big call, but we're probably more correct choosing a US or UK release if there's two
+ # release events with the same date, so prioritise them
+ $releaseDate = $releaseEvent->{date};
+ $releaseLabel = $releaseEvent->{label}->{name}
+ if $releaseEvent->{label};
+ $releaseCountry = code2country($releaseEvent->{country});
+ $releaseFormat = $releaseEvent->{format};
+ $releaseDateFromCompare = $releaseDateToCompare;
+ }
+ }
+
+ $self->{curInfo}->{release} = $releaseDate;
+ $self->{curInfo}->{label} = $releaseLabel;
+ $self->{curInfo}->{origin} = $releaseCountry;
+ $self->{curInfo}->{format} = $releaseFormat;
+
+ for my $track(@{$xml->{release}->{'track-list'}->{track}})
+ {
+ $self->addTrack($track->{title}, $track->{duration} / 1000);
+ }
+ $self->{curInfo}->{tracks} = $self->getTracks;
+ $self->{curInfo}->{running} = $self->getTotalTime;
+
+ for my $genre(@{$xml->{release}->{'tag-list'}->{tag}})
+ {
+ # Capitalize first letter of each word
+ $genre->{content} =~ s/\b(\w+)\b/ucfirst($1)/ge;
+ # Only add genres if they have more then 1 vote, strips out a lot of
+ # weird/wrong tags
+ push @{$self->{curInfo}->{genre}}, [$genre->{content}]
+ if ($genre->{count} > 1);
+ }
+
+ # If amazon artwork exists, use it
+ if (($xml->{release}->{asin}) && (!$self->{curInfo}->{cover}))
+ {
+ if ($self->{bigPics})
+ {
+ $self->{curInfo}->{cover} = 'http://images.amazon.com/images/P/'.$xml->{release}->{asin}.'.01.LZZZZZZZ.jpg'
+ }
+ else
+ {
+ $self->{curInfo}->{cover} = 'http://images.amazon.com/images/P/'.$xml->{release}->{asin}.'.01.MZZZZZZZ.jpg'
+ }
+ }
+ }
+ }
+
+ sub convertDate
+ {
+ my ($self, $date) = @_;
+ $date =~ /([0-9]{4})-?([0-9]{2})?-?([0-9]{2})?/;
+ return $3 .($3 ? '/' : '').$2.($2 ? '/' : '').$1;
+ }
+
+ sub new
+ {
+ my $proto = shift;
+ my $class = ref($proto) || $proto;
+ my $self = $class->SUPER::new();
+ bless ($self, $class);
+
+ $self->{hasField} = {
+ title => 1,
+ artist => 1,
+ release => 1,
+ tracks => 1
+ };
+
+ return $self;
+ }
+
+ sub preProcess
+ {
+ my ($self, $html) = @_;
+
+ return $html;
+ }
+
+ sub decodeEntitiesWanted
+ {
+ return 0;
+ }
+
+ sub getSearchUrl
+ {
+ my ($self, $word) = @_;
+
+ my $key = ($self->{searchField} eq 'artist') ? 'artist' : 'title';
+ return "http://musicbrainz.org/ws/1/release/?type=xml&$key=$word";
+ }
+
+ sub getItemUrl
+ {
+ my ($self, $url) = @_;
+ return $url if $url;
+ return "http://musicbrainz.org/";
+ }
+
+ sub changeUrl
+ {
+ my ($self, $url) = @_;
+ $url =~ s|http://musicbrainz.org/album/(.*?)\.html|http://musicbrainz.org/ws/1/release/$1?type=xml&inc=artist+tracks+release-events+artist-rels+url-rels+ratings+labels+tags|;
+ $url =~ s|http://musicbrainz.org/release/(.*?)\.html|http://musicbrainz.org/ws/1/release/$1?type=xml&inc=artist+tracks+release-events+artist-rels+url-rels+ratings+labels+tags|;
+ return $url;
+ }
+
+ sub getName
+ {
+ return 'MusicBrainz';
+ }
+
+ sub getAuthor
+ {
+ return 'Tian';
+ }
+
+ sub getLang
+ {
+ return 'EN';
+ }
+
+ sub getCharset
+ {
+ my $self = shift;
+
+ return "UTF-8";
+ }
+
+ sub getSearchCharset
+ {
+ my $self = shift;
+
+ # Need urls to be double character encoded
+ return "utf8";
+ }
+
+ sub convertCharset
+ {
+ my ($self, $value) = @_;
+ return $value;
+ }
+
+ sub getNotConverted
+ {
+ my $self = shift;
+ return [];
+ }
+
+ sub getSearchFieldsArray
+ {
+ return ['title', 'artist'];
+ }
+
+ sub isPreferred
+ {
+ # Return status of 2 means plugin is default regardless of user's language
+ return 2;
+ }
+}
+
+1;
diff --git a/lib/gcstar/GCPlugins/GCmusics/GCmusicsCommon.pm b/lib/gcstar/GCPlugins/GCmusics/GCmusicsCommon.pm
new file mode 100644
index 0000000..186662c
--- /dev/null
+++ b/lib/gcstar/GCPlugins/GCmusics/GCmusicsCommon.pm
@@ -0,0 +1,62 @@
+package GCPlugins::GCmusics::GCmusicsCommon;
+
+###################################################
+#
+# Copyright 2005-2010 Christian Jodar
+#
+# This file is part of GCstar.
+#
+# GCstar is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GCstar is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCstar; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+#
+###################################################
+
+use strict;
+
+use GCPlugins::GCPluginsBase;
+use GCExtract::GCExtractMusics;
+
+{
+ package GCPlugins::GCmusics::GCmusicsPluginsBase;
+
+ use base ('GCPluginParser', 'GCExtract::GCmusicsExtracter');
+ #use base ('GCPluginParser');
+ use HTML::Entities;
+
+ sub new
+ {
+ my $proto = shift;
+ my $class = ref($proto) || $proto;
+ my $self = $class->SUPER::new();
+ bless ($self, $class);
+ return $self;
+ }
+
+ sub getSearchFieldsArray
+ {
+ return ['title'];
+ }
+
+ sub loadUrl
+ {
+ my ($self, $url) = @_;
+
+ $self->resetTracks;
+ $self->SUPER::loadUrl($url);
+ return $self->{curInfo};
+ }
+
+}
+
+1; \ No newline at end of file