soulsync/api/video
BoulderBadgeDad 3af3a1cd24 video downloads Phase C: auto-retry + alternate-query requery
When a grabbed release fails (transfer error / peer-cancel / never lands), the engine
now retries instead of giving up — the music-style depth:
- Grab stores the OTHER accepted results as a retry pool + the search context (schema
  v16: candidates / search_ctx / tried_queries / tried_files / attempts).
- core/video/retry.py (pure, tested): plan_retry() → try the next-best candidate; when
  the pool is dry, next_query() generates an ALTERNATE query (movie: drop the year; TV:
  numbering variants) to re-search; budget MAX_ATTEMPTS=6. merge_candidates dedupes
  against already-tried releases.
- Monitor: on failure, _fail_or_retry hops to the next candidate inline; if none, flips
  the row to a new 'searching' state and a background requery thread re-searches the
  alternate query, evaluates against the profile, and starts the best fresh hit — or
  marks failed once truly exhausted. 'searching' rows are owned by their thread.
- Page: 'Searching' status (Trying another release…) + a 'Nx' attempt badge.
16 tests (retry engine + candidate-retry transition); ruff clean on touched files.
2026-06-19 17:12:44 -07:00
..
__init__.py video downloads (phase 1): video-specific download + transfer folders 2026-06-19 00:04:27 -07:00
calendar.py Video Calendar: week navigation + owned/missing filter 2026-06-15 19:32:57 -07:00
dashboard.py Video: scope library reads to the active server (Plex/Jellyfin don't commingle) 2026-06-15 18:45:28 -07:00
detail.py video: episode detail expand (guest stars + bigger still) 2026-06-15 13:20:15 -07:00
discover.py Discover: streaming-provider filter + infinite scroll + a11y polish 2026-06-16 14:55:13 -07:00
downloads.py video downloads Phase C: auto-retry + alternate-query requery 2026-06-19 17:12:44 -07:00
enrichment.py video enrichment: add Wikidata (official website link) — full parity, completes the batch 2026-06-18 23:13:22 -07:00
libraries.py Video side: own server connection (Plex/Jellyfin), music-style picker, isolated 2026-06-15 16:42:22 -07:00
library.py Video: scope library reads to the active server (Plex/Jellyfin don't commingle) 2026-06-15 18:45:28 -07:00
poster.py Search avatars: proxy with a UA + graceful initials fallback 2026-06-17 09:57:42 -07:00
scan.py video Tools: match music Database Updater (stats, cancel, real progress) 2026-06-14 07:35:57 -07:00
search.py video: smart multi-layer back button + next-level search/person 2026-06-15 08:30:17 -07:00
watchlist.py Video watchlist: richer show cards (status pill + ep count) + sort dropdown 2026-06-16 10:19:13 -07:00
wishlist.py Wishlist: episode synopsis + clickable cards + FIFO/newest sort 2026-06-16 18:21:26 -07:00
youtube.py video enrichment: add DeArrow (crowd-sourced YouTube titles) — full parity 2026-06-18 23:09:02 -07:00