#!/bin/sh
# Steve Parker (http://steve-parker.org/)
# (c) 25 Jan 2007 
# BSD License.

# Version 0.1 - 25 Jan 2007

# Inspired by http://www.elsewhere.org/journal/archives/2004/09/25/howto-capture-streaming-audio-for-later/
# and http://burner.geekserver.net/bbc/

# Requires: mplayer (http://www.mplayerhq.hu/)
# Good to have: wget (http://www.gnu.org/software/wget/)
# To create MP3s: lame (http://lame.sourceforge.net/)

# Consult your lawyer before using this script.

# Default Radio Station...  (case-sensitive)
# configurable with the "-1 -2 -3 -4 -x" commandline switches; see usage()
# radio1, 1xtra, radio2, radio3, radio4
RADIO=radio4
DEBUG=""
DONT_DOWNLOAD=""

if [ ! -d ~/.bbc ]; then
	mkdir ~/.bbc
	if [ "$?" -ne "0" ]; then
		echo "WARNING: Can't create ~/.bbc/ for storing schedules :-("
	fi
fi

usage()
{
	echo
	echo "    bbc.sh (c) Steve Parker (http://steve-parker.org/)"
	echo
	echo "bbc.sh [ -1|2|3|4|x ] [ -d ] [ -D ] list | progname"
	echo "  -1,2,3,4,x  : selects radio station"
	echo "  -d          : Don't download the schedule (why?!)"
	echo "  -D          : Enable Debug mode."
	echo "  progname    : downloads the specified programme."
	echo "  list        : Displays a list of programmes"
	echo "      (you probably want to run this through \"| less\" or \"| grep progname\""
	echo "      Sample output: "
	echo "          rhcpdoc : Red Hot Chili Peppers - From Skateboards to Stadiums"
	echo "          - Tracing the story of the band over the last 20 years."
	echo "      To download this, you would run:"
	echo "          bbc.sh -1 rhcpdoc"
	echo "      You will end up with a file called rhcpdoc.mp3"
	echo
	echo "Station is tuned to : $RADIO"
	echo
	exit 0
}

getshowlist()
{
	if [ -z "${DONT_DOWNLOAD}" ]; then
	  rm -f ~/.bbc/audiolist_${RADIO}.shtml
	  echo "Downloading schedule for ${RADIO} ..."
	  if [ -z "${DEBUG}" ]; then
		  QUIET=" -q "
	  fi
	  wget ${QUIET} http://www.bbc.co.uk/radio/aod/networks/${RADIO}/audiolist.shtml -O ~/.bbc/audiolist_${RADIO}.shtml
	fi
}

getshows()
{
# Expected input:
#<div id="az">
#<li><a href="aod.shtml?radio4/morning_news" target="bbcplayer">8am News</a> - The latest 8am news from BBC Radio 4
#.... etc ...
#</div>
# This should get just the stuff in the "az" div, and nothing else.
# example of the expected output:
#morning_news : 8am News
#- The latest 8am news from BBC Radio 4

	getshowlist
sed -n '/div id="az">/,/<\/div>/p' ~/.bbc/audiolist_${RADIO}.shtml | grep -w bbcplayer | cut -d'"' -f2- | while read l
do
	# I've gone a bit paranoid here to cover for some simple
	# changes in the Beeb's HTML formatting. However, it would
	# need to be on the same line.

	# Assume that 'aod.shtml?radioX/filename"' gives the filename
	shortname=`echo $l | cut -d'/' -f7 | cut -d'"' -f1`

	# The full name is the between '<...>programme name<' arrows
	longname=`echo $l | cut -d'>' -f2-|cut -d'<' -f1`

	# Any description comes after the link
	descr=`echo $l | cut -d'>' -f3-`

	echo $shortname : $longname
	if [ ! -z "${descr}" ]; then
	  echo $descr
        fi
	echo "-------------------------------------------"
done
}

downloadshow()
{
	if [ -f ${1}.ram ]; then
		echo "${1}.ram already exists.. aborting"
		exit 1
	fi
	echo "------------------------------------------------------------------------------"
	echo "|                                                                            |"
	echo "| `date` : Download starting. "
	echo "| Please wait, this will take as long as the show itself.                    |"
	echo "|                                                                            |"
	echo "------------------------------------------------------------------------------"
	cmd="mplayer -download -dumpfile ${1}.dump -dumpstream -playlist http://www.bbc.co.uk/radio/aod/shows/rpms/${RADIO}/${1}.ram"
	#if [ -z "${DEBUG}" ]; then
		#time (${cmd} >/dev/null 2>&1)
	#else
		time ${cmd}
	#fi
	#time (mplayer -download -dumpfile ${1}.dump -dumpstream -playlist http://www.bbc.co.uk/radio/aod/shows/rpms/${RADIO}/${1}.ram > /dev/null 2>&1)
	ls -lh ${1}.dump
	echo "------------------------------------------------------------------------------"
	echo "|                                                                            |"
	echo "| `date` : Download complete. "
	echo "|                                                                            |"
	echo "------------------------------------------------------------------------------"
}
convertshow()
{

	if [ ! -s ${1}.dump ]; then
		echo "ERROR: No file found"
		echo "Try the 'list' feature."
		rm  -f ${1}.dump
		usage
		exit 1
	fi
	if [ -f ${1}.wav ]; then
		echo "${1}.wav already exists.. aborting"
		exit 1
	fi
	echo "Converting audio dump to WAV..."
	cmd="mplayer -download -ao pcm:file=${1}.wav ${1}.dump"
	#mplayer -ao pcm:file=${1}.wav ${1}.dump > /dev/null 2>&1
	if [ -z "${DEBUG}" ]; then
		${cmd} > /dev/null 2>&1
	else
		${cmd}
	fi
	ls -lh ${1}.wav && rm ${1}.dump
	if [ -f ${1}.mp3 ]; then
		echo "${1}.mp3 already exists.. aborting"
		exit 1
	fi
	type lame > /dev/null 2>&1
	if [ "$?" -eq "0" ]; then
	  echo "Converting WAV to MP3..."
	  cmd="lame --preset voice ${1}.wav ${1}.mp3"
	  if [ -z "${DEBUG}" ]; then
		  ${cmd} > /dev/null 2>&1
	  else
		  ${cmd}
	  fi
	  #lame --preset voice ${1}.wav ${1}.mp3 > /dev/null 2>&1
	  ls -lh ${1}.mp3 && rm ${1}.wav
        else
	  echo "Lame not found; leaving as WAV, not converting to MP3"
	fi
}


downloadandconvert()
{
PROG=$1
downloadshow $PROG
convertshow $PROG

	echo "------------------------------------------------------------------------------"
	echo "|                                                                            |"
	echo "| `date` : Finished. "
	echo "|                                                                            |"
	echo "------------------------------------------------------------------------------"
}

### main script

if [ "$#" -eq "0" ]; then
	usage
	exit 1
fi

while getopts '1234x?hdD' c
do
  case $c in
	  '1') RADIO=radio1 ;;
	  '2') RADIO=radio2 ;;
	  '3') RADIO=radio3 ;;
	  '4') RADIO=radio4 ;;
	  'x') RADIO=1xtra ;;
	  '\?') usage; exit 0  ;;
	  'h') usage; exit 0  ;;
	  'd') DONT_DOWNLOAD=1  ;;
	  'D') DEBUG=1  ;;
  esac
done

# http://dannyman.toldme.com/2005/06/22/sh-bash-getopts/
shift `echo $OPTIND-1 | bc`

prog=$1
if [ "$prog" = "list" ]; then
  getshows 2>/dev/null | tee ~/.bbc/audiolist_${RADIO}.txt
else
  echo "Programme: $1 on $RADIO"
  if [ -z "${DONT_DOWNLOAD}" ]; then
    echo "Getting schedule ..."
    getshows > ~/.bbc/audiolist_${RADIO}.txt
  fi
  if [ -f ~/.bbc/audiolist_${RADIO}.txt ]; then
    grep -A1 -w "${1}" ~/.bbc/audiolist_${RADIO}.txt
    if [ "$?" -ne "0" ]; then
	echo
	echo "------------------------------------------------------------------------------"
	echo "| Programme not found. This may not work. Trying anyway ...                  |"
	echo "------------------------------------------------------------------------------"
	echo
     else
	if [ ! -z ${DONT_DOWNLOAD} ]; then
		echo "However, the schedule may be out of date."
	fi
    fi
  else
	  echo "No schedule found; can't confirm. This could indicate an error."
	  if [ ! -z "${DONT_DOWNLOAD}" ]; then
		  echo "As you chose not to download the schedule, it's impossible to confirm."
	  fi
  fi
  downloadshow $prog
  convertshow $prog
  exit 0 
fi


