using System; using System.Collections.Generic; using System.Linq; using System.Threading; using Jellyfin.Database.Implementations.Entities; using Jellyfin.Database.Implementations.Entities.Libraries; using Jellyfin.Plugin.MediaCleaner.Configuration; using MediaBrowser.Controller.Entities; using Microsoft.Extensions.Logging; namespace Jellyfin.Plugin.MediaCleaner.Helpers; public class SeriesHelper(ILogger logger) { private readonly LoggingHelper _loggingHelper = new(logger); private static PluginConfiguration Configuration => Plugin.Instance!.Configuration; private List ProcessEpisodes(IReadOnlyCollection episodes) { List staleEpisodes = [.. episodes .Where(episode => { bool episodeIsStale = false; var staleCreationDate = episode.DateCreated < DateTime.Now.AddDays(-Configuration.StaleMediaCutoff); var hasUserDataWithLastPlayedDate = episode.UserData.Any(data => data.LastPlayedDate != null); if (staleCreationDate && !hasUserDataWithLastPlayedDate){ _loggingHelper.LogInformation("Creation date is stale, and no user data for episode {Episode}.", episode); episodeIsStale = true; } if (hasUserDataWithLastPlayedDate){ UserData mostRecentUserData = episode.UserData .OrderByDescending(data => data.LastPlayedDate) .First(); _loggingHelper.LogDebugInformation("User data for episode: {Episode}", episode); _loggingHelper.LogDebugInformation("-------------------------------------------------"); foreach (var property in typeof(UserData).GetProperties()) { _loggingHelper.LogDebugInformation("{PropertyName}: {PropertyValue}", property.Name, property.GetValue(mostRecentUserData)); } _loggingHelper.LogDebugInformation("-------------------------------------------------"); bool staleLastPlayedDate = mostRecentUserData.LastPlayedDate < DateTime.Now.AddDays(-Configuration.StaleMediaCutoff); if (staleLastPlayedDate && staleCreationDate) { episodeIsStale = true; _loggingHelper.LogDebugInformation("Most recent user data has a last played date of: {LastPlayedDate}.", [mostRecentUserData.LastPlayedDate]); _loggingHelper.LogDebugInformation("And episode created {DateCreated}.", episode.DateCreated); _loggingHelper.LogDebugInformation("Episode is marked as stale."); } } return episodeIsStale; })]; return staleEpisodes; } public bool IsSeasonDataStale(IReadOnlyList episodes) { if(episodes == null) { ArgumentNullException.ThrowIfNull(episodes); } bool seasonIsStale = false; List staleEpisodes = ProcessEpisodes(episodes); if(staleEpisodes.Count == episodes.Count) { seasonIsStale = true; _loggingHelper.LogDebugInformation("Stale episodes count matches season episode count. Season is stale."); _loggingHelper.LogDebugInformation("-------------------------------------------------"); } return seasonIsStale; } }