This commit is contained in:
@@ -59,48 +59,59 @@ Target deployment is an Unraid server using a single Docker container with a sim
|
||||
|
||||
- Entities:
|
||||
- **Show**: id, display name, search/RSS query, quality filter, fansub group, active flag.
|
||||
- **Episode**: id, show_id, episode_number (string or parsed integer), nyaa_torrent_id, title, status (`pending`, `downloaded_auto`, `downloaded_manual`), torrent_url, created_at, downloaded_at.
|
||||
- **Episode**: id, show_id, episode_code (string or parsed integer), nyaa_torrent_id, title, status (`pending`, `downloaded_auto`, `downloaded_manual`, `failed`), torrent_url, download_error, file_path, attempts, created_at, downloaded_at.
|
||||
- Behavior:
|
||||
- Adding a show:
|
||||
- Run an immediate search.
|
||||
- Populate existing episodes in DB as `pending` (no download) to let the user backfill by manually checking already downloaded ones.
|
||||
- Removing a show:
|
||||
- Leave episodes in DB but mark show as inactive (no further polling).
|
||||
- Run an immediate search and ingest existing feed items, then auto-download from the oldest episode upward (batch releases excluded).
|
||||
- Pausing a show:
|
||||
- Toggle the active flag off — episodes are preserved, polling stops.
|
||||
- Deleting a show:
|
||||
- Permanently remove the show and cascade-delete its episodes. `.torrent` files already written to disk are left in place.
|
||||
- Manual check:
|
||||
- User can mark an episode as already downloaded (`downloaded_manual`), no torrent action taken.
|
||||
- User can mark an episode as already downloaded (`downloaded_manual`), no torrent action taken; or reset a downloaded/failed episode back to `pending`.
|
||||
|
||||
|
||||
### 3. Auto-Download Logic
|
||||
|
||||
- Periodic job (e.g. every 5–15 minutes, configurable):
|
||||
- Periodic job (configurable interval, default 15 min). A re-entrancy guard
|
||||
prevents overlapping runs (a slow poll or a manual "Poll Now" won't double up):
|
||||
- For each active show:
|
||||
- Query Nyaa using its stored RSS/search parameters.[^4][^3][^6]
|
||||
- Determine the “next” episode:
|
||||
- Prefer simplest rule: highest episode number not yet marked downloaded.
|
||||
- Guard against batch torrents by using size or title pattern heuristics (e.g. skip titles containing “Batch”).
|
||||
- If the next episode’s torrent is not yet in DB:
|
||||
- Create an Episode record with status `downloaded_auto`.
|
||||
- Download the `.torrent` file (NOT the media itself) into the mapped host directory.
|
||||
- Filename suggestion: `<show-slug>-ep<episode>-<torrent-id>.torrent`.
|
||||
- Do not attempt to control or integrate directly with a torrent client (scope is “download the .torrent file” only).
|
||||
- Skip batch torrents via title heuristics (titles containing "Batch",
|
||||
"Complete", "Vol.", or an episode range).
|
||||
- Process every feed item not already downloaded (oldest episode first),
|
||||
plus any previously-`failed` episodes — including ones that have scrolled
|
||||
off the current feed, retried from their stored `torrent_url`.
|
||||
- For each candidate:
|
||||
- Insert a `pending` Episode record if new.
|
||||
- Download the `.torrent` file (NOT the media itself) into the mapped
|
||||
host directory as `<show-slug>-ep<episode>-<torrent-id>.torrent`.
|
||||
- On success, set status `downloaded_auto` and record the file path; on
|
||||
failure, set status `failed`, store the error, and increment `attempts`.
|
||||
- Stop retrying an episode once it reaches the attempt cap (5) so a
|
||||
permanently-dead torrent isn't re-attempted forever.
|
||||
- Do not attempt to control or integrate directly with a torrent client (scope is "download the .torrent file" only).
|
||||
|
||||
|
||||
### 4. Web UI
|
||||
|
||||
- Views:
|
||||
- **Shows list**:
|
||||
- Add show (form: name, search query, quality, group).
|
||||
- Toggle active/inactive.
|
||||
- Add show via a Nyaa search-first modal; clicking a result pre-fills the form.
|
||||
- Pause/resume polling per show.
|
||||
- Quick link to show detail.
|
||||
- **Show detail**:
|
||||
- Stats summary (total / pending / auto / manual / failed) and a failed-downloads panel with error details.
|
||||
- Table of episodes: episode number/title, Nyaa ID, status, timestamps.
|
||||
- Controls:
|
||||
- Manually mark individual episodes as downloaded.
|
||||
- Bulk “mark previous episodes as downloaded” helper (e.g. “mark up to episode N”).
|
||||
- Manually mark individual episodes as downloaded, or reset them to pending (with confirmation).
|
||||
- Bulk “mark up to episode N as downloaded” helper.
|
||||
- "Poll Now" to trigger an immediate check; Pause/Resume; Delete (with confirmation).
|
||||
- **Settings**:
|
||||
- Poll interval.
|
||||
- Default quality / sub group preferences.
|
||||
- Torrent download directory (read-only display; actual path comes from environment/volume).
|
||||
- A health-warning banner appears on every page when the torrent output directory isn't writable.
|
||||
- UX constraints:
|
||||
- Keep it extremely simple; focus is internal tool.
|
||||
- Assume a single user instance behind LAN.
|
||||
@@ -140,14 +151,18 @@ Target deployment is an Unraid server using a single Docker container with a sim
|
||||
- `created_at`, `updated_at`
|
||||
- `episodes`
|
||||
- `id` (PK)
|
||||
- `show_id` (FK → shows.id)
|
||||
- `show_id` (FK → shows.id, `ON DELETE CASCADE`)
|
||||
- `episode_code` (string, e.g. “S01E03” or “03”)
|
||||
- `title` (string)
|
||||
- `torrent_id` (string, Nyaa ID)
|
||||
- `torrent_url` (string)
|
||||
- `status` (enum: `pending`, `downloaded_auto`, `downloaded_manual`)
|
||||
- `status` (enum: `pending`, `downloaded_auto`, `downloaded_manual`, `failed`)
|
||||
- `download_error` (string, nullable — last failure message)
|
||||
- `file_path` (string, nullable — saved `.torrent` path)
|
||||
- `attempts` (integer, default 0 — failed download count, capped at 5)
|
||||
- `downloaded_at` (datetime, nullable)
|
||||
- `created_at`, `updated_at`
|
||||
- `UNIQUE(show_id, torrent_id)`
|
||||
|
||||
***
|
||||
|
||||
|
||||
Reference in New Issue
Block a user