docs: sync README + SPEC with the shipped reality
Both docs still described the pre-provider-layer single-source app:
- README: anidb-only framing, missing stats page, 'upstream.py is the
ONLY Cloudflare-facing code', and a self-check command that does not
work (plain script execution breaks the providers' relative imports;
the asserts are anidb-specific under the hianime-first default) —
now documents ANI_SOURCE=anidb + the -m form. Dropped the stale
'episode titles are not available' note (Jikan titles shipped).
- SPEC: 'no database' -> SQLite, architecture -> 3 providers, full
endpoint list (intros/searches/events/stats/cdn, DELETE history,
?all=1, {sub}), auth hardening (per-IP budget, X-Aniweb on /login),
tests/run.py -> pytest + ANIWEB_LIVE_TESTS gating, out-of-scope list
(countdown/intro-skip/titles shipped), risks updated for the
fallback layer, milestone 8 pointer.
This commit is contained in:
1 parent
4aca78cab8
commit
0f6bd0a52a
2 files changed
+110
-53
No files matched your search
@@ -1,9 +1,9 @@
|
||||
# ani-web
|
||||
|
||||
Web front-end for anime streaming: search, browse, and stream anime in
|
||||
the browser via anidb.app. Multi-user, with per-user watch history and
|
||||
HLS playback proxied through the backend. Tuned for phone as much as
|
||||
desktop.
|
||||
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.
|
||||
|
||||

|
||||
|
||||
@@ -66,10 +66,11 @@ relative timestamps.
|
||||
|
||||
### Search
|
||||
|
||||
The header search box queries anidb.app and shows results as a poster
|
||||
grid. Your last 8 searches (per user) appear in a dropdown under the
|
||||
box, filter live as you type, and click to re-run. Results open the
|
||||
detail view: synopsis, stats, season tabs, and filler badges.
|
||||
The header search box queries the active source and shows results as a
|
||||
poster grid. Your last 8 searches (per user) appear in a dropdown under
|
||||
the box, filter live as you type, and click to re-run. Results open the
|
||||
detail view: synopsis and season tabs (where the source provides
|
||||
them), plus filler badges.
|
||||
|
||||

|
||||
|
||||
@@ -106,11 +107,20 @@ stall playback.
|
||||
|
||||

|
||||
|
||||
### Stats
|
||||
|
||||
`?stats` (hamburger menu) — watch minutes, episodes started/completed,
|
||||
active days + best streak, sub/dub split, weekday and per-day heatmaps,
|
||||
top-10 shows, top searches. Derived server-side from the position-event
|
||||
stream (`POST /api/events`), 30–365 day windows.
|
||||
|
||||
## Layout
|
||||
|
||||
```
|
||||
server/ FastAPI app (app.py), anidb.app fetchers (upstream.py),
|
||||
accounts (users.py). upstream.py is the ONLY Cloudflare-facing code
|
||||
server/ FastAPI app (app.py), source providers (providers/: hianime,
|
||||
anidb, anikoto) over shared HTTP + dispatch (upstream.py),
|
||||
accounts (users.py). upstream.py + providers/ are the ONLY
|
||||
Cloudflare-facing code
|
||||
static/ front-end: index.html, login.html, app.js, style.css, hls.min.js (vendored)
|
||||
tests/ pytest suite: conftest.py (throwaway server), HTTP + browser tests
|
||||
docs/img/ README screenshots
|
||||
@@ -120,17 +130,21 @@ SPEC.md design + the verified anidb.app data flow
|
||||
|
||||
## Dev notes
|
||||
|
||||
- anidb.app is behind Cloudflare; all upstream requests use
|
||||
`curl_cffi` Chrome TLS impersonation. If that ever stops working,
|
||||
everything is isolated in `server/upstream.py`.
|
||||
- The upstream sites sit behind Cloudflare; all upstream requests use
|
||||
`curl_cffi` Chrome TLS impersonation. Sources are ordered by
|
||||
`ANI_SOURCE` (default `hianime,anidb,anikoto`) — a dead one falls
|
||||
through to the next. All upstream-facing code is isolated in
|
||||
`server/upstream.py` + `server/providers/`.
|
||||
- The video CDN sends no CORS headers, so playback goes through the
|
||||
backend HLS proxy (`/stream/{token}`), which rewrites playlist URIs.
|
||||
- `.venv/bin/python server/upstream.py` runs a self-check of the
|
||||
fetchers (search → details → episodes → dub stream for Chainsaw Man).
|
||||
- A background probe fetches 64KB from the CDN every 3 min and logs
|
||||
state flips to `server.log`; `GET /api/cdn` (public) returns the
|
||||
latest throughput + ~1h history. Use it to check if "playback
|
||||
broken" is the CDN again.
|
||||
- `ANI_SOURCE=anidb .venv/bin/python -m server.upstream` runs a live
|
||||
self-check of the anidb fetchers (search → details → episodes → dub
|
||||
stream). Must be the `-m` form — plain script execution breaks the
|
||||
providers' relative imports.
|
||||
- A background probe fetches 64KB from the CDN (and checks the origin
|
||||
site) every 3 min and logs state flips to `server.log`; `GET
|
||||
/api/cdn` (public) returns the latest throughput + ~1h history +
|
||||
origin state. Use it to check if "playback broken" is the CDN again.
|
||||
- The front-end is version-pinned: the server injects the git SHA as the
|
||||
`?v=` cache-bust on `app.js`/`style.css` at startup (index.html itself
|
||||
is `no-store`), so a restart is a cache bump — nothing to hand-bump.
|
||||
@@ -147,6 +161,3 @@ SPEC.md design + the verified anidb.app data flow
|
||||
and deterministic; the Playwright browser tests scrape and play LIVE
|
||||
upstream content, so they are opt-in: `ANIWEB_LIVE_TESTS=1
|
||||
.venv/bin/pytest tests/ -q` (needs playwright chromium installed).
|
||||
- Episode titles are not available: anidb's episode API only returns
|
||||
`{id, number, number2, filler}`. Adding titles needs a free
|
||||
MyAnimeList API key.
|
||||
Reference in new issue
Block a user