#!/usr/bin/perl -w # -*- cperl -*- # # # random.pm - Choose random N music files from the archive. # # GNU MP3D - A portable(ish) MP3 server. # # Homepage: # http://www.gnump3d.org/ # # Author: # Steve Kemp # # Version: # $Id: random.pm,v 1.10 2004/03/31 11:44:04 skx Exp $ # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Steve Kemp # --- # http://www.steve.org.uk/ # # # # Return the author of this plugin. # sub getAuthor() { return( 'Steve Kemp ' ); } # # Return the version of this plugin. # sub getVersion() { my $REVISION = '$Id: random.pm,v 1.10 2004/03/31 11:44:04 skx Exp $'; my $VERSION = ""; $VERSION = join (' ', (split (' ', $REVISION))[1..3]); $VERSION =~ s/,v\b//; $VERSION =~ s/(\S+)$/($1)/; return( $VERSION ); } # # Handle requests to this plugin. # sub handlePath( ) { my ( $uri ) = (@_); # # See if we should just return a random directory... # if ( $uri =~ /^\/random\/directory/ ) { &handleRandomDirectory( ); exit; } # # See if we were called as a result of our form submission or not. # if ( $uri =~ /^\/random\/play/ ) { # # We were - so use the submitted details to serve a # playlist to the client. # &handlePlaylist(); } else { # # We weren't, so we must choose some random tracks and # present them to the user for inspection. # # # The HTML template we use for output. # And the text we build up to send. # my @template = &getThemeFile( $ARGUMENTS{'theme'}, "random.html" ); my $output = ""; # # Send the HTTP header. # my $header = &getHTTPHeader( 200, "text/html" ); &sendData($data, $header ); # # Default to 20 songs, or the number specified in our configuration # file. # my $count = &getConfig( "plugin_random_song_count", 20 ); # # However this may be overridden by the user. # if ( defined( $ARGUMENTS{ "count" } ) ) { $count = $ARGUMENTS{ "count" }; } # # Choose random songs # my %selections = &getRandomFiles( $count ); # # Build up the output HTML # # Display them - using 'plugin_random_song_format' # my $format = &getConfig( "plugin_random_song_format", '$ARTIST - $SONGNAME' ); my $suffix = &getConfig( "always_stream", 1 ); if ( $suffix eq "1" ) { $suffix = ".m3u"; } else { $suffix = ""; } $output = "\n"; # # Add a hidden form to contain the selections. # my $form = "\n"; # # Add in the form. # $output .= $form; # # Create a second form. # $form = "
\n"; # # Add in the line numbers of the random songs. # $count = 0; foreach my $number (keys %selections ) { $form .= "\n"; $count ++; } $form .= "\n"; $form .= "
\n"; $form .= "\n"; $form .= "\n"; $form .= "[ Random Directory ]
\n"; $output .= $form; # # Now process the template and insert our output. # my $text = ""; foreach my $line ( @template ) { # # Make global substitutions. # $line =~ s/\$HEADER//g; $line =~ s/\$HOSTNAME/$host/g; $line =~ s/\$VERSION/$VERSION/g; $line =~ s/\$RELEASE/$RELEASE/g; $line =~ s/\$DIRECTORY/\/random\//g; # # Now handle the special sections. # if ( $line =~ /(.*)\$BANNER(.*)/ ) { # Insert banner; my $pre = $1; my $post = $2; $text .= $pre; $text .= &getBanner( "/random/" ); $text .= $post; } elsif ( $line =~ /(.*)\$TEXT(.*)/ ) { $text .= $1 . $output . $2; } else { $text .= $line; } } &sendData( $data, $text ); close( $data ); exit 1; } # # Can't reach here. # &sendData($data, "Fatal Error - Can't Happen. random.pm\n" ); close($data); exit; } # # Handle the result of a form submission by retrieving the # passed files - and serving a playlist containing them. # sub handlePlaylist( ) { my @songs = ( ); foreach my $key ( keys %ARGUMENTS ) { if ( $key =~ /^track/ ) { push @songs, $ARGUMENTS{ $key }; delete( $ARGUMENTS{ $key } ); } } # # If we have songs # if ( ($#songs+1) > 0 ) { # Send playlist header. my $header = &getHTTPHeader( 200, "audio/x-mpegurl" ); &sendData( $data, $header ); # # Open the song tags database, and read in the relevent # lines. open( FILY, "<$tag_cache" ); my @lines = ; close( FILY ); foreach my $number ( @songs ) { # The entry for the selected track. my $line = $lines[ $number ]; my $track = ""; if ( $line =~ /([^\t]+)\t(.*)/ ) { $track = $1; } # # Strip song root off - if present. # if ( $track =~ /$ROOT(.*)/ ) { $track = $1; } if ( substr( $track, 0, 1 ) ne "/" ) { $track = "/$track"; } &sendData($data, "http://" . $host . $track . "\n" ); } close( $data ); exit; } # Send error my $header = &getHTTPHeader( 200, "text/html" ); &sendData( $data, $header ); my $text = &getErrorPage( $ARGUMENTS{'theme'}, "Error - No tracks sent." ); &sendData( $data, $text ); close( $data ); exit; } # # Choose a random line from the cache file, and work out the # directory the given track lives in. # # Issue a redirect to force the user to view that. # # sub handleRandomDirectory( ) { open( FILY, "<$tag_cache" ); my @lines = ; close( FILY ); # Pick a random line from the database. my $random = $lines[ rand @lines ]; if ( $random =~ /([^\t]+)\t(.*)/ ) { $random = $1; } # # We only care about the directory name. # if ( $random =~ /(.*)\/(.*)$/ ) { $random = $1; } # # Strip off the root # if ( $random =~ /$ROOT\/(.*)/ ) { $random= $1; } &sendData($data, "HTTP/1.0 300 OK\nLocation: /$random\n\n" ); exit; } # # Return a hash containing some random files, the hash will be of # the form: # # $result{ 'number' } = 'song' # # Where number is the line number of the entry in the cache file. # sub getRandomFiles( $ ) { # Count of random tracks to return my ( $count ) = ( @_ ); # Results we return. my %RESULTS; # # Open the music "database" file. # open( FILY, "<$tag_cache" ); my @lines = ; close( FILY ); # # Loop till we have enough. # while( $count > 0 ) { my $num = int rand @lines; my $line = $lines[ $num ]; if ( $line =~ /([^\t]+)\t(.*)/ ) { # Save the filename. $RESULTS{ $num } = $1 ; $count -= 1; } } return( %RESULTS ); }