File Coverage

blib/lib/LyricFinder/Lrclib.pm
Criterion Covered Total %
statement 20 85 23.5
branch 0 30 0.0
condition 0 33 0.0
subroutine 7 10 70.0
pod 2 2 100.0
total 29 160 18.1


line stmt bran cond sub pod time code
1             package LyricFinder::Lrclib;
2              
3 1     1   8 use strict;
  1         2  
  1         43  
4 1     1   7 use warnings;
  1         2  
  1         59  
5 1     1   6 use Carp;
  1         2  
  1         69  
6 1     1   7 use URI::Escape;
  1         2  
  1         71  
7 1     1   6 use parent 'LyricFinder::_Class';
  1         2  
  1         6  
8              
9             our $haveLyricsCache;
10             BEGIN {
11 1     1   119 $haveLyricsCache = 0;
12 1     1   112 eval "use LyricFinder::Cache; \$haveLyricsCache = 1; 1";
  1         8  
  1         3  
  1         27  
13             }
14              
15             my $Source = 'Lrclib';
16             my $Site = 'https://lrclib.net';
17             my $DEBUG = 0;
18              
19             sub new
20             {
21 0     0 1   my $class = shift;
22              
23 0           my $self = $class->SUPER::new($Source, @_);
24 0           @{$self->{'_fetchers'}} = ($Source);
  0            
25 0           unshift(@{$self->{'_fetchers'}}, 'Cache') if ($haveLyricsCache
26 0 0 0       && $self->{'-cache'} && $self->{'-cache'} !~ /^\>/);
      0        
27              
28 0           bless $self, $class; #BLESS IT!
29              
30 0           return $self;
31             }
32              
33             sub fetch {
34 0     0 1   my ($self, $artist_in, $song_in) = @_;
35              
36 0           $self->_debug("Lrclib::fetch($artist_in, $song_in)!");
37              
38 0 0         return '' unless ($self->_check_inputs($artist_in, $song_in));
39 0 0         return '' if ($self->{'Error'} ne 'Ok');
40              
41             # first, see if we've got it cached:
42 0           $self->_debug("i:haveCache=$haveLyricsCache= -cachedir=".$self->{'-cache'}."=");
43 0 0 0       if ($haveLyricsCache && $self->{'-cache'} && $self->{'-cache'} !~ /^\>/) {
      0        
44 0           my $cache = new LyricFinder::Cache(%{$self});
  0            
45 0 0         if ($cache) {
46 0           my $lyrics = $cache->fetch($artist_in, $song_in);
47 0 0 0       if (defined($lyrics) && $lyrics =~ /\w/) {
48 0           $self->_debug("..Got lyrics from cache.");
49 0           $self->{'Source'} = 'Cache';
50 0           $self->{'Site'} = $cache->site();
51 0           $self->{'Url'} = $cache->url();
52              
53 0           return $lyrics;
54             }
55             }
56             }
57              
58 0           $self->{'Site'} = $Site;
59              
60 0           (my $artist = $artist_in) =~ s#\s*\/.*$##; #ONLY USE 1ST ARTIST, IF MORE THAN ONE!
61 0           $artist = uri_escape_utf8($artist);
62 0           $artist =~ s/\%20/\+/g;
63 0           $artist =~ s/\%26/\&/g;
64 0           $artist =~ s/\%28/\(/g;
65 0           $artist =~ s/\%29/\)/g;
66 0           $artist =~ s/\%3D/\=/g;
67 0           my $song = $song_in;
68 0           $song = uri_escape_utf8($song);
69 0           $song =~ s/\%20/\+/g;
70 0           $song =~ s/\%26/\&/g;
71 0           $song =~ s/\%28/\(/g;
72 0           $song =~ s/\%29/\)/g;
73 0           $song =~ s/\%3D/\=/g;
74            
75              
76             # Their URLs look like e.g.:
77             # https://lrclib.net/api/get?artist_name=Borislav+Slavov&track_name=I+Want+to+Live
78 0           $self->{'Url'} = $Site . "/api/get?artist_name=${artist}&track_name=$song";
79              
80 0           my $lyrics = $self->_web_fetch($artist_in, $song_in);
81 0 0 0       if ($lyrics && $haveLyricsCache && $self->{'-cache'} && $self->{'-cache'} !~ /^\
      0        
      0        
82 0           $self->_debug("=== WILL CACHE LYRICS! ===");
83             # cache the fetched lyrics, if we can:
84 0           my $cache = new LyricFinder::Cache(%{$self});
  0            
85 0 0         $cache->save($artist_in, $song_in, $lyrics) if ($cache);
86             }
87 0           return $lyrics;
88             }
89              
90             # Internal use only functions:
91              
92             sub _parse {
93 0     0     my $self = shift;
94 0           my $html = shift;
95              
96             #NOTE: -synced: 'YES'(synced|plain), 'NO'(plain|bust), 'ONLY'(synced|bust), or 'OK'|''(plain|synced)!
97 0 0 0       my $sync = (defined($self->{'-synced'}) && $self->{'-synced'}) ? $self->{'-synced'} : 'No';
98 0 0         $sync = 'yES' unless ($sync =~ /^(?:y|n|only|ok)/i);
99 0 0         my $whichLyrics = ($sync !~ /^(?:NO|OK)/i) ? 'syncedLyrics' : 'plainLyrics';
100 0           $self->_debug("Lrclib::_parse()!");
101 0           my $lyrics;
102 0           $html =~ s/\\\"/\x02QUOTE\x02/gs; #PROTECT ESCAPED QUOTES FROM NEXT REGEX!:
103 0           for my $i (0,1) {
104 0 0         $lyrics = ($html =~ m/\,\"$whichLyrics\"\:\"([^\"]+)\"(?:\,\"|\})/s) ? $1 : undef;
105 0 0 0       if (defined($lyrics) && length($lyrics) > 10)
    0 0        
106             {
107 0           my $text = '';
108             # convert literal "\" followed by "r" or "n", etc. to "\r" or "\n" characters respectively:
109 0           eval "\$text = \"$lyrics\";";
110 0           $text =~ s/\x02QUOTE\x02/\"/gs;
111 0           return $self->_normalize_lyric_text($self->_html2text($text));
112             } elsif ($i || $sync =~ /^(?:NO|ONLY)/i) {
113 0           carp($self->{'Error'} = "e:$Source - Failed to identify lyrics on result page.");
114 0           return '';
115             } else {
116 0 0         $whichLyrics = ($sync =~ /^YES/i)
117             ? 'plainLyrics' : 'syncedLyrics'; #NO SYNCED LYRICS, TRY PLAIN-TEXT ONES:
118             }
119             }
120             } # end of sub parse
121              
122             1
123              
124             __END__