File: autorip.sh

package info (click to toggle)
abcde 2.9.3-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, buster, forky, sid, trixie
  • size: 584 kB
  • sloc: sh: 4,761; perl: 272; python: 216; makefile: 79
file content (319 lines) | stat: -rw-r--r-- 7,914 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
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 unknown, 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/Unknown 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