imprv: mode handling

This commit is contained in:
2025-07-17 11:59:42 +02:00
parent 347014a8ce
commit 46dacef79d

179
fuzzique
View File

@@ -2,19 +2,34 @@
set -eu set -eu
if [ "${1:-}" = "--info" ]; then APP_NAME="fuzique"
if [ "${1:-}" = "--prompt" ]; then
shift shift
file="$1" file="$1"
shift
mode="$1"
case "$mode" in
"$MODE_SEARCH")
printf "search> "
;;
"$MODE_BROWSE")
rel=${file#"$ROOT/"} rel=${file#"$ROOT/"}
artist=$(echo "$rel" | cut -d "/" -f 1) artist=$(echo "$rel" | cut -d "/" -f 1)
release=$(echo "$rel" | cut -d "/" -f 2) release=$(echo "$rel" | cut -d "/" -f 2)
d=$(echo "$rel" | awk -F'/' '{ print NF }') d=$(echo "$rel" | awk -F'/' '{ print NF }')
[ "$d" -eq 2 ] && printf ">> $AFMT" "$artist" [ "$d" -eq 2 ] && printf " $AFMT" "$artist"
[ "$d" -eq 3 ] && printf ">> $AFMT >> $RFMT" "$artist" "$release" [ "$d" -eq 3 ] && printf " $AFMT $RFMT" "$artist" "$release"
;;
"$MODE_PLAYLIST")
printf ""
;;
esac
exit 0 exit 0
fi fi
if [ "${1:-}" = "--preview" ]; then if [ "${1:-}" = "--preview" ]; then
echo "call to --preview" >>/tmp/foo
shift shift
file="$1" file="$1"
tags=$(ffprobe -v quiet -show_entries format -of json "$file" | jq) tags=$(ffprobe -v quiet -show_entries format -of json "$file" | jq)
@@ -22,29 +37,39 @@ if [ "${1:-}" = "--preview" ]; then
echo "## Lyrics" echo "## Lyrics"
echo "" echo ""
printf "%s" "$tags" | jq -C -r '.format.tags.LYRICS' printf "%s" "$tags" | jq -C -r '.format.tags.LYRICS'
} | batcat --color always --number --language md } | $CAT
exit 0 exit 0
fi fi
if [ "${1:-}" = "--show-playlist" ]; then if [ "${1:-}" = "--show-playlist" ]; then
[ ! -S "${MPV_SOCKET:-}" ] && exit 1 [ ! -S "${MPV_SOCKET:-}" ] && exit 1
count=$(echo "{ \"command\": [\"expand-text\",\"\${playlist/count}\"] }" | socat - "$MPV_SOCKET" | jq -r '.data') count=$(echo "{ \"command\": [\"expand-text\",\"\${playlist/count}\"] }" | socat - "$MPV_SOCKET" | jq -r '.data')
if [ "$count" -eq 0 ]; then
printf "(empty playlist)\t\t%s\n" "$MODE_PLAYLIST"
exit 0
fi
for i in $(seq 0 $((count - 1))); do for i in $(seq 0 $((count - 1))); do
file=$(echo "{ \"command\": [\"expand-text\",\"\${playlist/$i/filename}\"] }" | socat - "$MPV_SOCKET" | jq -r '.data') file=$(echo "{ \"command\": [\"expand-text\",\"\${playlist/$i/filename}\"] }" | socat - "$MPV_SOCKET" | jq -r '.data')
curr=$(echo "{ \"command\": [\"expand-text\",\"\${playlist/$i/current}\"] }" | socat - "$MPV_SOCKET" | jq -r '.data') curr=$(echo "{ \"command\": [\"expand-text\",\"\${playlist/$i/current}\"] }" | socat - "$MPV_SOCKET" | jq -r '.data')
pnt=" " pnt=" "
[ "$curr" = "yes" ] && pnt="👉" [ "$curr" = "yes" ] && pnt="$PLAYLIST_POINTER"
artist=$(echo "$file" | rev | cut -d "/" -f 3 | rev) artist=$(echo "$file" | rev | cut -d "/" -f 3 | rev)
release=$(echo "$file" | rev | cut -d "/" -f 2 | rev) release=$(echo "$file" | rev | cut -d "/" -f 2 | rev)
title=$(echo "$file" | rev | cut -d "/" -f 1 | rev | sed 's/\..*$//') title=$(echo "$file" | rev | cut -d "/" -f 1 | rev | sed 's/\..*$//')
artist=$(printf "$AFMT" "$artist") artist=$(printf "$AFMT" "$artist")
release=$(printf "$RFMT" "$release") release=$(printf "$RFMT" "$release")
title=$(printf "$TFMT" "$title") title=$(printf "$TFMT" "$title")
printf "%s|%s|%s|%s\t%s\n" "$pnt" "$title" "$release" "$artist" "$file" printf "%s|%s|%s|%s\t%s\t%s\n" "$pnt" "$title" "$release" "$artist" "$file" "$MODE_PLAYLIST"
done | grep '.' | column -t -s '|' done |
grep '.' |
column -t -s '|'
exit 0 exit 0
fi fi
# Tools
command -v "fdfind" >/dev/null && FD="fdfind" || (err "Did not find \`fdfind\`." && exit 1)
command -v "fzf" >/dev/null && FZF="fzf" || (err "Did not find \`fzf\`." && exit 1)
command -v "mpv" >/dev/null && MPV="mpv" || (err "Did not find \`mpv\`." && exit 1)
if command -v "bat" >/dev/null; then if command -v "bat" >/dev/null; then
CAT="bat" CAT="bat"
elif command -v "batcat" >/dev/null; then elif command -v "batcat" >/dev/null; then
@@ -91,48 +116,71 @@ EOF
exit 0 exit 0
fi fi
[ "${1:-}" ] && ROOT="$1" && shift # Load configuration
[ ! -d "${ROOT:-}" ] && echo "Faild to recognize music directory. Run $0 --help." && exit 1 [ "${1:-}" ] && ROOT="$(realpath "$1")" && shift
ROOT=${ROOT%%/} ROOT=${ROOT%%/}
CACHE="$HOME/.cache/fuzzique" [ ! -d "${ROOT:-}" ] && echo "Faild to recognize music directory. Run $0 --help." && exit 1
ROOTHASH=$(echo "$ROOT" | sha1sum | cut -d ' ' -f 1)
CACHE="$CACHE/$ROOTHASH"
DEPTH=$(echo "$ROOT" | awk -F'/' '{ print NF }') DEPTH=$(echo "$ROOT" | awk -F'/' '{ print NF }')
FD=/usr/bin/fdfind
FZF=fzf # Cache support
MPV=mpv ROOTHASH=$(echo "$ROOT" | sha1sum | cut -d ' ' -f 1)
MPV_SOCKET="$(mktemp --suffix=.sock)" CACHE_DIR="$HOME/.cache/$APP_NAME"
ARTIST_COLOR='\033[38;5;202m' CACHE_FILE="$CACHE_DIR/$ROOTHASH"
RELEASE_COLOR='\033[38;5;208m'
TRACK_COLOR='\033[38;5;215m' # Theme
ARTIST_COLOR=${ARTIST_COLOR:-'\033[38;5;202m'}
RELEASE_COLOR=${RELEASE_COLOR:-'\033[38;5;208m'}
TRACK_COLOR=${TRACK_COLOR:-'\033[38;5;215m'}
OFF="\033[m" OFF="\033[m"
AFMT="🎤 ${ARTIST_COLOR}%s${OFF}" AFMT="${AFTM:-"🎤 ${ARTIST_COLOR}%s${OFF}"}"
RFMT="💽 ${RELEASE_COLOR}%s${OFF}" RFMT="${RFMT:-"💽 ${RELEASE_COLOR}%s${OFF}"}"
TFMT="🎵 ${TRACK_COLOR}%s${OFF}" TFMT="${TFMT:-"🎵 ${TRACK_COLOR}%s${OFF}"}"
export ROOT MPV_SOCKET AFMT RFMT TFMT PLAYLIST_POINTER="${PLAYLIST_POINTER:-☞}"
#PLAYLIST_POINTER="${PLAYLIST_POINTER:-👉}"
# Modes
MODE_BROWSE="B"
MODE_SEARCH="S"
MODE_PLAYLIST="P"
# Make socket
MPV_SOCKET="$(mktemp --suffix=.sock)"
# Export
export ROOT MPV_SOCKET AFMT RFMT TFMT PLAYLIST_POINTER MODE_SEARCH MODE_BROWSE MODE_PLAYLIST
# Load # Load
artists_file="$CACHE/artists" if [ "${1:-}" = "--reset-cache" ] || [ ! -f "$CACHE_FILE" ]; then
release_file="$CACHE/release" rm -f "$CACHE_FILE"
tracks_file="$CACHE/tracks" [ ! -d "$CACHE_DIR" ] && mkdir -p "$CACHE_DIR"
if [ "${1:-}" = "--build-db" ] || [ ! -f "$artists_file" ]; then
rm -rf "$CACHE"
mkdir -p "$CACHE"
[ ! -d "$CACHE" ] && echo "Failed to create cache directory" && exit 1
{ {
$FD --max-depth 2 --type d . "$ROOT" $FD --max-depth 2 --type d . "$ROOT"
$FD --exact-depth 3 --type f -i -e "mp3" -e "mp4" -e "m4a" -e "ogg" -e "flac" -e "wav" . "$ROOT" $FD --exact-depth 3 --type f -i -e "mp3" -e "mp4" -e "m4a" -e "ogg" -e "flac" -e "wav" . "$ROOT"
} | } |
sort | sort >"$CACHE_FILE"
fi
# Parse
artists_file_browse=$(mktemp)
artists_file_search=$(mktemp)
release_file_browse=$(mktemp)
release_file_search=$(mktemp)
tracks_file_browse=$(mktemp)
tracks_file_search=$(mktemp)
awk \ awk \
-F'/' \ -F'/' \
-v afmt="$AFMT" \ -v afmt="$AFMT" \
-v rfmt="$RFMT" \ -v rfmt="$RFMT" \
-v tfmt="$TFMT" \ -v tfmt="$TFMT" \
-v depth="$DEPTH" \ -v depth="$DEPTH" \
-v artists_file="$artists_file" \ -v artists_file_browse="$artists_file_browse" \
-v release_file="$release_file" \ -v release_file_browse="$release_file_browse" \
-v tracks_file="$tracks_file" \ -v tracks_file_browse="$tracks_file_browse" \
-v artists_file_search="$artists_file_search" \
-v release_file_search="$release_file_search" \
-v tracks_file_search="$tracks_file_search" \
-v mode_browse="$MODE_BROWSE" \
-v mode_search="$MODE_SEARCH" \
'BEGIN { 'BEGIN {
OFS="\t" OFS="\t"
iartist = depth + 1 iartist = depth + 1
@@ -142,14 +190,13 @@ if [ "${1:-}" = "--build-db" ] || [ ! -f "$artists_file" ]; then
NF >= depth + 1 { ar = sprintf(afmt, $iartist) } NF >= depth + 1 { ar = sprintf(afmt, $iartist) }
NF >= depth + 2 { rl = sprintf(rfmt, $irelease) } NF >= depth + 2 { rl = sprintf(rfmt, $irelease) }
NF >= depth + 3 { tr = $itrack; gsub(/\..*$/, "", tr); tr = sprintf(tfmt, tr) } NF >= depth + 3 { tr = $itrack; gsub(/\..*$/, "", tr); tr = sprintf(tfmt, tr) }
NF == depth + 1 { print ar, $0 >> artists_file } NF == depth + 1 { print ar, $0, mode_browse >> artists_file_browse }
NF == depth + 2 { print rl, $0 >> release_file } NF == depth + 2 { print rl, $0, mode_browse >> release_file_browse }
NF == depth + 3 { print tr, $0 >> tracks_file } NF == depth + 3 { print tr, $0, mode_browse >> tracks_file_browse }
' NF == depth + 1 { print ar, $0, mode_search >> artists_file_search }
# NF == depth + 1 { print ar, $0 >> artists_file } NF == depth + 2 { print rl "|" ar, $0, mode_search >> release_file_search }
# NF == depth + 2 { print rl "|" ar, $0 >> release_file } NF == depth + 3 { print tr "|" rl "|" ar, $0, mode_search >> tracks_file_search }
# NF == depth + 3 { print tr "|" rl "|" ar, $0 >> tracks_file } ' <"$CACHE_FILE"
fi
$MPV --no-config --no-terminal --input-ipc-server="$MPV_SOCKET" --idle & $MPV --no-config --no-terminal --input-ipc-server="$MPV_SOCKET" --idle &
@@ -160,29 +207,43 @@ $FZF \
--delimiter="\t" \ --delimiter="\t" \
--with-nth="{1}" \ --with-nth="{1}" \
--cycle \ --cycle \
--info=inline-right \
--info-command="$0 --info {2}" \
--bind="ctrl-d:half-page-down,ctrl-u:half-page-up" \ --bind="ctrl-d:half-page-down,ctrl-u:half-page-up" \
--bind="enter:execute:printf '{ \"command\": [\"loadfile\", \"%s\"] }\n' {2} | socat - \"$MPV_SOCKET\"" \ --bind="enter:execute:printf '{ \"command\": [\"loadfile\", \"%s\"] }\n' {2} | socat - \"$MPV_SOCKET\"" \
--bind="alt-enter:execute:printf '{ \"command\": [\"loadfile\", \"%s\", \"append-play\"] }\n' {2} | socat - \"$MPV_SOCKET\"" \ --bind="alt-enter:execute:printf '{ \"command\": [\"loadfile\", \"%s\", \"append-play\"] }\n' {2} | socat - \"$MPV_SOCKET\"" \
--bind="alt-t:show-input+reload:cat \"$tracks_file\" | column -t -s '|' -E 0" \ --preview="$0 --preview {2}" \
--bind="alt-r:show-input+reload:cat \"$release_file\" | column -t -s '|'" \ --bind="alt-1:reload:column -t -s '|' -E 0 \"$artists_file_search\"" \
--bind="alt-a:show-input+reload:cat \"$artists_file\" | column -t -s '|'" \ --bind="alt-2:reload:column -t -s '|' -E 0 \"$release_file_search\"" \
--bind="ctrl-l:show-input+transform: --bind="alt-3:reload:column -t -s '|' -E 0 \"$tracks_file_search\"" \
d=\$(echo {2} | awk -F'/' '{ print NF }') --bind="ctrl-p:reload:$0 --show-playlist" \
[ \"\$d\" -eq \"$((DEPTH + 1))\" ] && echo \"reload:grep -F {2}/ \\\"$release_file\\\" | column -t -s '|' || true\" --bind="load:transform:
[ \"\$d\" -eq \"$((DEPTH + 2))\" ] && echo \"reload:grep -F {2}/ \\\"$tracks_file\\\" | column -t -s '|' || true\" echo \"l2:{}\" >> /tmp/foo
[ {3} = \"$MODE_SEARCH\" ] && printf \"+hide-preview\" || printf \"+show-preview\"
[ {3} = \"$MODE_PLAYLIST\" ] && printf \"+hide-input\" || printf \"+show-input\"
echo \"l3:{}\" >> /tmp/foo
printf \"+transform-prompt:$0 --prompt {2} {3}\"
echo \"l4:{}\" >> /tmp/foo
echo \"load ended..\" >> /tmp/foo
" \ " \
--bind="ctrl-h:show-input+transform: --bind="ctrl-l:transform:
printf \"clear-query+pos(1)\"
d=\$(echo {2} | awk -F'/' '{ print NF }')
[ \"\$d\" -eq \"$((DEPTH + 1))\" ] && echo \"+reload:grep -F {2}/ \\\"$release_file_browse\\\" | column -t -s '|' || true\"
[ \"\$d\" -eq \"$((DEPTH + 2))\" ] && echo \"+reload:grep -F {2}/ \\\"$tracks_file_browse\\\" | column -t -s '|' || true\"
" \
--bind="ctrl-h:transform:
printf \"clear-query+pos(1)\"
d=\$(echo {2} | awk -F'/' '{ print NF }') d=\$(echo {2} | awk -F'/' '{ print NF }')
p=\$(echo {2} | rev | cut -d '/' -f 3- | rev) p=\$(echo {2} | rev | cut -d '/' -f 3- | rev)
[ \"\$d\" -eq \"$((DEPTH + 3))\" ] && echo \"reload:grep -F \\\"\$p/\\\" \\\"$release_file\\\" | column -t -s '|' || true\" [ \"\$d\" -eq \"$((DEPTH + 3))\" ] && echo \"+reload:grep -F \\\"\$p/\\\" \\\"$release_file_browse\\\" | column -t -s '|' || true\"
[ \"\$d\" -eq \"$((DEPTH + 2))\" ] && echo \"reload:grep -F \\\"\$p/\\\" \\\"$artists_file\\\" | column -t -s '|' || true\" [ \"\$d\" -eq \"$((DEPTH + 2))\" ] && echo \"+reload:grep -F \\\"\$p/\\\" \\\"$artists_file_browse\\\" | column -t -s '|' || true\"
" \ " \
--bind="ctrl-p:hide-input+reload:$0 --show-playlist" \ <"$artists_file_search" || true
--preview="$0 --preview {2}" \
--bind="alt-/:toggle-preview" \
<"$artists_file" || true
printf '{ "command": ["quit"] }\n' | socat - "$MPV_SOCKET" printf '{ "command": ["quit"] }\n' | socat - "$MPV_SOCKET"
rm -f "$MPV_SOCKET" rm -f "$MPV_SOCKET" \
"$artists_file_browse" \
"$artists_file_search" \
"$release_file_browse" \
"$release_file_search" \
"$tracks_file_browse" \
"$tracks_file_search"