436 lines
8.8 KiB
Bash
Executable File
436 lines
8.8 KiB
Bash
Executable File
#!/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
|