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:
|
Optional:
|
||||||
* vorbis-tools
|
* vorbis-tools
|
||||||
http://www.vorbis.com/
|
http://www.vorbis.com/
|
||||||
* ogginfo (Ogg Vorbis tags support)
|
* ogginfo (Ogg Vorbis metadata)
|
||||||
* oggenc (Ogg Vorbis destination)
|
* oggenc (Ogg Vorbis encoding)
|
||||||
* opus-tools
|
* opus-tools
|
||||||
http://opus-codec.org/
|
http://opus-codec.org/
|
||||||
* opusinfo (Opus tags support)
|
* opusinfo (Opus metadata)
|
||||||
* opusenc (Opus destination)
|
* opusenc (Opus encoding)
|
||||||
|
* opusdec (Opus decoding)
|
||||||
* LAME MP3 Encoder
|
* LAME MP3 Encoder
|
||||||
http://lame.sourceforge.net/
|
http://lame.sourceforge.net/
|
||||||
* lame (MP3 destination)
|
* lame (MP3 encoding)
|
||||||
* FLAC
|
* FLAC
|
||||||
http://flac.sourceforge.net/
|
http://flac.sourceforge.net/
|
||||||
* metaflac (FLAC tags support)
|
* metaflac (FLAC metadata)
|
||||||
* Musepack
|
* Musepack
|
||||||
http://www.musepack.net/
|
http://www.musepack.net/
|
||||||
* mpcdec (Musepack decoding)
|
* mpcdec (Musepack decoding)
|
||||||
|
* FFmpeg
|
||||||
|
http://ffmpeg.org/
|
||||||
|
* ffprobe (ID3v2, Musepack, Windows Media and video metadata)
|
||||||
|
* ffmpeg (Windows Media and video decoding)
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Using the software
|
Using the software
|
||||||
@ -41,3 +46,33 @@ Using the software
|
|||||||
Configuration:
|
Configuration:
|
||||||
Please read doc/config before anything else.
|
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
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
#FIXME: check sanity
|
|
||||||
|
|
||||||
if [ ! -f "$cffile" ]
|
if [ ! -f "$cffile" ]
|
||||||
then
|
then
|
||||||
if [ ! -d ~/.atom ]
|
if [ ! -d ~/.atom ]
|
||||||
@ -117,9 +115,143 @@ fi
|
|||||||
getConfig
|
getConfig
|
||||||
|
|
||||||
set +H
|
set +H
|
||||||
|
|
||||||
|
# Apply CLI overrides
|
||||||
|
[ -n "$cliload" ] && maxload=$cliload
|
||||||
|
[ -n "$cliltimer" ] && loadinterval=$cliltimer
|
||||||
|
|
||||||
(( debug || cfgdump )) && printConfig
|
(( debug || cfgdump )) && printConfig
|
||||||
(( cfgdump )) && exit
|
(( 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
|
openDatabase
|
||||||
|
|
||||||
createDestinations
|
createDestinations
|
||||||
@ -144,8 +276,8 @@ removed=0
|
|||||||
read -u4 line
|
read -u4 line
|
||||||
until [[ $line == AtOM:NoMoreFiles ]]
|
until [[ $line == AtOM:NoMoreFiles ]]
|
||||||
do
|
do
|
||||||
id=${line%|*}
|
id=${line%::AtOM:SQL:Sep::*}
|
||||||
filename=${line#*|}
|
filename=${line#*::AtOM:SQL:Sep::}
|
||||||
if [ -n "$filename" ]
|
if [ -n "$filename" ]
|
||||||
then
|
then
|
||||||
if rm -f "$filename"
|
if rm -f "$filename"
|
||||||
@ -161,115 +293,20 @@ do
|
|||||||
done
|
done
|
||||||
echo "Suppressed $deleted files, $removed removed from database"
|
echo "Suppressed $deleted files, $removed removed from database"
|
||||||
|
|
||||||
# get files
|
updateTags
|
||||||
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;
|
|
||||||
|
|
||||||
SELECT "AtOM:NoMoreFiles";' >&3
|
for forcedest in "${forceall[@]}"
|
||||||
read -u4 line
|
|
||||||
while ! [[ $line = AtOM:NoMoreFiles ]]
|
|
||||||
do
|
do
|
||||||
tagfiles+=("$line")
|
if forcedestid=$(Select destinations id <<<"name = $forcedest")
|
||||||
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 ))
|
|
||||||
then
|
then
|
||||||
echo 'COMMIT;BEGIN TRANSACTION;' >&3
|
echo "Resetting destination files timestamps on" \
|
||||||
(( debug )) \
|
"$forcedest ($forcedestid)..."
|
||||||
&& echo -n " $count files read, committing..."
|
Update destination_files last_change 1 \
|
||||||
fi
|
<<<"destination_id = $forcedestid"
|
||||||
if getTags
|
else
|
||||||
then
|
echo "Destination $forcedest does not exist!" >&2
|
||||||
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
|
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
echo 'COMMIT;' >&3
|
|
||||||
echo -e "\rRead tags from ${count:-0} files."
|
|
||||||
unset count tagfiles
|
|
||||||
|
|
||||||
echo '
|
echo '
|
||||||
CREATE TEMPORARY TABLE tasks(
|
CREATE TEMPORARY TABLE tasks(
|
||||||
@ -376,7 +413,7 @@ echo '
|
|||||||
read -u4 line
|
read -u4 line
|
||||||
while ! [[ $line = AtOM:NoMoreFiles ]]
|
while ! [[ $line = AtOM:NoMoreFiles ]]
|
||||||
do
|
do
|
||||||
decodefiles+=("$line|")
|
decodefiles+=("$line::AtOM:SQL:Sep::")
|
||||||
read -u4 line
|
read -u4 line
|
||||||
done
|
done
|
||||||
echo -n 'Creating tasks... '
|
echo -n 'Creating tasks... '
|
||||||
@ -384,42 +421,47 @@ echo -n 'Creating tasks... '
|
|||||||
echo 'BEGIN TRANSACTION;' >&3
|
echo 'BEGIN TRANSACTION;' >&3
|
||||||
for line in "${decodefiles[@]}"
|
for line in "${decodefiles[@]}"
|
||||||
do
|
do
|
||||||
fileid=${line%%|*}
|
fileid=${line%%::AtOM:SQL:Sep::*}
|
||||||
rest=${line#*|}
|
rest=${line#*::AtOM:SQL:Sep::}
|
||||||
filename=${rest%%|*}
|
filename=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
mimetype=${rest%%|*}
|
mimetype=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
destination=${rest%%|*}
|
destination=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
destfileid=${rest%%|*}
|
destfileid=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
rate=${rest%%|*}
|
rate=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
channels=${rest%%|*}
|
channels=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
bitrate=${rest%%|*}
|
bitrate=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
genre=${rest%%|*}
|
genre=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
albumartist=${rest%%|*}
|
albumartist=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
year=${rest%%|*}
|
year=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
album=${rest%%|*}
|
album=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
disc=${rest%%|*}
|
disc=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
artist=${rest%%|*}
|
artist=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
track=${rest%%|*}
|
track=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
title=${rest%%|*}
|
title=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
composer=${rest%%|*}
|
composer=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
performer=${rest%%|*}
|
performer=${rest%%::AtOM:SQL:Sep::*}
|
||||||
unset rest
|
unset rest
|
||||||
|
case ${destinationformat["$destination"]} in
|
||||||
|
vorbis) (( disableoggenc )) && continue ;;
|
||||||
|
opus) (( disableopusenc )) && continue ;;
|
||||||
|
mp3) (( disablelame )) && continue ;;
|
||||||
|
esac
|
||||||
decodeFile
|
decodeFile
|
||||||
getDestDir
|
getDestDir
|
||||||
getDestFile
|
getDestFile
|
||||||
@ -502,13 +544,13 @@ do
|
|||||||
checkworkers
|
checkworkers
|
||||||
cleaner
|
cleaner
|
||||||
master
|
master
|
||||||
if (( ran ))
|
if (( ran - failed ))
|
||||||
then
|
then
|
||||||
currenttime=$(date +%s)
|
currenttime=$(date +%s)
|
||||||
avgduration=$((
|
avgduration=$((
|
||||||
((currenttime - starttime) * 1000)
|
((currenttime - starttime) * 1000)
|
||||||
/
|
/
|
||||||
ran
|
( ran - failed )
|
||||||
))
|
))
|
||||||
secsremaining=$(( remaining * avgduration / 1000 ))
|
secsremaining=$(( remaining * avgduration / 1000 ))
|
||||||
(( days =
|
(( days =
|
||||||
@ -647,32 +689,32 @@ do
|
|||||||
echo -n "$destination: rename pattern changed, renaming files... "
|
echo -n "$destination: rename pattern changed, renaming files... "
|
||||||
while [[ $line != AtOM:NoMoreFiles ]]
|
while [[ $line != AtOM:NoMoreFiles ]]
|
||||||
do
|
do
|
||||||
oldfilename=${line%%|*}
|
oldfilename=${line%%::AtOM:SQL:Sep::*}
|
||||||
rest=${line#*|}'|'
|
rest=${line#*::AtOM:SQL:Sep::}'::AtOM:SQL:Sep::'
|
||||||
destfileid=${rest%%|*}
|
destfileid=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
filename=${rest%%|*}
|
filename=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
album=${rest%%|*}
|
album=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
albumartist=${rest%%|*}
|
albumartist=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
artist=${rest%%|*}
|
artist=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
composer=${rest%%|*}
|
composer=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
disc=${rest%%|*}
|
disc=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
genre=${rest%%|*}
|
genre=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
performer=${rest%%|*}
|
performer=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
title=${rest%%|*}
|
title=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
track=${rest%%|*}
|
track=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
year=${rest%%|*}
|
year=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
if [ -n "$oldfilename" -a -f "$oldfilename" ]
|
if [ -n "$oldfilename" -a -f "$oldfilename" ]
|
||||||
then
|
then
|
||||||
getDestDir
|
getDestDir
|
||||||
@ -720,11 +762,11 @@ done
|
|||||||
echo 'BEGIN TRANSACTION;' >&3
|
echo 'BEGIN TRANSACTION;' >&3
|
||||||
for line in "${lines[@]}"
|
for line in "${lines[@]}"
|
||||||
do
|
do
|
||||||
id=${line%%|*}
|
id=${line%%::AtOM:SQL:Sep::*}
|
||||||
rest=${line#*|}
|
rest=${line#*::AtOM:SQL:Sep::}
|
||||||
filename=${rest%%|*}
|
filename=${rest%%::AtOM:SQL:Sep::*}
|
||||||
oldfilename=${rest#*|}
|
oldfilename=${rest#*::AtOM:SQL:Sep::}
|
||||||
if [[ $oldfilename != $filename ]] && [ -f "$oldfilename" ]
|
if [[ $oldfilename != "$filename" ]] && [ -f "$oldfilename" ]
|
||||||
then
|
then
|
||||||
rm -f "$oldfilename"
|
rm -f "$oldfilename"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@ -8,12 +8,15 @@ getConfigDestination() {
|
|||||||
case "$value" in
|
case "$value" in
|
||||||
'mp3')
|
'mp3')
|
||||||
destinationformat["$destination"]=mp3
|
destinationformat["$destination"]=mp3
|
||||||
|
lameneeded=1
|
||||||
;;
|
;;
|
||||||
'opus')
|
'opus')
|
||||||
destinationformat["$destination"]=opus
|
destinationformat["$destination"]=opus
|
||||||
|
opusencneeded=1
|
||||||
;;
|
;;
|
||||||
'vorbis')
|
'vorbis')
|
||||||
destinationformat["$destination"]=vorbis
|
destinationformat["$destination"]=vorbis
|
||||||
|
oggencneeded=1
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Unsupported destination format: $value" >2&
|
echo "Unsupported destination format: $value" >2&
|
||||||
|
|||||||
@ -6,6 +6,7 @@ copyFiles_action() {
|
|||||||
source_files.filename,
|
source_files.filename,
|
||||||
source_files.last_change,
|
source_files.last_change,
|
||||||
destinations.id,
|
destinations.id,
|
||||||
|
destinations.name,
|
||||||
destination_files.id
|
destination_files.id
|
||||||
FROM source_files
|
FROM source_files
|
||||||
INNER JOIN destination_files
|
INNER JOIN destination_files
|
||||||
@ -31,36 +32,43 @@ copyFiles_action() {
|
|||||||
echo 'BEGIN TRANSACTION;' >&3
|
echo 'BEGIN TRANSACTION;' >&3
|
||||||
for copyfile in "${copyfiles[@]}"
|
for copyfile in "${copyfiles[@]}"
|
||||||
do
|
do
|
||||||
sourcefilename=${copyfile%%|*}
|
sourcefilename=${copyfile%%::AtOM:SQL:Sep::*}
|
||||||
sourcedir=${sourcefilename%/*}
|
sourcedir=${sourcefilename%/*}
|
||||||
rest="${copyfile#*|}|"
|
rest="${copyfile#*::AtOM:SQL:Sep::}::AtOM:SQL:Sep::"
|
||||||
lastchange=${rest%%|*}
|
lastchange=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
destinationid=${rest%%|*}
|
destinationid=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
destfileid=${rest%%|*}
|
destination=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
echo 'SELECT IFNULL( (
|
destfileid=${rest%%::AtOM:SQL:Sep::*}
|
||||||
SELECT destination_files.filename
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
FROM destination_files
|
(( count++ ))
|
||||||
INNER JOIN source_files
|
printf '\b\b\b\b%3i%%' $(( (count * 100) / ${#copyfiles[@]} ))
|
||||||
ON destination_files.source_file_id=source_files.id
|
if [ -n "${renamepath["$destination"]}" ]
|
||||||
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
|
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\
|
if cp -al "$sourcepath/$sourcefilename" "$destdir" 2>/dev/null\
|
||||||
|| cp -a "$sourcepath/$sourcefilename" "$destdir"
|
|| cp -a "$sourcepath/$sourcefilename" "$destdir"
|
||||||
then
|
then
|
||||||
@ -73,11 +81,13 @@ copyFiles_action() {
|
|||||||
EOWhere
|
EOWhere
|
||||||
(( done++ ))
|
(( done++ ))
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
(( count++ ))
|
|
||||||
printf '\b\b\b\b%3i%%' $(( (count * 100) / ${#copyfiles[@]} ))
|
|
||||||
done
|
done
|
||||||
echo 'COMMIT;' >&3
|
echo 'COMMIT;' >&3
|
||||||
|
if (( count ))
|
||||||
|
then
|
||||||
echo -e "\rCopied ${done:-0} of $count files.\033[K"
|
echo -e "\rCopied ${done:-0} of $count files.\033[K"
|
||||||
|
else
|
||||||
|
echo -e "\rNothing to copy.\033[K"
|
||||||
|
fi
|
||||||
unset count done
|
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_keys+='`'"$key"'`'
|
||||||
(( ${#insert_values} )) && insert_values+=","
|
(( ${#insert_values} )) && insert_values+=","
|
||||||
case $value in
|
case $value in
|
||||||
|
'::AtOM:FT::'*)
|
||||||
|
value="${value//::AtOM:FT::/}"
|
||||||
|
insert_values+='"'"${value//\"/\"\"}"'"'
|
||||||
|
;;
|
||||||
'NULL')
|
'NULL')
|
||||||
insert_values+="NULL"
|
insert_values+="NULL"
|
||||||
;;
|
;;
|
||||||
|
|||||||
@ -25,7 +25,8 @@ InsertIfUnset() {
|
|||||||
Select "$table" "$column" < <(
|
Select "$table" "$column" < <(
|
||||||
for key in ${!keys[@]}
|
for key in ${!keys[@]}
|
||||||
do
|
do
|
||||||
echo "${keys[$key]}" = "${values[$key]}"
|
echo "${keys[$key]}" = \
|
||||||
|
"${values[$key]//::AtOM:FT::}"
|
||||||
done
|
done
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@ -26,6 +26,10 @@ Update() {
|
|||||||
;;
|
;;
|
||||||
value)
|
value)
|
||||||
case $argument in
|
case $argument in
|
||||||
|
'::AtOM:FT::'*)
|
||||||
|
argument="${argument//::AtOM:FT::/}"
|
||||||
|
set_statement+=" = "'"'"${argument//\"/\"\"}"'"'
|
||||||
|
;;
|
||||||
'NULL')
|
'NULL')
|
||||||
set_statement+=" = NULL"
|
set_statement+=" = NULL"
|
||||||
;;
|
;;
|
||||||
|
|||||||
@ -1,19 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
openDatabase() {
|
openDatabase() {
|
||||||
if [ ! -d "$tempdir" ]
|
|
||||||
then
|
|
||||||
mkdir -p "$tempdir"
|
|
||||||
fi
|
|
||||||
rm -f "$tempdir"/sqlite.{in,out}
|
rm -f "$tempdir"/sqlite.{in,out}
|
||||||
mkfifo "$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" \
|
sqlite3 -bail "$database" \
|
||||||
< "$tempdir/sqlite.in" \
|
< "$tempdir/sqlite.in" \
|
||||||
> "$tempdir/sqlite.out" &
|
> "$tempdir/sqlite.out" &
|
||||||
@ -24,5 +12,7 @@ openDatabase() {
|
|||||||
exec 5>&3
|
exec 5>&3
|
||||||
exec 3> >(tee -a $tempdir/debug.log >&5)
|
exec 3> >(tee -a $tempdir/debug.log >&5)
|
||||||
fi
|
fi
|
||||||
|
cat $schema >&3
|
||||||
|
echo '.separator ::AtOM:SQL:Sep::' >&3
|
||||||
echo 'PRAGMA foreign_keys = ON;' >&3
|
echo 'PRAGMA foreign_keys = ON;' >&3
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
decodeFile() {
|
decodeFile() {
|
||||||
case "$mimetype" in
|
case "$mimetype" in
|
||||||
'video/'*)
|
'video/'*)
|
||||||
|
(( disablevideo )) && continue
|
||||||
extractAudio
|
extractAudio
|
||||||
if (( ${destinationnormalize["$destination"]}))\
|
if (( ${destinationnormalize["$destination"]}))\
|
||||||
|| (
|
|| (
|
||||||
@ -30,6 +31,7 @@ decodeFile() {
|
|||||||
then
|
then
|
||||||
copied=1
|
copied=1
|
||||||
else
|
else
|
||||||
|
(( disableopusdec )) && continue
|
||||||
decodeOpusdec
|
decodeOpusdec
|
||||||
if (( ${destinationnormalize["$destination"]}))\
|
if (( ${destinationnormalize["$destination"]}))\
|
||||||
|| (
|
|| (
|
||||||
@ -60,6 +62,7 @@ decodeFile() {
|
|||||||
extendedtype=$(file -b "$sourcepath/$filename")
|
extendedtype=$(file -b "$sourcepath/$filename")
|
||||||
case "$extendedtype" in
|
case "$extendedtype" in
|
||||||
*'Musepack '*)
|
*'Musepack '*)
|
||||||
|
(( disablempcdec )) && continue
|
||||||
decodeMpcdec
|
decodeMpcdec
|
||||||
if (( ${destinationnormalize["$destination"]}))\
|
if (( ${destinationnormalize["$destination"]}))\
|
||||||
|| (
|
|| (
|
||||||
|
|||||||
@ -51,7 +51,12 @@ encodeFile::mp3() {
|
|||||||
$(
|
$(
|
||||||
for key in ${!lameopts[@]}
|
for key in ${!lameopts[@]}
|
||||||
do
|
do
|
||||||
echo "cmd_arg$key ${lameopts[key]}"
|
cleanedopts="${lameopts[key]//\&/\\\&}"
|
||||||
|
cleanedopts="${cleanedopts//\[/\\[}"
|
||||||
|
cleanedopts="${cleanedopts//\]/\\]}"
|
||||||
|
cleanedopts="${cleanedopts//\{/\\{}"
|
||||||
|
cleanedopts="${cleanedopts//\}/\\\}}"
|
||||||
|
echo "cmd_arg$key $cleanedopts"
|
||||||
done
|
done
|
||||||
)
|
)
|
||||||
cleanup $tempdir/$tmpfile.wav
|
cleanup $tempdir/$tmpfile.wav
|
||||||
|
|||||||
@ -26,7 +26,12 @@ encodeFile::opus() {
|
|||||||
$(
|
$(
|
||||||
for key in ${!opusencopts[@]}
|
for key in ${!opusencopts[@]}
|
||||||
do
|
do
|
||||||
echo "cmd_arg$key ${opusencopts[key]}"
|
cleanedopts="${opusencopts[key]//\&/\\\&}"
|
||||||
|
cleanedopts="${cleanedopts//\[/\\[}"
|
||||||
|
cleanedopts="${cleanedopts//\]/\\]}"
|
||||||
|
cleanedopts="${cleanedopts//\{/\\{}"
|
||||||
|
cleanedopts="${cleanedopts//\}/\\\}}"
|
||||||
|
echo "cmd_arg$key $cleanedopts"
|
||||||
done
|
done
|
||||||
)
|
)
|
||||||
cleanup $tempdir/$tmpfile.wav
|
cleanup $tempdir/$tmpfile.wav
|
||||||
|
|||||||
@ -22,6 +22,11 @@ encodeFile::vorbis() {
|
|||||||
$(
|
$(
|
||||||
for key in ${!oggencopts[@]}
|
for key in ${!oggencopts[@]}
|
||||||
do
|
do
|
||||||
|
cleanedopts="${oggencopts[key]//\&/\\\&}"
|
||||||
|
cleanedopts="${cleanedopts//\[/\\[}"
|
||||||
|
cleanedopts="${cleanedopts//\]/\\]}"
|
||||||
|
cleanedopts="${cleanedopts//\{/\\{}"
|
||||||
|
cleanedopts="${cleanedopts//\}/\\\}}"
|
||||||
echo "cmd_arg$key ${oggencopts[key]}"
|
echo "cmd_arg$key ${oggencopts[key]}"
|
||||||
done
|
done
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,7 +1,34 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
getDestDir() {
|
getDestDir() {
|
||||||
destdir="${destinationpath[$destination]}/"
|
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
|
then
|
||||||
replace=$(sanitizeFile "$album" dir)
|
replace=$(sanitizeFile "$album" dir)
|
||||||
destdir+="${destinationrenamepath[$destination]//%\{album\}/$replace}"
|
destdir+="${destinationrenamepath[$destination]//%\{album\}/$replace}"
|
||||||
|
|||||||
@ -1,6 +1,33 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
getDestFile() {
|
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
|
then
|
||||||
destfile="${destinationrename[$destination]//%\{album\}/$album}"
|
destfile="${destinationrename[$destination]//%\{album\}/$album}"
|
||||||
destfile="${destfile//%\{albumartist\}/$albumartist}"
|
destfile="${destfile//%\{albumartist\}/$albumartist}"
|
||||||
|
|||||||
@ -19,7 +19,7 @@ getFiles() {
|
|||||||
mimetype=$(file -b --mime-type "$sourcepath/$filename")
|
mimetype=$(file -b --mime-type "$sourcepath/$filename")
|
||||||
if [[ $mimetype == application/ogg ]]
|
if [[ $mimetype == application/ogg ]]
|
||||||
then
|
then
|
||||||
case "$(head -n1 "$sourcepath/$filename")" in
|
case "$(head -n5 "$sourcepath/$filename")" in
|
||||||
*'vorbis'*)
|
*'vorbis'*)
|
||||||
mimetype+=' 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
|
#!/bin/bash
|
||||||
getInfosOgg_version='Ogg-1'
|
getInfosOgg_version='Ogg-2'
|
||||||
tagreaders+=( "$getInfosOgg_version" )
|
tagreaders+=( "$getInfosOgg_version" )
|
||||||
getInfos::Ogg() {
|
getInfos::Ogg() {
|
||||||
tagreader="$getInfosOgg_version"
|
tagreader="$getInfosOgg_version"
|
||||||
@ -22,9 +22,9 @@ 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 'average bitrate')
|
||||||
bitrate=${bitrate%%,*}
|
bitrate=${bitrate%%,*}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
getInfosOpus_version='Opus-1'
|
getInfosOpus_version='Opus-2'
|
||||||
tagreaders+=( "$getInfosOpus_version" )
|
tagreaders+=( "$getInfosOpus_version" )
|
||||||
getInfos::Opus() {
|
getInfos::Opus() {
|
||||||
tagreader="$getInfosOpus_version"
|
tagreader="$getInfosOpus_version"
|
||||||
@ -22,7 +22,7 @@ getInfos::Opus() {
|
|||||||
tracknum="$tracknum/$tracktotal"
|
tracknum="$tracknum/$tracktotal"
|
||||||
fi
|
fi
|
||||||
year=$(gettag date)
|
year=$(gettag date)
|
||||||
infos="${infos/: /=}"
|
infos="${infos//: /=}"
|
||||||
rate=$(gettag 'original sample rate'|head -n1)
|
rate=$(gettag 'original sample rate'|head -n1)
|
||||||
channels=$(gettag channels|head -n1)
|
channels=$(gettag channels|head -n1)
|
||||||
bitrate=$(gettag 'average bitrate')
|
bitrate=$(gettag 'average bitrate')
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
getInfosffmpeg_version='ffmpeg-1'
|
getInfosffmpeg_version='ffmpeg-2'
|
||||||
tagreaders+=( "$getInfosffmpeg_version" )
|
tagreaders+=( "$getInfosffmpeg_version" )
|
||||||
getInfos::ffmpeg() {
|
getInfos::ffmpeg() {
|
||||||
tagreader="$getInfosffmpeg_version"
|
tagreader="$getInfosffmpeg_version"
|
||||||
@ -31,8 +31,8 @@ getInfos::ffmpeg() {
|
|||||||
genre=$(gettag genre)
|
genre=$(gettag genre)
|
||||||
performer=$(gettag TOPE)
|
performer=$(gettag TOPE)
|
||||||
title=$(gettag title)
|
title=$(gettag title)
|
||||||
tracknum=$(gettag tracknumber)
|
tracknum=$(gettag track)
|
||||||
year=$(gettag year)
|
year=$(gettag date)
|
||||||
expr='^[0-9]*$'
|
expr='^[0-9]*$'
|
||||||
if [ -n "$genre" ] && [[ $genre =~ $expr ]]
|
if [ -n "$genre" ] && [[ $genre =~ $expr ]]
|
||||||
then
|
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
|
#!/bin/bash
|
||||||
getTags_version='unknown-3'
|
getTags_version='unknown-4'
|
||||||
tagreaders+=( "$getTags_version" )
|
|
||||||
getTags() {
|
getTags() {
|
||||||
unset type
|
unset type
|
||||||
case "$mimetype" in
|
case "$mimetype" in
|
||||||
audio/mpeg)
|
audio/mpeg)
|
||||||
type=MP3
|
type=ffmpeg
|
||||||
|
(( disableffprobe )) && unset type
|
||||||
;;
|
;;
|
||||||
'application/ogg opus')
|
'application/ogg opus')
|
||||||
type=Opus
|
type=Opus
|
||||||
|
(( disableopusinfo )) && unset type
|
||||||
;;
|
;;
|
||||||
application/ogg*)
|
application/ogg*)
|
||||||
type=Ogg
|
type=Ogg
|
||||||
|
(( disableogginfo )) && unset type
|
||||||
;;
|
;;
|
||||||
audio/x-flac)
|
audio/x-flac)
|
||||||
type=FLAC
|
type=FLAC
|
||||||
|
(( disableflac )) && unset type
|
||||||
;;
|
;;
|
||||||
video/*)
|
video/*)
|
||||||
type=ffmpeg
|
type=ffmpeg
|
||||||
|
(( disableffprobe )) && unset type
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
extendedtype=$(file -b "$sourcepath/$filename")
|
type=ffmpeg
|
||||||
case "$extendedtype" in
|
(( disableffprobe )) && unset type
|
||||||
*' ID3 '*)
|
|
||||||
type=MP3
|
|
||||||
;;
|
|
||||||
*'Musepack '*)
|
|
||||||
getRateChannelMPC
|
|
||||||
tryAPE
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
getRateChannelSoxi
|
|
||||||
tryAPE
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
if [ -n "$type" ]
|
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';
|
WHERE id='$1';
|
||||||
' >&3
|
' >&3
|
||||||
read -u4 line
|
read -u4 line
|
||||||
taskid=${line%%|*}
|
taskid=${line%%::AtOM:SQL:Sep::*}
|
||||||
rest="${line#*|}|"
|
rest="${line#*::AtOM:SQL:Sep::}::AtOM:SQL:Sep::"
|
||||||
sourcefileid=${rest%%|*}
|
sourcefileid=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
required=${rest%%|*}
|
required=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cleanup=${rest%%|*}
|
cleanup=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
destfileid=${rest%%|*}
|
destfileid=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
destfilename=${rest%%|*}
|
destfilename=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,6 +10,7 @@ cleaner() {
|
|||||||
EOWhere
|
EOWhere
|
||||||
)
|
)
|
||||||
(( failed+=faildepends ))
|
(( failed+=faildepends ))
|
||||||
|
(( ran+=faildepends ))
|
||||||
Update tasks status 2 <<<"id = $taskid"
|
Update tasks status 2 <<<"id = $taskid"
|
||||||
Update tasks status 2 <<<"requires = $taskid"
|
Update tasks status 2 <<<"requires = $taskid"
|
||||||
echo "SELECT COUNT(*)
|
echo "SELECT COUNT(*)
|
||||||
|
|||||||
@ -69,78 +69,78 @@ master() {
|
|||||||
else
|
else
|
||||||
(( ++active ))
|
(( ++active ))
|
||||||
read -u4 line
|
read -u4 line
|
||||||
taskid=${line%%|*}
|
taskid=${line%%::AtOM:SQL:Sep::*}
|
||||||
rest="${line#*|}|"
|
rest="${line#*::AtOM:SQL:Sep::}::AtOM:SQL:Sep::"
|
||||||
sourcefileid=${rest%%|*}
|
sourcefileid=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
required=${rest%%|*}
|
required=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cmd_arg=("${rest%%|*}")
|
cmd_arg=("${rest%%::AtOM:SQL:Sep::*}")
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cmd_arg+=("${rest%%|*}")
|
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cmd_arg+=("${rest%%|*}")
|
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cmd_arg+=("${rest%%|*}")
|
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cmd_arg+=("${rest%%|*}")
|
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cmd_arg+=("${rest%%|*}")
|
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cmd_arg+=("${rest%%|*}")
|
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cmd_arg+=("${rest%%|*}")
|
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cmd_arg+=("${rest%%|*}")
|
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cmd_arg+=("${rest%%|*}")
|
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cmd_arg+=("${rest%%|*}")
|
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cmd_arg+=("${rest%%|*}")
|
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cmd_arg+=("${rest%%|*}")
|
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cmd_arg+=("${rest%%|*}")
|
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cmd_arg+=("${rest%%|*}")
|
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cmd_arg+=("${rest%%|*}")
|
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cmd_arg+=("${rest%%|*}")
|
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cmd_arg+=("${rest%%|*}")
|
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cmd_arg+=("${rest%%|*}")
|
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cmd_arg+=("${rest%%|*}")
|
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cmd_arg+=("${rest%%|*}")
|
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cmd_arg+=("${rest%%|*}")
|
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cmd_arg+=("${rest%%|*}")
|
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cmd_arg+=("${rest%%|*}")
|
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cmd_arg+=("${rest%%|*}")
|
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cmd_arg+=("${rest%%|*}")
|
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cmd_arg+=("${rest%%|*}")
|
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cmd_arg+=("${rest%%|*}")
|
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cmd_arg+=("${rest%%|*}")
|
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cmd_arg+=("${rest%%|*}")
|
cmd_arg+=("${rest%%::AtOM:SQL:Sep::*}")
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
cleanup=${rest%%|*}
|
cleanup=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
destfileid=${rest%%|*}
|
destfileid=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
destfilename=${rest%%|*}
|
destfilename=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
for key in ${!cmd_arg[@]}
|
for key in ${!cmd_arg[@]}
|
||||||
do
|
do
|
||||||
[ -z "${cmd_arg[key]}" ] && unset cmd_arg[key]
|
[ -z "${cmd_arg[key]}" ] && unset cmd_arg[key]
|
||||||
|
|||||||
@ -4,12 +4,3 @@ worker() {
|
|||||||
(( debug >= 2 )) && echo "${cmd_arg[@]}" >&2
|
(( debug >= 2 )) && echo "${cmd_arg[@]}" >&2
|
||||||
"${cmd_arg[@]}" >/dev/null
|
"${cmd_arg[@]}" >/dev/null
|
||||||
}
|
}
|
||||||
createworker() {
|
|
||||||
worker $1 &
|
|
||||||
workers[$1]=$!
|
|
||||||
}
|
|
||||||
destroyworker() {
|
|
||||||
dyingworker=${workers[$1]}
|
|
||||||
unset workers[$1]
|
|
||||||
wait $dyingworker
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
BEGIN TRANSACTION;
|
BEGIN TRANSACTION;
|
||||||
CREATE TABLE source_files (
|
CREATE TABLE IF NOT EXISTS source_files (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
filename TEXT UNIQUE NOT NULL,
|
filename TEXT UNIQUE NOT NULL,
|
||||||
size INTEGER NOT NULL,
|
size INTEGER NOT NULL,
|
||||||
@ -10,11 +10,11 @@ CREATE TABLE source_files (
|
|||||||
FOREIGN KEY (mime_type) REFERENCES mime_types(id)
|
FOREIGN KEY (mime_type) REFERENCES mime_types(id)
|
||||||
ON DELETE SET NULL
|
ON DELETE SET NULL
|
||||||
);
|
);
|
||||||
CREATE TABLE destinations (
|
CREATE TABLE IF NOT EXISTS destinations (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
name TEXT UNIQUE NOT NULL
|
name TEXT UNIQUE NOT NULL
|
||||||
);
|
);
|
||||||
CREATE TABLE destination_files (
|
CREATE TABLE IF NOT EXISTS destination_files (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
filename TEXT,
|
filename TEXT,
|
||||||
old_filename TEXT,
|
old_filename TEXT,
|
||||||
@ -27,11 +27,11 @@ CREATE TABLE destination_files (
|
|||||||
FOREIGN KEY (destination_id) REFERENCES destinations(id)
|
FOREIGN KEY (destination_id) REFERENCES destinations(id)
|
||||||
ON DELETE CASCADE
|
ON DELETE CASCADE
|
||||||
);
|
);
|
||||||
CREATE TABLE mime_types (
|
CREATE TABLE IF NOT EXISTS mime_types (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
mime_text TEXT UNIQUE NOT NULL
|
mime_text TEXT UNIQUE NOT NULL
|
||||||
);
|
);
|
||||||
CREATE TABLE mime_actions (
|
CREATE TABLE IF NOT EXISTS mime_actions (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
mime_type INTEGER,
|
mime_type INTEGER,
|
||||||
destination_id INTEGER,
|
destination_id INTEGER,
|
||||||
@ -40,7 +40,7 @@ CREATE TABLE mime_actions (
|
|||||||
FOREIGN KEY (destination_id) REFERENCES destinations(id)
|
FOREIGN KEY (destination_id) REFERENCES destinations(id)
|
||||||
ON DELETE CASCADE
|
ON DELETE CASCADE
|
||||||
);
|
);
|
||||||
CREATE TABLE tags (
|
CREATE TABLE IF NOT EXISTS tags (
|
||||||
source_file INTEGER PRIMARY KEY,
|
source_file INTEGER PRIMARY KEY,
|
||||||
genre TEXT,
|
genre TEXT,
|
||||||
albumartist TEXT,
|
albumartist TEXT,
|
||||||
@ -61,13 +61,14 @@ CREATE TABLE tags (
|
|||||||
ON DELETE CASCADE
|
ON DELETE CASCADE
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE VIEW mime_type_actions AS
|
CREATE VIEW IF NOT EXISTS mime_type_actions AS
|
||||||
SELECT
|
SELECT
|
||||||
mime_types.id,mime_types.mime_text,
|
mime_types.id,mime_types.mime_text,
|
||||||
mime_actions.destination_id,mime_actions.action
|
mime_actions.destination_id,mime_actions.action
|
||||||
FROM mime_types INNER JOIN mime_actions
|
FROM mime_types INNER JOIN mime_actions
|
||||||
ON mime_actions.mime_type = mime_types.id;
|
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
|
BEGIN
|
||||||
UPDATE mime_actions
|
UPDATE mime_actions
|
||||||
SET action=new.action
|
SET action=new.action
|
||||||
@ -75,7 +76,8 @@ BEGIN
|
|||||||
AND destination_id=old.destination_id;
|
AND destination_id=old.destination_id;
|
||||||
END;
|
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
|
BEGIN
|
||||||
INSERT INTO mime_actions
|
INSERT INTO mime_actions
|
||||||
(mime_type,destination_id)
|
(mime_type,destination_id)
|
||||||
@ -87,7 +89,7 @@ BEGIN
|
|||||||
FROM source_files;
|
FROM source_files;
|
||||||
END;
|
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
|
BEGIN
|
||||||
INSERT INTO mime_actions (mime_type,destination_id)
|
INSERT INTO mime_actions (mime_type,destination_id)
|
||||||
SELECT mime_types.id,destinations.id
|
SELECT mime_types.id,destinations.id
|
||||||
@ -95,18 +97,39 @@ BEGIN
|
|||||||
WHERE mime_types.id=new.id;
|
WHERE mime_types.id=new.id;
|
||||||
END;
|
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
|
BEGIN
|
||||||
INSERT INTO destination_files (source_file_id,destination_id)
|
INSERT INTO destination_files (source_file_id,destination_id)
|
||||||
SELECT source_files.id,destinations.id FROM source_files
|
SELECT source_files.id,destinations.id FROM source_files
|
||||||
INNER JOIN destinations
|
INNER JOIN destinations
|
||||||
WHERE source_files.id=new.id;
|
WHERE source_files.id=new.id;
|
||||||
END;
|
END;
|
||||||
CREATE TRIGGER create_tags AFTER INSERT ON source_files
|
CREATE TRIGGER IF NOT EXISTS create_tags AFTER INSERT ON source_files
|
||||||
BEGIN
|
BEGIN
|
||||||
INSERT INTO tags (source_file,last_change) VALUES (new.id,0);
|
INSERT INTO tags (source_file,last_change) VALUES (new.id,0);
|
||||||
END;
|
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;
|
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
|
checkextensions
|
||||||
===============
|
===============
|
||||||
Reports files whose extension does not match the (detected) mime-type.
|
Reports files whose extension does not match the (detected) mime-type.
|
||||||
|
|||||||
@ -112,8 +112,8 @@ getdstfiles() {
|
|||||||
done
|
done
|
||||||
for line in "${lines[@]}"
|
for line in "${lines[@]}"
|
||||||
do
|
do
|
||||||
fileid=${line%|*}
|
fileid=${line%::AtOM:SQL:Sep::*}
|
||||||
filename=${line#*|}
|
filename=${line#*::AtOM:SQL:Sep::}
|
||||||
echo $'\t'"$filename"
|
echo $'\t'"$filename"
|
||||||
(( rename )) && echo -n $'\t'
|
(( rename )) && echo -n $'\t'
|
||||||
(( rename )) && renameFile
|
(( rename )) && renameFile
|
||||||
@ -149,12 +149,12 @@ do
|
|||||||
done
|
done
|
||||||
for line in "${lines[@]}"
|
for line in "${lines[@]}"
|
||||||
do
|
do
|
||||||
fileid=${line%%|*}
|
fileid=${line%%::AtOM:SQL:Sep::*}
|
||||||
rest="${line#*|}|"
|
rest="${line#*::AtOM:SQL:Sep::}::AtOM:SQL:Sep::"
|
||||||
filename=${rest%%|*}
|
filename=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
mimetype=${rest%%|*}
|
mimetype=${rest%%::AtOM:SQL:Sep::*}
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
dest=$sourcepath
|
dest=$sourcepath
|
||||||
case "$mimetype" in
|
case "$mimetype" in
|
||||||
'audio/mpeg')
|
'audio/mpeg')
|
||||||
|
|||||||
@ -61,7 +61,7 @@ checkwanted() {
|
|||||||
for destination in "${!destinationpath[@]}"
|
for destination in "${!destinationpath[@]}"
|
||||||
do
|
do
|
||||||
echo -ne "\rScanning destination $destination... \033[K"
|
echo -ne "\rScanning destination $destination... \033[K"
|
||||||
while read filename
|
while read -r filename
|
||||||
do
|
do
|
||||||
if ! Select destination_files id \
|
if ! Select destination_files id \
|
||||||
>/dev/null \
|
>/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,24 +93,12 @@ if (( update ))
|
|||||||
then
|
then
|
||||||
getFiles
|
getFiles
|
||||||
updateMimes
|
updateMimes
|
||||||
|
updateTags
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for check in ${!checks[@]}
|
for check in ${!checks[@]}
|
||||||
do
|
do
|
||||||
case $check in
|
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)
|
tracktotal)
|
||||||
whereclause+="${whereclause+OR }NOT tags.track LIKE \"%/%\""
|
whereclause+="${whereclause+OR }NOT tags.track LIKE \"%/%\""
|
||||||
;;
|
;;
|
||||||
@ -137,8 +125,15 @@ cat >&3 <<-EOSelect
|
|||||||
FROM tags
|
FROM tags
|
||||||
INNER JOIN source_files
|
INNER JOIN source_files
|
||||||
ON tags.source_file=source_files.id
|
ON tags.source_file=source_files.id
|
||||||
WHERE $whereclause
|
INNER JOIN mime_types
|
||||||
AND NOT tags.tagreader LIKE "unknown-%";
|
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";
|
SELECT "AtOM:NoMoreFiles";
|
||||||
EOSelect
|
EOSelect
|
||||||
@ -153,33 +148,33 @@ done
|
|||||||
for line in "${lines[@]}"
|
for line in "${lines[@]}"
|
||||||
do
|
do
|
||||||
missing=()
|
missing=()
|
||||||
filename=${line%%|*}
|
filename=${line%%::AtOM:SQL:Sep::*}
|
||||||
rest="${line#*|}|"
|
rest="${line#*::AtOM:SQL:Sep::}::AtOM:SQL:Sep::"
|
||||||
(( ${checks[genre]} )) && [ -z "${rest%%|*}" ] && missing+=( "Genre" )
|
(( ${checks[genre]} )) && [ -z "${rest%%::AtOM:SQL:Sep::*}" ] && missing+=( "Genre" )
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
(( ${checks[albumartist]} )) && [ -z "${rest%%|*}" ] && missing+=( "AlbumArtist" )
|
(( ${checks[albumartist]} )) && [ -z "${rest%%::AtOM:SQL:Sep::*}" ] && missing+=( "AlbumArtist" )
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
(( ${checks[year]} )) && [ -z "${rest%%|*}" ] && missing+=( "Year" )
|
(( ${checks[year]} )) && [ -z "${rest%%::AtOM:SQL:Sep::*}" ] && missing+=( "Year" )
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
(( ${checks[album]} )) && [ -z "${rest%%|*}" ] && missing+=( "Album" )
|
(( ${checks[album]} )) && [ -z "${rest%%::AtOM:SQL:Sep::*}" ] && missing+=( "Album" )
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
(( ${checks[disc]} )) && [ -z "${rest%%|*}" ] && missing+=( "Disc" )
|
(( ${checks[disc]} )) && [ -z "${rest%%::AtOM:SQL:Sep::*}" ] && missing+=( "Disc" )
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
(( ${checks[artist]} )) && [ -z "${rest%%|*}" ] && missing+=( "Artist" )
|
(( ${checks[artist]} )) && [ -z "${rest%%::AtOM:SQL:Sep::*}" ] && missing+=( "Artist" )
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
track=${rest%%|*}
|
track=${rest%%::AtOM:SQL:Sep::*}
|
||||||
(( ${checks[track]} )) && [ -z "$track" ] && missing+=( "Track" )
|
(( ${checks[track]} )) && [ -z "$track" ] && missing+=( "Track" )
|
||||||
if (( ${checks[tracktotal]} )) && ! [[ $track =~ / ]]
|
if (( ${checks[tracktotal]} )) && ! [[ $track =~ / ]]
|
||||||
then
|
then
|
||||||
missing+=( TrackTotal )
|
missing+=( TrackTotal )
|
||||||
fi
|
fi
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
(( ${checks[title]} )) && [ -z "${rest%%|*}" ] && missing+=( "Title" )
|
(( ${checks[title]} )) && [ -z "${rest%%::AtOM:SQL:Sep::*}" ] && missing+=( "Title" )
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
(( ${checks[composer]} )) && [ -z "${rest%%|*}" ] && missing+=( "Composer" )
|
(( ${checks[composer]} )) && [ -z "${rest%%::AtOM:SQL:Sep::*}" ] && missing+=( "Composer" )
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
(( ${checks[performer]} )) && [ -z "${rest%%|*}" ] && missing+=( "Performer" )
|
(( ${checks[performer]} )) && [ -z "${rest%%::AtOM:SQL:Sep::*}" ] && missing+=( "Performer" )
|
||||||
rest=${rest#*|}
|
rest=${rest#*::AtOM:SQL:Sep::}
|
||||||
echo "$filename: ${missing[@]}"
|
echo "$filename: ${missing[@]}"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user