#!/bin/bash

# cd2ogg.sh
# (c) 2003 Dennis Leeuw
# License: GPL v.2.0 or any newer version
MY_VERSION="0.7.2"

# User changeable variables
CDROM_DRIVE="/dev/cdrom"	# Where is the CD-ROM drive?
DATA_DIR="/data/cds"		# Where to dump the files?
				# CDs are dumped as:
				# DATA_DIR/Artist/Album/tracks
ENCODE_QUALITY="4"		# ogg encode quality

# CDDB variables
# USE_FREEDB if set to Y uses the freedb.org database
#            see the CDDB_HOST* variables for configuration.
USE_FREEDB="Y"

CDDB_HOST="www.freedb.org"		# The freedb server
CDDB_HOST_CGI="/cgi-bin/cddb.cgi"	# The cddb script
CDDB_HOST_PORT="80"			# Port to contact the server
CDDB_HOST_CONNECT_MODE="http"		# Protocol to contact server
FREEDB_MAILTO="freedb-submit@freedb.org" # E-mail address for submissions

# Command usage
CMD_DISCID="/usr/bin/cd-discid"		# Used to get Disc ID
CMD_CDDB="/usr/bin/cddbcmd"		# Used to contact FreeDB
CMD_CDREAD="/usr/bin/cdparanoia"	# Used for reading CD
CMD_OGGENC="/usr/bin/oggenc"		# Used for encoding to .ogg
CMD_MAIL="/usr/sbin/sendmail -t"	# Used for sending submissions

# For more verbose output set DEBUG to 1
DEBUG=0

###############################################################################
#                Nothing configureable below this line                        #
###############################################################################

function get_freedb_artist () {
	ARTIST=${CDDBOUTPUT%% \/*}
	ARTIST=${ARTIST#*$FETCH_ID }
}

function get_freedb_album () {
	ALBUM=${CDDBOUTPUT%%$'\n'*}
	ALBUM=${ALBUM#*\/ }
	ALBUM_TEST=${ALBUM/No match for disc ID/}
	if [ "x$CD_TYPE" = "x" ]; then
		echo "Could not contact host"
		echo -n "Do you want to add it? [Y/N]"; read A
		if [ "$A" = "Y" ]; then
			get_user_data
		else
			echo "EXIT"
			exit 1
		fi
	elif [ ${#ALBUM} != ${#ALBUM_TEST} ] || [ "x$CD_TYPE" = "x" ]; then
		echo "CD is not in $CDDB_HOST database"
		echo -n "Do you want to add it? [Y/N]"; read A
		if [ "$A" = "Y" ]; then
			get_user_data
			send_freedb_data
		else
			echo "EXIT"
			exit 1
		fi
	else
		local IFS=$'\n'
		ALBUM_DB=(`$CMD_CDDB -m $CDDB_HOST_CONNECT_MODE -h $CDDB_HOST:$CDDB_HOST_PORT -c $CDDB_HOST_CGI CDDB READ $CD_TYPE $FETCH_ID`)
	fi
}

function get_freedb_tracks () {
	local I=0
	local N=0
	for (( $I < ${#ALBUM_DB[*]}; $I < ${#ALBUM_DB[*]}; I=$(( $I +1 )) )); do
		TEST=${ALBUM_DB[$I]}
		TEST=${TEST/TTITLE/}
		if [ ${#TEST} != ${#ALBUM_DB[$I]} ]; then
			TRACKS[$N]=${ALBUM_DB[$I]#*=}
			N=$(($N+1))
		fi
	done
}

function get_freedb_data () {
	CDDBOUTPUT=`$CMD_CDDB -m $CDDB_HOST_CONNECT_MODE -h $CDDB_HOST:$CDDB_HOST_PORT -c $CDDB_HOST_CGI CDDB QUERY $@`
	CD_TYPE=${CDDBOUTPUT%% *}
	FETCH_ID=${CDDBOUTPUT#*$TYPE }
	FETCH_ID=${FETCH_ID%% *}

	get_freedb_artist
	get_freedb_album
	get_freedb_tracks
}

function send_freedb_data () {
	# Create e-mail
	TMP_FILE="/tmp/${CDID}"
	echo "To: $FREEDB_MAILTO" > $TMP_FILE
	echo "From: `whoami`@`dnsdomainname`" >> $TMP_FILE
	echo "Subject: cddb ${CD_TYPE} ${CDID}" >>$TMP_FILE
	echo "# xmcd" >> $TMP_FILE
	echo "#" >> $TMP_FILE
	echo "# Track frame offsets:" >> $TMP_FILE
	for OFFSET in ${TRACKOFFSET}; do
		echo "# ${OFFSET}" >> $TMP_FILE
	done
	echo "#" >> $TMP_FILE
	echo "# Disc length: ${LENGTH} seconds" >> $TMP_FILE
	echo "# Revision: 1" >> $TMP_FILE
	echo "# Submitted via: cd2ogg.sh ${MY_VERSION}" >> $TMP_FILE
	echo "DISCID=${CDID}" >> $TMP_FILE
	echo "DTITLE=${ARTIST} / ${ALBUM}" >> $TMP_FILE
	echo "DYEAR=" >> $TMP_FILE
	echo "DGENRE=" >> $TMP_FILE
	local I=0
	for (( $I < ${#TRACKS[*]}; $I < ${#TRACKS[*]}; I=$(( $I +1 )) )); do
		echo "TTITLE${I}=${TRACKS[$I]}" >>$TMP_FILE
	done
	echo "EXTD=" >> $TMP_FILE
	local I=0
	for (( $I < ${#TRACKS[*]}; $I < ${#TRACKS[*]}; I=$(( $I +1 )) )); do
		echo "EXTT${I}=" >> $TMP_FILE
	done
	echo "PLAYORDER=" >> $TMP_FILE

	# Send and remove e-mail
	$CMD_MAIL < $TMP_FILE
	rm $TMP_FILE
}

function get_user_artist () {
	while (test -z $ARTIST) do
		echo -n "Artist: "; read ARTIST
	done
}

function get_user_album () {
	while (test -z $ALBUM) do
		echo -n "Album title: "; read ALBUM
	done
}

function get_user_genre () {
	echo " 1- Blues              2- Country                   3- Folk"
	echo " 4- Jazz               5- Rock (pop,rock,house,etc) 6- Newage"
	echo " 7- Reggae             8- Classical                 9- Soundtrack"
	echo "10- Data (ISO9660)    11-Misc"
	while (test -z $CD_TYPE) do
		echo -n "Genre: "; read GENRE
		case $GENRE in
			1) CD_TYPE=blues
			;;
			2) CD_TYPE=country
			;;
			3) CD_TYPE=folk
			;;
			4) CD_TYPE=jazz
			;;
			5) CD_TYPE=rock
			;;
			6) CD_TYPE=newage
			;;
			7) CD_TYPE=reggae
			;;
			8) CD_TYPE=classical
			;;
			9) CD_TYPE=soundtrack
			;;
			10) CD_TYPE=data
			;;
			11) CD_TYPE=misc
			;;
		esac
	done
}

function get_user_tracks () {
	echo "Add the track names. Enter a track title per line."
	I=0
	for (( $I < $TRACKNUM ; $I < $TRACKNUM ; I=$(( $I +1 )) )); do
		TRACK=""
		while (test -z $TRACK) do
			echo -n "Track $(( $I +1 )): "; read TRACK
		done
		TRACKS[$I]="${TRACK}"
	done
}

function get_user_data () {
	echo "Manual CD data entry:"
	get_user_artist
	get_user_album
	get_user_genre
	display_cdid
	get_user_tracks
}

function rip_and_encode () {
	# Rip CD and encode
	local N=0
	for (( $N < ${#TRACKS[*]}; $N < ${#TRACKS[*]}; N=$(( $N +1 )) )); do
		TRACK=${TRACKS[$N]}
		I=$(($N+1))
		echo "Now rippining and encoding track $I: $TRACK"
		FILENAME=${TRACK// /_}
		FILENAME=${FILENAME%_}
		FILENAME=${FILENAME//\//-}
		if [ ${#I} = 1 ]; then
			FILENAME="0${I}_${FILENAME}"
		else
			FILENAME="${I}_${FILENAME}"
		fi
		$CMD_CDREAD -r -q $I - |\
			$CMD_OGGENC -Q -r \
			-a "${ARTIST}" -l "${ALBUM}" \
			-N "${I}" -t "${TRACK}" \
			-q "${ENCODE_QUALITY}" \
			-o "${DATA_DIR}/${FILE_ARTIST}/${FILE_ALBUM}/${FILENAME}.ogg" -
	done
}

function display_cdid () {
	clear
	echo "==================================== cd2ogg .sh ==============================="
	echo "CD id            : $CDID playing time ${LENGTH} seconds ($(($LENGTH / 60)) minutes)"
	echo "Amount of tracks : $TRACKNUM"
	echo "Artist           : $ARTIST"
	echo "Album            : $ALBUM"
	echo "Genre            : $CD_TYPE"
	echo "-------------------------------------------------------------------------------"
}

function display_album () {
	while (true); do
		echo "Track  #"$'\t'Offset$'\t'Trackname
		echo ========$'\t'======$'\t'=========
		local I=0
		for (( $I < ${#TRACKS[*]}; $I < ${#TRACKS[*]}; I=$(( $I +1 )) )); do
			N=$(($I+1))
			if [ ${#N} = 1 ]; then
				N=0${N}
			fi
			echo Track $N$'\t'${OFFSET[$I]}$'\t'${TRACKS[$I]}
		done
		echo "-------------------------------------------------------------------------------"
		echo -n "Is this correct? [Y/N] "; read A
		if [ "$A" = "Y" ]; then
			break
		else
			exit 1
		fi
	done
}

# Main
ARTIST=""
ALBUM=""
CD_TYPE=""

CD_ID=`$CMD_DISCID $CDROM_DRIVE`

# Splitting the CD_ID code
CDID=${CD_ID%% *}

TRACKNUM=${CD_ID#* }
TRACKNUM=${TRACKNUM%% *}
LENGTH=${CD_ID##* }
TRACKOFFSET=${CD_ID#* }
TRACKOFFSET=${TRACKOFFSET#* }
TRACKOFFSET=${TRACKOFFSET% *}
OFFSET=(`echo $TRACKOFFSET`)

display_cdid

if [ "$USE_FREEDB" = "Y" ]; then
	get_freedb_data $CD_ID
else
	get_user_data
fi

display_cdid
display_album

# Creating the directory structure in $DATA_DIR
# with: Artist/Album where all spaces are replaced by _
# and where a / in the artist or album name creates an
# extra directory
echo -n "Creating directory structure... "
FILE_ARTIST=`echo $ARTIST`
FILE_ARTIST=${FILE_ARTIST// /_}
FILE_ALBUM=`echo $ALBUM`
FILE_ALBUM=${FILE_ALBUM// /_}
echo "$DATA_DIR/$FILE_ARTIST/$FILE_ALBUM"
mkdir -p $DATA_DIR/$FILE_ARTIST/$FILE_ALBUM

echo "Starting the ripping and encoding..."
rip_and_encode 

#END
