Merge branch 'master' into video
This commit is contained in:
commit
95e7bbbbf6
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
*.ex
|
||||
*.EX
|
||||
trace.log
|
||||
47
README
47
README
@ -19,21 +19,26 @@ Required:
|
||||
Optional:
|
||||
* vorbis-tools
|
||||
http://www.vorbis.com/
|
||||
* ogginfo (Ogg Vorbis tags support)
|
||||
* oggenc (Ogg Vorbis destination)
|
||||
* ogginfo (Ogg Vorbis metadata)
|
||||
* oggenc (Ogg Vorbis encoding)
|
||||
* opus-tools
|
||||
http://opus-codec.org/
|
||||
* opusinfo (Opus tags support)
|
||||
* opusenc (Opus destination)
|
||||
* opusinfo (Opus metadata)
|
||||
* opusenc (Opus encoding)
|
||||
* opusdec (Opus decoding)
|
||||
* LAME MP3 Encoder
|
||||
http://lame.sourceforge.net/
|
||||
* lame (MP3 destination)
|
||||
* lame (MP3 encoding)
|
||||
* FLAC
|
||||
http://flac.sourceforge.net/
|
||||
* metaflac (FLAC tags support)
|
||||
* metaflac (FLAC metadata)
|
||||
* Musepack
|
||||
http://www.musepack.net/
|
||||
* mpcdec (Musepack decoding)
|
||||
* FFmpeg
|
||||
http://ffmpeg.org/
|
||||
* ffprobe (ID3v2, Musepack, Windows Media and video metadata)
|
||||
* ffmpeg (Windows Media and video decoding)
|
||||
|
||||
==================
|
||||
Using the software
|
||||
@ -41,3 +46,33 @@ Using the software
|
||||
Configuration:
|
||||
Please read doc/config before anything else.
|
||||
|
||||
====
|
||||
Toys
|
||||
----
|
||||
AtOM requires a database to function. Now that we have a database containing
|
||||
various information about our media files, why not use it?
|
||||
AtOM comes with a small set of tools in the toys/ directory. These are
|
||||
documented in toys/README.
|
||||
|
||||
========================
|
||||
Shameless Self Promotion
|
||||
------------------------
|
||||
I am the author of free (Creative Commons CC-By-SA) music which you can stream
|
||||
for free, or buy to get high quality and bonuses from Bandcamp
|
||||
(http://djblackred.bandcamp.com). If you like electronic music taking its
|
||||
inspiration from Trance, Drum & Bass, Ambient and (rarely) Free Jazz, please
|
||||
check it out!
|
||||
Downloads are available in FLAC, Ogg, MP3, and more, and includes the "source
|
||||
code" (sequencer files and the likes) for most tracks.
|
||||
I am receiving 85% of the money you'll spend, so you won't be feeding some
|
||||
greedy BigCorp producer or distributor.
|
||||
And if you don't like it, you can still spread the word to friends who may like.
|
||||
You can see this as a way to thank me for this piece of code.
|
||||
|
||||
=====
|
||||
Legal
|
||||
-----
|
||||
Some of the format and/or tool names cited above are trademarks belonging to
|
||||
their rightful owners. AtOM and its authors are not linked in any way to
|
||||
those companies or individuals. Said companies do not endorse nor support
|
||||
AtOM in any way.
|
||||
|
||||
396
atom
396
atom
@ -96,8 +96,6 @@ do
|
||||
esac
|
||||
done
|
||||
|
||||
#FIXME: check sanity
|
||||
|
||||
if [ ! -f "$cffile" ]
|
||||
then
|
||||
if [ ! -d ~/.atom ]
|
||||
@ -117,9 +115,143 @@ fi
|
||||
getConfig
|
||||
|
||||
set +H
|
||||
|
||||
# Apply CLI overrides
|
||||
[ -n "$cliload" ] && maxload=$cliload
|
||||
[ -n "$cliltimer" ] && loadinterval=$cliltimer
|
||||
|
||||
(( debug || cfgdump )) && printConfig
|
||||
(( cfgdump )) && exit
|
||||
|
||||
# check sanity
|
||||
if [ ! -d "$tempdir" ] && ! mkdir -p "$tempdir"
|
||||
then
|
||||
echo "[FATAL] Could not create temp directory $tempdir" >&2
|
||||
(( sanityfail++ ))
|
||||
fi
|
||||
if [ ! -f "$database" ] && [ ! -d "${database%/*}" ] && ! mkdir -p "${database%/*}"
|
||||
then
|
||||
echo "[FATAL] Directory holding database file does not exist and could" \
|
||||
"not be created" >&2
|
||||
(( sanityfail++ ))
|
||||
fi
|
||||
if [ ! -d "$sourcepath" ]
|
||||
then
|
||||
echo "[FATAL] Source path $sourcepath does not exist or is not a directory" >&2
|
||||
(( sanityfail++ ))
|
||||
fi
|
||||
if ! which sed >/dev/null
|
||||
then
|
||||
echo "[FATAL] Required tool sed is not installed or not in PATH
|
||||
I never thought this would actually hit someone..." >&2
|
||||
(( sanityfail++ ))
|
||||
fi
|
||||
if ! which sox >/dev/null
|
||||
then
|
||||
echo "[FATAL] Required tool sox is not installed or not in PATH" >&2
|
||||
(( sanityfail++ ))
|
||||
fi
|
||||
if ! which ogginfo >/dev/null
|
||||
then
|
||||
echo "[WARNING] Tool ogginfo (from vorbis-tools) is not" \
|
||||
"installed or not in PATH
|
||||
Vorbis metadata disabled" >&2
|
||||
disableogginfo=1
|
||||
(( sanitywarn++ ))
|
||||
fi
|
||||
if (( oggencneeded )) && ! which oggenc >/dev/null
|
||||
then
|
||||
echo "[WARNING] Tool oggenc (from vorbis-tools) is not" \
|
||||
"installed or not in PATH
|
||||
Vorbis targets disabled" >&2
|
||||
disableoggenc=1
|
||||
(( sanitywarn++ ))
|
||||
fi
|
||||
if ! which opusinfo >/dev/null
|
||||
then
|
||||
echo "[WARNING] Tool opusinfo (from opus-tools) is not" \
|
||||
"installed or not in PATH
|
||||
Opus metadata disabled" >&2
|
||||
disableopusinfo=1
|
||||
(( sanitywarn++ ))
|
||||
fi
|
||||
if (( opusencneeded )) && ! which opusenc >/dev/null
|
||||
then
|
||||
echo "[WARNING] Tool opusenc (from opus-tools) is not" \
|
||||
"installed or not in PATH
|
||||
Opus targets disabled" >&2
|
||||
disableopusenc=1
|
||||
(( sanitywarn++ ))
|
||||
fi
|
||||
if ! which opusdec >/dev/null
|
||||
then
|
||||
echo "[WARNING] Tool opusdec (from opus-tools) is not" \
|
||||
"installed or not in PATH
|
||||
Opus support disabled" >&2
|
||||
disableopusdec=1
|
||||
(( sanitywarn++ ))
|
||||
fi
|
||||
if (( lameneeded )) && ! which lame >/dev/null
|
||||
then
|
||||
echo "[WARNING] Tool lame is not installed or not in PATH
|
||||
MP3 targets disabled" >&2
|
||||
disablelame=1
|
||||
(( sanitywarn++ ))
|
||||
fi
|
||||
if ! which metaflac >/dev/null
|
||||
then
|
||||
echo "[WARNING] Tool metaflac (from FLAC) is not installed" \
|
||||
"or not in PATH
|
||||
FLAC metadata disabled" >&2
|
||||
disableflac=1
|
||||
(( sanitywarn++ ))
|
||||
fi
|
||||
if ! which mpcdec >/dev/null
|
||||
then
|
||||
echo "[WARNING] Tool mpcdec (from Musepack) is not" \
|
||||
"installed or not in PATH
|
||||
Musepack support disabled" >&2
|
||||
disablempcdec=1
|
||||
(( sanitywarn++ ))
|
||||
fi
|
||||
if ! which ffprobe >/dev/null
|
||||
then
|
||||
echo "[WARNING] Tool ffprobe (from FFmpeg) is not installed or not in PATH
|
||||
Video metadata disabled
|
||||
MPEG metadata disabled
|
||||
MusePack metadata disabled
|
||||
Unknown format metadata disabled" >&2
|
||||
disableffprobe=1
|
||||
(( sanitywarn++ ))
|
||||
fi
|
||||
if ! which ffmpeg >/dev/null
|
||||
then
|
||||
echo "[WARNING] Tool ffmpeg is not installed or not in PATH
|
||||
Video support disabled" >&2
|
||||
disablevideo=1
|
||||
(( sanitywarn++ ))
|
||||
fi
|
||||
if (( sanityfail ))
|
||||
then
|
||||
echo "
|
||||
Sanity checks raised ${sanitywarn:-0} warnings, $sanityfail failures. Dying now." >&2
|
||||
exit $ESANITY
|
||||
elif (( sanitywarn ))
|
||||
then
|
||||
echo "
|
||||
Sanity checks raised $sanitywarn warnings... Hit Control-C to abort." >&2
|
||||
timeout=$(( sanitywarn * 10 ))
|
||||
echo -n "Starting in $(printf %3i $timeout)" \
|
||||
$'seconds...\b\b\b\b\b\b\b\b\b\b\b' >&2
|
||||
while (( timeout ))
|
||||
do
|
||||
echo -n $'\b\b\b'"$(printf %3i $timeout)" >&2
|
||||
sleep 1
|
||||
(( timeout-- ))
|
||||
done
|
||||
echo -en "\r\033[K"
|
||||
fi
|
||||
|
||||
openDatabase
|
||||
|
||||
createDestinations
|
||||
@ -144,8 +276,8 @@ removed=0
|
||||
read -u4 line
|
||||
until [[ $line == AtOM:NoMoreFiles ]]
|
||||
do
|
||||
id=${line%|*}
|
||||
filename=${line#*|}
|
||||
id=${line%::AtOM:SQL:Sep::*}
|
||||
filename=${line#*::AtOM:SQL:Sep::}
|
||||
if [ -n "$filename" ]
|
||||
then
|
||||
if rm -f "$filename"
|
||||
@ -161,115 +293,20 @@ do
|
||||
done
|
||||
echo "Suppressed $deleted files, $removed removed from database"
|
||||
|
||||
# get files
|
||||
for reader in "${tagreaders[@]}"
|
||||
do
|
||||
tagreaderclause+="${tagreaderclause:+ AND }NOT tags.tagreader = \"$reader\""
|
||||
done
|
||||
echo '
|
||||
SELECT COUNT(DISTINCT source_files.filename)
|
||||
FROM source_files
|
||||
INNER JOIN destination_files
|
||||
ON destination_files.source_file_id=source_files.id
|
||||
INNER JOIN destinations
|
||||
ON destination_files.destination_id=destinations.id
|
||||
INNER JOIN mime_type_actions
|
||||
ON destinations.id=mime_type_actions.destination_id
|
||||
INNER JOIN tags
|
||||
ON source_files.id=tags.source_file
|
||||
WHERE mime_type_actions.id = source_files.mime_type
|
||||
AND (
|
||||
CAST(tags.last_change AS TEXT)
|
||||
<>
|
||||
CAST(source_files.last_change AS TEXT)
|
||||
OR ('"$tagreaderclause"')
|
||||
)
|
||||
AND mime_type_actions.action = 1;' >&3
|
||||
read -u4 filecount
|
||||
echo '
|
||||
SELECT DISTINCT
|
||||
source_files.id,
|
||||
source_files.last_change,
|
||||
mime_type_actions.mime_text,
|
||||
source_files.filename
|
||||
FROM source_files
|
||||
INNER JOIN destination_files
|
||||
ON destination_files.source_file_id=source_files.id
|
||||
INNER JOIN destinations
|
||||
ON destination_files.destination_id=destinations.id
|
||||
INNER JOIN mime_type_actions
|
||||
ON destinations.id=mime_type_actions.destination_id
|
||||
INNER JOIN tags
|
||||
ON source_files.id=tags.source_file
|
||||
WHERE mime_type_actions.id = source_files.mime_type
|
||||
AND (
|
||||
CAST(tags.last_change AS TEXT)
|
||||
<>
|
||||
CAST(source_files.last_change AS TEXT)
|
||||
OR ('"$tagreaderclause"')
|
||||
)
|
||||
AND mime_type_actions.action = 1;
|
||||
updateTags
|
||||
|
||||
SELECT "AtOM:NoMoreFiles";' >&3
|
||||
read -u4 line
|
||||
while ! [[ $line = AtOM:NoMoreFiles ]]
|
||||
for forcedest in "${forceall[@]}"
|
||||
do
|
||||
tagfiles+=("$line")
|
||||
read -u4 line
|
||||
done
|
||||
echo 'BEGIN TRANSACTION;' >&3
|
||||
for line in "${tagfiles[@]}"
|
||||
do
|
||||
sourcefileid=${line%%|*}
|
||||
rest=${line#*|}
|
||||
lastchange=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
mimetype=${rest%%|*}
|
||||
filename=${rest#*|}
|
||||
echo -en "\rTags: $((++count*100/filecount))%"
|
||||
if (( count % 1000 == 0 ))
|
||||
if forcedestid=$(Select destinations id <<<"name = $forcedest")
|
||||
then
|
||||
echo 'COMMIT;BEGIN TRANSACTION;' >&3
|
||||
(( debug )) \
|
||||
&& echo -n " $count files read, committing..."
|
||||
fi
|
||||
if getTags
|
||||
then
|
||||
Update tags \
|
||||
album "${album:-NULL}" \
|
||||
albumartist "${albumartist:-NULL}" \
|
||||
artist "${artist:-NULL}" \
|
||||
composer "${composer:-NULL}" \
|
||||
disc "${disc:-NULL}" \
|
||||
genre "${genre:-NULL}" \
|
||||
performer "${performer:-NULL}" \
|
||||
title "${title:-NULL}" \
|
||||
track "${tracknum:-NULL}" \
|
||||
year "${year:-NULL}" \
|
||||
last_change "$lastchange" \
|
||||
rate "${rate:-NULL}" \
|
||||
channels "${channels:-NULL}" \
|
||||
bitrate "${bitrate:-NULL}" \
|
||||
tagreader "$tagreader" \
|
||||
>/dev/null <<<"source_file = $sourcefileid"
|
||||
unset genre \
|
||||
albumartist \
|
||||
year \
|
||||
album \
|
||||
disc \
|
||||
artist \
|
||||
tracknum \
|
||||
title \
|
||||
composer \
|
||||
performer \
|
||||
rate \
|
||||
bitrate \
|
||||
channels
|
||||
echo "Resetting destination files timestamps on" \
|
||||
"$forcedest ($forcedestid)..."
|
||||
Update destination_files last_change 1 \
|
||||
<<<"destination_id = $forcedestid"
|
||||
else
|
||||
echo "Destination $forcedest does not exist!" >&2
|
||||
fi
|
||||
done
|
||||
echo 'COMMIT;' >&3
|
||||
echo -e "\rRead tags from ${count:-0} files."
|
||||
unset count tagfiles
|
||||
|
||||
echo '
|
||||
CREATE TEMPORARY TABLE tasks(
|
||||
@ -376,7 +413,7 @@ echo '
|
||||
read -u4 line
|
||||
while ! [[ $line = AtOM:NoMoreFiles ]]
|
||||
do
|
||||
decodefiles+=("$line|")
|
||||
decodefiles+=("$line::AtOM:SQL:Sep::")
|
||||
read -u4 line
|
||||
done
|
||||
echo -n 'Creating tasks... '
|
||||
@ -384,42 +421,47 @@ echo -n 'Creating tasks... '
|
||||
echo 'BEGIN TRANSACTION;' >&3
|
||||
for line in "${decodefiles[@]}"
|
||||
do
|
||||
fileid=${line%%|*}
|
||||
rest=${line#*|}
|
||||
filename=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
mimetype=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
destination=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
destfileid=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
rate=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
channels=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
bitrate=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
genre=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
albumartist=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
year=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
album=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
disc=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
artist=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
track=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
title=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
composer=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
performer=${rest%%|*}
|
||||
fileid=${line%%::AtOM:SQL:Sep::*}
|
||||
rest=${line#*::AtOM:SQL:Sep::}
|
||||
filename=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
mimetype=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
destination=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
destfileid=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
rate=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
channels=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
bitrate=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
genre=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
albumartist=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
year=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
album=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
disc=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
artist=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
track=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
title=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
composer=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
performer=${rest%%::AtOM:SQL:Sep::*}
|
||||
unset rest
|
||||
case ${destinationformat["$destination"]} in
|
||||
vorbis) (( disableoggenc )) && continue ;;
|
||||
opus) (( disableopusenc )) && continue ;;
|
||||
mp3) (( disablelame )) && continue ;;
|
||||
esac
|
||||
decodeFile
|
||||
getDestDir
|
||||
getDestFile
|
||||
@ -502,13 +544,13 @@ do
|
||||
checkworkers
|
||||
cleaner
|
||||
master
|
||||
if (( ran ))
|
||||
if (( ran - failed ))
|
||||
then
|
||||
currenttime=$(date +%s)
|
||||
avgduration=$((
|
||||
((currenttime - starttime) * 1000)
|
||||
/
|
||||
ran
|
||||
( ran - failed )
|
||||
))
|
||||
secsremaining=$(( remaining * avgduration / 1000 ))
|
||||
(( days =
|
||||
@ -647,32 +689,32 @@ do
|
||||
echo -n "$destination: rename pattern changed, renaming files... "
|
||||
while [[ $line != AtOM:NoMoreFiles ]]
|
||||
do
|
||||
oldfilename=${line%%|*}
|
||||
rest=${line#*|}'|'
|
||||
destfileid=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
filename=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
album=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
albumartist=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
artist=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
composer=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
disc=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
genre=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
performer=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
title=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
track=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
year=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
oldfilename=${line%%::AtOM:SQL:Sep::*}
|
||||
rest=${line#*::AtOM:SQL:Sep::}'::AtOM:SQL:Sep::'
|
||||
destfileid=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
filename=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
album=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
albumartist=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
artist=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
composer=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
disc=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
genre=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
performer=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
title=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
track=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
year=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
if [ -n "$oldfilename" -a -f "$oldfilename" ]
|
||||
then
|
||||
getDestDir
|
||||
@ -720,11 +762,11 @@ done
|
||||
echo 'BEGIN TRANSACTION;' >&3
|
||||
for line in "${lines[@]}"
|
||||
do
|
||||
id=${line%%|*}
|
||||
rest=${line#*|}
|
||||
filename=${rest%%|*}
|
||||
oldfilename=${rest#*|}
|
||||
if [[ $oldfilename != $filename ]] && [ -f "$oldfilename" ]
|
||||
id=${line%%::AtOM:SQL:Sep::*}
|
||||
rest=${line#*::AtOM:SQL:Sep::}
|
||||
filename=${rest%%::AtOM:SQL:Sep::*}
|
||||
oldfilename=${rest#*::AtOM:SQL:Sep::}
|
||||
if [[ $oldfilename != "$filename" ]] && [ -f "$oldfilename" ]
|
||||
then
|
||||
rm -f "$oldfilename"
|
||||
fi
|
||||
|
||||
@ -8,12 +8,15 @@ getConfigDestination() {
|
||||
case "$value" in
|
||||
'mp3')
|
||||
destinationformat["$destination"]=mp3
|
||||
lameneeded=1
|
||||
;;
|
||||
'opus')
|
||||
destinationformat["$destination"]=opus
|
||||
opusencneeded=1
|
||||
;;
|
||||
'vorbis')
|
||||
destinationformat["$destination"]=vorbis
|
||||
oggencneeded=1
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported destination format: $value" >2&
|
||||
|
||||
@ -6,6 +6,7 @@ copyFiles_action() {
|
||||
source_files.filename,
|
||||
source_files.last_change,
|
||||
destinations.id,
|
||||
destinations.name,
|
||||
destination_files.id
|
||||
FROM source_files
|
||||
INNER JOIN destination_files
|
||||
@ -31,36 +32,43 @@ copyFiles_action() {
|
||||
echo 'BEGIN TRANSACTION;' >&3
|
||||
for copyfile in "${copyfiles[@]}"
|
||||
do
|
||||
sourcefilename=${copyfile%%|*}
|
||||
sourcefilename=${copyfile%%::AtOM:SQL:Sep::*}
|
||||
sourcedir=${sourcefilename%/*}
|
||||
rest="${copyfile#*|}|"
|
||||
lastchange=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
destinationid=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
destfileid=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
echo 'SELECT IFNULL( (
|
||||
SELECT destination_files.filename
|
||||
FROM destination_files
|
||||
INNER JOIN source_files
|
||||
ON destination_files.source_file_id=source_files.id
|
||||
INNER JOIN mime_type_actions
|
||||
ON
|
||||
mime_type_actions.id=source_files.mime_type
|
||||
INNER JOIN destinations
|
||||
ON destinations.id=destination_files.destination_id
|
||||
WHERE destinations.id = '$destinationid'
|
||||
AND source_files.filename LIKE
|
||||
"'"${sourcedir//\"/\"\"}"'/%"
|
||||
AND mime_type_actions.action = 1
|
||||
LIMIT 1
|
||||
),"AtOM:NotFound");
|
||||
'>&3
|
||||
read -u4 filename
|
||||
if [[ $filename != AtOM:NotFound ]]
|
||||
rest="${copyfile#*::AtOM:SQL:Sep::}::AtOM:SQL:Sep::"
|
||||
lastchange=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
destinationid=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
destination=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
destfileid=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
(( count++ ))
|
||||
printf '\b\b\b\b%3i%%' $(( (count * 100) / ${#copyfiles[@]} ))
|
||||
if [ -n "${renamepath["$destination"]}" ]
|
||||
then
|
||||
destdir=${filename%/*}
|
||||
destdir="$(guessPath)" || continue
|
||||
else
|
||||
destdir="${destinationpath["$destination"]}/"
|
||||
if [[ $sourcefilename =~ / ]]
|
||||
then
|
||||
destdir+=$(
|
||||
sanitizeFile "${sourcefilename%%/*}" dir
|
||||
)
|
||||
part=${sourcefilename#*/}
|
||||
while [[ $part =~ / ]]
|
||||
do
|
||||
destdir+="/$(
|
||||
sanitizeFile "${part%%/*}" dir
|
||||
)"
|
||||
part=${part#*/}
|
||||
done
|
||||
if ! [ -d "$destdir" ]
|
||||
then
|
||||
mkdir -p "$destdir"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if cp -al "$sourcepath/$sourcefilename" "$destdir" 2>/dev/null\
|
||||
|| cp -a "$sourcepath/$sourcefilename" "$destdir"
|
||||
then
|
||||
@ -73,11 +81,13 @@ copyFiles_action() {
|
||||
EOWhere
|
||||
(( done++ ))
|
||||
fi
|
||||
fi
|
||||
(( count++ ))
|
||||
printf '\b\b\b\b%3i%%' $(( (count * 100) / ${#copyfiles[@]} ))
|
||||
done
|
||||
echo 'COMMIT;' >&3
|
||||
if (( count ))
|
||||
then
|
||||
echo -e "\rCopied ${done:-0} of $count files.\033[K"
|
||||
else
|
||||
echo -e "\rNothing to copy.\033[K"
|
||||
fi
|
||||
unset count done
|
||||
}
|
||||
|
||||
28
lib/copy/guessPath
Normal file
28
lib/copy/guessPath
Normal file
@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
|
||||
guessPath() {
|
||||
echo 'SELECT IFNULL( (
|
||||
SELECT destination_files.filename
|
||||
FROM destination_files
|
||||
INNER JOIN source_files
|
||||
ON destination_files.source_file_id=source_files.id
|
||||
INNER JOIN mime_type_actions
|
||||
ON
|
||||
mime_type_actions.id=source_files.mime_type
|
||||
INNER JOIN destinations
|
||||
ON destinations.id=destination_files.destination_id
|
||||
WHERE destinations.id = '$destinationid'
|
||||
AND source_files.filename LIKE
|
||||
"'"${sourcedir//\"/\"\"}"'/%"
|
||||
AND mime_type_actions.action = 1
|
||||
LIMIT 1
|
||||
),"AtOM:NotFound");
|
||||
'>&3
|
||||
read -u4 filename
|
||||
if [[ $filename != AtOM:NotFound ]]
|
||||
then
|
||||
echo "${filename%/*}"
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
@ -15,6 +15,10 @@ Insert() {
|
||||
insert_keys+='`'"$key"'`'
|
||||
(( ${#insert_values} )) && insert_values+=","
|
||||
case $value in
|
||||
'::AtOM:FT::'*)
|
||||
value="${value//::AtOM:FT::/}"
|
||||
insert_values+='"'"${value//\"/\"\"}"'"'
|
||||
;;
|
||||
'NULL')
|
||||
insert_values+="NULL"
|
||||
;;
|
||||
|
||||
@ -25,7 +25,8 @@ InsertIfUnset() {
|
||||
Select "$table" "$column" < <(
|
||||
for key in ${!keys[@]}
|
||||
do
|
||||
echo "${keys[$key]}" = "${values[$key]}"
|
||||
echo "${keys[$key]}" = \
|
||||
"${values[$key]//::AtOM:FT::}"
|
||||
done
|
||||
)
|
||||
)
|
||||
|
||||
@ -26,6 +26,10 @@ Update() {
|
||||
;;
|
||||
value)
|
||||
case $argument in
|
||||
'::AtOM:FT::'*)
|
||||
argument="${argument//::AtOM:FT::/}"
|
||||
set_statement+=" = "'"'"${argument//\"/\"\"}"'"'
|
||||
;;
|
||||
'NULL')
|
||||
set_statement+=" = NULL"
|
||||
;;
|
||||
|
||||
@ -1,19 +1,7 @@
|
||||
#!/bin/bash
|
||||
openDatabase() {
|
||||
if [ ! -d "$tempdir" ]
|
||||
then
|
||||
mkdir -p "$tempdir"
|
||||
fi
|
||||
rm -f "$tempdir"/sqlite.{in,out}
|
||||
mkfifo "$tempdir"/sqlite.{in,out}
|
||||
if [ ! -f "$database" ]
|
||||
then
|
||||
if [ ! -d "${database%/*}" ]
|
||||
then
|
||||
mkdir -p "${database%/*}"
|
||||
fi
|
||||
sqlite3 "$database" < $schema
|
||||
fi
|
||||
sqlite3 -bail "$database" \
|
||||
< "$tempdir/sqlite.in" \
|
||||
> "$tempdir/sqlite.out" &
|
||||
@ -24,5 +12,7 @@ openDatabase() {
|
||||
exec 5>&3
|
||||
exec 3> >(tee -a $tempdir/debug.log >&5)
|
||||
fi
|
||||
cat $schema >&3
|
||||
echo '.separator ::AtOM:SQL:Sep::' >&3
|
||||
echo 'PRAGMA foreign_keys = ON;' >&3
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
decodeFile() {
|
||||
case "$mimetype" in
|
||||
'video/'*)
|
||||
(( disablevideo )) && continue
|
||||
extractAudio
|
||||
if (( ${destinationnormalize["$destination"]}))\
|
||||
|| (
|
||||
@ -30,6 +31,7 @@ decodeFile() {
|
||||
then
|
||||
copied=1
|
||||
else
|
||||
(( disableopusdec )) && continue
|
||||
decodeOpusdec
|
||||
if (( ${destinationnormalize["$destination"]}))\
|
||||
|| (
|
||||
@ -60,6 +62,7 @@ decodeFile() {
|
||||
extendedtype=$(file -b "$sourcepath/$filename")
|
||||
case "$extendedtype" in
|
||||
*'Musepack '*)
|
||||
(( disablempcdec )) && continue
|
||||
decodeMpcdec
|
||||
if (( ${destinationnormalize["$destination"]}))\
|
||||
|| (
|
||||
|
||||
@ -51,7 +51,12 @@ encodeFile::mp3() {
|
||||
$(
|
||||
for key in ${!lameopts[@]}
|
||||
do
|
||||
echo "cmd_arg$key ${lameopts[key]}"
|
||||
cleanedopts="${lameopts[key]//\&/\\\&}"
|
||||
cleanedopts="${cleanedopts//\[/\\[}"
|
||||
cleanedopts="${cleanedopts//\]/\\]}"
|
||||
cleanedopts="${cleanedopts//\{/\\{}"
|
||||
cleanedopts="${cleanedopts//\}/\\\}}"
|
||||
echo "cmd_arg$key $cleanedopts"
|
||||
done
|
||||
)
|
||||
cleanup $tempdir/$tmpfile.wav
|
||||
|
||||
@ -26,7 +26,12 @@ encodeFile::opus() {
|
||||
$(
|
||||
for key in ${!opusencopts[@]}
|
||||
do
|
||||
echo "cmd_arg$key ${opusencopts[key]}"
|
||||
cleanedopts="${opusencopts[key]//\&/\\\&}"
|
||||
cleanedopts="${cleanedopts//\[/\\[}"
|
||||
cleanedopts="${cleanedopts//\]/\\]}"
|
||||
cleanedopts="${cleanedopts//\{/\\{}"
|
||||
cleanedopts="${cleanedopts//\}/\\\}}"
|
||||
echo "cmd_arg$key $cleanedopts"
|
||||
done
|
||||
)
|
||||
cleanup $tempdir/$tmpfile.wav
|
||||
|
||||
@ -22,6 +22,11 @@ encodeFile::vorbis() {
|
||||
$(
|
||||
for key in ${!oggencopts[@]}
|
||||
do
|
||||
cleanedopts="${oggencopts[key]//\&/\\\&}"
|
||||
cleanedopts="${cleanedopts//\[/\\[}"
|
||||
cleanedopts="${cleanedopts//\]/\\]}"
|
||||
cleanedopts="${cleanedopts//\{/\\{}"
|
||||
cleanedopts="${cleanedopts//\}/\\\}}"
|
||||
echo "cmd_arg$key ${oggencopts[key]}"
|
||||
done
|
||||
)
|
||||
|
||||
@ -1,7 +1,34 @@
|
||||
#!/bin/bash
|
||||
getDestDir() {
|
||||
destdir="${destinationpath[$destination]}/"
|
||||
if [ -n "${destinationrenamepath[$destination]}" ]
|
||||
if [ -n "${destinationrenamepath[$destination]}" ] \
|
||||
&& (
|
||||
(
|
||||
! [[ ${destinationrenamepath[$destination]} =~ %\{album\} ]] \
|
||||
|| [ -n "$album" ]
|
||||
) && (
|
||||
! [[ ${destinationrenamepath[$destination]} =~ %\{albumartist\} ]] \
|
||||
|| [ -n "$albumartist" ]
|
||||
) && (
|
||||
! [[ ${destinationrenamepath[$destination]} =~ %\{artist\} ]] \
|
||||
|| [ -n "$artist" ]
|
||||
) && (
|
||||
! [[ ${destinationrenamepath[$destination]} =~ %\{genre\} ]] \
|
||||
|| [ -n "$genre" ]
|
||||
) && (
|
||||
! [[ ${destinationrenamepath[$destination]} =~ %\{title\} ]] \
|
||||
|| [ -n "$title" ]
|
||||
) && (
|
||||
! [[ ${destinationrenamepath[$destination]} =~ %\{track\} ]] \
|
||||
|| [ -n "$track" ]
|
||||
) && (
|
||||
! [[ ${destinationrenamepath[$destination]} =~ %\{year\} ]] \
|
||||
|| [ -n "$year" ]
|
||||
) && (
|
||||
! [[ ${destinationrenamepath[$destination]} =~ %\{disc\} ]] \
|
||||
|| [ -n "$disc" ]
|
||||
)
|
||||
)
|
||||
then
|
||||
replace=$(sanitizeFile "$album" dir)
|
||||
destdir+="${destinationrenamepath[$destination]//%\{album\}/$replace}"
|
||||
|
||||
@ -1,6 +1,33 @@
|
||||
#!/bin/bash
|
||||
getDestFile() {
|
||||
if [ -n "${destinationrename[$destination]}" ]
|
||||
if [ -n "${destinationrename[$destination]}" ] \
|
||||
&& (
|
||||
(
|
||||
! [[ ${destinationrename[$destination]} =~ %\{album\} ]] \
|
||||
|| [ -n "$album" ]
|
||||
) && (
|
||||
! [[ ${destinationrename[$destination]} =~ %\{albumartist\} ]] \
|
||||
|| [ -n "$albumartist" ]
|
||||
) && (
|
||||
! [[ ${destinationrename[$destination]} =~ %\{artist\} ]] \
|
||||
|| [ -n "$artist" ]
|
||||
) && (
|
||||
! [[ ${destinationrename[$destination]} =~ %\{genre\} ]] \
|
||||
|| [ -n "$genre" ]
|
||||
) && (
|
||||
! [[ ${destinationrename[$destination]} =~ %\{title\} ]] \
|
||||
|| [ -n "$title" ]
|
||||
) && (
|
||||
! [[ ${destinationrename[$destination]} =~ %\{track\} ]] \
|
||||
|| [ -n "$track" ]
|
||||
) && (
|
||||
! [[ ${destinationrename[$destination]} =~ %\{year\} ]] \
|
||||
|| [ -n "$year" ]
|
||||
) && (
|
||||
! [[ ${destinationrename[$destination]} =~ %\{disc\} ]] \
|
||||
|| [ -n "$disc" ]
|
||||
)
|
||||
)
|
||||
then
|
||||
destfile="${destinationrename[$destination]//%\{album\}/$album}"
|
||||
destfile="${destfile//%\{albumartist\}/$albumartist}"
|
||||
|
||||
@ -19,7 +19,7 @@ getFiles() {
|
||||
mimetype=$(file -b --mime-type "$sourcepath/$filename")
|
||||
if [[ $mimetype == application/ogg ]]
|
||||
then
|
||||
case "$(head -n1 "$sourcepath/$filename")" in
|
||||
case "$(head -n5 "$sourcepath/$filename")" in
|
||||
*'vorbis'*)
|
||||
mimetype+=' vorbis'
|
||||
;;
|
||||
|
||||
@ -1,55 +0,0 @@
|
||||
#!/bin/bash
|
||||
getInfosAPE_version='APE-1'
|
||||
tagreaders+=( "$getInfosAPE_version" )
|
||||
getInfos::APE() {
|
||||
# I was not able to find a decent cli tool to read APE tags.
|
||||
# This is raw but works for the very few MusePack files I got.
|
||||
#
|
||||
# Please tell me if you know of any good tool.
|
||||
tagreader="$getInfosAPE_version"
|
||||
IFS='='
|
||||
while read tag value
|
||||
do
|
||||
IFS="$oldIFS"
|
||||
case $tag in
|
||||
[Aa][Ll][Bb][Uu][Mm]' '[Aa][Rr][Tt][Ii][Ss][Tt])
|
||||
albumartist="$value"
|
||||
;;
|
||||
[Aa][Rr][Tt][Ii][Ss][Tt])
|
||||
artist="$value"
|
||||
;;
|
||||
[Yy][Ee][Aa][Rr])
|
||||
year="$value"
|
||||
;;
|
||||
[Aa][Ll][Bb][Uu][Mm])
|
||||
album="$value"
|
||||
;;
|
||||
[Tt][Ii][Tt][Ll][Ee])
|
||||
title="$value"
|
||||
;;
|
||||
[Tt][Rr][Aa][Cc][Kk])
|
||||
tracknum="$value"
|
||||
;;
|
||||
[Gg][Ee][Nn][Rr][Ee])
|
||||
genre="$value"
|
||||
;;
|
||||
[Cc][Oo][Mm][Pp][Oo][Ss][Ee][Rr])
|
||||
composer="$value"
|
||||
;;
|
||||
[Pp][Ee][Rr][Ff][Oo][Rr][Mm][Ee][Rr])
|
||||
performer="$value"
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
IFS='='
|
||||
done < <(
|
||||
IFS="$oldIFS"
|
||||
sed \
|
||||
's/APETAGEX/\n/;s/[\x00\-\x1F]\x00\+/\n/g;s/\x00/=/g' \
|
||||
"$sourcepath/$filename" \
|
||||
| egrep -i \
|
||||
'^(Album Artist|Artist|Year|Album|Title|Track|Genre|Composer|Performer)='
|
||||
)
|
||||
IFS="$oldIFS"
|
||||
}
|
||||
@ -1,27 +0,0 @@
|
||||
#!/bin/bash
|
||||
getInfosMP3_version='ID3-3'
|
||||
tagreaders+=( "$getInfosMP3_version" )
|
||||
getInfos::MP3() {
|
||||
tagreader="$getInfosMP3_version"
|
||||
infos=$(
|
||||
soxi "$sourcepath/$filename" 2>/dev/null \
|
||||
| sed 's/ *: /=/'
|
||||
)
|
||||
album=$(gettag album)
|
||||
artist=$(gettag artist)
|
||||
genre=$(gettag genre)
|
||||
title=$(gettag title)
|
||||
tracknum=$(gettag tracknumber)
|
||||
year=$(gettag year)
|
||||
expr='^[0-9]*$'
|
||||
if [[ $genre =~ $expr ]]
|
||||
then
|
||||
genre="${id3genres[$genre]}"
|
||||
fi
|
||||
infos="${infos/: /=}"
|
||||
channels=$(gettag channels)
|
||||
rate=$(gettag 'sample rate')
|
||||
bitrate=$(gettag 'bit rate')
|
||||
bitrate=${bitrate%%.*}
|
||||
bitrate=${bitrate%k}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
getInfosOgg_version='Ogg-1'
|
||||
getInfosOgg_version='Ogg-2'
|
||||
tagreaders+=( "$getInfosOgg_version" )
|
||||
getInfos::Ogg() {
|
||||
tagreader="$getInfosOgg_version"
|
||||
@ -22,9 +22,9 @@ getInfos::Ogg() {
|
||||
tracknum="$tracknum/$tracktotal"
|
||||
fi
|
||||
year=$(gettag date)
|
||||
infos="${infos/: /=}"
|
||||
infos="${infos//: /=}"
|
||||
rate=$(gettag rate|head -n1)
|
||||
channels=$(gettag channels|head -n1)
|
||||
bitrate=$(gettag 'nominal bitrate')
|
||||
bitrate=$(gettag 'average bitrate')
|
||||
bitrate=${bitrate%%,*}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
getInfosOpus_version='Opus-1'
|
||||
getInfosOpus_version='Opus-2'
|
||||
tagreaders+=( "$getInfosOpus_version" )
|
||||
getInfos::Opus() {
|
||||
tagreader="$getInfosOpus_version"
|
||||
@ -22,7 +22,7 @@ getInfos::Opus() {
|
||||
tracknum="$tracknum/$tracktotal"
|
||||
fi
|
||||
year=$(gettag date)
|
||||
infos="${infos/: /=}"
|
||||
infos="${infos//: /=}"
|
||||
rate=$(gettag 'original sample rate'|head -n1)
|
||||
channels=$(gettag channels|head -n1)
|
||||
bitrate=$(gettag 'average bitrate')
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
getInfosffmpeg_version='ffmpeg-1'
|
||||
getInfosffmpeg_version='ffmpeg-2'
|
||||
tagreaders+=( "$getInfosffmpeg_version" )
|
||||
getInfos::ffmpeg() {
|
||||
tagreader="$getInfosffmpeg_version"
|
||||
@ -31,8 +31,8 @@ getInfos::ffmpeg() {
|
||||
genre=$(gettag genre)
|
||||
performer=$(gettag TOPE)
|
||||
title=$(gettag title)
|
||||
tracknum=$(gettag tracknumber)
|
||||
year=$(gettag year)
|
||||
tracknum=$(gettag track)
|
||||
year=$(gettag date)
|
||||
expr='^[0-9]*$'
|
||||
if [ -n "$genre" ] && [[ $genre =~ $expr ]]
|
||||
then
|
||||
|
||||
@ -1,16 +0,0 @@
|
||||
#!/bin/bash
|
||||
getRateChannelMPC() {
|
||||
while read key value garbage
|
||||
do
|
||||
case $key in
|
||||
'samplerate:')
|
||||
rate=$value
|
||||
;;
|
||||
'channels:')
|
||||
channels=$value
|
||||
;;
|
||||
esac
|
||||
done < <(
|
||||
mpcdec "$sourcepath/$filename" -i 2>&1
|
||||
)
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
#!/bin/bash
|
||||
getRateChannelSoxi() {
|
||||
rate=$(soxi -r "$sourcepath/$filename" 2>/dev/null)
|
||||
channels=$(soxi -c "$sourcepath/$filename" 2>/dev/null)
|
||||
}
|
||||
@ -1,39 +1,31 @@
|
||||
#!/bin/bash
|
||||
getTags_version='unknown-3'
|
||||
tagreaders+=( "$getTags_version" )
|
||||
getTags_version='unknown-4'
|
||||
getTags() {
|
||||
unset type
|
||||
case "$mimetype" in
|
||||
audio/mpeg)
|
||||
type=MP3
|
||||
type=ffmpeg
|
||||
(( disableffprobe )) && unset type
|
||||
;;
|
||||
'application/ogg opus')
|
||||
type=Opus
|
||||
(( disableopusinfo )) && unset type
|
||||
;;
|
||||
application/ogg*)
|
||||
type=Ogg
|
||||
(( disableogginfo )) && unset type
|
||||
;;
|
||||
audio/x-flac)
|
||||
type=FLAC
|
||||
(( disableflac )) && unset type
|
||||
;;
|
||||
video/*)
|
||||
type=ffmpeg
|
||||
(( disableffprobe )) && unset type
|
||||
;;
|
||||
*)
|
||||
extendedtype=$(file -b "$sourcepath/$filename")
|
||||
case "$extendedtype" in
|
||||
*' ID3 '*)
|
||||
type=MP3
|
||||
;;
|
||||
*'Musepack '*)
|
||||
getRateChannelMPC
|
||||
tryAPE
|
||||
;;
|
||||
*)
|
||||
getRateChannelSoxi
|
||||
tryAPE
|
||||
;;
|
||||
esac
|
||||
type=ffmpeg
|
||||
(( disableffprobe )) && unset type
|
||||
;;
|
||||
esac
|
||||
if [ -n "$type" ]
|
||||
|
||||
158
lib/tags/updateTags
Normal file
158
lib/tags/updateTags
Normal file
@ -0,0 +1,158 @@
|
||||
#!/bin/bash
|
||||
updateTags() {
|
||||
for reader in "${tagreaders[@]}"
|
||||
do
|
||||
tagreaderclause+="${tagreaderclause:+ AND }NOT tags.tagreader = \"$reader\""
|
||||
done
|
||||
echo '
|
||||
SELECT DISTINCT
|
||||
source_files.id,
|
||||
source_files.last_change,
|
||||
mime_type_actions.mime_text,
|
||||
source_files.filename,
|
||||
tags.album,
|
||||
tags.albumartist,
|
||||
tags.artist,
|
||||
tags.composer,
|
||||
tags.disc,
|
||||
tags.genre,
|
||||
tags.performer,
|
||||
tags.title,
|
||||
tags.track,
|
||||
tags.year,
|
||||
tags.rate,
|
||||
tags.channels,
|
||||
tags.bitrate
|
||||
FROM source_files
|
||||
INNER JOIN destination_files
|
||||
ON destination_files.source_file_id=source_files.id
|
||||
INNER JOIN destinations
|
||||
ON destination_files.destination_id=destinations.id
|
||||
INNER JOIN mime_type_actions
|
||||
ON destinations.id=mime_type_actions.destination_id
|
||||
INNER JOIN tags
|
||||
ON source_files.id=tags.source_file
|
||||
WHERE mime_type_actions.id = source_files.mime_type
|
||||
AND (
|
||||
CAST(tags.last_change AS TEXT)
|
||||
<>
|
||||
CAST(source_files.last_change AS TEXT)
|
||||
OR ('"$tagreaderclause"')
|
||||
)
|
||||
AND mime_type_actions.action = 1;
|
||||
|
||||
SELECT "AtOM:NoMoreFiles";' >&3
|
||||
read -u4 line
|
||||
while ! [[ $line = AtOM:NoMoreFiles ]]
|
||||
do
|
||||
tagfiles+=("$line")
|
||||
(( filecount++ ))
|
||||
read -u4 line
|
||||
done
|
||||
echo 'BEGIN TRANSACTION;' >&3
|
||||
for line in "${tagfiles[@]}"
|
||||
do
|
||||
sourcefileid=${line%%::AtOM:SQL:Sep::*}
|
||||
rest=${line#*::AtOM:SQL:Sep::}
|
||||
lastchange=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
mimetype=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
filename=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
oldalbum=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
oldalbumartist=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
oldartist=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
oldcomposer=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
olddisc=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
oldgenre=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
oldperformer=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
oldtitle=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
oldtrack=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
oldyear=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
oldrate=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
oldchannels=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
oldbitrate=${rest%%::AtOM:SQL:Sep::*}
|
||||
echo -en "\rTags: $((++count*100/filecount))%"
|
||||
if (( count % 1000 == 0 ))
|
||||
then
|
||||
echo 'COMMIT;BEGIN TRANSACTION;' >&3
|
||||
(( debug )) \
|
||||
&& echo -n " $count files read, committing..."
|
||||
fi
|
||||
if getTags
|
||||
then
|
||||
[[ $oldalbum != "$album" ]]&& ual=1
|
||||
[[ $oldalbumartist != "$albumartist" ]]&&uaa=1
|
||||
[[ $oldartist != "$artist" ]]&& uar=1
|
||||
[[ $oldcomposer != "$composer" ]]&& uco=1
|
||||
[[ $olddisc != "$disc" ]]&& udi=1
|
||||
[[ $oldgenre != "$genre" ]]&& uge=1
|
||||
[[ $oldperformer != "$performer" ]]&& upe=1
|
||||
[[ $oldtitle != "$title" ]]&& uti=1
|
||||
[[ $oldtrack != "$tracknum" ]]&& utr=1
|
||||
[[ $oldyear != "$year" ]]&& uye=1
|
||||
[[ $oldrate != "$rate" ]]&& ura=1
|
||||
[[ $oldchannels != "$channels" ]]&& uch=1
|
||||
[[ $oldbitrate != "$bitrate" ]]&& ubi=1
|
||||
Update tags \
|
||||
${ual:+album "::AtOM:FT::${album:-NULL}"}\
|
||||
${uaa:+albumartist "::AtOM:FT::${albumartist:-NULL}"}\
|
||||
${uar:+artist "::AtOM:FT::${artist:-NULL}"}\
|
||||
${uco:+composer "::AtOM:FT::${composer:-NULL}"}\
|
||||
${udi:+disc "${disc:-NULL}"} \
|
||||
${uge:+genre "${genre:-NULL}"} \
|
||||
${upe:+performer "::AtOM:FT::${performer:-NULL}"}\
|
||||
${uti:+title "::AtOM:FT::${title:-NULL}"}\
|
||||
${utr:+track "::AtOM:FT::${tracknum:-NULL}"}\
|
||||
${uye:+year "${year:-NULL}"} \
|
||||
last_change "$lastchange" \
|
||||
${ura:+rate "${rate:-NULL}"} \
|
||||
${uch:+channels "${channels:-NULL}"} \
|
||||
${ubi:+bitrate "${bitrate:-NULL}"} \
|
||||
tagreader "$tagreader" \
|
||||
>/dev/null <<<"source_file = $sourcefileid"
|
||||
unset genre \
|
||||
albumartist \
|
||||
year \
|
||||
album \
|
||||
disc \
|
||||
artist \
|
||||
tracknum \
|
||||
title \
|
||||
composer \
|
||||
performer \
|
||||
rate \
|
||||
bitrate \
|
||||
channels \
|
||||
ual \
|
||||
uaa \
|
||||
uar \
|
||||
uco \
|
||||
udi \
|
||||
uge \
|
||||
upe \
|
||||
uti \
|
||||
utr \
|
||||
uye \
|
||||
ura \
|
||||
uch \
|
||||
ubi
|
||||
fi
|
||||
done
|
||||
echo 'COMMIT;' >&3
|
||||
echo -e "\rRead tags from ${count:-0} files.\033[K"
|
||||
unset count tagfiles
|
||||
}
|
||||
@ -12,16 +12,16 @@ gettaskinfos() {
|
||||
WHERE id='$1';
|
||||
' >&3
|
||||
read -u4 line
|
||||
taskid=${line%%|*}
|
||||
rest="${line#*|}|"
|
||||
sourcefileid=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
required=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
cleanup=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
destfileid=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
destfilename=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
taskid=${line%%::AtOM:SQL:Sep::*}
|
||||
rest="${line#*::AtOM:SQL:Sep::}::AtOM:SQL:Sep::"
|
||||
sourcefileid=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
required=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cleanup=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
destfileid=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
destfilename=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ cleaner() {
|
||||
EOWhere
|
||||
)
|
||||
(( failed+=faildepends ))
|
||||
(( ran+=faildepends ))
|
||||
Update tasks status 2 <<<"id = $taskid"
|
||||
Update tasks status 2 <<<"requires = $taskid"
|
||||
echo "SELECT COUNT(*)
|
||||
|
||||
@ -69,78 +69,78 @@ master() {
|
||||
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#*|}
|
||||
taskid=${line%%::AtOM:SQL:Sep::*}
|
||||
rest="${line#*::AtOM:SQL:Sep::}::AtOM:SQL:Sep::"
|
||||
sourcefileid=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
required=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cmd_arg=("${rest%%::AtOM:SQL:Sep::*}")
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
cleanup=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
destfileid=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
destfilename=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
for key in ${!cmd_arg[@]}
|
||||
do
|
||||
[ -z "${cmd_arg[key]}" ] && unset cmd_arg[key]
|
||||
|
||||
@ -4,12 +4,3 @@ worker() {
|
||||
(( debug >= 2 )) && echo "${cmd_arg[@]}" >&2
|
||||
"${cmd_arg[@]}" >/dev/null
|
||||
}
|
||||
createworker() {
|
||||
worker $1 &
|
||||
workers[$1]=$!
|
||||
}
|
||||
destroyworker() {
|
||||
dyingworker=${workers[$1]}
|
||||
unset workers[$1]
|
||||
wait $dyingworker
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
BEGIN TRANSACTION;
|
||||
CREATE TABLE source_files (
|
||||
CREATE TABLE IF NOT EXISTS source_files (
|
||||
id INTEGER PRIMARY KEY,
|
||||
filename TEXT UNIQUE NOT NULL,
|
||||
size INTEGER NOT NULL,
|
||||
@ -10,11 +10,11 @@ CREATE TABLE source_files (
|
||||
FOREIGN KEY (mime_type) REFERENCES mime_types(id)
|
||||
ON DELETE SET NULL
|
||||
);
|
||||
CREATE TABLE destinations (
|
||||
CREATE TABLE IF NOT EXISTS destinations (
|
||||
id INTEGER PRIMARY KEY,
|
||||
name TEXT UNIQUE NOT NULL
|
||||
);
|
||||
CREATE TABLE destination_files (
|
||||
CREATE TABLE IF NOT EXISTS destination_files (
|
||||
id INTEGER PRIMARY KEY,
|
||||
filename TEXT,
|
||||
old_filename TEXT,
|
||||
@ -27,11 +27,11 @@ CREATE TABLE destination_files (
|
||||
FOREIGN KEY (destination_id) REFERENCES destinations(id)
|
||||
ON DELETE CASCADE
|
||||
);
|
||||
CREATE TABLE mime_types (
|
||||
CREATE TABLE IF NOT EXISTS mime_types (
|
||||
id INTEGER PRIMARY KEY,
|
||||
mime_text TEXT UNIQUE NOT NULL
|
||||
);
|
||||
CREATE TABLE mime_actions (
|
||||
CREATE TABLE IF NOT EXISTS mime_actions (
|
||||
id INTEGER PRIMARY KEY,
|
||||
mime_type INTEGER,
|
||||
destination_id INTEGER,
|
||||
@ -40,7 +40,7 @@ CREATE TABLE mime_actions (
|
||||
FOREIGN KEY (destination_id) REFERENCES destinations(id)
|
||||
ON DELETE CASCADE
|
||||
);
|
||||
CREATE TABLE tags (
|
||||
CREATE TABLE IF NOT EXISTS tags (
|
||||
source_file INTEGER PRIMARY KEY,
|
||||
genre TEXT,
|
||||
albumartist TEXT,
|
||||
@ -61,13 +61,14 @@ CREATE TABLE tags (
|
||||
ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE VIEW mime_type_actions AS
|
||||
CREATE VIEW IF NOT EXISTS mime_type_actions AS
|
||||
SELECT
|
||||
mime_types.id,mime_types.mime_text,
|
||||
mime_actions.destination_id,mime_actions.action
|
||||
FROM mime_types INNER JOIN mime_actions
|
||||
ON mime_actions.mime_type = mime_types.id;
|
||||
CREATE TRIGGER update_mime_actions INSTEAD OF UPDATE OF action ON mime_type_actions
|
||||
CREATE TRIGGER IF NOT EXISTS update_mime_actions
|
||||
INSTEAD OF UPDATE OF action ON mime_type_actions
|
||||
BEGIN
|
||||
UPDATE mime_actions
|
||||
SET action=new.action
|
||||
@ -75,7 +76,8 @@ BEGIN
|
||||
AND destination_id=old.destination_id;
|
||||
END;
|
||||
|
||||
CREATE TRIGGER create_dest_files_and_mime_actions AFTER INSERT ON destinations
|
||||
CREATE TRIGGER IF NOT EXISTS create_dest_files_and_mime_actions
|
||||
AFTER INSERT ON destinations
|
||||
BEGIN
|
||||
INSERT INTO mime_actions
|
||||
(mime_type,destination_id)
|
||||
@ -87,7 +89,7 @@ BEGIN
|
||||
FROM source_files;
|
||||
END;
|
||||
|
||||
CREATE TRIGGER create_mime_actions AFTER INSERT ON mime_types
|
||||
CREATE TRIGGER IF NOT EXISTS create_mime_actions AFTER INSERT ON mime_types
|
||||
BEGIN
|
||||
INSERT INTO mime_actions (mime_type,destination_id)
|
||||
SELECT mime_types.id,destinations.id
|
||||
@ -95,18 +97,39 @@ BEGIN
|
||||
WHERE mime_types.id=new.id;
|
||||
END;
|
||||
|
||||
CREATE INDEX sourcefiles_by_name ON source_files (filename,id);
|
||||
CREATE INDEX IF NOT EXISTS sourcefiles_by_name ON source_files (filename,id);
|
||||
|
||||
CREATE TRIGGER create_destinations AFTER INSERT ON source_files
|
||||
CREATE TRIGGER IF NOT EXISTS create_destinations AFTER INSERT ON source_files
|
||||
BEGIN
|
||||
INSERT INTO destination_files (source_file_id,destination_id)
|
||||
SELECT source_files.id,destinations.id FROM source_files
|
||||
INNER JOIN destinations
|
||||
WHERE source_files.id=new.id;
|
||||
END;
|
||||
CREATE TRIGGER create_tags AFTER INSERT ON source_files
|
||||
CREATE TRIGGER IF NOT EXISTS create_tags AFTER INSERT ON source_files
|
||||
BEGIN
|
||||
INSERT INTO tags (source_file,last_change) VALUES (new.id,0);
|
||||
END;
|
||||
DROP TRIGGER IF EXISTS force_destination_update_on_tag_update;
|
||||
CREATE TRIGGER force_destination_update_on_tag_update
|
||||
AFTER UPDATE OF
|
||||
genre,
|
||||
albumartist,
|
||||
year,
|
||||
album,
|
||||
disc,
|
||||
artist,
|
||||
track,
|
||||
title,
|
||||
composer,
|
||||
performer,
|
||||
rate,
|
||||
channels,
|
||||
bitrate
|
||||
ON tags
|
||||
BEGIN
|
||||
UPDATE destination_files SET last_change=0
|
||||
WHERE source_file_id=old.source_file;
|
||||
END;
|
||||
|
||||
COMMIT;
|
||||
|
||||
34
toys/README
34
toys/README
@ -1,3 +1,37 @@
|
||||
createindex
|
||||
===========
|
||||
Creates a nice index of your collection, similar to what oidua
|
||||
(http://oidua.suxbad.com/) does, but much faster, as it is using AtOM's DB
|
||||
instead of rescanning your whole collection.
|
||||
|
||||
Options define what will be shown and may optionnally be followed by the column
|
||||
width (default: 50).
|
||||
|
||||
Options:
|
||||
-f: Path
|
||||
-b: Average bitrate
|
||||
-C: Channels
|
||||
-s: Sample rate
|
||||
-m: Mofification time
|
||||
-M: Format
|
||||
|
||||
-A: Album artist
|
||||
-l: Album
|
||||
-a: Artist
|
||||
-c: Composer
|
||||
-d: Disc
|
||||
-g: Genre
|
||||
-p: Performer
|
||||
-t: Title
|
||||
-y: Year
|
||||
|
||||
-T <format>: date-time format (see 'man date' for possible values)
|
||||
-o -|<file>: output file (path relative to Source) - mandatory - must
|
||||
appear last.
|
||||
|
||||
-u: update database first
|
||||
-D: debug
|
||||
|
||||
checkextensions
|
||||
===============
|
||||
Reports files whose extension does not match the (detected) mime-type.
|
||||
|
||||
@ -112,8 +112,8 @@ getdstfiles() {
|
||||
done
|
||||
for line in "${lines[@]}"
|
||||
do
|
||||
fileid=${line%|*}
|
||||
filename=${line#*|}
|
||||
fileid=${line%::AtOM:SQL:Sep::*}
|
||||
filename=${line#*::AtOM:SQL:Sep::}
|
||||
echo $'\t'"$filename"
|
||||
(( rename )) && echo -n $'\t'
|
||||
(( rename )) && renameFile
|
||||
@ -149,12 +149,12 @@ do
|
||||
done
|
||||
for line in "${lines[@]}"
|
||||
do
|
||||
fileid=${line%%|*}
|
||||
rest="${line#*|}|"
|
||||
filename=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
mimetype=${rest%%|*}
|
||||
rest=${rest#*|}
|
||||
fileid=${line%%::AtOM:SQL:Sep::*}
|
||||
rest="${line#*::AtOM:SQL:Sep::}::AtOM:SQL:Sep::"
|
||||
filename=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
mimetype=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
dest=$sourcepath
|
||||
case "$mimetype" in
|
||||
'audio/mpeg')
|
||||
|
||||
@ -61,7 +61,7 @@ checkwanted() {
|
||||
for destination in "${!destinationpath[@]}"
|
||||
do
|
||||
echo -ne "\rScanning destination $destination... \033[K"
|
||||
while read filename
|
||||
while read -r filename
|
||||
do
|
||||
if ! Select destination_files id \
|
||||
>/dev/null \
|
||||
|
||||
435
toys/createindex
Executable file
435
toys/createindex
Executable file
@ -0,0 +1,435 @@
|
||||
#!/bin/bash
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
# config structures
|
||||
declare -A \
|
||||
destinationchannels \
|
||||
destinationfat32compat \
|
||||
destinationcopymime \
|
||||
destinationformat \
|
||||
destinationfrequency \
|
||||
destinationid \
|
||||
destinationloss \
|
||||
destinationmaxbps \
|
||||
destinationnormalize \
|
||||
destinationpath \
|
||||
destinationquality \
|
||||
destinationrename \
|
||||
destinationnoresample \
|
||||
destinationrenamepath \
|
||||
destinationskipmime \
|
||||
|| {
|
||||
echo "Check your Bash version. You need >= 4.0" >&2
|
||||
exit $EBASHVERS
|
||||
}
|
||||
|
||||
declare -r \
|
||||
DOCDIR=./doc \
|
||||
LIBDIR=./lib \
|
||||
SHAREDIR=./share
|
||||
declare -r \
|
||||
exampleconf=$DOCDIR/example.cfg \
|
||||
schema=$SHAREDIR/schema.sql \
|
||||
\
|
||||
oldIFS="$IFS"
|
||||
|
||||
cffile="$HOME/.atom/atom.cfg"
|
||||
|
||||
shopt -s extglob
|
||||
|
||||
for function in "$LIBDIR"/*/*
|
||||
do
|
||||
source "$function"
|
||||
done
|
||||
|
||||
while [ -n "$1" ]
|
||||
do
|
||||
opt="$1"
|
||||
shift
|
||||
case $opt in
|
||||
'-A') show+=(albumartists) ;;
|
||||
'-l') show+=(albums) ;;
|
||||
'-a') show+=(artists) ;;
|
||||
'-b') show+=(bitrates) ;;
|
||||
'-c') show+=(composers) ;;
|
||||
'-C') show+=(channelss) ;;
|
||||
'-d') show+=(discs) ;;
|
||||
'-f') show+=(path) ;;
|
||||
'-g') show+=(genres) ;;
|
||||
'-m') show+=(oldtimestamp) ;;
|
||||
'-M') show+=(types) ;;
|
||||
'-p') show+=(performers) ;;
|
||||
'-s') show+=(rates) ;;
|
||||
'-t') show+=(titles) ;;
|
||||
'-y') show+=(years) ;;
|
||||
|
||||
'-T') timeformat="$OPTARG" ;;
|
||||
'-o') output="$1"
|
||||
continue ;;
|
||||
'-u') update=1 ;;
|
||||
'-D') (( debug++ )) ;;
|
||||
[0-9]*) length[count-1]=$opt
|
||||
continue ;;
|
||||
esac
|
||||
(( count++ ))
|
||||
done
|
||||
|
||||
[ -z "$output" ] && {
|
||||
cat <<-EOHelp
|
||||
No output specified!
|
||||
-f Path
|
||||
-b Average bitrate
|
||||
-C Channels
|
||||
-s Sample rate
|
||||
-m Mofification time
|
||||
-M Format
|
||||
|
||||
-A Album artist
|
||||
-l Album
|
||||
-a Artist
|
||||
-c Composer
|
||||
-d Disc
|
||||
-g Genre
|
||||
-p Performer
|
||||
-t Title
|
||||
-y Year
|
||||
|
||||
-T <format>: date-time format (see 'man date' for possible values)
|
||||
-o <file> : output file (path relative to Source)
|
||||
|
||||
-u : update database first
|
||||
-D : debug
|
||||
EOHelp
|
||||
exit 1
|
||||
}
|
||||
|
||||
getConfig
|
||||
|
||||
openDatabase
|
||||
|
||||
columns="${show[@]//*/-}"
|
||||
|
||||
if ! [[ "$output" == - ]]
|
||||
then
|
||||
exec > "$output"
|
||||
fi
|
||||
|
||||
printPath() {
|
||||
for key in ${!pathparts[@]}
|
||||
do
|
||||
if [[ ${pathparts[key]} == ${oldpathparts[key]} ]]
|
||||
then
|
||||
echo -n " ${pathparts[key]//?/ }"
|
||||
else
|
||||
echo -n "${pathparts[key]}/"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
printline() {
|
||||
local print
|
||||
for index in ${!show[@]}
|
||||
do
|
||||
info="${show[index]}"
|
||||
locallength="${length[index]:=50}"
|
||||
path="$olddir"
|
||||
case $info in
|
||||
'bitrates')
|
||||
info=$((bitrates/count))
|
||||
(( info )) || unset info
|
||||
;;
|
||||
'oldtimestamp')
|
||||
info=$(printDate ${!info})
|
||||
;;
|
||||
'path')
|
||||
while [[ $path =~ / ]]
|
||||
do
|
||||
pathparts+=("${path%%/*}")
|
||||
path=${path#*/}
|
||||
done
|
||||
pathparts+=("$path")
|
||||
info=$(printPath)
|
||||
unset oldpathparts
|
||||
for key in ${!pathparts[@]}
|
||||
do
|
||||
oldpathparts[key]=${pathparts[key]}
|
||||
done
|
||||
unset pathparts
|
||||
;;
|
||||
*)
|
||||
info="${!info}"
|
||||
;;
|
||||
esac
|
||||
printtmp="${info:0:$locallength}"
|
||||
if [ -z "$printtmp" ]
|
||||
then
|
||||
until (( ${#printtmp} == locallength/2))
|
||||
do
|
||||
printtmp+=' '
|
||||
done
|
||||
printtmp+='-'
|
||||
fi
|
||||
until (( ${#printtmp} == locallength ))
|
||||
do
|
||||
printtmp+=' '
|
||||
done
|
||||
print+=(${print+|} "$printtmp")
|
||||
done
|
||||
echo "${print[@]}"
|
||||
}
|
||||
|
||||
if (( update ))
|
||||
then
|
||||
getFiles
|
||||
updateMimes
|
||||
updateTags
|
||||
fi
|
||||
|
||||
printDate() {
|
||||
date -d"@$1" +"${timeformat:-%x %X}"
|
||||
}
|
||||
|
||||
for index in ${!show[@]}
|
||||
do
|
||||
info="${show[index]}"
|
||||
locallength="${length[index]:=50}"
|
||||
case $info in
|
||||
albumartists) info="Album artist" ;;
|
||||
albums) info="Album" ;;
|
||||
artists) info="Artist" ;;
|
||||
bitrates) info="Bitrate" ;;
|
||||
composers) info="Composer" ;;
|
||||
channelss) info="Channels" ;;
|
||||
discs) info="Disc" ;;
|
||||
path) info="Directory name" ;;
|
||||
genres) info="Genre" ;;
|
||||
oldtimestamp) info="Last modified" ;;
|
||||
types) info="Format" ;;
|
||||
performers) info="Performer" ;;
|
||||
rates) info="Sample rate" ;;
|
||||
titles) info="Title" ;;
|
||||
years) info="Date" ;;
|
||||
esac
|
||||
printtmp="${info:0:$locallength}"
|
||||
until (( ${#printtmp} == locallength ))
|
||||
do
|
||||
printtmp+=' '
|
||||
done
|
||||
print+=(${print+|} "$printtmp")
|
||||
done
|
||||
echo "${print[@]}"
|
||||
echo "${print[@]//[^|]/=}"
|
||||
unset print
|
||||
|
||||
echo '
|
||||
SELECT
|
||||
source_files.filename,
|
||||
tags.bitrate,
|
||||
tags.channels,
|
||||
tags.rate,
|
||||
source_files.last_change,
|
||||
mime_types.mime_text,
|
||||
tags.albumartist,
|
||||
tags.album,
|
||||
tags.artist,
|
||||
tags.composer,
|
||||
tags.disc,
|
||||
tags.genre,
|
||||
tags.performer,
|
||||
tags.title,
|
||||
tags.year
|
||||
FROM source_files
|
||||
INNER JOIN mime_types
|
||||
ON source_files.mime_type=mime_types.id
|
||||
INNER JOIN tags
|
||||
ON source_files.id=tags.source_file
|
||||
WHERE
|
||||
NOT mime_types.mime_text LIKE "text/%"
|
||||
AND NOT mime_types.mime_text LIKE "image/%"
|
||||
ORDER BY source_files.filename
|
||||
COLLATE NOCASE;
|
||||
|
||||
SELECT "AtOM:NoMoreFiles";' >&3
|
||||
|
||||
read -u4 line
|
||||
until [[ $line == AtOM:NoMoreFiles ]]
|
||||
do
|
||||
files+=("$line")
|
||||
read -u4 line
|
||||
done
|
||||
|
||||
for line in "${files[@]}"
|
||||
do
|
||||
filename="${line%%::AtOM:SQL:Sep::*}"
|
||||
dir="${filename%/*}"
|
||||
rest="${line#*::AtOM:SQL:Sep::}::AtOM:SQL:Sep::"
|
||||
bitrate="${rest%%::AtOM:SQL:Sep::*}"
|
||||
rest="${rest#*::AtOM:SQL:Sep::}"
|
||||
channels="${rest%%::AtOM:SQL:Sep::*}"
|
||||
rest="${rest#*::AtOM:SQL:Sep::}"
|
||||
rate="${rest%%::AtOM:SQL:Sep::*}"
|
||||
rest="${rest#*::AtOM:SQL:Sep::}"
|
||||
timestamp="${rest%%::AtOM:SQL:Sep::*}"
|
||||
timestamp="${timestamp%%.*}"
|
||||
rest="${rest#*::AtOM:SQL:Sep::}"
|
||||
mimetype="${rest%%::AtOM:SQL:Sep::*}"
|
||||
rest="${rest#*::AtOM:SQL:Sep::}"
|
||||
albumartist="${rest%%::AtOM:SQL:Sep::*}"
|
||||
rest="${rest#*::AtOM:SQL:Sep::}"
|
||||
album="${rest%%::AtOM:SQL:Sep::*}"
|
||||
rest="${rest#*::AtOM:SQL:Sep::}"
|
||||
artist="${rest%%::AtOM:SQL:Sep::*}"
|
||||
rest="${rest#*::AtOM:SQL:Sep::}"
|
||||
composer="${rest%%::AtOM:SQL:Sep::*}"
|
||||
rest="${rest#*::AtOM:SQL:Sep::}"
|
||||
disc="${rest%%::AtOM:SQL:Sep::*}"
|
||||
rest="${rest#*::AtOM:SQL:Sep::}"
|
||||
genre="${rest%%::AtOM:SQL:Sep::*}"
|
||||
rest="${rest#*::AtOM:SQL:Sep::}"
|
||||
performer="${rest%%::AtOM:SQL:Sep::*}"
|
||||
rest="${rest#*::AtOM:SQL:Sep::}"
|
||||
title="${rest%%::AtOM:SQL:Sep::*}"
|
||||
rest="${rest#*::AtOM:SQL:Sep::}"
|
||||
year="${rest%%::AtOM:SQL:Sep::*}"
|
||||
rest="${rest#*::AtOM:SQL:Sep::}"
|
||||
case $mimetype in
|
||||
application/ogg\ opus) type=Opus ;;
|
||||
application/ogg\ vorbis) type=Vorbis ;;
|
||||
audio/mp4) type=MPEG4\ Audio;;
|
||||
audio/mpeg) type=MPEG\ Audio;;
|
||||
audio/x-flac) type=FLAC ;;
|
||||
video/mpeg) type=MPEG\ Video;;
|
||||
video/webm) type=WebM ;;
|
||||
audio/*) type=Other\ Audio;;
|
||||
video/*) type=Other\ Video;;
|
||||
*) type=Other ;;
|
||||
esac
|
||||
if [[ $dir == $olddir ]]
|
||||
then
|
||||
(( $bitrate )) && (( count++ , bitrates+=bitrate ))
|
||||
((
|
||||
oldtimestamp = (
|
||||
timestamp > oldtimestamp
|
||||
? timestamp
|
||||
: oldtimestamp
|
||||
)
|
||||
))
|
||||
expr1='(^|,)'
|
||||
expr2='(,|$)'
|
||||
if ! [[ $channelss =~ $expr1"$channels"$expr2 ]]
|
||||
then
|
||||
if [ -n "$channelss" ] \
|
||||
&& (( channels < ${channelss%%,*} ))
|
||||
then
|
||||
channelss="$channels,$channelss"
|
||||
else
|
||||
channelss+="${channelss+,}$channels"
|
||||
fi
|
||||
fi
|
||||
if ! [[ $rates =~ $expr1"$rate"$expr2 ]]
|
||||
then
|
||||
if [ -n "$rates" ] \
|
||||
&& (( rate < ${rates%%,*} ))
|
||||
then
|
||||
rates="$rate,$rates"
|
||||
else
|
||||
rates+="${rates+,}$rate"
|
||||
fi
|
||||
fi
|
||||
if ! [[ $types =~ $expr1"$type"$expr2 ]]
|
||||
then
|
||||
[ -z "$types" ] \
|
||||
&& unset types
|
||||
[ -n "$type" ] \
|
||||
&& types+="${types+,}$type"
|
||||
fi
|
||||
if ! [[ $albumartists =~ $expr1"$albumartist"$expr2 ]]
|
||||
then
|
||||
[ -z "$albumartists" ] \
|
||||
&& unset albumartists
|
||||
[ -n "$albumartist" ] \
|
||||
&& albumartists+="${albumartists+,}$albumartist"
|
||||
fi
|
||||
if ! [[ $albums =~ $expr1"$album"$expr2 ]]
|
||||
then
|
||||
[ -z "$albums" ] \
|
||||
&& unset albums
|
||||
[ -n "$album" ] \
|
||||
&& albums+="${albums+,}$album"
|
||||
fi
|
||||
if ! [[ $artists =~ $expr1"$artist"$expr2 ]]
|
||||
then
|
||||
[ -z "$artists" ] \
|
||||
&& unset artists
|
||||
[ -n "$artist" ] \
|
||||
&& artists+="${artists+,}$artist"
|
||||
fi
|
||||
if ! [[ $composers =~ $expr1"$composer"$expr2 ]]
|
||||
then
|
||||
[ -z "$composers" ] \
|
||||
&& unset composers
|
||||
[ -n "$composer" ] \
|
||||
&& composers+="${composers+,}$composer"
|
||||
fi
|
||||
if ! [[ $discs =~ $expr1"$disc"$expr2 ]]
|
||||
then
|
||||
[ -z "$discs" ] \
|
||||
&& unset discs
|
||||
[ -n "$disc" ] \
|
||||
&& discs+="${discs+,}$disc"
|
||||
fi
|
||||
if ! [[ $genres =~ $expr1"$genre"$expr2 ]]
|
||||
then
|
||||
[ -z "$genres" ] \
|
||||
&& unset genres
|
||||
[ -n "$genre" ] \
|
||||
&& genres+="${genres+,}$genre"
|
||||
fi
|
||||
if ! [[ $performers =~ $expr1"$performer"$expr2 ]]
|
||||
then
|
||||
[ -z "$performers" ] \
|
||||
&& unset performers
|
||||
[ -n "$performer" ] \
|
||||
&& performers+="${performers+,}$performer"
|
||||
fi
|
||||
if ! [[ $titles =~ $expr1"$title"$expr2 ]]
|
||||
then
|
||||
[ -z "$titles" ] \
|
||||
&& unset titles
|
||||
[ -n "$title" ] \
|
||||
&& titles+="${titles+,}$title"
|
||||
fi
|
||||
if ! [[ $years =~ $expr1"$year"$expr2 ]]
|
||||
then
|
||||
[ -z "$years" ] \
|
||||
&& unset years
|
||||
[ -n "$year" ] \
|
||||
&& years+="${years+,}$year"
|
||||
fi
|
||||
else
|
||||
if [ -n "$olddir" ]
|
||||
then
|
||||
printline
|
||||
fi
|
||||
unset bitrates
|
||||
channelss="$channels"
|
||||
rates="$rate"
|
||||
types="$type"
|
||||
albumartists="$albumartist"
|
||||
albums="$album"
|
||||
artists="$artist"
|
||||
composers="$composer"
|
||||
discs="$disc"
|
||||
genres="$genre"
|
||||
performers="$performer"
|
||||
titles="$title"
|
||||
years="$year"
|
||||
(( bitrate )) && (( count=1 , bitrates=bitrate ))
|
||||
oldmimetype=$mimetype
|
||||
oldrate=$rate
|
||||
oldtimestamp=$timestamp
|
||||
fi
|
||||
olddir="$dir"
|
||||
done
|
||||
printline
|
||||
130
toys/lowquality
Executable file
130
toys/lowquality
Executable file
@ -0,0 +1,130 @@
|
||||
#!/bin/bash
|
||||
|
||||
# config structures
|
||||
declare -A \
|
||||
destinationchannels \
|
||||
destinationfat32compat \
|
||||
destinationcopymime \
|
||||
destinationformat \
|
||||
destinationfrequency \
|
||||
destinationid \
|
||||
destinationloss \
|
||||
destinationmaxbps \
|
||||
destinationnormalize \
|
||||
destinationpath \
|
||||
destinationquality \
|
||||
destinationrename \
|
||||
destinationnoresample \
|
||||
destinationrenamepath \
|
||||
destinationskipmime \
|
||||
|| {
|
||||
echo "Check your Bash version. You need >= 4.0" >&2
|
||||
exit $EBASHVERS
|
||||
}
|
||||
|
||||
declare -r \
|
||||
DOCDIR=./doc \
|
||||
LIBDIR=./lib \
|
||||
SHAREDIR=./share
|
||||
declare -r \
|
||||
exampleconf=$DOCDIR/example.cfg \
|
||||
schema=$SHAREDIR/schema.sql \
|
||||
\
|
||||
oldIFS="$IFS"
|
||||
|
||||
cffile="$HOME/.atom/atom.cfg"
|
||||
LC_ALL=C
|
||||
|
||||
shopt -s extglob
|
||||
|
||||
for function in "$LIBDIR"/*/*
|
||||
do
|
||||
source "$function"
|
||||
done
|
||||
|
||||
while getopts 'fm:o:p:*:uD' opt
|
||||
do
|
||||
case $opt in
|
||||
f) mimetypes+=("audio/x-flac")
|
||||
bitrates+=("")
|
||||
;;
|
||||
m) mimetypes+=("audio/mpeg")
|
||||
bitrates+=("$OPTARG")
|
||||
;;
|
||||
o) mimetypes+=("application/ogg vorbis")
|
||||
bitrates+=("$OPTARG")
|
||||
;;
|
||||
p) mimetypes+=("application/ogg opus")
|
||||
bitrates+=("$OPTARG")
|
||||
;;
|
||||
\*) mimetypes+=("*")
|
||||
bitrates+=("$OPTARG")
|
||||
;;
|
||||
|
||||
u) update=1 ;;
|
||||
D) (( debug++ )) ;;
|
||||
esac
|
||||
done
|
||||
|
||||
getConfig
|
||||
|
||||
openDatabase
|
||||
|
||||
if (( update ))
|
||||
then
|
||||
getFiles
|
||||
updateMimes
|
||||
updateTags
|
||||
fi
|
||||
|
||||
echo '
|
||||
SELECT DISTINCT
|
||||
mime_type_actions.mime_text,
|
||||
tags.bitrate,
|
||||
source_files.filename
|
||||
FROM source_files
|
||||
INNER JOIN tags
|
||||
ON source_files.id=tags.source_file
|
||||
INNER JOIN mime_type_actions
|
||||
ON mime_type_actions.id=source_files.mime_type
|
||||
WHERE mime_type_actions.action=1
|
||||
AND (
|
||||
' >&3
|
||||
|
||||
for indice in ${!mimetypes[@]}
|
||||
do
|
||||
(( notfirst )) && echo OR >&3
|
||||
case ${mimetypes[indice]} in
|
||||
'audio/x-flac')
|
||||
echo 'mime_type_actions.mime_text="audio/x-flac"'>&3
|
||||
;;
|
||||
'*')
|
||||
echo '( (
|
||||
NOT mime_type_actions.mime_text="audio/x-flac"
|
||||
AND NOT mime_type_actions.mime_text="audio/mpeg"
|
||||
AND NOT
|
||||
mime_type_actions.mime_text="application/ogg vorbis"
|
||||
AND NOT
|
||||
mime_type_actions.mime_text="application/ogg opus"
|
||||
) AND tags.bitrate < '${bitrates[indice]}' )' >&3
|
||||
;;
|
||||
*)
|
||||
echo '(
|
||||
mime_type_actions.mime_text="'"${mimetypes[indice]}"'"
|
||||
AND tags.bitrate < '${bitrates[indice]}' )' >&3
|
||||
;;
|
||||
esac
|
||||
notfirst=1
|
||||
done
|
||||
echo ') ORDER BY bitrate;' >&3
|
||||
|
||||
echo 'SELECT "AtOM:NoMoreFiles";' >&3
|
||||
|
||||
read -u4 line
|
||||
until [[ $line == AtOM:NoMoreFiles ]]
|
||||
do
|
||||
echo "${line//::AtOM:SQL:Sep::/$'\t'}"
|
||||
read -u4 line
|
||||
done
|
||||
|
||||
closeDatabase
|
||||
@ -93,29 +93,17 @@ if (( update ))
|
||||
then
|
||||
getFiles
|
||||
updateMimes
|
||||
updateTags
|
||||
fi
|
||||
|
||||
for check in ${!checks[@]}
|
||||
do
|
||||
case $check in
|
||||
albumartist)
|
||||
cat >&2 <<-EONotice
|
||||
Album artist is not supported for ID3. Files in this format will be ignored by
|
||||
this check (other checks still apply).
|
||||
EONotice
|
||||
mimemp3=$(
|
||||
Select mime_types id <<<"mime_text = audio/mpeg"
|
||||
)
|
||||
whereclause+="${whereclause+ OR }("
|
||||
whereclause+='tags.albumartist IS NULL '
|
||||
whereclause+="AND NOT tags.tagreader LIKE \"ID3-%\""
|
||||
whereclause+=')'
|
||||
;;
|
||||
tracktotal)
|
||||
whereclause+="${whereclause+ OR }NOT tags.track LIKE \"%/%\""
|
||||
whereclause+="${whereclause+OR }NOT tags.track LIKE \"%/%\""
|
||||
;;
|
||||
*)
|
||||
whereclause+="${whereclause+ OR }tags.$check IS NULL"
|
||||
whereclause+="${whereclause+OR }tags.$check IS NULL"
|
||||
;;
|
||||
esac
|
||||
whereclause+='
|
||||
@ -137,8 +125,15 @@ cat >&3 <<-EOSelect
|
||||
FROM tags
|
||||
INNER JOIN source_files
|
||||
ON tags.source_file=source_files.id
|
||||
WHERE $whereclause
|
||||
AND NOT tags.tagreader LIKE "unknown-%";
|
||||
INNER JOIN mime_types
|
||||
ON source_files.mime_type=mime_types.id
|
||||
WHERE (
|
||||
$whereclause
|
||||
)
|
||||
AND NOT tags.tagreader LIKE "unknown-%"
|
||||
AND NOT mime_types.mime_text LIKE "text/%"
|
||||
AND NOT mime_types.mime_text LIKE "image/%"
|
||||
;
|
||||
|
||||
SELECT "AtOM:NoMoreFiles";
|
||||
EOSelect
|
||||
@ -153,33 +148,33 @@ done
|
||||
for line in "${lines[@]}"
|
||||
do
|
||||
missing=()
|
||||
filename=${line%%|*}
|
||||
rest="${line#*|}|"
|
||||
(( ${checks[genre]} )) && [ -z "${rest%%|*}" ] && missing+=( "Genre" )
|
||||
rest=${rest#*|}
|
||||
(( ${checks[albumartist]} )) && [ -z "${rest%%|*}" ] && missing+=( "AlbumArtist" )
|
||||
rest=${rest#*|}
|
||||
(( ${checks[year]} )) && [ -z "${rest%%|*}" ] && missing+=( "Year" )
|
||||
rest=${rest#*|}
|
||||
(( ${checks[album]} )) && [ -z "${rest%%|*}" ] && missing+=( "Album" )
|
||||
rest=${rest#*|}
|
||||
(( ${checks[disc]} )) && [ -z "${rest%%|*}" ] && missing+=( "Disc" )
|
||||
rest=${rest#*|}
|
||||
(( ${checks[artist]} )) && [ -z "${rest%%|*}" ] && missing+=( "Artist" )
|
||||
rest=${rest#*|}
|
||||
track=${rest%%|*}
|
||||
filename=${line%%::AtOM:SQL:Sep::*}
|
||||
rest="${line#*::AtOM:SQL:Sep::}::AtOM:SQL:Sep::"
|
||||
(( ${checks[genre]} )) && [ -z "${rest%%::AtOM:SQL:Sep::*}" ] && missing+=( "Genre" )
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
(( ${checks[albumartist]} )) && [ -z "${rest%%::AtOM:SQL:Sep::*}" ] && missing+=( "AlbumArtist" )
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
(( ${checks[year]} )) && [ -z "${rest%%::AtOM:SQL:Sep::*}" ] && missing+=( "Year" )
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
(( ${checks[album]} )) && [ -z "${rest%%::AtOM:SQL:Sep::*}" ] && missing+=( "Album" )
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
(( ${checks[disc]} )) && [ -z "${rest%%::AtOM:SQL:Sep::*}" ] && missing+=( "Disc" )
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
(( ${checks[artist]} )) && [ -z "${rest%%::AtOM:SQL:Sep::*}" ] && missing+=( "Artist" )
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
track=${rest%%::AtOM:SQL:Sep::*}
|
||||
(( ${checks[track]} )) && [ -z "$track" ] && missing+=( "Track" )
|
||||
if (( ${checks[tracktotal]} )) && ! [[ $track =~ / ]]
|
||||
then
|
||||
missing+=( TrackTotal )
|
||||
fi
|
||||
rest=${rest#*|}
|
||||
(( ${checks[title]} )) && [ -z "${rest%%|*}" ] && missing+=( "Title" )
|
||||
rest=${rest#*|}
|
||||
(( ${checks[composer]} )) && [ -z "${rest%%|*}" ] && missing+=( "Composer" )
|
||||
rest=${rest#*|}
|
||||
(( ${checks[performer]} )) && [ -z "${rest%%|*}" ] && missing+=( "Performer" )
|
||||
rest=${rest#*|}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
(( ${checks[title]} )) && [ -z "${rest%%::AtOM:SQL:Sep::*}" ] && missing+=( "Title" )
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
(( ${checks[composer]} )) && [ -z "${rest%%::AtOM:SQL:Sep::*}" ] && missing+=( "Composer" )
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
(( ${checks[performer]} )) && [ -z "${rest%%::AtOM:SQL:Sep::*}" ] && missing+=( "Performer" )
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
echo "$filename: ${missing[@]}"
|
||||
done
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user