diff -rupN orig/lib/Plugins/SqueezeScrobbler/LastFMAsyncHTTP.pm patched/lib/Plugins/SqueezeScrobbler/LastFMAsyncHTTP.pm --- orig/lib/Plugins/SqueezeScrobbler/LastFMAsyncHTTP.pm 1970-01-01 01:00:00.000000000 +0100 +++ patched/lib/Plugins/SqueezeScrobbler/LastFMAsyncHTTP.pm 2013-01-06 11:10:57.000000000 +0100 @@ -0,0 +1,55 @@ +package Plugins::SqueezeScrobbler::LastFMAsyncHTTP; + +# Jan 6 2013, Frederik Orellana + +use strict; + +use base qw(Slim::Networking::SimpleAsyncHTTP); + +use Digest::MD5 qw(md5_hex); +use Data::Dumper; +use URI::Escape; + +my $log = undef;# logger('plugin.lastfm'); +if (!$log) { + $log = Slim::Utils::Log->addLogCategory({ + 'category' => 'plugin.lastfm', + 'defaultLevel' => 'DEBUG', + 'description' => "none", + }); +} + +sub post_lastfm_signed { + + my $self = shift; + my $url = shift; + my %args = @_; + + my $params = $self->_params; + + $args{api_key} = $params->{api_key}; + + my $to_hash = ''; + foreach my $key ( sort keys %args ) { + my $value = $args{$key}; + $to_hash .= $key . $value; + } + $to_hash .= $params->{api_secret}; + $args{api_sig} = md5_hex($to_hash); + + my $content = escape_hash(%args); + $log->info("ARGS: $self, $url, $content"); + $log->info(Dumper(\%args)); + + $self->_createHTTPRequest(POST => ($url, ,"user-agent" => "myapp/1.0", + "Content-type" => "application/x-www-form-urlencoded", $content)); +} + +sub escape_hash { + my %hash = @_; + my @pairs; + for my $key (keys %hash) { + push @pairs, join "=", map { uri_escape($_) } $key, $hash{$key}; + } + return join "&", @pairs; +} diff -rupN orig/lib/Plugins/SqueezeScrobbler/LastFM.pm patched/lib/Plugins/SqueezeScrobbler/LastFM.pm --- orig/lib/Plugins/SqueezeScrobbler/LastFM.pm 2011-02-15 21:26:34.000000000 +0100 +++ patched/lib/Plugins/SqueezeScrobbler/LastFM.pm 2013-01-06 16:55:49.000000000 +0100 @@ -21,6 +21,7 @@ package Plugins::SqueezeScrobbler::LastFM; use base qw(Slim::Plugin::Base); use Plugins::SqueezeScrobbler::Settings; +use Plugins::SqueezeScrobbler::LastFMAsyncHTTP; use Slim::Utils::Strings qw(string); use Slim::Utils::Prefs; @@ -32,12 +33,20 @@ use Class::Struct; use Digest::MD5 qw(md5_hex); use File::Spec::Functions qw(:ALL); use Data::Dumper; +use XML::Simple; +use Encode; +use LWP::Simple; + #use warnings; #use strict; $Plugins::SqueezeScrobbler::LastFM::CVS_VERSION = substr(q$Revision: 1.26 $,10); my $prefs = preferences('plugin.slimscrobbler'); my $prefsServer = preferences('server'); +## TODO: move into preferences. +my $api_key = "XXXX"; +my $api_secret = "XXXX"; +my $lastfm_root = 'https://ws.audioscrobbler.com/2.0/'; #loggers don't seem to persist correctly yet my $log = undef;# logger('plugin.lastfm'); @@ -55,8 +64,6 @@ my @lastfm_subscriber_options = qw/neigh my $lastfm_timeout = 60; # how long between scheduled updates my $lastfm_command_timeout = 10; # how long to wait for an update after sending a command -#my $lastfm_server_address = 'http://wsdev.audioscrobbler.com'; -my $lastfm_server_address = 'http://ws.audioscrobbler.com'; my %players; my $cli_next; @@ -159,97 +166,98 @@ sub handleWebIndex { $params->{refresh} = $lastfm_timeout; # without a player, don't do anything - if ($client = Slim::Player::Client::getClient($params->{player})) { - my $macaddress = getPlayerKey($client); + $client = Slim::Player::Client::getClient($params->{player}) || + return Slim::Web::HTTP::filltemplatefile('plugins/LastFM/index.html', $params); - #web page status is keyed off this field - $params->{lastfmplaying} = 0; + my $macaddress = getPlayerKey($client); - #similar artists search - if (defined $params->{lastfms1}) { - $log->debug($params->{lastfms1}."\n"); - $params->{lastfmp1} = "artist/$params->{lastfms1}/similarartists"; - #LastFM have disabled this - #if (my $station = similarArtistsSearch($params->{lastfms1})) { - # $params->{lastfmp1} = $station; - #} - } - - if (defined $params->{lastfmp1}) { - if ( $params->{lastfm} eq 'delete' ) { - deleteStation($params->{lastfmp1}); - } elsif ( $params->{lastfm} eq 'addlfm' or defined $params->{"addlfm.x"}) { - addStation($params->{lastfmp1}); - } elsif ($params->{lastfm} eq 'playlfm' or defined $params->{"playlfm.x"}) { - playLastFM($client,$params->{lastfmp1}); - $params->{refresh} = ($lastfm_timeout/4); - } elsif (!$params->{lastfm}) { - #user hit enter in ie! - #firefox submits add on enter - addStation($params->{lastfmp1}); - } + #web page status is keyed off this field + $params->{lastfmplaying} = 0; + + #similar artists search + if (defined $params->{lastfms1}) { + $log->debug($params->{lastfms1}."\n"); + $params->{lastfmp1} = "artist/$params->{lastfms1}/similarartists"; + #LastFM have disabled this + #if (my $station = similarArtistsSearch($params->{lastfms1})) { + # $params->{lastfmp1} = $station; + #} + } + + if (defined $params->{lastfmp1}) { + if ( $params->{lastfm} eq 'delete' ) { + deleteStation($params->{lastfmp1}); + } elsif ( $params->{lastfm} eq 'addlfm' or defined $params->{"addlfm.x"}) { + addStation($params->{lastfmp1}); + } elsif ($params->{lastfm} eq 'playlfm' or defined $params->{"playlfm.x"}) { + playLastFM($client,$params->{lastfmp1}); + $params->{refresh} = ($lastfm_timeout/4); + } elsif (!$params->{lastfm}) { + #user hit enter in ie! + #firefox submits add on enter + addStation($params->{lastfmp1}); } + } - if (getLastFMStatus($client)) { - #web page status is keyed off this field - $params->{lastfmplaying} = 1; + if (getLastFMStatus($client)) { + #web page status is keyed off this field + $params->{lastfmplaying} = 1; - if (defined $params->{lastfm}) { - if ( $params->{lastfm} eq 'command') { - commandLastFM($client,$params->{lastfmp1}); - } + if (defined $params->{lastfm}) { + if ( $params->{lastfm} eq 'command') { + commandLastFM($client,$params->{lastfmp1}); } + } - # show any track data we may have - my %data = %{$players{$macaddress}->datahash}; - @$params{keys %data} = values %data; + # show any track data we may have + my %data = %{$players{$macaddress}->datahash}; + @$params{keys %data} = values %data; - $params->{station} = $players{$macaddress}->station; - $params->{station_url} = $players{$macaddress}->station_url; + $params->{station} = $players{$macaddress}->station; + $params->{station_url} = $players{$macaddress}->station_url; - #possible commands - $params->{commands} = $players{$macaddress}->commands; - $params->{rtp} = $players{$macaddress}->rtp; - $params->{disco} = $players{$macaddress}->disco; + #possible commands + $params->{commands} = $players{$macaddress}->commands; + $params->{rtp} = $players{$macaddress}->rtp; + $params->{disco} = $players{$macaddress}->disco; - #add the selected album art size - $params->{'track'} = getTrackData($client); - } + #add the selected album art size + $params->{'track'} = getTrackData($client); + } - #status flag, if any - if (my $status = $players{$macaddress}->status) { - $params->{status} = $status; - # calculate refresh interval - $params->{refresh} = ($lastfm_timeout / 4) if ($status eq 'STARTING'); - } + #status flag, if any + if (my $status = $players{$macaddress}->status) { + $params->{status} = $status; + # calculate refresh interval + $params->{refresh} = ($lastfm_timeout / 4) if ($status eq 'STARTING'); + } - #stations + #stations - #split out the aliases - if ($params->{lastfm} eq 'browse' or defined $params->{"browse.x"}) { - @stationList = getLastFMData($client,$params->{lastfmp1}); - } else { - @stationList = genStationNames($client,undef); - } - my @stationShortNameList; - my @stationRealNameList; - for ( @stationList ) { - my ($nickname) = m/^(.*?);/; - $nickname = $_ unless $nickname; - push @stationShortNameList, $nickname; - push @stationRealNameList, $_; - } - $params->{stationnames} = \@stationShortNameList; - $params->{stationlinks} = \@stationRealNameList; + #split out the aliases + if ($params->{lastfm} eq 'browse' or defined $params->{"browse.x"}) { + @stationList = getLastFMData($client,$params->{lastfmp1}); + } else { + @stationList = genStationNames($client,undef,1); + } + my @stationShortNameList; + my @stationRealNameList; + for ( @stationList ) { + my ($nickname) = m/^(.*?);/; + $nickname = $_ unless $nickname; + push @stationShortNameList, $nickname; + push @stationRealNameList, $_; + } + $params->{stationnames} = \@stationShortNameList; + $params->{stationlinks} = \@stationRealNameList; - # add the recently played history - $params->{history} = Plugins::SqueezeScrobbler::Scrobbler::getRecentlyPlayed($client); + # add the recently played history + $params->{history} = Plugins::SqueezeScrobbler::Scrobbler::getRecentlyPlayed($client); + + # add the user' name + my ($user) = Plugins::SqueezeScrobbler::Settings::getUserIDPasswordForClient($client); + $params->{user} = $user; - # add the user' name - my ($user) = Plugins::SqueezeScrobbler::Settings::getUserIDPasswordForClient($client); - $params->{user} = $user; - - } $log->info("web page refresh: ".$params->{refresh}."\n"); return Slim::Web::HTTP::filltemplatefile('plugins/LastFM/index.html', $params); } @@ -565,8 +573,9 @@ sub getLastFMStatus { my $player = getPlayer(getPlayerKey($client)); #get session from LastFM - initializes subscriber flag correctly getLastFMSession($client) unless ($player->session ne 'UNSET'); - - return (scalar keys %{getTrackData($client)}); + $trackData = getTrackData($client); + $log->info(Dumper($trackData)); + return (scalar keys %{$trackData}); } sub commandLastFM { @@ -596,10 +605,9 @@ sub commandLastFM { $players{$playername}->rtp(1); } } else { - my $page = 'control.php'; #love,ban showMessage($client, $client->string('PLUGIN_LASTFM_MODULE_NAME'), "Sending $command to Last.FM"); - postXMLToLastFM($client,{command => $command} ); + trackExe($client, $command); if ($command eq 'ban') { #skip current track $client->execute(['playlist','jump', "+1"]); @@ -611,87 +619,88 @@ sub getTrackData{ my $client = shift; return unless $client; my $song = $client->playingSong(); #or streamingSong() ? + $log->info(Dumper($song)); return unless $song; my $dat = $song->pluginData(); $log->info(Dumper($dat)); return $dat; } -sub postXMLToLastFM { +sub trackExe { my $client = shift; - my $args = shift; + my $command = shift; my $playername = getPlayerKey($client); my $player = $players{$playername}; - - - my ($user, $password_md5) = Plugins::SqueezeScrobbler::Settings::getUserIDPasswordForClient($client); my $track = getTrackData($client); - return unless ($user and $password_md5 and $track); - my $challenge = time(); - my $lastfm_url = "http://ws.audioscrobbler.com/1.0/rw/xmlrpc.php"; - - my $post = ""; - $post .= "".$args->{command}."Track\n"; - $post .= "".Slim::Utils::Misc::escape($user)."\n"; - $post .= "".$challenge."\n"; - $post .= "".md5_hex($password_md5.$challenge)."\n"; - $post .= "".XMLencode($track->{creator})."\n"; - $post .= "".XMLencode($track->{title})."\n"; - $post .= ""; - - $log->warn("Sending $lastfm_url\?$post\n"); - my $http = Slim::Networking::SimpleAsyncHTTP->new( - \&gotLastFMControl, - \&failedLastFMUpdate, - { client => $client}, + my $params = { + 'client' => $client, + 'api_key' => $api_key, + 'api_secret' => $api_secret + }; + + my %args; + %args = ( + 'sk' => $player->session, + 'method' => "track.".$command, + 'artist' => Encode::encode("UTF-8", $track->{creator}), + 'track' => Encode::encode("UTF-8", $track->{title}) ); - $http->post("$lastfm_url", - 'Content-Type' => 'text/xml', - $post); + + my $http = Plugins::SqueezeScrobbler::LastFMAsyncHTTP->new( + \&gotLastFMControl, + \&failedLastFMUpdate, + $params + ); + $http->post_lastfm_signed($lastfm_root, %args); } -sub postToLastFM { +sub postStationToLastFM { my $client = shift; my $params = shift; my $args = shift; my $playername = getPlayerKey($client); my ($page, $session, $callback); + + getLastFMSession($client) unless ($players{$playername}->session ne 'UNSET'); + if ( isPlaylistURL( $args->{'url'} ) ) { - $page = '../1.0/webclient/getresourceplaylist.php'; - $session = 'sk'; $args->{'desktop'} = '1'; - $callback = \&gotLastFMPlaylist; + ## Cannot find a 2.0 API replacement for this. + my $lastfm_url = $players{$playername}->base_url."/../1.0/webclient/getresourceplaylist.php"; + my $post = "sk=".$players{$playername}->session; + for (keys %{$args}) { + $post .= "\&$_=".Slim::Utils::Misc::escape($args->{$_}); + } + $params->{client} = $client; + $log->warn("Sending $lastfm_url\?$post\n"); + my $http = Slim::Networking::SimpleAsyncHTTP->new( + \&gotLastFMPlaylist, + \&failedLastFMUpdate, + $params, + ); + $http->get("$lastfm_url\?$post"); } else { - $callback = \&gotLastFMControl; - $page = 'adjust.php'; - $session = 'session'; - $params->{'url'} = $args->{'url'}; - } - - getLastFMSession($client) unless ($players{$playername}->session ne 'UNSET'); - my $lastfm_url = $players{$playername}->base_url."/$page"; - my $post = "session=".$players{$playername}->session; - for (keys %{$args}) { - $post .= "\&$_=".Slim::Utils::Misc::escape($args->{$_}); + $args->{'sk'} = $players{$playername}->session; + $args->{'method'} = "radio.tune"; + $params->{client} = $client; + $params->{api_key} = $api_key; + $params->{api_secret} = $api_secret; + my $http = Plugins::SqueezeScrobbler::LastFMAsyncHTTP->new( + \&gotLastFMControl, + \&failedLastFMUpdate, + $params + ); + $http->post_lastfm_signed($lastfm_root, %{$args}); } - $params->{client} = $client; - - $log->warn("Sending $lastfm_url\?$post\n"); - my $http = Slim::Networking::SimpleAsyncHTTP->new( - $callback, - \&failedLastFMUpdate, - $params, - ); - $http->get("$lastfm_url\?$post"); } sub gotLastFMControl { my $http = shift; my $lastFMData = $http->content(); my $client = $http->params('client'); - my $url = $http->params('url'); + my $url = $http->params('station'); my $playername = getPlayerKey($client); $http->close(); $log->info("$lastFMData\n"); @@ -701,17 +710,17 @@ sub gotLastFMControl { } return 0; } else { - my %data = parseLastFMData($lastFMData); + my $data = parseLastFMData($lastFMData); - if ($data{url}) { + if ($data->{station}->{url}) { $log->info("Setting station_url to: $url\n"); #reformat station url #$data{url} =~ s/http:\/\/www.last.fm\/listen\//lastfm:\/\//; $players{$playername}->station_url($url); getLastFMPlaylist($client,$http->params()); } - if ($data{stationname}){ - setStationName($players{$playername},$data{stationname}); + if ($data->{station}->{name}){ + setStationName($players{$playername}, $data->{station}->{name}); } } @@ -722,32 +731,30 @@ sub getLastFMSession { my $force = shift; my $playername = getPlayerKey($client); my $player = getPlayer($playername); - - my ($lastfm_user, $lastfm_password_md5sum) = Plugins::SqueezeScrobbler::Settings::getUserIDPasswordForClient($client); - - return 0 unless (defined $lastfm_user and defined $lastfm_password_md5sum); - - return 1 if ($player->session ne 'UNSET' and !$force); + my ($lastfm_user, $lastfm_password) = Plugins::SqueezeScrobbler::Settings::getUserIDPasswordForClient($client); - my $lastfm_url = "$lastfm_server_address/radio/handshake.php?version=$version&platform=slim&username=$lastfm_user&passwordmd5=$lastfm_password_md5sum"; - $log->warn("Connecting to: $lastfm_url\n"); + return 0 unless (defined $lastfm_user and defined $lastfm_password); + return 1 if ($player->session ne 'UNSET' and !$force); $player->status("STARTING"); - my $params; - $params->{client} = $client; - my $http = Slim::Networking::SimpleAsyncHTTP->new( + my $params = { + 'client' => $client, + 'api_key' => $api_key, + 'api_secret' => $api_secret + }; + my $http = Plugins::SqueezeScrobbler::LastFMAsyncHTTP->new( \&gotSession, \&failedSession, - $params, + $params ); - $http->get("$lastfm_url"); - + my %args; + %args = ( + 'method' => "auth.getMobileSession", + 'username' => $lastfm_user, + 'password' => $lastfm_password + ); + $http->post_lastfm_signed($lastfm_root, %args); return 1; - # we don't use async here, because when we exit, I want to be sure the new session url has been populated - #my $http = Slim::Player::Protocols::HTTP->new({ - # 'url' => $lastfm_url, - # 'create' => 0, - #}); } sub gotSession{ @@ -756,19 +763,20 @@ sub gotSession{ if (defined $http) { my $lastFMData = $http->content(); my $client = $http->params('client'); + $http->close(); my $playername = getPlayerKey($client); my $player = getPlayer($playername); - my %data = parseLastFMData($lastFMData); + my $data = parseLastFMData($lastFMData); if ($lastFMData =~ /FAILED/) { $log->warn('Failed login!'); $player->session('UNSET'); $player->status('FAILEDLOGIN'); return; } - $player->session($data{session}); + $player->session($data->{session}->{key}); $player->status(undef); #set a cookie - required for track playback @@ -786,15 +794,15 @@ sub gotSession{ ); #need to do this as SS will remove the port if 80, and we need to match with its url - my ($server, $port, $path, $user, $password) = Slim::Utils::Misc::crackURL($data{stream_url}); + my ($server, $port, $path, $user, $password) = Slim::Utils::Misc::crackURL($data->{session}->{stream_url}); my $host = $port == 80 ? $server : "$server:$port"; #use custom lastfm: handler $player->stream_url("lastfm://$host$path"); - $player->base_url("http://$data{base_url}$data{base_path}"); - $player->subscriber($data{subscriber}); + $player->base_url("http://$data->{session}->{base_url}$data->{session}->{base_path}"); + $player->subscriber($data->{session}->{subscriber}); - if ($data{subscriber} == 1) { + if ($data->{session}->{subscriber} == 1) { $player->commands([@lastfm_commands,'discovery']); } else { $player->commands([@lastfm_commands]); @@ -842,15 +850,21 @@ sub getLastFMPlaylist { $log->info("Getting playlist for $playername"); $player->tracks('LOADING'); - my $lastfm_url = $player->base_url."/xspf.php?sk=".$player->session."&discovery=".$player->disco."&desktop=1.5.1"; - $log->info("Sending $lastfm_url\?$post\n"); + + $args->{'sk'} = $player->session; + $args->{'discovery'} = $player->disco; + $args->{'rtp'} = $player->rtp; + $args->{'method'} = "radio.getPlaylist"; $params->{client} = $client; - my $http = Slim::Networking::SimpleAsyncHTTP->new( - \&gotLastFMPlaylist, - \&failedLastFMUpdate, - $params, + $params->{api_key} = $api_key; + $params->{api_secret} = $api_secret; + my $http = Plugins::SqueezeScrobbler::LastFMAsyncHTTP->new( + \&gotLastFMPlaylist, + \&failedLastFMUpdate, + $params ); - $http->get("$lastfm_url"); + $http->post_lastfm_signed($lastfm_root, %{$args}); + } sub failedLastFMUpdate { @@ -877,16 +891,13 @@ sub gotLastFMPlaylist { $player->tracks('UNSET'); return 0; } else { - #stick an xml header on... - $lastFMData = "\n".$lastFMData; - #the format we get from this is pretty horrible! $parsed = Slim::Formats::XML::xmlToHash(\$lastFMData); $log->info(Dumper($parsed)); if (ref $parsed->{title} ne 'HASH'){ setStationName($player,$parsed->{title}); } - $player->skips($parsed->{'link'}->{content}); - my $tracks = $parsed->{trackList}->{track}; + $player->skips($parsed->{playlist}->{'link'}->{content}); + my $tracks = $parsed->{playlist}->{trackList}->{track}; if ($tracks and ref $tracks eq 'ARRAY' and scalar(@$tracks) > 0) { $player->tracks($tracks); $log->info("Got playlist for $playername with ".scalar(@$tracks)." tracks"); @@ -894,10 +905,10 @@ sub gotLastFMPlaylist { $player->tracks([$tracks]); $log->info("Got playlist for $playername with 1 track"); } else { - $log->info("Got empty playlist for $playername!"); + $log->warn("Got empty playlist for $playername!"); $player->tracks('NOCONTENT'); } - } + } if ( isPlaylistURL($http->params()->{'station'}) ) { $log->info("Setting station_url to: $http->params()->{'station'}\n"); @@ -1248,14 +1259,10 @@ sub getPlayer { sub parseLastFMData { my $lastFMData = Slim::Utils::Misc::unescape(shift); - my %data; - for (split /\n/, $lastFMData) { - # strip whitespace from end of line - m/^(.+?)=(.*?)\s*$/; - $data{$1} = $2; - } - $log->debug(Dumper(\%data)); - return %data; + my $xml = new XML::Simple; + my $data = $xml->XMLin("$lastFMData"); + $log->debug(Dumper($data)); + return $data; } ## station related stuff ########### @@ -1263,7 +1270,7 @@ sub similarArtistsSearch { my $artists = shift; my $searchString = Slim::Utils::Misc::escape($artists); my $url = "http://www.last.fm/listen/?artists=$searchString"; - $log->warn("Similar artists search: $url\n"); + $log->info("Similar artists search: $url\n"); # we don't use async here, because when we exit, I want to be sure the new session url has been populated my $http = Slim::Player::Protocols::HTTP->new({ 'url' => $url, @@ -1292,7 +1299,7 @@ sub switchStation { #remove lastfm:// $selectedstation =~ s/^lastfm:\/\///i; $selectedstation = "lastfm://$selectedstation"; - postToLastFM($client,$params,{url=>$selectedstation}); + postStationToLastFM($client,$params,{station=>$selectedstation}); } sub deleteStation { @@ -1379,9 +1386,10 @@ sub genStationNamesLevel1 { if ($addrecent){ #add similar artist stations from current track/Scrobbler history my @artists; - my %seen; + my %seen; + my $recent = Plugins::SqueezeScrobbler::Scrobbler::getRecentlyPlayed($client); # use in memory history to generate a list of stations - foreach ( @{Plugins::SqueezeScrobbler::Scrobbler::getRecentlyPlayed($client)}) { + foreach ( @{$recent}) { my $artist = $_->[0]; next if ($seen{$artist}); $seen{$artist}++; @@ -1454,15 +1462,12 @@ sub getLastFMData{ my $client = shift; my $type = lc shift; my ($user) = Plugins::SqueezeScrobbler::Settings::getUserIDPasswordForClient($client); - my $url = "http://ws.audioscrobbler.com/1.0/user/$user/$type.xml"; + my $url = $lastfm_root."?method=user.get".$type."&user=".$user."&api_key=".$api_key; my $data = getFeedSync($url); my @values; - print Dumper $data; - for (@{$data->{user}}) { - print dumper \$_; + for (@{$data->{$type}->{user}}) { if (ref($_) eq "HASH"){ - print "adding $_->{username}...\n"; - push @values, genStationNames($client,addNickName('user/'.$_->{username})); + push @values, genStationNames($client, addNickName('user/'.$_->{name})); } } return @values; @@ -1474,31 +1479,20 @@ sub XMLencode($) $input =~ s/&/&/g; $input =~ s/>/>/g; $input =~ s/new({ - 'url' => $url, - 'create' => 0, - }); - - if (defined $http) { - my $content = $http->content(); - $http->close(); - return 0 unless defined $content; - my $xml = eval { Slim::Formats::XML::xmlToHash(\$content) }; - if ($@) { - $log->error("Failed to parse XML feed: $@"); - return 0; - } - return $xml; + my $content = get($url); + my $xml = eval { Slim::Formats::XML::xmlToHash(\$content) }; + if ($@) { + $log->error("Failed to parse XML feed: $@"); + return 0; } - return 0; + return $xml } #generic 'on-screen' message handler diff -rupN orig/lib/Plugins/SqueezeScrobbler/ProtocolHandler.pm patched/lib/Plugins/SqueezeScrobbler/ProtocolHandler.pm --- orig/lib/Plugins/SqueezeScrobbler/ProtocolHandler.pm 2011-02-15 21:26:34.000000000 +0100 +++ patched/lib/Plugins/SqueezeScrobbler/ProtocolHandler.pm 2013-01-04 16:57:44.000000000 +0100 @@ -204,11 +204,12 @@ sub canDoAction { if ( $action eq 'stop' && !canSkip($client) ) { # Is skip allowed? - $log->debug("Skip limit exceeded, disallowing skip"); + $log->warn("Skip limit exceeded, disallowing skip"); $client->showBriefly( { line1 => $client->string('PLUGIN_LASTFM_MODULE_NAME'), - line2 => $client->string('PLUGIN_LASTFM_SKIPS_EXCEEDED'), + #line2 => $client->string('PLUGIN_LASTFM_SKIPS_EXCEEDED'), + line2 => "Skipping not allowed", }, { scroll => 1, diff -rupN orig/lib/Plugins/SqueezeScrobbler/Scrobbler/Session.pm patched/lib/Plugins/SqueezeScrobbler/Scrobbler/Session.pm --- orig/lib/Plugins/SqueezeScrobbler/Scrobbler/Session.pm 2011-02-15 21:26:34.000000000 +0100 +++ patched/lib/Plugins/SqueezeScrobbler/Scrobbler/Session.pm 2013-01-06 10:11:46.000000000 +0100 @@ -91,7 +91,9 @@ sub new if (defined($password)) { #password is already MD5 encoded - $self->{passwordMD5} = $password; + # -- UPDATE, Jan 6, 2013: With the 2.0 API we need unencrypted passwords + $self->{password} = $password; + $self->{passwordMD5} = md5_hex($password); } $self->clearHandshake(); @@ -157,6 +159,8 @@ sub password sub passwordMD5 { shift->{passwordMD5}; } +sub password { shift->{password}; } + sub pendingSongFile { my $self = shift; diff -rupN orig/lib/Plugins/SqueezeScrobbler/Settings.pm patched/lib/Plugins/SqueezeScrobbler/Settings.pm --- orig/lib/Plugins/SqueezeScrobbler/Settings.pm 2011-02-15 21:26:34.000000000 +0100 +++ patched/lib/Plugins/SqueezeScrobbler/Settings.pm 2013-01-06 11:13:00.000000000 +0100 @@ -134,7 +134,8 @@ $prefs->migrate(1, sub { for (@{$old_accounts}){ my ($usr,$pwd) = split /:/,$_; #password is now saved encrypted - $pwd = md5_hex($pwd); + # -- UPDATE, Jan 6, 2013: With the 2.0 API we need unencrypted passwords + #$pwd = md5_hex($pwd); $new_accounts{$usr} = $pwd; } $prefs->set('accounts', \%new_accounts ); @@ -187,7 +188,8 @@ sub handler { #pre-encrypt passwords if (!defined $old_accounts or $old_accounts->{$inuser[$i]} ne $inpwd[$i]) { #it's a new value, therefore unencrypted (?) - $inpwd[$i] = md5_hex($inpwd[$i]); + # -- UPDATE, Jan 6, 2013: With the 2.0 API we need unencrypted passwords + #$inpwd[$i] = md5_hex($inpwd[$i]); } $accounts{$inuser[$i]} = $inpwd[$i]; } @@ -259,15 +261,16 @@ sub getUserIDPasswordForClient { my $accPassHash = retrieveAccountPasswordHash(); #check official plugin for user details - if ($slimprefs->get('enable_scrobbling') and my $userid = $slimprefs->client($client)->get('account')){ - my $accounts = $slimprefs->get('accounts') || []; - for my $account ( @{$accounts} ) { - if ( $account->{username} eq $userid ) { - $log->info("Got account $userid from official plugin!"); - return ($userid,$account->{password}); - } - } - } + # -- UPDATE, Jan 6, 2013: With the 2.0 API we need unencrypted passwords +# if ($slimprefs->get('enable_scrobbling') and my $userid = $slimprefs->client($client)->get('account')){ +# my $accounts = $slimprefs->get('accounts') || []; +# for my $account ( @{$accounts} ) { +# if ( $account->{username} eq $userid ) { +# $log->info("Got account $userid from official plugin!"); +# return ($userid,$account->{password}); +# } +# } +# } #find default my $defaultID = $prefs->get("defaultid");