Merge branch 'master' into opus
* master: fix file rename nicer status infos small fixes no SQL inside the signal-handler (race-condition) overzealous search and replace get rid of pipes extension is stripped before passing through sanitizeFile() minor fixes typo: sanitize path sanitize path createworker() destroyworker() rename on fat32compat change fat32compat
This commit is contained in:
commit
19e6b8c0f2
723
atom
723
atom
@ -14,6 +14,7 @@ EFMTINVPARM=49
|
|||||||
# config structures
|
# config structures
|
||||||
declare -A \
|
declare -A \
|
||||||
destinationchannels \
|
destinationchannels \
|
||||||
|
destinationfat32compat \
|
||||||
destinationcopymime \
|
destinationcopymime \
|
||||||
destinationformat \
|
destinationformat \
|
||||||
destinationfrequency \
|
destinationfrequency \
|
||||||
@ -255,7 +256,7 @@ getConfigDestination() {
|
|||||||
"'off'"
|
"'off'"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
'rename')
|
'rename')
|
||||||
case "$value" in
|
case "$value" in
|
||||||
*/*)
|
*/*)
|
||||||
@ -264,6 +265,21 @@ getConfigDestination() {
|
|||||||
esac
|
esac
|
||||||
destinationrename["$destination"]="${value##*/}"
|
destinationrename["$destination"]="${value##*/}"
|
||||||
;;
|
;;
|
||||||
|
'fat32compat')
|
||||||
|
case $value in
|
||||||
|
'true'|'on'|'yes')
|
||||||
|
destinationfat32compat["$destination"]=1
|
||||||
|
;;
|
||||||
|
'false'|'off'|'no')
|
||||||
|
destinationfat32compat["$destination"]=0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "fat32compat takes values:" \
|
||||||
|
"'yes' ,'true' ,'on', 'no', 'false',"\
|
||||||
|
"'off'"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
'skip_mime-type')
|
'skip_mime-type')
|
||||||
destinationskipmime[$destination]="${destinationskipmime[$destination]:+${destinationskipmime[$destination]}|}$value"
|
destinationskipmime[$destination]="${destinationskipmime[$destination]:+${destinationskipmime[$destination]}|}$value"
|
||||||
;;
|
;;
|
||||||
@ -759,7 +775,7 @@ gettag() {
|
|||||||
| sed -n "/^${1}=/I{s/^${1}=//I;p;q}"
|
| sed -n "/^${1}=/I{s/^${1}=//I;p;q}"
|
||||||
}
|
}
|
||||||
|
|
||||||
getInfosMP3_version='ID3-1'
|
getInfosMP3_version='ID3-2'
|
||||||
tagreaders+=( "$getInfosMP3_version" )
|
tagreaders+=( "$getInfosMP3_version" )
|
||||||
getInfos::MP3() {
|
getInfos::MP3() {
|
||||||
tagreader="$getInfosMP3_version"
|
tagreader="$getInfosMP3_version"
|
||||||
@ -773,12 +789,14 @@ getInfos::MP3() {
|
|||||||
title=$(gettag title)
|
title=$(gettag title)
|
||||||
tracknum=$(gettag tracknumber)
|
tracknum=$(gettag tracknumber)
|
||||||
year=$(gettag year)
|
year=$(gettag year)
|
||||||
expr='^[0-9]*$'
|
expr='^\([0-9]*\)$'
|
||||||
if [[ $genre =~ $expr ]]
|
if [[ $genre =~ $expr ]]
|
||||||
then
|
then
|
||||||
|
genre=${genre%)}
|
||||||
|
genre=${genre#(}
|
||||||
genre="${id3genres[$genre]}"
|
genre="${id3genres[$genre]}"
|
||||||
fi
|
fi
|
||||||
infos="${infos//: /=}"
|
infos="${infos/: /=}"
|
||||||
channels=$(gettag channels)
|
channels=$(gettag channels)
|
||||||
rate=$(gettag 'sample rate')
|
rate=$(gettag 'sample rate')
|
||||||
bitrate=$(gettag 'bit rate')
|
bitrate=$(gettag 'bit rate')
|
||||||
@ -809,7 +827,7 @@ getInfos::Ogg() {
|
|||||||
tracknum="$tracknum/$tracktotal"
|
tracknum="$tracknum/$tracktotal"
|
||||||
fi
|
fi
|
||||||
year=$(gettag date)
|
year=$(gettag date)
|
||||||
infos="${infos//: /=}"
|
infos="${infos/: /=}"
|
||||||
rate=$(gettag rate|head -n1)
|
rate=$(gettag rate|head -n1)
|
||||||
channels=$(gettag channels|head -n1)
|
channels=$(gettag channels|head -n1)
|
||||||
bitrate=$(gettag 'nominal bitrate')
|
bitrate=$(gettag 'nominal bitrate')
|
||||||
@ -1088,13 +1106,14 @@ copyFile() {
|
|||||||
" WHERE id=$destfileid" \
|
" WHERE id=$destfileid" \
|
||||||
" )," \
|
" )," \
|
||||||
" rename_pattern=" \
|
" rename_pattern=" \
|
||||||
"\"${destinationrenamepath[$destination]}/${destinationrename[$destination]}\""\
|
"\"${destinationrenamepath[$destination]}/${destinationrename[$destination]}:${destinationfat32compat["$destination"]}\""\
|
||||||
"WHERE id=$destfileid;" \
|
"WHERE id=$destfileid;" \
|
||||||
>&3
|
>&3
|
||||||
(( ++copies ))
|
(( ++copies ))
|
||||||
}
|
}
|
||||||
|
|
||||||
sanitizeFile() {
|
sanitizeFile() {
|
||||||
|
shopt -s extglob
|
||||||
string="$1"
|
string="$1"
|
||||||
# Filenames can't contain /
|
# Filenames can't contain /
|
||||||
string="${string//\// }"
|
string="${string//\// }"
|
||||||
@ -1112,8 +1131,7 @@ sanitizeFile() {
|
|||||||
|
|
||||||
# Filenames can't begin or end with ' '
|
# Filenames can't begin or end with ' '
|
||||||
string=${string/#+( )/}
|
string=${string/#+( )/}
|
||||||
string=${string//+( )./.}
|
string=${string/%+( )/}
|
||||||
string=${string//.+( )/.}
|
|
||||||
fi
|
fi
|
||||||
echo "$string"
|
echo "$string"
|
||||||
}
|
}
|
||||||
@ -1139,7 +1157,13 @@ getDestDir() {
|
|||||||
replace=$(sanitizeFile "$disc")
|
replace=$(sanitizeFile "$disc")
|
||||||
destdir="${destdir//%\{disc\}/$replace}"
|
destdir="${destdir//%\{disc\}/$replace}"
|
||||||
else
|
else
|
||||||
destdir+="${filename%/*}"
|
destdir+=$(sanitizeFile "${filename%%/*}")
|
||||||
|
part=${filename#*/}
|
||||||
|
while [[ $part =~ / ]]
|
||||||
|
do
|
||||||
|
destdir+="/$(sanitizeFile "${part%%/*}")"
|
||||||
|
part=${part#*/}
|
||||||
|
done
|
||||||
fi
|
fi
|
||||||
if ! [ -d "$destdir" ]
|
if ! [ -d "$destdir" ]
|
||||||
then
|
then
|
||||||
@ -1223,7 +1247,7 @@ encodeFile::mp3() {
|
|||||||
cleanup $tempdir/$tmpfile.wav
|
cleanup $tempdir/$tmpfile.wav
|
||||||
source_file $fileid
|
source_file $fileid
|
||||||
status 0
|
status 0
|
||||||
rename_pattern "${destinationrenamepath[$destination]}/${destinationrename[$destination]}"
|
rename_pattern ${destinationrenamepath[$destination]}/${destinationrename[$destination]}:${destinationfat32compat["$destination"]}
|
||||||
EOInsert
|
EOInsert
|
||||||
)
|
)
|
||||||
progressSpin
|
progressSpin
|
||||||
@ -1297,338 +1321,306 @@ encodeFile::vorbis() {
|
|||||||
cleanup $tempdir/$tmpfile.wav
|
cleanup $tempdir/$tmpfile.wav
|
||||||
source_file $fileid
|
source_file $fileid
|
||||||
status 0
|
status 0
|
||||||
rename_pattern "${destinationrenamepath[$destination]}/${destinationrename[$destination]}"
|
rename_pattern ${destinationrenamepath[$destination]}/${destinationrename[$destination]}:${destinationfat32compat["$destination"]}
|
||||||
EOInsert
|
EOInsert
|
||||||
)
|
)
|
||||||
progressSpin
|
progressSpin
|
||||||
}
|
}
|
||||||
|
|
||||||
worker() {
|
worker() {
|
||||||
trap "kill -USR1 $masterpid" EXIT
|
exec 2>>"$tempdir/worker$1.log"
|
||||||
while :
|
(( debug >= 2 )) && echo "${cmd_arg[@]}" >&2
|
||||||
do
|
"${cmd_arg[@]}" >/dev/null
|
||||||
echo work
|
|
||||||
read line
|
|
||||||
until [[ $line != AtOM:ComFail ]]
|
|
||||||
do
|
|
||||||
echo work
|
|
||||||
read line
|
|
||||||
done
|
|
||||||
if [[ $line == AtOM:Die ]]
|
|
||||||
then
|
|
||||||
break
|
|
||||||
elif [[ $line == AtOM:Sleep ]]
|
|
||||||
then
|
|
||||||
sleep 1
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
taskid=${line%%|*}
|
|
||||||
rest="${line#*|}|"
|
|
||||||
sourcefileid=${rest%%|*}
|
|
||||||
rest=${rest#*|}
|
|
||||||
required=${rest%%|*}
|
|
||||||
rest=${rest#*|}
|
|
||||||
cmd_arg=("${rest%%|*}")
|
|
||||||
rest=${rest#*|}
|
|
||||||
cmd_arg+=("${rest%%|*}")
|
|
||||||
rest=${rest#*|}
|
|
||||||
cmd_arg+=("${rest%%|*}")
|
|
||||||
rest=${rest#*|}
|
|
||||||
cmd_arg+=("${rest%%|*}")
|
|
||||||
rest=${rest#*|}
|
|
||||||
cmd_arg+=("${rest%%|*}")
|
|
||||||
rest=${rest#*|}
|
|
||||||
cmd_arg+=("${rest%%|*}")
|
|
||||||
rest=${rest#*|}
|
|
||||||
cmd_arg+=("${rest%%|*}")
|
|
||||||
rest=${rest#*|}
|
|
||||||
cmd_arg+=("${rest%%|*}")
|
|
||||||
rest=${rest#*|}
|
|
||||||
cmd_arg+=("${rest%%|*}")
|
|
||||||
rest=${rest#*|}
|
|
||||||
cmd_arg+=("${rest%%|*}")
|
|
||||||
rest=${rest#*|}
|
|
||||||
cmd_arg+=("${rest%%|*}")
|
|
||||||
rest=${rest#*|}
|
|
||||||
cmd_arg+=("${rest%%|*}")
|
|
||||||
rest=${rest#*|}
|
|
||||||
cmd_arg+=("${rest%%|*}")
|
|
||||||
rest=${rest#*|}
|
|
||||||
cmd_arg+=("${rest%%|*}")
|
|
||||||
rest=${rest#*|}
|
|
||||||
cmd_arg+=("${rest%%|*}")
|
|
||||||
rest=${rest#*|}
|
|
||||||
cmd_arg+=("${rest%%|*}")
|
|
||||||
rest=${rest#*|}
|
|
||||||
cmd_arg+=("${rest%%|*}")
|
|
||||||
rest=${rest#*|}
|
|
||||||
cmd_arg+=("${rest%%|*}")
|
|
||||||
rest=${rest#*|}
|
|
||||||
cmd_arg+=("${rest%%|*}")
|
|
||||||
rest=${rest#*|}
|
|
||||||
cmd_arg+=("${rest%%|*}")
|
|
||||||
rest=${rest#*|}
|
|
||||||
cmd_arg+=("${rest%%|*}")
|
|
||||||
rest=${rest#*|}
|
|
||||||
cmd_arg+=("${rest%%|*}")
|
|
||||||
rest=${rest#*|}
|
|
||||||
cmd_arg+=("${rest%%|*}")
|
|
||||||
rest=${rest#*|}
|
|
||||||
cmd_arg+=("${rest%%|*}")
|
|
||||||
rest=${rest#*|}
|
|
||||||
cmd_arg+=("${rest%%|*}")
|
|
||||||
rest=${rest#*|}
|
|
||||||
cmd_arg+=("${rest%%|*}")
|
|
||||||
rest=${rest#*|}
|
|
||||||
cmd_arg+=("${rest%%|*}")
|
|
||||||
rest=${rest#*|}
|
|
||||||
cmd_arg+=("${rest%%|*}")
|
|
||||||
rest=${rest#*|}
|
|
||||||
cmd_arg+=("${rest%%|*}")
|
|
||||||
rest=${rest#*|}
|
|
||||||
cmd_arg+=("${rest%%|*}")
|
|
||||||
rest=${rest#*|}
|
|
||||||
cleanup=${rest%%|*}
|
|
||||||
rest=${rest#*|}
|
|
||||||
destfileid=${rest%%|*}
|
|
||||||
rest=${rest#*|}
|
|
||||||
destfilename=${rest%%|*}
|
|
||||||
rest=${rest#*|}
|
|
||||||
for key in ${!cmd_arg[@]}
|
|
||||||
do
|
|
||||||
[ -z "${cmd_arg[key]}" ] && unset cmd_arg[key]
|
|
||||||
done
|
|
||||||
(( debug >= 2 )) && echo "${cmd_arg[@]}" >>"$tempdir/errors.log"
|
|
||||||
if "${cmd_arg[@]}" >/dev/null 2>>"$tempdir/errors.log"
|
|
||||||
then
|
|
||||||
echo "finished $taskid|$sourcefileid|$destfileid|$destfilename"
|
|
||||||
read line
|
|
||||||
until [[ $line == AtOM:OK ]]
|
|
||||||
do
|
|
||||||
echo "finished $taskid|$sourcefileid|$destfileid|$destfilename"
|
|
||||||
read line
|
|
||||||
done
|
|
||||||
else
|
|
||||||
echo "failed $taskid"
|
|
||||||
read line
|
|
||||||
until [[ $line == AtOM:OK ]]
|
|
||||||
do
|
|
||||||
echo "failed $taskid"
|
|
||||||
read line
|
|
||||||
done
|
|
||||||
[ -n "$filename" ] \
|
|
||||||
&& eval rm -f $filename
|
|
||||||
fi
|
|
||||||
unset cmd_arg
|
|
||||||
if [ -n "$cleanup" -a -n "$required" ]
|
|
||||||
then
|
|
||||||
echo "cleanup $required"
|
|
||||||
read answer
|
|
||||||
until [[ $answer != AtOM:ComFail ]]
|
|
||||||
do
|
|
||||||
echo "cleanup $required"
|
|
||||||
read answer
|
|
||||||
done
|
|
||||||
if (( answer == 1 ))
|
|
||||||
then
|
|
||||||
eval rm -f $cleanup
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
master() {
|
master() {
|
||||||
for workerid in ${!workers[@]}
|
if (( active >= concurrency)) || [ -n "$quit" ]
|
||||||
do
|
then
|
||||||
if read -t0.001 -u$((200+workerid)) workercommand workerquery
|
sleep 0.1
|
||||||
|
else
|
||||||
|
echo '
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM tasks
|
||||||
|
WHERE status = 0;
|
||||||
|
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM tasks
|
||||||
|
WHERE status = 0
|
||||||
|
AND requires is NULL;
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
source_file,
|
||||||
|
required,
|
||||||
|
cmd_arg0,
|
||||||
|
cmd_arg1,
|
||||||
|
cmd_arg2,
|
||||||
|
cmd_arg3,
|
||||||
|
cmd_arg4,
|
||||||
|
cmd_arg5,
|
||||||
|
cmd_arg6,
|
||||||
|
cmd_arg7,
|
||||||
|
cmd_arg8,
|
||||||
|
cmd_arg9,
|
||||||
|
cmd_arg10,
|
||||||
|
cmd_arg11,
|
||||||
|
cmd_arg12,
|
||||||
|
cmd_arg13,
|
||||||
|
cmd_arg14,
|
||||||
|
cmd_arg15,
|
||||||
|
cmd_arg16,
|
||||||
|
cmd_arg17,
|
||||||
|
cmd_arg18,
|
||||||
|
cmd_arg19,
|
||||||
|
cmd_arg20,
|
||||||
|
cmd_arg21,
|
||||||
|
cmd_arg22,
|
||||||
|
cmd_arg23,
|
||||||
|
cmd_arg24,
|
||||||
|
cmd_arg25,
|
||||||
|
cmd_arg26,
|
||||||
|
cmd_arg27,
|
||||||
|
cmd_arg28,
|
||||||
|
cmd_arg29,
|
||||||
|
cleanup,
|
||||||
|
fileid,
|
||||||
|
filename
|
||||||
|
FROM tasks
|
||||||
|
WHERE status = 0
|
||||||
|
AND requires is NULL
|
||||||
|
ORDER BY source_file
|
||||||
|
LIMIT 1;
|
||||||
|
' >&3
|
||||||
|
read -u4 remaining
|
||||||
|
read -u4 ready
|
||||||
|
if (( remaining == 0 ))
|
||||||
then
|
then
|
||||||
break
|
sleep 0.1
|
||||||
|
continue
|
||||||
|
elif (( ready == 0 ))
|
||||||
|
then
|
||||||
|
sleep 0.1
|
||||||
|
else
|
||||||
|
(( ++active ))
|
||||||
|
read -u4 line
|
||||||
|
taskid=${line%%|*}
|
||||||
|
rest="${line#*|}|"
|
||||||
|
sourcefileid=${rest%%|*}
|
||||||
|
rest=${rest#*|}
|
||||||
|
required=${rest%%|*}
|
||||||
|
rest=${rest#*|}
|
||||||
|
cmd_arg=("${rest%%|*}")
|
||||||
|
rest=${rest#*|}
|
||||||
|
cmd_arg+=("${rest%%|*}")
|
||||||
|
rest=${rest#*|}
|
||||||
|
cmd_arg+=("${rest%%|*}")
|
||||||
|
rest=${rest#*|}
|
||||||
|
cmd_arg+=("${rest%%|*}")
|
||||||
|
rest=${rest#*|}
|
||||||
|
cmd_arg+=("${rest%%|*}")
|
||||||
|
rest=${rest#*|}
|
||||||
|
cmd_arg+=("${rest%%|*}")
|
||||||
|
rest=${rest#*|}
|
||||||
|
cmd_arg+=("${rest%%|*}")
|
||||||
|
rest=${rest#*|}
|
||||||
|
cmd_arg+=("${rest%%|*}")
|
||||||
|
rest=${rest#*|}
|
||||||
|
cmd_arg+=("${rest%%|*}")
|
||||||
|
rest=${rest#*|}
|
||||||
|
cmd_arg+=("${rest%%|*}")
|
||||||
|
rest=${rest#*|}
|
||||||
|
cmd_arg+=("${rest%%|*}")
|
||||||
|
rest=${rest#*|}
|
||||||
|
cmd_arg+=("${rest%%|*}")
|
||||||
|
rest=${rest#*|}
|
||||||
|
cmd_arg+=("${rest%%|*}")
|
||||||
|
rest=${rest#*|}
|
||||||
|
cmd_arg+=("${rest%%|*}")
|
||||||
|
rest=${rest#*|}
|
||||||
|
cmd_arg+=("${rest%%|*}")
|
||||||
|
rest=${rest#*|}
|
||||||
|
cmd_arg+=("${rest%%|*}")
|
||||||
|
rest=${rest#*|}
|
||||||
|
cmd_arg+=("${rest%%|*}")
|
||||||
|
rest=${rest#*|}
|
||||||
|
cmd_arg+=("${rest%%|*}")
|
||||||
|
rest=${rest#*|}
|
||||||
|
cmd_arg+=("${rest%%|*}")
|
||||||
|
rest=${rest#*|}
|
||||||
|
cmd_arg+=("${rest%%|*}")
|
||||||
|
rest=${rest#*|}
|
||||||
|
cmd_arg+=("${rest%%|*}")
|
||||||
|
rest=${rest#*|}
|
||||||
|
cmd_arg+=("${rest%%|*}")
|
||||||
|
rest=${rest#*|}
|
||||||
|
cmd_arg+=("${rest%%|*}")
|
||||||
|
rest=${rest#*|}
|
||||||
|
cmd_arg+=("${rest%%|*}")
|
||||||
|
rest=${rest#*|}
|
||||||
|
cmd_arg+=("${rest%%|*}")
|
||||||
|
rest=${rest#*|}
|
||||||
|
cmd_arg+=("${rest%%|*}")
|
||||||
|
rest=${rest#*|}
|
||||||
|
cmd_arg+=("${rest%%|*}")
|
||||||
|
rest=${rest#*|}
|
||||||
|
cmd_arg+=("${rest%%|*}")
|
||||||
|
rest=${rest#*|}
|
||||||
|
cmd_arg+=("${rest%%|*}")
|
||||||
|
rest=${rest#*|}
|
||||||
|
cmd_arg+=("${rest%%|*}")
|
||||||
|
rest=${rest#*|}
|
||||||
|
cleanup=${rest%%|*}
|
||||||
|
rest=${rest#*|}
|
||||||
|
destfileid=${rest%%|*}
|
||||||
|
rest=${rest#*|}
|
||||||
|
destfilename=${rest%%|*}
|
||||||
|
rest=${rest#*|}
|
||||||
|
for key in ${!cmd_arg[@]}
|
||||||
|
do
|
||||||
|
[ -z "${cmd_arg[key]}" ] && unset cmd_arg[key]
|
||||||
|
done
|
||||||
|
workerid=$(getworkerid)
|
||||||
|
workertasks[workerid]=$taskid
|
||||||
|
Update tasks status 1 <<<"id = $taskid"
|
||||||
|
createworker $workerid
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
getworkerid() {
|
||||||
|
local i
|
||||||
|
for (( i=0 ; i >= 0 ; i++ ))
|
||||||
|
do
|
||||||
|
if [ -z "${workers[i]}" ]
|
||||||
|
then
|
||||||
|
echo $i
|
||||||
|
return
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
(( ${#workers[@]} == 0 )) && break
|
# If we reach this, we have reached the signed long limit
|
||||||
if [ -n "$workercommand" ]
|
# (2^63 - 1 = 9223372036854775807 - Got a supercomputer?)
|
||||||
then
|
(( concurrency-- ))
|
||||||
case $workercommand in
|
}
|
||||||
'work')
|
|
||||||
if [ -n "$quit" ]
|
|
||||||
then
|
|
||||||
dyingworker=${workers[workerid]}
|
|
||||||
unset workers[workerid]
|
|
||||||
eval echo AtOM:Die '>&'$((100+workerid))
|
|
||||||
wait $dyingworker
|
|
||||||
eval $((100+workerid))'>&-'
|
|
||||||
eval $((200+workerid))'<&-'
|
|
||||||
rm "$tempdir"/worker${workerid}{in,out}
|
|
||||||
elif (( active < concurrency ))
|
|
||||||
then
|
|
||||||
echo '
|
|
||||||
SELECT COUNT(*)
|
|
||||||
FROM tasks
|
|
||||||
WHERE status = 0;
|
|
||||||
|
|
||||||
SELECT COUNT(*)
|
createworker() {
|
||||||
FROM tasks
|
worker $1 &
|
||||||
WHERE status = 0
|
workers[$1]=$!
|
||||||
AND requires is NULL;
|
}
|
||||||
|
|
||||||
SELECT
|
destroyworker() {
|
||||||
id,
|
dyingworker=${workers[$1]}
|
||||||
source_file,
|
unset workers[$1]
|
||||||
required,
|
wait $dyingworker
|
||||||
cmd_arg0,
|
}
|
||||||
cmd_arg1,
|
|
||||||
cmd_arg2,
|
gettaskinfos() {
|
||||||
cmd_arg3,
|
echo '
|
||||||
cmd_arg4,
|
SELECT
|
||||||
cmd_arg5,
|
id,
|
||||||
cmd_arg6,
|
source_file,
|
||||||
cmd_arg7,
|
required,
|
||||||
cmd_arg8,
|
cleanup,
|
||||||
cmd_arg9,
|
fileid,
|
||||||
cmd_arg10,
|
filename
|
||||||
cmd_arg11,
|
FROM tasks
|
||||||
cmd_arg12,
|
WHERE id='$1';
|
||||||
cmd_arg13,
|
' >&3
|
||||||
cmd_arg14,
|
read -u4 line
|
||||||
cmd_arg15,
|
taskid=${line%%|*}
|
||||||
cmd_arg16,
|
rest="${line#*|}|"
|
||||||
cmd_arg17,
|
sourcefileid=${rest%%|*}
|
||||||
cmd_arg18,
|
rest=${rest#*|}
|
||||||
cmd_arg19,
|
required=${rest%%|*}
|
||||||
cmd_arg20,
|
rest=${rest#*|}
|
||||||
cmd_arg21,
|
cleanup=${rest%%|*}
|
||||||
cmd_arg22,
|
rest=${rest#*|}
|
||||||
cmd_arg23,
|
destfileid=${rest%%|*}
|
||||||
cmd_arg24,
|
rest=${rest#*|}
|
||||||
cmd_arg25,
|
destfilename=${rest%%|*}
|
||||||
cmd_arg26,
|
rest=${rest#*|}
|
||||||
cmd_arg27,
|
}
|
||||||
cmd_arg28,
|
|
||||||
cmd_arg29,
|
cleaner() {
|
||||||
cleanup,
|
for key in ${!failedtasks[@]}
|
||||||
fileid,
|
do
|
||||||
filename
|
taskid=${failedtasks[key]}
|
||||||
FROM tasks
|
gettaskinfos $taskid
|
||||||
WHERE status = 0
|
faildepends=$(
|
||||||
AND requires is NULL
|
Select tasks 'COUNT(*)' <<-EOWhere
|
||||||
ORDER BY source_file
|
requires = $taskid
|
||||||
LIMIT 1;
|
EOWhere
|
||||||
' >&3
|
)
|
||||||
read -u4 remaining
|
(( failed+=faildepends ))
|
||||||
read -u4 ready
|
Update tasks status 2 <<<"id = $taskid"
|
||||||
if (( remaining == 0 ))
|
Update tasks status 2 <<<"requires = $taskid"
|
||||||
then
|
echo "SELECT COUNT(*)
|
||||||
dyingworker=${workers[workerid]}
|
FROM tasks
|
||||||
unset workers[workerid]
|
WHERE ( status = 0 OR status = 1 )
|
||||||
eval echo AtOM:Die '>&'$((100+workerid))
|
AND required = $taskid;">&3
|
||||||
wait $dyingworker
|
read -u4 count
|
||||||
eval $((100+workerid))'>&-'
|
if (( count == 0 ))
|
||||||
eval $((200+workerid))'<&-'
|
then
|
||||||
rm "$tempdir"/worker${workerid}{in,out}
|
rm -f "$cleanup"
|
||||||
continue
|
fi
|
||||||
elif (( ready == 0 ))
|
unset failedtasks[key]
|
||||||
then
|
done
|
||||||
line=AtOM:Sleep
|
for key in ${!finishedtasks[@]}
|
||||||
else
|
do
|
||||||
(( ++active ))
|
taskid=${finishedtasks[key]}
|
||||||
read -u4 line
|
gettaskinfos $taskid
|
||||||
taskid=${line%%|*}
|
if [ -n "$destfilename" ]
|
||||||
Update tasks status 1 <<<"id = $taskid"
|
then
|
||||||
fi
|
echo \
|
||||||
eval echo '"$line" >&'$((100+workerid))
|
"UPDATE destination_files" \
|
||||||
else
|
"SET filename=\"${destfilename//\"/\"\"}\"," \
|
||||||
dyingworker=${workers[workerid]}
|
" last_change=(" \
|
||||||
unset workers[workerid]
|
" SELECT last_change" \
|
||||||
eval echo AtOM:Die '>&'$((100+workerid))
|
" FROM source_files" \
|
||||||
wait $dyingworker
|
" WHERE id=$sourcefileid" \
|
||||||
eval $((100+workerid))'>&-'
|
" )," \
|
||||||
eval $((200+workerid))'<&-'
|
" old_filename=(" \
|
||||||
rm "$tempdir"/worker${workerid}{in,out}
|
" SELECT filename" \
|
||||||
fi
|
" FROM destination_files" \
|
||||||
;;
|
" WHERE id=$destfileid" \
|
||||||
'finished')
|
" )," \
|
||||||
eval 'echo AtOM:OK >&'$((workerid+100))
|
" rename_pattern=(" \
|
||||||
(( active-- )) || true
|
" SELECT rename_pattern" \
|
||||||
taskid=${workerquery%%|*}
|
" FROM tasks" \
|
||||||
rest="${workerquery#*|}|"
|
" WHERE id=$taskid" \
|
||||||
sourcefileid=${rest%%|*}
|
" )" \
|
||||||
rest=${rest#*|}
|
"WHERE id=$destfileid;" \
|
||||||
destfileid=${rest%%|*}
|
>&3
|
||||||
rest=${rest#*|}
|
fi
|
||||||
destfilename=${rest%%|*}
|
echo "SELECT COUNT(*)
|
||||||
Delete tasks <<<"id = $taskid"
|
FROM tasks
|
||||||
if [ -n "$destfilename" ]
|
WHERE ( status = 0 OR status = 1 )
|
||||||
then
|
AND required = $taskid;">&3
|
||||||
echo \
|
read -u4 count
|
||||||
"UPDATE destination_files" \
|
if (( count == 0 ))
|
||||||
"SET filename=\"${destfilename//\"/\"\"}\"," \
|
then
|
||||||
" last_change=(" \
|
rm -f "$cleanup"
|
||||||
" SELECT last_change" \
|
fi
|
||||||
" FROM source_files" \
|
Delete tasks <<<"id = $taskid"
|
||||||
" WHERE id=$sourcefileid" \
|
unset finishedtasks[key]
|
||||||
" )," \
|
done
|
||||||
" old_filename=(" \
|
|
||||||
" SELECT filename" \
|
|
||||||
" FROM destination_files" \
|
|
||||||
" WHERE id=$destfileid" \
|
|
||||||
" )," \
|
|
||||||
" rename_pattern=(" \
|
|
||||||
" SELECT rename_pattern" \
|
|
||||||
" FROM tasks" \
|
|
||||||
" WHERE id=$taskid" \
|
|
||||||
" )" \
|
|
||||||
"WHERE id=$destfileid;" \
|
|
||||||
>&3
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
'failed')
|
|
||||||
eval 'echo AtOM:OK >&'$((workerid+100))
|
|
||||||
(( --active )) || true
|
|
||||||
(( ++failed ))
|
|
||||||
taskid=$workerquery
|
|
||||||
faildepends=$(
|
|
||||||
Select tasks 'COUNT(*)' <<-EOWhere
|
|
||||||
requires = taskid
|
|
||||||
EOWhere
|
|
||||||
)
|
|
||||||
(( failed+=faildepends ))
|
|
||||||
Update tasks status 2 <<<"id = $taskid"
|
|
||||||
Update tasks status 2 <<<"requires = $taskid"
|
|
||||||
;;
|
|
||||||
'cleanup')
|
|
||||||
required=$workerquery
|
|
||||||
echo "SELECT COUNT(*)
|
|
||||||
FROM tasks
|
|
||||||
WHERE ( status = 0 OR status = 1 )
|
|
||||||
AND required = $required;">&3
|
|
||||||
read -u4 count
|
|
||||||
if (( count == 0 ))
|
|
||||||
then
|
|
||||||
eval echo 1 '>&'$((100+workerid))
|
|
||||||
else
|
|
||||||
eval echo 0 '>&'$((100+workerid))
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
eval 'echo "AtOM:ComFail" >&'$((100+workerid))
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
checkworkers() {
|
checkworkers() {
|
||||||
for key in ${!workers[@]}
|
for key in ${!workers[@]}
|
||||||
do
|
do
|
||||||
if ! kill -0 ${workers[key]}
|
if ! kill -0 ${workers[key]} 2>/dev/null
|
||||||
then
|
then
|
||||||
worker $key \
|
taskid=${workertasks[key]}
|
||||||
<"$tempdir"/worker${key}in \
|
(( ++ran ))
|
||||||
>"$tempdir"/worker${key}out &
|
(( active-- ))
|
||||||
workers[key]=$!
|
if destroyworker $key
|
||||||
eval exec $((100+key))'>"$tempdir"/worker${key}in'
|
then
|
||||||
eval exec $((200+key))'<"$tempdir"/worker${key}out'
|
finishedtasks+=($taskid)
|
||||||
(( ++failed ))
|
else
|
||||||
|
failedtasks+=($taskid)
|
||||||
|
(( ++failed ))
|
||||||
|
fi
|
||||||
|
unset workertasks[key]
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
@ -2075,28 +2067,21 @@ done
|
|||||||
echo 'COMMIT;' >&3
|
echo 'COMMIT;' >&3
|
||||||
echo -e "\rCreated ${count:-0} tasks for $filecount files (${copies:-0} immediate copies)"
|
echo -e "\rCreated ${count:-0} tasks for $filecount files (${copies:-0} immediate copies)"
|
||||||
|
|
||||||
masterpid=$$
|
|
||||||
trap checkworkers USR1 ALRM
|
|
||||||
rm -f "$tempdir"/worker*
|
|
||||||
concurrency=$(( maxload / 2 ))
|
concurrency=$(( maxload / 2 ))
|
||||||
(( concurrency )) || concurrency=1
|
(( concurrency )) || concurrency=1
|
||||||
active=0
|
active=0
|
||||||
|
#set -x
|
||||||
for (( i=0 ; i < concurrency ; i++ ))
|
for (( i=0 ; i < concurrency ; i++ ))
|
||||||
do
|
do
|
||||||
(( ++wnum ))
|
master
|
||||||
mkfifo "$tempdir"/worker${wnum}{in,out}
|
|
||||||
worker $wnum <"$tempdir"/worker${wnum}in >"$tempdir"/worker${wnum}out &
|
|
||||||
workers[wnum]=$!
|
|
||||||
eval exec $((100+wnum))'>"$tempdir"/worker${wnum}in'
|
|
||||||
eval exec $((200+wnum))'<"$tempdir"/worker${wnum}out'
|
|
||||||
done
|
done
|
||||||
concurrencychange=$(date +%s)
|
concurrencychange=$(date +%s)
|
||||||
starttime=$concurrencychange
|
starttime=$concurrencychange
|
||||||
taskcount=$count
|
taskcount=$count
|
||||||
failed=0
|
failed=0
|
||||||
while :
|
while (( ${#workers[@]} ))
|
||||||
do
|
do
|
||||||
if read -n 1 -t 0.01 userinput
|
if read -n 1 -t 0.1 userinput
|
||||||
then
|
then
|
||||||
case $userinput in
|
case $userinput in
|
||||||
'+')
|
'+')
|
||||||
@ -2123,27 +2108,20 @@ do
|
|||||||
then
|
then
|
||||||
concurrencychange=$(date +%s)
|
concurrencychange=$(date +%s)
|
||||||
(( ++concurrency ))
|
(( ++concurrency ))
|
||||||
(( ++wnum ))
|
|
||||||
mkfifo "$tempdir"/worker${wnum}{in,out}
|
|
||||||
worker $wnum \
|
|
||||||
<"$tempdir"/worker${wnum}in \
|
|
||||||
>"$tempdir"/worker${wnum}out &
|
|
||||||
workers[wnum]=$!
|
|
||||||
eval exec $((100+wnum))'>"$tempdir"/worker${wnum}in'
|
|
||||||
eval exec $((200+wnum))'<"$tempdir"/worker${wnum}out'
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
checkworkers
|
||||||
|
cleaner
|
||||||
master
|
master
|
||||||
if ((taskcount - remaining))
|
if (( ran ))
|
||||||
then
|
then
|
||||||
currenttime=$(date +%s)
|
currenttime=$(date +%s)
|
||||||
secsremaining=$((
|
avgduration=$((
|
||||||
remaining
|
((currenttime - starttime) * 1000)
|
||||||
*
|
|
||||||
(currenttime - starttime)
|
|
||||||
/
|
/
|
||||||
(taskcount - remaining)
|
ran
|
||||||
))
|
))
|
||||||
|
secsremaining=$(( remaining * avgduration / 1000 ))
|
||||||
(( days =
|
(( days =
|
||||||
secsremaining
|
secsremaining
|
||||||
/
|
/
|
||||||
@ -2159,12 +2137,28 @@ do
|
|||||||
/
|
/
|
||||||
60
|
60
|
||||||
)) || true
|
)) || true
|
||||||
|
(( seconds =
|
||||||
|
secsremaining
|
||||||
|
-
|
||||||
|
( ( ( ( days*24 + hours ) *60 ) + minutes ) *60 )
|
||||||
|
)) || true
|
||||||
|
avgduration=$(printf %04i $avgduration)
|
||||||
|
avgdsec=${avgduration:0:-3}
|
||||||
|
avgdmsec=${avgduration#$avgdsec}
|
||||||
fi
|
fi
|
||||||
echo -en "\rload: $humanload / $maxload" \
|
dran=$(printf %${#taskcount}i ${ran:-0})
|
||||||
"workers: $active / $concurrency" \
|
rtime=$(
|
||||||
"done: $(( (taskcount - remaining ) * 100 / taskcount ))%" \
|
printf '%2id %2ih%02im%02is' \
|
||||||
"- $((taskcount - remaining)) of $taskcount ($failed failed)" \
|
${days:-0} \
|
||||||
"${days}d ${hours}h${minutes}m "
|
${hours:-0} \
|
||||||
|
${minutes:-0} \
|
||||||
|
${seconds:-0}
|
||||||
|
)
|
||||||
|
percent=$(printf %3i $((ran * 100 / taskcount)))
|
||||||
|
echo -en "\rL: $humanload/$maxload" \
|
||||||
|
"W: $active/$concurrency" \
|
||||||
|
"T: ${dran}/$taskcount (F:$failed) $percent% $rtime" \
|
||||||
|
"(A: ${avgdsec:--}.${avgdmsec:--}s/task)"
|
||||||
done
|
done
|
||||||
unset count
|
unset count
|
||||||
|
|
||||||
@ -2192,7 +2186,7 @@ endtime=$(date +%s)
|
|||||||
( ( ( ( days*24 + hours ) *60 ) + minutes ) *60 )
|
( ( ( ( days*24 + hours ) *60 ) + minutes ) *60 )
|
||||||
)) || true
|
)) || true
|
||||||
|
|
||||||
echo -e "\rRan $taskcount tasks, $failed of which failed, in $days" \
|
echo -e "\rRan ${ran:=0} tasks, $failed of which failed, in $days" \
|
||||||
"days, $hours hours, $minutes minutes and $seconds seconds."
|
"days, $hours hours, $minutes minutes and $seconds seconds."
|
||||||
|
|
||||||
if [ -n "$quit" ]
|
if [ -n "$quit" ]
|
||||||
@ -2207,6 +2201,8 @@ do
|
|||||||
echo '
|
echo '
|
||||||
SELECT
|
SELECT
|
||||||
destination_files.filename,
|
destination_files.filename,
|
||||||
|
destination_files.id,
|
||||||
|
source_files.filename,
|
||||||
tags.album,
|
tags.album,
|
||||||
tags.albumartist,
|
tags.albumartist,
|
||||||
tags.artist,
|
tags.artist,
|
||||||
@ -2224,11 +2220,15 @@ do
|
|||||||
INNER JOIN tags
|
INNER JOIN tags
|
||||||
ON destination_files.source_file_id
|
ON destination_files.source_file_id
|
||||||
=tags.source_file
|
=tags.source_file
|
||||||
|
INNER JOIN source_files
|
||||||
|
ON destination_files.source_file_id
|
||||||
|
=source_files.id
|
||||||
WHERE destinations.name="'"$destination"'"
|
WHERE destinations.name="'"$destination"'"
|
||||||
AND (destination_files.rename_pattern
|
AND (destination_files.rename_pattern
|
||||||
!=
|
!=
|
||||||
"'"${destinationrenamepath[$destination]}/${destinationrename[$destination]}"'"
|
"'"${destinationrenamepath[$destination]}/${destinationrename[$destination]}:${destinationfat32compat["$destination"]}"'"
|
||||||
OR destination_files.rename_pattern is NULL)
|
OR destination_files.rename_pattern is NULL)
|
||||||
|
AND destination_files.last_change > 0
|
||||||
;
|
;
|
||||||
|
|
||||||
SELECT "AtOM:NoMoreFiles";
|
SELECT "AtOM:NoMoreFiles";
|
||||||
@ -2246,6 +2246,10 @@ do
|
|||||||
do
|
do
|
||||||
oldfilename=${line%%|*}
|
oldfilename=${line%%|*}
|
||||||
rest=${line#*|}'|'
|
rest=${line#*|}'|'
|
||||||
|
destfileid=${rest%%|*}
|
||||||
|
rest=${rest#*|}
|
||||||
|
filename=${rest%%|*}
|
||||||
|
rest=${rest#*|}
|
||||||
album=${rest%%|*}
|
album=${rest%%|*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*|}
|
||||||
albumartist=${rest%%|*}
|
albumartist=${rest%%|*}
|
||||||
@ -2271,16 +2275,21 @@ do
|
|||||||
getDestDir
|
getDestDir
|
||||||
getDestFile
|
getDestFile
|
||||||
destfilename="$destdir/$destfile.$extension"
|
destfilename="$destdir/$destfile.$extension"
|
||||||
mv "$oldfilename" "$destfilename"
|
if [[ $oldfilename != $destfilename ]]
|
||||||
|
then
|
||||||
|
mv "$oldfilename" "$destfilename"
|
||||||
|
progressSpin
|
||||||
|
fi
|
||||||
echo "UPDATE destination_files" \
|
echo "UPDATE destination_files" \
|
||||||
"SET filename=\"${destfilename//\"/\"\"}\"," \
|
"SET filename=\"${destfilename//\"/\"\"}\"," \
|
||||||
" rename_pattern=" \
|
" rename_pattern=" \
|
||||||
"\"${destinationrenamepath[$destination]}/${destinationrename[$destination]}\"" \
|
"\"${destinationrenamepath[$destination]}/${destinationrename[$destination]}:${destinationfat32compat["$destination"]}\"" \
|
||||||
"WHERE id=$destfileid;" \
|
"WHERE id=$destfileid;" \
|
||||||
>&3
|
>&3
|
||||||
progressSpin
|
|
||||||
fi
|
fi
|
||||||
|
read -u4 line
|
||||||
done
|
done
|
||||||
|
echo $'\r'"$destination: Renamed ${count:-0} files "
|
||||||
fi
|
fi
|
||||||
unset count
|
unset count
|
||||||
done
|
done
|
||||||
|
|||||||
@ -66,6 +66,8 @@ Sections:
|
|||||||
%{track},
|
%{track},
|
||||||
%{year}.
|
%{year}.
|
||||||
Untagged files or files in unrecognized formats will not be changed.
|
Untagged files or files in unrecognized formats will not be changed.
|
||||||
|
* fat32compat <yes>/<no>: Rename files for compatibility with FAT32
|
||||||
|
filesystems.
|
||||||
* skip_mime-type <mime-type>: Files with mime-type <mime-type> will not
|
* skip_mime-type <mime-type>: Files with mime-type <mime-type> will not
|
||||||
be included in that destination. For more than one mime-type, use multiple
|
be included in that destination. For more than one mime-type, use multiple
|
||||||
times, as needed. The '*' character is a wildcard.
|
times, as needed. The '*' character is a wildcard.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user