3 # LastFM - API to LastFM
15 my $username = LJ
::eurl
(shift);
17 return { error
=> "Missing last.fm credentials" }
18 unless $LJ::LAST_FM_API_KEY
&& $LJ::LAST_FM_API_URL
;
20 my $ua = LJ
::get_useragent
( role
=>'last_fm', timeout
=>$LJ::LAST_FM_TIMEOUT
);
21 my $url = "$LJ::LAST_FM_API_URL&api_key=$LJ::LAST_FM_API_KEY&user=$username";
22 my $response = $ua->get($url);
23 unless ($response->is_success) {
24 return { error
=> "Can't retrieve data from last.fm: " . $response->status_line };
27 my $content = $response->content();
30 my $in_current_play_tag = 0; # if we are inside track tag with nowplaying attribute
31 my $current_tag = ''; # a name of a current tag
35 my $error_message = '';
37 # now plaing song attributes
43 my $handler_start = sub {
48 # catch tag 'track' with 'nowplaying=true'
49 if ($element eq "track"
50 && exists($attr{'nowplaying'}) && $attr{'nowplaying'} eq "true") {
51 $in_current_play_tag = 1;
55 $error_code = $attr{'code'}
56 if ($element eq "error" && exists($attr{'code'}));
58 # for all other tags just remember name
59 $current_tag = $element;
63 my $handler_end = sub {
68 # if we leave 'track' tag
69 if ($element eq "track") {
70 $in_current_play_tag = 0;
73 # forget a name of a current tag
78 my $handler_char = sub {
83 if ($current_tag eq 'error') {
84 $error_message = $string;
88 # pay attention only on current playing tracks
89 return unless($in_current_play_tag);
91 # remember song attributes
92 if ($current_tag eq "artist") {
97 if ($current_tag eq "name") {
103 my $parser = new XML
::Parser
(Handlers
=> {
104 Start
=> $handler_start,
106 Char
=> $handler_char,
108 eval { $parser->parse($content); };
109 if ($@
) { # invalid xml
110 return { error
=> "Can't retrieve data from last.fm: wrong response from server" };
113 if ($error_message) {
114 return { error
=> "Can't retrieve data from last.fm: $error_message" };
117 # This prevents worker from die when it catch unicode characters in last.fm title.
118 # (turn off UTF-8 flags from text strings)
119 ($artist, $name) = map { Encode
::is_utf8
($_) ? Encode
::encode
("utf8", $_) : $_ } ($artist, $name);
121 if ($artist || $name) {
122 my $track = HTML
::Entities
::decode
(
123 ($artist ?
$artist : 'Unknown artist') . ' - ' . ($name ?
$name : 'Unknown track' ) . $LJ::LAST_FM_SIGN_TEXT
125 return { data
=> $track };
127 return { error
=> 'No "now listening" track in last.fm data' };
131 sub format_current_music_string
{
134 if ($string =~ $LJ::LAST_FM_SIGN_RE
) {
136 my ($artist, $track) = $string =~ /^\s*(.*)\s{1}-\s{1}(.*)$LJ::LAST_FM_SIGN_RE/;
138 if ($artist && $track) {
139 $string = $artist ne 'Unknown artist' ?
qq{<a href
='$LJ::LAST_FM_ARTIST_URL'>$artist</a
>} : $artist;
141 $string .= $track ne 'Unknown track' ?
qq{<a href
='$LJ::LAST_FM_TRACK_URL'>$track</a
>} : $track;
143 $string .= " $LJ::LAST_FM_SIGN_TEXT";
145 $string =~ s/%artist%/$artist/g;
146 $artist = LJ
::eurl
($artist);
147 $string =~ s/%artist_esc%/$artist/g;
149 $string =~ s/%track%/$track/g;
150 $track = LJ
::eurl
($track);
151 $string =~ s/%track_esc%/$track/g;
154 $string =~ s!Last\.fm!$LJ::LAST_FM_SIGN_URL!;