From d5b3d7c5973798ece1b8ead2f10b09778ce93d1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=84min=20Baumeler?= Date: Mon, 8 Sep 2025 12:10:10 +0200 Subject: [PATCH] cleaned up --- src/main.sh | 167 +++++++++++++++++-------------------------- src/sh/api.sh | 1 - src/sh/awk.sh | 36 +++++----- src/sh/cache.sh | 4 +- src/sh/config.sh | 1 + src/sh/filter.sh | 173 +++++---------------------------------------- src/sh/fzf.sh | 62 ++-------------- src/sh/helper.sh | 19 ----- src/sh/info.sh | 2 +- src/sh/keys.sh | 57 ++++++--------- src/sh/lists.sh | 57 +++------------ src/sh/local.sh | 26 +++---- src/sh/log.sh | 15 ++++ src/sh/mb.sh | 10 +-- src/sh/mpv.sh | 2 +- src/sh/playback.sh | 101 +++++++++++++++++++++++++- src/sh/playlist.sh | 26 +++++++ src/sh/preview.sh | 14 ++-- src/sh/query.sh | 155 ++++++++++++++++++++++++++++++++++++++++ src/sh/theme.sh | 20 ++++++ src/sh/tools.sh | 72 ++++++++++--------- 21 files changed, 522 insertions(+), 498 deletions(-) delete mode 100644 src/sh/helper.sh create mode 100644 src/sh/log.sh create mode 100644 src/sh/query.sh diff --git a/src/main.sh b/src/main.sh index c48dd44..f16d52a 100755 --- a/src/main.sh +++ b/src/main.sh @@ -40,23 +40,15 @@ VIEW_QUIT="quit" MODE_NORMAL="hidden" MODE_INSERT="show" -# Load helper methods +# Methods and variables used in main instance and subprocesses +# Load application information . "sh/info.sh" -# Load helper methods -. "sh/helper.sh" +# Load logging methods +. "sh/log.sh" -# Load configuration -. "sh/config.sh" - -# Load theme -. "sh/theme.sh" - -# Load keys -. "sh/keys.sh" - -# Load filters -. "sh/filter.sh" +# Load query methods +. "sh/query.sh" # Load playback helper . "sh/playback.sh" @@ -64,12 +56,6 @@ MODE_INSERT="show" # Load playlist tools . "sh/playlist.sh" -# Load AWK scripts -. "sh/awk.sh" - -# Load tools -. "sh/tools.sh" - # Load MusicBrainz and Discogs methods . "sh/api.sh" @@ -129,82 +115,22 @@ case "${1:-}" in exit 0 ;; "--playback") - # Control mpv instance + # Control mpv instance (see `src/sh/playback.sh`) # # @argument $2: view # @argument $3: MusicBrainz ID of current object # @argument $4: MusicBrainz ID of selected object # @argument $5: Path to decoration file - # - # This option controls the mpv instance via a key pressed in fzf. The key - # pressed is stored in the environment variable FZF_KEY and is resolved to - # the playback command through the method `playback_cmd_from_key` (see - # `src/sh/playback.sh` for a description of all playback commands). - view=${2:-} - mbid_current="${3:-}" - mbid="${4:-}" - path="${5:-}" - pbcmd=$(playback_cmd_from_key "$FZF_KEY") - case "$pbcmd" in - "$PLAYBACK_CMD_PLAY") - [ "$path" ] || exit 0 - case "$view" in - "$VIEW_ARTIST" | "$VIEW_SEARCH_ARTIST" | "$VIEW_SEARCH_ALBUM" | "$VIEW_LIST_ARTISTS" | "$VIEW_LIST_ALBUMS") debug "not implemented" ;; - "$VIEW_RELEASEGROUP") generate_playlist "$mbid" "$path" | mpv_play_list >/dev/null ;; - "$VIEW_RELEASE") generate_playlist "$mbid_current" "$path" "$mbid" | mpv_play_list >/dev/null ;; - "$VIEW_PLAYLIST") mpv_play_index $((FZF_POS - 1)) >/dev/null ;; - esac - ;; - "$PLAYBACK_CMD_QUEUE") - [ "$path" ] || exit 0 - case "$view" in - "$VIEW_ARTIST" | "$VIEW_SEARCH_ARTIST" | "$VIEW_SEARCH_ALBUM" | "$VIEW_LIST_ARTISTS" | "$VIEW_LIST_ALBUMS") debug "not implemented" ;; - "$VIEW_RELEASEGROUP") generate_playlist "$mbid" "$path" | mpv_queue_list >/dev/null ;; - "$VIEW_RELEASE") generate_playlist "$mbid_current" "$path" "$mbid" | mpv_queue_list >/dev/null ;; - "$VIEW_PLAYLIST") generate_playlist "$mbid_current" "$path" "$mbid" | mpv_queue_list >/dev/null ;; - esac - ;; - "$PLAYBACK_CMD_QUEUE_NEXT") - [ "$path" ] || exit 0 - case "$view" in - "$VIEW_ARTIST" | "$VIEW_SEARCH_ARTIST" | "$VIEW_SEARCH_ALBUM" | "$VIEW_LIST_ARTISTS" | "$VIEW_LIST_ALBUMS") debug "not implemented" ;; - "$VIEW_RELEASEGROUP") generate_playlist "$mbid" "$path" | mpv_queue_next_list >/dev/null ;; - "$VIEW_RELEASE") generate_playlist "$mbid_current" "$path" "$mbid" | mpv_queue_next_list >/dev/null ;; - "$VIEW_PLAYLIST") generate_playlist "$mbid_current" "$path" "$mbid" | mpv_queue_next_list >/dev/null ;; - esac - ;; - "$PLAYBACK_CMD_TOGGLE_PLAYBACK") mpv_toggle_pause ;; - "$PLAYBACK_CMD_PLAY_NEXT") mpv_next ;; - "$PLAYBACK_CMD_PLAY_PREV") mpv_prev ;; - "$PLAYBACK_CMD_SEEK_FORWARD") mpv_seek_forward ;; - "$PLAYBACK_CMD_SEEK_BACKWARD") mpv_seek_backward ;; - esac + shift + playback "$@" exit 0 ;; "--playlist") - # Run playback commands + # Run playback commands (see `src/sh/playlits.sh`) # - # @argument $2: playback command (see `src/sh/playback.sh`) - # - # This is a wrapper to execute mpv commands. - case "$2" in - "$PLAYLIST_CMD_REMOVE") mpv_rm_index $((FZF_POS - 1)) ;; - "$PLAYLIST_CMD_UP") mpv_playlist_move $((FZF_POS - 1)) $((FZF_POS - 2)) ;; - "$PLAYLIST_CMD_DOWN") mpv_playlist_move $((FZF_POS - 0)) $((FZF_POS - 1)) ;; - "$PLAYLIST_CMD_CLEAR") mpv_playlist_clear ;; - "$PLAYLIST_CMD_CLEAR_ABOVE") - for i in $(seq "$FZF_POS"); do - mpv_rm_index 0 - done - ;; - "$PLAYLIST_CMD_CLEAR_BELOW") - cnt=$(mpv_playlist_count) - rem=$((cnt - FZF_POS + 1)) - for i in $(seq "$rem"); do - mpv_rm_index $((FZF_POS - 1)) - done - ;; - esac + # @argument $2: playlist command + shift + playlist "$@" exit 0 ;; "--action-playlistcursor") @@ -254,9 +180,9 @@ case "${1:-}" in mbid_cur="${4:-}" mbid="${5:-}" case "$view" in - "$VIEW_ARTIST" | "$VIEW_SEARCH_ALBUM" | "$VIEW_LIST_ALBUMS") j="$(mb_releasegroup "$mbid" | $JQ -r --compact-output '."artist-credit"')" ;; - "$VIEW_RELEASEGROUP") j="$(mb_release "$mbid" | $JQ -r --compact-output '."artist-credit"')" ;; - "$VIEW_RELEASE" | "$VIEW_PLAYLIST") j="$(mb_release "$mbid_cur" | $JQ -r --compact-output ".media | map(.tracks) | flatten[] | select(.id == \"$mbid\") | .\"artist-credit\"")" ;; + "$VIEW_ARTIST" | "$VIEW_SEARCH_ALBUM" | "$VIEW_LIST_ALBUMS") j="$(mb_releasegroup "$mbid" | $JQ '."artist-credit"')" ;; + "$VIEW_RELEASEGROUP") j="$(mb_release "$mbid" | $JQ '."artist-credit"')" ;; + "$VIEW_RELEASE" | "$VIEW_PLAYLIST") j="$(mb_release "$mbid_cur" | $JQ ".media | map(.tracks) | flatten[] | select(.id == \"$mbid\") | .\"artist-credit\"")" ;; "$VIEW_SEARCH_ARTIST" | "$VIEW_LIST_ARTISTS") aid="$mbid" ;; esac if [ "$view" = "$VIEW_PLAYLIST" ]; then @@ -265,7 +191,7 @@ case "${1:-}" in fi if [ "${j:-}" ]; then cnt=$(echo "$j" | $JQ 'length') - [ "$cnt" -eq 1 ] && aid="$(echo "$j" | $JQ -r '.[0].artist.id')" + [ "$cnt" -eq 1 ] && aid="$(echo "$j" | $JQ '.[0].artist.id')" fi [ "${aid:-}" ] && $0 --action-draw "$mode" "$VIEW_ARTIST" "$aid" || printf "print(%s)+print(%s)+print(%s)+print(%s)+accept" "$VIEW_SELECT_ARTIST" "$j" "$view" "$mbid_cur" exit 0 @@ -322,11 +248,11 @@ case "${1:-}" in ;; "$VIEW_RELEASEGROUP") view="$VIEW_ARTIST" - mbid="$(mb_releasegroup "$mbid" | $JQ -r --compact-output '."artist-credit"[0].artist.id')" + mbid="$(mb_releasegroup "$mbid" | $JQ '."artist-credit"[0].artist.id')" ;; "$VIEW_RELEASE") view="$VIEW_RELEASEGROUP" - mbid="$(mb_release "$mbid" | $JQ -r --compact-output '."release-group".id')" + mbid="$(mb_release "$mbid" | $JQ '."release-group".id')" ;; esac ;; @@ -501,10 +427,39 @@ case "${1:-}" in ;; esac -# Start application: Set title, get temporary directory, start mpv daemon, and -# enter main fzf loop. +# Start application: +# - load configuration +# - load and export theme +# - load and export preset filters +# - load and export keys +# - load and export tools +# - load and export awk scripts +# - set title +# - get temporary directory for temporary files +# - start mpv daemon +# - enter main loop and start fzf + +# Load configuration +. "sh/config.sh" + +# Load theme +. "sh/theme.sh" + +# Load filters +. "sh/filter.sh" + +# Load keys +. "sh/keys.sh" + +# Load tools +. "sh/tools.sh" + +# Load AWK scripts +. "sh/awk.sh" + # Set window title printf '\033]0;%s\007' "$WINDOW_TITLE" + # Generate filenames for temporary files tmpdir=$(mktemp -d) LOCKFILE="$tmpdir/lock" @@ -512,6 +467,7 @@ RESULTS="$tmpdir/results" PIDFILE="$tmpdir/pid" trap 'rm -rf "$tmpdir"' EXIT INT export LOCKFILE RESULTS PIDFILE + # Start mpv mpv_start @@ -541,6 +497,8 @@ PUT_FZF_KEY_LOGIC="case \$FZF_KEY in space) echo \"put( )\";; left) echo backwar while true; do case "$VIEW" in "$VIEW_SELECT_ARTIST") + info "SELECT ARTIST VIEW with ARGS=$ARGS" + info "$(echo "$ARGS" | list_artists_from_json)" sel=$( echo "$ARGS" | list_artists_from_json | $FZF \ --bind="$KEYS_DOWN:down" \ @@ -548,13 +506,13 @@ while true; do --bind="$KEYS_HALFPAGE_DOWN:half-page-down" \ --bind="$KEYS_HALFPAGE_UP:half-page-up" \ --bind="enter,$KEYS_IN:print($VIEW_ARTIST)+accept" \ - --bind="$KEYS_OUT,$KEYS_QUIT:print($LASTVIEW)+print($LASTARG)+print($VIEW_SELECT_ARTIST)+print($ARGS)+accept" \ + --bind="$KEYS_OUT,$KEYS_QUIT:print($LASTVIEW)+print($LASTARG)+accept" \ --bind="$KEYS_LIST_ARTISTS:print($VIEW_LIST_ARTISTS)+accept" \ --bind="$KEYS_LIST_ALBUMS:print($VIEW_LIST_ALBUMS)+accept" \ --bind="$KEYS_SEARCH_ARTIST:print($VIEW_SEARCH_ARTIST)+accept" \ --bind="$KEYS_SEARCH_ALBUM:print($VIEW_SEARCH_ALBUM)+accept" \ --bind="$KEYS_BROWSE:execute-silent:open \"https://musicbrainz.org/artist/{r3}\"" \ - --bind="$KEYS_SHOW_PLAYLIST:print($VIEW_PLAYLIST)+print()+print($VIEW_SELECT_ARTIST)+print($ARGS)+accept" \ + --bind="$KEYS_SHOW_PLAYLIST:print($VIEW_PLAYLIST)+print()+accept" \ -0 -1 \ --border="bold" \ --border-label="Select artist" \ @@ -565,11 +523,16 @@ while true; do --accept-nth="{3}" \ --with-nth="{1}" || true ) - debug "$sel" - VIEW="$(echo "$sel" | head -1)" - MBID="$(echo "$sel" | head -2 | tail -1)" - LASTVIEW="$(echo "$sel" | head -3 | tail -1)" - LASTARG="$(echo "$sel" | head -4 | tail -1)" + lines=$(echo "$sel" | wc -l) + if [ "$lines" -eq 1 ]; then + VIEW="$VIEW_ARTIST" + MBID="$sel" + else + VIEW="$(echo "$sel" | head -1)" + MBID="$(echo "$sel" | head -2 | tail -1)" + fi + LASTVIEW="$VIEW_SELECT_ARTIST" + LASTARG="$ARGS" ;; "$VIEW_PLAYLIST") sel=$( diff --git a/src/sh/api.sh b/src/sh/api.sh index 33ba37d..fb00114 100644 --- a/src/sh/api.sh +++ b/src/sh/api.sh @@ -2,7 +2,6 @@ MB_MAX_RETRIES=10 MB_BROWSE_STEPS=100 USER_AGENT="$APP_NAME/$APP_VERSION ($APP_WEBSITE)" SLEEP_ON_ERROR=1 -export MB_BROWSE_STEPS __api_mb() { tmpout=$(mktemp) diff --git a/src/sh/awk.sh b/src/sh/awk.sh index 400cbac..d356136 100644 --- a/src/sh/awk.sh +++ b/src/sh/awk.sh @@ -1,27 +1,31 @@ -AWK_ARTISTS=$( - cat <<'EOF' +if [ ! "${AWK_LOADED:-}" ]; then + AWK_ARTISTS=$( + cat <<'EOF' @@include awk/artists.awk EOF -) -export AWK_ARTISTS + ) + export AWK_ARTISTS -AWK_RELEASES=$( - cat <<'EOF' + AWK_RELEASES=$( + cat <<'EOF' @@include awk/releases.awk EOF -) -export AWK_RELEASES + ) + export AWK_RELEASES -AWK_RELEASEGROUPS=$( - cat <<'EOF' + AWK_RELEASEGROUPS=$( + cat <<'EOF' @@include awk/releasegroups.awk EOF -) -export AWK_RELEASEGROUPS + ) + export AWK_RELEASEGROUPS -AWK_RECORDINGS=$( - cat <<'EOF' + AWK_RECORDINGS=$( + cat <<'EOF' @@include awk/recordings.awk EOF -) -export AWK_RECORDINGS + ) + export AWK_RECORDINGS + + export AWK_LOADED=1 +fi diff --git a/src/sh/cache.sh b/src/sh/cache.sh index f54f26b..ba5b4ee 100644 --- a/src/sh/cache.sh +++ b/src/sh/cache.sh @@ -82,7 +82,7 @@ cache_append_artist_releasegroups() { 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" + $JQ --slurpfile n "$tmpf" '."release-groups" += ($n[0]|."release-groups")' "$f" >"$updated" && mv "$updated" "$f" rm -f "$tmpf" } @@ -120,7 +120,7 @@ cache_append_releasegroup_releases() { 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" + $JQ --slurpfile n "$tmpf" '."releases" += ($n[0]|."releases")' "$f" >"$updated" && mv "$updated" "$f" rm -f "$tmpf" } diff --git a/src/sh/config.sh b/src/sh/config.sh index 16ae10c..ce387c6 100644 --- a/src/sh/config.sh +++ b/src/sh/config.sh @@ -1,3 +1,4 @@ +# Configuration capabilities CONFIGFILE_DEFAULT="$HOME/.config/$APP_NAME/config" CONFIGFILE="${CONFIGFILE:-"$CONFIGFILE_DEFAULT"}" [ "$CONFIGFILE" != "$CONFIGFILE_DEFAULT" ] && [ ! -f "$CONFIGFILE" ] && err "The configuration file manually specified with the environment variable CONFIGFILE=($CONFIGFILE) does not exist." && exit 1 diff --git a/src/sh/filter.sh b/src/sh/filter.sh index 5e2f8a9..0db8e40 100644 --- a/src/sh/filter.sh +++ b/src/sh/filter.sh @@ -1,34 +1,6 @@ -# The default queries depend on the current view, and are usually derived from -# the theme. Nevertheless, they may be overwritten with the configuration file. -# Note that filters are not used in the views VIEW_SEARCH_ARTIST and -# VIEW_SEARCH_ALBUM. The reason for this is that in those modes, changing the -# query string triggers a search on the MusicBrainz website (the input is not a -# filter, but a query). +# Preset filters # -# The keybinding KEYS_FILTER_LOCAL triggers a filter of QUERY_LOCAL in the -# views VIEW_ARTIST, VIEW_RELEASEGROUP, and VIEW_RELEASE only. Here, it is only -# possible to adjust QUERY_LOCAL via the configuration. The keybinding KEYS_FILTER_0 -# resets the query. F_1_.. filters are the default filters when the respective -# view is entered. For all other keys, the filters are individually -# configurable, by specifying e.g., F_3_VIEW_LIST_ALBUMS. -# -# Derived queries -# To derive the queries from the theme, we must perform some steps: 1) remove -# colors, and 2) escape white spaces. This is implemented in the method -# `__clean_filter`. -# -# List of derived queries: -# - QUERY_LOCAL: Hide items that are not locally available -# - q_has_secondary: Release groups with secondary types -# - q_album: Release group is of type Album -# - q_ep: Release group is of type EP -# - q_single: Release group is of type single -# - q_official: Release is official - -__clean_filter() { - cat | sed "s/${ESC}\[[0-9;]*[mK]//g" | sed "s/ /\\\ /g" -} - +# See `src/sh/query.sh` for details and the associated methods. QUERY_LOCAL="${QUERY_LOCAL:-"$(printf "'%s'" "$FORMAT_LOCAL" | __clean_filter)"}" q_has_seconary="$(printf "$FORMAT_TYPE_HAS_SECONDARY" "" | __clean_filter)" q_album="$(printf "%s" "$FORMAT_TYPE_ALBUM" | __clean_filter)" @@ -37,6 +9,7 @@ q_single=$(printf "%s" "$FORMAT_TYPE_SINGLE" | sed "s/${ESC}\[[0-9;]*[mK]//g" | if printf "$RV_FORMAT" | grep -q "<>"; then q_official=$(printf "'%s'" "$FORMAT_STATUS_OFFICIAL" | sed "s/${ESC}\[[0-9;]*[mK]//g" | sed "s/ /\\\ /g") fi +export QUERY_LOCAL F_1_VIEW_ARTIST="${F_1_VIEW_ARTIST:-"!'$q_has_seconary'"}" F_2_VIEW_ARTIST="${F_2_VIEW_ARTIST:-"'$q_album'"}" @@ -47,6 +20,9 @@ F_6_VIEW_ARTIST="${F_6_VIEW_ARTIST:-}" F_7_VIEW_ARTIST="${F_7_VIEW_ARTIST:-}" F_8_VIEW_ARTIST="${F_8_VIEW_ARTIST:-}" F_9_VIEW_ARTIST="${F_9_VIEW_ARTIST:-}" +export F_1_VIEW_ARTIST F_2_VIEW_ARTIST F_3_VIEW_ARTIST F_4_VIEW_ARTIST \ + F_5_VIEW_ARTIST F_6_VIEW_ARTIST F_7_VIEW_ARTIST F_8_VIEW_ARTIST \ + F_9_VIEW_ARTIST F_1_VIEW_RELEASEGROUP="${F_1_VIEW_RELEASEGROUP:-"${q_official:-}"}" F_2_VIEW_RELEASEGROUP="${F_2_VIEW_RELEASEGROUP:-}" @@ -57,6 +33,9 @@ F_6_VIEW_RELEASEGROUP="${F_6_VIEW_RELEASEGROUP:-}" F_7_VIEW_RELEASEGROUP="${F_7_VIEW_RELEASEGROUP:-}" F_8_VIEW_RELEASEGROUP="${F_8_VIEW_RELEASEGROUP:-}" F_9_VIEW_RELEASEGROUP="${F_9_VIEW_RELEASEGROUP:-}" +export F_1_VIEW_RELEASEGROUP F_2_VIEW_RELEASEGROUP F_3_VIEW_RELEASEGROUP \ + F_4_VIEW_RELEASEGROUP F_5_VIEW_RELEASEGROUP F_6_VIEW_RELEASEGROUP \ + F_7_VIEW_RELEASEGROUP F_8_VIEW_RELEASEGROUP F_9_VIEW_RELEASEGROUP F_1_VIEW_RELEASE="${F_1_VIEW_RELEASE:-}" F_2_VIEW_RELEASE="${F_2_VIEW_RELEASE:-}" @@ -67,6 +46,9 @@ F_6_VIEW_RELEASE="${F_6_VIEW_RELEASE:-}" F_7_VIEW_RELEASE="${F_7_VIEW_RELEASE:-}" F_8_VIEW_RELEASE="${F_8_VIEW_RELEASE:-}" F_9_VIEW_RELEASE="${F_9_VIEW_RELEASE:-}" +export F_1_VIEW_RELEASE F_2_VIEW_RELEASE F_3_VIEW_RELEASE F_4_VIEW_RELEASE \ + F_5_VIEW_RELEASE F_6_VIEW_RELEASE F_7_VIEW_RELEASE F_8_VIEW_RELEASE \ + F_9_VIEW_RELEASE F_1_LIST_ARTISTS="${F_1_LIST_ARTISTS:-}" F_2_LIST_ARTISTS="${F_2_LIST_ARTISTS:-}" @@ -77,6 +59,9 @@ F_6_LIST_ARTISTS="${F_6_LIST_ARTISTS:-}" F_7_LIST_ARTISTS="${F_7_LIST_ARTISTS:-}" F_8_LIST_ARTISTS="${F_8_LIST_ARTISTS:-}" F_9_LIST_ARTISTS="${F_9_LIST_ARTISTS:-}" +export F_1_LIST_ARTISTS F_2_LIST_ARTISTS F_3_LIST_ARTISTS F_4_LIST_ARTISTS \ + F_5_LIST_ARTISTS F_6_LIST_ARTISTS F_7_LIST_ARTISTS F_8_LIST_ARTISTS \ + F_9_LIST_ARTISTS F_1_LIST_ALBUMS="${F_1_LIST_ALBUMS:-}" F_2_LIST_ALBUMS="${F_2_LIST_ALBUMS:-}" @@ -87,128 +72,6 @@ F_6_LIST_ALBUMS="${F_6_LIST_ALBUMS:-}" F_7_LIST_ALBUMS="${F_7_LIST_ALBUMS:-}" F_8_LIST_ALBUMS="${F_8_LIST_ALBUMS:-}" F_9_LIST_ALBUMS="${F_9_LIST_ALBUMS:-}" - -# Determine preset query -# @argument $1: Current view -# @argument $2: Key pressed (optional) -# -# If the key is not given, then the F_1_.. query is used for the respective -# view, i.e, its as if a key from KEYS_FILTER_1 has been pressed. -default_query() { - view=$1 - key="${2:-"$(echo "$KEYS_FILTER_1" | cut -d ',' -f 1)"}" - case ",$KEYS_FILTER_LOCAL," in - *",$key,"*) - case "$view" in - "$VIEW_ARTIST" | "$VIEW_RELEASEGROUP" | "$VIEW_RELEASE") echo "$QUERY_LOCAL" ;; - esac - ;; - esac - case ",$KEYS_FILTER_1," in - *",$key,"*) - case "$view" in - "$VIEW_ARTIST") echo "$F_1_VIEW_ARTIST" ;; - "$VIEW_RELEASEGROUP") echo "$F_1_VIEW_RELEASEGROUP" ;; - "$VIEW_RELEASE") echo "$F_1_VIEW_RELEASE" ;; - "$VIEW_LIST_ARTISTS") echo "$F_1_LIST_ARTISTS" ;; - "$VIEW_LIST_ALBUMS") echo "$F_1_LIST_ALBUMS" ;; - esac - ;; - esac - case ",$KEYS_FILTER_2," in - *",$key,"*) - case "$view" in - "$VIEW_ARTIST") echo "$F_2_VIEW_ARTIST" ;; - "$VIEW_RELEASEGROUP") echo "$F_2_VIEW_RELEASEGROUP" ;; - "$VIEW_RELEASE") echo "$F_2_VIEW_RELEASE" ;; - "$VIEW_LIST_ARTISTS") echo "$F_2_LIST_ARTISTS" ;; - "$VIEW_LIST_ALBUMS") echo "$F_2_LIST_ALBUMS" ;; - esac - ;; - esac - case ",$KEYS_FILTER_3," in - *",$key,"*) - case "$view" in - "$VIEW_ARTIST") echo "$F_3_VIEW_ARTIST" ;; - "$VIEW_RELEASEGROUP") echo "$F_3_VIEW_RELEASEGROUP" ;; - "$VIEW_RELEASE") echo "$F_3_VIEW_RELEASE" ;; - "$VIEW_LIST_ARTISTS") echo "$F_3_LIST_ARTISTS" ;; - "$VIEW_LIST_ALBUMS") echo "$F_3_LIST_ALBUMS" ;; - esac - ;; - esac - case ",$KEYS_FILTER_4," in - *",$key,"*) - case "$view" in - "$VIEW_ARTIST") echo "$F_4_VIEW_ARTIST" ;; - "$VIEW_RELEASEGROUP") echo "$F_4_VIEW_RELEASEGROUP" ;; - "$VIEW_RELEASE") echo "$F_4_VIEW_RELEASE" ;; - "$VIEW_LIST_ARTISTS") echo "$F_4_LIST_ARTISTS" ;; - "$VIEW_LIST_ALBUMS") echo "$F_4_LIST_ALBUMS" ;; - esac - ;; - esac - case ",$KEYS_FILTER_5," in - *",$key,"*) - case "$view" in - "$VIEW_ARTIST") echo "$F_5_VIEW_ARTIST" ;; - "$VIEW_RELEASEGROUP") echo "$F_5_VIEW_RELEASEGROUP" ;; - "$VIEW_RELEASE") echo "$F_5_VIEW_RELEASE" ;; - "$VIEW_LIST_ARTISTS") echo "$F_5_LIST_ARTISTS" ;; - "$VIEW_LIST_ALBUMS") echo "$F_5_LIST_ALBUMS" ;; - esac - ;; - esac - case ",$KEYS_FILTER_6," in - *",$key,"*) - case "$view" in - "$VIEW_ARTIST") echo "$F_6_VIEW_ARTIST" ;; - "$VIEW_RELEASEGROUP") echo "$F_6_VIEW_RELEASEGROUP" ;; - "$VIEW_RELEASE") echo "$F_6_VIEW_RELEASE" ;; - "$VIEW_LIST_ARTISTS") echo "$F_6_LIST_ARTISTS" ;; - "$VIEW_LIST_ALBUMS") echo "$F_6_LIST_ALBUMS" ;; - esac - ;; - esac - case ",$KEYS_FILTER_7," in - *",$key,"*) - case "$view" in - "$VIEW_ARTIST") echo "$F_7_VIEW_ARTIST" ;; - "$VIEW_RELEASEGROUP") echo "$F_7_VIEW_RELEASEGROUP" ;; - "$VIEW_RELEASE") echo "$F_7_VIEW_RELEASE" ;; - "$VIEW_LIST_ARTISTS") echo "$F_7_LIST_ARTISTS" ;; - "$VIEW_LIST_ALBUMS") echo "$F_7_LIST_ALBUMS" ;; - esac - ;; - esac - case ",$KEYS_FILTER_8," in - *",$key,"*) - case "$view" in - "$VIEW_ARTIST") echo "$F_8_VIEW_ARTIST" ;; - "$VIEW_RELEASEGROUP") echo "$F_8_VIEW_RELEASEGROUP" ;; - "$VIEW_RELEASE") echo "$F_8_VIEW_RELEASE" ;; - "$VIEW_LIST_ARTISTS") echo "$F_8_LIST_ARTISTS" ;; - "$VIEW_LIST_ALBUMS") echo "$F_8_LIST_ALBUMS" ;; - esac - ;; - esac - case ",$KEYS_FILTER_9," in - *",$key,"*) - case "$view" in - "$VIEW_ARTIST") echo "$F_9_VIEW_ARTIST" ;; - "$VIEW_RELEASEGROUP") echo "$F_9_VIEW_RELEASEGROUP" ;; - "$VIEW_RELEASE") echo "$F_9_VIEW_RELEASE" ;; - "$VIEW_LIST_ARTISTS") echo "$F_9_LIST_ARTISTS" ;; - "$VIEW_LIST_ALBUMS") echo "$F_9_LIST_ALBUMS" ;; - esac - ;; - esac - # Doing nothing is the same as this last block: - # case ",$KEYS_FILTER_0," in - # *",$key,"*) - # case "$view" in - # "$VIEW_ARTIST" | "$VIEW_RELEASEGROUP" | "$VIEW_RELEASE" | "$VIEW_LIST_ARTISTS" | "$VIEW_LIST_ALBUMS") echo "" ;; - # esac - # ;; - # esac -} +export F_1_LIST_ALBUMS F_2_LIST_ALBUMS F_3_LIST_ALBUMS F_4_LIST_ALBUMS \ + F_5_LIST_ALBUMS F_6_LIST_ALBUMS F_7_LIST_ALBUMS F_8_LIST_ALBUMS \ + F_9_LIST_ALBUMS diff --git a/src/sh/fzf.sh b/src/sh/fzf.sh index 78446b0..32525fc 100644 --- a/src/sh/fzf.sh +++ b/src/sh/fzf.sh @@ -10,75 +10,27 @@ fzf_command_set_header() { "$VIEW_LIST_ARTISTS") header="Search locally available artist" ;; "$VIEW_LIST_ALBUMS") header="Search locally available album" ;; "$VIEW_ARTIST") - name="$(mb_artist "$mbid" | $JQ -r '.name')" + name="$(mb_artist "$mbid" | $JQ '.name')" header=$(printf "$ARTIST_PROMPT" "$name") ;; "$VIEW_RELEASEGROUP") title="$(mb_releasegroup "$mbid" | - $JQ -r '.title')" + $JQ '.title')" artist="$(mb_releasegroup "$mbid" | - $JQ -r '."artist-credit" | map(([.name, .joinphrase]|join(""))) | join("")')" + $JQ '."artist-credit" | map(([.name, .joinphrase]|join(""))) | join("")')" header=$(printf "$FULL_PROMPT" "$artist" "$title") ;; "$VIEW_RELEASE") title="$(mb_release "$mbid" | - $JQ -r '.title')" + $JQ '.title')" artist="$(mb_release "$mbid" | - $JQ -r '."artist-credit" | map(([.name, .joinphrase]|join(""))) | join("")')" + $JQ '."artist-credit" | map(([.name, .joinphrase]|join(""))) | join("")')" header=$(printf "$FULL_PROMPT" "$artist" "$title") ;; esac printf "+change-header(%s)" "${header:-"???"}" } -# Print the command that tells fzf to load the data -# @argument $1: view -# @argument $2: mbid -fzf_command_load_data() { - view=$1 - mbid=${2:-} - case "$view" in - "$VIEW_SEARCH_ARTIST") ;; - "$VIEW_SEARCH_ALBUM") ;; - "$VIEW_LIST_ARTISTS") ;; - "$VIEW_LIST_ALBUMS") ;; - "$VIEW_ARTIST") ;; - "$VIEW_RELEASEGROUP") ;; - "$VIEW_RELEASE") ;; - esac - printf "+reload($0 --lines %s %s)" "$VIEW_LIST_ARTISTS" "" -} - -# Set prompt of input field -# @argument $1: view -# @argument $2: mode -__set_prompt() { - view=$1 - mode=$2 - case "$view" in - "$VIEW_ARTIST") - name="$(mb_artist "$args" | $JQ -r '.name')" - PROMPT=$(printf "$ARTIST_PROMPT" "$name") - ;; - "$VIEW_RELEASEGROUP") - title="$(mb_releasegroup "$args" | - $JQ -r '.title')" - artist="$(mb_releasegroup "$args" | - $JQ -r '."artist-credit" | map(([.name, .joinphrase]|join(""))) | join("")')" - PROMPT=$(printf "$FULL_PROMPT" "$artist" "$title") - ;; - "$VIEW_RELEASE") - title="$(mb_release "$args" | - $JQ -r '.title')" - artist="$(mb_release "$args" | - $JQ -r '."artist-credit" | map(([.name, .joinphrase]|join(""))) | join("")')" - PROMPT=$(printf "$FULL_PROMPT" "$artist" "$title") - ;; - esac - [ "$mode" = "$MODE_INSERT" ] && PT="$PROMPT_INSERT" || PT="$PROMPT_NORMAL" - printf "+change-header(%s %s)" "$PT" "${PROMPT:-"$SEARCH_PROMPT"}" -} - # Reload hook that is used after change in query fzf_reload_after_change() { # Wait for async. process to terminate @@ -108,7 +60,7 @@ fzf_handle_change() { sleep 1 if [ "$view" = "$VIEW_SEARCH_ARTIST" ]; then api_mb_search_artist "$FZF_QUERY" | - $JQ -r '.artists[] | [ + $JQ '.artists[] | [ .id, .type, .name, @@ -127,7 +79,7 @@ fzf_handle_change() { true else api_mb_search_releasegroup "$FZF_QUERY" | - $JQ -r '."release-groups"[] | [ + $JQ '."release-groups"[] | [ .id, ."primary-type", (."secondary-types" // []|join(";")), diff --git a/src/sh/helper.sh b/src/sh/helper.sh deleted file mode 100644 index 3aa9961..0000000 --- a/src/sh/helper.sh +++ /dev/null @@ -1,19 +0,0 @@ -ERR="\033[38;5;196m" -INFO="\033[38;5;75m" -DBG=$ERR -OFF="\033[m" -LOGDIR="$HOME/.local/state/$APP_NAME" -[ -d "$LOGDIR" ] || mkdir -p "$LOGDIR" -LOGFILE="$LOGDIR/log" - -err() { - echo "${ERR}ERROR:${OFF} ${1:-}" >/dev/stderr -} - -info() { - echo "${INFO}Info:${OFF} ${1:-}" >/dev/stderr -} - -debug() { - echo "${DBG}DEBUG${OFF} ${INFO} [$$] $(date)${OFF}: $*" >>"$LOGFILE" -} diff --git a/src/sh/info.sh b/src/sh/info.sh index f008979..4501650 100644 --- a/src/sh/info.sh +++ b/src/sh/info.sh @@ -1,5 +1,5 @@ +# Application information APP_NAME="muf" APP_VERSION="zero.zero" APP_WEBSITE="https://git.indyfac.ch/amin/muf" WINDOW_TITLE="๐Ÿ”Ž๐ŸŽถ $APP_NAME | a simple music finder and player" -export APP_NAME APP_VERSION APP_WEBSITE WINDOW_TITLE diff --git a/src/sh/keys.sh b/src/sh/keys.sh index 6d6d132..f5f7bb9 100644 --- a/src/sh/keys.sh +++ b/src/sh/keys.sh @@ -81,6 +81,7 @@ # Mode selection: KEYS_I_NORMAL="${KEYS_I_NORMAL:-"esc"}" KEYS_N_INSERT="${KEYS_N_INSERT:-"a,i,/,?"}" +export KEYS_I_NORMAL KEYS_N_INSERT # Vertical navigation: KEYS_DOWN="${KEYS_DOWN:-"ctrl-j,down"}" @@ -91,6 +92,8 @@ KEYS_N_DOWN="${KEYS_N_DOWN:-"j"}" KEYS_N_UP="${KEYS_N_UP:-"k"}" KEYS_N_BOT="${KEYS_N_BOT:-"G"}" KEYS_N_TOP="${KEYS_N_TOP:-"1"}" +export KEYS_DOWN KEYS_UP KEYS_HALFPAGE_DOWN KEYS_HALFPAGE_UP KEYS_N_DOWN \ + KEYS_N_UP KEYS_N_BOT KEYS_N_TOP # Horizontal navigation: KEYS_IN="${KEYS_IN:-"ctrl-l"}" @@ -104,6 +107,9 @@ KEYS_SEARCH_ARTIST="${KEYS_SEARCH_ARTIST:-"alt-z"}" KEYS_SEARCH_ALBUM="${KEYS_SEARCH_ALBUM:-"alt-x"}" KEYS_SWITCH_ARTIST_ALBUM="${KEYS_SWITCH_ARTIST_ALBUM:-"tab"}" KEYS_SWITCH_LOCAL_REMOTE="${KEYS_SWITCH_LOCAL_REMOTE:-"ctrl-/"}" +export KEYS_IN KEYS_OUT KEYS_N_IN KEYS_N_OUT KEYS_SELECT_ARTIST \ + KEYS_LIST_ARTISTS KEYS_SELECT_ARTIST KEYS_SEARCH_ALBUM \ + KEYS_SWITCH_ARTIST_ALBUM KEYS_SWITCH_LOCAL_REMOTE # Filtering: KEYS_FILTER_LOCAL="${KEYS_FILTER_LOCAL:-"alt-l"}" @@ -118,13 +124,17 @@ KEYS_FILTER_8="${KEYS_FILTER_8:-"alt-8"}" KEYS_FILTER_9="${KEYS_FILTER_9:-"alt-9"}" KEYS_FILTER_0="${KEYS_FILTER_0:-"alt-0"}" KEYS_FILTER="$KEYS_FILTER_LOCAL,$KEYS_FILTER_1,$KEYS_FILTER_2,$KEYS_FILTER_3,$KEYS_FILTER_4,$KEYS_FILTER_5,$KEYS_FILTER_6,$KEYS_FILTER_7,$KEYS_FILTER_8,$KEYS_FILTER_9,$KEYS_FILTER_0" +export KEYS_FILTER_LOCAL KEYS_FILTER_1 KEYS_FILTER_2 KEYS_FILTER_3 \ + KEYS_FILTER_4 KEYS_FILTER_5 KEYS_FILTER_6 KEYS_FILTER_7 KEYS_FILTER_8 \ + KEYS_FILTER_9 KEYS_FILTER_0 KEYS_FILTER # Specials: KEYS_BROWSE="${KEYS_BROWSE:-"alt-b"}" KEYS_OPEN="${KEYS_OPEN:-"alt-o"}" KEYS_SHOW_PLAYLIST="${KEYS_SHOW_PLAYLIST:-"ctrl-p"}" -KEYS_QUIT="${KEYS_QUIT:-"ctrl-c,esc"}" +KEYS_QUIT="${KEYS_QUIT:-"ctrl-c"}" KEYS_N_QUIT="${KEYS_N_QUIT:-"q"}" +export KEYS_BROWSE KEYS_OPEN KEYS_SHOW_PLAYLIST KEYS_QUIT KEYS_N_QUIT # Playback: KEYS_PLAY="${KEYS_PLAY:-"enter"}" @@ -145,6 +155,11 @@ KEYS_N_PLAY_PREV="${KEYS_N_PLAY_PREV:-"left,p"}" KEYS_N_SEEK_FORWARD="${KEYS_N_SEEK_FORWARD:-"N,f"}" KEYS_N_SEEK_BACKWARD="${KEYS_N_SEEK_BACKWARD:-"P,b"}" KEYS_N_PLAYBACK="$KEYS_N_PLAY,$KEYS_N_QUEUE,$KEYS_N_QUEUE_NEXT,$KEYS_N_TOGGLE_PLAYBACK,$KEYS_N_PLAY_NEXT,$KEYS_N_PLAY_PREV,$KEYS_N_SEEK_FORWARD,$KEYS_N_SEEK_BACKWARD" +export KEYS_PLAY KEYS_QUEUE KEYS_QUEUE_NEXT KEYS_TOGGLE_PLAYBACK \ + KEYS_PLAY_NEXT KEYS_PLAY_PREV KEYS_SEEK_FORWARD KEYS_SEEK_BACKWARD \ + KEYS_PLAYBACK KEYS_N_PLAY KEYS_N_QUEUE KEYS_N_QUEUE_NEXT \ + KEYS_N_TOGGLE_PLAYBACK KEYS_N_PLAY_NEXT KEYS_N_PLAY_PREV \ + KEYS_N_SEEK_FORWARD KEYS_N_SEEK_BACKWARD KEYS_N_PLAYBACK # Playlist (in the playlist, there is no `insert` mode): KEYS_PLAYLIST_RELOAD="${KEYS_PLAYLIST_RELOAD:-"r,ctrl-r"}" @@ -157,39 +172,7 @@ KEYS_PLAYLIST_CLEAR_BELOW="${KEYS_PLAYLIST_CLEAR_BELOW:-"D"}" KEYS_PLAYLIST_GOTO_RELEASE="${KEYS_PLAYLIST_GOTO_RELEASE:-"ctrl-g"}" KEYS_PLAYLIST_STORE="${KEYS_PLAYLIST_STORE:-"ctrl-s"}" KEYS_PLAYLIST_LOAD="${KEYS_PLAYLIST_LOAD:-"ctrl-o"}" - -## Not yet characterized -########################## - -KEYS_INPUT_SINGLE='0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,!,",#,$,%,&,\,(,),*,+,,,-,.,/,:,;,<,=,>,?,@,[,\,\,],^,_,`,{,|,},~' -KEYS_INPUT_SINGLE="$KEYS_INPUT_SINGLE,'" -KEYS_INPUT_SPECIAL="space,backspace,delete,left,right" -export KEYS_INPUT_SINGLE KEYS_INPUT_SPECIAL - -# Normal and insert mode -KEYS_NI="$KEYS_HALFPAGE_DOWN,$KEYS_HALFPAGE_UP,$KEYS_BROWSE,$KEYS_OPEN,$KEYS_OUT,$KEYS_IN,$KEYS_SELECT_ARTIST,$KEYS_FILTER_LOCAL,$KEYS_FILTER_1,$KEYS_FILTER_2,$KEYS_FILTER_3,$KEYS_FILTER_4,$KEYS_SWITCH_ARTIST_ALBUM,$KEYS_SWITCH_LOCAL_REMOTE,$KEYS_PLAY,$KEYS_QUEUE,$KEYS_SHOW_PLAYLIST" -export KEYS_NI - -# Keys in normal mode only -KEYS_N="$KEYS_N_DOWN,$KEYS_N_UP,$KEYS_N_OUT,$KEYS_N_IN,$KEYS_N_TOP,$KEYS_N_BOT,$KEYS_N_QUIT,$KEYS_N_INSERT,$KEYS_N_TOGGLE_PLAYBACK,$KEYS_N_PLAY_NEXT,$KEYS_N_PLAY_PREV,$KEYS_N_SEEK_FORWARD,$KEYS_N_SEEK_BACKWARD" -export KEYS_N - -# Keys in insert mode only -KEYS_I="$KEYS_I_NORMAL" -export KEYS_I - -# Special playlist keys -KEYS_PLAYLIST="$KEYS_PLAYLIST_RELOAD" -export KEYS_PLAYLIST - -# Grouping -KEYS_ALL="$KEYS_NI,$KEYS_N,$KEYS_I,$KEYS_INPUT_SINGLE,$KEYS_INPUT_SPECIAL,$KEYS_PLAYLIST" - -export KEYS_HALFPAGE_DOWN KEYS_HALFPAGE_UP KEYS_OPEN KEYS_BROWSE KEYS_OUT KEYS_IN \ - KEYS_SELECT_ARTIST KEYS_FILTER_LOCAL KEYS_FILTER_1 KEYS_FILTER_2 KEYS_FILETER_3 KEYS_FILTER_4 \ - KEYS_SWITCH_ARTIST_ALBUM KEYS_SWITCH_LOCAL_REMOTE KEYS_PLAY KEYS_QUEUE \ - KEYS_N_DOWN KEYS_N_UP KEYS_N_OUT KEYS_N_IN KEYS_N_TOP KEYS_N_BOT KEYS_N_QUIT KEYS_N_INSERT \ - KEYS_N_TOGGLE_PLAYBACK KEYS_N_PLAY_NEXT KEYS_N_PLAY_PREV KEYS_N_SEEK_FORWARD \ - KEYS_N_SEEK_BACKWARD KEYS_SHOW_PLAYLIST \ - KEYS_I_NORMAL \ - KEYS_GROUP_NI KEYS_GROUP_N KEYS_GROUP_I KEYS PLAYLIST KEYS_ALL +export KEYS_PLAYLIST_RELOAD KEYS_PLAYLIST_REMOVE KEYS_PLAYLIST_UP \ + KEYS_PLAYLIST_DOWN KEYS_PLAYLIST_CLEAR KEYS_PLAYLIST_CLEAR_ABOVE \ + KEYS_PLAYLIST_CLEAR_BELOW KEYS_PLAYLIST_GOTO_RELEASE KEYS_PLAYLIST_STORE \ + KEYS_PLAYLIST_LOAD diff --git a/src/sh/lists.sh b/src/sh/lists.sh index e974fa6..c94936d 100644 --- a/src/sh/lists.sh +++ b/src/sh/lists.sh @@ -1,9 +1,9 @@ # List release groups of given artist # argument $1: MB artist id list_releasegroups() { - name=$(mb_artist "$1" | $JQ -r '.name') + name=$(mb_artist "$1" | $JQ '.name') mb_artist_releasegroups "$1" | - $JQ -r '."release-groups"[] | [ + $JQ '."release-groups"[] | [ .id, ."primary-type", (."secondary-types" // []|join(";")), @@ -50,11 +50,11 @@ list_releasegroups() { # argument $1: MB release-group id list_releases() { title="$(mb_releasegroup "$1" | - $JQ -r '.title')" + $JQ '.title')" artist="$(mb_releasegroup "$1" | - $JQ -r '."artist-credit" | map(([.name, .joinphrase]|join(""))) | join("")')" + $JQ '."artist-credit" | map(([.name, .joinphrase]|join(""))) | join("")')" mb_releasegroup_releases "$1" | - $JQ -r '."releases"[] | [ + $JQ '."releases"[] | [ .id, .status, .date, @@ -97,10 +97,10 @@ list_recordings() { deco="$(grep "$1" "$LOCALDATA_RELEASES" | cut -d "$(printf '\t')" -f 2)" if [ "$deco" ]; then rectmp=$(mktemp) - $JQ -r '.tracks | keys | join("\n")' "$deco" >"$rectmp" + $JQ '.tracks | keys | join("\n")' "$deco" >"$rectmp" fi mb_release "$1" | - $JQ -r \ + $JQ \ --arg rid "$1" \ --arg deco "$deco" \ '.media[] | @@ -146,51 +146,10 @@ list_local_releases() { cat "$LOCALDATA_RELEASES_VIEW" 2>/dev/null } -# Generate playlist from MB release ID and path to decoration -# @argument $1: MusicBrainz Release ID -# @argument $2: Path to decoration file -# @argument $3: MusicBrainz Track ID to select (optional) -generate_playlist() { - printf "#EXTM3U\n" - dir="$(dirname "$2")" - mb_release "$1" | - $JQ -r \ - --slurpfile decofile "$2" \ - --arg base "$dir" \ - --arg deco "$2" \ - --arg tid "${3:-}" \ - '$decofile[].tracks as $filenames | - . | - .id as $rid | - .media[] | - .position as $pos | - .tracks | - if ($tid == "") then . else map(select(.id == $tid)) end | - map({ - t: [ - $rid, - .id, - $pos, - .number, - .length, - .title, - (."artist-credit" | map([.name, .joinphrase] | join("")) | join("")), - $deco - ] | join("\t"), - length: (.length / 1000 | round | tostring), - $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("#EXTINF:" + .length + "," + .t + "\n" + $base + "/" + .file)[]' -} - # Generate artist list from JSON list_artists_from_json() { cat | - $JQ -r 'map([.artist.id, .artist.type, .name] | join("\t")) | join("\n")' | + $JQ 'map([.artist.id, .artist.type, .name] | join("\t")) | join("\n")' | awk \ -F "\t" \ -v file_local_artists="${LOCALDATA_ARTISTS:-}" \ diff --git a/src/sh/local.sh b/src/sh/local.sh index bd64c77..81a6fbd 100644 --- a/src/sh/local.sh +++ b/src/sh/local.sh @@ -1,6 +1,6 @@ gettags() { ffprobe -v error -show_entries format_tags -print_format json "$1" | - $JQ -r --compact-output '.format.tags | { + $JQ '.format.tags | { trackid: (."MusicBrainz Release Track Id" // ."MUSICBRAINZ_RELEASETRACKID" // ."MusicBrainz/Release Track Id" // ""), releaseid: (."MusicBrainz Album Id" // ."MUSICBRAINZ_ALBUMID" // ."MusicBrainz/Album Id" // "") }' @@ -19,8 +19,8 @@ decorate() { (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') + rid=$(echo "$mbid" | $JQ '.releaseid') + tid=$(echo "$mbid" | $JQ '.trackid') if [ ! "$rid" ] || [ ! "$tid" ]; then err "File $f: Seems not tagged" releaseid="" @@ -40,7 +40,7 @@ decorate() { done <"$tmpf" rm -f "$tmpf" if [ "$releaseid" ]; then - echo "$decoration" | $JQ --compact-output ".releaseid = \"$releaseid\"" >"$1/$DECORATION_FILENAME" + echo "$decoration" | $JQ ".releaseid = \"$releaseid\"" >"$1/$DECORATION_FILENAME" else return 1 fi @@ -75,13 +75,13 @@ __batch_load_missing() { while IFS= read -r mbid; do case "$1" in "$TYPE_ARTIST") - name=$(mb_artist "$mbid" | $JQ -r ".name") + name=$(mb_artist "$mbid" | $JQ ".name") ;; "$TYPE_RELEASEGROUP") - name=$(mb_releasegroup "$mbid" | $JQ -r ".title") + name=$(mb_releasegroup "$mbid" | $JQ ".title") ;; "$TYPE_RELEASE") - name=$(mb_release "$mbid" | $JQ -r ".title") + name=$(mb_release "$mbid" | $JQ ".title") ;; esac cnt=$((cnt + 1)) @@ -107,7 +107,7 @@ DECORATION_FILENAME=${DECORATION_FILENAME:-"mbid.json"} precompute_view() { info "Precomputing artist view" while IFS= read -r aid; do - mb_artist "$aid" | $JQ -r '[ + mb_artist "$aid" | $JQ '[ .id, .type, .name, @@ -129,7 +129,7 @@ precompute_view() { sed 's| \+\([0-9a-f-]\+\) \+\([0-9a-f-]\+\)$|\t\1\t\2|' >"$LOCALDATA_ARTISTS_VIEW" info "Precomputing releasegroup view" while IFS= read -r rgid; do - mb_releasegroup "$rgid" | $JQ -r '[ + mb_releasegroup "$rgid" | $JQ '[ .id, ."primary-type", (."secondary-types" // []|join(";")), @@ -172,7 +172,7 @@ precompute_view() { info "Precomputing release view" cut -d "$(printf '\t')" -f 1 "$LOCALDATA_RELEASES" | while IFS= read -r rid; do - mb_release "$rid" | $JQ -r '[ + mb_release "$rid" | $JQ '[ .id, .status, .date, @@ -215,15 +215,15 @@ load_local() { [ -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' | + xargs -0 -P 4 $JQ '.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" + echo "$mb" | $JQ '."release-group".id' >>"$LOCALDATA_RELEASEGROUPS" + echo "$mb" | $JQ '."release-group"."artist-credit" | map(.artist.id) | join("\n")' >>"$LOCALDATA_ARTISTS" done <"$tmpreleases" tf=$(mktemp) sort "$LOCALDATA_RELEASEGROUPS" | uniq >"$tf" && mv "$tf" "$LOCALDATA_RELEASEGROUPS" diff --git a/src/sh/log.sh b/src/sh/log.sh new file mode 100644 index 0000000..7334daf --- /dev/null +++ b/src/sh/log.sh @@ -0,0 +1,15 @@ +# Logging methods +ERR="\033[38;5;196m" +INFO="\033[38;5;75m" +OFF="\033[m" +LOGDIR="$HOME/.local/state/$APP_NAME" +[ -d "$LOGDIR" ] || mkdir -p "$LOGDIR" +LOGFILE="$LOGDIR/log" + +err() { + echo "$(date) [$$]>${ERR}ERROR:${OFF} ${1:-}" | tee -a "$LOGFILE" | cut -d ">" -f 2- >/dev/stderr +} + +info() { + echo "$(date) [$$]>${INFO}Info:${OFF} ${1:-}" | tee -a "$LOGFILE" | cut -d ">" -f 2- >/dev/stderr +} diff --git a/src/sh/mb.sh b/src/sh/mb.sh index f7688fa..4fa8c2e 100644 --- a/src/sh/mb.sh +++ b/src/sh/mb.sh @@ -27,7 +27,7 @@ __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"') + total=$(printf "%s" "$rg" | $JQ '."release-group-count"') seen=$MB_BROWSE_STEPS while [ "$total" -gt "$seen" ]; do # Fetch remaning release groups, and append to cache @@ -43,7 +43,7 @@ __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"') + total=$(printf "%s" "$releases" | $JQ '."release-count"') seen=$MB_BROWSE_STEPS while [ "$total" -gt "$seen" ]; do # Fetch remaning releases, and append to cache @@ -66,7 +66,7 @@ mb_artist() { mb_artist_wikidata() { if ! cache_get_artist_wikidata "$1"; then wikidataid=$(mb_artist "$1" | - $JQ -r '.relations | + $JQ '.relations | map(select(.type=="wikidata")) | .[0].url.resource // ""' | awk -F "/" '{print $NF}') @@ -89,7 +89,7 @@ mb_artist_enwikipedia() { # take the second route. wikidata=$(mb_artist_wikidata "$1" || true) wikiid=$(printf "%s" "$wikidata" | - $JQ -r '.enwiki.url // ""' | + $JQ '.enwiki.url // ""' | awk -F "/" '{print $NF}') [ ! "$wikiid" ] && return api_wikipedia_en_summary "$wikiid" | cache_put_artist_enwikipedia "$1" @@ -102,7 +102,7 @@ mb_artist_enwikipedia() { mb_artist_discogs() { if ! cache_get_artist_discogs "$1"; then discogsid=$(mb_artist "$1" | - $JQ -r '.relations | + $JQ '.relations | map(select(.type=="discogs")) | .[0].url.resource // ""' | awk -F "/" '{print $NF}') diff --git a/src/sh/mpv.sh b/src/sh/mpv.sh index aa4a04a..4fac3fc 100644 --- a/src/sh/mpv.sh +++ b/src/sh/mpv.sh @@ -11,7 +11,7 @@ __mpv_command_with_args2() { } __mpv_get() { - __mpv_command_with_arg "expand-text" "$1" | $JQ -r '.data' + __mpv_command_with_arg "expand-text" "$1" | $JQ '.data' } mpv_playlist_count() { diff --git a/src/sh/playback.sh b/src/sh/playback.sh index 802bdba..23657b0 100644 --- a/src/sh/playback.sh +++ b/src/sh/playback.sh @@ -1,3 +1,8 @@ +# Playback tools and helper +# +# The methods to control the mpv instance are in `src/sh/mpv.sh`. Here, +# a higher-level playback functionality is provided. + # Available playback commands PLAYBACK_CMD_PLAY="play" PLAYBACK_CMD_QUEUE="queue" @@ -10,7 +15,7 @@ PLAYBACK_CMD_SEEK_BACKWARD="seekb" # Obtain playback command from key press # @argument $1: key -playback_cmd_from_key() { +__playback_cmd_from_key() { key=$1 case ",$KEYS_PLAY," in *",$key,"*) echo "$PLAYBACK_CMD_PLAY" && return ;; esac case ",$KEYS_N_PLAY," in *",$key,"*) echo "$PLAYBACK_CMD_PLAY" && return ;; esac @@ -29,3 +34,97 @@ playback_cmd_from_key() { case ",$KEYS_SEEK_BACKWARD," in *",$key,"*) echo "$PLAYBACK_CMD_SEEK_BACKWARD" && return ;; esac case ",$KEYS_N_SEEK_BACKWARD," in *",$key,"*) echo "$PLAYBACK_CMD_SEEK_BACKWARD" && return ;; esac } + +# Generate playlist from MB release ID and path to decoration +# @argument $1: MusicBrainz Release ID +# @argument $2: Path to decoration file +# @argument $3: MusicBrainz Track ID to select (optional) +__generate_playlist() { + printf "#EXTM3U\n" + dir="$(dirname "$2")" + mb_release "$1" | + $JQ \ + --slurpfile decofile "$2" \ + --arg base "$dir" \ + --arg deco "$2" \ + --arg tid "${3:-}" \ + '$decofile[].tracks as $filenames | + . | + .id as $rid | + .media[] | + .position as $pos | + .tracks | + if ($tid == "") then . else map(select(.id == $tid)) end | + map({ + t: [ + $rid, + .id, + $pos, + .number, + .length, + .title, + (."artist-credit" | map([.name, .joinphrase] | join("")) | join("")), + $deco + ] | join("\t"), + length: (.length / 1000 | round | tostring), + $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("#EXTINF:" + .length + "," + .t + "\n" + $base + "/" + .file)[]' +} + +# Main playback method +# +# @argument $1: view +# @argument $2: MusicBrainz ID of current object +# @argument $3: MusicBrainz ID of selected object +# @argument $4: Path to decoration file +# +# This option controls the mpv instance via a key pressed in fzf. The key +# pressed is stored in the environment variable FZF_KEY and is resolved to +# the playback command through the method `__playback_cmd_from_key`. +playback() { + view=${1:-} + mbid_current="${2:-}" + mbid="${3:-}" + path="${4:-}" + pbcmd=$(__playback_cmd_from_key "$FZF_KEY") + info "playback(): view=$view; mbid_current=$mbid_current; mbid=$mbid; path=$path; pbcmd=$pbcmd" + case "$pbcmd" in + "$PLAYBACK_CMD_PLAY") + [ "$path" ] || exit 0 + case "$view" in + "$VIEW_ARTIST" | "$VIEW_SEARCH_ARTIST" | "$VIEW_SEARCH_ALBUM" | "$VIEW_LIST_ARTISTS" | "$VIEW_LIST_ALBUMS") info "not implemented" ;; + "$VIEW_RELEASEGROUP") __generate_playlist "$mbid" "$path" | mpv_play_list >/dev/null ;; + "$VIEW_RELEASE") __generate_playlist "$mbid_current" "$path" "$mbid" | mpv_play_list >/dev/null ;; + "$VIEW_PLAYLIST") mpv_play_index $((FZF_POS - 1)) >/dev/null ;; + esac + ;; + "$PLAYBACK_CMD_QUEUE") + [ "$path" ] || exit 0 + case "$view" in + "$VIEW_ARTIST" | "$VIEW_SEARCH_ARTIST" | "$VIEW_SEARCH_ALBUM" | "$VIEW_LIST_ARTISTS" | "$VIEW_LIST_ALBUMS") info "not implemented" ;; + "$VIEW_RELEASEGROUP") __generate_playlist "$mbid" "$path" | mpv_queue_list >/dev/null ;; + "$VIEW_RELEASE") __generate_playlist "$mbid_current" "$path" "$mbid" | mpv_queue_list >/dev/null ;; + "$VIEW_PLAYLIST") __generate_playlist "$mbid_current" "$path" "$mbid" | mpv_queue_list >/dev/null ;; + esac + ;; + "$PLAYBACK_CMD_QUEUE_NEXT") + [ "$path" ] || exit 0 + case "$view" in + "$VIEW_ARTIST" | "$VIEW_SEARCH_ARTIST" | "$VIEW_SEARCH_ALBUM" | "$VIEW_LIST_ARTISTS" | "$VIEW_LIST_ALBUMS") info "not implemented" ;; + "$VIEW_RELEASEGROUP") __generate_playlist "$mbid" "$path" | mpv_queue_next_list >/dev/null ;; + "$VIEW_RELEASE") __generate_playlist "$mbid_current" "$path" "$mbid" | mpv_queue_next_list >/dev/null ;; + "$VIEW_PLAYLIST") __generate_playlist "$mbid_current" "$path" "$mbid" | mpv_queue_next_list >/dev/null ;; + esac + ;; + "$PLAYBACK_CMD_TOGGLE_PLAYBACK") mpv_toggle_pause ;; + "$PLAYBACK_CMD_PLAY_NEXT") mpv_next ;; + "$PLAYBACK_CMD_PLAY_PREV") mpv_prev ;; + "$PLAYBACK_CMD_SEEK_FORWARD") mpv_seek_forward ;; + "$PLAYBACK_CMD_SEEK_BACKWARD") mpv_seek_backward ;; + esac +} diff --git a/src/sh/playlist.sh b/src/sh/playlist.sh index 511ed7e..9881d44 100644 --- a/src/sh/playlist.sh +++ b/src/sh/playlist.sh @@ -4,3 +4,29 @@ PLAYLIST_CMD_DOWN="down" PLAYLIST_CMD_CLEAR="clear" PLAYLIST_CMD_CLEAR_ABOVE="clear-above" PLAYLIST_CMD_CLEAR_BELOW="clear-below" + +# Run playback commands +# +# @argument $1: playlist command +# +# This is a wrapper to execute mpv commands. +playlist() { + case "$1" in + "$PLAYLIST_CMD_REMOVE") mpv_rm_index $((FZF_POS - 1)) ;; + "$PLAYLIST_CMD_UP") mpv_playlist_move $((FZF_POS - 1)) $((FZF_POS - 2)) ;; + "$PLAYLIST_CMD_DOWN") mpv_playlist_move $((FZF_POS - 0)) $((FZF_POS - 1)) ;; + "$PLAYLIST_CMD_CLEAR") mpv_playlist_clear ;; + "$PLAYLIST_CMD_CLEAR_ABOVE") + for i in $(seq "$FZF_POS"); do + mpv_rm_index 0 + done + ;; + "$PLAYLIST_CMD_CLEAR_BELOW") + cnt=$(mpv_playlist_count) + rem=$((cnt - FZF_POS + 1)) + for i in $(seq "$rem"); do + mpv_rm_index $((FZF_POS - 1)) + done + ;; + esac +} diff --git a/src/sh/preview.sh b/src/sh/preview.sh index c1d307d..06a9b8c 100644 --- a/src/sh/preview.sh +++ b/src/sh/preview.sh @@ -5,14 +5,14 @@ __shape() { # Print preview of artist # @input $1: MusicBrainz Artist ID __preview_artist() { - 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 + desc=$(mb_artist_enwikipedia "$1" | $JQ '.extract' | __shape) + [ "$desc" ] || desc=$(mb_artist_discogs "$1" | $JQ '.profile' | sed 's/\[a=\([^]]*\)\]/\1/g' | __shape) + if [ "$(mb_artist "$1" | $JQ '.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 // ""') + lsb=$(mb_artist "$1" | $JQ '."life-span".begin // ""' | head -c 4) + lse=$(mb_artist "$1" | $JQ '."life-span".end // ""' | head -c 4) + ab=$(mb_artist "$1" | $JQ '."begin-area".name // ""') + ae=$(mb_artist "$1" | $JQ '."end-area".name // ""') if [ "$lsb" ] && [ "$ab" ]; then begin=$(printf "$APV_DATEPLACE" "$lsb" "$ab") elif [ "$lsb" ]; then diff --git a/src/sh/query.sh b/src/sh/query.sh new file mode 100644 index 0000000..ca9d23b --- /dev/null +++ b/src/sh/query.sh @@ -0,0 +1,155 @@ +# The default queries depend on the current view, and are usually derived from +# the theme. Nevertheless, they may be overwritten with the configuration file. +# Note that filters are not used in the views VIEW_SEARCH_ARTIST and +# VIEW_SEARCH_ALBUM. The reason for this is that in those modes, changing the +# query string triggers a search on the MusicBrainz website (the input is not a +# filter, but a query). +# +# The keybinding KEYS_FILTER_LOCAL triggers a filter of QUERY_LOCAL in the +# views VIEW_ARTIST, VIEW_RELEASEGROUP, and VIEW_RELEASE only. Here, it is only +# possible to adjust QUERY_LOCAL via the configuration. The keybinding KEYS_FILTER_0 +# resets the query. F_1_.. filters are the default filters when the respective +# view is entered. For all other keys, the filters are individually +# configurable, by specifying e.g., F_3_VIEW_LIST_ALBUMS. +# +# Derived queries +# To derive the queries from the theme, we must perform some steps: 1) remove +# colors, and 2) escape white spaces. This is implemented in the method +# `__clean_filter`. +# +# List of derived queries: +# - QUERY_LOCAL: Hide items that are not locally available +# - q_has_secondary: Release groups with secondary types +# - q_album: Release group is of type Album +# - q_ep: Release group is of type EP +# - q_single: Release group is of type single +# - q_official: Release is official + +__clean_filter() { + cat | sed "s/${ESC}\[[0-9;]*[mK]//g" | sed "s/ /\\\ /g" +} + +# Determine preset query +# @argument $1: Current view +# @argument $2: Key pressed (optional) +# +# If the key is not given, then the F_1_.. query is used for the respective +# view, i.e, its as if a key from KEYS_FILTER_1 has been pressed. +default_query() { + view=$1 + key="${2:-"$(echo "$KEYS_FILTER_1" | cut -d ',' -f 1)"}" + case ",$KEYS_FILTER_LOCAL," in + *",$key,"*) + case "$view" in + "$VIEW_ARTIST" | "$VIEW_RELEASEGROUP" | "$VIEW_RELEASE") echo "$QUERY_LOCAL" ;; + esac + ;; + esac + case ",$KEYS_FILTER_1," in + *",$key,"*) + case "$view" in + "$VIEW_ARTIST") echo "$F_1_VIEW_ARTIST" ;; + "$VIEW_RELEASEGROUP") echo "$F_1_VIEW_RELEASEGROUP" ;; + "$VIEW_RELEASE") echo "$F_1_VIEW_RELEASE" ;; + "$VIEW_LIST_ARTISTS") echo "$F_1_LIST_ARTISTS" ;; + "$VIEW_LIST_ALBUMS") echo "$F_1_LIST_ALBUMS" ;; + esac + ;; + esac + case ",$KEYS_FILTER_2," in + *",$key,"*) + case "$view" in + "$VIEW_ARTIST") echo "$F_2_VIEW_ARTIST" ;; + "$VIEW_RELEASEGROUP") echo "$F_2_VIEW_RELEASEGROUP" ;; + "$VIEW_RELEASE") echo "$F_2_VIEW_RELEASE" ;; + "$VIEW_LIST_ARTISTS") echo "$F_2_LIST_ARTISTS" ;; + "$VIEW_LIST_ALBUMS") echo "$F_2_LIST_ALBUMS" ;; + esac + ;; + esac + case ",$KEYS_FILTER_3," in + *",$key,"*) + case "$view" in + "$VIEW_ARTIST") echo "$F_3_VIEW_ARTIST" ;; + "$VIEW_RELEASEGROUP") echo "$F_3_VIEW_RELEASEGROUP" ;; + "$VIEW_RELEASE") echo "$F_3_VIEW_RELEASE" ;; + "$VIEW_LIST_ARTISTS") echo "$F_3_LIST_ARTISTS" ;; + "$VIEW_LIST_ALBUMS") echo "$F_3_LIST_ALBUMS" ;; + esac + ;; + esac + case ",$KEYS_FILTER_4," in + *",$key,"*) + case "$view" in + "$VIEW_ARTIST") echo "$F_4_VIEW_ARTIST" ;; + "$VIEW_RELEASEGROUP") echo "$F_4_VIEW_RELEASEGROUP" ;; + "$VIEW_RELEASE") echo "$F_4_VIEW_RELEASE" ;; + "$VIEW_LIST_ARTISTS") echo "$F_4_LIST_ARTISTS" ;; + "$VIEW_LIST_ALBUMS") echo "$F_4_LIST_ALBUMS" ;; + esac + ;; + esac + case ",$KEYS_FILTER_5," in + *",$key,"*) + case "$view" in + "$VIEW_ARTIST") echo "$F_5_VIEW_ARTIST" ;; + "$VIEW_RELEASEGROUP") echo "$F_5_VIEW_RELEASEGROUP" ;; + "$VIEW_RELEASE") echo "$F_5_VIEW_RELEASE" ;; + "$VIEW_LIST_ARTISTS") echo "$F_5_LIST_ARTISTS" ;; + "$VIEW_LIST_ALBUMS") echo "$F_5_LIST_ALBUMS" ;; + esac + ;; + esac + case ",$KEYS_FILTER_6," in + *",$key,"*) + case "$view" in + "$VIEW_ARTIST") echo "$F_6_VIEW_ARTIST" ;; + "$VIEW_RELEASEGROUP") echo "$F_6_VIEW_RELEASEGROUP" ;; + "$VIEW_RELEASE") echo "$F_6_VIEW_RELEASE" ;; + "$VIEW_LIST_ARTISTS") echo "$F_6_LIST_ARTISTS" ;; + "$VIEW_LIST_ALBUMS") echo "$F_6_LIST_ALBUMS" ;; + esac + ;; + esac + case ",$KEYS_FILTER_7," in + *",$key,"*) + case "$view" in + "$VIEW_ARTIST") echo "$F_7_VIEW_ARTIST" ;; + "$VIEW_RELEASEGROUP") echo "$F_7_VIEW_RELEASEGROUP" ;; + "$VIEW_RELEASE") echo "$F_7_VIEW_RELEASE" ;; + "$VIEW_LIST_ARTISTS") echo "$F_7_LIST_ARTISTS" ;; + "$VIEW_LIST_ALBUMS") echo "$F_7_LIST_ALBUMS" ;; + esac + ;; + esac + case ",$KEYS_FILTER_8," in + *",$key,"*) + case "$view" in + "$VIEW_ARTIST") echo "$F_8_VIEW_ARTIST" ;; + "$VIEW_RELEASEGROUP") echo "$F_8_VIEW_RELEASEGROUP" ;; + "$VIEW_RELEASE") echo "$F_8_VIEW_RELEASE" ;; + "$VIEW_LIST_ARTISTS") echo "$F_8_LIST_ARTISTS" ;; + "$VIEW_LIST_ALBUMS") echo "$F_8_LIST_ALBUMS" ;; + esac + ;; + esac + case ",$KEYS_FILTER_9," in + *",$key,"*) + case "$view" in + "$VIEW_ARTIST") echo "$F_9_VIEW_ARTIST" ;; + "$VIEW_RELEASEGROUP") echo "$F_9_VIEW_RELEASEGROUP" ;; + "$VIEW_RELEASE") echo "$F_9_VIEW_RELEASE" ;; + "$VIEW_LIST_ARTISTS") echo "$F_9_LIST_ARTISTS" ;; + "$VIEW_LIST_ALBUMS") echo "$F_9_LIST_ALBUMS" ;; + esac + ;; + esac + # Doing nothing is the same as this last block: + # case ",$KEYS_FILTER_0," in + # *",$key,"*) + # case "$view" in + # "$VIEW_ARTIST" | "$VIEW_RELEASEGROUP" | "$VIEW_RELEASE" | "$VIEW_LIST_ARTISTS" | "$VIEW_LIST_ALBUMS") echo "" ;; + # esac + # ;; + # esac +} diff --git a/src/sh/theme.sh b/src/sh/theme.sh index cab687b..d2fa7e5 100644 --- a/src/sh/theme.sh +++ b/src/sh/theme.sh @@ -23,6 +23,7 @@ OFF="${ESC}[m" FORMAT_LOCAL="${FORMAT_LOCAL:-"๐Ÿ”†"}" # Pointer to the track currently playing (playlist) FORMAT_CURRENT="${FORMAT_CURRENT:-"๐Ÿ‘‰"}" +export FORMAT_LOCAL FORMAT_CURRENT # Input prompts # ============= @@ -33,6 +34,7 @@ ARTIST_PROMPT="${ARTIST_PROMPT:-"๐ŸŽค ${CARTIST}%s$OFF โŒช"}" # Prompt that takes an artist name and a release name as arguments (in that # order) FULL_PROMPT="${FULL_PROMPT:-"๐ŸŽค ${CARTIST}%s$OFF ใ€‹${CTITLE}%s$OFF โŒช"}" +export SEARCH_PROMPT ARTIST_PROMPT FULL_PROMPT # Visual representation of current mode # ===================================== @@ -40,6 +42,7 @@ FULL_PROMPT="${FULL_PROMPT:-"๐ŸŽค ${CARTIST}%s$OFF ใ€‹${CTITLE}%s$OFF โŒช"}" PROMPT_NORMAL="${PROMPT_NORMAL:-"${FAINT}[n]${OFF}"}" # Sign to indicate `insert` mode PROMPT_INSERT="${PROMPT_INSERT:-"${FAINT}[i]${OFF}"}" +export PROMPT_NORMAL PROMPT_INSERT # Artist view # =========== @@ -49,6 +52,7 @@ AV_PERSON="${AV_PERSON:-"๐Ÿง‘โ€๐ŸŽค $CARTIST<>$OFF"}" AV_GROUP="${AV_GROUP:-"๐Ÿง‘โ€๐Ÿคโ€๐Ÿง‘ $CARTIST<>$OFF"}" # Artist disambiguation string AV_DISAMBIGUATION="${AV_DISAMBIGUATION:-"$CDISAMB(<>)$OFF"}" +export AV_PERSON AV_GROUP AV_DISAMBIGUATION # Release-group view # ================== @@ -58,6 +62,7 @@ RGV_RELEASE="${RGV_RELEASE:-"${CTITLE}<>$OFF"}" RGV_RELEASE_W_ARTIST="${RGV_RELEASE_W_ARTIST:-"${CTITLE}<<title>>$OFF โ€” ${CARTIST}<<artist>>$OFF"}" # Year of the release group RGV_YEAR="${RGV_YEAR:-"${CYEAR}(<<year>>)$OFF"}" +export RGV_RELEASE RGV_RELEASE_W_ARTIST RGV_YEAR # Release-group types # =================== @@ -88,6 +93,15 @@ 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"}" +export FORMAT_TYPE_ALBUM FORMAT_TYPE_EP FORMAT_TYPE_SINGLE \ + FORMAT_TYPE_BROADCAST FORMAT_TYPE_OTHER FORMAT_TYPE_HAS_SECONDARY \ + FORMAT_TYPE_SECONDARY FORMAT_TYPE_SECONDARY_COMPILATION \ + FORMAT_TYPE_SECONDARY_SOUNDTRACK FORMAT_TYPE_SECONDARY_SPOKENWORD \ + FORMAT_TYPE_SECONDARY_INTERVIEW FORMAT_TYPE_SECONDARY_AUDIOBOOK \ + FORMAT_TYPE_SECONDARY_AUDIODRAMA FORMAT_TYPE_SECONDARY_LIVE \ + FORMAT_TYPE_SECONDARY_REMIX FORMAT_TYPE_SECONDARY_DJMIX \ + FORMAT_TYPE_SECONDARY_MIXTAPE FORMAT_TYPE_SECONDARY_DEMO \ + FORMAT_TYPE_SECONDARY_FIELDREC # Artist Preview # ============== @@ -104,6 +118,7 @@ APV_DATEPLACE="${APV_DATEPLACE:-"$APV_DATE, $APV_PLACE"}" APV_BORN="${APV_BORN:-"๐Ÿผ Born: %s"}" # String to represent when/where a person died APV_DIED="${APV_DIED:-"๐Ÿ•ฏ๏ธ Died: %s"}" +export APV_FORMAT APV_DATE APV_PLACE APV_DATEPLACE APV_BORN APV_DIED # Release view # ============ @@ -115,6 +130,7 @@ RV_TITLE_ARTIST="${RV_TITLE_ARTIST:-"${FAINT}as ${CTITLE}<<title>>$OFF by ${FAIN RV_TITLE="${RV_TITLE:-"${FAINT}as ${CTITLE}<<title>>$OFF"}" # Additional string to display the artist RV_ARTIST="${RV_ARTIST:-"${FAINT}by ${CARTIST}<<artist>>$OFF"}" +export RV_FORMAT RV_TITLE_ARTIST RV_TITLE RV_ARTIST # Release Status # ============== @@ -125,6 +141,9 @@ FORMAT_STATUS_PSEUDO="${FORMAT_STATUS_PSEUDO:-"๐ŸŒ€"}" FORMAT_STATUS_WITHDRAWN="${FORMAT_STATUS_WITHDRAWN:-"๐Ÿ”™"}" FORMAT_STATUS_EXPUNGED="${FORMAT_STATUS_EXPUNGED:-"๐Ÿงน"}" FORMAT_STATUS_CANCELLED="${FORMAT_STATUS_CANCELLED:-"โŒ"}" +export FORMAT_STATUS_OFFICIAL FORMAT_STATUS_PROMO FORMAT_STATUS_BOOTLEG \ + FORMAT_STATUS_PSEUDO FORMAT_STATUS_WITHDRAWN FORMAT_STATUS_EXPUNGED \ + FORMAT_STATUS_CANCELLED # Recording view # ============== @@ -132,3 +151,4 @@ FORMAT_STATUS_CANCELLED="${FORMAT_STATUS_CANCELLED:-"โŒ"}" REC_FORMAT="${REC_FORMAT:-"${CNOTE}${FAINT}<<med>>\t${CNOTE}<<nr>>$OFF\t${CTITLE}<<title>>\t${CARTIST}<<artist>>\t${CXXX}<<duration>>$OFF"}" # Format of a track in the playlist REC_FORMAT_NO_NUMBER="${REC_FORMAT_NO_NUMBER:-"${CTITLE}<<title>>\t${CARTIST}<<artist>>\t${CXXX}<<duration>>$OFF"}" +export REC_FORMAT REC_FORMAT_NO_NUMBER diff --git a/src/sh/tools.sh b/src/sh/tools.sh index 5211c2d..7d5ac08 100644 --- a/src/sh/tools.sh +++ b/src/sh/tools.sh @@ -1,39 +1,43 @@ -if command -v "fzf" >/dev/null; then - FZF="fzf --black --ansi --cycle --tiebreak=chunk,index" -else - err "Did not find the command-line fuzzy finder fzf." - exit 1 -fi -export FZF +if [ ! "${TOOLS_LOADED:-}" ]; then + if command -v "fzf" >/dev/null; then + FZF="fzf --black --ansi --cycle --tiebreak=chunk,index" + else + err "Did not find the command-line fuzzy finder fzf." + exit 1 + fi + export FZF -if command -v "curl" >/dev/null; then - CURL="curl --silent" -else - err "Did not find curl." - exit 1 -fi -export CURL + if command -v "curl" >/dev/null; then + CURL="curl --silent" + else + err "Did not find curl." + exit 1 + fi + export CURL -if command -v "jq" >/dev/null; then - JQ="jq" -else - err "Did not find jq." - exit 1 -fi -export JQ + if command -v "jq" >/dev/null; then + JQ="jq -r --compact-output" + else + err "Did not find jq." + 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 "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 + if command -v "socat" >/dev/null; then + SOCAT="socat" + else + err "Did not find socat." + exit 1 + fi + export SOCAT + + export TOOLS_LOADED=1 fi -export SOCAT