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.
88 lines
2.9 KiB
Markdown
88 lines
2.9 KiB
Markdown
# J621
|
|
|
|
Self-hosted media library and e621 archive manager, rebuilt as a **React SPA + Django REST API**.
|
|
|
|
## Structure
|
|
|
|
```
|
|
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
|
|
|
|
### Backend
|
|
|
|
```bash
|
|
cd backend
|
|
source venv/bin/activate
|
|
python manage.py migrate
|
|
python manage.py scan_files # index the watched folder
|
|
python manage.py runserver
|
|
```
|
|
|
|
Copy `.env.example` to `.env` and set `WATCHED_FOLDER` before scanning.
|
|
|
|
### Frontend
|
|
|
|
```bash
|
|
cd frontend
|
|
npm install
|
|
npm run dev # http://localhost:5173, proxies /api to :8000
|
|
```
|
|
|
|
### Production
|
|
|
|
Docker: see [`deploy/`](deploy/README.md) for the two images (SPA on static
|
|
nginx, API on gunicorn), the three compose variants (both / frontend-only /
|
|
backend-only) behind a shared nginx service and a Tailscale sidecar, and the
|
|
public-funnel or tailnet-only serve configs. `deploy/push_*.sh` builds and
|
|
pushes the multi-arch images to the Gitea registry.
|
|
|
|
## Random image endpoint
|
|
|
|
Used by the SPA's Random page and by shell greetings (fish_greeting +
|
|
fastfetch):
|
|
|
|
```bash
|
|
curl -H "Authorization: Token <token>" \
|
|
"https://j621.example.ts.net/api/random/?rating=s,q&fastfetch=1"
|
|
```
|
|
|
|
```json
|
|
{
|
|
"j_id": "J-59",
|
|
"filename": "J-59.jpg",
|
|
"extension": "jpg",
|
|
"rating": "e",
|
|
"url": "https://j621.example.ts.net/api/files/J-59/raw/?sig=…",
|
|
"download_url": "https://j621.example.ts.net/api/files/J-59/raw/?sig=…&download=1",
|
|
"thumbnail_url": "https://j621.example.ts.net/api/files/J-59/thumbnail/?sig=…",
|
|
"fastfetch": true
|
|
}
|
|
```
|
|
|
|
- `rating` — comma separated subset of `s`, `q`, `e` (default: any).
|
|
- `fastfetch=1`, or any request whose User-Agent contains `fastfetch`, limits
|
|
the roll to `png`/`jpg`/`gif` so terminals can display it. Images are the
|
|
only candidates in both modes.
|
|
- `url` is absolute, and signed for authenticated callers, so fastfetch can
|
|
load it without headers. Guests get an unsigned URL and only see
|
|
guest-visible items.
|
|
- `/random` and `/random/` are aliases of `/api/random/` for scripts. Behind
|
|
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
|
|
|
|
Source-available, **non-commercial**: personal and other non-commercial use is
|
|
welcome under the [Jake Labs Non-Commercial Software Licence](LICENSE), which
|
|
requires attribution and keeps derivative works under the same licence.
|
|
Commercial use is not permitted. Third-party dependencies keep their own
|
|
licences (all permissive: MIT, BSD, Apache-2.0, ISC).
|