popback#
Rate TMDB movies in a TUI, backfill ratings to popfeed. Resumes where you left off -- close it, come back, keep rating.
Why#
Popfeed's own backfill is unreliable: duplicates, broken pagination, missing ratings. This reads your CSV of rated movies and backfills one entry at a time with proper error tracking.
Usage#
export TMDB_API_KEY=...
popback viewed [output.csv]
export TMDB_API_KEY=... POPFEED_AUTH_TOKEN=...
popback backfill [input.csv]
Resume is automatic: viewed skips already-rated movies from the CSV.
backfill skips entries already posted to popfeed.
How it works#
viewed#
Streaming TUI: movies arrive from TMDB one page at a time (~20). A
background fetch runs while you rate so the next movie is always ready.
Press b to go back and re-rate. Results write to CSV on exit.
TMDB pages --> [pre-fetch buffer] --> movie at cursor --> rate/skip --> CSV
backfill#
Reads CSV, posts each entry to popfeed's internal API two-step: a review (rating + metadata) and an experience (watched/seen timestamp). Pure request builders are tested separately from HTTP I/O.
popfeed internal API#
No public docs. Endpoints reverse-engineered from browser devtools:
POST /api/rest/v1/reviewPOST /api/rest/v1/experience
Auth: JWT token from browser session, sent as cookie.
Persistence#
CSV format: id,rating,seen,skip. Human-readable, append-only. The store
interface is mocked in tests so the write path is tested without disk.
Design#
- Sandwich pattern: impure gather (CSV, TMDB) -> pure logic (build requests, dedup) -> impure commit (write CSV, post HTTP).
- Streaming TUI: no batch cap. Async pre-fetch hides network latency.
- The CSV is the skip set. No in-memory state across restarts.
- slog to stderr for ops, fmt to stdout for UX. No log noise.
- Table-driven tests, no shared mutable state.
Environment#
TMDB_API_KEY TMDB key or JWT bearer token
POPFEED_AUTH_TOKEN Popfeed session JWT (for backfill)