Delete files and untrack, for one season or one episode #174

Closed
opened 2026-08-24 16:13:06 +01:00 by naps62-yolo · 0 comments
Owner

There is no way to remove a downloaded season or episode. DELETE /api/movies/{id}
and DELETE /api/series/{id} exist and both unlink files, but below the series
there is nothing.

Depends on: #171

Add one action per level, doing both halves at once:

  • DELETE /api/series/{series_id}/seasons/{number}/files
  • DELETE /api/episodes/{episode_id}/files

Each unlinks the imported files for its scope, removes the matching media_files
rows, and clears wanted on the episodes it covers. One call, both effects — the
operator asked for removal and un-wanting as a single action, not two controls to
remember to use together.

Seasons and episodes are not deleted as rows. They come from TMDB and the next
metadata refresh would recreate them. The metadata stays; only files and intent go.
This is the difference from DELETE /api/series/{id}, which does delete its rows.

Reuse what the series delete already does rather than writing a second unlink path:
remove_library_files for the disk side, and the media_files cleanup it is
paired with — note that deletion there is explicit because media_files.path is
UNIQUE with a polymorphic owner and nothing cascades. The same reasoning applies
here. The wanted clear should go through whatever #171 lands for §4.1, so both
paths agree on what clearing intent means.

Returns 204 on success, 404 for an unknown season or episode. Removing a season
with nothing on disk is not an error — it still clears intent.

Out of scope: the torrent keeps seeding, exactly as the movie removal path already
warns. Nothing here touches Transmission.

Tests: files gone from disk and from media_files; wanted cleared across the
season; an episode-level call leaves its siblings alone; a scope with no files
succeeds. Regenerate and commit .sqlx/.

There is no way to remove a downloaded season or episode. `DELETE /api/movies/{id}` and `DELETE /api/series/{id}` exist and both unlink files, but below the series there is nothing. Depends on: #171 Add one action per level, doing both halves at once: - `DELETE /api/series/{series_id}/seasons/{number}/files` - `DELETE /api/episodes/{episode_id}/files` Each unlinks the imported files for its scope, removes the matching `media_files` rows, and clears `wanted` on the episodes it covers. One call, both effects — the operator asked for removal and un-wanting as a single action, not two controls to remember to use together. **Seasons and episodes are not deleted as rows.** They come from TMDB and the next metadata refresh would recreate them. The metadata stays; only files and intent go. This is the difference from `DELETE /api/series/{id}`, which does delete its rows. Reuse what the series delete already does rather than writing a second unlink path: `remove_library_files` for the disk side, and the `media_files` cleanup it is paired with — note that deletion there is explicit because `media_files.path` is UNIQUE with a polymorphic owner and nothing cascades. The same reasoning applies here. The `wanted` clear should go through whatever #171 lands for §4.1, so both paths agree on what clearing intent means. Returns 204 on success, 404 for an unknown season or episode. Removing a season with nothing on disk is not an error — it still clears intent. Out of scope: the torrent keeps seeding, exactly as the movie removal path already warns. Nothing here touches Transmission. Tests: files gone from disk and from `media_files`; `wanted` cleared across the season; an episode-level call leaves its siblings alone; a scope with no files succeeds. Regenerate and commit `.sqlx/`.
naps62-yolo added this to the Removal and navigation milestone 2026-08-24 16:13:06 +01:00
naps62-yolo added the area/apiphase/6-tvdifficulty/moderatetype/feature labels 2026-08-24 16:13:06 +01:00
naps62-yolo added a new dependency 2026-08-24 16:13:22 +01:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Reference: yolo/arr#174