Compare commits
22 Commits
master
...
18-tag-gue
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7944dbffe8 | ||
|
|
6275485da6 | ||
|
|
586785d546 | ||
|
|
0b08622108 | ||
|
|
8a53f8b07a | ||
|
|
ff2d93feda | ||
|
|
a60e12a2da | ||
|
|
cf981eee25 | ||
|
|
301f51f2dd | ||
|
|
9acb957cb8 | ||
|
|
094ef5f68f | ||
|
|
803983a5a6 | ||
|
|
73f00a1fac | ||
|
|
66d67dbd3d | ||
|
|
fbabf840de | ||
|
|
a7f6668e72 | ||
|
|
4e2bb8aab9 | ||
|
|
e960b18462 | ||
|
|
7ff9923113 | ||
|
|
a0cb1bae1b | ||
|
|
1a75cd4764 | ||
|
|
298f6f1c60 |
@ -1,12 +1,3 @@
|
||||
# 1.0.6
|
||||
### BUGS
|
||||
* Support for newline character in filenames
|
||||
* Fix obsolete files deletion
|
||||
|
||||
### BUGS (Minor)
|
||||
* Fix timing information
|
||||
* Fix level 3+ debug levels (hanging waiting for child processes)
|
||||
|
||||
# 1.0.5
|
||||
### BUGS (Minor)
|
||||
* `toys/createindex`: handle empty channel count, bitdepth and sampling rate cleanly
|
||||
|
||||
16
README.md
16
README.md
@ -20,19 +20,19 @@ in the same format, it will want a constant sample-rate and bitrate. You can
|
||||
have AtOM do that!
|
||||
|
||||
Here's what I have for my tests:
|
||||
| Directory | Format | Sample rate | Bitrate | Channels | FAT32 compat. | ASCII | Size |
|
||||
| --------- | ------ | ----------- | --------- | -------- | ------------- | ----- | ---- |
|
||||
| 0-Full | Mixed | Mixed | Mixed | Mixed | No | No | 568G |
|
||||
| 1-High | Vorbis | Same | Quality 5 | Same | Yes | No | 143G |
|
||||
| 2-Medium | Opus | Same | 64 | Same | Yes | No | 60G |
|
||||
| 3-Small | Opus | Same | 32 | Same | Yes | No | 31G |
|
||||
| 4-MP3 | MP3 | 44100 | 128 | 2 | Yes | Yes | 119G |
|
||||
| Directory | Format | Sample rate | Bitrate | Channels | Normalize | FAT32 compat. | ASCII | Size |
|
||||
| --------- | ------ | ----------- | --------- | -------- | --------- | ------------- | ----- | ---- |
|
||||
| 0-Full | Mixed | Mixed | Mixed | Mixed | No | No | No | 508G |
|
||||
| 1-High | Vorbis | Original | Quality 5 | Same | No | Yes | No | 136G |
|
||||
| 2-Medium | Opus | Original | 64 | Same | No | Yes | No | 58G |
|
||||
| 3-Small | Opus | Original | 32 | Same | No | Yes | No | 30G |
|
||||
| 4-MP3 | MP3 | 44100 | 128 | 2 | No | Yes | Yes | 113G |
|
||||
|
||||
|
||||
|
||||
* URL: https://framagit.org/atom/AtOM/
|
||||
* Author: Vincent Riquer <vincent+prog.atom@riquer.fr>
|
||||
* Copyright/left: 2012-2013,2015,2025-2026 Vincent Riquer - GPLv3
|
||||
* Copyright/left: 2012-2013,2015,2025 Vincent Riquer - GPLv3
|
||||
|
||||
## Dependencies
|
||||
### Required:
|
||||
|
||||
45
atom
45
atom
@ -202,7 +202,7 @@ echo '
|
||||
FROM destination_files
|
||||
WHERE source_file_id is NULL;' >&3
|
||||
|
||||
read -u4 -r -d $'\0' removecount
|
||||
read -u4 removecount
|
||||
until (( ${#removefile[@]} == removecount ))
|
||||
do
|
||||
echo '
|
||||
@ -219,15 +219,15 @@ do
|
||||
SELECT "AtOM:NoMoreFiles";
|
||||
' >&3
|
||||
|
||||
read -u4 -r -d $'\0' line
|
||||
read -u4 line
|
||||
until [[ $line == AtOM:NoMoreFiles ]]
|
||||
do
|
||||
removeFileId=${line%%::AtOM:SQL:Sep::*}
|
||||
rest=${line#*::AtOM:SQL:Sep::}
|
||||
removeFileDestName=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
removeFileDestName=${line%%::AtOM:SQL:Sep::*}
|
||||
rest=${line#*::AtOM:SQL:Sep::}
|
||||
removefile[$removeFileId]="${destinationpath["$removeFileDestName"]}/${rest%%::AtOM:SQL:Sep::*}"
|
||||
read -u4 -r -d $'\0' line
|
||||
read -u4 line
|
||||
done
|
||||
done
|
||||
|
||||
@ -239,7 +239,7 @@ do
|
||||
filename=${removefile[id]}
|
||||
if [ -n "$filename" ]
|
||||
then
|
||||
if rm "$filename"
|
||||
if rm -f "$filename"
|
||||
then
|
||||
Delete destination_files <<<"id = $id"
|
||||
(( ++deleted ))
|
||||
@ -387,7 +387,7 @@ echo '
|
||||
<> CAST(source_files.last_change AS TEXT)
|
||||
AND mime_type_actions.destination_id = destinations.id
|
||||
AND mime_type_actions.action = 1;' >&3
|
||||
read -u4 -r -d $'\0' filecount
|
||||
read -u4 filecount
|
||||
if [ -n "$maxbatch" ] && (( maxbatch < filecount ))
|
||||
then
|
||||
(( togo = filecount - maxbatch ))
|
||||
@ -436,11 +436,11 @@ echo '
|
||||
(( maxbatch )) && echo "LIMIT $maxbatch" >&3
|
||||
echo ';
|
||||
SELECT "AtOM:NoMoreFiles";' >&3
|
||||
read -u4 -r -d $'\0' line
|
||||
read -u4 line
|
||||
while ! [[ $line = AtOM:NoMoreFiles ]]
|
||||
do
|
||||
decodefiles+=("$line::AtOM:SQL:Sep::")
|
||||
read -u4 -r -d $'\0' line
|
||||
read -u4 line
|
||||
done
|
||||
(( cron )) || echo -n $'Creating tasks...\033[K'
|
||||
|
||||
@ -550,9 +550,9 @@ done
|
||||
echo 'COMMIT;' >&3
|
||||
(( cron )) || echo -n $'\r\033[K'
|
||||
(( count )) \
|
||||
&& echo "Created $count tasks for $filecount files" \
|
||||
"${togo:+($togo left) }" \
|
||||
"${copies:+($copies immediate copies)}"
|
||||
&& echo "Created $count tasks for $filecount files \
|
||||
${togo:+($togo left) } \
|
||||
${copies:+($copies immediate copies)}"
|
||||
|
||||
# remove perl unicode to ascii coprocess
|
||||
(( textunidecodeneeded )) && eval exec "${toascii[1]}>&-"
|
||||
@ -675,17 +675,20 @@ endtime=$EPOCHSECONDS
|
||||
elapsedseconds
|
||||
/
|
||||
( 24*60*60 )
|
||||
)) || unset days
|
||||
)) || true
|
||||
(( days )) || unset days
|
||||
(( hours =
|
||||
( elapsedseconds - ( days*24*60*60 ) )
|
||||
/
|
||||
( 60*60 )
|
||||
)) || (( days )) || unset hours
|
||||
)) || true
|
||||
(( days && hours )) || unset hours
|
||||
(( minutes =
|
||||
( elapsedseconds - ( ( days*24 + hours ) *60*60 ) )
|
||||
/
|
||||
60
|
||||
)) || (( days || hours )) || unset minutes
|
||||
)) || true
|
||||
(( days && hours && minutes )) || unset minutes
|
||||
(( seconds =
|
||||
elapsedseconds
|
||||
-
|
||||
@ -773,11 +776,11 @@ then
|
||||
WHERE tasks.status = 2;
|
||||
|
||||
SELECT "AtOM:NoMoreFiles";' >&3
|
||||
read -u4 -r -d $'\0' line
|
||||
read -u4 line
|
||||
while ! [[ $line = AtOM:NoMoreFiles ]]
|
||||
do
|
||||
failedtasks+=("$line")
|
||||
read -u4 -r -d $'\0' line
|
||||
read -u4 line
|
||||
done
|
||||
for line in "${failedtasks[@]}"
|
||||
do
|
||||
@ -833,11 +836,11 @@ do
|
||||
SELECT "AtOM:NoMoreFiles";
|
||||
' >&3
|
||||
|
||||
read -u4 -r -d $'\0' line
|
||||
read -u4 line
|
||||
while [[ $line != AtOM:NoMoreFiles ]]
|
||||
do
|
||||
renamefiles+=("$line")
|
||||
read -u4 -r -d $'\0' line
|
||||
read -u4 line
|
||||
done
|
||||
if (( ${#renamefiles[@]} ))
|
||||
then
|
||||
@ -940,11 +943,11 @@ echo '
|
||||
|
||||
(( cron )) || echo -n 'Removing obsolete files...'$'\033[K'
|
||||
lines=()
|
||||
read -u4 -r -d $'\0' line
|
||||
read -u4 line
|
||||
while [[ $line != AtOM:NoMoreFiles ]]
|
||||
do
|
||||
lines+=("$line")
|
||||
read -u4 -r -d $'\0' line
|
||||
read -u4 line
|
||||
done
|
||||
echo 'BEGIN TRANSACTION;' >&3
|
||||
for line in "${lines[@]}"
|
||||
|
||||
14
doc/config
14
doc/config
@ -52,6 +52,20 @@ Sections:
|
||||
Default: /var/lib/mpd/music
|
||||
* skip <directory>: String. Files in <directory> will be ignored. Note that
|
||||
<directory> can be any expression accepted by find.
|
||||
* tag-guessing <expression>: String. Filenaming scheme to allow for guessing
|
||||
tags from filenames and directories. The placeholders are the same as thosefor rename below:
|
||||
%{album},
|
||||
%{albumartist},
|
||||
%{artist},
|
||||
%{disc},
|
||||
%{genre},
|
||||
%{releasecountry},
|
||||
%{title},
|
||||
%{track},
|
||||
%{year}.
|
||||
* tag-guessing-trigger <tag>: String. Specify multiple times for multiple
|
||||
tags.
|
||||
If <tag> cannot be fetched by tag readers, guessing will be attempted.
|
||||
|
||||
[<some arbitrary string>]
|
||||
Each section not named 'general' or 'source' will define a new destination.
|
||||
|
||||
@ -52,6 +52,33 @@ skip /last
|
||||
skip /lastfm
|
||||
skip /zzz-atrier
|
||||
|
||||
# Tag guessing expresssion. Uses same values as "rename" below. This is used to
|
||||
# guess tags from filenames and paths. This is useful for files with no tags but
|
||||
# can lead to issues if a strict naming scheme is not used.
|
||||
# Tag guessing disabled if unset (default).
|
||||
# %{album},
|
||||
# %{albumartist},
|
||||
# %{artist},
|
||||
# %{disc} (1 digit),
|
||||
# %{genre},
|
||||
# %{releasecountry} (2 letter code),
|
||||
# %{title},
|
||||
# %{track} (2 digits),
|
||||
# %{year}.
|
||||
#tag-guessing %{genre}/%{albumartist}/%{year}-%{album}-%{releasecountry}/%{disc}%{track}--%{artist}-%{title}
|
||||
|
||||
# Guess tags on missing infos:
|
||||
#tag-guessing-trigger artist
|
||||
#tag-guessing-trigger albumartist
|
||||
#tag-guessing-trigger album
|
||||
#tag-guessing-trigger releasecountry
|
||||
#tag-guessing-trigger disc
|
||||
#tag-guessing-trigger title
|
||||
#tag-guessing-trigger track
|
||||
#tag-guessing-trigger year
|
||||
#tag-guessing-trigger genre
|
||||
|
||||
|
||||
[Vorbis]
|
||||
# Each section not named 'general' or 'source' will define a new destination.
|
||||
|
||||
|
||||
@ -7,5 +7,11 @@ getConfigSource() {
|
||||
'skip')
|
||||
skippeddirectories+=( "$value" )
|
||||
;;
|
||||
'tag-guessing')
|
||||
tagguessing="$value"
|
||||
;;
|
||||
'tag-guessing-trigger')
|
||||
tagguessingtriggers+=( "$value" )
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
@ -21,6 +21,16 @@ printConfig() {
|
||||
printed=1
|
||||
done
|
||||
unset printed
|
||||
echo " |Tag guessing expression|$tagguessing"
|
||||
for trigger in "${tagguessingtriggers[@]}"
|
||||
do
|
||||
(( printed )) \
|
||||
&& echo -n ' | |' \
|
||||
|| echo -n ' |Tag guessing triggers|'
|
||||
echo "$trigger"
|
||||
printed=1
|
||||
done
|
||||
|
||||
for destination in ${destinations[@]}
|
||||
do
|
||||
cat <<-EOF
|
||||
|
||||
@ -54,6 +54,32 @@ path $sourcepath
|
||||
cat <<-EOCfg
|
||||
|
||||
|
||||
# Tag guessing expresssion. Uses same values as "rename" below. This is used to
|
||||
# guess tags from filenames and paths. This is useful for files with no tags but
|
||||
# can lead to issues if a strict naming scheme is not used.
|
||||
# Tag guessing disabled if unset (default).
|
||||
# %{album},
|
||||
# %{albumartist},
|
||||
# %{artist},
|
||||
# %{disc} (1 digit),
|
||||
# %{genre},
|
||||
# %{releasecountry} (2 letter code),
|
||||
# %{title},
|
||||
# %{track} (2 digits),
|
||||
# %{year}.
|
||||
#tag-guessing %{genre}/%{albumartist}/%{year}-%{album}-%{releasecountry}/%{disc}%{track}--%{artist}-%{title}
|
||||
tag-guessing $tagguessing
|
||||
|
||||
# Guess tags on missing infos:
|
||||
#tag-guessing-trigger artist
|
||||
#tag-guessing-trigger albumartist
|
||||
EOCfg
|
||||
for trigger in "${tagguessingtriggers[@]}"
|
||||
do
|
||||
echo $'tag-guessing-trigger\t'"$trigger"
|
||||
done
|
||||
|
||||
|
||||
EOCfg
|
||||
for destination in "${destinations[@]}"
|
||||
do
|
||||
|
||||
@ -22,11 +22,11 @@ copyFiles_action() {
|
||||
AND mime_type_actions.action = 2;
|
||||
|
||||
SELECT "AtOM:NoMoreFiles";' >&3
|
||||
read -u4 -r -d $'\0' line
|
||||
read -u4 line
|
||||
while ! [[ $line = AtOM:NoMoreFiles ]]
|
||||
do
|
||||
copyfiles+=("$line")
|
||||
read -u4 -r -d $'\0' line
|
||||
read -u4 line
|
||||
done
|
||||
|
||||
echo 'BEGIN TRANSACTION;' >&3
|
||||
@ -91,10 +91,9 @@ copyFiles_action() {
|
||||
"$sourcepath/$sourcefilename" \
|
||||
"$destdir"
|
||||
then
|
||||
destfilename=${sourcefilename//$'\n'/::AtOM:NewLine:SQL:Inline::}
|
||||
Update destination_files \
|
||||
filename \
|
||||
"$destdir/${destfilename##*/}"\
|
||||
"$destdir/${sourcefilename##*/}"\
|
||||
rename_pattern \
|
||||
"${destinationrenamepath[$destination]}/${destinationrename[$destination]}"\
|
||||
fat32compat \
|
||||
|
||||
@ -21,7 +21,7 @@ guessPath() {
|
||||
LIMIT 1
|
||||
),"0.0");
|
||||
'>&3
|
||||
read -u4 -r -d $'\0' timestamp
|
||||
read -u4 timestamp
|
||||
if (( ${timestamp/./} == 0 ))
|
||||
then
|
||||
return 2
|
||||
@ -46,7 +46,7 @@ guessPath() {
|
||||
LIMIT 1
|
||||
),"AtOM:NotFound");
|
||||
'>&3
|
||||
read -u4 -r -d $'\0' filename
|
||||
read -u4 filename
|
||||
if [[ $filename != AtOM:NotFound ]]
|
||||
then
|
||||
echo "${filename%/*}"
|
||||
|
||||
@ -26,7 +26,6 @@ Insert() {
|
||||
insert_values+=$value
|
||||
;;
|
||||
*)
|
||||
value=${value//::AtOM:NewLine:SQL:Inline::/$'\n'}
|
||||
insert_values+='"'"${value//\"/\"\"}"'"'
|
||||
;;
|
||||
esac
|
||||
@ -37,7 +36,7 @@ Insert() {
|
||||
"( $insert_values );" >&3
|
||||
(( no_id )) || {
|
||||
echo 'SELECT LAST_INSERT_ROWID();' >&3
|
||||
read -u4 -r -d $'\0' results
|
||||
read -u 4 results
|
||||
echo "$results"
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,7 +19,6 @@ Select() {
|
||||
while read key operator value
|
||||
do
|
||||
(( ${#where_statement} )) && where_statement+=( "AND" )
|
||||
value=${value//::AtOM:NewLine:SQL:Inline::/$'\n'}
|
||||
where_statement+=( "$key $operator "'"'"${value//\"/\"\"}"'"' )
|
||||
done
|
||||
echo "SELECT IFNULL(" \
|
||||
@ -27,7 +26,7 @@ Select() {
|
||||
"WHERE ${where_statement[@]})" \
|
||||
",'SQL::Select:not found'" \
|
||||
");" >&3
|
||||
read -u 4 -r -d $'\0' results
|
||||
read -u 4 results
|
||||
if ! [[ $results == "SQL::Select:not found" ]]
|
||||
then
|
||||
echo "$results"
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
currentdbversion=8
|
||||
currentdbversion=7
|
||||
checkDatabaseVersion() {
|
||||
local dbversion
|
||||
if dbversion=$(Select atom version <<<"\"1\" = 1")
|
||||
@ -15,9 +15,9 @@ checkDatabaseVersion() {
|
||||
dbversion=$(Select atom version <<<"\"1\" = 1")
|
||||
done
|
||||
else
|
||||
echo "Database schema version $dbversion is" \
|
||||
"higher thanthat of this version of" \
|
||||
"AtOM ($currentdbversion). Bailing out." >&2
|
||||
echo "Database schema version $dbversion is higher than
|
||||
that of this version of AtOM
|
||||
($currentdbversion). Bailing out." >&2
|
||||
exit $EDBVERSION
|
||||
fi
|
||||
else
|
||||
|
||||
@ -3,8 +3,7 @@ closeDatabase() {
|
||||
echo 'vacuum;' >&3
|
||||
echo .quit >&3
|
||||
(( debug )) && echo -n "Waiting for SQLite to terminate... "
|
||||
(( debug > 2 )) && exec 5>&-
|
||||
wait $db_pid
|
||||
wait
|
||||
(( debug )) && echo OK
|
||||
exec 3>&-
|
||||
exec 4<&-
|
||||
|
||||
@ -1,22 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
openDatabase() {
|
||||
local \
|
||||
populate_db
|
||||
|
||||
[[ -f "$database" ]] || populate_db=1
|
||||
rm -f "$tempdir"/sqlite.{in,out}
|
||||
mkfifo "$tempdir"/sqlite.{in,out}
|
||||
stdbuf -o0 sqlite3 -bail \
|
||||
-newline $'::AtOM:SQL:EOL::\n' \
|
||||
"$database" \
|
||||
< "$tempdir/sqlite.in" \
|
||||
| stdbuf -o0 \
|
||||
sed 's/::AtOM:SQL:EOL::/\x0/g;s/\(\x0\)\xA/\1/g' \
|
||||
sqlite3 -bail "$database" \
|
||||
< "$tempdir/sqlite.in" \
|
||||
> "$tempdir/sqlite.out" &
|
||||
db_pid=$!
|
||||
exec 3> "$tempdir"/sqlite.in
|
||||
exec 4< "$tempdir"/sqlite.out
|
||||
rm "$tempdir"/sqlite.{in,out}
|
||||
rm "$tempdir"/sqlite.in "$tempdir"/sqlite.out
|
||||
if (( debug > 2 ))
|
||||
then
|
||||
exec 5>&3
|
||||
@ -28,7 +20,7 @@ openDatabase() {
|
||||
echo 'PRAGMA recursive_triggers = ON;' >&3
|
||||
echo 'PRAGMA temp_store = 2;' >&3
|
||||
echo 'PRAGMA locking_mode = EXCLUSIVE;' >&3
|
||||
read -u4 -r -d $'\0'
|
||||
read -u4
|
||||
unset REPLY
|
||||
checkDatabaseVersion
|
||||
}
|
||||
|
||||
@ -18,11 +18,11 @@ FROM destination_files;
|
||||
|
||||
SELECT "AtOM::NoMoreData";' >&3
|
||||
|
||||
read -u4 -r -d $'\0' data
|
||||
read -u4 data
|
||||
while [[ $data != AtOM::NoMoreData ]]
|
||||
do
|
||||
datas+=( "$data" )
|
||||
read -u4 -r -d $'\0' data
|
||||
read -u4 data
|
||||
done
|
||||
echo 'BEGIN TRANSACTION;' >&3
|
||||
for data in "${datas[@]}"
|
||||
|
||||
@ -1,9 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
upgradedatabase_7_8() {
|
||||
echo "Upgrading database to version 8... (backup is $database.bak_v7)"
|
||||
cp "$database" "$database.bak_v7"
|
||||
echo 'Deletion of old files was failing. Users of previous versions (YOU!) are strongly advised to run cleandestinations with the "-r" flag.'
|
||||
read -p "Press Enter to continue..."
|
||||
Update atom version 8 <<<"1 = 1"
|
||||
}
|
||||
@ -2,5 +2,5 @@
|
||||
decodeMpcdec() {
|
||||
tmpfile="${fileid}mpcdec"
|
||||
commandline=(${ionice}mpcdec)
|
||||
commandline+=("$sourcepath/${filename//$'\n'/::AtOM:NewLine:SQL:Inline::}" "$tempdir/$tmpfile.wav")
|
||||
commandline+=("$sourcepath/$filename" "$tempdir/$tmpfile.wav")
|
||||
}
|
||||
|
||||
@ -2,5 +2,5 @@
|
||||
decodeOpusdec() {
|
||||
tmpfile="${fileid}opusdec"
|
||||
commandline=(${ionice}opusdec)
|
||||
commandline+=("$sourcepath/${filename//$'\n'/::AtOM:NewLine:SQL:Inline::}" "$tempdir/$tmpfile.wav")
|
||||
commandline+=("$sourcepath/$filename" "$tempdir/$tmpfile.wav")
|
||||
}
|
||||
|
||||
@ -12,7 +12,7 @@ decodeSox() {
|
||||
then
|
||||
commandline+=("$1")
|
||||
else
|
||||
commandline+=("$sourcepath/${filename//$'\n'/::AtOM:NewLine:SQL:Inline::}")
|
||||
commandline+=("$sourcepath/$filename")
|
||||
fi
|
||||
if [ -n "${destinationfrequency["$destination"]}" ] \
|
||||
&& (( ${rate:-0} != ${destinationfrequency["$destination"]} ))
|
||||
|
||||
@ -88,7 +88,6 @@ getDestDir() {
|
||||
while [[ $part =~ / ]]
|
||||
do
|
||||
thispart="${part%%/*}"
|
||||
thispart=${thispart//$'\n'/::AtOM:NewLine:SQL:Inline::}
|
||||
if (( ${destinationascii["$destination"]} ))
|
||||
then
|
||||
echo "$thispart" >&${toascii[1]}
|
||||
@ -101,7 +100,7 @@ getDestDir() {
|
||||
fi
|
||||
if ! [ -d "${destinationpath[$destination]}/$destdir" ]
|
||||
then
|
||||
mkdir -p "${destinationpath[$destination]}/${destdir//::AtOM:NewLine:SQL:Inline::/$'\n'}"
|
||||
mkdir -p "${destinationpath[$destination]}/$destdir"
|
||||
fi
|
||||
destdir="${destdir//+(\/)//}"
|
||||
}
|
||||
|
||||
@ -55,11 +55,10 @@ getDestFile() {
|
||||
destfile="${filename##*/}"
|
||||
destfile="${destfile%.*}"
|
||||
fi
|
||||
destfile=$(sanitizeFile "$destfile")
|
||||
destfile=${destfile//$'\n'/::AtOM:NewLine:SQL:Inline::}
|
||||
if (( ${destinationascii["$destination"]} ))
|
||||
then
|
||||
echo "$destfile" >&${toascii[1]}
|
||||
read -r -u${toascii[0]} destfile
|
||||
fi
|
||||
destfile=$(sanitizeFile "$destfile")
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@ getFiles() {
|
||||
(( cron )) || echo -n "Scanning $sourcepath... "
|
||||
# We probably have thousands of files, don't waste time on disk writes
|
||||
echo 'BEGIN TRANSACTION;' >&3
|
||||
while read -d $'\0' time size filename
|
||||
while read time size filename
|
||||
do
|
||||
if (( skip_us_timestamp ))
|
||||
then
|
||||
@ -17,7 +17,7 @@ getFiles() {
|
||||
compare_time=$time
|
||||
fi
|
||||
if ! Select source_files id >/dev/null <<-EOWhere
|
||||
filename = ${filename//$'\n'/::AtOM:NewLine:SQL:Inline::}
|
||||
filename = $filename
|
||||
mime_type > 0
|
||||
last_change LIKE $compare_time
|
||||
size = $size
|
||||
@ -47,7 +47,7 @@ getFiles() {
|
||||
mime_type $mimetypeid \
|
||||
>/dev/null \
|
||||
<<-EOWhere
|
||||
filename ${filename//$'\n'/::AtOM:NewLine:SQL:Inline::}
|
||||
filename $filename
|
||||
EOWhere
|
||||
(( ++new ))
|
||||
if (( new % 1000 == 0 ))
|
||||
@ -58,12 +58,12 @@ getFiles() {
|
||||
fi
|
||||
else
|
||||
Update source_files last_seen $scantime <<-EOWhere
|
||||
filename = ${filename//$'\n'/::AtOM:NewLine:SQL:Inline::}
|
||||
filename = $filename
|
||||
EOWhere
|
||||
fi
|
||||
progressSpin
|
||||
done < <(
|
||||
find "$sourcepath" "${prunes[@]}" -type f -not -name '.*' -printf "%T@ %s %P\0"
|
||||
find "$sourcepath" "${prunes[@]}" -type f -not -name '.*' -printf "%T@ %s %P\n"
|
||||
)
|
||||
echo 'COMMIT;' >&3
|
||||
(( cron )) || echo -n $'\r'
|
||||
|
||||
@ -55,4 +55,58 @@ setupSource() {
|
||||
done
|
||||
unset count
|
||||
cd - >/dev/null
|
||||
cat <<-EODesc
|
||||
|
||||
Tag guessing pattern:
|
||||
This is a pattern that will be used to guess the tag names of files
|
||||
that do not have any tags. The pattern is a string with the following
|
||||
variables:
|
||||
%{album} - The album name
|
||||
%{albumartist} - The album artist name
|
||||
%{artist} - The artist name
|
||||
%{disc} - The disc number - 1 digit
|
||||
%{genre} - The genre name
|
||||
%{releasecountry} - The country of the release - 2 letter code
|
||||
%{title} - The title of the track
|
||||
%{track} - The track number - 2 digits
|
||||
%{year} - The year or date of the album
|
||||
EODesc
|
||||
read \
|
||||
-e \
|
||||
-i"${tagguessing} \
|
||||
-p'Pattern: ' \
|
||||
tagguessing
|
||||
cat <<-EODesc
|
||||
|
||||
Tag guessing trigger(s):
|
||||
Tags whose absence will trigger tag guessing.
|
||||
album - The album name
|
||||
albumartist - The album artist name
|
||||
artist - The artist name
|
||||
disc - The disc number
|
||||
genre - The genre name
|
||||
releasecountry - The country of the release
|
||||
title - The title of the track
|
||||
track - The track number
|
||||
year - The year or date of the album
|
||||
EODesc
|
||||
count=${#tagguessingtriggers[@]}
|
||||
for (( i=0 ; 1 ; i++ ))
|
||||
do
|
||||
read \
|
||||
-e \
|
||||
${tagguessingtriggers[i]+-i"${tagguessingtriggers[i]}"}\
|
||||
-p'Tag guessing trigger: ' \
|
||||
value
|
||||
if [ -n "$value" ]
|
||||
then
|
||||
tagguessingtriggers[i]="$value"
|
||||
elif (( i < count ))
|
||||
then
|
||||
unset tagguessingtriggers[i]
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
unset count
|
||||
}
|
||||
|
||||
10
lib/tags/getInfos::guess
Normal file
10
lib/tags/getInfos::guess
Normal file
@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
getInfosGuess_version='guess-1'
|
||||
tagreaders+=( "$getInfosGuess_version" )
|
||||
getInfos::Guess() {
|
||||
tagreader="$getInfosGuess_version"
|
||||
local \
|
||||
infos \
|
||||
|
||||
: #FIXME
|
||||
}
|
||||
@ -52,12 +52,12 @@ echo '
|
||||
;
|
||||
|
||||
SELECT "AtOM:NoMoreFiles";' >&3
|
||||
read -u4 -r -d $'\0' line
|
||||
read -u4 line
|
||||
while ! [[ $line = AtOM:NoMoreFiles ]]
|
||||
do
|
||||
tagfiles+=("$line")
|
||||
(( filecount++ ))
|
||||
read -u4 -r -d $'\0' line
|
||||
read -u4 line
|
||||
done
|
||||
echo 'BEGIN TRANSACTION;' >&3
|
||||
for line in "${tagfiles[@]}"
|
||||
|
||||
@ -10,7 +10,7 @@ gettaskinfos() {
|
||||
FROM tasks
|
||||
WHERE id='$1';
|
||||
' >&3
|
||||
read -u4 -r -d $'\0' line
|
||||
read -u4 line
|
||||
taskid=${line%%::AtOM:SQL:Sep::*}
|
||||
rest="${line#*::AtOM:SQL:Sep::}::AtOM:SQL:Sep::"
|
||||
sourcefileid=${rest%%::AtOM:SQL:Sep::*}
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
createworker() {
|
||||
(( ++active ))
|
||||
read -u4 -r -d $'\0' line
|
||||
read -u4 line
|
||||
taskid=${line%%::AtOM:SQL:Sep::*}
|
||||
rest="${line#*::AtOM:SQL:Sep::}::AtOM:SQL:Sep::"
|
||||
sourcefileid=${rest%%::AtOM:SQL:Sep::*}
|
||||
|
||||
@ -10,7 +10,7 @@ master() {
|
||||
WHERE status = 0;
|
||||
'>&3
|
||||
|
||||
read -u4 -r -d $'\0' remaining
|
||||
read -u4 remaining
|
||||
if (( remaining == 0 ))
|
||||
then
|
||||
sleep 0.1
|
||||
@ -108,7 +108,7 @@ master() {
|
||||
LIMIT 1;
|
||||
'>&3
|
||||
|
||||
read -u4 -r -d $'\0' ready
|
||||
read -u4 ready
|
||||
if (( ready > 0 ))
|
||||
then
|
||||
createworker
|
||||
@ -194,7 +194,7 @@ master() {
|
||||
LIMIT 1;
|
||||
' >&3
|
||||
|
||||
read -u4 -r -d $'\0' ready
|
||||
read -u4 ready
|
||||
|
||||
if (( active == 0 && ready == 0 ))
|
||||
then
|
||||
@ -234,7 +234,7 @@ master() {
|
||||
WHERE status = 0;
|
||||
'>&3
|
||||
|
||||
read -u4 -r -d $'\0' remaining
|
||||
read -u4 remaining
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
@ -121,7 +121,7 @@ getdstfiles() {
|
||||
;
|
||||
SELECT "AtOM:NoMoreFiles";
|
||||
'>&3
|
||||
while read -u4 -r -d $'\0' line
|
||||
while read -u4 line
|
||||
do
|
||||
if [[ $line == AtOM:NoMoreFiles ]]
|
||||
then
|
||||
@ -159,7 +159,7 @@ renameFile() {
|
||||
fi
|
||||
}
|
||||
|
||||
while read -u4 -r -d $'\0' line
|
||||
while read -u4 line
|
||||
do
|
||||
if [[ $line == AtOM:NoMoreFiles ]]
|
||||
then
|
||||
|
||||
@ -65,7 +65,6 @@ getConfig
|
||||
sanityCheck
|
||||
openDatabase
|
||||
|
||||
echo -n "Checking for missing files... "
|
||||
echo '
|
||||
SELECT
|
||||
destination_files.id,
|
||||
@ -80,7 +79,7 @@ echo 'SELECT "AtOM:NoMoreFiles";' >&3
|
||||
declare -a \
|
||||
destination_names \
|
||||
files
|
||||
read -u4 -r -d $'\0' line
|
||||
read -u4 line
|
||||
until [[ $line == AtOM:NoMoreFiles ]]
|
||||
do
|
||||
id=${line%%::AtOM:SQL:Sep::*}
|
||||
@ -88,11 +87,12 @@ do
|
||||
destination_names[id]=${rest%%::AtOM:SQL:Sep::*}
|
||||
rest=${rest#*::AtOM:SQL:Sep::}
|
||||
files[id]=${rest}
|
||||
read -u4 -r -d $'\0' line
|
||||
read -u4 line
|
||||
done
|
||||
|
||||
echo 'BEGIN TRANSACTION;' >&3
|
||||
|
||||
echo -n "Checking for missing files... "
|
||||
for index in "${!files[@]}"
|
||||
do
|
||||
destination=${destination_names[index]}
|
||||
|
||||
@ -65,22 +65,25 @@ getConfig
|
||||
sanityCheck
|
||||
openDatabase
|
||||
|
||||
checkwanted() {
|
||||
Select id <<<"filename = $1"
|
||||
}
|
||||
|
||||
for destination in "${!destinationpath[@]}"
|
||||
do
|
||||
echo -ne "\rScanning destination $destination... \033[K"
|
||||
while read -r -d $'\0' filename
|
||||
while read -r filename
|
||||
do
|
||||
sqlfile=${filename//$'\n'/::AtOM:NewLine:SQL:Inline::}
|
||||
if ! Select destination_files id \
|
||||
>/dev/null \
|
||||
<<<"filename = ${sqlfile#${destinationpath["$destination"]}/}"
|
||||
<<<"filename = ${filename#${destinationpath["$destination"]}/}"
|
||||
then
|
||||
echo -e $'\r'"$filename\033[K"
|
||||
(( remove )) && rm "$filename"
|
||||
(( remove )) && rm -f "$filename"
|
||||
echo -n "Scanning destination $destination... "
|
||||
fi
|
||||
progressSpin
|
||||
done < <(find "${destinationpath["$destination"]}" -type f -print0)
|
||||
done < <(find "${destinationpath["$destination"]}" -type f)
|
||||
done
|
||||
echo -en "\r\033[K"
|
||||
|
||||
|
||||
@ -274,7 +274,7 @@ fi
|
||||
echo 'SELECT IFNULL(
|
||||
(SELECT last_seen FROM source_files ORDER BY last_seen DESC LIMIT 1),
|
||||
0);' >&3
|
||||
read -u4 -r -d $'\0' lastupdate
|
||||
read -u4 lastupdate
|
||||
|
||||
if ! [[ "$output" == - ]]
|
||||
then
|
||||
@ -369,11 +369,11 @@ COLLATE NOCASE;
|
||||
|
||||
SELECT "AtOM:NoMoreFiles";' >&3
|
||||
|
||||
read -u4 -r -d $'\0' line
|
||||
read -u4 line
|
||||
until [[ $line == AtOM:NoMoreFiles ]]
|
||||
do
|
||||
files+=("$line")
|
||||
read -u4 -r -d $'\0' line
|
||||
read -u4 line
|
||||
done
|
||||
|
||||
for line in "${files[@]}"
|
||||
@ -675,7 +675,7 @@ echo '
|
||||
|
||||
SELECT "AtOM:NoMoreFiles";' >&3
|
||||
|
||||
read -u4 -r -d $'\0' line
|
||||
read -u4 line
|
||||
until [[ $line == AtOM:NoMoreFiles ]]
|
||||
do
|
||||
artist="${line%%::AtOM:SQL:Sep::*}"
|
||||
@ -685,7 +685,7 @@ do
|
||||
artists+=( "$artist" )
|
||||
maxcountlen=$(( ${#count} > maxcountlen ? ${#count} : maxcountlen ))
|
||||
maxartistlen=$(( ${#artist} > maxartistlen ? ${#artist} : maxartistlen ))
|
||||
read -u4 -r -d $'\0' line
|
||||
read -u4 line
|
||||
done
|
||||
head=$(
|
||||
printf "| # | %'${maxcoutlen}s | %-${maxartistlen}s |" \
|
||||
@ -714,7 +714,7 @@ echo '
|
||||
FROM source_files
|
||||
INNER JOIN mime_types
|
||||
ON source_files.mime_type=mime_types.id;' >&3
|
||||
read -u4 -r -d $'\0' line
|
||||
read -u4 line
|
||||
totalcount="${line%%::AtOM:SQL:Sep::*}"
|
||||
maxcountlen=$(printf "%'i" $totalcount)
|
||||
maxcountlen=${#maxcountlen}
|
||||
@ -743,7 +743,7 @@ do
|
||||
INNER JOIN mime_types
|
||||
ON source_files.mime_type=mime_types.id
|
||||
WHERE mime_text LIKE "'"$format"'";' >&3
|
||||
read -u4 -r -d $'\0' line
|
||||
read -u4 line
|
||||
count="${line%%::AtOM:SQL:Sep::*}"
|
||||
rest="${line#*::AtOM:SQL:Sep::}::AtOM:SQL:Sep::"
|
||||
size="${rest%%::AtOM:SQL:Sep::*}"
|
||||
|
||||
@ -131,11 +131,11 @@ echo ') ORDER BY bitrate;' >&3
|
||||
|
||||
echo 'SELECT "AtOM:NoMoreFiles";' >&3
|
||||
|
||||
read -u4 -r -d $'\0' line
|
||||
read -u4 line
|
||||
until [[ $line == AtOM:NoMoreFiles ]]
|
||||
do
|
||||
echo "${line//::AtOM:SQL:Sep::/$'\t'}"
|
||||
read -u4 -r -d $'\0' line
|
||||
read -u4 line
|
||||
done
|
||||
|
||||
closeDatabase
|
||||
|
||||
@ -149,11 +149,11 @@ cat >&3 <<-EOSelect
|
||||
SELECT "AtOM:NoMoreFiles";
|
||||
EOSelect
|
||||
|
||||
read -u4 -r -d $'\0' line
|
||||
read -u4 line
|
||||
until [[ $line == AtOM:NoMoreFiles ]]
|
||||
do
|
||||
lines+=( "$line" )
|
||||
read -u4 -r -d $'\0' line
|
||||
read -u4 line
|
||||
done
|
||||
|
||||
for line in "${lines[@]}"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user