diff --git a/.vscode/extensions.json b/.vscode/extensions.json
deleted file mode 100644
index 698bc34..0000000
--- a/.vscode/extensions.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- // See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
- // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
- // List of extensions which should be recommended for users of this workspace.
- "recommendations": [
- "ms-dotnettools.csharp",
- "editorconfig.editorconfig"
- ],
- // List of extensions recommended by VS Code that should not be recommended for users of this workspace.
- "unwantedRecommendations": []
-}
\ No newline at end of file
diff --git a/.vscode/launch.json b/.vscode/launch.json
deleted file mode 100644
index 9f17676..0000000
--- a/.vscode/launch.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- // Paths and plugin names are configured in settings.json
- "version": "0.2.0",
- "configurations": [
- {
- "type": "coreclr",
- "name": "Launch",
- "request": "launch",
- "preLaunchTask": "build-and-copy",
- "program": "${config:jellyfinDir}/bin/Debug/net9.0/jellyfin.dll",
- "args": [
- //"--nowebclient"
- "--webdir",
- "${config:jellyfinWebDir}/dist/"
- ],
- "cwd": "${config:jellyfinDir}",
- }
- ]
-}
diff --git a/.vscode/settings.json b/.vscode/settings.json
deleted file mode 100644
index b075e97..0000000
--- a/.vscode/settings.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- // jellyfinDir : The directory of the cloned jellyfin server project
- // This needs to be built once before it can be used
- "jellyfinDir": "${workspaceFolder}/../jellyfin/Jellyfin.Server",
- // jellyfinWebDir : The directory of the cloned jellyfin-web project
- // This needs to be built once before it can be used
- "jellyfinWebDir": "${workspaceFolder}/../jellyfin-web",
- // jellyfinDataDir : the root data directory for a running jellyfin instance
- // This is where jellyfin stores its configs, plugins, metadata etc
- // This is platform specific by default, but on Windows defaults to
- // ${env:LOCALAPPDATA}/jellyfin
- // and on Linux, it defaults to
- // ${env:XDG_DATA_HOME}/jellyfin
- // However ${env:XDG_DATA_HOME} does not work in Visual Studio Code's development container!
- "jellyfinWindowsDataDir": "${env:LOCALAPPDATA}/jellyfin",
- "jellyfinLinuxDataDir": "$HOME/.local/share/jellyfin",
- // The name of the plugin
- "pluginName": "Jellyfin.Plugin.MediaCleaner",
-}
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
deleted file mode 100644
index 62e3e70..0000000
--- a/.vscode/tasks.json
+++ /dev/null
@@ -1,76 +0,0 @@
-{
- // Paths and plugin name are configured in settings.json
- "version": "2.0.0",
- "tasks": [
- {
- // A chain task - build the plugin, then copy it to your
- // jellyfin server's plugin directory
- "label": "build-and-copy",
- "dependsOrder": "sequence",
- "dependsOn": [
- "build",
- "make-plugin-dir",
- "copy-dll"
- ]
- },
- {
- // Build the plugin
- "label": "build",
- "command": "dotnet",
- "type": "shell",
- "args": [
- "publish",
- "--configuration=Debug",
- "${workspaceFolder}\\${config:pluginName}.sln",
- "/property:GenerateFullPaths=true",
- "/consoleloggerparameters:NoSummary"
- ],
- "group": "build",
- "presentation": {
- "reveal": "silent"
- },
- "problemMatcher": "$msCompile"
- },
- {
- // Ensure the plugin directory exists before trying to use it
- "label": "make-plugin-dir",
- "type": "shell",
- "command": "mkdir",
- "windows": {
- "args": [
- "-Force",
- "-Path",
- "${config:jellyfinWindowsDataDir}/plugins/${config:pluginName}/"
- ]
- },
- "linux": {
- "args": [
- "-p",
- "${config:jellyfinLinuxDataDir}/plugins/${config:pluginName}/"
- ]
- }
- },
- {
- // Copy the plugin dll to the jellyfin plugin install path
- // This command copies every .dll from the build directory to the plugin dir
- // Usually, you probablly only need ${config:pluginName}.dll
- // But some plugins may bundle extra requirements
- "label": "copy-dll",
- "type": "shell",
- "command": "cp",
- "windows": {
- "args": [
- "./${config:pluginName}/bin/Debug/net9.0/publish/*",
- "${config:jellyfinWindowsDataDir}/plugins/${config:pluginName}/"
- ]
- },
- "linux": {
- "args": [
- "-r",
- "./${config:pluginName}/bin/Debug/net9.0/publish/*",
- "${config:jellyfinLinuxDataDir}/plugins/${config:pluginName}/"
- ]
- }
- },
- ]
-}
diff --git a/Jellyfin.Plugin.MediaCleaner/Jellyfin.Plugin.MediaCleaner.csproj b/Jellyfin.Plugin.MediaCleaner/Jellyfin.Plugin.MediaCleaner.csproj
index 6fb1a62..7dbda16 100644
--- a/Jellyfin.Plugin.MediaCleaner/Jellyfin.Plugin.MediaCleaner.csproj
+++ b/Jellyfin.Plugin.MediaCleaner/Jellyfin.Plugin.MediaCleaner.csproj
@@ -11,10 +11,10 @@
-
+
runtime
-
+
runtime
diff --git a/Jellyfin.Plugin.MediaCleaner/Plugin.cs b/Jellyfin.Plugin.MediaCleaner/Plugin.cs
index 530c2e6..f28a686 100644
--- a/Jellyfin.Plugin.MediaCleaner/Plugin.cs
+++ b/Jellyfin.Plugin.MediaCleaner/Plugin.cs
@@ -4,6 +4,7 @@ using System.Globalization;
using Jellyfin.Plugin.MediaCleaner.Configuration;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Plugins;
+using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Plugins;
using MediaBrowser.Model.Serialization;
@@ -36,6 +37,10 @@ public class Plugin : BasePlugin, IHasWebPages
///
public static Plugin? Instance { get; private set; }
+ private static List StaleMovies { get; set; } = new();
+
+ private static List StaleShows { get; set; } = new();
+
///
public IEnumerable GetPages()
{
diff --git a/Jellyfin.Plugin.MediaCleaner/ScheduledTasks/StaleMediaTask.cs b/Jellyfin.Plugin.MediaCleaner/ScheduledTasks/StaleMediaTask.cs
new file mode 100644
index 0000000..8f187c9
--- /dev/null
+++ b/Jellyfin.Plugin.MediaCleaner/ScheduledTasks/StaleMediaTask.cs
@@ -0,0 +1,81 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Model.Tasks;
+using Microsoft.Extensions.Logging;
+
+namespace Jellyfin.Plugin.MediaCleaner.ScheduledTasks;
+
+///
+/// A task to scan media for stale files.
+///
+public sealed class StaleMediaTask : IScheduledTask
+{
+ private readonly ILogger _logger;
+ private readonly IUserManager _userManager;
+ private readonly ILibraryManager _libraryManager;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Logger.
+ /// User manager.
+ /// .
+ public StaleMediaTask(ILogger logger, IUserManager userManager, ILibraryManager libraryManager)
+ {
+ _logger = logger;
+ _userManager = userManager;
+ _libraryManager = libraryManager;
+ }
+
+ string IScheduledTask.Name => "Scan Stale Media";
+
+ string IScheduledTask.Key => "Stale Media";
+
+ string IScheduledTask.Description => "Scan Stale Media";
+
+ string IScheduledTask.Category => "Media";
+
+ Task IScheduledTask.ExecuteAsync(IProgress progress, CancellationToken cancellationToken)
+ {
+ var query = new InternalItemsQuery
+ {
+ IncludeItemTypes = new[] { BaseItemKind.Movie, BaseItemKind.Series },
+ Recursive = true
+ };
+ var allItems = _libraryManager.GetItemsResult(query).Items;
+
+ _logger.LogInformation("Total items found: {AllItems}", allItems);
+
+ foreach (BaseItem item in allItems)
+ {
+ var userData = item.UserData.ToList();
+ var mostRecentUserData = userData.OrderByDescending(data => data.LastPlayedDate).First();
+ if (mostRecentUserData.LastPlayedDate < DateTime.Now.AddDays(1))
+ {
+ // Stale data
+ }
+ }
+
+ Debugger.Break();
+
+ return Task.CompletedTask;
+ }
+
+ IEnumerable IScheduledTask.GetDefaultTriggers()
+ {
+ // Run this task every 24 hours
+ yield return new TaskTriggerInfo
+ {
+ Type = TaskTriggerInfoType.IntervalTrigger,
+ IntervalTicks = TimeSpan.FromHours(24).Ticks
+ };
+ }
+}