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>