172 lines
5.8 KiB
Bash
172 lines
5.8 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
set -e
|
|
|
|
DATA="$(cat "$1")"
|
|
|
|
. "$HOME/.local/share/music/common.sh"
|
|
|
|
function get_songs_from_playlists() {
|
|
local data="$1"
|
|
local song_paths=""
|
|
|
|
for playlist in $(echo "$data" | jq -c '.PLAYLISTS[]' | sed -e 's/ /%20;/g')
|
|
do
|
|
playlist="$(echo "$playlist" | sed -e 's/%20;/ /g')"
|
|
|
|
for song_path in $(echo "$playlist" | jq -rc '.SONGS[]' | sed -e 's/ /%20;/g')
|
|
do
|
|
local song_path="$(echo "$song_path" | sed -e 's/%20;/ /g' )"
|
|
if [[ -f "$song_path" ]]
|
|
then
|
|
song_paths="$(echo -e "$song_paths\n$song_path")"
|
|
fi
|
|
done
|
|
done
|
|
|
|
echo "$song_paths" | sort | uniq
|
|
}
|
|
|
|
function search_artist_index() {
|
|
local name="$(echo "$1" | sed -e 's/^"//' -e 's/"$//')"
|
|
|
|
for artist in $(echo "$DATA" | jq -c '.ARTISTS' | sed -e 's/^{//' -e 's/}$//' -e 's/},"/}\n"/g' -e 's/ /%20;/g')
|
|
do
|
|
artist="$( echo "$artist" | sed -e 's/%20;/ /g' )"
|
|
|
|
local artist_name="$(echo "$artist" | sed -e 's/^.*"\([^"]*\)"}$/\1/')"
|
|
if [[ "$name" == "$artist_name" ]]
|
|
then
|
|
echo "$artist" | sed -e 's/^"\([0-9]*\)".*$/\1/'
|
|
return
|
|
fi
|
|
done
|
|
}
|
|
|
|
function search_album_index() {
|
|
local name="$1"
|
|
local artist="$2"
|
|
|
|
for album in $(echo "$DATA" | jq -c '.ALBUMS' | sed -e 's/^{//' -e 's/}$//' -e 's/},"/}\n"/g' -e 's/ /%20;/g')
|
|
do
|
|
album="$( echo "{$album}" | sed -e 's/%20;/ /g' )"
|
|
|
|
local album_name="$(echo "$album" | jq -c '.[].title' || error_here)"
|
|
if [[ "$name" == "$album_name" ]]
|
|
then
|
|
local index="$(echo "$album" | jq -c 'keys[0]' | tr -dc '0-9')"
|
|
echo "$(echo "$album" | jq -c '.[]' || error_here) {\"index\":$index}" | jq -c -s add || error_here
|
|
return
|
|
fi
|
|
done
|
|
|
|
echo "{\"title\":$name,\"artist\":$artist,\"index\":-1}"
|
|
}
|
|
|
|
function apply_changes() {
|
|
local song="$1"
|
|
|
|
local genre="$(echo "$song" | jq -r '.genre')"
|
|
local pls="$(echo "$song" | jq -r '.playlist')"
|
|
pls="${pls^^}" # make uppercase
|
|
local like="$(echo "$song" | jq -r '.likeLevel')"
|
|
genre="$genre $pls L$like"
|
|
local block="$(echo "$song" | jq -r '.blockLevel')"
|
|
if [[ "$block" != "0" ]]
|
|
then
|
|
genre="$genre B$block"
|
|
fi
|
|
genre="$(echo "$genre" | sed -e 's/^ *//' -e 's/ *$//' -e 's/ / /g')"
|
|
|
|
echo "genre: '$genre'"
|
|
|
|
echo -n 'continue [y/N]: '
|
|
answer=""
|
|
read answer
|
|
if [[ "$answer" = "y" ]]
|
|
then
|
|
local format="$(echo "$song" | jq -r '.path.file' | sed 's/^.*\.\([^.]*\)$/\1/')"
|
|
case "$format" in
|
|
flac)
|
|
metaflac --remove-tag="GENRE" "$(echo "$song" | jq -r '.path.file')"
|
|
metaflac --set-tag="GENRE=$genre" "$(echo "$song" | jq -r '.path.file')"
|
|
;;
|
|
mp3)
|
|
id3v2 --genre "$genre" "$(echo "$song" | jq -r '.path.file')"
|
|
;;
|
|
*)
|
|
echo "ERROR: unsuported format $format"
|
|
;;
|
|
esac
|
|
else
|
|
echo "change aborted"
|
|
fi
|
|
}
|
|
|
|
song_db_old=""
|
|
song_db_new=""
|
|
|
|
song_paths="$(echo "$DATA" | jq -c '.SONGS | keys | @csv' | sed -e 's/^"\\\"//' -e 's/\\\""$//')"
|
|
for mucke_path in $(echo "$song_paths" | sed -e 's/\\\",\\\"/\n/g' -e 's/ /%20;/g' | grep -v 'Movies/Dadi')
|
|
do
|
|
mucke_path="$(echo "$mucke_path" | sed -e 's/%20;/ /g')"
|
|
song_path="$MUSIC_DIR/$(echo "$mucke_path" | sed -e 's|^/storage/emulated/0/Music/||')"
|
|
|
|
|
|
song_info="$(music_get_song_info_from_file "$song_path" || echo)"
|
|
if [[ "$(echo "$song_info" | head -c1)" != "{" ]]
|
|
then
|
|
echo "$song_info"
|
|
exit 1
|
|
fi
|
|
song_info="$(music_process_genre "$song_info")"
|
|
|
|
artist_name="$(echo "$song_info" | jq -c '.artist' || error_here)"
|
|
artistId="-1"
|
|
artist=""
|
|
if [[ "$artist_name" == "\"\"" || "$artist_name" == "" ]]
|
|
then
|
|
artist="{\"artist\":\"\",\"index\":-1}"
|
|
else
|
|
artistId="$(search_artist_index "$artist_name")"
|
|
artist="{\"artist\":$artist_name,\"index\":$artistId}"
|
|
fi
|
|
|
|
album="$(echo "$song_info" | jq -c '.album' || error_here)"
|
|
album_artist="$artist_name"
|
|
if [[ "$album" == "\"\"" || "$album" == "" ]]
|
|
then
|
|
album="{\"title\":\"\",\"artist\":$artist_name,\"index\":-1}"
|
|
else
|
|
album="$(search_album_index "$album" "$artist_name")"
|
|
album_artist="$(echo "$album" | jq -c '.artist' || error_here)"
|
|
fi
|
|
|
|
song_info="$(echo "$song_info {\"artist\":$artist,\"album\":$album}" | jq -c -s add || error_here)"
|
|
song_db_old="$song_db_old,$(echo "$song_info" | jq '.path.mpd' || error_here):$song_info"
|
|
|
|
mucke_song="$(echo "$DATA" | jq -c ".SONGS.\"$mucke_path\"" || error_here)"
|
|
mucke_song="$(echo "$mucke_song" | jq -c ". | {\"title\":.title,\"album\":{\"title\":.album,\"artist\":$album_artist,\"index\":.albumId},\"artist\":{\"artist\":.artist,\"index\":$artistId},\"blockLevel\":.blockLevel,\"likeLevel\":.likeCount}" || error_here)"
|
|
|
|
new_info="$(echo "$song_info $mucke_song" | jq -c -s add || error_here)"
|
|
song_db_new="$song_db_new,$(echo "$new_info" | jq '.path.mpd' || error_here):$new_info"
|
|
|
|
tmp_old="$(mktemp)"
|
|
echo "$song_info" | jq >"$tmp_old" || error_here
|
|
tmp_new="$(mktemp)"
|
|
echo "$new_info" | jq >"$tmp_new" || error_here
|
|
|
|
diff "$tmp_old" "$tmp_new" &>/dev/null || {
|
|
echo "$song_path"
|
|
diff "$tmp_old" "$tmp_new" || echo
|
|
|
|
apply_changes "$new_info"
|
|
}
|
|
rm "$tmp_old" "$tmp_new"
|
|
done
|
|
|
|
echo "{$(echo "$song_db_old" | tail -c+2)}" | jq >"$HOME/.local/share/music/songs.json" \
|
|
|| echo "{$(echo "$song_db_old" | tail -c+2)}" >"$HOME/.local/share/music/songs.json"
|
|
echo "{$(echo "$song_db_new" | tail -c+2)}" | jq >"$HOME/.local/share/music/songs_new.json" \
|
|
|| echo "{$(echo "$song_db_new" | tail -c+2)}" >"$HOME/.local/share/music/songs_new.json"
|