File Coverage

lib/Net/GNUDBSearch.pm
Criterion Covered Total %
statement 90 94 95.7
branch 5 10 50.0
condition n/a
subroutine 16 16 100.0
pod 2 2 100.0
total 113 122 92.6


line stmt bran cond sub pod time code
1             package Net::GNUDBSearch;
2              
3             =pod
4              
5             =head1 NAME
6              
7             Net::GNUDBSearch - Search interface to GNUDB database
8              
9             =head1 SYNOPSIS
10              
11             use Net::GNUDBSearch;
12             my $search = Net::GNUDBSearch->new();
13             my $results = $search->byArtist("The Prodigy");
14              
15             =head1 DESCRIPTION
16              
17             Net::GNUDBSearch is an interface to the website www.gnudb.org online free CD information database. Based on Net::CDDBSearch by Vitaliy Babiy. This module
18             allows you to search by artist and retrive a list of albums found then get their tracks.
19              
20             =head1 METHODS
21              
22             =cut
23              
24 2     2   14857 use warnings;
  2         2  
  2         52  
25 2     2   6 use strict;
  2         1  
  2         30  
26 2     2   5 use Carp;
  2         1  
  2         97  
27 2     2   1265 use WWW::Mechanize;
  2         195249  
  2         68  
28 2     2   904 use URI::Encode;
  2         1838  
  2         82  
29 2     2   1340 use Data::Dumper;
  2         8439  
  2         95  
30 2     2   1317 use XML::Simple;
  2         11768  
  2         11  
31 2     2   415 use Net::GNUDBSearch::Cd;
  2         3  
  2         1203  
32             our $VERSION = "1.01";
33             #########################################################
34              
35             =head2 new()
36              
37             my $gnudb = Net::GNUDBSearch->new();
38              
39             Constructor, returns a new instance of the search object ready for use.
40              
41             =cut
42              
43             #########################################################
44             sub new{
45 1     1 1 521 my $class = shift;
46 1         5 my $self = {
47             '__baseUrl' => "http://www.gnudb.org",
48             '__action' => undef
49             };
50 1         3 bless $self, $class;
51 1         2 return $self;
52             }
53             ##########################################################
54              
55             =head2 byArtist($query)
56              
57             my $albums = $gnudb->byArtist("The Prodigy");
58              
59             Returns an array reference of L objects containing CD's found from the artist name given.
60              
61             =cut
62              
63             ##########################################################
64             sub byArtist{
65 1     1 1 571 my($self, $query) = @_;
66 1         3 my @results = ();
67 1         2 my $class = ref($self);
68 1 50       3 if($query){
69 1         3 $self->__setAction("artist");
70 1         3 my $url = $self->__getSearchUrl();
71 1         4 my $encoded = $class->__encode($query);
72 1         3 $url .= "/" . $encoded; #add search terms
73 1         7 my $mech = WWW::Mechanize->new();
74 1         10465 print "Getting url: $url\n";
75 1         7 my $res = $mech->get($url);
76 1 50       242987 if($mech->success()){
77 1         24 my $content = $mech->content();
78 1 50       340 if($content =~ m/

Search Results, \d+ albums found:<\/h2>.+

(.+
)/s){

79 1         7 my $results = $1;
80 1         7 my $xml = $class->__htmlToXml($results);
81 1         12 my $xs = XML::Simple->new();
82 1         68 my $ref = $xs->XMLin($xml);
83 1         173568 foreach my $match (@{$ref->{'match'}}){
  1         4  
84             #print Dumper $match;
85 50         51 my $a = $match->{'a'}[0];
86             #get the album and artist
87 50         35 my $name = $a->{'b'};
88 50         103 my($cdArtist, $cdAlbum) = split(" / ", $name);
89 50         57 $cdArtist =~ s/^\s+//g; #remove leading whitespace
90 50         63 $cdArtist =~ s/\s+$//g; #remove trailing whitespace
91 50         53 $cdAlbum =~ s/^\s+//g; #remove leading whitespace
92 50         66 $cdAlbum =~ s/\s+$//g; #remove trailing whitespace
93             #get data for the track lookup
94 50         42 $a = $match->{'a'}[1];
95 50 50       111 if($a->{'content'} =~ m/^Discid: (\w+) \/ ([a-f0-9]+)$/){
96 50         52 my $cdGenre = $1;
97 50         41 my $cdId = $2;
98 50         42 my $objClass = $class . "::Cd"; #avoid hard coding classes
99 50         84 my $config = {
100             "id" => $cdId,
101             "artist" => $cdArtist,
102             "album" => $cdAlbum,
103             "genre" => $cdGenre
104             };
105 50         76 my $cdObj = $objClass->new($config);
106 50         164 push(@results, $cdObj); #save it in the results
107             }
108             else{
109 0         0 confess("Invalid GNUDB info");
110             }
111             }
112             }
113             }
114             else{
115 0         0 confess("Problem with search, code: " . $mech->status());
116             }
117             }
118             else{
119 0         0 confess("No artist given");
120             }
121 1         126 return \@results;
122             }
123             #########################################################
124             sub __getSearchUrl{
125 1     1   1 my$self = shift;
126 1         1 my $url = undef;
127 1 50       3 if($self->__getAction()){
128 1         2 $url = $self->__getBaseUrl() . "/" . $self->__getAction();
129             }
130             else{
131 0         0 confess("No action set");
132             }
133 1         2 return $url;
134             }
135             #########################################################
136             sub __getBaseUrl{
137 1     1   2 my $self = shift;
138 1         3 return $self->{'__baseUrl'};
139             }
140             #########################################################
141             sub __setAction{
142 1     1   2 my($self, $action) = @_;
143 1         4 $self->{'__action'} = $action;
144 1         1 return 1;
145             }
146             #########################################################
147             sub __getAction{
148 2     2   3 my $self = shift;
149 2         4 return $self->{'__action'};
150             }
151             #########################################################
152             sub __htmlToXml{
153 1     1   3 my($class, $html) = @_;
154 1         2 my $xml = $html;
155 1         128 $xml =~ s/
//g;
156 1         179 $xml =~ s/( 157 1         118 $xml =~ s/
/<\/match>/g;
158 1         92 $xml =~ s/ target=_blank//g;
159 1         96 $xml =~ s/&/&/g;
160 1         29 $xml = "" . $xml . "\n";
161 1         14 return $xml;
162             }
163             #########################################################
164             sub __encode{
165 1     1   1 my($class, $query) = @_;
166 1         10 my $uri = URI::Encode->new();
167 1         648 my $encoded = $uri->encode($query);
168 1         72 $encoded =~ s/%20/\+/g; #the gnudb search does a redirect if + signs are not used
169 1         45 return $encoded;
170             }
171             #########################################################
172              
173             =pod
174              
175             =head1 Notes
176              
177             Only retrieves the first page of results as that should be good enough to find data.
178              
179             =head1 Author
180              
181             MacGyveR
182              
183             Development questions, bug reports, and patches are welcome to the above address.
184              
185             =head1 Thanks
186              
187             Vitaliy Babiy for module Net::CDDBSearch
188              
189             =head1 Copyright
190              
191             Copyright (c) 2012 MacGyveR. All rights reserved.
192              
193             This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
194              
195             =head1 See Also
196              
197             Net::CDDBSearch
198              
199             =cut
200              
201             #########################################################
202             return 1;