Files
ani-web/README.md
T
jozamudi 778bf2bfc1 status: consolidate CDN/upstream status into the header pill + tap panel
- pill label now shows KB/s when degraded ('cdn 23 KB/s'); tap opens a
  panel (replaces the transient toast) with origin/CDN state, KB/s,
  a sparkline of the ~1h /api/cdn hist, and last-updated age
- 60s poll while the page is visible (was: load/play/failure only)
- playback failure overlay appends CDN context when degraded/down
- buffer gauge + spinner untouched: client buffer state, not CDN state
- server unchanged: /api/cdn already returned everything
- tests: 3 hermetic browser tests (mocked /api/cdn via page.route —
  the throwaway server's probe runs live upstream, so its data is
  mocked out of the assertions); 37 passed
- docs: README + SPEC synced
2026-09-20 23:53:47 +00:00

95 lines
3.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ani-web
Web front-end for anime streaming: search, browse, and stream anime in
the browser (hianime.at primary; anidb.app and anikototv.to as
fallbacks). Multi-user, with per-user watch history and HLS playback
proxied through the backend. Tuned for phone as much as desktop.
![login](docs/img/login.png)
## Quick start
```sh
uv venv .venv
uv pip install --python .venv/bin/python -r requirements.txt
.venv/bin/python -m server.users add <you> # create your account (one-time)
./run.sh
```
Open it through your HTTPS proxy (or <http://localhost:8321> from the
host itself — browsers treat localhost as trusted). `run.sh` restarts
cleanly if the server is already running; logs go to `server.log`.
Accounts are CLI-created only (no self-signup):
```sh
.venv/bin/python -m server.users add <name> # add user (prompted password)
.venv/bin/python -m server.users rm <name> # remove user + their history
.venv/bin/python -m server.users list # list users
```
Passwords are PBKDF2-SHA256 in `server/data/aniweb.db` (SQLite, 0600);
sessions are signed 30-day `HttpOnly` `SameSite=Lax` cookies, `Secure`
via `run.sh`, so remote plain-HTTP can't hold a session — the HTTPS
proxy is the way in. See [SPEC.md](SPEC.md) for the rest.
## Features
- **History** — server-side and per-user: a new device picks up your
exact watch state after login. Entries show poster, progress, and a
per-entry delete.
![history](docs/img/history.png)
- **Home** — continue-watching hero (poster, position, Resume) plus a
recently-played grid with progress bars.
![home](docs/img/home.png)
- **Search** — poster-grid results from the active source; your last 8
searches (per user) in a live-filtering dropdown. Results open the
detail view (synopsis, season tabs, filler badges).
![search](docs/img/search.png)
- **Player** — resume at the saved position, skip intro (MAL timings),
dub/sub toggle, playback speed, hide fillers, auto-next with a
5-second countdown, ✓ on completed episodes. Playback goes through a
backend HLS proxy (the CDN sends no CORS headers); segments are
pulled across parallel byte-range lanes so a slow connection doesn't
stall.
![detail](docs/img/detail.png)
- **Status** — the header pill shows upstream/CDN health (dots +
label); tap opens a panel with detail + the ~1h throughput trend.
A failure overlay names the CDN when it's the likely culprit.
- **Stats** — `?stats`: watch minutes, episodes, streaks, sub/dub
split, weekday/per-day heatmaps, top-10 shows, top searches
(30–365 day windows).
## Layout
```
server/ FastAPI app (app.py), source providers (providers/: hianime,
anidb, anikoto) over shared HTTP + dispatch (upstream.py)
static/ front-end: index.html, login.html, app.js, hls.min.js (vendored)
tests/ pytest suite: hermetic default, live browser e2e opt-in
docs/img/ README screenshots
run.sh launch/restart the server (sets ANIWEB_SECURE=1)
SPEC.md design, verified anidb.app data flow, security + runbook notes
```
## Dev
- `.venv/bin/pytest tests/ -q` — hermetic suite against a throwaway
server (never touches real data). Live-upstream browser e2e is
opt-in: `ANIWEB_LIVE_TESTS=1 .venv/bin/pytest tests/ -q`
(needs playwright chromium).
- `ANI_SOURCE=anidb .venv/bin/python -m server.upstream` — live
self-check of the anidb fetchers (must be the `-m` form; plain
script execution breaks the providers' relative imports).
- Everything else (Cloudflare/impersonation, HLS proxy, CDN probe,
auth hardening, cache-busting): [SPEC.md](SPEC.md).