Add CLAUDE.md documenting architecture and deploy pipeline
All checks were successful
Deploy / deploy (push) Successful in 1m54s
All checks were successful
Deploy / deploy (push) Successful in 1m54s
This commit is contained in:
parent
5baba883f1
commit
9804283396
1 changed files with 82 additions and 0 deletions
82
CLAUDE.md
Normal file
82
CLAUDE.md
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
# Arr Summary (Greendale)
|
||||
|
||||
Flask dashboard aggregating status from the user's self-hosted media stack
|
||||
— Sonarr, Radarr, SABnzbd, Tautulli, Prowlarr, Ombi — plus Unraid array
|
||||
stats and a Rotten Tomatoes "what's popular that I don't have yet" feed.
|
||||
Branded "Greendale Media Centre." Runs as one Docker container on the
|
||||
user's Unraid home server. Server-side project directory is named
|
||||
`greendale`; the container/repo are named `arr-summary`.
|
||||
|
||||
## Architecture
|
||||
|
||||
- **`app.py`** — single Flask app, session-based single-shared-password
|
||||
auth (`LOGIN_PASSWORD` env var, hashed comparison; can be changed at
|
||||
runtime via `/api/change-password`, persisted to `settings.json`).
|
||||
Supports running behind a reverse-proxy subpath via `SCRIPT_NAME` +
|
||||
`ScriptNameMiddleware` + `ProxyFix` (currently deployed at domain root,
|
||||
not a subpath, but the capability exists — see `nginx/` configs for
|
||||
both).
|
||||
- Per-service client functions (`sonarr_get`, `radarr_get`,
|
||||
`sabnzbd_get`, `tautulli_get`, `prowlarr_get`, `ombi_get`) each call
|
||||
that service's REST API directly with its API key from env vars.
|
||||
- The dashboard route (`/`) fetches all services **in parallel** via
|
||||
`ThreadPoolExecutor` with a hard 5-second wall-clock deadline — any
|
||||
slow/unreachable service degrades to an error dict rather than
|
||||
blocking the whole page. This matters for remote/cellular access.
|
||||
- Aggressive per-service caching with different TTLs tuned to how often
|
||||
each actually changes: Sonarr/Radarr library lists 5 min (the biggest
|
||||
latency cost — full Radarr list is ~4.4MB), Tautulli stats 2 min,
|
||||
SABnzbd history 10 min, Ombi requests 4 hours, Rotten Tomatoes scrapes
|
||||
4 hours. Active streams (Tautulli) and the SABnzbd queue are always
|
||||
fetched live, never cached — those need to be current-second accurate.
|
||||
- Rotten Tomatoes / IMDB are scraped directly (`requests` +
|
||||
`BeautifulSoup`, JSON-LD parsing), not via an official API — brittle
|
||||
to upstream HTML changes by nature.
|
||||
- **`templates/`** — Jinja2 templates (`dashboard.html`, `login.html`,
|
||||
`settings.html`); duplicated at the top level too (`dashboard.html` etc.
|
||||
outside `templates/`) — appears to be a leftover from an earlier project
|
||||
layout or the `export-to-unraid.sh` tooling. Left as-is rather than
|
||||
restructured without confirming with the user first.
|
||||
- **`export-to-unraid.sh`** — a pre-existing standalone deploy script
|
||||
(build image locally → tarball → rsync + `docker load` over SSH) that
|
||||
predates the Forgejo pipeline below. Still present, not removed, but the
|
||||
Forgejo pipeline is now the primary deploy path going forward.
|
||||
- **`nginx/`** — reference nginx location-block snippets for subdomain vs.
|
||||
subpath reverse-proxy setups; not actually consumed by the app at
|
||||
runtime (NPM handles proxying in practice), kept as documentation/config
|
||||
reference.
|
||||
|
||||
## Local development
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
python3 app.py
|
||||
```
|
||||
|
||||
Runs on port 5000. Needs the various `*_API_KEY` and `*_HOST`/`ARR_HOST`
|
||||
env vars (see `.env.example`) to reach real services — without them,
|
||||
dashboard cards degrade to "error" status individually rather than
|
||||
crashing the page.
|
||||
|
||||
## Deployment
|
||||
|
||||
**Target:** Unraid server, container path `/mnt/user/appdata/greendale`
|
||||
(note the directory name differs from the container/repo name), built from
|
||||
`Dockerfile`/`docker-compose.yml` in this repo. Container name
|
||||
`arr-summary`, port `5055` (overridable via `HOST_PORT`) → container port
|
||||
`5000`.
|
||||
|
||||
**Deploy mechanism: Forgejo push-to-deploy**, same pattern as the other
|
||||
three projects on this box — see `card-grader`'s `CLAUDE.md` for the full
|
||||
pipeline mechanics. Push to `main` on the `forgejo` remote
|
||||
(`https://git.hippofam.com/ninja_hippo/arr-summary.git`) triggers
|
||||
`.forgejo/workflows/deploy.yml`, which syncs into
|
||||
`/mnt/user/appdata/greendale` (excluding `.git`, `.env`) and runs
|
||||
`docker compose up -d --build`.
|
||||
|
||||
**Persistent state, never touched by deploys:** `.env` holds every API key
|
||||
and `LOGIN_PASSWORD` — this project was already doing this correctly
|
||||
before the Forgejo migration (compose file uses `${VAR}` substitution from
|
||||
`.env`, no hardcoded secrets), unlike `n64-tracker` which needed fixing.
|
||||
`settings.json` (timezone, theme, changed login password) also persists
|
||||
server-side outside git.
|
||||
Loading…
Add table
Add a link
Reference in a new issue