#!/bin/bash
# GSRip is a wav/mp3/ogg command line Audio CD ripper
# Copyright 2010  Grégory Soutadé
# 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 3 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, see .
set -e
CDDA2WAV=icedax
LAME=lame
OGGENC=oggenc
EDITORS="emacs vim gedit kate"
tmp=
function _exit()
{
    cd /
    [ ! -z "$tmp" ] && /bin/rm -rf $tmp
}
function usage()
{
    echo "gsrip : rip an audio CD into wav/mp3/ogg (Grégory Soutadé )"
    echo 
    echo "usage : gsrip.sh [options]"
    echo 
    echo "Options :"
    echo "-a|--auto"
    echo "\tSelect the first entry from cddb server"
    echo ""
    echo "-b|--bitrate "
    echo "mp3 bitrate (32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320), default : 128"
    echo ""
    echo "-d|--dest "
    echo "mp3 destination, default : /tmp "
    echo ""
    echo "-D|--dev "
    echo "CDROM device, default :  /dev/cdrom"
    echo ""
    echo "-e|--extract-only"
    echo "Only extract wav"
    echo ""
    echo "-f|--file "
    echo "Use a .cddb file instead of retrieving from cddb server"
    echo ""
    echo "-h|--help"
    echo "This message"
    echo ""
    echo "-o|--overwrite"
    echo "Overwrite files if existing, default is skipping"
    echo ""
    echo "-p|--pattern "
    echo "Output filename pattern"
    echo "%g, %a, %l, %n, %t, %y replaced by genre, artist, album, track number, title, and year"
    echo "default is \"%n - %t\""
    echo ""
    echo "-r|--resume "
    echo "Don't extract wav files from CD, just encode. Wav files must be into "
    echo "This option can be combined with -f"
    echo ""
    echo "--wav"
    echo "Keep .wav files"
    echo ""
    echo "--mp3"
    echo "Encode wav into mp3"
    echo ""
    echo "--ogg"
    echo "Encode wav into ogg"
    exit
}
function isAbsolute()
{
    echo "$1" | grep "^/" > /dev/null
    return $?
}
trap "_exit" 0
auto=0
bitrate=128
bitrates="32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320"
dev="/dev/cdrom"
dest="/tmp"
extract_only=0
audio_cddb="audio.cddb"
retrieve_infos=1
overwrite=0
pattern="%n - %t"
resume=0
keep_wav=0
encode_mp3=0
encode_ogg=0
[ $# = 0 ] && usage
while getopts ":ab:d:D:ef:hkop:r:-:" arg ; do
    if [ "$arg" = "-" ] ; then
	arg="${OPTARG%%=*}"
	OPTARG="${OPTARG#*=}"
    fi
    case $arg in
	a|auto)
	    auto=1
	    ;;
	b|bitrate)
	    bitrate=$OPTARG
	    echo $bitrates | grep $bitrate
	    if [ ! $? ] ; then
		echo "Invalid bitrate $bitrate"
		echo "valid bitrates are $bitrates"
		exit 1
	    fi
	    ;;
	d|dest)
	    dest="$OPTARG"
	    isAbsolute $dest || dest=$PWD/$dest
	    ;;
	D|dev)
	    dev="$OPTARG"
	    ;;
	e|extract-only)
	    extract_only=1
	    ;;
	f|file)
	    audio_cddb="$OPTARG"
	    isAbsolute $audio_cddb || audio_cddb=$PWD/$audio_cddb
	    retrieve_infos=0
	    ;;
	h|"help")
	    usage
	    ;;
	o|overwrite)
	    overwrite=1
	    ;;
	p|pattern)
	    pattern="$OPTARG"
	    ;;
	r|resume)
	    resume=1
	    cd "$OPTARG"
	    retrieve_infos=0
	    ;;
	wav)
	    keep_wav=1
	    ;;
	mp3)
	    encode_mp3=1
	    if [ "`which $LAME`" == "" ] ; then
		echo "$LAME not found, cannot continue"
		exit 1
	    fi
	    ;;
	ogg)
	    encode_ogg=1
	    if [ "`which $OGGENC`" == "" ] ; then
		echo "$OGGENC not found, cannot continue"
		exit 1
	    fi
	    ;;
	":")
	    echo "Invalid argument: -$OPTARG need argument" >&2
	    usage
	    ;;
	"\?")
	    echo "Invalid option: -$OPTARG" >&2
	    usage
	    ;;
    esac
done
if [ $keep_wav = 0 -a $encode_mp3 = 0 -a $encode_ogg = 0 ] ; then
    echo "At least one of --wav --mp3 --ogg option must be set"
    exit 1
fi
if [ $resume = 0 ] ; then
    if [ "`which $CDDA2WAV`" == "" ] ; then
	echo "$CDDA2WAV not found, cannot continue"
	exit 1
    fi
    tmp=$(mktemp)
    /bin/rm -f $tmp
    /bin/mkdir -p $tmp
    cd $tmp
fi
if [ $retrieve_infos = 0 ] ; then
    if [ ! -f "$audio_cddb" ] ; then
    	echo "$audio_cddb not found"
    	exit
    fi
    cat "$audio_cddb"
    echo 
    echo "Is this correct ? (y[es], n[o], e[xit], c[opy])"
    echo -n "> "
    read response
    if [ "$response" = "c" -o "$response" = "copy" ] ; then
    	echo /bin/cp audio.cddb /tmp
    	/bin/cp "$audio_cddb" /tmp
    	exit
    fi
    [ ! -z "$response" -a $response != "y" -a $response = "yes" ] && exit
else
    if [ $auto = 1 ] ; then
	    $CDDA2WAV -D "$dev" -L 1 -J -v title	
    else	
# Info query
	while [ 1 ] ; do
	    if [ "$response" = "e" -o "$response" = "edit" ] ; then
	    	cat "$audio_cddb"
	    else
	    	$CDDA2WAV -D "$dev" -L 0 -J -v title
	    fi
	    echo 
	    echo "Is this correct ? (y[es], n[o], q[uit], c[opy], e[dit])"
	    echo -n "> "
	    read response
	    if [ "$response" = "c" -o "$response" = "copy" ] ; then
	    	echo /bin/cp audio.cddb /tmp
	    	/bin/cp "$audio_cddb" /tmp
	    	exit
	    fi
	    if [ "$response" = "e" -o "$response" = "edit" ] ; then
	    	for editor in $EDITORS ; do
	    	    if [ "`which $editor`" != "" ] ; then
	    		$editor "$audio_cddb"
	    		break
	    	    fi
	    	done
	    fi
	    [ -z "$response" -o "$response" = "y" -o "$response" = "yes" ] && break
	    [ "$response" = "q" -o "$response" = "quit" ] && exit
	done
    fi
fi
# Read CD infos
band="Unknown"
album="Album"
genre="unknown"
year=""
i=0
if [ ! -f "$audio_cddb" ] ; then
    while [ -d $dest/$band/$album ] ; do
	i=$((i + 1))
	album="album$i"
    done
else
    infos=`cat "$audio_cddb" | grep DTITLE | cut -d= -f2`
    band=$(echo $infos | cut -d/ -f1)
    album=$(echo $infos | cut -d/ -f2)
    genre=`cat "$audio_cddb" | grep DGENRE | cut -d= -f2`
    year=`cat "$audio_cddb" | grep DYEAR | cut -d= -f2`
fi
# Suppress spaces
band=$(echo $band | sed "s;/;-;g")
album=$(echo $album | sed "s;/;-;g")
genre=$(echo $genre | sed "s;/;-;g")
year=$(echo $year | sed "s;/;-;g")
if [ $resume = 0 ] ; then
# Extract wav
    tracks=""
    track=""
    tracknum=1
    while [ 1 ] ;
    do
	if [ $tracknum -lt 10 ] ; then
	    track="audio_0$tracknum"
	else
	    track="audio_$tracknum"
	fi
	[ ! -f "$track.inf" ] && break
	tracks="$tracks $track.wav"
	tracknum=$((tracknum + 1))
    done;
    $CDDA2WAV -B -D $dev $tracks
fi
# Convert into mp3
dir="$dest/$band/$album"
/bin/mkdir -p "$dir"
if [ $extract_only = 1 ] ; then
    cp *.wav $dir
    exit
fi
i=0
for track_wav in *.wav ; do
    echo $track_wav | grep audio_ >/dev/null || continue
    i=$(echo $track_wav | sed -r s/audio_0*\([0-9]*\).wav/\\1/g)
    i=$((i - 1))
    title=`cat "$audio_cddb" | grep TTITLE$i= | cut -d= -f2`
    i=$((i + 1))
    if [ $i -lt 10 ] ; then
	prefix="0$i"
    else
	prefix=$i
    fi
    [ -z "$title" ] && title="Audio Track $prefix"
    
    title=$(echo $title | sed "s;/;-;g")
    filename=$pattern
    filename=$(echo $filename | sed "s/%g/$genre/g")
    filename=$(echo $filename | sed "s/%a/$album/g")
    filename=$(echo $filename | sed "s/%l/$band/g")
    filename=$(echo $filename | sed "s/%n/$prefix/g")
    filename=$(echo $filename | sed "s/%y/$year/g")
    filename=$(echo $filename | sed "s/%t/$title/g")
    new_file="$dir/$filename"
    if [ $encode_mp3 = 1 ] ; then
	if [ ! -f "$new_file.mp3" -o $overwrite = 1 ] ; then
	    $LAME -b $bitrate -h --tt "$title" --ta "$band" --tl "$album" --ty "$year" --tn $i --tg "$genre" --add-id3v2 $track_wav "$new_file.mp3"
	else
	    echo "$new_file.mp3 already exists, skipping"
	fi
    fi
    if [ $encode_ogg = 1 ] ; then
	if [ ! -f "$new_file.ogg" -o $overwrite = 1 ] ; then
	    $OGGENC -b $bitrate -q 10 -t "$title" -a "$band" --album "$album" -d "$year" -N $i -G "$genre" $track_wav -o "$new_file.mp3"
	else
	    echo "$new_file.ogg already exists, skipping"
	fi
    fi
    if [ $keep_wav = 1 ] ; then
	if [ ! -f "$new_file.wav" -o $overwrite = 1 ] ; then
	    cp $track_wav "$new_file.wav"
	else
	    echo "$new_file.wav already exists, skipping"
	fi
    else
    	/bin/rm -f $track_wav
	
    fi
done
echo "CD extracted into $dest/$dir"
exit