Commit Graph
6 Commits
Author SHA1 Message Date
jozamudi 0613cf7e27 Intro skip: MAL timings via keyless Jikan + player button
- upstream: _intros(mal_id) -> per-episode {start,length} (seconds),
  30d TTL cache; Jikan is down or show uncovered -> [] (no button)
- app: GET /api/intros/{mal_id}, never errors into the player
- player: 'skip intro' pill appears while currentTime is inside the
  intro window (+8s grace); click seeks past; reappears if rewound.
  Ep-1 intros are often missing in MAL data, so falls back to the
  show's first known timing (usually identical across eps)
- test: _parse_intros unit test (Jikan itself is 504ing right now,
  live path verified by hand: endpoint returns [] cleanly)
2026-08-30 21:01:24 +00:00
jozamudi 0fd06f036a Playback: retry flaky upstream, faster proxy fail, cache /stream in browser
- upstream._get: one 300ms retry on transient errors (CF 403/503, 429,
  5xx); 404 stays final. Fixes the 502 cluster that hls.js couldn't
  recover from (fragLoadTimeOut x3 in error log)
- /stream: upstream timeout 12s < hls.js fragLoadingTimeOut (20s), so a
  hung segment 502s first and hls.js retries instead of fatal-timing-out
- /stream responses: Cache-Control public max-age=86400 (VOD + token is
  the exact upstream URL => immutable); re-opens/re-seeks skip the proxy
- /api/stream: drop unused qualities (frontend never read it; saved a
  ~0.2s cold upstream round-trip per episode)
- app.js/style.css: max-age=300 instead of no-store
- test_history_page_and_delete: stale selector (home redesign removed
  the 'view all' link; use 'history ->')
2026-08-30 17:23:57 +00:00
jozamudi aae5857dba harden: stream-token host allowlist (SSRF), CSRF header on mutating routes, atomic JSON writes
- /stream/{token}: tokens are plain base64; allowlist https://hls.anidb.app
  so a session can't use the proxy for arbitrary URLs (new test)
- X-Aniweb:1 required on POST/DELETE except /login — SameSite=Lax is
  still sent on cross-site form POSTs, which could hit /account/delete
  (new test; SPA + tests send the header)
- tmp+os.replace writes for users/history/searches: a crash mid-write
  could corrupt the JSON -> load() returned {} -> silent data loss
- resume positions now read from full history (?all=1), not top-5
- pagehide bound once; savePos reads currentEp (no stale closures)
- account delete also removes the searches file; episodes TTL 5m
- ani-web.service: supervised restart (not installed; see header)
- gitignore pi-session dumps + .pytest_cache
2026-08-23 23:22:09 +00:00
jozamudi 19e878800c perf: keep-alive upstream sessions, TTL cache on upstream data, /stream LRU, cache hls.min.js
- shared thread-local curl_cffi sessions (no TLS handshake per call)
- in-memory TTL cache: search 5min, details/episodes/languages/
  playlist-URLs 1h; api_stream retries once with a cold cache on 502
  (recovers rotated playlist URLs)
- /stream LRU (24 entries) serves re-seeks and playlist re-fetches from memory
- hls.min.js: Cache-Control public max-age=30d (was no-store -> 500KB
  re-download per page load on mobile)

Measured (click->play chain, cold -> warm):
  search    0.45s -> 0.00s
  detail    0.46s -> 0.00s
  episodes  0.40s -> 0.00s
  stream    1.06s -> 0.00s
  m3u8 x2   0.64s -> 0.00s
  segment   0.20s -> 0.00s
2026-08-19 17:46:17 +00:00
jozamudi 2efb537edc home polish: continue-watching hero, progress bars, posters, time-ago
- showHome(): most recent entry renders as a hero card (poster,
  episode/lang/position, progress bar, Resume); the rest become
  mini poster cards with progress + relative timestamp
- history entries now persist dur (video.duration) and poster;
  /api/anime returns poster (parsed from the details page)
- old entries without dur render without a bar (backward compatible)
- browser test asserts the seeded entry, not a section header that
  only existed via a cross-test side effect
2026-08-19 17:01:04 +00:00
jozamudi 2c203990bc move server code into server/, update docs
- app.py + upstream.py -> server/ (relative import, __init__.py)
- static/ resolved relative to repo root, works from any CWD
- watch history migrated to server/data/history.json
- README.md: quick start, features, layout, dev notes
- SPEC.md: marked implemented, updated endpoints/run/deviations
- ignore *.tar.gz (local curl-impersonate download at repo root)
2026-08-19 15:33:31 +00:00