Problems fixed:
- No User-Agent header: Nyaa returns HTML/redirect for bot requests;
add browser-like UA + Accept + Referer + redirect:follow
- Silent failures: downloads failed with no visible feedback; add
'failed' episode status + download_error column to store the error
- No retry: failed/pending episodes were skipped forever on subsequent
polls; scheduler now retries them via ON CONFLICT upsert
- Content validation: check response starts with 'd' (bencoded dict)
to catch HTML error pages masquerading as torrents
Also adds:
- /api/health write-test for torrent dir (shows ⚠ banner if not writable)
- /api/poll endpoint for manual immediate poll trigger
- '↻ Poll Now' button in ShowDetailPage
- Failed episode badge with hover tooltip showing the error message
- Migration to widen status CHECK constraint to include 'failed'
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
fast-xml-parser returns elements with attributes (like <guid isPermaLink>)
as { "@_isPermaLink": "true", "#text": "url" } — calling String() on that
gives "[object Object]", making every torrent_id identical and causing the
UNIQUE constraint to drop all but the first episode insert.
Fixes:
- Add textOf() helper that extracts #text from attribute-bearing nodes
- Apply textOf() to guid, link, title, category, size, pubDate fields
- Add isArray config so a single-result feed still returns an array
- Use <link> directly as torrent_url (Nyaa provides the .torrent URL there)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When a show is added, ingest the Nyaa feed, sort episodes oldest→newest
(ep 1 first), and auto-download them all in order rather than leaving
them as pending. Ongoing polls continue downloading new episodes the
same way.
Extracted a shared downloadItems() helper from the scheduler so both
the initial ingest and the cron poll use identical insert→download→
status-update logic.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Node.js + TypeScript + Express backend using built-in node:sqlite
- React + Vite frontend with dark-themed UI
- Nyaa.si RSS polling via fast-xml-parser
- Watch list with show/episode CRUD and status tracking
- Auto-download scheduler with node-cron (configurable interval)
- .torrent file downloader with batch-release filtering
- Settings page for poll interval and quality defaults
- Dockerfile and docker-compose for Unraid deployment
- SQLite DB with migrations (shows, episodes, settings tables)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>