File Coverage

blib/lib/Lyrics/Fetcher/LyricWiki.pm
Criterion Covered Total %
statement 38 45 84.4
branch 8 12 66.6
condition 1 3 33.3
subroutine 6 6 100.0
pod 1 1 100.0
total 54 67 80.6


line stmt bran cond sub pod time code
1             package Lyrics::Fetcher::LyricWiki;
2              
3             # $Id$
4              
5 1     1   22657 use 5.005000;
  1         4  
  1         42  
6 1     1   6 use strict;
  1         3  
  1         32  
7 1     1   5 use warnings;
  1         5  
  1         23  
8 1     1   1475 use LWP::UserAgent;
  1         57896  
  1         29  
9 1     1   9 use Carp;
  1         2  
  1         483  
10              
11             our $VERSION = '0.10';
12              
13             # the HTTP User-Agent we'll send:
14             our $AGENT = "Perl/Lyrics::Fetcher::LyricWiki $VERSION";
15              
16              
17             =head1 NAME
18              
19             Lyrics::Fetcher::LyricWiki - Get song lyrics from www.LyricWiki.org
20              
21             =head1 SYNOPSIS
22              
23             use Lyrics::Fetcher;
24             print Lyrics::Fetcher->fetch("","","LyricWiki");
25              
26             # or, if you want to use this module directly without Lyrics::Fetcher's
27             # involvement:
28             use Lyrics::Fetcher::LyricWiki;
29             print Lyrics::Fetcher::LyricWiki->fetch('', '');
30              
31              
32             =head1 DESCRIPTION
33              
34             This module tries to get song lyrics from www.lyricwiki.org. It's designed to
35             be called by Lyrics::Fetcher, but can be used directly if you'd prefer.
36              
37              
38             =head1 FUNCTIONS
39              
40             =over 4
41              
42             =item I($artist, $song)
43              
44             Fetch lyrics for the requested song.
45              
46             =cut
47              
48             sub fetch {
49            
50 6     6 1 29338 my $self = shift;
51 6         17 my ( $artist, $song ) = @_;
52            
53             # reset the error var, change it if an error occurs.
54 6         16 $Lyrics::Fetcher::Error = 'OK';
55            
56 6 50 33     51 unless ($artist && $song) {
57 0         0 carp($Lyrics::Fetcher::Error =
58             'fetch() called without artist and song');
59 0         0 return;
60             }
61              
62 6         53 my $ua = LWP::UserAgent->new();
63 6         5241 $ua->agent($AGENT);
64              
65             # We'll fetch the edit page for the lyrics, as it provides nice clean text
66             # to parse out, without ringtone adverts etc which made the HTML
67             # unparseable.
68 6         992 my $url = join ':', map { s/\s+/_/; $_ } ($artist, $song);
  12         48  
  12         37  
69 6         43 my $resp = $ua->get("http://lyrics.wikia.com/index.php?action=edit"
70             . "&title=$url");
71            
72 6 50       3812510 if (!$resp->is_success) {
73 0 0       0 if ($resp->status_line =~ /404/) {
74             # Lyrics for this song not found (this doesn't seem to happen, we
75             # get a 200 anyway, handled below...)
76 0         0 $Lyrics::Fetcher::Error = 'Lyrics not found';
77 0         0 return;
78             } else {
79             # Something else wrong, so return HTTP error description
80 0         0 $Lyrics::Fetcher::Error = "Failed to fetch - " . $resp->status_line;
81 0         0 return;
82             }
83             }
84              
85             # Check it wasn't the "page doesn't exist yet" error page
86 6 100       113 if ($resp->content =~ /a link to a page that doesn't exist yet/) {
87 1         132 $Lyrics::Fetcher::Error = 'Lyrics not found';
88 1         251 return;
89             }
90            
91             # If it was a redirect, we should follow it; just call ourselves again.
92             # TODO: make sure we don't end up with infinite recursion if there's a
93             # redirect loop.
94 5 100       660 if (my($newartist, $newtitle) =
95             $resp->content =~ m{\#REDIRECT \s+ \[\[ ([^:]+) : ([^:]+) \]\] }xi)
96             {
97 1         247 return __PACKAGE__->fetch($newartist, $newtitle);
98             }
99              
100             # OK, parse the HTML:
101 4         2808 my $html = $resp->content;
102 4         542 my ($lyrics) = $html =~ m{
103             <lyrics?(?:>|>)
104             (.+?)
105             </lyrics?(?:>|>)
106             }xms;
107            
108 4 100       19 if ($lyrics) {
109             # Looks like we got something usable:
110 3         11 $Lyrics::Fetcher::Error = 'OK';
111 3         631 return $lyrics;
112             } else {
113 1         5 $Lyrics::Fetcher::Error = 'No lyrics parsed from page';
114 1         115 return;
115             }
116             }
117              
118              
119              
120             1;
121             __END__