141 lines
4.2 KiB
Bash
141 lines
4.2 KiB
Bash
gettags() {
|
|
ffprobe -v error -show_entries format_tags -print_format json "$1" |
|
|
$JQ -r --compact-output '.format.tags | {
|
|
trackid: (."MusicBrainz Release Track Id" // ."MUSICBRAINZ_RELEASETRACKID" // ."MusicBrainz/Release Track Id" // ""),
|
|
releaseid: (."MusicBrainz Album Id" // ."MUSICBRAINZ_ALBUMID" // ."MusicBrainz/Album Id" // "")
|
|
}'
|
|
}
|
|
|
|
# Read music files in specified directory and create json file that points to
|
|
# all relevant MusicBrainz IDs.
|
|
# @input $1: Path to directory with album
|
|
decorate() {
|
|
if [ -f "$1/$DECORATION_FILENAME" ]; then
|
|
info "Directory $1 has already been decorated (skipping)"
|
|
return 0
|
|
fi
|
|
decoration=$($JQ -n '.tracks = {}')
|
|
tmpf=$(mktemp)
|
|
(cd "$1" && find . -type f -iname '*.mp3' -o -iname '*.mp4' -o -iname '*.flac' -o -iname '*.m4a') >"$tmpf"
|
|
while IFS= read -r f; do
|
|
mbid=$(gettags "$1/$f")
|
|
rid=$(echo "$mbid" | $JQ -r '.releaseid')
|
|
tid=$(echo "$mbid" | $JQ -r '.trackid')
|
|
if [ ! "$rid" ] || [ ! "$tid" ]; then
|
|
err "File $f: Seems not tagged"
|
|
releaseid=""
|
|
break
|
|
fi
|
|
if [ "${releaseid:-}" ]; then
|
|
if [ "$releaseid" != "$rid" ]; then
|
|
err "Directory $1 contains files of different releases"
|
|
releaseid=""
|
|
break
|
|
fi
|
|
else
|
|
info "Decorating $1 as release $rid"
|
|
releaseid="$rid"
|
|
fi
|
|
decoration=$(echo "$decoration" | $JQ ".tracks += {\"$tid\": \"$f\"}")
|
|
done <"$tmpf"
|
|
rm -f "$tmpf"
|
|
if [ "$releaseid" ]; then
|
|
echo "$decoration" | $JQ --compact-output ".releaseid = \"$releaseid\"" >"$1/$DECORATION_FILENAME"
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Load missing cache entries (batch mode)
|
|
# argument $1: type
|
|
# argument $2: File with one ID per line
|
|
__batch_load_missing() {
|
|
tmpf=$(mktemp)
|
|
while IFS= read -r mbid; do
|
|
if ! in_cache "$1" "$mbid"; then
|
|
echo "$mbid" >>"$tmpf"
|
|
fi
|
|
done <"$2"
|
|
if [ -s "$tmpf" ]; then
|
|
lines=$(wc -l "$tmpf" | cut -d ' ' -f 1)
|
|
if [ "$lines" -gt 0 ]; then
|
|
case "$1" in
|
|
"$TYPE_ARTIST")
|
|
tt="artists"
|
|
;;
|
|
"$TYPE_RELEASEGROUP")
|
|
tt="release groups"
|
|
;;
|
|
"$TYPE_RELEASE")
|
|
tt="releases"
|
|
;;
|
|
esac
|
|
info "Fetching $lines missing $tt"
|
|
cnt=0
|
|
while IFS= read -r mbid; do
|
|
case "$1" in
|
|
"$TYPE_ARTIST")
|
|
mb_artist "$mbid" >/dev/null
|
|
;;
|
|
"$TYPE_RELEASEGROUP")
|
|
mb_releasegroup "$mbid" >/dev/null
|
|
;;
|
|
"$TYPE_RELEASE")
|
|
mb_release "$mbid" >/dev/null
|
|
;;
|
|
esac
|
|
cnt=$((cnt + 1))
|
|
printf "\033[K\r%d/%d (%s: %s)" "$cnt" "$lines" "$mbid" "$($JQ -r ".name // .title")"
|
|
sleep 1
|
|
done <"$tmpf"
|
|
printf "\n"
|
|
fi
|
|
fi
|
|
rm -f "$tmpf"
|
|
}
|
|
|
|
LOCALDATADIR="$HOME/.cache/$APP_NAME/local"
|
|
LOCALDATA_ARTISTS="$LOCALDATADIR/artists"
|
|
LOCALDATA_RELEASEGROUPS="$LOCALDATADIR/releasegroups"
|
|
LOCALDATA_RELEASES="$LOCALDATADIR/releases"
|
|
|
|
# Load local music
|
|
load_local() {
|
|
[ -d "$LOCALDATADIR" ] || mkdir -p "$LOCALDATADIR"
|
|
tmpreleases=$(mktemp)
|
|
[ -f "$tmpreleases" ] || exit 1
|
|
find "$MUSICDIR" -type f -name "$DECORATION_FILENAME" -print0 |
|
|
xargs -0 -P 4 $JQ -r '.releaseid+"\t"+input_filename' |
|
|
tee "$LOCALDATA_RELEASES" |
|
|
cut -d "$(printf '\t')" -f 1 >"$tmpreleases"
|
|
__batch_load_missing "$TYPE_RELEASE" "$tmpreleases"
|
|
# Get release groups and album artists
|
|
while IFS= read -r rid; do
|
|
mb=$(mb_release "$rid")
|
|
echo "$mb" | $JQ -r '."release-group".id' >>"$LOCALDATA_RELEASEGROUPS"
|
|
echo "$mb" | $JQ -r '."release-group"."artist-credit" | map(.artist.id) | join("\n")' >>"$LOCALDATA_ARTISTS"
|
|
done <"$tmpreleases"
|
|
tf=$(mktemp)
|
|
sort "$LOCALDATA_RELEASEGROUPS" | uniq >"$tf" && mv "$tf" "$LOCALDATA_RELEASEGROUPS"
|
|
sort "$LOCALDATA_ARTISTS" | uniq >"$tf" && mv "$tf" "$LOCALDATA_ARTISTS"
|
|
# Populate cache with missing data
|
|
__batch_load_missing "$TYPE_RELEASEGROUP" "$LOCALDATA_RELEASEGROUPS"
|
|
__batch_load_missing "$TYPE_ARTIST" "$LOCALDATA_ARTISTS"
|
|
rm -f "$tmpreleases"
|
|
}
|
|
|
|
# List all releases
|
|
list_releases() {
|
|
cut -d "$(printf '\t')" -f 1 "$LOCALDATA_RELEASES"
|
|
}
|
|
|
|
# List all release groups
|
|
list_releasegroups() {
|
|
cat "$LOCALDATA_RELEASEGROUPS"
|
|
}
|
|
|
|
# List all album artists
|
|
list_artists() {
|
|
cat "$LOCALDATA_ARTISTS"
|
|
}
|