File Coverage

lib/Net/GNUDBSearch.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


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   42927 use warnings;
  2         5  
  2         57  
25 2     2   10 use strict;
  2         5  
  2         52  
26 2     2   8 use Carp;
  2         4  
  2         478  
27 2     2   2920 use WWW::Mechanize;
  0            
  0            
28             use URI::Encode;
29             use Data::Dumper;
30             use XML::Simple;
31             use Net::GNUDBSearch::Cd;
32             our $VERSION = "1.0";
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             my $class = shift;
46             my $self = {
47             '__baseUrl' => "http://www.gnudb.org",
48             '__action' => undef
49             };
50             bless $self, $class;
51             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             my($self, $query) = @_;
66             my @results = ();
67             my $class = ref($self);
68             if($query){
69             $self->__setAction("artist");
70             my $url = $self->__getSearchUrl();
71             my $encoded = $class->__encode($query);
72             $url .= "/" . $encoded; #add search terms
73             my $mech = WWW::Mechanize->new();
74             print "Getting url: $url\n";
75             my $res = $mech->get($url);
76             if($mech->success()){
77             my $content = $mech->content();
78             if($content =~ m/

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

(.+
)/s){

79             my $results = $1;
80             my $xml = $class->__htmlToXml($results);
81             my $xs = XML::Simple->new();
82             my $ref = $xs->XMLin($xml);
83             foreach my $match (@{$ref->{'match'}}){
84             #print Dumper $match;
85             my $a = $match->{'a'}[0];
86             #get the album and artist
87             my $name = $a->{'b'};
88             my($cdArtist, $cdAlbum) = split(" / ", $name);
89             $cdArtist =~ s/^\s+//g; #remove leading whitespace
90             $cdArtist =~ s/\s+$//g; #remove trailing whitespace
91             $cdAlbum =~ s/^\s+//g; #remove leading whitespace
92             $cdAlbum =~ s/\s+$//g; #remove trailing whitespace
93             #get data for the track lookup
94             $a = $match->{'a'}[1];
95             if($a->{'content'} =~ m/^Discid: (\w+) \/ ([a-f0-9]+)$/){
96             my $cdGenre = $1;
97             my $cdId = $2;
98             my $objClass = $class . "::Cd"; #avoid hard coding classes
99             my $config = {
100             "id" => $cdId,
101             "artist" => $cdArtist,
102             "album" => $cdAlbum,
103             "genre" => $cdGenre
104             };
105             my $cdObj = $objClass->new($config);
106             push(@results, $cdObj); #save it in the results
107             }
108             else{
109             confess("Invalid GNUDB info");
110             }
111             }
112             }
113             }
114             else{
115             confess("Problem with search, code: " . $mech->status());
116             }
117             }
118             else{
119             confess("No artist given");
120             }
121             return \@results;
122             }
123             #########################################################
124             sub __getSearchUrl{
125             my$self = shift;
126             my $url = undef;
127             if($self->__getAction()){
128             $url = $self->__getBaseUrl() . "/" . $self->__getAction();
129             }
130             else{
131             confess("No action set");
132             }
133             return $url;
134             }
135             #########################################################
136             sub __getBaseUrl{
137             my $self = shift;
138             return $self->{'__baseUrl'};
139             }
140             #########################################################
141             sub __setAction{
142             my($self, $action) = @_;
143             $self->{'__action'} = $action;
144             return 1;
145             }
146             #########################################################
147             sub __getAction{
148             my $self = shift;
149             return $self->{'__action'};
150             }
151             #########################################################
152             sub __htmlToXml{
153             my($class, $html) = @_;
154             my $xml = $html;
155             $xml =~ s/
//g;
156             $xml =~ s/( 157             $xml =~ s/
/<\/match>/g;
158             $xml =~ s/ target=_blank//g;
159             $xml =~ s/&/&/g;
160             $xml = "" . $xml . "\n";
161             return $xml;
162             }
163             #########################################################
164             sub __encode{
165             my($class, $query) = @_;
166             my $uri = URI::Encode->new();
167             my $encoded = $uri->encode($query);
168             $encoded =~ s/%20/\+/g; #the gnudb search does a redirect if + signs are not used
169             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;