Reworked comparison for numerical answer when selecting a CDDB output.
[clinton/abcde.git] / abcde
diff --git a/abcde b/abcde
index d23fc80..1ce8ba8 100755 (executable)
--- a/abcde
+++ b/abcde
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 # Copyright (c) 1998-2001 Robert Woodcock <rcw@debian.org>
 # Copyright (c) 2003-2005 Jesus Climent <jesus.climent@hispalinux.es>
 # This code is hereby licensed for public consumption under either the
 #
 # Copyright for this work is to expire January 1, 2010, after which it
 # shall be public domain.
+#
+# $Id$
 
-VERSION="2.3.99"
+VERSION='2.3.99-$Revision$'
 
 usage ()
 {
@@ -32,7 +34,6 @@ echo "-d <device>"
 echo "       Specify CDROM device to grab (flac uses a single-track flac file)"
 echo "-D     Debugging mode (equivalent to sh -x abcde)"
 echo "-e     Erase encoded track information from status file"
-#echo "-E     Set the encoding information for the tags"
 echo "-f     Force operations that otherwise are considered harmful. Read \"man abcde\""
 echo "-g     Use \"lame --nogap\" for MP3 encoding. Disables low disk and pipes flags"
 echo "-h     This help information"
@@ -57,6 +58,7 @@ echo "       Show dielfs from the CDDB info (year,genre)"
 echo "-S <#> Set the CD speed"
 echo "-t <#> Start the track numbering at a given number"
 echo "-T <#> Same as -t but modifies tag numbering"
+echo "-u     Use UNICODE tags and comments"
 echo "-v     Show version number and exit"
 echo "-V     Be a bit more verbose about what is happening behind the scenes"
 echo "-x     Eject CD after all tracks are read"
@@ -84,9 +86,9 @@ log ()
        BLURB="$1"
        shift
        case $BLURB in
-               error)   echo "[ERR] abcde: $@" >&2 ;;
-               warning) echo "[WAR] $@" >&2 ;;
-               info)    echo "[INF] $@" ;;
+               error)   echo "[ERROR] abcde: $@" >&2 ;;
+               warning) echo "[WARNING] $@" >&2 ;;
+               info)    echo "[INFO] $@" ;;
        esac
 }
 
@@ -332,11 +334,6 @@ relpath ()
 
 # do_getcddbinfo
 # Finds an specific field from cddbinfo
-# 
-#      TRACKNAME=$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | cut -f2 -d= | tr -d \[:cntrl:\] | sed 's/\ \+$//')
-#      TRACKNAME=$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | head -n 1 | cut -f2 -d= | tr -d \[:cntrl:\])
-#      TRACKNAME="$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | cut -f2- -d= | tr -d \[:cntrl:\] | sed 's/\ \+$//')"
-
 do_getcddbinfo()
 {
        case $1 in
@@ -377,6 +374,7 @@ do_replaygain()
                                        ;;
                        esac
                        OUTPUTFILES=""
+                       REPLAYINDEX=0
                        for UTRACKNUM in $TRACKQUEUE
                        do
                                CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
@@ -387,21 +385,25 @@ do_replaygain()
                                ALBUMFILE="$(mungefilename "$DALBUM")"
                                do_gettracknum
                                if [ "$VARIOUSARTISTS" = "y" ]; then
-                                       OUTPUTFILE=$(eval echo $VAOUTPUTFORMAT)
+                                       OUTPUTFILE="$(eval echo $VAOUTPUTFORMAT)"
                                else
-                                       OUTPUTFILE=$(eval echo $OUTPUTFORMAT)
+                                       OUTPUTFILE="$(eval echo $OUTPUTFORMAT)"
                                fi
-                               OUTPUTFILES="$OUTPUTDIR/$OUTPUTFILE.$OUTPUT $OUTPUTFILES"
+                               OUTPUTFILES[$REPLAYINDEX]="$OUTPUTDIR/$OUTPUTFILE.$OUTPUT"
+                               (( REPLAYINDEX = $REPLAYINDEX + 1 ))
                        done
                        case "$OUTPUT" in
                                flac)
-                                       run_command replaygain-flac $METAFLAC --add-replay-gain $OUTPUTFILES
+                                       run_command replaygain-flac $METAFLAC --add-replay-gain "${OUTPUTFILES[@]}"
                                        ;;
                                vorbis|ogg)
-                                       run_command replaygain-vorbis $VORBISGAIN --album $OUTPUTFILES
+                                       run_command replaygain-vorbis $VORBISGAIN --album "${OUTPUTFILES[@]}"
                                        ;;
                                mp3)
-                                       run_command replaygain-mp3 $MP3GAIN -a $OUTPUTFILES
+                                       run_command replaygain-mp3 $MP3GAIN -a "${OUTPUTFILES[@]}"
+                                       ;;
+                               mpc)
+                                       run_command replaygain-mpc $MPPGAIN --auto "${OUTPUTFILES[@]}"
                                        ;;
                                *);;
                        esac
@@ -838,20 +840,22 @@ do_encode ()
        if [ -s "$IN" -o X"$USEPIPES" = "Xy" ] ; then
                for OUTPUT in $(echo $OUTPUTTYPE | tr , \ )
                do
-                       if [ "$NOGAP" = "y" ] && checkstatus encodetrack-$OUTPUT-$1 ; then 
-                               continue
-                       fi
                        case "$OUTPUT" in
                                vorbis|ogg)
                                        OUT="$ABCDETEMPDIR/track$1.$OGGOUTPUTCONTAINER"
+                                       OUTPUT=$OGGOUTPUTCONTAINER
                                        ;;
                                flac)
                                        OUT="$ABCDETEMPDIR/track$1.$FLACOUTPUTCONTAINER"
+                                       OUTPUT=$FLACOUTPUTCONTAINER
                                        ;;
                                *)
                                        OUT="$ABCDETEMPDIR/track$1.$OUTPUT"
                                        ;;
                        esac
+                       if [ "$NOGAP" = "y" ] && checkstatus encodetrack-$OUTPUT-$1 ; then 
+                               continue
+                       fi
                        if [ X"$USEPIPES" = "Xy" ]; then
                                RUN_COMMAND=""
                                # We need a way to store the creation of the files when using PIPES
@@ -894,7 +898,7 @@ do_encode ()
                                case "$2" in
                                %local*%)
                                        case "$FLACENCODERSYNTAX" in
-                                       flac) $RUN_COMMAND nice $ENCNICE $FLACENCODER $FLACENCODEROPTS -o "$OUT" "$IN" ;; 
+                                       flac) $RUN_COMMAND nice $ENCNICE $FLACENCODER -f $FLACENCODEROPTS -o "$OUT" "$IN" ;; 
                                        esac
                                                ;;
                                        *)
@@ -1039,7 +1043,7 @@ do_single_gain ()
 
 # do_batch_gain
 # variables used:
-# MP3GAIN, MP3GAINOPTS, VORBISGAIN, VORBISGAINOPTS
+# MP3GAIN, MP3GAINOPTS, VORBISGAIN, VORBISGAINOPTS, MPPGAIN, MPPGAINOPTS
 # FIXME #
 do_batch_gain ()
 {
@@ -1273,7 +1277,6 @@ do_playlist ()
                        do
                                # Shares some code with do_move since the filenames have to match
                                CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
-                               #TRACKNAME=$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | cut -f2 -d= | tr -d \[:cntrl:\] | sed 's/\ \+$//')
                                do_getcddbinfo TRACKNAME
                                splitvarious
                                TRACKFILE="$(mungefilename "$TRACKNAME")"
@@ -1349,6 +1352,7 @@ do_discid ()
                        disktool -m ${CDROM#/dev/}
                fi
                WEHAVEACD=y
+               DISCID=$(echo $TRACKINFO | cut -f1 -d' ')
        else
                TRACKINFO=$(cat "$WAVOUTPUTDIR/abcde.$DISCID/discid")
        fi
@@ -1380,6 +1384,11 @@ do_discid ()
                                                TRACKS="$(echo "$CDPARANOIAOUTPUT" | egrep '^[[:space:]]+[[:digit:]]' | tail -n 1 | get_first | tr -d "." | tr '\n' ' ')"
                                                CDPARANOIAAUDIOTRACKS="$TRACKS"
                                        else
+                                               # Previous versions of abcde would store the tracks on a file, instead of the status record.
+                                               if [ -f "$ABCDETEMPDIR/cdparanoia-audio-tracks" ]; then
+                                                       echo cdparanoia-audio-tracks=$( cat "$ABCDETEMPDIR/cdparanoia-audio-tracks" ) >> "$ABCDETEMPDIR/status"
+                                                       rm -f "$ABCDETEMPDIR/cdparanoia-audio-tracks"
+                                               fi
                                                if [ -f "$ABCDETEMPDIR/status" ] && TRACKS=$(checkstatus cdparanoia-audio-tracks); then :; else
                                                        TRACKS=$(echo $TRACKINFO | cut -f2 -d' ')
                                                fi
@@ -1495,6 +1504,8 @@ do_discid ()
                        exit 1
                fi
                cat /dev/null > "$ABCDETEMPDIR/status"
+               # Store the abcde version in the status file.
+               echo "abcde-version=$VERSION" >> "$ABCDETEMPDIR/status"
        fi
        if [ X"$MAKECUEFILE" = "Xy" -a X"$WEHAVEACD" = "Xy" ]; then
                if checkstatus cuefile > /dev/null 2>&1 ; then :; else
@@ -1841,16 +1852,15 @@ do_cddbedit ()
                                                echo -n "Which entry would you like abcde to use (0 for none)? [0-$CDDBCHOICES]: " >&2
                                                read CDDBCHOICE
                                                [ X"$CDDBCHOICE" = "X" ] && CDDBCHOICE=1
-                                               if echo $CDDBCHOICE | egrep -q "[[:digit:]]+,[[:digit:]]+" ; then
+                                               if echo $CDDBCHOICE | egrep -q "[[:space:]]*[[:digit:]]+,[[:digit:]]+[[:space:]]*" ; then
                                                        if [ ! X"$DIFF" = "X" ]; then
-                                                               PARSECHOICE1=$(echo $CDDBCHOICE | cut -d"," -f1)
-                                                               PARSECHOICE2=$(echo $CDDBCHOICE | cut -d"," -f2)
+                                                               PARSECHOICE1=$(echo $CDDBCHOICE | cut -d"," -f1 | xargs printf %d 2>/dev/null)
+                                                               PARSECHOICE2=$(echo $CDDBCHOICE | cut -d"," -f2 | xargs printf %d 2>/dev/null)
                                                                if [ $PARSECHOICE1 -lt 1 ] || [ $PARSECHOICE1 -gt $CDDBCHOICES ] || \
                                                                   [ $PARSECHOICE2 -lt 1 ] || [ $PARSECHOICE2 -gt $CDDBCHOICES ] || \
                                                                   [ $PARSECHOICE1 -eq $PARSECHOICE2 ]; then 
                                                                        echo "Invalid diff range. Please select two coma-separated numbers between 1 and $CDDBCHOICES" >&2
                                                                else
-
                                                                        # We parse the 2 choices to diff, store them in temporary files and diff them.
                                                                        for PARSECHOICE in $(echo $CDDBCHOICE | tr , \ ); do
                                                                                do_cddbparse "$ABCDETEMPDIR/cddbread.$PARSECHOICE" > "$ABCDETEMPDIR/cddbread.parsechoice.$PARSECHOICE"
@@ -1866,10 +1876,10 @@ do_cddbedit ()
                                                        else
                                                                echo "The diff program was not found in your path. Please choose a number between 0 and $CDDBCHOICES." >&2
                                                        fi
-                                               else
+                                               elif echo $CDDBCHOICE | egrep -q "[[:space:]]*[[:digit:]]+[[:space:]]*" ; then
+                                                       # Make sure we get a valid choice
+                                                       CDCHOICENUM=$(echo $CDDBCHOICE | xargs printf %d 2>/dev/null)
                                                        if [ $CDCHOICENUM -lt 0 ] || [ $CDCHOICENUM -gt $CDDBCHOICES ]; then
-                                                               # Make sure we get a valid choice
-                                                               CDCHOICENUM=$(echo $CDDBCHOICE | xargs printf %d 2>/dev/null)
                                                                echo "Invalid selection. Please choose a number between 0 and $CDDBCHOICES." >&2
                                                        fi
                                                fi
@@ -2132,14 +2142,6 @@ do_cdread ()
                FIRSTTRACK=$2
                LASTTRACK=$3
                UTRACKNUM=$FIRSTTRACK
-               case "$CDROMREADERSYNTAX" in
-                       ### FIXME ### How are we calculating the tracks in flac mode?
-                       flac) READTRACKNUMS="$FIRSTTRACK.1-$(($LASTTRACK + 1)).0" ;;
-                       cdparanoia) READTRACKNUMS="$FIRSTTRACK-$LASTTRACK" ;;
-                       cdda2wav) READTRACKNUMS="$FIRSTTRACK+$LASTRACK" ;;
-                       *) log error "$CDROMREADERSYNTAX does not support ONETRACK mode"
-                          exit 1 ;;
-               esac
        else
                UTRACKNUM=$1
        fi
@@ -2169,7 +2171,6 @@ do_cdread ()
                echo "Grabbing ${PIPE_MESSAGE}tracks $UTRACKNUM - $LASTTRACK as one track ..." >&2
        else
                if [ -r "$CDDBDATA" ]; then
-                       #TRACKNAME=$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | head -n 1 | cut -f2 -d= | tr -d \[:cntrl:\])
                        do_getcddbinfo TRACKNAME
                        echo "Grabbing ${PIPE_MESSAGE}track $UTRACKNUM: $TRACKNAME..." >&2
                else
@@ -2275,8 +2276,12 @@ fi
 decho ()
 {
 if [ x"$DEBUG" != "x" ]; then
-       DEBUGECHO=$(echo "$@" | tr -d '[]')
-       echo "[DEBUG] $DEBUGECHO: `eval echo \\$${DEBUGECHO}`"
+       if echo $1 | grep -q "^\[" ; then
+               DEBUGECHO=$(echo "$@" | tr -d '[]')
+               echo "[DEBUG] $DEBUGECHO: `eval echo \\$${DEBUGECHO}`"
+       else
+               echo "[DEBUG] $1"
+       fi
 fi
 }
 
@@ -2405,6 +2410,7 @@ NORMALIZE=normalize-audio
 CDSPEED=eject
 VORBISGAIN=vorbisgain
 MP3GAIN=mp3gain
+MPPGAIN=replaygain
 MKCUE=mkcue
 MKTOC=cdrdao
 DIFF=diff
@@ -2423,7 +2429,7 @@ MP3ENCOPTS=
 VORBIZEOPTS=
 OGGENCOPTS=
 # flac
-FLACOPTS="-f"
+FLACOPTS=
 # speex
 SPEEXENCOPTS=
 # mpc
@@ -2445,6 +2451,7 @@ MKCUEOPTS=
 MKTOCOPTS=""
 VORBISCOMMENTOPTS="-R"
 METAFLACOPTS="--no-utf8-convert"
+DIFFOPTS=
 
 # Default to one process if -j isn't specified
 MAXPROCS=1
@@ -2533,8 +2540,8 @@ if [ "$CDROM" = "" ] ; then
 fi
 
 # Parse command line options
-#while getopts 1a:A:bc:C:d:Dehj:klLmMnNo:pPr:Rs:S:t:T:vVxw:W: opt ; do
-while getopts 1a:bBc:C:d:Defghj:klLmMnNo:pPr:s:S:t:T:vVxw:W:z opt ; do
+#while getopts 1a:bc:C:d:Dehj:klLmMnNo:pPr:Rs:S:t:T:vVxw:W: opt ; do
+while getopts 1a:bBc:C:d:Defghj:klLmMnNo:pPr:s:S:t:T:uvVxw:W:z opt ; do
        case "$opt" in
                1) ONETRACK=y ;;
                a) ACTIONS="$OPTARG" ;;
@@ -2542,7 +2549,7 @@ while getopts 1a:bBc:C:d:Defghj:klLmMnNo:pPr:s:S:t:T:vVxw:W:z opt ; do
                b) BATCHNORM=y ;;
                B) NOBATCHREPLAYGAIN=y ;;
                c) if [ -e "$OPTARG" ] ; then . "$OPTARG" ; else log error "config file \"$OPTARG\" cannot be found." ; exit 1 ; fi ;;
-               C) DISCID="${OPTARG#abcde.}" ;;
+               C) DISCID="$( echo ${OPTARG#abcde.} | tr -d /)" ;;
                d) CDROM="$OPTARG" ;;
                D) set -x ;;
                e) ERASEENCODEDSTATUS=y ;;
@@ -2567,11 +2574,9 @@ while getopts 1a:bBc:C:d:Defghj:klLmMnNo:pPr:s:S:t:T:vVxw:W:z opt ; do
                R) DOREPLAYGAIN=y ;;
                s) SHOWCDDBFIELDS="$OPTARG" ;;
                S) CDSPEEDVALUE="$OPTARG" ;;
-#              t) PREPROCESSFORMATS="$OPTARG"
-#                 PREPROCESS=y ;;
-#              T) POSTPROCESSFORMATS="$OPTARG" ;;
                t) STARTTRACKNUMBER="$OPTARG" ;;
                T) STARTTRACKNUMBER="$OPTARG" ; STARTTRACKNUMBERTAG="y" ;;
+               u) CDDBPROTO=6 ;;
                v) 
                   echo "This is abcde v$VERSION."
                   echo "Usage: abcde [options] [tracks]"
@@ -2605,6 +2610,9 @@ if echo $CDROM | grep -i -q '.flac$'; then
        fi
 fi
 
+# If the user provided a DISCID, disable eject
+if [ -n "$DISCID" ]; then EJECTCD=n ; fi
+
 # Decide if we can continue.
 if [ "$ONETRACK" = "y" ]; then 
        # FIXME # remove check as soon as we find out about the other readers
@@ -2860,9 +2868,11 @@ do
                        ;;
                spx)
                        [ "$SPEEXENCODERSYNTAX" = "default" ] && SPEEXENCODERSYNTAX=speexenc
+#                      [ "$DOREPLAYGAIN" = "y" ] &&
                        ;;
                mpc)
                        [ "$MPPENCODERSYNTAX" = "default" ] && MPPENCODERSYNTAX=mppenc
+                       [ "$DOREPLAYGAIN" = "y" ] && NEEDMPPGAIN=y
                        ;;
                wav)
                        if [ "$KEEPWAVS" = "y" ]; then
@@ -3017,9 +3027,12 @@ if [ X"$CDSPEEDVALUE" != "X" ]; then
        esac
 fi
 
+###USEPIPESSUPPORT###
+
 # Rippers with USEPIPE support
 # FIXME # Include here all the rippers we can figure out support pipes
 PIPERIPPER_cdparanoia="-"
+PIPERIPPER_debug="-"
 PIPERIPPER_flac="-c "
 
 # Encoders with USEPIPE support
@@ -3045,13 +3058,17 @@ if [ "$USEPIPES" = "y" ]; then
                mpc)
                        PIPEENCODERSVARCHECK="PIPE_$MPPENCODER" ;;
        esac
-       if [ "$( eval echo "\$$PIPERIPPERSVARCHECK" )" = "$" ] ; then
+       decho "PIPERIPPERSVARCHECK: $( eval echo "\$$PIPERIPPERSVARCHECK" )"
+       if [ "$( eval echo "\$$PIPERIPPERSVARCHECK" )" = "$" ] || \
+          [ "$( eval echo "\$$PIPERIPPERSVARCHECK" )" = "" ] ; then
                log error "no support for pipes with given ripper"
                log error "read the USEPIPES file from the source tarball to get help."
                log error "On a Debian system, it is under /usr/share/doc/abcde/USEPIPES.gz"
                exit 1;
        fi
-       if [ "$( eval echo "\$$PIPEENCODERSVARCHECK" )" = "$" ] ; then
+       decho "PIPEENCODERSVARCHECK: $( eval echo "\$$PIPEENCODERSVARCHECK" )"
+       if [ "$( eval echo "\$$PIPEENCODERSVARCHECK" )" = "$" ] || \
+          [ "$( eval echo "\$$PIPEENCODERSVARCHECK" )" = "" ] ; then
                log error "no support for pipes with given encoder"
                log error "read the USEPIPES file from the source tarball to help"
                log error "on a Debian system, read /usr/share/doc/abcde/USEPIPES.gz"
@@ -3067,6 +3084,7 @@ for X in $CDROMREADER $CDDISCID ${NEEDTAGGER+$TAGGER} $MP3ENCODER \
        ${NEEDNORMALIZER+$NORMALIZER} ${NEEDEJECT+$EJECT} \
        ${NEEDDISKTOOL+disktool} ${NEEDCDSPEED+$CDSPEED} \
        ${NEEDVORBISGAIN+$VORBISGAIN} ${NEEDMP3GAIN+$MP3GAIN} \
+       ${NEEDMPPGAIN+$MPPGAIN} \
        ${NEEDCUEREADER+$CUEREADER} ${NEEDCUE2DISCID+$CUE2DISCID}
 do
        # Cut off the command-line options we just added in
@@ -3197,6 +3215,11 @@ else
                if [ "$NOGAP" = "y" ] || [ "$BATCHNORM" = "y" ]; then
                    :
                else
+                       # If we are not reading, set the encode output to loud already, so
+                       # that we can see the output of the first track.
+                       if [ "$MAXPROCS" = "1" ] && [ ! "$DOREAD" = "y" ]; then
+                               echo "encode-output=loud" >> "$ABCDETEMPDIR/status"
+                       fi
                        echo NEXTTRACK # Get the encoder machine churning again
                        if [ "$DOREAD" = "y" ]; then
                                if [ "$LOWDISK" = "y" ] && [ "$DOENCODE" = "y" ]; then
@@ -3372,10 +3395,8 @@ do
                        TRACKNUM="$FIRSTTRACK"
                        splitvarious
                else
-#                      TRACKNUM=$(printf %0.${TRACKNUMPADDING}d $(expr ${UTRACKNUM} + 0))
                        TRACKNUM=$UTRACKNUM
                        CDDBTRACKNUM=$(expr $UTRACKNUM - 1)
-                       #TRACKNAME="$(grep ^TTITLE$CDDBTRACKNUM= "$CDDBDATA" | cut -f2- -d= | tr -d \[:cntrl:\] | sed 's/\ \+$//')"
                        do_getcddbinfo TRACKNAME
                        splitvarious
                fi
@@ -3450,6 +3471,7 @@ wait
 if [ "$DOREPLAYGAIN" = "y" ]; then
        do_replaygain
 fi
+
 # Check to see if run_command logged any errors
 if [ -f "$ABCDETEMPDIR/errors" ]; then
        log error "The following commands failed to run:"
@@ -3465,11 +3487,11 @@ fi
 if [ "$DOCLEAN" = "y" ] && [ ! "$FORCE" = "y" ]; then
        ENCODED_FORMATS=$(egrep "^encodetrack-(.{3,6})-(.{1,2})$" "$ABCDETEMPDIR/status" | cut -d"-" -f2 | sort -u | tr '\n' '|')
        MOVED_FORMATS=$(egrep "^movetrack-output-(.{3,6})$" "$ABCDETEMPDIR/status" | cut -d"-" -f3 | sort -u | tr '\n' '|')
-       decho [ENCODED_FORMATS]
-       decho [MOVED_FORMATS]
        if [ "$ENCODED_FORMATS" != "$MOVED_FORMATS" ]; then
-               log warning "Not all encoded formats have been requested to be moved."
-               log warning "Use \"-a clean -f -C $DISCID\" to force the removal of the remaining data."
+               log warning "The encoded formats does not match with the moved ones"
+               log warning "Formats encoded: $( echo $ENCODED_FORMATS | tr "|" " " )"
+               log warning "Formats moved: $( echo $MOVED_FORMATS | tr "|" " " )"
+               log warning "Use \"abcde -a clean -f -C $DISCID\" to force the removal of the remaining data."
                DOCLEAN=n
        fi
 fi