diff -Nur squeezeserver/Slim/Plugin/RadioInfo.orig/install.xml squeezeserver/Slim/Plugin/RadioInfo/install.xml --- squeezeserver/Slim/Plugin/RadioInfo.orig/install.xml 1970-01-01 01:00:00.000000000 +0100 +++ squeezeserver/Slim/Plugin/RadioInfo/install.xml 2013-03-31 19:55:53.000000000 +0200 @@ -0,0 +1,18 @@ + + + PLUGIN_RADIOINFO_META + Claus Muus + enabled + PLUGIN_RADIOINFO_META + mld@clausmuus.de + http://www.minidvbinux.de + A97BFFEF-7654-42B1-B75B-775930D0BA49 + Plugins::RadioInfo::Plugin + + SqueezeCenter + * + 7.5 + + 2 + 1.0 + diff -Nur squeezeserver/Slim/Plugin/RadioInfo.orig/Plugin.pm squeezeserver/Slim/Plugin/RadioInfo/Plugin.pm --- squeezeserver/Slim/Plugin/RadioInfo.orig/Plugin.pm 1970-01-01 01:00:00.000000000 +0100 +++ squeezeserver/Slim/Plugin/RadioInfo/Plugin.pm 2013-03-31 19:55:53.000000000 +0200 @@ -0,0 +1,267 @@ +package Plugins::RadioInfo::Plugin; + +use strict; + +use vars qw($VERSION); +use HTML::Entities; +use Digest::SHA1; +use HTTP::Request; + +use Slim::Networking::SimpleAsyncHTTP; +use Slim::Networking::SqueezeNetwork; +use Slim::Utils::Log; +use Slim::Utils::Prefs; + + +my $log = Slim::Utils::Log->addLogCategory({ + 'category' => 'plugin.RadioInfo', + 'description' => 'PLUGIN_RADIOINFO_META', +}); + +my $prefs = preferences('server'); + +use constant cacheTTL => 15; + +my $stations = { + NDR1 => { + # http://opml.radiotime.com/Tune.ashx?id=s25044&formats=aac,ogg,mp3&partnerId=16&serial=7ea275cff83ed4601509c1592260b72f + regex => qr/opml.radiotime.com\/Tune.ashx\?id\=s25044/i, + parse => \&parseNDR, + url => 'http://www.ndr.de/public/playlist/wn.txt', + logo => 'http://d1i6vahw24eb07.cloudfront.net/s25044q.png' + }, + NDR2 => { + # http://opml.radiotime.com/Tune.ashx?id=s56867&formats=aac,ogg,mp3&partnerId=16&serial=7ea275cff83ed4601509c1592260b72f + regex => qr/opml.radiotime.com\/Tune.ashx\?id\=s56867/i, + parse => \&parseNDR, + url => 'http://www.ndr.de/public/playlist/ndr2.txt', + logo => 'http://d1i6vahw24eb07.cloudfront.net/s17492q.png' + }, +}; + +my $meta = {}; + + + +sub getDisplayName { + return 'PLUGIN_RADIOINFO_META'; +} + +sub initPlugin { + my $class = shift; + + $VERSION = $class->_pluginDataFor('version'); + + foreach my $name (keys $stations) { + main::DEBUGLOG && $log->is_debug && $log->debug("Register $name"); + + Slim::Formats::RemoteMetadata->registerProvider( + match => $stations->{$name}->{regex}, + func => \&provider, + ); + } +} + +sub _pluginDataFor { + my $class = shift; + my $key = shift; + + my $pluginData = Slim::Utils::PluginManager->dataForPlugin($class); + + if ($pluginData && ref($pluginData) && $pluginData->{$key}) { + return $pluginData->{$key}; + } + + return undef; +} + +sub provider { + my ( $client, $url ) = @_; + my $station; + + foreach my $name (keys $stations) { + if ($url =~ $stations->{$name}->{regex}) { + $station = $name; + } + } + +# main::DEBUGLOG && $log->is_debug && $log->debug("RadioInfo received for $station: $url"); + + # don't query the meta data every time we're called + if ( $client->isPlaying && (!$meta->{$station} || $meta->{$station}->{ttl} <= time) && !$meta->{$station}->{busy} ) { + main::DEBUGLOG && $log->is_debug && $log->debug('Fetching data for station ' . $station); + + $meta->{$station}->{busy} = 1; + + my $http = Slim::Networking::SimpleAsyncHTTP->new( + sub { + $meta->{ $station } = $stations->{$station}->{parse}($client, shift->content, $station); + }, + sub { + # in case of an error, don't try too hard... + $meta->{ $station } = $stations->{$station}->{parse}($client, '', $station); + } + ); + $http->get($stations->{$station}->{url}); + } + + return $meta->{$station}; +} + + +sub parseNDR { + my ( $client, $content, $station ) = @_; + + main::DEBUGLOG && $log->is_debug && $log->debug('Parse ' . $station . ' - ' . $content); + + my $info = { + icon => $stations->{$station}->{logo}, + cover => $stations->{$station}->{logo}, + artist => undef, + title => undef, + ttl => time + cacheTTL, + }; + + # "song_now": "Mrs. Greenbird: Box of colors", + if ($content =~ /"song_now"\: "(.*?):(.*?)"/sig) { + $info->{artist} = HTML::Entities::decode($1); + $info->{title} = HTML::Entities::decode($2); + } + + Slim::Control::Request::notifyFromArray( $client, [ 'playlist', 'newsong', $info->{title} ] ); + + return $info; +} + + +=p1 +sub parseContent { + my ( $client, $content, $station ) = @_; + + main::DEBUGLOG && $log->is_debug && $log->debug('Parse ' . $station . ' - ' . $content); + + my $info = { + icon => $icons->{$station}, + cover => $icons->{$station}, + artist => undef, + title => undef, + ttl => time + cacheTTL, + }; + + # hopefully we get title/artist information + if ($content =~ /"active_with_icon"[^>]*>(.*?)<\/span/sig) { + $content = HTML::Entities::decode($1); + } + + # if no song is available, try to get the current show's name + elsif ($content =~ /(.*?)<\/b>.*class="inactive_with_icon"/sig) { + $content = ''; + $info->{title} = HTML::Entities::decode($1); + } + + # ...otherwise try to get the last played song + elsif ($content =~ /"active"[^>]*>(.*?)<\/span/sig) { + $content = HTML::Entities::decode($1); + } + + # oh well... + else { + $content = ''; + } + + if ( $content ) { + my $i = 0; + map { + $info->{ ('artist', 'title', '__playtime', '__dummy1', '__dummy2')[$i++] } = _lowercase($_); + } split(//i, $content); + } + + $info->{title} ||= uc($station); + + main::DEBUGLOG && $log->is_debug && $log->debug("Got station information for $station - artist: $info->{artist}, title: $info->{title}"); + + $info->{busy} = 0; + + if ( $info->{title} ne $meta->{$station}->{title} + || $info->{artist} ne $meta->{$station}->{artist} ) { + + getArtwork( $client, $station, $info ); + } + + Slim::Control::Request::notifyFromArray( $client, [ 'playlist', 'newsong', $info->{title} ] ); + + return $info; +} + + +sub getArtwork { + my ( $client, $station, $info ) = @_; + + return if $station ne 'drs3'; + return unless $info->{artist}; + + main::DEBUGLOG && $log->is_debug && $log->debug("Let's get some artwork..."); + + my $args = '?track=' . URI::Escape::uri_escape_utf8( $info->{title} || '' ) + . '&artist=' . URI::Escape::uri_escape_utf8( $info->{artist} || '' ); + + my $http = Slim::Networking::SimpleAsyncHTTP->new( + sub { + my $html = shift; + + if ( $html && $html->content && $html->content =~ /^http/ ) { + my $imageUrl = $html->content; + + main::DEBUGLOG && $log->is_debug && $log->debug("Found title artwork: " . $imageUrl); + + #$meta->{$station}->{icon} = $meta->{$station}->{cover} = $imageUrl; + + $client->playingSong->pluginData( wmaMeta => { + icon => $imageUrl, + cover => $imageUrl, + artist => $info->{artist}, + title => $info->{title}, + } ); + + Slim::Control::Request::notifyFromArray( $client, [ 'newmetadata' ] ); + } + elsif ( $html && $html->content ) { + + main::DEBUGLOG && $log->is_debug && $log->debug("Nothing found: " . $html->content); + + } + else { + + main::DEBUGLOG && $log->is_debug && $log->debug(Data::Dump::dump($html)); + + } + }, + sub { + logError(Data::Dump::dump(shift)); + }, + ); + + $http->get( SEARCH_URL . $args ); + + return 1; +} + +sub _lowercase { + my $s = shift; + + return $s if $s =~ /[a-z]+/; + + # uppercase all first characters + $s =~ s/([\w'\`[:alpha:]äöüéàèçôî]+)/\u\L$1/ig; + + # fallback in case locale is wrong +# $s =~ tr/äöüàéèçôî/ÄÖÜÀÉÈÇÔÎ/; + + $s =~ s/^\s+//; + $s =~ s/[\:\s]+$//; + + return $s; +} +=cut + +1; \ Kein Zeilenumbruch am Dateiende. diff -Nur squeezeserver/Slim/Plugin/RadioInfo.orig/strings.txt squeezeserver/Slim/Plugin/RadioInfo/strings.txt --- squeezeserver/Slim/Plugin/RadioInfo.orig/strings.txt 1970-01-01 01:00:00.000000000 +0100 +++ squeezeserver/Slim/Plugin/RadioInfo/strings.txt 2013-03-31 19:55:53.000000000 +0200 @@ -0,0 +1,3 @@ +PLUGIN_RADIOINFO_META + EN Extended radio title info + DE Erweiterte Radio Titel Informationen \ Kein Zeilenumbruch am Dateiende.