From 2d9493d9fe062a0c2805890d9e149e06a717d1e1 Mon Sep 17 00:00:00 2001 From: JakeBreath Date: Fri, 18 Sep 2026 13:22:55 -0500 Subject: [PATCH] fish_greeting installer asks for the API origin and probes the backend install.fish now: - asks for the API origin (default https://j621.rainbow-herring.ts.net) and an optional token when run interactively, or takes --url/--token; - writes ~/.config/j621Greeting/config.fish with mode 600 (it may hold a token), keeps an existing config unless --force/--url is given, and --no-prompt runs fully unattended; - verifies the setup: /health must answer 'ok' and a fastfetch random roll is attempted, reporting the API's own message when it finds nothing; exits non-zero when the backend is unreachable so scripts notice. README documents the prompts/flags, the chmod 600 config, and that the greeting is designed to run without a token (guest mode: unsigned links, guest-visible items only) with a token adding signed links and hidden items. Tested with fish 4.9.3 in throwaway HOME dirs: flag-driven install with a token, interactive install with a piped origin and no token, re-run keeping the existing config, and an unreachable backend exiting 1. --- README.md | 4 + extras/fish_greeting/install.fish | 134 ++++++++++++++++++++++++++---- 2 files changed, 121 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 49e1dc8..8e9a0c2 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ Self-hosted media library and e621 archive manager, rebuilt as a **React SPA + D ``` backend/ Django 6 + DRF API (MariaDB + Redis via docker compose) frontend/ Vite + React + TypeScript SPA +deploy/ Docker images, compose variants and Tailscale serve configs +extras/ shell integrations (fish_greeting with fastfetch) ``` ## Development @@ -73,6 +75,8 @@ curl -H "Authorization: Token " \ the bundled nginx those aliases negotiate on `Accept`: browsers get the SPA page, requesters like curl/wget/fastfetch get the JSON. `/api/random/` is the unambiguous path for scripts; 404 when nothing matches the filters. +- A ready-made shell greeting that uses this endpoint lives in + [`extras/fish_greeting/`](extras/fish_greeting/README.md). ## Licence diff --git a/extras/fish_greeting/install.fish b/extras/fish_greeting/install.fish index 181b848..b6dc95a 100644 --- a/extras/fish_greeting/install.fish +++ b/extras/fish_greeting/install.fish @@ -1,52 +1,152 @@ #!/usr/bin/env fish # Install the J621 fish greeting: # * copies fish_greeting.fish into ~/.config/fish/functions/ -# * creates ~/.config/j621Greeting/config.fish from the example (once) -# * checks the tools it needs +# * writes ~/.config/j621Greeting/config.fish (asks for the API origin and an +# optional token, or takes them as flags) +# * checks the tools it needs and probes the configured backend # -# Usage: fish install.fish +# Usage: +# fish install.fish +# fish install.fish --url https://j621.example.ts.net --token +# fish install.fish --no-prompt # never ask, keep/derive defaults +# fish install.fish --force # rewrite an existing config + +argparse 'url=' 'token=' 'no-prompt' 'force' 'help' -- $argv +or begin + echo "Try: fish install.fish --help" + exit 1 +end + +if set -q _flag_help + sed -n '2,12p' (status --current-filename) | sed 's/^# \{0,1\}//' + exit 0 +end set -l here (path resolve (dirname (status --current-filename))) set -l functions_dir ~/.config/fish/functions set -l config_dir ~/.config/j621Greeting +set -l config_file $config_dir/config.fish +set -l default_url https://j621.rainbow-herring.ts.net +set -l url $default_url +set -l token "" set -l problems 0 +if set -q _flag_url + set url $_flag_url +end +if set -q _flag_token + set token $_flag_token +end + +# --- Install the function ----------------------------------------------------- mkdir -p $functions_dir cp "$here/fish_greeting.fish" "$functions_dir/fish_greeting.fish" echo "Installed $functions_dir/fish_greeting.fish" +# --- Configuration ------------------------------------------------------------ mkdir -p $config_dir -if test -f "$config_dir/config.fish" - echo "Keeping existing $config_dir/config.fish" + +set -l write_config 0 +if not test -f $config_file + set write_config 1 +else if set -q _flag_force; or set -q _flag_url + set write_config 1 else - cp "$here/config.example.fish" "$config_dir/config.fish" - echo "Created $config_dir/config.fish — edit J621_BASE (and J621_TOKEN) there" + echo "Keeping existing $config_file (use --force to rewrite it)" + # Read the current origin back so the probe below uses it. + set -l current (grep -E '^set -g J621_BASE ' $config_file 2>/dev/null | head -1 | string replace -r '^set -g J621_BASE +' '') + test -n "$current"; and set url $current end -for tool in curl fastfetch file +if test $write_config -eq 1 + if not set -q _flag_no_prompt + if not set -q _flag_url + read -P "API origin [$default_url]: " answer + test -n "$answer"; and set url $answer + end + if not set -q _flag_token + read -P "API token (optional, Enter to run as a guest): " answer + test -n "$answer"; and set token $answer + end + end + + set url (string trim --right --chars=/ "$url") + printf '# Written by install.fish on %s\n' (date '+%Y-%m-%d') > $config_file + printf 'set -g J621_BASE %s\n' "$url" >> $config_file + if test -n "$token" + printf 'set -g J621_TOKEN %s\n' "$token" >> $config_file + else + printf '# set -g J621_TOKEN paste-a-token-here\n' >> $config_file + end + printf '# set -g J621_WEB %s\n' "$url" >> $config_file + printf '# set -g J621_FASTFETCH_CONFIG jake\n' >> $config_file + chmod 600 $config_file + echo "Wrote $config_file" +end + +# --- Dependencies ------------------------------------------------------------- +for tool in fastfetch file if not command -v $tool >/dev/null 2>&1 set problems 1 echo "Missing required tool: $tool" end end - if not command -v curl >/dev/null 2>&1; and not command -v wget >/dev/null 2>&1 set problems 1 echo "Missing required tool: curl (or wget)" end - for tool in gifsicle jq python3 if not command -v $tool >/dev/null 2>&1 echo "Optional tool not found: $tool (the greeting still works)" end end -if test $problems -eq 0 - echo - echo "Done. Test it now with: fish_greeting" - echo "Rating mode lives in ~/.config/fish/greeting_mode (0=NSFW, 1=SFW, 2=Questionable)." - echo "The old gm-switch tool / .desktop launchers keep working — same file." +# --- Probe the configured backend -------------------------------------------- +echo +echo "Checking $url ..." +set -l health "" +if command -v curl >/dev/null 2>&1 + set health (curl -s -m 10 "$url/health" | string collect) else - echo - echo "Install the missing tools, then run: fish_greeting" + set health (wget -qO- -T 10 "$url/health" | string collect) end + +if string match -q '*"status":"ok"*' "$health" + echo " backend: ok" + set -l random_args -s -m 10 + if test -n "$token" + set -a random_args -H "Authorization: Token $token" + end + set -l probe "" + if command -v curl >/dev/null 2>&1 + set probe (curl $random_args "$url/api/random/?fastfetch=1" | string collect) + else + set probe (wget -qO- -T 10 "$url/api/random/?fastfetch=1" | string collect) + end + set -l detail (printf '%s' "$probe" | grep -o '"detail"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed -E 's/.*:[[:space:]]*"//; s/"$//') + if test -n "$detail" + echo " random: $detail" + if test -z "$token" + echo " (a token would also let you see items that are hidden from guests)" + end + else + echo " random: ok" + end +else + set problems 1 + echo " backend did not answer at $url/health" + echo " got: $health" + echo " Fix J621_BASE in $config_file (or pass --url) and run again." +end + +# --- Wrap up ------------------------------------------------------------------ +echo +if test $problems -eq 0 + echo "Done. Test it now with: fish_greeting" +else + echo "Finished with problems above; the greeting will report them too." +end +echo "Rating mode lives in ~/.config/fish/greeting_mode (0=NSFW, 1=SFW, 2=Questionable)." +echo "The old gm-switch tool / .desktop launchers keep working — same file." + +exit $problems