shemanaev / jellyfin-plugin-media-cleaner

Automatically delete played media files after specified amount of time.
MIT License
71 stars 1 forks source link

[Bug]: Entire season/series folders are deleted when the last episode expires #35

Closed TheSpyder closed 7 months ago

TheSpyder commented 8 months ago

What happened?

I have started using ytdl-sub which keeps the subscription archive file in the series folder where it downloads to. Some of the last episodes from a channel were deleted this morning, and the entire series folder is gone so now it's redownloading the channel as a new subscription. I would like to have the series folder retained (perhaps the season too but I'm less concerned about that).

I'm going to look at the ytdl-sub options to see if it can keep the subscription details somewhere else, but thought I'd come here first to see if there was some way media cleaner could change it's behaviour.

This doesn't happen when I manually delete so something is different about how media cleaner deletes episodes. Here's the jellyfin log from one of the channels where this happened:

[2024-01-08 20:16:57.189 +00:00] [INF] [103] MediaCleaner.MediaCleanupTask: ("Episode") ""2023-12-29 - The step-by-step, mechanical logic of old pinball machines"" will be deleted because expired for: "spyder (01/06/2024 02:42:37)"
[2024-01-08 20:16:57.206 +00:00] [INF] [103] Emby.Server.Implementations.Library.LibraryManager: Removing item, Type: "Episode", Name: "2023-12-29 - The step-by-step, mechanical logic of old pinball machines", Path: "/media/youtube/andy/tv/Technology Connections/Season 2023/s2023.e122901 - The step-by-step, mechanical logic of old pinball machines.webm", Id: 7a0badaa-93ae-9e4d-02dc-a665e67d377f
[2024-01-08 20:16:57.222 +00:00] [INF] [103] Emby.Server.Implementations.Library.LibraryManager: Deleting item path, Type: "Episode", Name: "2023-12-29 - The step-by-step, mechanical logic of old pinball machines", Path: "/media/youtube/andy/tv/Technology Connections/Season 2023/s2023.e122901 - The step-by-step, mechanical logic of old pinball machines.webm", Id: 7a0badaa-93ae-9e4d-02dc-a665e67d377f
[2024-01-08 20:16:57.244 +00:00] [INF] [103] Emby.Server.Implementations.Library.LibraryManager: Deleting item path, Type: "Episode", Name: "2023-12-29 - The step-by-step, mechanical logic of old pinball machines", Path: "/media/youtube/andy/tv/Technology Connections/Season 2023/s2023.e122901 - The step-by-step, mechanical logic of old pinball machines-thumb.jpg", Id: 7a0badaa-93ae-9e4d-02dc-a665e67d377f
[2024-01-08 20:16:57.244 +00:00] [INF] [103] Emby.Server.Implementations.Library.LibraryManager: Deleting item path, Type: "Episode", Name: "2023-12-29 - The step-by-step, mechanical logic of old pinball machines", Path: "/media/youtube/andy/tv/Technology Connections/Season 2023/s2023.e122901 - The step-by-step, mechanical logic of old pinball machines.nfo", Id: 7a0badaa-93ae-9e4d-02dc-a665e67d377f
[2024-01-08 20:16:57.349 +00:00] [INF] [103] Emby.Server.Implementations.Library.LibraryManager: Removing item, Type: "Season", Name: "Season 2023", Path: "/media/youtube/andy/tv/Technology Connections/Season 2023", Id: 194e5d41-4a9c-9070-d20a-37bb3c5887e0
[2024-01-08 20:16:57.366 +00:00] [INF] [103] Emby.Server.Implementations.Library.LibraryManager: Deleting item path, Type: "Season", Name: "Season 2023", Path: "/media/youtube/andy/tv/Technology Connections/Season 2023", Id: 194e5d41-4a9c-9070-d20a-37bb3c5887e0
[2024-01-08 20:16:57.451 +00:00] [INF] [103] Emby.Server.Implementations.Library.LibraryManager: Removing item, Type: "Series", Name: "Technology Connections", Path: "/media/youtube/andy/tv/Technology Connections", Id: 8a433fcf-2113-96de-6246-a4ec2e08b86a
[2024-01-08 20:16:57.454 +00:00] [INF] [103] Emby.Server.Implementations.Library.LibraryManager: Deleting item path, Type: "Series", Name: "Technology Connections", Path: "/media/youtube/andy/tv/Technology Connections", Id: 8a433fcf-2113-96de-6246-a4ec2e08b86a

And later when I deleted the redownloaded file manually:

[2024-01-09 02:38:39.151 +00:00] [INF] [110] Emby.Server.Implementations.Library.LibraryManager: Removing item, Type: "Episode", Name: "2023-12-29 - The step-by-step, mechanical logic of old pinball machines", Path: "/media/youtube/andy/tv/Technology Connections/Season 2023/s2023.e122901 - The step-by-step, mechanical logic of old pinball machines.webm", Id: 7a0badaa-93ae-9e4d-02dc-a665e67d377f
[2024-01-09 02:38:39.170 +00:00] [INF] [110] Emby.Server.Implementations.Library.LibraryManager: Deleting item path, Type: "Episode", Name: "2023-12-29 - The step-by-step, mechanical logic of old pinball machines", Path: "/media/youtube/andy/tv/Technology Connections/Season 2023/s2023.e122901 - The step-by-step, mechanical logic of old pinball machines.webm", Id: 7a0badaa-93ae-9e4d-02dc-a665e67d377f
[2024-01-09 02:39:39.185 +00:00] [INF] [108] Emby.Server.Implementations.IO.LibraryMonitor: "Season 2023" ("/media/youtube/andy/tv/Technology Connections/Season 2023") will be refreshed.

Troubleshooting info

(some lines removed, sorry, not putting my whole media server in the log)

[Deb] JunkCollectors.SeriesJunkCollector: Filters order: Expired, Favorites, Locations, Series [Deb] JunkCollectors.SeriesJunkCollector: 394 items before filtering [Tra] Filtering.ExpiredFilter: Filtering item "20240107 - When LCD Displays Arrived, Did We Notice They Were Worse Than CRT?" [Tra] Filtering.ExpiredFilter: Filtering item "20230926 - These Healthy Stir Fries will (quickly) improve your life." [Tra] Filtering.ExpiredFilter: Filtering item "20230303 - How Tiny Formula 1 Engines Make 1000 HP!" [Tra] Filtering.ExpiredFilter: Filtering item "20230428 - Why Are" [Tra] Filtering.ExpiredFilter: Filtering item "20231214 - 50 Food Mistakes You Need To Avoid" [Tra] Filtering.ExpiredFilter: Filtering item "20231215 - Do You Really Need AWD? Settling The Winter Tire Debate" [Tra] Filtering.ExpiredFilter: Played by "spyder" [Tra] Filtering.ExpiredFilter: Filtering item "20231201 - Formula 1 V10 - The Greatest Engine Of All Time?" [Tra] Filtering.ExpiredFilter: Played by "spyder" [Tra] Filtering.ExpiredFilter: Filtering item "2024-01-06 - Super Mario RPG: 25 Years Later a Nintendo Classic" [Tra] Filtering.ExpiredFilter: Played by "spyder" [Tra] Filtering.ExpiredFilter: Filtering item "2024-01-01 - LITERALLY SWARMED | Pre-wipe Tarkov Shenanigans" [Tra] Filtering.ExpiredFilter: Played by "spyder" [Tra] Filtering.ExpiredFilter: Filtering item "20231203 - Ancient Money Secrets Revealed! Kuan Tian: The Untold Story" [Tra] Filtering.ExpiredFilter: Filtering item "2023-12-24 - THIS IS A HORROR GAME - Escape from Tarkov"

(some lines removed, sorry, not putting my whole media server in the log)

[Tra] JunkCollectors.SeriesJunkCollector: "20240107 - When LCD Displays Arrived, Did We Notice They Were Worse Than CRT?" filtered by Expired [Tra] JunkCollectors.SeriesJunkCollector: "20230926 - These Healthy Stir Fries will (quickly) improve your life." filtered by Expired [Tra] JunkCollectors.SeriesJunkCollector: "20230303 - How Tiny Formula 1 Engines Make 1000 HP!" filtered by Expired [Tra] JunkCollectors.SeriesJunkCollector: "20230428 - Why Are" filtered by Expired [Tra] JunkCollectors.SeriesJunkCollector: "20231214 - 50 Food Mistakes You Need To Avoid" filtered by Expired [Tra] JunkCollectors.SeriesJunkCollector: "20231203 - Ancient Money Secrets Revealed! Kuan Tian: The Untold Story" filtered by Expired

(some lines removed, sorry, not putting my whole media server in the log)

[Deb] JunkCollectors.SeriesJunkCollector: 5 items after filtering [Tra] JunkCollectors.SeriesJunkCollector: Collecting finished at 01/09/2024 02:39:02 [Inf] MediaCleanupTask: (Episode) "2023-12-24 - THIS IS A HORROR GAME - Escape from Tarkov" will be deleted because expired for: spyder (01/04/2024 21:57:06) [Inf] MediaCleanupTask: (Episode) "2024-01-01 - LITERALLY SWARMED | Pre-wipe Tarkov Shenanigans" will be deleted because expired for: spyder (01/06/2024 17:16:20) [Inf] MediaCleanupTask: (Episode) "2024-01-06 - Super Mario RPG: 25 Years Later a Nintendo Classic" will be deleted because expired for: spyder (01/07/2024 20:31:00) [Inf] MediaCleanupTask: (Episode) "20231201 - Formula 1 V10 - The Greatest Engine Of All Time?" will be deleted because expired for: spyder (01/08/2024 02:30:45) [Inf] MediaCleanupTask: (Episode) "20231215 - Do You Really Need AWD? Settling The Winter Tire Debate" will be deleted because expired for: spyder (01/08/2024 02:37:51)

TheSpyder commented 8 months ago

Same behaviour today - for a moment I thought it didn't delete them all but those are cases I either manually deleted (thus keeping the seasons) or watched within my "keep for" window.

Maybe an option to always leave 1 episode behind would help?

shemanaev commented 7 months ago

Hi. How exactly ytdl-sub keeps track of subscriptions? Does it store metadata file in series/season folders? Or some magic around downloaded episodes filename?

TheSpyder commented 7 months ago

Oh I forgot to include a link 🫣 https://ytdl-sub.readthedocs.io/en/latest/

It stores metadata in the series folder. Given a channelname, There's a .ytdl-sub-<channelname>-download-archive.json which stores the list of youtube IDs such as

{
  "5HSjJU562e8": {
    "extractor": "youtube",
    "file_names": [
      "Season 2023/s2023.e121901 - Reverse Engineering Game Code from the Neutral Zone-thumb.jpg",
      "Season 2023/s2023.e121901 - Reverse Engineering Game Code from the Neutral Zone.info.json",
      "Season 2023/s2023.e121901 - Reverse Engineering Game Code from the Neutral Zone.nfo",
      "Season 2023/s2023.e121901 - Reverse Engineering Game Code from the Neutral Zone.webm"
    ],
    "upload_date": "2023-12-19"
  }
}

In the default config, it has a "season" for each year. It also creates .nfo files for the series, each season and each episode, but I think that's just standard jellyfin data.

I looked into another media cleanup tool that has an option to always keep one episode, but it's harder to get started with so I haven't gotten around to it yet. I would very much appreciate a similar feature here.

shemanaev commented 7 months ago

I made exception when series folder contains .ytdl-sub-<channelname>-download-archive.json it wouldn't be deleted. In my tests (not very deep, honestly) this should be enough. Please, report back if it will work the intended way 😀

TheSpyder commented 7 months ago

That looks like it should work! My files are names like .ytdl-sub-Skill Up-download-archive.json and .ytdl-sub-Retro Game Mechanics Explained-download-archive.json which looks like it will match. I'll update and report back after the next cleanup run.

TheSpyder commented 7 months ago

Apologies, I thought I had set an expiration date but must've forgotten to save. I just set it, and ran the media cleanup task manually rather than wait until tomorrow, it's working well and keeps the folder after deleting every episode and season 👍 Thank you!