4 Commits

Author SHA1 Message Date
08e26943c9 Added debugging 2025-12-04 20:24:24 -07:00
65dd638b09 Added logging 2025-12-03 23:30:58 -07:00
6b20bc0828 Fixed bug for nullable movie user data 2025-12-03 23:00:19 -07:00
db3a06cc67 Logic fix 2025-12-03 22:35:14 -07:00
4 changed files with 88 additions and 16 deletions

View File

@@ -1,5 +1,5 @@
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<AssemblyVersion>0.0.0.3</AssemblyVersion> <AssemblyVersion>0.0.0.4</AssemblyVersion>
</PropertyGroup> </PropertyGroup>
</Project> </Project>

View File

@@ -31,4 +31,9 @@ public class PluginConfiguration : BasePluginConfiguration
/// Gets or sets the cut off days before deleting unwatched files. /// Gets or sets the cut off days before deleting unwatched files.
/// </summary> /// </summary>
public int StaleMediaCutoff { get; set; } = 90; public int StaleMediaCutoff { get; set; } = 90;
/// <summary>
/// Gets or sets debug mode.
/// </summary>
public bool DebugMode { get; set; }
} }

View File

@@ -24,6 +24,12 @@
<input id="StaleMediaCutoff" name="StaleMediaCutoff" type="number" is="emby-input" style="width: 20%;"/> <input id="StaleMediaCutoff" name="StaleMediaCutoff" type="number" is="emby-input" style="width: 20%;"/>
<div class="fieldDescription">How many days to wait before marking files as stale</div> <div class="fieldDescription">How many days to wait before marking files as stale</div>
</div> </div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label class="emby-checkbox-label">
<input id="DebugMode" name="DebugMode" type="checkbox" is="emby-checkbox" />
<span>Debug Mode</span>
</label>
</div>
<!-- <div class="selectContainer"> <!-- <div class="selectContainer">
<label class="selectLabel" for="Options">Several Options</label> <label class="selectLabel" for="Options">Several Options</label>
<select is="emby-select" id="Options" name="Options" class="emby-select-withcolor emby-select"> <select is="emby-select" id="Options" name="Options" class="emby-select-withcolor emby-select">
@@ -71,6 +77,7 @@
document.querySelector('#RadarrAPIKey').value = config.RadarrAPIKey; document.querySelector('#RadarrAPIKey').value = config.RadarrAPIKey;
document.querySelector('#SonarrAPIKey').value = config.SonarrAPIKey; document.querySelector('#SonarrAPIKey').value = config.SonarrAPIKey;
document.querySelector('#StaleMediaCutoff').value = config.StaleMediaCutoff; document.querySelector('#StaleMediaCutoff').value = config.StaleMediaCutoff;
document.querySelector('#DebugMode').checked = config.DebugMode;
Dashboard.hideLoadingMsg(); Dashboard.hideLoadingMsg();
}); });
}); });
@@ -86,6 +93,7 @@
config.RadarrAPIKey = document.querySelector('#RadarrAPIKey').value; config.RadarrAPIKey = document.querySelector('#RadarrAPIKey').value;
config.SonarrAPIKey = document.querySelector('#SonarrAPIKey').value; config.SonarrAPIKey = document.querySelector('#SonarrAPIKey').value;
config.StaleMediaCutoff = document.querySelector('#StaleMediaCutoff').value; config.StaleMediaCutoff = document.querySelector('#StaleMediaCutoff').value;
config.DebugMode = document.querySelector('#DebugMode').checked;
ApiClient.updatePluginConfiguration(MediaCleanerConfig.pluginUniqueId, config).then(function (result) { ApiClient.updatePluginConfiguration(MediaCleanerConfig.pluginUniqueId, config).then(function (result) {
Dashboard.processPluginConfigurationUpdateResult(result); Dashboard.processPluginConfigurationUpdateResult(result);
}); });

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data.Common; using System.Data.Common;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
@@ -61,10 +62,13 @@ public sealed class StaleMediaTask : IScheduledTask
}; };
List<BaseItem> allItems = [.. _libraryManager.GetItemsResult(query).Items]; List<BaseItem> allItems = [.. _libraryManager.GetItemsResult(query).Items];
_logger.LogInformation("Total items found: {AllItems}", allItems); if (Configuration.DebugMode)
{
_logger.LogInformation("Total items found: {AllItems}", allItems);
}
List<BaseItem> series = [.. allItems.Where(item => item.GetBaseItemKind() == BaseItemKind.Series)]; List<BaseItem> series = [.. allItems.Where(item => item.GetBaseItemKind() == BaseItemKind.Series)];
List<BaseItem> movies = [.. allItems.Where(item => item.GetBaseItemKind() == BaseItemKind.Movie && item.UserData.Count > 0)]; List<BaseItem> movies = [.. allItems.Where(item => item.GetBaseItemKind() == BaseItemKind.Movie)];
List<BaseItem> staleEpisodes = [.. series.SelectMany(GetStaleEpisodes)]; List<BaseItem> staleEpisodes = [.. series.SelectMany(GetStaleEpisodes)];
List<BaseItem> staleMovies = [.. GetStaleMovies(movies)]; List<BaseItem> staleMovies = [.. GetStaleMovies(movies)];
@@ -83,7 +87,10 @@ public sealed class StaleMediaTask : IScheduledTask
foreach (var seriesInfo in seriesInfoList) foreach (var seriesInfo in seriesInfoList)
{ {
_logger.LogInformation("Series Info: ID: {Id} | Series Name: {SeriesName} | Stale Seasons: {Seasons}", [seriesInfo.Id, seriesInfo.SeriesName, string.Join(", ", seriesInfo.Seasons)]); if (Configuration.DebugMode)
{
_logger.LogInformation("Series Info: ID: {Id} | Series Name: {SeriesName} | Stale Seasons: {Seasons}", [seriesInfo.Id, seriesInfo.SeriesName, string.Join(", ", seriesInfo.Seasons)]);
}
} }
} }
@@ -96,15 +103,36 @@ public sealed class StaleMediaTask : IScheduledTask
foreach (var movie in movies) foreach (var movie in movies)
{ {
bool movieIsStale = movie.DateCreated > DateTime.Now.AddDays(-Configuration.StaleMediaCutoff); bool movieIsStale = movie.DateCreated < DateTime.Now.AddDays(-Configuration.StaleMediaCutoff);
var mostRecentUserData = movie.UserData.OrderByDescending(data => data.LastPlayedDate).First(); bool movieHasUserData = movie.UserData.Count > 0;
if (movieHasUserData)
if (mostRecentUserData.LastPlayedDate < DateTime.Now.AddDays(-Configuration.StaleMediaCutoff))
{ {
staleMovies.Add(movie); if (Configuration.DebugMode){
_logger.LogInformation("Movie has user data: {Movie}", movie);
_logger.LogInformation("-------------------------------------------------");
}
var mostRecentUserData = movie.UserData.OrderByDescending(data => data.LastPlayedDate).First();
if (Configuration.DebugMode){
_logger.LogInformation("Most recent user data: {Movie}", movie);
foreach (var property in typeof(UserData).GetProperties())
{
_logger.LogInformation("{PropertyName}: {PropertyValue}", property.Name, property.GetValue(mostRecentUserData));
}
_logger.LogInformation("-------------------------------------------------");
}
if (mostRecentUserData.LastPlayedDate < DateTime.Now.AddDays(-Configuration.StaleMediaCutoff))
{
_logger.LogInformation("Most recent user data last played date is outside of cutoff. Adding to stale movies.");
staleMovies.Add(movie);
}
} }
else if (movieIsStale) else if (movieIsStale)
{ {
_logger.LogInformation("Movie has no user data and was created outside of cutoff: {DateCreated}", movie.DateCreated);
staleMovies.Add(movie); staleMovies.Add(movie);
} }
} }
@@ -136,11 +164,11 @@ public sealed class StaleMediaTask : IScheduledTask
series.ForEach(series => series.ForEach(series =>
{ {
seriesInfoList.Add(new SeriesInfo seriesInfoList.Add(new SeriesInfo
{ {
Id = series.Id, Id = series.Id,
SeriesName = series.Name, SeriesName = series.Name,
Seasons = [.. seasons.Where(season => season.ParentId == series.Id).Select(season => season.Name)] Seasons = [.. seasons.Where(season => season.ParentId == series.Id).Select(season => season.Name)]
}); });
}); });
return seriesInfoList; return seriesInfoList;
@@ -165,18 +193,45 @@ public sealed class StaleMediaTask : IScheduledTask
ParentId = season.Id, ParentId = season.Id,
Recursive = false Recursive = false
}); });
bool seasonHasUserData = episodes.Any(episode => episode.UserData.Count > 0); bool seasonHasUserData = episodes.Any(episode => episode.UserData.Count > 0);
bool seasonIsStale = episodes.All(episode => episode.DateCreated > DateTime.Now.AddDays(-Configuration.StaleMediaCutoff)); if (seasonHasUserData && Configuration.DebugMode)
{
_logger.LogInformation("Season has user data for episodes: {Episodes}", episodes);
_logger.LogInformation("-------------------------------------------------");
}
bool seasonIsStale = episodes.All(episode => episode.DateCreated < DateTime.Now.AddDays(-Configuration.StaleMediaCutoff));
if (seasonIsStale && Configuration.DebugMode)
{
_logger.LogInformation("All episodes are outside media cutoff.");
_logger.LogInformation("-------------------------------------------------");
}
if (seasonHasUserData) if (seasonHasUserData)
{ {
var episodesWithUserData = episodes.Where(episode => episode.UserData.Count > 0).ToList(); var episodesWithUserData = episodes.Where(episode => episode.UserData.Count > 0).ToList();
if(Configuration.DebugMode){
_logger.LogInformation("Episodes with user data: {EpisodesWithUserData}", episodesWithUserData);
_logger.LogInformation("-------------------------------------------------");
}
foreach (var episode in episodesWithUserData) foreach (var episode in episodesWithUserData)
{ {
var mostRecentUserData = episode.UserData.OrderByDescending(data => data.LastPlayedDate).First(); var mostRecentUserData = episode.UserData.OrderByDescending(data => data.LastPlayedDate).First();
if(Configuration.DebugMode){
foreach (var property in typeof(UserData).GetProperties())
{
_logger.LogInformation("{PropertyName}: {PropertyValue}", property.Name, property.GetValue(mostRecentUserData));
}
_logger.LogInformation("-------------------------------------------------");
}
if (mostRecentUserData.LastPlayedDate < DateTime.Now.AddDays(-Configuration.StaleMediaCutoff)) if (mostRecentUserData.LastPlayedDate < DateTime.Now.AddDays(-Configuration.StaleMediaCutoff))
{ {
if(Configuration.DebugMode){
_logger.LogInformation("Most Recent User Data Last Played Date is: {LastPlayedDate}. All Episodes are stale.", mostRecentUserData.LastPlayedDate);
_logger.LogInformation("-------------------------------------------------");
}
staleEpisodes.AddRange(episodes); staleEpisodes.AddRange(episodes);
break; break;
} }
@@ -185,6 +240,10 @@ public sealed class StaleMediaTask : IScheduledTask
// Check for episodes that have gone unwatched for stale media cutoff // Check for episodes that have gone unwatched for stale media cutoff
else if (seasonIsStale) else if (seasonIsStale)
{ {
if(Configuration.DebugMode){
_logger.LogInformation("No user data, adding all episodes as it is outside of cutoff.");
_logger.LogInformation("-------------------------------------------------");
}
staleEpisodes.AddRange(episodes); staleEpisodes.AddRange(episodes);
} }
} }