Compare commits

...

11 Commits

Author SHA1 Message Date
f3c58ca859 rg caching, improved display 2025-07-23 20:51:22 +02:00
06e07f0f13 improved --help 2025-07-23 13:01:15 +02:00
a5646b8f6e minor iprv 2025-07-23 12:58:20 +02:00
fd162e2a63 imrpv: main view 2025-07-23 12:24:04 +02:00
b7f45c613c feat: discogs description and bugfixes 2025-07-23 12:11:24 +02:00
dcba30bf94 bugfix 2025-07-23 10:45:28 +02:00
81e49c0984 cacheing and mb wrapper 2025-07-23 10:22:11 +02:00
20152a368e imprv: prompts 2025-07-22 16:28:49 +02:00
8e9ae45724 imprv: trap to clean up 2025-07-22 16:18:53 +02:00
fa7c37c7ab improved release group display 2025-07-22 16:14:23 +02:00
47194034bf album imprv 2025-07-21 22:35:48 +02:00
7 changed files with 364 additions and 84 deletions

View File

@@ -1,22 +1,51 @@
BEGIN { OFS="\t" }
{
line_type=""
line_sectype=""
line_release=format_release
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
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)
line_year = year ? format_year : ""
sub("<<year>>", year, line_year)
sort = year ? year : 0
print line_type, line_release, line_year, line_sectype, sort, id
}

View File

@@ -23,13 +23,19 @@ set -eu
# Load preview methods
. "sh/preview.sh"
# Load cache functionality
. "sh/cache.sh"
# Load MusicBrainz wrappers
. "sh/mb.sh"
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
@@ -47,10 +53,16 @@ if [ "${1:-}" = "--internal-search" ]; then
[ ! "${2}" ] && 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")' |
__api_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" \
@@ -63,30 +75,61 @@ if [ "${1:-}" = "--internal-search" ]; then
exit 0
fi
if [ "${1:-}" = "--internal-browse-artist" ]; then
mb_browse_release_groups "$2" |
if [ "${1:-}" = "--internal-list-releases-fresh" ]; then
artistid="$2"
cache_delete_artist "$artistid"
shift 2
set -- "--internal-list-releases" "$artistid"
mb_artist "$artistid" >/dev/null
fi
if [ "${1:-}" = "--internal-list-releases" ]; then
mb_artist_releasegroups "$2" |
$JQ -r '."release-groups"[] | [
.id,
."primary-type",
(."secondary-types"|join(";")),
."first-release-date",
.title
] | join("\t")' |
awk \
-F "\t" \
-v format_album="$FORMAT_ALBUM" \
-v format_single="$FORMAT_SINGLE" \
-v format_ep="$FORMAT_EP" \
-v format_release="$FORMAT_RELEASE" \
-v format_year="$FORMAT_YEAR" \
"$AWK_RELEASEGROUPS"
-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" \
"$AWK_RELEASEGROUPS" |
sort |
sort -t "$(printf '\t')" -k 4 -n -r |
column -t -s "$(printf '\t')" |
sed 's| \+[0-9]\+ \+\([0-9a-f-]\+\)$|\t\1|'
exit 0
fi
if [ "${1:-}" = "--help" ]; then
$CAT <<EOF
Usage: \`$0\` [ \`--help\` ]
Usage: \`$0\` [ \`--help\` | \`--show-artist\` \`<mbid>\` ]
Options:
\`--help\`: Show this help and exit.
\`--show-artist\` \`<mbid>\`: Show releaes of the artist given by the MusicBrainz ID \`<mbid>\`.
EOF
exit 0
fi
@@ -99,6 +142,7 @@ 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
@@ -109,15 +153,22 @@ fi
while true; do
case "${1:-}" in
"--show-artist")
name=$(mb_artist "$2" | $JQ -r '.name')
secsymb=$(printf "$FORMAT_TYPE_HAS_SECONDARY" "")
sel=$(
$0 --internal-browse-artist "$2" |
$0 --internal-list-releases "$2" |
$FZF \
--ansi \
--no-sort \
--disabled \
--reverse \
--cycle \
--query="!$secsymb " \
--delimiter="\t" \
--accept-nth="{1}" \
--with-nth="{2}"
--prompt="$(printf "$ARTIST_PROMPT" "$name")" \
--accept-nth="{2}" \
--with-nth="{1}" \
--bind="alt-1:change-query(!$secsymb ),alt-2:change-query($secsymb )" \
--bind="ctrl-d:half-page-down,ctrl-u:half-page-up" \
--bind="ctrl-r:reload:$0 --internal-list-releases-fresh \"$2\""
)
[ "$sel" ] && set -- "--show-release" "$sel"
;;
@@ -126,13 +177,19 @@ while true; do
printf "" |
$FZF \
--ansi \
--reverse \
--no-sort \
--disabled \
--cycle \
--delimiter="\t" \
--prompt="$SEARCH_PROMPT" \
--info="inline-right" \
--info-command="echo \"Search music artist\"" \
--accept-nth="{1}" \
--with-nth="{2}" \
--preview-window="wrap" \
--preview="$0 --internal-preview-artist {1}" \
--bind="ctrl-d:half-page-down,ctrl-u:half-page-up" \
--bind="change:execute-silent($0 --internal-search \$FZF_QUERY &)+reload($0 --internal-reload)"
)
[ "$sel" ] && set -- "--show-artist" "$sel"

View File

@@ -1,46 +1,51 @@
MB_BROWSE_STEPS=100
export MB_BROWSE_STEPS
# Argument: MB Artist ID
mb_browse_releases() {
__api_mb_browse_releases() {
$CURL \
--get \
--data-urlencode fmt=json \
--data fmt=json \
--data inc=release-groups \
--data-urlencode artist="$1" \
--data-urlencode inc=release-groups \
-A "$APP_NAME/$APP_VERSION ($APP_WEBSITE)" \
"https://musicbrainz.org/ws/2/release"
}
# Argument: MB Artist ID
mb_browse_release_groups() {
__api_mb_browse_release_groups() {
$CURL \
--get \
--data-urlencode fmt=json \
--data fmt=json \
--data limit="$MB_BROWSE_STEPS" \
--data offset="${2:-0}" \
--data-urlencode artist="$1" \
-A "$APP_NAME/$APP_VERSION ($APP_WEBSITE)" \
"https://musicbrainz.org/ws/2/release-group"
}
# Argument: Search string
mb_search_artists() {
__api_mb_search_artists() {
$CURL \
--get \
--data-urlencode fmt=json \
--data fmt=json \
--data-urlencode query="$1" \
-A "$APP_NAME/$APP_VERSION ($APP_WEBSITE)" \
"https://musicbrainz.org/ws/2/artist"
}
# Argument: MB Artist ID
mb_get_artist() {
__api_mb_get_artist() {
$CURL \
--get \
--data-urlencode fmt=json \
--data-urlencode inc="url-rels" \
--data fmt=json \
--data inc="url-rels+artist-rels+aliases" \
-A "$APP_NAME/$APP_VERSION ($APP_WEBSITE)" \
"https://musicbrainz.org/ws/2/artist/$1"
}
# Argument: Discogs id
discogs_get_artist() {
__api_discogs_get_artist() {
$CURL \
--get \
-A "$APP_NAME/$APP_VERSION ($APP_WEBSITE)" \
@@ -48,7 +53,7 @@ discogs_get_artist() {
}
# Argument: wikidata id
wikidata_get_links() {
__api_wikidata_get_sitelinks() {
$CURL \
--get \
-A "$APP_NAME/$APP_VERSION ($APP_WEBSITE)" \
@@ -56,7 +61,7 @@ wikidata_get_links() {
}
# Argument: Wikipedia name (last part of URL)
wikipedia_en_get_summary() {
__api_wikipedia_en_get_summary() {
$CURL \
--get \
-A "$APP_NAME/$APP_VERSION ($APP_WEBSITE)" \

103
src/sh/cache.sh Normal file
View File

@@ -0,0 +1,103 @@
CACHEDIR="$HOME/.cache/$APP_NAME"
[ -d "$CACHEDIR" ] || mkdir "$CACHEDIR"
artist_mb_filename="musicbrainz.json"
artist_mb_releasegroups_filename="releasegroups.json"
artist_discogs_filename="discogs.json"
artist_wikidata_filename="wikidata.json"
artist_enwikipedia_filename="enwikipedia.json"
# Super wrapper
# argument $1: MusicBrainz Artist ID
# argument $2: Filename of json file
__get_artist_json() {
f="$CACHEDIR/$1/$2"
[ -f "$f" ] || return
cat "$f"
}
# Super wrapper
# argument $1: MusicBrainz Artist ID
# argument $2: Filename of json file
__put_artist_json() {
artistdir="$CACHEDIR/$1"
[ -d "$artistdir" ] || mkdir "$artistdir"
f="$artistdir/$2"
tmpf=$(mktemp)
cat >"$tmpf"
[ -s "$tmpf" ] && mv "$tmpf" "$f" || printf "{}" >"$f"
}
# Delete all cache associated to the given artist
# argument $1: MusicBrainz Artist ID
cache_delete_artist() {
artistdir="$CACHEDIR/$1"
rm -rf "$artistdir"
}
# Returns the cached MusicBrainz data for the artist given by the MusicBrainz
# Artist ID in $1
cache_get_artist_mb() {
__get_artist_json "$1" "$artist_mb_filename"
}
# Returns the cached MusicBrainz release-group data for the artist given by the
# MusicBrainz Artist ID in $1
cache_get_artist_mb_releasegroups() {
__get_artist_json "$1" "$artist_mb_releasegroups_filename"
}
# Returns the cached Discogs data for the artist given by the MusicBrainz
# Artist ID in $1
cache_get_artist_discogs() {
__get_artist_json "$1" "$artist_discogs_filename"
}
# Returns the cached Wikipedia (English) data for the artist given by the
# MusicBrainz Artist ID in $1
cache_get_artist_enwikipedia() {
__get_artist_json "$1" "$artist_enwikipedia_filename"
}
cache_get_artist_wikidata() {
__get_artist_json "$1" "$artist_wikidata_filename"
}
# Read from stdin the MusicBrainz data for the artist given by the MusicBrainz
# Artist ID in $1, and cache it.
cache_put_artist_mb() {
cat | __put_artist_json "$1" "$artist_mb_filename"
}
# Read from stdin the MusicBrainz release-group data for the artist given by
# the MusicBrainz Artist ID in $1, and cache it.
cache_put_artist_mb_releasegroups() {
cat | __put_artist_json "$1" "$artist_mb_releasegroups_filename"
}
# Read from stdin the MusicBrainz release-group data for the artist given by
# the MusicBrainz Artist ID in $1, and append it to the current cache.
cache_append_artist_mb_releasegroups() {
tmpf=$(mktemp)
cat >"$tmpf"
updated=$(mktemp)
f="$CACHEDIR/$1/$artist_mb_releasegroups_filename"
$JQ -r --slurpfile n "$tmpf" '."release-groups" += ($n[0]|."release-groups")' "$f" >"$updated" && mv "$updated" "$f"
rm -f "$tmpf"
}
# Read from stdin the Discogs data for the artist given by the MusicBrainz
# Artist ID in $1, and cache it.
cache_put_artist_discogs() {
cat | __put_artist_json "$1" "$artist_discogs_filename"
}
# Read from stdin the Wikipedia data (English) for the artist given by the
# MusicBrainz Artist ID in $1, and cache it.
cache_put_artist_enwikipedia() {
cat | __put_artist_json "$1" "$artist_enwikipedia_filename"
}
cache_put_artist_wikidata() {
cat | __put_artist_json "$1" "$artist_wikidata_filename"
}

89
src/sh/mb.sh Normal file
View File

@@ -0,0 +1,89 @@
# 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_mb "$1"; then
__api_mb_get_artist "$1" | cache_put_artist_mb "$1"
cache_get_artist_mb "$1"
fi
}
__mb_artist_cache_or_fetch_releasegroups() {
if ! cache_get_artist_mb_releasegroups "$1"; then
__api_mb_browse_release_groups "$1" | cache_put_artist_mb_releasegroups "$1"
rg="$(cache_get_artist_mb_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_release_groups "$1" "$seen" | cache_append_artist_mb_releasegroups "$1"
seen=$((seen + MB_BROWSE_STEPS))
done
cache_get_artist_mb_releasegroups "$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" ] || [ "$wikidataid" != "null" ] || return
__api_wikidata_get_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 || [ "$wikiid" = "null" ] && return
__api_wikipedia_en_get_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 || [ "$discogsid" = "null" ] && return
__api_discogs_get_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"
}

View File

@@ -1,35 +1,9 @@
__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"
}
# 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')
if [ ! "$desc" ]; then
desc=$(mb_artist_discogs "$1" | $JQ -r '.profile' | sed 's/\[a=\([^]]*\)\]/\1/g')
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
}

View File

@@ -4,14 +4,37 @@ 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_TYPE="\033[38;5;177m"
COLOR_TYPE_SECONDARY="\033[38;5;242m"
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_RELEASE="${FORMAT_RELEASE:-"${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
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:-"${COLOR_TYPE_SECONDARY}[☼: %s]$COLOR_RESET"}"
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"}"
SEARCH_PROMPT=${SEARCH_PROMPT:-"🔎 〉"}
ARTIST_PROMPT="${ARTIST_PROMPT:-"🎤 ${COLOR_ARTIST}%s$COLOR_RESET"}"
#BROWSE_PROMPT_ROOT="${BROWSE_PROMPT_ROOT:-"$SEARCH_PROMPT"}"
#BROWSE_PROMPT_ARTIST="${BROWSE_PROMPT_ARTIST:-"$AFMT 〉"}"
#BROWSE_PROMPT_RELEASE="${BROWSE_PROMPT_RELEASE:-"$AFMT 》 $RFMT 〉"}"
#AFMT="${AFMT:-"🎤 ${ARTIST_COLOR}%s${OFF}"}"
#RFMT="${RFMT:-"💽 ${RELEASE_COLOR}%s${OFF}"}"
#TFMT="${TFMT:-"🎵 ${TRACK_COLOR}%s${OFF}"}"