shemanaev / jellyfin-plugin-media-cleaner

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

[Bug]: wrong interaction between filters #39

Closed NicolaSmaniotto closed 6 months ago

NicolaSmaniotto commented 6 months ago

What happened?

I configured the new " Keep not played for X days" option to 60 days, but I noticed that it would try to delete some movies even when in my opinion it should not.

Here is a specific example: Nosferatu was added to the server on the 31st of January 2023. I've watched it recently, the log shows: [Deb] ItemsAdapter: "Nosferatu" played by "nicola" (01/31/2024 00:20:11) Since it has been opened in the last 30 days, then the log shows: [Tra] Filtering.ExpiredFilter: Filtering item "Nosferatu" [Tra] Filtering.ExpiredFilter: Latest played by "nicola" [Tra] JunkCollectors.MoviesJunkCollector: "Nosferatu" filtered by Expired Then when the new filter is applied: [Tra] Filtering.ExpiredNotPlayedFilter: Filtering item "Nosferatu" [Tra] Filtering.ExpiredNotPlayedFilter: Not played by anyone since 01/31/2023 00:00:00 And at the bottom: [Inf] MediaCleanupTask: (Movie) "Nosferatu" will be deleted because no one played it since 01/31/2023 00:00:00

I think this is not intuitive at all (or even wrong). I don't want the plugin to delete something that users are watching, no matter how old the file is.

A solution could be to run the ExpiredNotPlayedFileter first, to collect all the old files, then the ExpiredFilter, overwriting the list if needed. Finally check its most recent play.

Troubleshooting info

* Jellyfin version: 10.8.13
* Plugin version: 2.14.0.0
<details>
<summary>Configuration</summary>
<pre>
&lt;PluginConfiguration&gt;
  &lt;KeepMoviesFor&gt;30&lt;/KeepMoviesFor&gt;
  &lt;KeepMoviesNotPlayedFor&gt;60&lt;/KeepMoviesNotPlayedFor&gt;
  &lt;KeepPlayedMovies&gt;AnyUserRolling&lt;/KeepPlayedMovies&gt;
  &lt;KeepFavoriteMovies&gt;AnyUser&lt;/KeepFavoriteMovies&gt;
  &lt;KeepEpisodesFor&gt;30&lt;/KeepEpisodesFor&gt;
  &lt;KeepEpisodesNotPlayedFor&gt;-1&lt;/KeepEpisodesNotPlayedFor&gt;
  &lt;KeepPlayedEpisodes&gt;AnyUserRolling&lt;/KeepPlayedEpisodes&gt;
  &lt;KeepFavoriteEpisodes&gt;AnyUser&lt;/KeepFavoriteEpisodes&gt;
  &lt;DeleteEpisodes&gt;Season&lt;/DeleteEpisodes&gt;
  &lt;KeepVideosFor&gt;-1&lt;/KeepVideosFor&gt;
  &lt;KeepVideosNotPlayedFor&gt;-1&lt;/KeepVideosNotPlayedFor&gt;
  &lt;KeepPlayedVideos&gt;AnyUserRolling&lt;/KeepPlayedVideos&gt;
  &lt;KeepFavoriteVideos&gt;AnyUser&lt;/KeepFavoriteVideos&gt;
  &lt;KeepAudioFor&gt;-1&lt;/KeepAudioFor&gt;
  &lt;KeepAudioNotPlayedFor&gt;-1&lt;/KeepAudioNotPlayedFor&gt;
  &lt;KeepPlayedAudio&gt;AnyUserRolling&lt;/KeepPlayedAudio&gt;
  &lt;KeepFavoriteAudio&gt;AnyUser&lt;/KeepFavoriteAudio&gt;
  &lt;KeepAudioBooksFor&gt;-1&lt;/KeepAudioBooksFor&gt;
  &lt;KeepAudioBooksNotPlayedFor&gt;-1&lt;/KeepAudioBooksNotPlayedFor&gt;
  &lt;KeepPlayedAudioBooks&gt;AnyUserRolling&lt;/KeepPlayedAudioBooks&gt;
  &lt;KeepFavoriteAudioBooks&gt;AnyUser&lt;/KeepFavoriteAudioBooks&gt;
  &lt;UsersIgnorePlayed&gt;
    &lt;string&gt;da1c429756594ff6b4719d24d1f65c9c&lt;/string&gt;
  &lt;/UsersIgnorePlayed&gt;
  &lt;UsersPlayedMode&gt;Ignore&lt;/UsersPlayedMode&gt;
  &lt;UsersIgnoreFavorited&gt;
    &lt;string&gt;da1c429756594ff6b4719d24d1f65c9c&lt;/string&gt;
  &lt;/UsersIgnoreFavorited&gt;
  &lt;UsersFavoritedMode&gt;Ignore&lt;/UsersFavoritedMode&gt;
  &lt;LocationsExcluded&gt;
    &lt;string&gt;/run/media/hpuser/hdd1/media/movies&lt;/string&gt;
    &lt;string&gt;/run/media/hpuser/hdd1/media/trakt-watchlists&lt;/string&gt;
    &lt;string&gt;/run/media/hpuser/hdd1/media/series&lt;/string&gt;
  &lt;/LocationsExcluded&gt;
  &lt;LocationsMode&gt;Include&lt;/LocationsMode&gt;
  &lt;MarkAsUnplayed&gt;false&lt;/MarkAsUnplayed&gt;
&lt;/PluginConfiguration&gt;
</pre>
</details>
JamsRepos commented 6 months ago

Well it all depends on your Keep while not played by but either way, it's not been 60 days since the time you watched the movie so something is wrong.

Let's use 60 days as my example below and say I watched the movie on the 01/01/2024.

The "Any user" option should delete the movie 60 days after the FIRST watch. So in this case, it would be deleted on 1st March 2024.

The "Any user (latest playback)" option should delete the movie 60 days after the LAST watch. So if I watch the movie on the 01/01/2024 and then you watch it 30 days later, the movie should delete itself on 31st March 2024.

JamsRepos commented 6 months ago

@NicolaSmaniotto It's been highlighted to be that this is due to your media library probably being set to "File creation date" as opposed to "Use date scanned into the library". You can find this at the route /web/index.html#!/librarydisplay.html.

NicolaSmaniotto commented 6 months ago

The setting is already "Use date scanned into the library". The metadata is correct.

I understand the difference between "Any user" and "Any user (latest playback)", I don't see how it is relevant to this issue.

shemanaev commented 6 months ago

@NicolaSmaniotto What Jellyfin shows in "Date added" metadata for "Nosferatu"?

JamsRepos commented 6 months ago

I'm not saying you don't understand how the logic works, I'm saying how it SHOULD work in-case the plugin doesn't do this already. Helps both us understand how it works and for the dev to understand what functionality we expect.

In the future, understand people aren't trying to undermine you. You also haven't provided your metadata to back your point.

shemanaev commented 6 months ago

@NicolaSmaniotto What Jellyfin shows in "Date added" metadata for "Nosferatu"?

Nevermind, I figured out the problem. Sorry, busy days at work 😅

NicolaSmaniotto commented 6 months ago

Jellyfin metadata

Sorry, I can't upload the file since I don't know where Jellyfin saves it, this is what the admin page shows:

long screenshot ![Screenshot 2024-02-26 at 18-19-36 Jellyfin](https://github.com/shemanaev/jellyfin-plugin-media-cleaner/assets/22083075/50ab929d-9913-458d-bd66-6bd523f81125)

busy days

Don't worry :+1:

shemanaev commented 6 months ago

@NicolaSmaniotto Could you please test this build?

NicolaSmaniotto commented 6 months ago

That build freezes Jellyfin when trying to open the plugin settings. It logs:

[19:38:12] [ERR] [48] Jellyfin.Api.Controllers.DashboardController: Failed to get resource ysis.Web.general.html from plugin Media Cleaner
shemanaev commented 6 months ago

That build freezes Jellyfin when trying to open the plugin settings

Did you restart Jellyfin after replacing file?

NicolaSmaniotto commented 6 months ago

I did not :sweat_smile:

Now the log looks good, it is no longer trying to delete Nosferatu. I'll check it better and report if some other unexpected files appear. Thank you!

NicolaSmaniotto commented 6 months ago

I've tried all the combinations of events I could think of:

The last two just confirm that the behavior is the same as before, whether the user sets -1 or a very high amount of days.

Also, I tried with "Keep while not played by" set to "Any user", and it seems to work as well:

This build seems to fix my issue :+1:

shemanaev commented 6 months ago

Thanks for comprehensive testing! I'll push an update to release.

NicolaSmaniotto commented 6 months ago

Sorry to bother you again, but there is still an issue. If someone watches a few episodes of a series, but then drops it, the latest version of the plugin (2.15.0.0) is unable to remove it.

Here is an example: I watched the first episode 30+ days ago. If the plugin is set to keep watched items for 30 days and unwatched forever, something like this is logged:

[Deb] ItemsAdapter: "Series Title | S01E01 | Season 1 | Episode 1" played by "nicola" (02/02/2024 23:51:32)
[Tra] Filtering.ExpiredFilter: Filtering item "Series Title | S01E01 | Season 1 | Episode 1"
[Tra] Filtering.ExpiredFilter: Latest played by "nicola"
[Deb] Filtering.SeriesFilter: "nicola" has watched episodes 1 of 8 in season "Series Title": "Season 1"
[Tra] JunkCollectors.SeriesJunkCollector: "Episode 1" filtered by Series

If I then set both "keep played for" and "keep not played for" to 30 days, something like this is logged instead:

[Deb] ItemsAdapter: "Series Title | S01E01 | Season 1 | Episode Title" played by "nicola" (02/02/2024 23:51:32)
[Tra] Filtering.ExpiredFilter: Filtering item "Series Title | S01E01 | Season 1 | Episode 1"
[Tra] Filtering.ExpiredFilter: Latest played by "nicola"
[Deb] Filtering.SeriesFilter: "nicola" has watched episodes 1 of 8 in season "Series Title": "Season 1"
[Tra] JunkCollectors.SeriesJunkCollector: "Episode 1" filtered by Series
[Tra] ItemsAdapter: "Episode 1" (e5d27649-9eaf-9f7a-cb0c-11de84277e8a) was played by nicola
[Tra] ItemsAdapter: "Episode 2" (401843c4-57b7-c4c7-ee79-d4e35e036b0a) added because not played by nicola
[Tra] ItemsAdapter: "Episode 3" (31ba3fa2-dc57-7696-20f5-307ef417e410) added because not played by nicola
[Tra] ItemsAdapter: "Episode 4" (a407f8e4-0e98-c439-4fb3-58e5f03278d6) added because not played by nicola
[Tra] ItemsAdapter: "Episode 5" (e3ba9466-2977-4394-6752-da127843f7a3) added because not played by nicola
[Tra] ItemsAdapter: "Episode 6" (fc3c721c-783b-5cdf-9894-3e5d15ffa8b6) added because not played by nicola
[Tra] ItemsAdapter: "Episode 7" (4af27cc4-13e4-7b46-4dde-4f66adec009b) added because not played by nicola
[Tra] ItemsAdapter: "Episode 8" (7cbda549-db1a-88d0-0d90-3c7d4f82f632) added because not played by nicola
[Tra] Filtering.ExpiredNotPlayedFilter: Filtering item "Series Title | S01E02 | Season 1 | Episode 2"
[Tra] Filtering.ExpiredNotPlayedFilter: Not played by anyone since 01/31/2024 14:05:22
[Tra] Filtering.ExpiredNotPlayedFilter: Filtering item "Series Title | S01E03 | Season 1 | Episode 3"
[Tra] Filtering.ExpiredNotPlayedFilter: Not played by anyone since 01/31/2024 14:05:18
[Tra] Filtering.ExpiredNotPlayedFilter: Filtering item "Series Title | S01E04 | Season 1 | Episode 4"
[Tra] Filtering.ExpiredNotPlayedFilter: Not played by anyone since 01/31/2024 14:05:15
[Tra] Filtering.ExpiredNotPlayedFilter: Filtering item "Series Title | S01E05 | Season 1 | Episode 5"
[Tra] Filtering.ExpiredNotPlayedFilter: Not played by anyone since 01/31/2024 14:05:12
[Tra] Filtering.ExpiredNotPlayedFilter: Filtering item "Series Title | S01E06 | Season 1 | Episode 6"
[Tra] Filtering.ExpiredNotPlayedFilter: Not played by anyone since 01/31/2024 14:05:06
[Tra] Filtering.ExpiredNotPlayedFilter: Filtering item "Series Title | S01E07 | Season 1 | Episode 7"
[Tra] Filtering.ExpiredNotPlayedFilter: Not played by anyone since 01/31/2024 14:04:56
[Tra] Filtering.ExpiredNotPlayedFilter: Filtering item "Series Title | S01E08 | Season 1 | Episode 8"
[Tra] Filtering.ExpiredNotPlayedFilter: Not played by anyone since 01/31/2024 14:03:37
[Deb] Filtering.SeriesFilter: "[None]" has watched episodes 7 of 8 in season "Series Title": "Season 1"
[Tra] JunkCollectors.SeriesJunkCollector: "Episode 2" filtered by Series
[Tra] JunkCollectors.SeriesJunkCollector: "Episode 3" filtered by Series
[Tra] JunkCollectors.SeriesJunkCollector: "Episode 4" filtered by Series
[Tra] JunkCollectors.SeriesJunkCollector: "Episode 5" filtered by Series
[Tra] JunkCollectors.SeriesJunkCollector: "Episode 6" filtered by Series
[Tra] JunkCollectors.SeriesJunkCollector: "Episode 7" filtered by Series
[Tra] JunkCollectors.SeriesJunkCollector: "Episode 8" filtered by Series

So in this way the series will never be removed.

Since nobody actually watched it in many days, who started it probably decided not to continue watching it, so the plugin should remove it.

Users who for some reason watch the series really slowly can always add it to their favorites to keep it around.

shemanaev commented 5 months ago

If someone watches a few episodes of a series, but then drops it, the latest version of the plugin (2.15.0.0) is unable to remove it.

Yup, that's right. There will be another setting for that case (because I personally use it this way, I don't want to mark all show as favorites 😄 ).

NicolaSmaniotto commented 5 months ago

Makes sense, thank you!