[Slim-Checkins] r33641 - /7.7/trunk/server/Slim/Plugin/MOG/ProtocolHandler.pm

[email protected]
Newsgroups gmane.music.equipment.slimdevices.cvs
Message-ID <[email protected]>
Author: mherger
Date: Wed Nov  2 01:32:39 2011
New Revision: 33641

URL: http://svn.slimdevices.com/slim?rev=33641&view=rev
Log:
Bug: 17696
Description: add support for auto-refreshing radio lists. Needs more mysb.com changes to fully work.

Modified:
    7.7/trunk/server/Slim/Plugin/MOG/ProtocolHandler.pm

Modified: 7.7/trunk/server/Slim/Plugin/MOG/ProtocolHandler.pm
URL: http://svn.slimdevices.com/slim/7.7/trunk/server/Slim/Plugin/MOG/ProtocolHandler.pm?rev=33641&r1=33640&r2=33641&view=diff
==============================================================================
--- 7.7/trunk/server/Slim/Plugin/MOG/ProtocolHandler.pm (original)
+++ 7.7/trunk/server/Slim/Plugin/MOG/ProtocolHandler.pm Wed Nov  2 01:32:39 2011
@@ -16,6 +16,7 @@
 use Slim::Utils::Timers;
 use Slim::Utils::Prefs;
 
+use constant MAX_RADIO_QUEUE => 10;
 
 my $log = Slim::Utils::Log->addLogCategory( {
 	category     => 'plugin.mog',
@@ -131,40 +132,106 @@
 	my $client = $song->master();
 	my $url    = $song->track()->url;
 
-	$song->pluginData( radioTrackURL => undef );
-	$song->pluginData( radioTitle    => undef );
-	$song->pluginData( radioTrack    => undef );
 	$song->pluginData( abandonSong   => 0 );
 	
-	my $params = {
+	_getTrack($client, $song, {
 		song      => $song,
 		url       => $url,
 		successCb => $successCb,
 		errorCb   => $errorCb,
-	};
-		_getTrack($params);
-
+	});
+}
+
+sub _getRadioTracks {
+	my ( $client, $id, $count ) = @_;
+
+	main::DEBUGLOG && $log->is_debug && $log->debug("Getting tracks for station $id from SN");
+	
+	my $http = Slim::Networking::SqueezeNetwork->new(
+		\&_gotRadioTracks,
+		sub {
+			my $http  = shift;
+			
+			if ( main::DEBUGLOG && $log->is_debug ) {
+				$log->debug( 'getRadioTracks failed: ' . $http->error );
+			}
+		},
+		{
+			client  => $client,
+			radioId => $id,
+		},
+	);
+	
+	$http->get(
+		Slim::Networking::SqueezeNetwork->url(
+			'/api/mog/v1/playback/getRadioTracks?radioid=' . $id . '&count=' . $count
+		)
+	);
+}
+
+sub _gotRadioTracks {
+	my $http = shift;
+
+	my $client = $http->params->{client};
+
+	my $info = eval { from_json( $http->content ) };
+
+	if ( $@ ) {
+		$log->error(Data::Dump::dump($info, $@));
+	}
+	else {
+		my $icon   = __PACKAGE__->getIcon();
+		my $cache  = Slim::Utils::Cache->new;
+		
+		if ( main::DEBUGLOG && $log->is_debug ) {
+			$log->debug( 'getRadioTracks ok: ' . Data::Dump::dump($info) );
+		}
+		
+		my @urls;
+		foreach my $track ( @$info ) {
+			next unless ref $track eq 'HASH';
+		
+			# cache the metadata we need for display
+			my $trackId = delete $track->{id};
+			
+			my $meta = {
+				artist    => $track->{artist},
+				album     => $track->{album},
+				title     => $track->{title},
+				cover     => $track->{cover} || $icon,
+				duration  => $track->{duration},
+				genre     => $track->{genre},
+				year      => $track->{year},
+				bitrate   => '320k CBR', # XXX bulk API call does not know the actual bitrate, it will be replaced in _gotTrack
+				type      => 'MP3 (MOG)',
+				info_link => 'plugins/mog/trackinfo.html',
+				icon      => $icon,
+			};
+		
+			$cache->set( 'mog_meta_' . $trackId, $meta, 86400 );
+
+			my $url = 'mog://' . $http->params->{radioId} . '-' . $trackId . '.mp3';
+			push @urls, $url;
+		}
+
+		$client->execute([ 'playlist', 'addtracks', 'listRef', \@urls ]);
+		$client->execute([ 'play' ]);
+		
+		# Update the playlist time so the web will refresh, etc
+		$client->currentPlaylistUpdateTime( Time::HiRes::time() );
+		
+		Slim::Control::Request::notifyFromArray( $client, [ 'newmetadata' ] );
+	}
 }
 
 sub _getTrack {
-	my $params  = shift;
-	
-	my $song    = $params->{song};
-	my @players = $song->master()->syncGroupActiveMembers();
-	
-	# Fetch the track info
-	_getTrackInfo( $song->master(), undef, $params );
-}
-
-sub _getTrackInfo {
-	my ( $client, undef, $params ) = @_;
-	my $song   = $params->{song};
+	my ( $client, $song, $params ) = @_;
 	
 	return if $song->pluginData('abandonSong');
 	
 	# Get track URL for the next track
-	my ($trackId) = $params->{url} =~ m{mog://(.+)\.mp3};
-	
+	my ($trackId, $radioId) = getIds($params->{url});
+
 	my $http = Slim::Networking::SqueezeNetwork->new(
 		sub {
 			my $http = shift;
@@ -202,8 +269,9 @@
 	main::DEBUGLOG && $log->is_debug && $log->debug('Getting next track playback info from SN');
 	
 	$http->get(
+		# XXX - this call is to be renamed to getMediaURL, it's only kept here until we update mysb.com for backwards compatibility
 		Slim::Networking::SqueezeNetwork->url(
-			'/api/mog/v1/playback/playStream?trackid=' . uri_escape_utf8($trackId)
+			'/api/mog/v1/playback/playStream?trackid=' . ($trackId || '') . '&radioid=' . ($radioId || '')
 		)
 	);
 }
@@ -271,7 +339,7 @@
 	my $cache = Slim::Utils::Cache->new;
 	
 	# If metadata is not here, fetch it so the next poll will include the data
-	my ($trackId) = $url =~ m{mog://(.+)\.mp3};
+	my ($trackId) = getIds($url);
 	my $meta      = $cache->get( 'mog_meta_' . $trackId );
 	
 	if ( !$meta && !$client->master->pluginData('fetchingMeta') ) {
@@ -279,11 +347,10 @@
 		my @need;
 		
 		for my $track ( @{ Slim::Player::Playlist::playList($client) } ) {
-			my $trackURL = blessed($track) ? $track->url : $track;
-			if ( $trackURL =~ m{mog://(.+)\.mp3} ) {
-				my $id = $1;
-				if ( !$cache->get("mog_meta_$id") ) {
-					push @need, $id;
+			my ($trackURL) = blessed($track) ? $track->url : $track;
+			if ( my ($trackId) = getIds($trackURL) ) {
+				if ( !$cache->get("mog_meta_$trackId") ) {
+					push @need, $trackId;
 				}
 			}
 		}
@@ -292,26 +359,28 @@
 			$log->debug( "Need to fetch metadata for: " . join( ', ', @need ) );
 		}
 		
-		$client->master->pluginData( fetchingMeta => 1 );
-		
-		my $metaUrl = Slim::Networking::SqueezeNetwork->url(
-			"/api/mog/v1/playback/getBulkMetadata"
-		);
-	
-		my $http = Slim::Networking::SqueezeNetwork->new(
-			\&_gotBulkMetadata,
-			\&_gotBulkMetadataError,
-			{
-				client  => $client,
-				timeout => 60,
-			},
-		);
-
-		$http->post(
-			$metaUrl,
-			'Content-Type' => 'application/x-www-form-urlencoded',
-			'trackids=' . join( ',', @need ),
-		);
+		if (scalar @need) {
+			$client->master->pluginData( fetchingMeta => 1 );
+			
+			my $metaUrl = Slim::Networking::SqueezeNetwork->url(
+				"/api/mog/v1/playback/getBulkMetadata"
+			);
+		
+			my $http = Slim::Networking::SqueezeNetwork->new(
+				\&_gotBulkMetadata,
+				\&_gotBulkMetadataError,
+				{
+					client  => $client,
+					timeout => 60,
+				},
+			);
+
+			$http->post(
+				$metaUrl,
+				'Content-Type' => 'application/x-www-form-urlencoded',
+				'trackids=' . join( ',', @need ),
+			);
+		}
 	}
 	
 	#$log->debug( "Returning metadata for: $url" . ($meta ? '' : ': default') );
@@ -324,6 +393,23 @@
 	};
 }
 
+sub getIds {
+	my $url = shift;
+
+	my ($radioId, $trackId);
+
+	# radio track
+	if ( $url =~ m{mog://([at].+v\d+)-(.+)\.mp3}) {
+		$radioId = $1;
+		$trackId = $2;
+	}
+	else {
+		($trackId) = $url =~ m{mog://(.+)\.mp3};
+	}
+	
+	return ($trackId, $radioId);
+}
+
 sub _gotBulkMetadata {
 	my $http   = shift;
 
@@ -339,7 +425,7 @@
 	}
 	
 	if ( main::DEBUGLOG && $log->is_debug ) {
-		$log->debug( "Caching metadata for " . scalar( @{$info} ) . " tracks" );
+		$log->debug( "Caching metadata for " . scalar( @{$info} ) . " tracks: " . Data::Dump::dump($info) );
 	}
 	
 	# Cache metadata
@@ -421,7 +507,7 @@
 	my $request = shift;
 
 	my $client  = $request->client();
-	my $p1      = $request->getRequest(1);
+	my $event   = $request->getRequest(1);
 	
 	return unless defined $client;
 	
@@ -429,33 +515,43 @@
 	my $song = $client->playingSong();
 	
 	if ( !$song || $song->currentTrackHandler ne __PACKAGE__ ) {
-		# User stopped playing MOG 
-
+		# User stopped playing MOG
 		main::DEBUGLOG && $log->debug( "Stopped MOG, unsubscribing from playlistCallback" );
 		Slim::Control::Request::unsubscribe( \&_playlistCallback, $client );
 		
 		return;
 	}
-	
-	if ( $song->pluginData('radioTrackURL') && $p1 eq 'newsong' ) {
-		# A new song has started playing.  We use this to change titles
-		
-		my $title = $song->pluginData('radioTitle');
-		
-		main::DEBUGLOG && $log->debug("Setting title for radio station to $title");
-		
-		Slim::Music::Info::setCurrentTitle( $song->track()->url, $title );
+
+	my $url = $song->track->url;
+
+	my ($trackId, $radioId) = getIds($url);
+	
+	if ( $radioId ) {
+		main::DEBUGLOG && $log->debug( "Need to queue up new MOG Radio tracks..." );
+		
+		my $pos = Slim::Player::Source::playingSongIndex($client);
+
+		# remove played/skipped tracks from queue
+		while ($pos-- > 0) {
+			$client->execute([ 'playlist', 'delete', 0 ]);
+		}
+		
+		my $length = Slim::Player::Playlist::count($client);
+		
+		if ($length < MAX_RADIO_QUEUE) {
+			_getRadioTracks($client, $radioId, MAX_RADIO_QUEUE - $length);
+		}
 	}
 }
 
 sub trackInfoURL {
 	my ( $class, $client, $url ) = @_;
 	
-	my ($trackId) = $url =~ m{mog://(.+)\.mp3};
+	my ($trackId, $radioId) = getIds($url);
 	
 	# SN URL to fetch track info menu
 	my $trackInfoURL = Slim::Networking::SqueezeNetwork->url(
-		'/api/mog/v1/opml/trackinfo?trackid=' . $trackId
+		'/api/mog/v1/opml/trackinfo?trackid=' . ($trackId || '') . '&radioid=' . ($radioId || '')
 	);
 	
 	return $trackInfoURL;
@@ -498,7 +594,7 @@
 	main::DEBUGLOG && $log->is_debug && $log->debug("Re-init MOG - $url");
 	
 	my $cache     = Slim::Utils::Cache->new;
-	my ($trackId) = $url =~ m{mog://(.+)\.mp3};
+	my ($trackId, $radioId) = getIds($url);
 	my $meta      = $cache->get( 'mog_meta_' . $trackId );
 	
 	if ( $meta ) {
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.