Files
J621/extras/fish_greeting
JakeBreath 770b1e5ee6 Scoped API tokens for the random endpoint, with a management page
Backend: a GreetingToken model stores only a SHA-256 hash of a j621r_…
key (shown once at creation) plus label, prefix, created/last-used. A
dedicated GreetingTokenAuthentication understands the usual
'Authorization: Token …' header but is registered only on RandomItemView
(alongside the normal token auth), so a greeting token authenticates
/api/random/ and is rejected with 401 everywhere else — exactly the scope
shell greetings need. Endpoints: GET/POST /api/auth/greeting-tokens/ and
DELETE /api/auth/greeting-tokens/{id}/ (own tokens only; the list never
returns keys or hashes).

Frontend: /tokens page (Account → Shell tokens card, command palette entry)
lists tokens with label, prefix, created/last-used and revoke (shared
confirm dialog). Creating one shows the key with Copy and 'Copy for fish'
buttons plus a pointer to extras/fish_greeting.

Tests: apps/accounts/tests/test_greeting_tokens.py — 9 tests covering
create-once semantics and hashing, hidden keys in listings, the scope
guarantee (random 200 with a signed URL; 401 on files, storage, me, tags
cloud, delete and the token list itself), unknown/revoked keys, cross-user
revocation, last-used tracking and label limits.

Verified live: created a token, rolled /random (signed URL), got 401 from
four other endpoints, saw the list omit secrets, revoked it (204) and the
same key then 401'd on /random. Full suite: 39 tests green.
2026-09-18 13:37:29 -05:00
..

fish_greeting (updated for the J621 rewrite)

Shows a random library image as your shell greeting, using fastfetch. This is the updated version of the script from J621-Django/extras/fish_greeting system/fish_greeting.fish, adapted to the new REST API.

What changed from the old script

Old J621-Django This version
Endpoint GET /random/?rating=X returned image bytes GET /api/random/?fastfetch=1&rating=X returns JSON
Image access same response, X-File-MD5/X-File-Name headers signed url from the JSON, downloaded separately
Unsupported types rolled again (recursion) server only returns png/jpg/gif in fastfetch mode
Config hardcoded https://j621.jake.i J621_BASE / J621_TOKEN / J621_WEB
Printed link /view/<md5> on the old host /detail/<J-ID> on J621_WEB
Modes, logging, gifsicle, fastfetch flags same same (~/.config/fish/greeting_mode, ~/.config/j621Logos/logs.log)

The gm-switch helper and the .desktop launchers from the old repo keep working unchanged: they write the same ~/.config/fish/greeting_mode file (0 = NSFW, 1 = SFW, 2 = Questionable).

Install

cd extras/fish_greeting
fish install.fish

The installer copies the function into ~/.config/fish/functions/, asks for your API origin (and an optional scoped token — see below), writes ~/.config/j621Greeting/config.fish (mode 600, it may hold the token), checks the tools it needs and then verifies the backend: /health must answer and a random roll is attempted. It exits non-zero when the backend cannot be reached.

Non-interactive / re-install:

fish install.fish --url https://j621.example.ts.net --token <api-token>
fish install.fish --no-prompt     # defaults, never asks
fish install.fish --force         # rewrite an existing config

Then test:

fish_greeting

Requirements: curl (or wget), fastfetch, file. Optional: gifsicle (GIF downscaling), jq or python3 (JSON parsing — without either it falls back to grep/sed).

No token? That is fine

The greeting is meant to run without a token: it then behaves like a guest of your instance — unsigned image links and only items that are visible to guests. Adding a token to the config unlocks signed links (useful when something else fetches the URL for you) and items that are hidden from guests.

Configuration

Any of these work; the config file is read by the function on every run:

# ~/.config/j621Greeting/config.fish, or universal variables
set -g J621_BASE https://j621.rainbow-herring.ts.net   # API origin
set -g J621_WEB  https://j621.example.ts.net           # link origin (split deploys)
set -g J621_TOKEN <api token>                          # signed URLs + hidden items
set -g J621_FASTFETCH_CONFIG jake                      # fastfetch config name

J621_TOKEN is optional. The recommended value is a scoped greeting token: open the app, go to Account → Shell tokens (or /tokens), create one and copy the j621r_… key — it only works with /api/random/, so it is safe to keep in this config. It also gives you signed image URLs and access to items that are hidden from guests. Without a token the greeting runs as a guest and sees the public library only.

Rating filters

greeting_mode Rating requested Label
0 e NSFW
1 s SFW
2 (default) q Questionable

Troubleshooting

  • No logo (No image matches those filters.) — the library has no images for that rating; try another mode or add files.
  • No logo (API error) — check J621_BASE, and that the deployment is up (https://<host>/health).
  • No logo (download failed) — the signed URL expired (they last 24 h) or the item was deleted between the two requests; just run it again.
  • The greeting is slow — the API and image fetch have --max-time guards; a slow tailnet link is usually the cause.