Added a new autoripper
[clinton/abcde.git] / examples / autorip.sh
diff --git a/examples/autorip.sh b/examples/autorip.sh
new file mode 100644 (file)
index 0000000..bf8e3d6
--- /dev/null
@@ -0,0 +1,319 @@
+#!/bin/bash
+# TODO:
+#      Add paranoia.
+#      Fix logger messages.
+#      Add periodic/startup file/directory checks.
+#      Auto check of cd drive perms.
+
+echo "Autorip 0.1.3 started."
+
+# Set script local variables
+
+# FREEMIN
+# The minimum free space to have on the local TMP directory.
+FREEMIN="750"
+
+# TIMEOUT
+# The timeout, in seconds (approx), for the cd-tray to be sucked back 
+# in if it's not in already, this isn't exact, as a cycle is a bit more
+# then a second, but it comes out to about 3 hours.
+TIMEOUT=21600
+
+
+# CDROM
+# The cd-rom device to be used.
+CDROM="/dev/cdroms/cdrom1"
+
+# BASE
+# The folder to be used for all of the actions
+BASE="`pwd`"
+
+# DONE
+# The destination of the encoded files.
+DONE="$BASE/done"
+
+# TMP
+# Defaukt temporary directory.
+TMP="$BASE/tmp"
+
+# REMTEMP
+# Remote temporary directory. (currently unused)
+REMTEMP="$BASE/remtmp"
+
+# LOCTEMP
+# Local temporary directory.
+LOCTEMP="$BASE/tmp"
+
+# LOGDEST
+# The syslog facility to use for logging purposes.
+LOGDEST="local3"
+
+
+# Oher variables (Do not set)
+
+# LASTSTART - Last CD in the drive that was encoded.
+# LASTDONE - Last CD that was finished encoding.
+# TIME  - Approximately how many seconds have passed without having a cd in the drive.
+# CURRCD - This variable obtains the discid of whatever's in the cd drive.
+# REENC         - The disc-id of an already encoded disc put into the drive.
+# PROCESS - A short feild of the DISCID that's used for keeping track of running encodes.
+# PROCDIR - The working directory of a process.
+# DISCNAME - A process local variable that's just the name of the finished disc.
+# DONELOCK - A timer for waiting for an add to the DB. Wait no more than 60 seconds.
+
+LASTSTART=""
+TIME=0
+REENC=0
+
+# Reset the status of running.
+
+echo 0 > "$BASE/lib/stop"
+
+rm -r "$TMP"
+mkdir "$TMP"
+
+main ()
+{
+       getcurcd
+       
+       # If the cd in the drive is currently being encoded, don't try to encode it.
+       # Just sleep for 120 seconds and try again later.       
+
+       if [ "$CURCD" != "" ] && [ "$CURCD" = "$LASTSTART" ]
+       then    
+               sleep 120
+               TIME=0
+               return 0
+               
+       # If the CD isn't the same as the last one started, and cdparanoia is running
+       # Assume shit has hit the fan and kill it to end the current process.
+       # The process will die on it's own.
+       
+       elif [ "$CURCD" != "$LASTSTART" ] && [ "$(ps --no-heading -C cdparanoia)" != "" ]
+       then
+
+               logger -p $LOGDEST.info "Error ($LASTSTART): Disc removed while encoding!"                                              
+               killall -KILL cdparanoia
+               
+               # Reset the last start, because it wasn't.
+               
+               LASTSTART=""
+               
+               sleep 10
+               return 0
+       
+       # If there's nothing in the drive, and there's no timeout yet, increase.
+       # If something was in the drive, the function would return without encoding it.
+       
+       elif [ $TIME -lt $TIMEOUT ] && [ "$CURCD" = "" ]
+       then
+               TIME=$(($TIME+15))
+               sleep 15
+               return 0
+       
+       # If the cd has been sticking out for the timeout period (which is approx three hours).
+       # Suck it back in. This could be used to send a message to the domain, or cause beeping.        
+               
+       elif [ $TIME -ge $TIMEOUT ]
+       then
+               timeout
+               
+               TIME=0
+               
+               return 0
+       fi
+
+       # Eject the CD if the last CD processed is sucked (or put) back in.     
+
+
+       # If there is a cd in the drive
+       # Do not encode the last CD to go through the encoding process.
+       # This would cause the same CD to be re-re-rencoded if left in the drive
+       # for too long.
+
+       if [ "$CURCD" != "" ] && [ "$CURCD" != "$(< "$BASE/lib/LASTDONE")" ] &! [ -d "$TMP/$(echo $CURCD | cut -f 1 -d \ )" ]
+       then
+               
+               # If the cd in the drive was already encoded, set reenc to the disc-id. If the user puts the
+               # disc back in the drive, it will re-encode. If it's different, REENC won't matter.
+               
+               if [ "`grep "$CURCD" $BASE/lib/done.db`" = "" ] || [ "$REENC" = "$CURCD" ] 
+               then
+                       until [ "$(($(stat -f "$TMP" --format=%a)*4096/1024/1024))" -gt "$FREEMIN" ]
+                       do
+                               sleep 120
+                       done
+               
+                       LASTSTART=$CURCD
+                       cdenc &
+                       REENC=$CURCD
+                       
+               else
+                       eject $CDROM
+                       beep -r 3
+                       REENC="$CURCD"
+                       return 0
+               fi
+       fi
+}
+
+getcurcd()
+{
+       # Check for a cd. If cd-discid exits successfully, then set the variable.
+       # If it exits with a 0 (backwards, I know), then blank it.
+
+       if $(cd-discid $CDROM > /dev/null 2>&1)
+
+       then
+               CURCD=$(cd-discid $CDROM 2>&1)
+       else
+               CURCD=""
+       fi
+       return 0
+}
+
+
+
+timeout()
+{
+       eject -t $CDROM && getcurcd
+
+       # If the cd was the last done, assume we timed out.
+
+       if [ "$CURCD" = "$(< "$BASE/lib/LASTDONE")" ] 
+       then
+               logger -p $LOGDEST.error "CD Left (or put back) in drive."
+               eject $CDROM
+               beep -r 4
+               return 0
+       fi
+
+       return 0
+}
+
+
+# CD Encoder function. The workhorse.
+# Note: Only call when CD is in drive, else exit.
+
+cdenc ()
+{      
+       # Check to make sure the cd wasn't changed or removed.
+               
+       if [ "$(cd-discid $CDROM 2>&1)" != "$CURCD" ]
+       then
+               return 0
+       fi
+       
+       # Set this process's id.
+       
+       local PROCESS="$(echo $CURCD | cut -f 1 -d \ )"
+       local THISDISC="$CURCD"
+       local PROCDIR="$TMP/$PROCESS"
+       local DONELOCK=0
+
+       # Make a work folder
+       
+       rm -fr "$PROCDIR"
+       mkdir "$PROCDIR"
+       cd "$PROCDIR"
+
+       
+       # Okay, abcde has a bug where it tries to rip data cd's. But the version that fixes it itself has
+       # even more. So instead of trying to install the new version, which doesn't work, we use a command
+       # similar to the one ABCDE uses to determine the number of valid tracks (since it assumes the data
+       # track always occurs at the end, which in some game CD's it doesn't) and pass it to the command
+       # line. Yes, it really is one line.
+       
+       local VALIDTRACKS="$(cdparanoia -d $CDROM -Q 2>&1 | egrep '^[[:space:]]+[[:digit:]]' | awk '{print $1}' | tr -d "." | tr '\n' ' ')"
+       
+       # Do it. Do it. 
+               
+       logger -p $LOGDEST.info "Info ($PROCESS): Starting encoding."
+       
+       abcde -Nx -d $CDROM $VALIDTRACKS > /dev/null 2>&1
+               
+
+       # If the disc is unknwon, give a warning and unique folder name.
+       
+       if [ -d "$PROCDIR/Unknown Artist - Unknown Album/" ]
+       then
+               logger -p $LOGDEST.warn "Warning ($PROCESS): Processed successfully, but info unknown."
+               mv "$PROCDIR/Unknown Artist - Unknown Album" "$PROCDIR/Unkown Disc - ID $PROCESS"
+       
+       fi
+       
+       # If more than one folder is left, or the abcde.process folder is left over,
+       # or if there's nothing in the directory, something has gone WRONG.
+       
+       if [ $(ls -1 "$PROCDIR" | wc -l) -gt 1 ] || [ "$(ls -1 "$PROCDIR")" = "abcde.$PROCESS" ] || [ "$(ls -1 "$PROCDIR")" = "" ]
+       then
+               logger -p $LOGDEST.error "Error ($PROCESS): More than one folder or something very bad happened."
+               rm -r "$PROCDIR"
+               return 0
+       fi
+               
+       # Note: Don't declare discname until process is finished. Now is fine.
+       
+       local DISCNAME=`ls -1 "$PROCDIR"`
+       
+       # Put the current disc's ID into a file in the disc's folder, JIC
+       
+       echo "$THISDISC" > "$PROCDIR/$DISCNAME/disc_id"
+       
+       
+       logger -p $LOGDEST.info "Info ($PROCESS): Encoding of "$DISCNAME" completed successfully."
+       
+       
+       # Wait for the done database to be ready...
+
+       until ! [ -f "$BASE/lib/done.lock" ] || [ $DONELOCK -ge 60 ]
+       do
+       sleep 10
+       DONELOCK=$(($DONELOCK+10)) 
+       done
+
+       # Then add this disc to it.     
+       if [ "`grep "$CURCD" $BASE/lib/done.db`" = "" ] 
+       then    
+               touch "$BASE/lib/done.lock"
+               cat "$BASE/lib/done.db" "$PROCDIR/$DISCNAME/disc_id" > "$BASE/lib/done.new"
+               mv "$BASE/lib/done.new" "$BASE/lib/done.db"
+               rm "$BASE/lib/done.lock"
+       else
+               logger -p $LOGDEST.notice "Not adding $PROCESS to done.db" 
+       fi
+       
+       # Move the process's completed directory into the done folder.
+       
+       if ! [ -d "$DONE/$DISCNAME" ]
+       then
+               mv -f "$PROCDIR/$DISCNAME" "$DONE/"
+       elif [ -d "$DONE/$DISCNAME" ]
+       then
+               rm -r "$DONE/$DISCNAME"
+               mv -f "$PROCDIR/$DISCNAME" "$DONE/"
+       fi
+       
+       # A file must be used here because the variable is lost when the function exits sometimes.      
+
+       echo "$THISDISC" > "$BASE/lib/LASTDONE"
+       
+       # If I was the last disc started, and I'm done, clear the laststart variable so the last disc
+       # encoded can be re-encoded if they really want to.
+       
+       if [ "$THISDISC" = "$LASTSTART" ]
+       then
+               LASTSTART=""
+       fi
+
+       
+       # Remove the process temp directory and call it a day.
+       
+       rm -r "$PROCDIR"
+       
+}
+
+until [[ $(< "$BASE/lib/stop") == 1 ]]
+do
+       main
+done