Compare commits
67 Commits
c40768c973
...
feat/mpv
Author | SHA1 | Date | |
---|---|---|---|
f4594ca492 | |||
3395f8e068 | |||
210cfd01f7 | |||
30765b7347 | |||
053b594608 | |||
30b3a44a98 | |||
0db4b7069c | |||
c46cd9a57f | |||
6549c3f022 | |||
91343b4b9f | |||
fac25108a6 | |||
58930c75e1 | |||
b56d691041 | |||
dd1b15e925 | |||
7826cb471c | |||
38c7ccea48 | |||
6fef0dcbae | |||
fc39a9a25d | |||
232877b241 | |||
5335332ab0 | |||
a48a92ca58 | |||
f93b85b55e | |||
54934f1eab | |||
c29d36a56e | |||
6776d817a4 | |||
d8b152146b | |||
5f91dbc2bb | |||
d525342187 | |||
bf3a26a4fd | |||
be23ea461e | |||
deaeb23a92 | |||
723fa58763 | |||
eae83d801f | |||
bde3e5a48b | |||
7f94ab9646 | |||
828a69d65e | |||
be32c2e2d6 | |||
7381d2432f | |||
d8a01e1079 | |||
c5c0e96942 | |||
d0e9ac3cd2 | |||
935c9b3b52 | |||
fcc9f5d252 | |||
e6b485e5ee | |||
eba10d6322 | |||
7eb9d6633f | |||
64afff2110 | |||
3e3622b5be | |||
8bbc57ffb2 | |||
5bfb76fadb | |||
5bc17bccc9 | |||
7b83b55f69 | |||
a70d0cd5fe | |||
6731d47b49 | |||
744dca7c1d | |||
c2c85260bf | |||
f3c58ca859 | |||
06e07f0f13 | |||
a5646b8f6e | |||
fd162e2a63 | |||
b7f45c613c | |||
dcba30bf94 | |||
81e49c0984 | |||
20152a368e | |||
8e9ae45724 | |||
fa7c37c7ab | |||
47194034bf |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +1,2 @@
|
||||
demo
|
||||
muf
|
||||
|
@@ -1,11 +1,20 @@
|
||||
BEGIN { OFS="\t" }
|
||||
$2 == "Group" { name = format_group }
|
||||
$2 != "Group" { name = format_person }
|
||||
{
|
||||
BEGIN {
|
||||
OFS="\t"
|
||||
local_artists[0] = 0
|
||||
delete local_artists[0]
|
||||
if (file_local_artists) {
|
||||
while ((getline < file_local_artists) == 1)
|
||||
local_artists[$1] = 1
|
||||
close(file_local_artists)
|
||||
}
|
||||
}
|
||||
{
|
||||
gsub("&", "\\\\&")
|
||||
name = $2 == "Group" ? format_group : format_person
|
||||
l = local_artists[$1] ? format_local : ""
|
||||
if ($4)
|
||||
name = name " " format_disambiguation
|
||||
sub("<<disambiguation>>", $4, name)
|
||||
sub("<<name>>", $3, name)
|
||||
print $1, name
|
||||
print l, name, $1
|
||||
}
|
||||
|
41
src/awk/recordings.awk
Normal file
41
src/awk/recordings.awk
Normal file
@@ -0,0 +1,41 @@
|
||||
BEGIN {
|
||||
OFS="\t"
|
||||
local_recordings[0] = 0
|
||||
delete local_recordings[0]
|
||||
if (file_local_recordings) {
|
||||
while ((getline < file_local_recordings) == 1)
|
||||
local_recordings[$1] = $2
|
||||
close(file_local_recordings)
|
||||
}
|
||||
}
|
||||
{
|
||||
gsub("&", "\\\\&")
|
||||
id = $1
|
||||
med = $2
|
||||
nr = $3
|
||||
dur = $4
|
||||
title = $5
|
||||
artist = $6
|
||||
# Parse duration
|
||||
if (dur) {
|
||||
dur = int(dur / 1000)
|
||||
dh = int(dur / 3600)
|
||||
dur = dur % 3600
|
||||
dm = int(dur / 60)
|
||||
ds = dur % 60
|
||||
if (ds <= 9)
|
||||
ds = "0"ds
|
||||
dur = dh ? dh":"dm":"ds : dm":"ds
|
||||
} else {
|
||||
dur = "??:??"
|
||||
}
|
||||
line = format
|
||||
sub("<<med>>", med, line)
|
||||
sub("<<nr>>", nr, line)
|
||||
sub("<<title>>", title, line)
|
||||
sub("<<artist>>", artist, line)
|
||||
sub("<<duration>>", dur, line)
|
||||
l = local_recordings[id] ? format_local : ""
|
||||
sortk = med" "nr
|
||||
print sortk, l, line, id ":" local_recordings[id]
|
||||
}
|
@@ -1,22 +1,62 @@
|
||||
BEGIN { OFS="\t" }
|
||||
|
||||
BEGIN {
|
||||
OFS="\t"
|
||||
local_releasegroups[0] = 0
|
||||
delete local_releasegroups[0]
|
||||
if (file_local_releasegroups) {
|
||||
while ((getline < file_local_releasegroups) == 1)
|
||||
local_releasegroups[$1] = 1
|
||||
close(file_local_releasegroups)
|
||||
}
|
||||
}
|
||||
{
|
||||
line_type=""
|
||||
line_sectype=""
|
||||
line_year=""
|
||||
gsub("&", "\\\\&")
|
||||
id = $1
|
||||
type = $2
|
||||
year = substr($3, 1, 4) + 0
|
||||
title = $4
|
||||
if (type == "Single")
|
||||
line = format_single
|
||||
else if (type == "Album")
|
||||
line = format_album
|
||||
else if (type == "EP")
|
||||
line = format_ep
|
||||
else
|
||||
line = format_album
|
||||
if (year)
|
||||
line = line " " format_year
|
||||
sub("<<title>>", title, line)
|
||||
sub("<<year>>", year, line)
|
||||
print id, line
|
||||
sectype = $3
|
||||
year = substr($4, 1, 4) + 0
|
||||
title = $5
|
||||
artistcredit = $6
|
||||
line_release = artist == artistcredit ? format_release : format_release_w_artist
|
||||
l = local_releasegroups[$1] ? format_local : ""
|
||||
switch (type) {
|
||||
case "Single": line_type=format_single; break
|
||||
case "Album": line_type=format_album; break
|
||||
case "EP": line_type=format_ep; break
|
||||
case "Broadcast": line_type=format_broadcast; break
|
||||
case "Other": line_type=format_other; break
|
||||
default: line_type=""
|
||||
}
|
||||
split(sectype, a, ";")
|
||||
for (i in a) {
|
||||
t=""
|
||||
switch (a[i]) {
|
||||
case "Compilation": t=format_compilation; break
|
||||
case "Soundtrack": t=format_soundtrack; break
|
||||
case "Spokenword": t=format_spokenword; break
|
||||
case "Interview": t=format_interview; break
|
||||
case "Audiobook": t=format_audiobook; break
|
||||
case "Audio drama": t=format_audiodrama; break
|
||||
case "Live": t=format_live; break
|
||||
case "Remix": t=format_remix; break
|
||||
case "DJ-mix": t=format_djmix; break
|
||||
case "Mixtape/Street": t=format_mixtape; break
|
||||
case "Demo": t=format_demo; break
|
||||
case "Field recording": t=fieldrec; break
|
||||
}
|
||||
if (t)
|
||||
line_sectype=line_sectype ? line_sectype ", " t : t
|
||||
}
|
||||
if (sectype) {
|
||||
line_type = sprintf(format_has_secondary, line_type)
|
||||
line_sectype = sprintf(format_secondary, line_sectype)
|
||||
}
|
||||
sub("<<title>>", title, line_release)
|
||||
sub("<<artist>>", artistcredit, line_release)
|
||||
line_year = year ? format_year : ""
|
||||
sub("<<year>>", year, line_year)
|
||||
sortk = year ? year : 0
|
||||
print sortk, l, line_type, line_release, line_year, line_sectype, id
|
||||
}
|
||||
|
@@ -1,57 +1,57 @@
|
||||
BEGIN {
|
||||
BEGIN {
|
||||
OFS="\t"
|
||||
year[0] = 0; del year[0]
|
||||
title[0] = 0; del title[0]
|
||||
type[0] = 0; del type[0]
|
||||
id[0] = 0; del id[0]
|
||||
score[0] = 0; del score[0]
|
||||
local_releases[0] = 0
|
||||
delete local_releases[0]
|
||||
if (file_local_releases) {
|
||||
while ((getline < file_local_releases) == 1)
|
||||
local_releases[$1] = $2
|
||||
close(file_local_releases)
|
||||
}
|
||||
}
|
||||
|
||||
function get_score(rgdt, rgti, dt, ti, qy, res) {
|
||||
res = 0
|
||||
if (rgdt == dt)
|
||||
res = res + 5
|
||||
if (rgti == ti)
|
||||
res = res + 5
|
||||
if (qy == "normal" || qy == "unknown")
|
||||
res = res + 1
|
||||
if (qy == "high")
|
||||
res = res + 2
|
||||
return res
|
||||
}
|
||||
|
||||
{
|
||||
gsub("&", "\\\\&")
|
||||
rgmi = $1 # Release Group ID
|
||||
rgty = $2 # Release Group Type
|
||||
rgdt = substr($3, 1, 4) + 0 # Release Group Year
|
||||
rgti = $4 # Release Group Title
|
||||
mi = $5 # MusicBrainz Release ID
|
||||
qy = $6 # Release Quality
|
||||
dt = substr($7, 1, 4) + 0 # Release Year
|
||||
ti = $8 # Release Title
|
||||
s = get_score(rgdt, rgti, dt, ti, qy)
|
||||
if (score[rgmi] < s) {
|
||||
score[rgmi] = s
|
||||
year[rgmi] = dt
|
||||
title[rgmi] = ti
|
||||
type[rgmi] = rgty
|
||||
id[rgmi] = mi
|
||||
id = $1
|
||||
status = $2
|
||||
year = substr($3, 1, 4) + 0
|
||||
year = year == 0 ? "" : year
|
||||
covercount = $4
|
||||
label = $5
|
||||
trackcnt = $6
|
||||
media = $7
|
||||
country = $8
|
||||
title = $9
|
||||
artist = $10
|
||||
switch (status) {
|
||||
case "Official": line_status = release_official; break
|
||||
case "Promotion": line_status = release_promotion; break
|
||||
case "Bootleg": line_status = release_bootleg; break
|
||||
case "Pseudo-release": line_status = release_pseudo; break
|
||||
case "Withdrawn": line_status = release_withdrawn; break
|
||||
case "Expunged": line_status = release_expunged; break
|
||||
case "Cancelled": line_status = release_cancelled; break
|
||||
default: line_status = ""
|
||||
}
|
||||
}
|
||||
line = release_format
|
||||
if (artist != rg_artist && title != rg_title)
|
||||
line = line "\t" release_format_title_artist
|
||||
else if (artist != rg_artist && title == rg_title)
|
||||
line = line "\t" release_format_artist
|
||||
else if (artist == rg_artist && title != rg_title)
|
||||
line = line "\t" release_format_title
|
||||
else
|
||||
line = line "\t"
|
||||
|
||||
END {
|
||||
for (rgmi in id) {
|
||||
if (type[rgmi] == "Single")
|
||||
line = format_single
|
||||
else if (type[rgmi] == "Album")
|
||||
line = format_album
|
||||
else if (type[rgmi] == "EP")
|
||||
line = format_ep
|
||||
else
|
||||
line = format_album
|
||||
sub("<<year>>", dt, line)
|
||||
sub("<<title>>", ti, line)
|
||||
print mi, line
|
||||
}
|
||||
sub("<<status>>", line_status, line)
|
||||
sub("<<year>>", year, line)
|
||||
sub("<<tracks>>", trackcnt, line)
|
||||
sub("<<media>>", media, line)
|
||||
gsub("&", "\\\\&", label)
|
||||
sub("<<label>>", label, line)
|
||||
gsub("&", "\\\\&", titel)
|
||||
sub("<<title>>", title, line)
|
||||
gsub("&", "\\\\&", artist)
|
||||
sub("<<artist>>", artist, line)
|
||||
sub("<<country>>", country, line)
|
||||
sortk = year ? year : 0
|
||||
l = local_releases[id] ? format_local : ""
|
||||
print sortk, l, line, id ":" local_releases[id]
|
||||
}
|
||||
|
679
src/main.sh
679
src/main.sh
@@ -8,6 +8,9 @@ set -eu
|
||||
# Load helper methods
|
||||
. "sh/helper.sh"
|
||||
|
||||
# Load configuration
|
||||
. "sh/config.sh"
|
||||
|
||||
# Load theme
|
||||
. "sh/theme.sh"
|
||||
|
||||
@@ -23,17 +26,126 @@ set -eu
|
||||
# Load preview methods
|
||||
. "sh/preview.sh"
|
||||
|
||||
# Load cache functionality
|
||||
. "sh/cache.sh"
|
||||
|
||||
# Load MusicBrainz wrappers
|
||||
. "sh/mb.sh"
|
||||
|
||||
# Load local file handling
|
||||
. "sh/local.sh"
|
||||
|
||||
# Support of local music files
|
||||
if [ "${1:-}" = "--decorate" ]; then
|
||||
[ ! "${2:-}" ] && err "You did not specify a directory." && exit 1
|
||||
[ ! -d "$2" ] && err "Path $2 does not point to a directory." && exit 1
|
||||
if ! decorate "$2"; then
|
||||
err "Something went wrong. Are you're files tagged correctly?"
|
||||
exit 1
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "${1:-}" = "--reload" ]; then
|
||||
[ ! "${2:-}" ] && err "Path to decorated music is missing." && exit 1
|
||||
[ ! -d "$2" ] && err "Path does not point to a directory." && exit 1
|
||||
info "Reloading information of local music directory $2"
|
||||
load_local "$2" || err "Failed to load local data"
|
||||
info "Done"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "${1:-}" = "--list-releases" ]; then
|
||||
list_releases
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "${1:-}" = "--list-releasegroups" ]; then
|
||||
list_releasegroups
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "${1:-}" = "--list-artists" ]; then
|
||||
list_artists
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "${1:-}" = "--play-release" ]; then
|
||||
mbid=${2}
|
||||
deco=${3}
|
||||
base="$(dirname "$deco")"
|
||||
echo "Playing release ($mbid) [$deco]" >>/tmp/foo
|
||||
tmplist=$(mktemp)
|
||||
mb_release "$mbid" |
|
||||
$JQ -r --slurpfile deco "$deco" --arg base "$base" '$deco[].tracks as $filenames |
|
||||
.media[] |
|
||||
.position as $pos |
|
||||
.tracks |
|
||||
map({
|
||||
$pos,
|
||||
number: .number,
|
||||
file: $filenames[.id]
|
||||
}) |
|
||||
map(
|
||||
if(.number | type == "string" and test("^[0-9]+$")) then
|
||||
.number |= tonumber
|
||||
else
|
||||
.
|
||||
end
|
||||
) |
|
||||
sort_by([.pos, .number]) |
|
||||
map($base + "/" + .file)[]' >"$tmplist"
|
||||
if [ "${4:-}" ]; then
|
||||
mpv_queue_list "$tmplist"
|
||||
else
|
||||
mpv_play_list "$tmplist"
|
||||
fi
|
||||
rm -f "$tmplist"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "${1:-}" = "--play-recording" ]; then
|
||||
echo "Playing recording $2" >>/tmp/foo
|
||||
if [ "${3:-}" ]; then
|
||||
mpv_queue_file "$2"
|
||||
else
|
||||
mpv_play_file "$2"
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "${1:-}" = "--play-toggle" ]; then
|
||||
mpv_toggle_pause
|
||||
fi
|
||||
|
||||
if [ "${1:-}" = "--play-next" ]; then
|
||||
mpv_next
|
||||
fi
|
||||
|
||||
if [ "${1:-}" = "--play-previous" ]; then
|
||||
mpv_prev
|
||||
fi
|
||||
|
||||
if [ "${1:-}" = "--seek-forward" ]; then
|
||||
mpv_seek_forward
|
||||
fi
|
||||
|
||||
if [ "${1:-}" = "--seek-backward" ]; then
|
||||
mpv_seek_backward
|
||||
fi
|
||||
|
||||
if [ "${1:-}" = "--internal-preview-artist" ]; then
|
||||
__preview_artist "$2"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "${1:-}" = "--internal-reload" ]; then
|
||||
sleep 2
|
||||
sleep 1
|
||||
while [ -f "$LOCKFILE" ]; do
|
||||
sleep 1
|
||||
done
|
||||
cat "$RESULTS"
|
||||
column -t -s "$(printf '\t')" "$RESULTS" |
|
||||
sed 's| \+\([0-9a-f-]\+\)$|\t\1|'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -44,49 +156,236 @@ if [ "${1:-}" = "--internal-search" ]; then
|
||||
rm -f "$PIDFILE"
|
||||
kill -9 "$pid" >/dev/null 2>&1 || true
|
||||
fi
|
||||
[ ! "${2}" ] && exit 0
|
||||
[ ! "${3}" ] && exit 0
|
||||
# Save current pid
|
||||
echo "$$" >"$PIDFILE"
|
||||
sleep 1
|
||||
touch "$LOCKFILE"
|
||||
mb_search_artists "$2" |
|
||||
$JQ -r '.artists[] | [.id, .type, .name, .disambiguation, .["life-span"].begin, .["life-span"].end] | join("\t")' |
|
||||
awk \
|
||||
-F "\t" \
|
||||
-v format_person="$FORMAT_PERSON" \
|
||||
-v format_group="$FORMAT_GROUP" \
|
||||
-v format_disambiguation="$FORMAT_DISAMBIGUATION" \
|
||||
"$AWK_ARTISTS" |
|
||||
tee "$RESULTS" ||
|
||||
true
|
||||
sleep 1
|
||||
if [ "$2" = "artist" ]; then
|
||||
api_mb_search_artist "$3" |
|
||||
$JQ -r '.artists[] | [
|
||||
.id,
|
||||
.type,
|
||||
.name,
|
||||
.disambiguation,
|
||||
.["life-span"].begin,
|
||||
.["life-span"].end
|
||||
] | join("\t")' |
|
||||
awk \
|
||||
-F "\t" \
|
||||
-v file_local_artists="${LOCALDATA_ARTISTS:-}" \
|
||||
-v format_person="$AV_PERSON" \
|
||||
-v format_group="$AV_GROUP" \
|
||||
-v format_disambiguation="$AV_DISAMBIGUATION" \
|
||||
-v format_local="$FORMAT_LOCAL" \
|
||||
"$AWK_ARTISTS" |
|
||||
tee "$RESULTS" ||
|
||||
true
|
||||
else
|
||||
api_mb_search_releasegroup "$3" |
|
||||
$JQ -r '."release-groups"[] | [
|
||||
.id,
|
||||
."primary-type",
|
||||
(."secondary-types" // []|join(";")),
|
||||
."first-release-date",
|
||||
.title,
|
||||
(."artist-credit" | map(([.name, .joinphrase]|join(""))) | join(""))
|
||||
] | join("\t")' |
|
||||
awk \
|
||||
-F "\t" \
|
||||
-v file_local_releasegroups="${LOCALDATA_RELEASEGROUPS:-}" \
|
||||
-v format_release="$RGV_RELEASE" \
|
||||
-v format_release_w_artist="$RGV_RELEASE_W_ARTIST" \
|
||||
-v format_year="$RGV_YEAR" \
|
||||
-v format_album="$FORMAT_TYPE_ALBUM" \
|
||||
-v format_single="$FORMAT_TYPE_SINGLE" \
|
||||
-v format_ep="$FORMAT_TYPE_EP" \
|
||||
-v format_broadcast="$FORMAT_TYPE_BROADCAST" \
|
||||
-v format_other="$FORMAT_TYPE_OTHER" \
|
||||
-v format_has_secondary="$FORMAT_TYPE_HAS_SECONDARY" \
|
||||
-v format_secondary="$FORMAT_TYPE_SECONDARY" \
|
||||
-v format_compilation="$FORMAT_TYPE_SECONDARY_COMPILATION" \
|
||||
-v format_soundtrack="$FORMAT_TYPE_SECONDARY_SOUNDTRACK" \
|
||||
-v format_spokenword="$FORMAT_TYPE_SECONDARY_SPOKENWORD" \
|
||||
-v format_interview="$FORMAT_TYPE_SECONDARY_INTERVIEW" \
|
||||
-v format_audiobook="$FORMAT_TYPE_SECONDARY_AUDIOBOOK" \
|
||||
-v format_audiodrama="$FORMAT_TYPE_SECONDARY_AUDIODRAMA" \
|
||||
-v format_live="$FORMAT_TYPE_SECONDARY_LIVE" \
|
||||
-v format_remix="$FORMAT_TYPE_SECONDARY_REMIX" \
|
||||
-v format_djmix="$FORMAT_TYPE_SECONDARY_DJMIX" \
|
||||
-v format_mixtape="$FORMAT_TYPE_SECONDARY_MIXTAPE" \
|
||||
-v format_demo="$FORMAT_TYPE_SECONDARY_DEMO" \
|
||||
-v format_fieldrec="$FORMAT_TYPE_SECONDARY_FIELDREC" \
|
||||
-v format_local="$FORMAT_LOCAL" \
|
||||
"$AWK_RELEASEGROUPS" |
|
||||
cut -d "$(printf '\t')" -f 2- |
|
||||
column -t -s "$(printf '\t')" |
|
||||
sed 's| \+\([0-9a-f-]\+\)$|\t\1|' |
|
||||
tee "$RESULTS" ||
|
||||
true
|
||||
fi
|
||||
rm -f "$LOCKFILE" "$PIDFILE"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "${1:-}" = "--internal-browse-artist" ]; then
|
||||
mb_browse_release_groups "$2" |
|
||||
if [ "${1:-}" = "--internal-list-releasegroups" ]; then
|
||||
name=$(mb_artist "$2" | $JQ -r '.name')
|
||||
mb_artist_releasegroups "$2" |
|
||||
$JQ -r '."release-groups"[] | [
|
||||
.id,
|
||||
."primary-type",
|
||||
(."secondary-types" // []|join(";")),
|
||||
."first-release-date",
|
||||
.title
|
||||
.title,
|
||||
(."artist-credit" | map(([.name, .joinphrase]|join(""))) | join(""))
|
||||
] | join("\t")' |
|
||||
awk \
|
||||
-F "\t" \
|
||||
-v format_album="$FORMAT_ALBUM" \
|
||||
-v format_single="$FORMAT_SINGLE" \
|
||||
-v format_ep="$FORMAT_EP" \
|
||||
-v format_year="$FORMAT_YEAR" \
|
||||
"$AWK_RELEASEGROUPS"
|
||||
-v artist="$name" \
|
||||
-v file_local_releasegroups="${LOCALDATA_RELEASEGROUPS:-}" \
|
||||
-v format_release="$RGV_RELEASE" \
|
||||
-v format_release_w_artist="$RGV_RELEASE_W_ARTIST" \
|
||||
-v format_year="$RGV_YEAR" \
|
||||
-v format_album="$FORMAT_TYPE_ALBUM" \
|
||||
-v format_single="$FORMAT_TYPE_SINGLE" \
|
||||
-v format_ep="$FORMAT_TYPE_EP" \
|
||||
-v format_broadcast="$FORMAT_TYPE_BROADCAST" \
|
||||
-v format_other="$FORMAT_TYPE_OTHER" \
|
||||
-v format_has_secondary="$FORMAT_TYPE_HAS_SECONDARY" \
|
||||
-v format_secondary="$FORMAT_TYPE_SECONDARY" \
|
||||
-v format_compilation="$FORMAT_TYPE_SECONDARY_COMPILATION" \
|
||||
-v format_soundtrack="$FORMAT_TYPE_SECONDARY_SOUNDTRACK" \
|
||||
-v format_spokenword="$FORMAT_TYPE_SECONDARY_SPOKENWORD" \
|
||||
-v format_interview="$FORMAT_TYPE_SECONDARY_INTERVIEW" \
|
||||
-v format_audiobook="$FORMAT_TYPE_SECONDARY_AUDIOBOOK" \
|
||||
-v format_audiodrama="$FORMAT_TYPE_SECONDARY_AUDIODRAMA" \
|
||||
-v format_live="$FORMAT_TYPE_SECONDARY_LIVE" \
|
||||
-v format_remix="$FORMAT_TYPE_SECONDARY_REMIX" \
|
||||
-v format_djmix="$FORMAT_TYPE_SECONDARY_DJMIX" \
|
||||
-v format_mixtape="$FORMAT_TYPE_SECONDARY_MIXTAPE" \
|
||||
-v format_demo="$FORMAT_TYPE_SECONDARY_DEMO" \
|
||||
-v format_fieldrec="$FORMAT_TYPE_SECONDARY_FIELDREC" \
|
||||
-v format_local="$FORMAT_LOCAL" \
|
||||
"$AWK_RELEASEGROUPS" |
|
||||
sort -n -r |
|
||||
cut -d "$(printf '\t')" -f 2- |
|
||||
column -t -s "$(printf '\t')" |
|
||||
sed 's| \+\([0-9a-f-]\+\)$|\t\1|'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "${1:-}" = "--internal-list-releases" ]; then
|
||||
title="$(mb_releasegroup "$2" |
|
||||
$JQ -r '.title')"
|
||||
artist="$(mb_releasegroup "$2" |
|
||||
$JQ -r '."artist-credit" | map(([.name, .joinphrase]|join(""))) | join("")')"
|
||||
mb_releasegroup_releases "$2" |
|
||||
$JQ -r '."releases"[] | [
|
||||
.id,
|
||||
.status,
|
||||
.date,
|
||||
."cover-art-archive".count,
|
||||
(."label-info" | map(.label.name) | unique | join(", ")),
|
||||
(.media | map(."track-count") | add),
|
||||
(.media | map(.format) | unique | join(", ")),
|
||||
.country,
|
||||
.title,
|
||||
(."artist-credit" | map(([.name, .joinphrase]|join(""))) | join(""))
|
||||
] | join("\t")' |
|
||||
awk \
|
||||
-F "\t" \
|
||||
-v file_local_releases="${LOCALDATA_RELEASES:-}" \
|
||||
-v release_official="$FORMAT_STATUS_OFFICIAL" \
|
||||
-v release_promotion="$FORMAT_STATUS_PROMO" \
|
||||
-v release_bootleg="$FORMAT_STATUS_BOOTLEG" \
|
||||
-v release_pseudo="$FORMAT_STATUS_PSEUDO" \
|
||||
-v release_withdrawn="$FORMAT_STATUS_WITHDRAWN" \
|
||||
-v release_expunged="$FORMAT_STATUS_EXPUNGED" \
|
||||
-v release_cancelled="$FORMAT_STATUS_CANCELLED" \
|
||||
-v release_format="$RV_FORMAT" \
|
||||
-v release_format_title_artist="$RV_TITLE_ARTIST" \
|
||||
-v release_format_title="$RV_TITLE" \
|
||||
-v release_format_artist="$RV_ARTIST" \
|
||||
-v rg_artist="$artist" \
|
||||
-v rg_title="$title" \
|
||||
-v format_local="$FORMAT_LOCAL" \
|
||||
"$AWK_RELEASES" |
|
||||
sort -n -r |
|
||||
cut -d "$(printf '\t')" -f 2- |
|
||||
column -t -s "$(printf '\t')" |
|
||||
sed 's| \+\([0-9a-f-]\+\):\(.*$\)$|\t\1\t\2|'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "${1:-}" = "--internal-list-recordings" ]; then
|
||||
deco="$(grep "$2" "$LOCALDATA_RELEASES" | cut -d "$(printf '\t')" -f 2)"
|
||||
if [ "$deco" ]; then
|
||||
base="$(dirname "$deco")"
|
||||
rectmp=$(mktemp)
|
||||
$JQ -r --arg base "$base/" '.tracks | to_entries | map(.key + "\t" + $base + .value) | join("\n")' "$deco" >"$rectmp"
|
||||
fi
|
||||
mb_release "$2" |
|
||||
$JQ -r '.media[] |
|
||||
.position as $pos |
|
||||
.tracks[] | [
|
||||
.id,
|
||||
$pos,
|
||||
.number,
|
||||
.length,
|
||||
.recording.title,
|
||||
(.recording."artist-credit" | map([.name, .joinphrase] | join("")) | join(""))
|
||||
] |
|
||||
join("\t")' |
|
||||
awk \
|
||||
-F "\t" \
|
||||
-v file_local_recordings="${rectmp:-}" \
|
||||
-v format="$REC_FORMAT" \
|
||||
-v format_local="$FORMAT_LOCAL" \
|
||||
"$AWK_RECORDINGS" |
|
||||
sort -k1,1n -k2,2g |
|
||||
cut -d "$(printf '\t')" -f 2- |
|
||||
column -t -s "$(printf '\t')" -R 2,3,6 |
|
||||
sed 's| \+\([0-9a-f-]\+\):\(.*$\)$|\t\1\t\2|'
|
||||
if [ "${rectmp:-}" ] && [ -f "$rectmp" ]; then
|
||||
rm -f "$rectmp"
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "${1:-}" = "--internal-list-local-artists" ]; then
|
||||
cat "$LOCALDATA_ARTISTS_VIEW" 2>/dev/null
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "${1:-}" = "--internal-list-local-releasegroups" ]; then
|
||||
cat "$LOCALDATA_RELEASEGROUPS_VIEW" 2>/dev/null
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "${1:-}" = "--internal-list-local-releases" ]; then
|
||||
cat "$LOCALDATA_RELEASES_VIEW" 2>/dev/null
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "${1:-}" = "--help" ]; then
|
||||
$CAT <<EOF
|
||||
Usage: \`$0\` [ \`--help\` ]
|
||||
cat <<EOF
|
||||
Usage: $0 [OPTION]
|
||||
|
||||
Options:
|
||||
\`--help\`: Show this help and exit.
|
||||
GENERAL OPTIONS:
|
||||
--help Show this help and exit.
|
||||
--artists Default options, list artists of local music
|
||||
--albums List albums of local music
|
||||
--search-artist [<query>] Search artist on MusicBrainz
|
||||
--search-album [<query>] Search album on MusicBrainz
|
||||
--artist <mbid> List release groups of given artist <mbid>
|
||||
--releasegroup <mbid> List releases in given release group <mbid>
|
||||
--release <mbid> Show release given by <mbid>
|
||||
--ni-search-artist [<query>] Non-interactive search on MusicBrainz
|
||||
--ni-search-album [<query>] Non-interactive search on MusicBrainz
|
||||
|
||||
MANAGE LOCAL MUSIC:
|
||||
--decorate <path> Decorate directory containing a tagged release
|
||||
--reload <path> Populate database with decorated local music from <path>
|
||||
EOF
|
||||
exit 0
|
||||
fi
|
||||
@@ -99,43 +398,341 @@ tmpdir=$(mktemp -d)
|
||||
LOCKFILE="$tmpdir/lock"
|
||||
RESULTS="$tmpdir/results"
|
||||
PIDFILE="$tmpdir/pid"
|
||||
trap 'rm -rf "$tmpdir"' EXIT INT
|
||||
export LOCKFILE RESULTS PIDFILE
|
||||
|
||||
if [ "${1:-}" = "--search" ]; then
|
||||
$0 --internal-search "$2"
|
||||
if [ "${1:-}" = "--ni-search-artist" ]; then
|
||||
$0 --internal-search "artist" "$2"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "${1:-}" = "--ni-search-album" ]; then
|
||||
$0 --internal-search "releasegroup" "$2"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
case "${1:-}" in
|
||||
"" | "--artist" | "--releasegroup" | "--release" | "--search-artist" | "--search-album" | "--albums" | "--artists") ;;
|
||||
*)
|
||||
err "Unknown option $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Start mpv
|
||||
mpv_start
|
||||
|
||||
while true; do
|
||||
case "${1:-}" in
|
||||
"--show-artist")
|
||||
"--artist")
|
||||
name="$(mb_artist "$2" | $JQ -r '.name')"
|
||||
secsymb="$(printf "$FORMAT_TYPE_HAS_SECONDARY" "")"
|
||||
sel=$(
|
||||
$0 --internal-browse-artist "$2" |
|
||||
$0 --internal-list-releasegroups "$2" |
|
||||
$FZF \
|
||||
--no-clear \
|
||||
--ansi \
|
||||
--reverse \
|
||||
--cycle \
|
||||
--no-sort \
|
||||
--disabled \
|
||||
--query="!$secsymb " \
|
||||
--delimiter="\t" \
|
||||
--accept-nth="{1}" \
|
||||
--with-nth="{2}"
|
||||
--prompt="$(printf "$ARTIST_PROMPT" "$name")" \
|
||||
--accept-nth="{2}" \
|
||||
--with-nth="{1}" \
|
||||
--expect="ctrl-h,ctrl-a" \
|
||||
--bind="alt-l:change-query($FORMAT_LOCAL )" \
|
||||
--bind="load:unbind(enter)+unbind(alt-enter)+transform:[ \"\$FZF_TOTAL_COUNT\" -gt 0 ] && echo \"rebind:ctrl-l\" || echo \"unbind:ctrl-l)\"" \
|
||||
--bind="ctrl-l:accept" \
|
||||
--bind="alt-b:execute-silent:xdg-open 'https://musicbrainz.org/release-group/{r2}' &" \
|
||||
--bind="alt-1:change-query(!$secsymb ),alt-2:change-query($secsymb )" \
|
||||
--bind="ctrl-d:half-page-down,ctrl-u:half-page-up"
|
||||
)
|
||||
[ "$sel" ] && set -- "--show-release" "$sel"
|
||||
lns=$(echo "$sel" | wc -l)
|
||||
key=$(echo "$sel" | head -1 | tail -1)
|
||||
mid=$(echo "$sel" | head -2 | tail -1)
|
||||
[ "$lns" -eq 2 ] && [ ! "$key" ] && [ "$mid" ] && set -- "--releasegroup" "$mid"
|
||||
[ "$lns" -eq 2 ] && [ "$key" = "ctrl-h" ] && set -- ""
|
||||
[ "$lns" -eq 2 ] && [ "$key" = "ctrl-a" ] && set -- "--select-artist" "$(mb_releasegroup "$mid" | $JQ -r '."artist-credit"')"
|
||||
;;
|
||||
*)
|
||||
"--releasegroup")
|
||||
title="$(mb_releasegroup "$2" |
|
||||
$JQ -r '.title')"
|
||||
artist="$(mb_releasegroup "$2" |
|
||||
$JQ -r '."artist-credit" | map(([.name, .joinphrase]|join(""))) | join("")')"
|
||||
sel=$(
|
||||
$0 --internal-list-releases "$2" |
|
||||
$FZF \
|
||||
--no-clear \
|
||||
--ansi \
|
||||
--reverse \
|
||||
--cycle \
|
||||
--no-sort \
|
||||
--query="$FORMAT_STATUS_OFFICIAL " \
|
||||
--delimiter="\t" \
|
||||
--prompt="$(printf "$FULL_PROMPT" "$artist" "$title")" \
|
||||
--accept-nth="{2}" \
|
||||
--with-nth="{1}" \
|
||||
--expect="ctrl-h,ctrl-a" \
|
||||
--bind="alt-l:change-query($FORMAT_LOCAL )" \
|
||||
--bind="load:transform:[ \"\$FZF_TOTAL_COUNT\" -gt 0 ] && echo \"rebind:ctrl-l\" || echo \"unbind:ctrl-l\"" \
|
||||
--bind="enter:execute-silent:$0 --play-release {2} {3}" \
|
||||
--bind="alt-enter:execute-silent:$0 --play-release {2} {3} q" \
|
||||
--bind="alt-space:execute-silent:$0 --play-toggle" \
|
||||
--bind="ctrl-n:execute-silent:$0 --play-next" \
|
||||
--bind="ctrl-p:execute-silent:$0 --play-previous" \
|
||||
--bind="shift-right:execute-silent:$0 --seek-forward" \
|
||||
--bind="shift-left:execute-silent:$0 --seek-backward" \
|
||||
--bind="focus:transform:
|
||||
[ {3} ] && c=rebind || c=unbind
|
||||
for key in enter alt-enter alt-space ctrl-n ctrl-p shift-right shift-left; do
|
||||
printf \"+%s(%s)\" \"\$c\" \"\$key\"
|
||||
done
|
||||
" \
|
||||
--bind="ctrl-l:accept" \
|
||||
--bind="alt-b:execute-silent:xdg-open 'https://musicbrainz.org/release/{r2}' &" \
|
||||
--bind="ctrl-d:half-page-down,ctrl-u:half-page-up"
|
||||
)
|
||||
lns=$(echo "$sel" | wc -l)
|
||||
key=$(echo "$sel" | head -1 | tail -1)
|
||||
mid=$(echo "$sel" | head -2 | tail -1)
|
||||
[ "$lns" -eq 2 ] && [ ! "$key" ] && [ "$mid" ] && set -- "--release" "$mid"
|
||||
[ "$lns" -eq 2 ] && [ "$key" = "ctrl-h" ] && set -- "--select-artist" "$(mb_releasegroup "$2" | $JQ -r -c '."artist-credit"')"
|
||||
[ "$lns" -eq 2 ] && [ "$key" = "ctrl-a" ] && set -- "--select-artist" "$(mb_release "$mid" | $JQ -r -c '."artist-credit"')"
|
||||
;;
|
||||
"--release")
|
||||
title="$(mb_release "$2" |
|
||||
$JQ -r '.title')"
|
||||
artist="$(mb_release "$2" |
|
||||
$JQ -r '."artist-credit" | map(([.name, .joinphrase]|join(""))) | join("")')"
|
||||
sel=$(
|
||||
$0 --internal-list-recordings "$2" |
|
||||
$FZF \
|
||||
--no-clear \
|
||||
--ansi \
|
||||
--reverse \
|
||||
--cycle \
|
||||
--no-sort \
|
||||
--delimiter="\t" \
|
||||
--prompt="$(printf "$FULL_PROMPT" "$artist" "$title")" \
|
||||
--accept-nth="{2}" \
|
||||
--with-nth="{1}" \
|
||||
--expect="ctrl-h,ctrl-a" \
|
||||
--bind="alt-l:change-query($FORMAT_LOCAL )" \
|
||||
--bind="enter:execute-silent:$0 --play-recording {3}" \
|
||||
--bind="alt-enter:execute-silent:$0 --play-recording {3} q" \
|
||||
--bind="alt-space:execute-silent:$0 --play-toggle" \
|
||||
--bind="ctrl-n:execute-silent:$0 --play-next" \
|
||||
--bind="ctrl-p:execute-silent:$0 --play-previous" \
|
||||
--bind="shift-right:execute-silent:$0 --seek-forward" \
|
||||
--bind="shift-left:execute-silent:$0 --seek-backward" \
|
||||
--bind="focus:transform:
|
||||
[ {3} ] && c=rebind || c=unbind
|
||||
for key in enter alt-enter alt-space ctrl-n ctrl-p shift-right shift-left; do
|
||||
printf \"+%s(%s)\" \"\$c\" \"\$key\"
|
||||
done
|
||||
" \
|
||||
--bind="alt-b:execute-silent:xdg-open 'https://musicbrainz.org/track/{r2}' &" \
|
||||
--bind="ctrl-d:half-page-down,ctrl-u:half-page-up"
|
||||
)
|
||||
lns=$(echo "$sel" | wc -l)
|
||||
key=$(echo "$sel" | head -1 | tail -1)
|
||||
mid=$(echo "$sel" | head -2 | tail -1)
|
||||
[ "$lns" -eq 2 ] && [ "$key" = "ctrl-h" ] && set -- "--releasegroup" "$(mb_release "$2" | $JQ -r -c '."release-group".id')"
|
||||
[ "$lns" -eq 2 ] && [ "$key" = "ctrl-a" ] && set -- "--select-artist" "$(mb_release "$2" | $JQ -r -c ".media[].tracks[] | select(.id==\"$mid\") | .\"artist-credit\"")"
|
||||
;;
|
||||
"--playlist")
|
||||
count=$(mpv_playlist_count)
|
||||
echo "Playlist: count=$count" >>/tmp/foo
|
||||
set -- ""
|
||||
;;
|
||||
"--select-artist")
|
||||
tput rmcup
|
||||
sel=$(
|
||||
echo "$2" |
|
||||
$JQ -r 'map([.artist.id, .artist.type, .name] | join("\t")) | join("\n")' |
|
||||
awk \
|
||||
-F "\t" \
|
||||
-v file_local_artists="${LOCALDATA_ARTISTS:-}" \
|
||||
-v format_person="$AV_PERSON" \
|
||||
-v format_group="$AV_GROUP" \
|
||||
-v format_disambiguation="$AV_DISAMBIGUATION" \
|
||||
-v format_local="$FORMAT_LOCAL" \
|
||||
"$AWK_ARTISTS" |
|
||||
column -t -s "$(printf '\t')" |
|
||||
sed 's| \+\([0-9a-f-]\+\)$|\t\1|' |
|
||||
$FZF \
|
||||
--no-clear \
|
||||
-1 \
|
||||
--ansi \
|
||||
--cycle \
|
||||
--no-sort \
|
||||
--border="bold" \
|
||||
--border-label="Select artist" \
|
||||
--delimiter="\t" \
|
||||
--prompt="$SEARCH_PROMPT" \
|
||||
--margin="5%,20%" \
|
||||
--bind="alt-l:change-query($FORMAT_LOCAL )" \
|
||||
--accept-nth="{2}" \
|
||||
--with-nth="{1}"
|
||||
)
|
||||
[ "$sel" ] && set -- "--artist" "$sel"
|
||||
;;
|
||||
"--search-album")
|
||||
sel=$(
|
||||
printf "" |
|
||||
$FZF \
|
||||
--no-clear \
|
||||
--ansi \
|
||||
--reverse \
|
||||
--no-sort \
|
||||
--disabled \
|
||||
--cycle \
|
||||
--delimiter="\t" \
|
||||
--accept-nth="{1}" \
|
||||
--with-nth="{2}" \
|
||||
--preview-window="wrap" \
|
||||
--preview="$0 --internal-preview-artist {1}" \
|
||||
--bind="change:execute-silent($0 --internal-search \$FZF_QUERY &)+reload($0 --internal-reload)"
|
||||
--prompt="$SEARCH_PROMPT" \
|
||||
--info="inline-right" \
|
||||
--info-command="echo \"Search album on MusicBrainz\"" \
|
||||
--color='input-fg:#ba478f' \
|
||||
--accept-nth="{2}" \
|
||||
--with-nth="{1}" \
|
||||
--expect="ctrl-c,ctrl-q,tab" \
|
||||
--expect="ctrl-/" \
|
||||
--bind="alt-l:change-query($FORMAT_LOCAL )" \
|
||||
--bind="start:transform:[ \"${2:-}\" ] && echo \"change-query:${2:-}\"" \
|
||||
--bind="load:unbind(enter)+unbind(alt-enter)+transform:[ \"\$FZF_TOTAL_COUNT\" -gt 0 ] && echo \"rebind:ctrl-l\" || echo \"unbind:ctrl-l\"" \
|
||||
--bind="ctrl-l:accept" \
|
||||
--bind="ctrl-d:half-page-down,ctrl-u:half-page-up" \
|
||||
--bind="alt-b:execute-silent:xdg-open 'https://musicbrainz.org/release-group/{r2}' &" \
|
||||
--bind="change:execute-silent($0 --internal-search releasegroup \$FZF_QUERY &)+reload($0 --internal-reload)" || true
|
||||
)
|
||||
[ "$sel" ] && set -- "--show-artist" "$sel"
|
||||
lns=$(echo "$sel" | wc -l)
|
||||
key=$(echo "$sel" | head -1 | tail -1)
|
||||
mid=$(echo "$sel" | head -2 | tail -1)
|
||||
[ "$key" = "ctrl-c" ] && tput rmcup && exit 0
|
||||
[ "$key" = "ctrl-q" ] && tput rmcup && exit 0
|
||||
[ "$key" = "tab" ] && set -- "--search-artist"
|
||||
[ "$key" = "ctrl-/" ] && set -- "--albums"
|
||||
[ "$lns" -eq 2 ] && [ ! "$key" ] && [ "$mid" ] && set -- "--releasegroup" "$mid"
|
||||
;;
|
||||
"--search-artist")
|
||||
sel=$(
|
||||
printf "" |
|
||||
$FZF \
|
||||
--no-clear \
|
||||
--ansi \
|
||||
--reverse \
|
||||
--no-sort \
|
||||
--disabled \
|
||||
--cycle \
|
||||
--delimiter="\t" \
|
||||
--prompt="$SEARCH_PROMPT" \
|
||||
--info="inline-right" \
|
||||
--info-command="echo \"Search music artist on MusicBrainz\"" \
|
||||
--color='input-fg:#ba478f' \
|
||||
--accept-nth="{2}" \
|
||||
--with-nth="{1}" \
|
||||
--preview-window="right,25%,border-left,wrap,<30(hidden)" \
|
||||
--preview="$0 --internal-preview-artist {2}" \
|
||||
--expect="ctrl-c,ctrl-q,tab" \
|
||||
--expect="ctrl-/" \
|
||||
--bind="alt-l:change-query($FORMAT_LOCAL )" \
|
||||
--bind="start:transform:[ \"${2:-}\" ] && echo \"change-query:${2:-}\"" \
|
||||
--bind="load:unbind(enter)+unbind(alt-enter)+transform:[ \"\$FZF_TOTAL_COUNT\" -gt 0 ] && echo \"rebind:ctrl-l\" || echo \"unbind:ctrl-l\"" \
|
||||
--bind="ctrl-l:accept" \
|
||||
--bind="ctrl-d:half-page-down,ctrl-u:half-page-up" \
|
||||
--bind="down:preview-half-page-down,up:preview-half-page-up" \
|
||||
--bind="alt-b:execute-silent:xdg-open 'https://musicbrainz.org/artist/{r2}' &" \
|
||||
--bind="change:execute-silent($0 --internal-search artist \$FZF_QUERY &)+reload($0 --internal-reload)" || true
|
||||
)
|
||||
lns=$(echo "$sel" | wc -l)
|
||||
key=$(echo "$sel" | head -1 | tail -1)
|
||||
mid=$(echo "$sel" | head -2 | tail -1)
|
||||
[ "$key" = "ctrl-c" ] && tput rmcup && exit 0
|
||||
[ "$key" = "ctrl-q" ] && tput rmcup && exit 0
|
||||
[ "$key" = "tab" ] && set -- "--search-album"
|
||||
[ "$key" = "ctrl-/" ] && set -- "--artists"
|
||||
[ "$lns" -eq 2 ] && [ ! "$key" ] && [ "$mid" ] && set -- "--artist" "$mid"
|
||||
;;
|
||||
"--albums")
|
||||
sel=$(
|
||||
$0 --internal-list-local-releasegroups |
|
||||
$FZF \
|
||||
--no-clear \
|
||||
--ansi \
|
||||
--reverse \
|
||||
--cycle \
|
||||
--delimiter="\t" \
|
||||
--prompt="$SEARCH_PROMPT" \
|
||||
--info="inline-right" \
|
||||
--info-command="echo \"Search albums\"" \
|
||||
--accept-nth="{2}" \
|
||||
--with-nth="{1}" \
|
||||
--expect="ctrl-h,ctrl-a" \
|
||||
--expect="ctrl-c,ctrl-q,tab" \
|
||||
--expect="ctrl-/" \
|
||||
--bind="alt-l:change-query($FORMAT_LOCAL )" \
|
||||
--bind="load:transform:[ \"\$FZF_TOTAL_COUNT\" -gt 0 ] && echo \"rebind:ctrl-l\" || echo \"unbind:ctrl-l\"" \
|
||||
--bind="enter:execute-silent:$0 --play-release {2} {3}" \
|
||||
--bind="alt-enter:execute-silent:$0 --play-release {2} {3} q" \
|
||||
--bind="alt-space:execute-silent:$0 --play-toggle" \
|
||||
--bind="ctrl-n:execute-silent:$0 --play-next" \
|
||||
--bind="ctrl-p:execute-silent:$0 --play-previous" \
|
||||
--bind="shift-right:execute-silent:$0 --seek-forward" \
|
||||
--bind="shift-left:execute-silent:$0 --seek-backward" \
|
||||
--bind="focus:transform:
|
||||
[ {3} ] && c=rebind || c=unbind
|
||||
for key in enter alt-enter alt-space ctrl-n ctrl-p shift-right shift-left; do
|
||||
printf \"+%s(%s)\" \"\$c\" \"\$key\"
|
||||
done
|
||||
" \
|
||||
--bind="ctrl-l:accept" \
|
||||
--bind="alt-b:execute-silent:xdg-open 'https://musicbrainz.org/release/{r2}' &" \
|
||||
--bind="ctrl-d:half-page-down,ctrl-u:half-page-up" || true
|
||||
)
|
||||
lns=$(echo "$sel" | wc -l)
|
||||
key=$(echo "$sel" | head -1 | tail -1)
|
||||
mid=$(echo "$sel" | head -2 | tail -1)
|
||||
[ "$lns" -eq 2 ] && [ ! "$key" ] && [ "$mid" ] && set -- "--releasegroup" "$mid"
|
||||
[ "$lns" -eq 2 ] && [ "$key" = "ctrl-h" ] && set -- "--albums"
|
||||
[ "$lns" -eq 2 ] && [ "$key" = "ctrl-a" ] && set -- "--select-artist" "$(mb_releasegroup "$mid" | $JQ -r -c '."artist-credit"')"
|
||||
[ "$key" = "ctrl-c" ] && tput rmcup && exit 0
|
||||
[ "$key" = "ctrl-q" ] && tput rmcup && exit 0
|
||||
[ "$key" = "ctrl-/" ] && set -- "--search-album"
|
||||
[ "$key" = "tab" ] && set -- "--artists"
|
||||
;;
|
||||
*)
|
||||
sel=$(
|
||||
$0 --internal-list-local-artists |
|
||||
$FZF \
|
||||
--no-clear \
|
||||
--ansi \
|
||||
--reverse \
|
||||
--cycle \
|
||||
--delimiter="\t" \
|
||||
--prompt="$SEARCH_PROMPT" \
|
||||
--info="inline-right" \
|
||||
--info-command="echo \"Search music artist\"" \
|
||||
--accept-nth="{2}" \
|
||||
--with-nth="{1}" \
|
||||
--preview-window="right,25%,border-left,wrap,<30(hidden)" \
|
||||
--preview="$0 --internal-preview-artist {2}" \
|
||||
--expect="ctrl-c,ctrl-q,tab" \
|
||||
--expect="ctrl-/" \
|
||||
--bind="alt-l:change-query($FORMAT_LOCAL )" \
|
||||
--bind="load:unbind(enter)+unbind(alt-enter)+transform:[ \"\$FZF_TOTAL_COUNT\" -gt 0 ] && echo \"rebind:ctrl-l\" || echo \"unbind:ctrl-l\"" \
|
||||
--bind="ctrl-l:accept" \
|
||||
--bind="ctrl-d:half-page-down,ctrl-u:half-page-up" \
|
||||
--bind="down:preview-half-page-down,up:preview-half-page-up" \
|
||||
--bind="alt-b:execute-silent:xdg-open 'https://musicbrainz.org/artist/{r2}' &" || true
|
||||
)
|
||||
lns=$(echo "$sel" | wc -l)
|
||||
key=$(echo "$sel" | head -1 | tail -1)
|
||||
mid=$(echo "$sel" | head -2 | tail -1)
|
||||
[ "$key" = "ctrl-c" ] && tput rmcup && exit 0
|
||||
[ "$key" = "ctrl-q" ] && tput rmcup && exit 0
|
||||
[ "$key" = "tab" ] && set -- "--albums"
|
||||
[ "$key" = "ctrl-/" ] && set -- "--search-artist"
|
||||
[ "$lns" -eq 2 ] && [ ! "$key" ] && [ "$mid" ] && set -- "--artist" "$mid"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
234
src/sh/api.sh
234
src/sh/api.sh
@@ -1,64 +1,216 @@
|
||||
# Argument: MB Artist ID
|
||||
mb_browse_releases() {
|
||||
$CURL \
|
||||
--get \
|
||||
--data-urlencode fmt=json \
|
||||
--data-urlencode artist="$1" \
|
||||
--data-urlencode inc=release-groups \
|
||||
-A "$APP_NAME/$APP_VERSION ($APP_WEBSITE)" \
|
||||
"https://musicbrainz.org/ws/2/release"
|
||||
MB_MAX_RETRIES=10
|
||||
MB_BROWSE_STEPS=100
|
||||
USER_AGENT="$APP_NAME/$APP_VERSION ($APP_WEBSITE)"
|
||||
SLEEP_ON_ERROR=1
|
||||
export MB_BROWSE_STEPS
|
||||
|
||||
__mpv_command() {
|
||||
echo "mpv_command: $*" >>/tmp/foo
|
||||
printf "{ \"command\": [\"%s\"] }\n" "$1" | $SOCAT - "$MPV_SOCKET"
|
||||
}
|
||||
|
||||
# Argument: MB Artist ID
|
||||
mb_browse_release_groups() {
|
||||
$CURL \
|
||||
--get \
|
||||
--data-urlencode fmt=json \
|
||||
--data-urlencode artist="$1" \
|
||||
-A "$APP_NAME/$APP_VERSION ($APP_WEBSITE)" \
|
||||
"https://musicbrainz.org/ws/2/release-group"
|
||||
__mpv_command_with_arg() {
|
||||
echo "mpv_command_1: $*" >>/tmp/foo
|
||||
printf "{ \"command\": [\"%s\", \"%s\"] }\n" "$1" "$2" | $SOCAT - "$MPV_SOCKET"
|
||||
}
|
||||
|
||||
__mpv_command_with_args2() {
|
||||
echo "mpv_command_2: $*" >>/tmp/foo
|
||||
printf "{ \"command\": [\"%s\", \"%s\", \"%s\"] }\n" "$1" "$2" "$3" | $SOCAT - "$MPV_SOCKET"
|
||||
}
|
||||
|
||||
__mpv_get() {
|
||||
__mpv_command_with_arg "expand-text" "$2" | $JQ -r '.data'
|
||||
}
|
||||
|
||||
mpv_playlist_count() {
|
||||
__mpv_get '${playlist/count}'
|
||||
}
|
||||
|
||||
mpv_playlist_position() {
|
||||
__mpv_get '${playlist-pos}'
|
||||
}
|
||||
|
||||
mpv_quit() {
|
||||
__mpv_command "quit"
|
||||
}
|
||||
|
||||
mpv_start() {
|
||||
MPV_SOCKET="$(mktemp --suffix=.sock)"
|
||||
trap 'mpv_quit; rm -f "$MPV_SOCKET"' EXIT INT
|
||||
$MPV --no-config --no-terminal --input-ipc-server="$MPV_SOCKET" --idle --no-osc --no-input-default-bindings &
|
||||
}
|
||||
|
||||
mpv_play_file() {
|
||||
__mpv_command_with_arg "loadfile" "$1"
|
||||
}
|
||||
|
||||
mpv_queue_file() {
|
||||
__mpv_command_with_args2 "loadfile" "$1" "append-play"
|
||||
}
|
||||
|
||||
mpv_play_list() {
|
||||
__mpv_command_with_arg "loadlist" "$1"
|
||||
}
|
||||
|
||||
mpv_queue_list() {
|
||||
__mpv_command_with_arg "loadlist" "$1" "append-play"
|
||||
}
|
||||
|
||||
mpv_next() {
|
||||
__mpv_command "playlist-next"
|
||||
}
|
||||
|
||||
mpv_prev() {
|
||||
__mpv_command "playlist-prev"
|
||||
}
|
||||
|
||||
mpv_seek_forward() {
|
||||
__mpv_command_with_arg "seek" "10"
|
||||
}
|
||||
|
||||
mpv_seek_backward() {
|
||||
__mpv_command_with_arg "seek" "-10"
|
||||
}
|
||||
|
||||
mpv_toggle_pause() {
|
||||
__mpv_command_with_arg "cycle" "pause"
|
||||
}
|
||||
|
||||
__api_mb() {
|
||||
tmpout=$(mktemp)
|
||||
for _ in $(seq "$MB_MAX_RETRIES"); do
|
||||
case "$1" in
|
||||
"artist")
|
||||
$CURL \
|
||||
--output "$tmpout" \
|
||||
--get \
|
||||
--data fmt=json \
|
||||
--data inc="url-rels+artist-rels+aliases" \
|
||||
-A "$USER_AGENT" \
|
||||
"https://musicbrainz.org/ws/2/artist/$2"
|
||||
;;
|
||||
"releasegroup")
|
||||
$CURL \
|
||||
--output "$tmpout" \
|
||||
--get \
|
||||
--data fmt=json \
|
||||
--data inc=artist-credits \
|
||||
-A "$USER_AGENT" \
|
||||
"https://musicbrainz.org/ws/2/release-group/$2"
|
||||
;;
|
||||
"release")
|
||||
$CURL \
|
||||
--output "$tmpout" \
|
||||
--get \
|
||||
--data fmt=json \
|
||||
--data inc="recordings+artist-credits+release-groups+labels" \
|
||||
-A "$USER_AGENT" \
|
||||
"https://musicbrainz.org/ws/2/release/$2"
|
||||
;;
|
||||
"browse-artist-releasegroups")
|
||||
$CURL \
|
||||
--output "$tmpout" \
|
||||
--get \
|
||||
--data fmt=json \
|
||||
--data inc=artist-credits \
|
||||
--data limit="$MB_BROWSE_STEPS" \
|
||||
--data offset="$3" \
|
||||
--data artist="$2" \
|
||||
-A "$USER_AGENT" \
|
||||
"https://musicbrainz.org/ws/2/release-group"
|
||||
;;
|
||||
"browse-releasegroup-releases")
|
||||
$CURL \
|
||||
--output "$tmpout" \
|
||||
--get \
|
||||
--data fmt=json \
|
||||
--data inc="artist-credits+labels+media+release-groups" \
|
||||
--data limit="$MB_BROWSE_STEPS" \
|
||||
--data offset="$3" \
|
||||
--data release-group="$2" \
|
||||
-A "$USER_AGENT" \
|
||||
"https://musicbrainz.org/ws/2/release"
|
||||
;;
|
||||
"search-artist")
|
||||
$CURL \
|
||||
--output "$tmpout" \
|
||||
--get \
|
||||
--data fmt=json \
|
||||
--data-urlencode query="$2" \
|
||||
-A "$USER_AGENT" \
|
||||
"https://musicbrainz.org/ws/2/artist"
|
||||
;;
|
||||
"search-releasegroup")
|
||||
$CURL \
|
||||
--output "$tmpout" \
|
||||
--get \
|
||||
--data fmt=json \
|
||||
--data inc=artist-credits \
|
||||
--data-urlencode query="$2" \
|
||||
-A "$USER_AGENT" \
|
||||
"https://musicbrainz.org/ws/2/release-group"
|
||||
;;
|
||||
esac
|
||||
if ! $JQ -e '.error' "$tmpout" >/dev/null 2>/dev/stdout; then
|
||||
cat "$tmpout"
|
||||
rm -f "$tmpout"
|
||||
return 0
|
||||
else
|
||||
sleep "$SLEEP_ON_ERROR"
|
||||
fi
|
||||
done
|
||||
rm -f "$tmpout"
|
||||
err "Failed to fetch MusicBrainz data for $1 $2"
|
||||
return 1
|
||||
}
|
||||
|
||||
api_mb_artist() {
|
||||
__api_mb "artist" "$1"
|
||||
}
|
||||
|
||||
api_mb_releasegroup() {
|
||||
__api_mb "releasegroup" "$1"
|
||||
}
|
||||
|
||||
api_mb_release() {
|
||||
__api_mb "release" "$1"
|
||||
}
|
||||
|
||||
api_mb_browse_artist_releasegroups() {
|
||||
__api_mb "browse-artist-releasegroups" "$1" "${2:-0}"
|
||||
}
|
||||
|
||||
api_mb_browse_releasegroup_releases() {
|
||||
__api_mb "browse-releasegroup-releases" "$1" "${2:-0}"
|
||||
}
|
||||
|
||||
# Argument: Search string
|
||||
mb_search_artists() {
|
||||
$CURL \
|
||||
--get \
|
||||
--data-urlencode fmt=json \
|
||||
--data-urlencode query="$1" \
|
||||
-A "$APP_NAME/$APP_VERSION ($APP_WEBSITE)" \
|
||||
"https://musicbrainz.org/ws/2/artist"
|
||||
api_mb_search_artist() {
|
||||
__api_mb "search-artist" "$1"
|
||||
}
|
||||
|
||||
# Argument: MB Artist ID
|
||||
mb_get_artist() {
|
||||
$CURL \
|
||||
--get \
|
||||
--data-urlencode fmt=json \
|
||||
--data-urlencode inc="url-rels" \
|
||||
-A "$APP_NAME/$APP_VERSION ($APP_WEBSITE)" \
|
||||
"https://musicbrainz.org/ws/2/artist/$1"
|
||||
api_mb_search_releasegroup() {
|
||||
__api_mb "search-releasegroup" "$1"
|
||||
}
|
||||
|
||||
# Argument: Discogs id
|
||||
discogs_get_artist() {
|
||||
api_discogs_artist() {
|
||||
$CURL \
|
||||
--get \
|
||||
-A "$APP_NAME/$APP_VERSION ($APP_WEBSITE)" \
|
||||
-A "$USER_AGENT" \
|
||||
"https://api.discogs.com/artists/$1"
|
||||
}
|
||||
|
||||
# Argument: wikidata id
|
||||
wikidata_get_links() {
|
||||
api_wikidata_sitelinks() {
|
||||
$CURL \
|
||||
--get \
|
||||
-A "$APP_NAME/$APP_VERSION ($APP_WEBSITE)" \
|
||||
-A "$USER_AGENT" \
|
||||
"https://www.wikidata.org/w/rest.php/wikibase/v1/entities/items/$1/sitelinks"
|
||||
}
|
||||
|
||||
# Argument: Wikipedia name (last part of URL)
|
||||
wikipedia_en_get_summary() {
|
||||
api_wikipedia_en_summary() {
|
||||
$CURL \
|
||||
--get \
|
||||
-A "$APP_NAME/$APP_VERSION ($APP_WEBSITE)" \
|
||||
-A "$USER_AGENT" \
|
||||
"https://en.wikipedia.org/api/rest_v1/page/summary/$1"
|
||||
}
|
||||
|
@@ -18,3 +18,10 @@ AWK_RELEASEGROUPS=$(
|
||||
EOF
|
||||
)
|
||||
export AWK_RELEASEGROUPS
|
||||
|
||||
AWK_RECORDINGS=$(
|
||||
cat <<'EOF'
|
||||
@@include awk/recordings.awk
|
||||
EOF
|
||||
)
|
||||
export AWK_RECORDINGS
|
||||
|
161
src/sh/cache.sh
Normal file
161
src/sh/cache.sh
Normal file
@@ -0,0 +1,161 @@
|
||||
# Caching structure
|
||||
#
|
||||
# ./artist/radix(uuid)/musicbrainz.json # Artist information
|
||||
# ./artist/radix(uuid)/releasegroups.json # List of all release groups
|
||||
# ./artist/radix(uuid)/... # Any other artist information
|
||||
# ./releasegroup/radix(uuid)/musicbrainz.json # Release group information
|
||||
# ./releasegroup/radix(uuid)/releases.json # List of all releases in release group
|
||||
# ./release/radix(uuid)/musicbrainz.json # Release information with tracklist etc.
|
||||
CACHEDIR="$HOME/.cache/$APP_NAME"
|
||||
TYPE_ARTIST="artist"
|
||||
TYPE_RELEASEGROUP="releasegroup"
|
||||
TYPE_RELEASE="release"
|
||||
|
||||
artist_filename="musicbrainz.json"
|
||||
artist_releasegroups_filename="releasegroups.json"
|
||||
artist_discogs_filename="discogs.json"
|
||||
artist_wikidata_filename="wikidata.json"
|
||||
artist_enwikipedia_filename="enwikipedia.json"
|
||||
releasegroup_filename="musicbrainz.json"
|
||||
releasegroup_releases_filename="releases.json"
|
||||
release_filename="musicbrainz.json"
|
||||
|
||||
# Radix transform directory name
|
||||
__radix() {
|
||||
echo "$1" | awk -F "" '{ print $1$2$3$4"/"$5$6$7$8"/"$0 }'
|
||||
}
|
||||
|
||||
# Super wrapper
|
||||
# argument $1: type
|
||||
# argument $2: MusicBrainz ID
|
||||
# argument $3: Filename of json file
|
||||
__get_json() {
|
||||
f="$CACHEDIR/$1/$(__radix "$2")/$3"
|
||||
[ -f "$f" ] || return
|
||||
cat "$f"
|
||||
}
|
||||
|
||||
# Super wrapper
|
||||
# argument $1: type
|
||||
# argument $2: MusicBrainz ID
|
||||
# argument $3: Filename of json file
|
||||
__put_json() {
|
||||
dir="$CACHEDIR/$1/$(__radix "$2")"
|
||||
[ -d "$dir" ] || mkdir -p "$dir"
|
||||
f="$dir/$3"
|
||||
tmpf=$(mktemp)
|
||||
cat >"$tmpf"
|
||||
[ -s "$tmpf" ] && mv "$tmpf" "$f" || printf "{}" >"$f"
|
||||
}
|
||||
|
||||
## Artist
|
||||
cache_get_artist() {
|
||||
__get_json "$TYPE_ARTIST" "$1" "$artist_filename"
|
||||
}
|
||||
|
||||
cache_get_artist_releasegroups() {
|
||||
__get_json "$TYPE_ARTIST" "$1" "$artist_releasegroups_filename"
|
||||
}
|
||||
|
||||
cache_get_artist_discogs() {
|
||||
__get_json "$TYPE_ARTIST" "$1" "$artist_discogs_filename"
|
||||
}
|
||||
|
||||
cache_get_artist_enwikipedia() {
|
||||
__get_json "$TYPE_ARTIST" "$1" "$artist_enwikipedia_filename"
|
||||
}
|
||||
|
||||
cache_get_artist_wikidata() {
|
||||
__get_json "$TYPE_ARTIST" "$1" "$artist_wikidata_filename"
|
||||
}
|
||||
|
||||
cache_put_artist() {
|
||||
cat | __put_json "$TYPE_ARTIST" "$1" "$artist_filename"
|
||||
}
|
||||
|
||||
cache_put_artist_releasegroups() {
|
||||
cat | __put_json "$TYPE_ARTIST" "$1" "$artist_releasegroups_filename"
|
||||
}
|
||||
|
||||
cache_append_artist_releasegroups() {
|
||||
tmpf=$(mktemp)
|
||||
cat >"$tmpf"
|
||||
updated=$(mktemp)
|
||||
f="$CACHEDIR/$TYPE_ARTIST/$(__radix "$1")/$artist_releasegroups_filename"
|
||||
$JQ -r --slurpfile n "$tmpf" '."release-groups" += ($n[0]|."release-groups")' "$f" >"$updated" && mv "$updated" "$f"
|
||||
rm -f "$tmpf"
|
||||
}
|
||||
|
||||
cache_put_artist_discogs() {
|
||||
cat | __put_json "$TYPE_ARTIST" "$1" "$artist_discogs_filename"
|
||||
}
|
||||
|
||||
cache_put_artist_enwikipedia() {
|
||||
cat | __put_json "$TYPE_ARTIST" "$1" "$artist_enwikipedia_filename"
|
||||
}
|
||||
|
||||
cache_put_artist_wikidata() {
|
||||
cat | __put_json "$TYPE_ARTIST" "$1" "$artist_wikidata_filename"
|
||||
}
|
||||
|
||||
## Release group
|
||||
cache_get_releasegroup() {
|
||||
__get_json "$TYPE_RELEASEGROUP" "$1" "$releasegroup_filename"
|
||||
}
|
||||
|
||||
cache_get_releasegroup_releases() {
|
||||
__get_json "$TYPE_RELEASEGROUP" "$1" "$releasegroup_releases_filename"
|
||||
}
|
||||
|
||||
cache_put_releasegroup() {
|
||||
cat | __put_json "$TYPE_RELEASEGROUP" "$1" "$releasegroup_filename"
|
||||
}
|
||||
|
||||
cache_put_releasegroup_releases() {
|
||||
cat | __put_json "$TYPE_RELEASEGROUP" "$1" "$releasegroup_releases_filename"
|
||||
}
|
||||
|
||||
cache_append_releasegroup_releases() {
|
||||
tmpf=$(mktemp)
|
||||
cat >"$tmpf"
|
||||
updated=$(mktemp)
|
||||
f="$CACHEDIR/$TYPE_RELEASEGROUP/$(__radix "$1")/$releasegroup_releases_filename"
|
||||
$JQ -r --slurpfile n "$tmpf" '."releases" += ($n[0]|."releases")' "$f" >"$updated" && mv "$updated" "$f"
|
||||
rm -f "$tmpf"
|
||||
}
|
||||
|
||||
## Release
|
||||
cache_get_release() {
|
||||
__get_json "$TYPE_RELEASE" "$1" "$release_filename"
|
||||
}
|
||||
|
||||
cache_put_release() {
|
||||
cat | __put_json "$TYPE_RELEASE" "$1" "$release_filename"
|
||||
}
|
||||
|
||||
## Cache deletion
|
||||
cache_delete_artist() {
|
||||
# Get release groups
|
||||
echo "NOT IMPLEMENTED" >/dev/stderr
|
||||
}
|
||||
|
||||
# Check if main items are in cache
|
||||
# argument $1: type
|
||||
# argument $2: MusicBrainz ID
|
||||
in_cache() {
|
||||
case "$1" in
|
||||
"$TYPE_ARTIST")
|
||||
fn="$artist_filename"
|
||||
;;
|
||||
"$TYPE_RELEASEGROUP")
|
||||
fn="$releasegroup_filename"
|
||||
;;
|
||||
"$TYPE_RELEASE")
|
||||
fn="$release_filename"
|
||||
;;
|
||||
*)
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
[ "$(__get_json "$1" "$2" "$fn")" ] && return 0 || return 1
|
||||
}
|
4
src/sh/config.sh
Normal file
4
src/sh/config.sh
Normal file
@@ -0,0 +1,4 @@
|
||||
if [ "${CONFIGFILE:-}" ]; then
|
||||
[ ! -f "$CONFIGFILE" ] && err "Configuration $CONFIGFILE not found." && exit 1
|
||||
. "$CONFIGFLIE"
|
||||
fi
|
@@ -1,3 +1,15 @@
|
||||
ERR="\033[38;5;196m"
|
||||
INFO="\033[38;5;75m"
|
||||
DBG=$ERR
|
||||
OFF="\033[m"
|
||||
err() {
|
||||
echo "ERROR: ${1:-}"
|
||||
echo "${ERR}ERROR:${OFF} ${1:-}" >/dev/stderr
|
||||
}
|
||||
|
||||
info() {
|
||||
echo "${INFO}Info:${OFF} ${1:-}" >/dev/stderr
|
||||
}
|
||||
|
||||
debug() {
|
||||
echo "${DBG}DEBUG${OFF} ${INFO}$(date)${OFF}: $*" >/dev/stderr
|
||||
}
|
||||
|
247
src/sh/local.sh
Normal file
247
src/sh/local.sh
Normal file
@@ -0,0 +1,247 @@
|
||||
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")
|
||||
name=$(mb_artist "$mbid" | $JQ -r ".name")
|
||||
;;
|
||||
"$TYPE_RELEASEGROUP")
|
||||
name=$(mb_releasegroup "$mbid" | $JQ -r ".title")
|
||||
;;
|
||||
"$TYPE_RELEASE")
|
||||
name=$(mb_release "$mbid" | $JQ -r ".title")
|
||||
;;
|
||||
esac
|
||||
cnt=$((cnt + 1))
|
||||
printf "\033[2K\r%d/%d (%s: %s)" "$cnt" "$lines" "$mbid" "$name"
|
||||
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"
|
||||
LOCALDATA_ARTISTS_VIEW="$LOCALDATADIR/artists_view"
|
||||
LOCALDATA_RELEASEGROUPS_VIEW="$LOCALDATADIR/releasegroups_view"
|
||||
LOCALDATA_RELEASES_VIEW="$LOCALDATADIR/releases_view"
|
||||
DECORATION_FILENAME=${DECORATION_FILENAME:-"mbid.json"}
|
||||
|
||||
# Load local music
|
||||
# argument $1: path to decorated music files
|
||||
load_local() {
|
||||
[ -d "$LOCALDATADIR" ] || mkdir -p "$LOCALDATADIR"
|
||||
tmpreleases=$(mktemp)
|
||||
[ -f "$tmpreleases" ] || exit 1
|
||||
info "Locating and parsing decoration files ($DECORATION_FILENAME)"
|
||||
find "$1" -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"
|
||||
# Precompute views
|
||||
info "Precomputing artist view"
|
||||
while IFS= read -r aid; do
|
||||
mb_artist "$aid" | $JQ -r '[
|
||||
.id,
|
||||
.type,
|
||||
.name,
|
||||
.disambiguation,
|
||||
.["life-span"].begin,
|
||||
.["life-span"].end
|
||||
] | join("\t")'
|
||||
done <"$LOCALDATA_ARTISTS" |
|
||||
awk \
|
||||
-F "\t" \
|
||||
-v file_local_artists="${LOCALDATA_ARTISTS:-}" \
|
||||
-v format_person="$AV_PERSON" \
|
||||
-v format_group="$AV_GROUP" \
|
||||
-v format_disambiguation="$AV_DISAMBIGUATION" \
|
||||
-v format_local="$FORMAT_LOCAL" \
|
||||
"$AWK_ARTISTS" |
|
||||
sort |
|
||||
column -t -s "$(printf '\t')" |
|
||||
sed 's| \+\([0-9a-f-]\+\)$|\t\1|' >"$LOCALDATA_ARTISTS_VIEW"
|
||||
info "Precomputing releasegroup view"
|
||||
while IFS= read -r rgid; do
|
||||
mb_releasegroup "$rgid" | $JQ -r '[
|
||||
.id,
|
||||
."primary-type",
|
||||
(."secondary-types" // []|join(";")),
|
||||
."first-release-date",
|
||||
.title,
|
||||
(."artist-credit" | map(([.name, .joinphrase]|join(""))) | join(""))
|
||||
] | join("\t")'
|
||||
done <"$LOCALDATA_RELEASEGROUPS" |
|
||||
awk \
|
||||
-F "\t" \
|
||||
-v file_local_releasegroups="${LOCALDATA_RELEASEGROUPS:-}" \
|
||||
-v format_release="$RGV_RELEASE" \
|
||||
-v format_release_w_artist="$RGV_RELEASE_W_ARTIST" \
|
||||
-v format_year="$RGV_YEAR" \
|
||||
-v format_album="$FORMAT_TYPE_ALBUM" \
|
||||
-v format_single="$FORMAT_TYPE_SINGLE" \
|
||||
-v format_ep="$FORMAT_TYPE_EP" \
|
||||
-v format_broadcast="$FORMAT_TYPE_BROADCAST" \
|
||||
-v format_other="$FORMAT_TYPE_OTHER" \
|
||||
-v format_has_secondary="$FORMAT_TYPE_HAS_SECONDARY" \
|
||||
-v format_secondary="$FORMAT_TYPE_SECONDARY" \
|
||||
-v format_compilation="$FORMAT_TYPE_SECONDARY_COMPILATION" \
|
||||
-v format_soundtrack="$FORMAT_TYPE_SECONDARY_SOUNDTRACK" \
|
||||
-v format_spokenword="$FORMAT_TYPE_SECONDARY_SPOKENWORD" \
|
||||
-v format_interview="$FORMAT_TYPE_SECONDARY_INTERVIEW" \
|
||||
-v format_audiobook="$FORMAT_TYPE_SECONDARY_AUDIOBOOK" \
|
||||
-v format_audiodrama="$FORMAT_TYPE_SECONDARY_AUDIODRAMA" \
|
||||
-v format_live="$FORMAT_TYPE_SECONDARY_LIVE" \
|
||||
-v format_remix="$FORMAT_TYPE_SECONDARY_REMIX" \
|
||||
-v format_djmix="$FORMAT_TYPE_SECONDARY_DJMIX" \
|
||||
-v format_mixtape="$FORMAT_TYPE_SECONDARY_MIXTAPE" \
|
||||
-v format_demo="$FORMAT_TYPE_SECONDARY_DEMO" \
|
||||
-v format_fieldrec="$FORMAT_TYPE_SECONDARY_FIELDREC" \
|
||||
-v format_local="$FORMAT_LOCAL" \
|
||||
"$AWK_RELEASEGROUPS" |
|
||||
sort -n -r |
|
||||
cut -d "$(printf '\t')" -f 2- |
|
||||
column -t -s "$(printf '\t')" |
|
||||
sed 's| \+\([0-9a-f-]\+\)$|\t\1|' >"$LOCALDATA_RELEASEGROUPS_VIEW"
|
||||
info "Precomputing release view"
|
||||
list_releases |
|
||||
while IFS= read -r rid; do
|
||||
mb_release "$rid" | $JQ -r '[
|
||||
.id,
|
||||
.status,
|
||||
.date,
|
||||
."cover-art-archive".count,
|
||||
(."label-info" | map(.label.name) | unique | join(", ")),
|
||||
(.media | map(."track-count") | add),
|
||||
(.media | map(.format) | unique | join(", ")),
|
||||
.country,
|
||||
.title,
|
||||
(."artist-credit" | map(([.name, .joinphrase]|join(""))) | join(""))
|
||||
] | join("\t")'
|
||||
done |
|
||||
awk \
|
||||
-F "\t" \
|
||||
-v file_local_releases="${LOCALDATA_RELEASES:-}" \
|
||||
-v release_official="$FORMAT_STATUS_OFFICIAL" \
|
||||
-v release_promotion="$FORMAT_STATUS_PROMO" \
|
||||
-v release_bootleg="$FORMAT_STATUS_BOOTLEG" \
|
||||
-v release_pseudo="$FORMAT_STATUS_PSEUDO" \
|
||||
-v release_withdrawn="$FORMAT_STATUS_WITHDRAWN" \
|
||||
-v release_expunged="$FORMAT_STATUS_EXPUNGED" \
|
||||
-v release_cancelled="$FORMAT_STATUS_CANCELLED" \
|
||||
-v release_format="$RV_FORMAT" \
|
||||
-v release_format_title_artist="$RV_TITLE_ARTIST" \
|
||||
-v release_format_title="$RV_TITLE" \
|
||||
-v release_format_artist="$RV_ARTIST" \
|
||||
-v format_local="$FORMAT_LOCAL" \
|
||||
"$AWK_RELEASES" |
|
||||
sort -n -r |
|
||||
cut -d "$(printf '\t')" -f 2- |
|
||||
column -t -s "$(printf '\t')" |
|
||||
sed 's| \+\([0-9a-f-]\+\):\(.*$\)$|\t\1\t\2|' >"$LOCALDATA_RELEASES_VIEW"
|
||||
}
|
||||
|
||||
# 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"
|
||||
}
|
133
src/sh/mb.sh
Normal file
133
src/sh/mb.sh
Normal file
@@ -0,0 +1,133 @@
|
||||
# The only IDs uses here are MusicBrainz IDs
|
||||
|
||||
# Helper methods to retrieve from cache, if it exists, and otherwise populate
|
||||
# cache and retrieve
|
||||
__mb_artist_cache_or_fetch() {
|
||||
if ! cache_get_artist "$1"; then
|
||||
api_mb_artist "$1" | cache_put_artist "$1"
|
||||
cache_get_artist "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
__mb_releasegroup_cache_or_fetch() {
|
||||
if ! cache_get_releasegroup "$1"; then
|
||||
api_mb_releasegroup "$1" | cache_put_releasegroup "$1"
|
||||
cache_get_releasegroup "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
__mb_release_cache_or_fetch() {
|
||||
if ! cache_get_release "$1"; then
|
||||
api_mb_release "$1" | cache_put_release "$1"
|
||||
cache_get_release "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
__mb_artist_cache_or_fetch_releasegroups() {
|
||||
if ! cache_get_artist_releasegroups "$1"; then
|
||||
api_mb_browse_artist_releasegroups "$1" | cache_put_artist_releasegroups "$1"
|
||||
rg="$(cache_get_artist_releasegroups "$1")"
|
||||
total=$(printf "%s" "$rg" | $JQ -r '."release-group-count"')
|
||||
seen=$MB_BROWSE_STEPS
|
||||
while [ "$total" -gt "$seen" ]; do
|
||||
# Fetch remaning release groups, and append to cache
|
||||
sleep 1 # Make sure we don't get blocked (we prefer not to handle failed requests...)
|
||||
api_mb_browse_artist_releasegroups "$1" "$seen" | cache_append_artist_releasegroups "$1"
|
||||
seen=$((seen + MB_BROWSE_STEPS))
|
||||
done
|
||||
cache_get_artist_releasegroups "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
__mb_releasegroup_cache_or_fetch_releases() {
|
||||
if ! cache_get_releasegroup_releases "$1"; then
|
||||
api_mb_browse_releasegroup_releases "$1" | cache_put_releasegroup_releases "$1"
|
||||
releases="$(cache_get_releasegroup_releases "$1")"
|
||||
total=$(printf "%s" "$releases" | $JQ -r '."release-count"')
|
||||
seen=$MB_BROWSE_STEPS
|
||||
while [ "$total" -gt "$seen" ]; do
|
||||
# Fetch remaning releases, and append to cache
|
||||
sleep 1 # Make sure we don't get blocked (we prefer not to handle failed requests...)
|
||||
api_mb_browse_releasegroup_releases "$1" "$seen" | cache_append_releasegroup_releases "$1"
|
||||
seen=$((seen + MB_BROWSE_STEPS))
|
||||
done
|
||||
cache_get_releasegroup_releases "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
# Get MusicBrainz json for artist
|
||||
# @argument $1: MusicBrainz Artist ID
|
||||
mb_artist() {
|
||||
__mb_artist_cache_or_fetch "$1"
|
||||
}
|
||||
|
||||
# Get Wikidata json for artist
|
||||
# @argument $1: MusicBrainz Artist ID
|
||||
mb_artist_wikidata() {
|
||||
if ! cache_get_artist_wikidata "$1"; then
|
||||
wikidataid=$(mb_artist "$1" |
|
||||
$JQ -r '.relations |
|
||||
map(select(.type=="wikidata")) |
|
||||
.[0].url.resource // ""' |
|
||||
awk -F "/" '{print $NF}')
|
||||
[ ! "$wikidataid" ] && return
|
||||
api_wikidata_sitelinks "$wikidataid" | cache_put_artist_wikidata "$1"
|
||||
cache_get_artist_wikidata "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
# Get Wikipedia (English) summary json for artist
|
||||
# @argument $1: MusicBrainz Artist ID
|
||||
mb_artist_enwikipedia() {
|
||||
if ! cache_get_artist_enwikipedia "$1"; then
|
||||
# To fetch the wikipedia data, we need the wikipedia URL
|
||||
# There are two possibly ways to get the wikipedia URL
|
||||
# 1. From the website relations in MB (MB artists donw have wiki rels)
|
||||
# 2. MB website relations -> Wikidata -> Wikipedia
|
||||
# Lately, Wikipedia pages are not stored in the MB artist url relations.
|
||||
# For obvious reasons it is recommended to link to wikidata only. So, we
|
||||
# take the second route.
|
||||
wikidata=$(mb_artist_wikidata "$1" || true)
|
||||
wikiid=$(printf "%s" "$wikidata" |
|
||||
$JQ -r '.enwiki.url // ""' |
|
||||
awk -F "/" '{print $NF}')
|
||||
[ ! "$wikiid" ] && return
|
||||
api_wikipedia_en_summary "$wikiid" | cache_put_artist_enwikipedia "$1"
|
||||
cache_get_artist_enwikipedia "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
# Get Discogs json for artist
|
||||
# @argument $1: MusicBrainz Artist ID
|
||||
mb_artist_discogs() {
|
||||
if ! cache_get_artist_discogs "$1"; then
|
||||
discogsid=$(mb_artist "$1" |
|
||||
$JQ -r '.relations |
|
||||
map(select(.type=="discogs")) |
|
||||
.[0].url.resource // ""' |
|
||||
awk -F "/" '{print $NF}')
|
||||
[ ! "$discogsid" ] && return
|
||||
api_discogs_artist "$discogsid" | cache_put_artist_discogs "$1"
|
||||
cache_get_artist_discogs "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
# Get release-groups json for artist
|
||||
# @argument $1: MusicBrainz Artist ID
|
||||
mb_artist_releasegroups() {
|
||||
__mb_artist_cache_or_fetch_releasegroups "$1"
|
||||
}
|
||||
|
||||
# Get MusicBrainz json for release group
|
||||
# @argument $1: MusicBrainz Release-Group ID
|
||||
mb_releasegroup() {
|
||||
__mb_releasegroup_cache_or_fetch "$1"
|
||||
}
|
||||
|
||||
mb_releasegroup_releases() {
|
||||
__mb_releasegroup_cache_or_fetch_releases "$1"
|
||||
}
|
||||
|
||||
mb_release() {
|
||||
__mb_release_cache_or_fetch "$1"
|
||||
}
|
@@ -1,35 +1,39 @@
|
||||
__description_from_wikidata() {
|
||||
wiki=$(wikidata_get_links "$1" | $JQ -r '.enwiki' | awk -F "/" '{print $NF}')
|
||||
[ ! "$wiki" ] || [ "$wiki" = "null" ] && return
|
||||
desc=$(wikipedia_en_get_summary "$wiki" | $JQ -r '.extract')
|
||||
[ ! "$wiki" ] || [ "$wiki" = "null" ] && return
|
||||
echo "$desc"
|
||||
__shape() {
|
||||
cat | tr -d '\r' | fold -s -w "$((FZF_PREVIEW_COLUMNS - 4))" | awk '{print " "$0" "}'
|
||||
}
|
||||
|
||||
# For now, this prints the description of the artist.
|
||||
#
|
||||
# Source of information:
|
||||
# 1. Wikipedia
|
||||
# 2. Discogs
|
||||
# Print preview of artist
|
||||
# @input $1: MusicBrainz Artist ID
|
||||
__preview_artist() {
|
||||
# Get artist information from MusicBrainz
|
||||
artist_relations=$(mb_get_artist "$1" | $JQ -r ".relations")
|
||||
wikidata=$(echo "$artist_relations" |
|
||||
$JQ -r 'map(select(.type="wikidata")) | .[0].url.resource' |
|
||||
awk -F "/" '{print $NF}')
|
||||
if [ "$wikidata" ] && [ "$wikidata" != "null" ]; then
|
||||
desc=$(__description_from_wikidata "$wikidata")
|
||||
desc=$(mb_artist_enwikipedia "$1" | $JQ -r '.extract' | __shape)
|
||||
[ "$desc" ] || desc=$(mb_artist_discogs "$1" | $JQ -r '.profile' | sed 's/\[a=\([^]]*\)\]/\1/g' | __shape)
|
||||
if [ "$(mb_artist "$1" | $JQ -r '.type')" = "Person" ]; then
|
||||
# Show birth place and death place of person
|
||||
lsb=$(mb_artist "$1" | $JQ -r '."life-span".begin // ""' | head -c 4)
|
||||
lse=$(mb_artist "$1" | $JQ -r '."life-span".end // ""' | head -c 4)
|
||||
ab=$(mb_artist "$1" | $JQ -r '."begin-area".name // ""')
|
||||
ae=$(mb_artist "$1" | $JQ -r '."end-area".name // ""')
|
||||
if [ "$lsb" ] && [ "$ab" ]; then
|
||||
begin=$(printf "$APV_DATEPLACE" "$lsb" "$ab")
|
||||
elif [ "$lsb" ]; then
|
||||
begin=$(printf "$APV_DATE" "$lsb")
|
||||
elif [ "$ab" ]; then
|
||||
begin=$(printf "$APV_PLACE" "$ab")
|
||||
else
|
||||
begin=""
|
||||
fi
|
||||
if [ "$lse" ] && [ "$ae" ]; then
|
||||
end=$(printf "$APV_DATEPLACE" "$lse" "$ae")
|
||||
elif [ "$lse" ]; then
|
||||
end=$(printf "$APV_DATE" "$lse")
|
||||
elif [ "$ae" ]; then
|
||||
end=$(printf "$APV_PLACE" "$ae")
|
||||
else
|
||||
end=""
|
||||
fi
|
||||
[ "$begin" ] && lifespan="$(printf "$APV_BORN" "$begin")"
|
||||
[ "$end" ] && lifespan="$(printf "%s\n$APV_DIED" "$lifespan" "$end")"
|
||||
fi
|
||||
# Alternative: Get information from Discogs
|
||||
if [ ! "${desc:-}" ]; then
|
||||
discogs=$(echo "$artist_relations" |
|
||||
$JQ -r 'map(select(.type=="discogs")) | .[0].url.resource' |
|
||||
awk -F "/" '{print $NF}')
|
||||
[ ! "$discogs" ] || [ "$discogs" = "null" ] && return
|
||||
desc=$(discogs_get_artist "$discogs" |
|
||||
$JQ -r '.profile')
|
||||
[ ! "$desc" ] || [ "$desc" = "null" ] && return
|
||||
fi
|
||||
|
||||
echo "$desc" | fold -s -w "$FZF_PREVIEW_COLUMNS" | $CAT
|
||||
#link=$(printf "More info:\033]8;;%s\033\\ %s\033]8;;\033\\" "https://musicbrainz.org/" "[MusicBrainz]")
|
||||
printf "$APV_FORMAT" "$desc" "${lifespan:-}"
|
||||
}
|
||||
|
@@ -1,17 +1,75 @@
|
||||
COLOR_ARTIST="\033[38;5;227m"
|
||||
COLOR_DISAMBIGUATION="\033[38;5;110m"
|
||||
COLOR_RESET="\033[m"
|
||||
FORMAT_PERSON="${FORMAT_PERSON:-👤 $COLOR_ARTIST<<name>>$COLOR_RESET}"
|
||||
FORMAT_GROUP="${FORMAT_GROUP:-👥 $COLOR_ARTIST<<name>>$COLOR_RESET}"
|
||||
FORMAT_DISAMBIGUATION="${FORMAT_DISAMBIGUATION:-$COLOR_DISAMBIGUATION(<<disambiguation>>)$COLOR_RESET}"
|
||||
COLOR_ALBUM="\033[38;5;208m"
|
||||
COLOR_SINGLE="\033[38;5;210m"
|
||||
COLOR_EP="\033[38;5;209m"
|
||||
COLOR_RELEASE_TITLE="\033[38;5;229m"
|
||||
COLOR_RELEASE_YEAR="\033[38;5;179m"
|
||||
FORMAT_ALBUM="${FORMAT_ALBUM:-"💽 ${COLOR_ALBUM} LP $COLOR_RESET $COLOR_RELEASE_TITLE<<title>>$COLOR_RESET"}"
|
||||
FORMAT_SINGLE="${FORMAT_SINGLE:-"💽 ${COLOR_SINGLE}single$COLOR_RESET $COLOR_RELEASE_TITLE<<title>>$COLOR_RESET"}"
|
||||
FORMAT_EP="${FORMAT_EP:-"💽 ${COLOR_EP} EP $COLOR_RESET $COLOR_RELEASE_TITLE<<title>>$COLOR_RESET"}"
|
||||
FORMAT_YEAR="${FORMAT_YEAR:-"${COLOR_RELEASE_YEAR}(<<year>>)${COLOR_RESET}"}"
|
||||
export FORMAT_PERSON FORMAT_GROUP FORMAT_DISAMBIGUATION \
|
||||
FORMAT_ALBUM FORMAT_SINGLE FORMAT_EP FORMAT_YEAR
|
||||
# Colors (local)
|
||||
FAINT="\033[2m"
|
||||
CARTIST="\033[38;5;209m"
|
||||
CTITLE="\033[38;5;229m"
|
||||
CYEAR="\033[38;5;179m"
|
||||
CDISAMB="$FAINT\033[38;5;172m"
|
||||
CNOTE="\033[38;5;242m"
|
||||
CXXX="\033[38;5;109m"
|
||||
CDESC="\033[38;5;254m"
|
||||
CLIFE="\033[38;5;251m"
|
||||
OFF="\033[m"
|
||||
|
||||
FORMAT_LOCAL="${FORMAT_LOCAL:-"🔆"}"
|
||||
|
||||
# Prompts
|
||||
SEARCH_PROMPT=${SEARCH_PROMPT:-"🔎 〉"}
|
||||
ARTIST_PROMPT="${ARTIST_PROMPT:-"🎤 ${CARTIST}%s$OFF 〉"}"
|
||||
FULL_PROMPT="${FULL_PROMPT:-"🎤 ${CARTIST}%s$OFF 》${CTITLE}%s$OFF 〉"}"
|
||||
|
||||
# Artist view
|
||||
AV_PERSON="${AV_PERSON:-"🧑🎤 $CARTIST<<name>>$OFF"}"
|
||||
AV_GROUP="${AV_GROUP:-"🧑🤝🧑 $CARTIST<<name>>$OFF"}"
|
||||
AV_DISAMBIGUATION="${AV_DISAMBIGUATION:-"$CDISAMB(<<disambiguation>>)$OFF"}"
|
||||
|
||||
# Release group view
|
||||
RGV_RELEASE="${RGV_RELEASE:-"${CTITLE}<<title>>$OFF"}"
|
||||
RGV_RELEASE_W_ARTIST="${RGV_RELEASE_W_ARTIST:-"${CTITLE}<<title>>$OFF — ${CARTIST}<<artist>>$OFF"}"
|
||||
RGV_YEAR="${RGV_YEAR:-"${CYEAR}(<<year>>)$OFF"}"
|
||||
|
||||
# Types
|
||||
FORMAT_TYPE_ALBUM="${FORMAT_TYPE_ALBUM:-"LP 💽"}"
|
||||
FORMAT_TYPE_EP="${FORMAT_TYPE_EP:-"EP 📀"}"
|
||||
FORMAT_TYPE_SINGLE="${FORMAT_TYPE_SINGLE:-"SI 🎶"}"
|
||||
FORMAT_TYPE_BROADCAST="${FORMAT_TYPE_BROADCAST:-"BR 📻"}"
|
||||
FORMAT_TYPE_OTHER="${FORMAT_TYPE_OTHER:-"OT ❔"}"
|
||||
FORMAT_TYPE_HAS_SECONDARY="${FORMAT_TYPE_HAS_SECONDARY:-"%s☼"}"
|
||||
FORMAT_TYPE_SECONDARY="${FORMAT_TYPE_SECONDARY:-"${CNOTE}[☼: %s]$OFF"}"
|
||||
FORMAT_TYPE_SECONDARY_COMPILATION="${FORMAT_TYPE_SECONDARY_COMPILATION:-"🧩 compilation"}"
|
||||
FORMAT_TYPE_SECONDARY_SOUNDTRACK="${FORMAT_TYPE_SECONDARY_SOUNDTRACK:-"🎬 soundtrack"}"
|
||||
FORMAT_TYPE_SECONDARY_SPOKENWORD="${FORMAT_TYPE_SECONDARY_SPOKENWORD:-"📖 spokenword"}"
|
||||
FORMAT_TYPE_SECONDARY_INTERVIEW="${FORMAT_TYPE_SECONDARY_INTERVIEW:-"💬 interview"}"
|
||||
FORMAT_TYPE_SECONDARY_AUDIOBOOK="${FORMAT_TYPE_SECONDARY_AUDIOBOOK:-"🎧 audiobook"}"
|
||||
FORMAT_TYPE_SECONDARY_AUDIODRAMA="${FORMAT_TYPE_SECONDARY_AUDIODRAMA:-"🎭 audio drama"}"
|
||||
FORMAT_TYPE_SECONDARY_LIVE="${FORMAT_TYPE_SECONDARY_LIVE:-"🎤 live"}"
|
||||
FORMAT_TYPE_SECONDARY_REMIX="${FORMAT_TYPE_SECONDARY_REMIX:-"🔁 remix"}"
|
||||
FORMAT_TYPE_SECONDARY_DJMIX="${FORMAT_TYPE_SECONDARY_DJMIX:-"🪩 DJ-mix"}"
|
||||
FORMAT_TYPE_SECONDARY_MIXTAPE="${FORMAT_TYPE_SECONDARY_MIXTAPE:-"📼 mixtape"}"
|
||||
FORMAT_TYPE_SECONDARY_DEMO="${FORMAT_TYPE_SECONDARY_DEMO:-"🧪 demo"}"
|
||||
FORMAT_TYPE_SECONDARY_FIELDREC="${FORMAT_TYPE_SECONDARY_FIELDREC:-"🌿 field recording"}"
|
||||
|
||||
# Artist Preview
|
||||
APV_FORMAT="${APV_FORMAT:-"\n\n${CDESC}%s${OFF}\n\n${CLIFE}%s${OFF}"}"
|
||||
APV_DATE="${APV_DATE:-"%s"}"
|
||||
APV_PLACE="${APV_PLACE:-"%s"}"
|
||||
APV_DATEPLACE="${APV_DATEPLACE:-"$APV_DATE, $APV_PLACE"}"
|
||||
APV_BORN="${APV_BORN:-"🍼 Born: %s"}"
|
||||
APV_DIED="${APV_DIED:-"🕯️ Died: %s"}"
|
||||
|
||||
# Status
|
||||
FORMAT_STATUS_OFFICIAL="${FORMAT_STATUS_OFFICIAL:-"🟢 official"}"
|
||||
FORMAT_STATUS_PROMO="${FORMAT_STATUS_PROMO:-"📣 promo"}"
|
||||
FORMAT_STATUS_BOOTLEG="${FORMAT_STATUS_BOOTLEG:-"💣 bootleg"}"
|
||||
FORMAT_STATUS_PSEUDO="${FORMAT_STATUS_PSEUDO:-"🌀 pseudo"}"
|
||||
FORMAT_STATUS_WITHDRAWN="${FORMAT_STATUS_WITHDRAWN:-"🔙 withdrawn"}"
|
||||
FORMAT_STATUS_EXPUNGED="${FORMAT_STATUS_EXPUNGED:-"🧹 expunged"}"
|
||||
FORMAT_STATUS_CANCELLED="${FORMAT_STATUS_CANCELLED:-"❌ cancelled"}"
|
||||
|
||||
# Release view
|
||||
RV_FORMAT="<<status>>\t${CXXX}<<tracks>> tracks\t<<media>>$OFF\t${CYEAR}<<year>>\t<<country>>$OFF\t${CARTIST}<<label>>$OFF"
|
||||
RV_TITLE_ARTIST="${FAINT}as ${CTITLE}<<title>>$OFF by ${FAINT}${CARTIST}<<artist>>$OFF"
|
||||
RV_TITLE="${FAINT}as ${CTITLE}<<title>>$OFF"
|
||||
RV_ARTIST="${FAINT}by ${CARTIST}<<artist>>$OFF"
|
||||
|
||||
# Recording view
|
||||
REC_FORMAT="${CNOTE}${FAINT}<<med>>\t${CNOTE}<<nr>>$OFF\t${CTITLE}<<title>>\t${CARTIST}<<artist>>\t${CXXX}<<duration>>$OFF"
|
||||
|
@@ -6,15 +6,6 @@ else
|
||||
fi
|
||||
export FZF
|
||||
|
||||
if command -v "bat" >/dev/null; then
|
||||
CAT="bat"
|
||||
elif command -v "batcat" >/dev/null; then
|
||||
CAT="batcat"
|
||||
fi
|
||||
CAT=${CAT:+$CAT --color=always --style=plain --language=md}
|
||||
CAT=${CAT:-cat}
|
||||
export CAT
|
||||
|
||||
if command -v "curl" >/dev/null; then
|
||||
CURL="curl --silent"
|
||||
else
|
||||
@@ -30,3 +21,19 @@ else
|
||||
exit 1
|
||||
fi
|
||||
export JQ
|
||||
|
||||
if command -v "mpv" >/dev/null; then
|
||||
MPV="mpv"
|
||||
else
|
||||
err "Did not find mpv."
|
||||
exit 1
|
||||
fi
|
||||
export MPV
|
||||
|
||||
if command -v "socat" >/dev/null; then
|
||||
SOCAT="socat"
|
||||
else
|
||||
err "Did not find socat."
|
||||
exit 1
|
||||
fi
|
||||
export SOCAT
|
||||
|
Reference in New Issue
Block a user