#!/bin/bash
# angela@crystalfaeries.net http://www.kahealani.com/kahealani/angela_kahealani.html	2011-03-09 02:43:58+00:00
# http://www.crystalfaeries.net/linux/bin/istream
# Downloads and plays YouTube videos from a list of their 11-character hashcodes
# Collects from Second Life(TM)'s and SponOn3D(TM)'s viewer logs the Parcel Music and Media stream URLs
# into a playlist for Real Life listening, and manages removal from the playlist of streams you later find undesirable.

#	Playlist for youtube hashcodes (1 11-char code per line):
	youtube=/home/www/playlists/youtube.txt
#	Playlist for streaming URLs (1 URL per line):
	playlist=/home/www/playlists/shoutcast2sl.txt
#	userland crontab entry-daily  updates (edit according to your Second Life(TM) viewers and place uncommented in your crontab):
# 04 2 * * * grep "Starting internet stream: " $HOME/.secondlife/logs/.firestorm/logs/Firestorm.log | sed 's/^.*Starting internet stream: //' >> $playlist
#	userland crontab entry-hourly updates (edit according to your Second Life(TM) viewers and place uncommented in your crontab):
# 04 * * * * grep "Starting internet stream: " $HOME/.secondlife/logs/.firestorm/logs/Firestorm.log | sed 's/^.*Starting internet stream: //' >> $playlist

#	Temporary file:
	exitval=1	#default to error condition because we have not yet chosen to intend to exit
	appname="$(basename $0)"
	tmpfile=$(mktemp	/tmp/${appname}.XXXXXX)	|| exit $exitval
	trap "rm -f		$tmpfile 		;  exit $exitval" 0 1 2 15

#
#	Get options
#
let youtube_flag=1 # false by default
let streams_flag=1 # false by default
while [ $# -ne 0 ] ; do
let arguments=$#	#before we shift out any flags

	if [ "$1" = "-v" ]
	then		# Versioning is done by date only
		shift
		echo "$(basename $0) Version:"
		tail -n +2 $0 | head -n 6	# number of header lines displayed as help
		exit $exitval			# traditionally expected behaviour
	fi
	
	if [ "$1" = "-h" ]
	then		# help, I need  somebody,
		shift	# help, not just anybody.
		echo "$(basename $0) Usage:"
		echo "If  you don't specify only Youtube_downloads with the -y flag, "
		echo "and you don't specify only Streaming___music with the -s flag, "
		echo "then first we play youtube downloads followed by streams."
		echo "Arguments after flags may be URLs or 11-character hashcodes."
		echo "Danger, Danger, Will Robinson... youtube hashcodes starting with a hyphen may fail miserably."
		echo "The wary programmer must investigate the handling of arguments to the echo command."
		echo "After each file we give you an opportunity to enter 'rm' to remove that file,"
		echo "or enter 'de' to defer that file, or enter 'ed' to edit that file."
		echo "Changing    stations is as easy as typing:    'q<enter>'"
		echo "To remove a station from your playlist, type: 'qrm<enter>'"
		echo "To stop listening, type:                      'q^C'"
		echo "To pause or resume listening, type:         ' '"
		echo "Some streams may not be resumable, so you 'resume' the next 'station'."
		exit $exitval			# traditionally expected behaviour
	fi
	
	if [ "$1" = "-y" ] # yes, "-y" tells us to play youtube downloads
	then
		shift
		let youtube_flag=0 # true
	fi
	
	if [ "$1" = "-s" ] # yes, "-s" tells us to play streams
	then
		shift
		let streams_flag=0 # true
	fi
	
	if [[ $arguments -eq $# ]]
	then
		break	# out of loop if no more flags
	fi
done # getting options

let both=1 # false
if [[ $youtube_flag -eq 0 ]]
then
	if [[ $streams_flag -eq 0 ]]
	then	# both flags were actually specified
		let both=0 # true
	else	# youtube only
		if [ -n "$1" ]	# any arguments on command line?
		then		# append hashcodes from command line onto youtube playlist
			while [ $# -ne 0 ] ; do
				echo $1 >> $youtube
				exitval=$?
				shift
			done
		fi
	fi
else
	if [[ $streams_flag -eq 0 ]]
	then	# streams only
		if [ -n "$1" ]	# any arguments on command line?
		then		# append URLs from command line onto streams playlist
			while [ $# -ne 0 ] ; do
				echo $1 >> $playlist
				exitval=$?
				shift
			done
		fi
	else	#   no      flags; defaults as if both flags had been specified
		let youtube_flag=0 # true
		let streams_flag=0 # true
		let both=0 # true
	fi
fi
if [[ $both -eq 0 ]]
then	# we have to guess what any further arguments are
	while [ $# -ne 0 ] ; do
		if [ "`echo $1 | wc`" = "      1       1      12" ]
		then	# is a hash - youtube
			echo "$1" >> $youtube
		else	# is a URL
			echo "$1" >> $playlist
		fi
		exitval=$?
		shift
	done
fi

# done with the command line, flags turned into internal variables.
 player='/usr/bin/mplayer -fs'
	 alert='/usr/share/sounds/gnome/default/alerts/bark.ogg'
$player $alert > /dev/null 2> /dev/null	# acknowledge the CLI input.
exitval=$?

# tidy the URL playlist on disk, but youtube hashcodes are not sequential, so
# we will *not* sort the youtube list which is in order for viewing multi-segment videos.
if [[ $streams_flag -eq 0 ]]
then	# we are going to stream, so tidy the stream list
	sort -u <	$playlist	>	$tmpfile
	mv					$tmpfile	$playlist
	echo =======	head:
	head $playlist
	echo -------	tail:
	tail $playlist
	echo =======	:end.
fi

exit	$exitval	#######	DEBUGGING EXIT	#######	CODE BELOW STILL BEING (RE)WRITTEN	#######

#
#	1 Infinite Loop (ref: where is the flagpole holding the pirate flag in "Pirates of Silicon Valley"? in the center of)
#
cd $HOME/Music/						# work at the relative root level of the Music itself
touch .music.txt					# keep a record of what we hear so we only hear each file once
while sleep 1;do	#loop forever, presuming concurrency with Second Life (TM) and streamripper

    if [ $streams_flag = 0 ]
    then
	echo Playing Streams, as requested
    else
	echo Playing Local Files followed by Streams, as requested
#
#	PLAY LOCAL FILES FIRST
#

# build the list of existing files
	cp	/dev/null			   		   "$tmpfile"
	for	   directories	in /media/cdrom $HOME/Music $HOME/Videos /media /mnt /opt ~/Downloads /usr/local/src /home/www	; do
		for extensions	in .asx .avi .flac .flv .mov .mp1 .mp2 .mp3 .mp4 .mpg .ogg .ra .rm .ram .wma .wmv	; do
			nice find $directories -iname "*$extensions" -exec du {} \; 2>/dev/null | grep -v kartrons_whores >> "$tmpfile"
		done
	done
# in decreasing size order
	sort -rn "$tmpfile" | cut -f 2- >	/tmp/$$.music.txt
	mv					/tmp/$$.music.txt	"$tmpfile"
# clean the list of pre-viewed files
	sort -u   .music.txt > /tmp/$$.music.txt
	mv /tmp/$$.music.txt          .music.txt

	if [ -s $HOME/Music/playlists/youtube.txt ]
	then	# presumably at least one youtube 11-char hashcode (one per line)
		echo Downloading according to  playlists/youtube.txt
# watching a youtube video does download the file into the browsers cache directory, but it does not give us file extensions (.flv,.mp4),
# so we have created a shared youtube cache for system-wide use by configuring browsers like firefox to cache videos here:
		pushd $HOME/Videos/www.youtube.com || pushd $HOME/Videos/www.youtube.com
# so we will use the same cache location now that we are going to explicitly download youtube videos
		for f in `cat playlists/youtube.txt`;do
			if [ -f "*$f*" ]			# the 11 character hash code should be unique
			then
				echo We already have a copy on disk of "*$f*"
			else
				c="$(echo $f | tr A-Z a-z)"	# cannonicalized to lower case
				if [ -f "*$c*" ]		# we may have lower cased it
				then
					echo We already have a copy on disk of "*$c*"
				else
					youtube-dl	http://www.youtube.com/watch?v="$f"
				fi
			fi
			exitval=$("$player" "$alert") > /dev/null			# alert the human we're about to pop-up a player window
			exitval=$("$player" "*$f*" "*$c*")	# either original or cannonicallized name will do
			echo -n "'rm' to remove, or new filename?: "
			read a
			if [ "$a" = "rm" ]
			then
				rm -i "*$f*" "*$c*"
			else
				for m in "*$f*" "*$c*";do
					mv -i "$m" "$a"."$m" || mv -i "$m" "$a"
				done
			fi
			tail -n +2	playlists/youtube.txt > "$tmpfile"
			mv "$tmpfile"	playlists/youtube.txt
		done
		popd
	fi
    fi	# end of local files

#DEBUG:
echo "ERROR: You must upgrade my code to account for your multiple 3D world chatlogs"
exit -1

#
#	UPDATE STREAMS PLAYLIST FROM SECOND LIFE (TM) SHOUTCAST2SL JUKEBOX
#
if [ -d "$HOME"/chatlogs ]
then
	if [ -f "$HOME"/chatlogs/chat.txt ]
	then
		echo "Good:	I found your chatlog."
	else
		echo "I can not find your chatlog, so please:"
		echo "ln -s "$HOME"/.secondlife/avatar_name/ "$HOME"/chatlogs"
		echo "I do not presume which 'avatar name' you use."
		exit 1
	fi
else
	echo "I can not find your chatlogs, so please:"
	echo " ln -s "$HOME"/.secondlife/avatar_name/ "$HOME"/chatlogs"
	echo "I do not presume which 'avatar name' you use."
	exit 1
fi
if [ -d $HOME/Music ]
then
	if [ -d $HOME/Music/playlists ]
	then
		echo "Good:	playlists directory found."
	else
		mkdir -p $HOME/Music/playlists
		echo "Good:	playlists directory created."
	fi
else
	mkdir -p $HOME/Music/playlists
	echo "Good:	playlists directory created."
fi
	echo "Good:	Refreshing Playlist from Second Life (TM) Public Chatlog..."
	if [ -f		playlists/$playlist ]
	then
		cp	playlists/$playlist							/tmp/$playlist.$$
	else
		touch										/tmp/$playlist.$$
	fi
	grep "SHOUTCAST2SL JUKEBOX" "$HOME"/chatlogs/chat.txt | cut -c 64- | sort -u | grep http >> 	/tmp/$playlist.$$
	sort -u			      /tmp/$playlist.$$	>			   		playlists/$playlist
	rm			      /tmp/$playlist.$$
	echo "Good:	Pruning the streams previously removed from the playlist:"
	if [ -f		playlists/."$playlist" ]
	then
		if [ -z playlists/."$playlist" ]
		then
			echo "OK:	Empty Mute List."
		else
			echo -n "Good:	Processing Mute List"
			for u in $(cat playlists/."$playlist");do
				grep -v "$u" playlists/$playlist	>		/tmp/$playlist.$$
				mv			  /tmp/$playlist.$$ playlists/$playlist
				echo -n "."
			done
			echo ""
			echo "Good:	Processed  Mute List."
		fi
	else
		echo "OK:	NonExistant Mute List."
	fi

#
#	PLAY STREAMS FROM INTERNET LISTED IN PLAYIST
#
	for f in $(cat playlists/$playlist);do
		echo "======= Begin: $f ======="
#		ping -c 1 `echo $f \
#			| sed 's/http:\/\///' \
#			| sed 's/\/.*$//' \
#			| sed 's/:.*$//'`
#		if [ $? = 0 ]
#		then
			exitval=$("$player" "$f")
			if [ $? == 0 ]
			then
				echo "========= End: $f ======="
				echo -n "Disposition: ('rm' to remove/mute)?: "
				read a
				if [ "$a" = "rm" ]
				then
					echo "$f" >> playlists/."$playlist"
					echo "MUTED:          $f"
				else
					echo "KEPT:           $f"
				fi
			else
				echo "$f" >> playlists/."$playlist"
				echo "FAILED:           $f"
			fi
#		else
#			echo "$f" >> playlists/."$playlist"
#			echo "OFFLINE:          $f"
#		fi
	done

#
#	ASK IF WE SHOULD REENABLE ALL KNOWN CHANNELS
#
        echo ======= END OF PLAYLIST, READY TO START OVER =======
        echo -n "Clear Mute List ('yes' to reenable all streams)?: "
        read a
        if [ "$a" = "yes" ]
        then
                mv      playlists/."$playlist"	playlists/."$playlist"-
		cat	playlists/"$playlist"	playlists/."$playlist"-	| sort -u >	playlists/."$playlist"
		mv	playlists/."$playlist"	playlists/"$playlist"
                echo "MUTE LIST CLEARED."
        else
                echo "MUTE LIST RETAINED."
        fi
        echo ======= 1 Infinite Loop =======

done
exitval=0
exit $exitval
# if the variable "file" contains a file's basename,
# we can substitute the existing extension to be ".ext" by:
# ${file%.*}.ext



syntax highlighted by Code2HTML, v. 0.9.1