From f7720e7c99e0e0f84f6492670dc1bcf83fa0f2fb Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Sat, 16 Sep 2023 15:08:45 +0200 Subject: Extend collections cleanup task to include playlists too --- .../Tasks/CleanupCollectionAndPlaylistPathsTask.cs | 147 +++++++++++++++++++++ .../Tasks/CleanupCollectionPathsTask.cs | 119 ----------------- 2 files changed, 147 insertions(+), 119 deletions(-) create mode 100644 Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs delete mode 100644 Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionPathsTask.cs (limited to 'Emby.Server.Implementations/ScheduledTasks') diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs new file mode 100644 index 000000000..3daa2b6d0 --- /dev/null +++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs @@ -0,0 +1,147 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Controller.Collections; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Movies; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Playlists; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Globalization; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Tasks; +using Microsoft.Extensions.Logging; + +namespace Emby.Server.Implementations.ScheduledTasks.Tasks; + +/// +/// Deletes path references from collections and playlists that no longer exists. +/// +public class CleanupCollectionAndPlaylistPathsTask : IScheduledTask +{ + private readonly ILocalizationManager _localization; + private readonly ICollectionManager _collectionManager; + private readonly IPlaylistManager _playlistManager; + private readonly ILogger _logger; + private readonly IProviderManager _providerManager; + private readonly IFileSystem _fileSystem; + + /// + /// Initializes a new instance of the class. + /// + /// Instance of the interface. + /// Instance of the interface. + /// Instance of the interface. + /// The logger. + /// The provider manager. + /// The filesystem. + public CleanupCollectionAndPlaylistPathsTask( + ILocalizationManager localization, + ICollectionManager collectionManager, + IPlaylistManager playlistManager, + ILogger logger, + IProviderManager providerManager, + IFileSystem fileSystem) + { + _localization = localization; + _collectionManager = collectionManager; + _playlistManager = playlistManager; + _logger = logger; + _providerManager = providerManager; + _fileSystem = fileSystem; + } + + /// + public string Name => _localization.GetLocalizedString("TaskCleanCollectionsAndPlaylists"); + + /// + public string Key => "CleanCollectionsAndPlaylists"; + + /// + public string Description => _localization.GetLocalizedString("TaskCleanCollectionsAndPlaylistsDescription"); + + /// + public string Category => _localization.GetLocalizedString("TasksMaintenanceCategory"); + + /// + public async Task ExecuteAsync(IProgress progress, CancellationToken cancellationToken) + { + var collectionsFolder = await _collectionManager.GetCollectionsFolder(false).ConfigureAwait(false); + if (collectionsFolder is null) + { + _logger.LogDebug("There is no collection folder to be found"); + } + else + { + var collections = collectionsFolder.Children.OfType().ToArray(); + _logger.LogDebug("Found {CollectionLength} boxsets", collections.Length); + + for (var index = 0; index < collections.Length; index++) + { + var collection = collections[index]; + _logger.LogDebug("Checking boxset {CollectionName}", collection.Name); + + CleanupLinkedChildren(collection, cancellationToken); + progress.Report(50D / collections.Length * (index + 1)); + } + } + + var playlistsFolder = _playlistManager.GetPlaylistsFolder(); + if (playlistsFolder is null) + { + _logger.LogDebug("There is no collection folder to be found"); + return; + } + + var playlists = playlistsFolder.Children.OfType().ToArray(); + _logger.LogDebug("Found {PlaylistLength} boxsets", playlists.Length); + + for (var index = 0; index < playlists.Length; index++) + { + var playlist = playlists[index]; + _logger.LogDebug("Checking playlist {PlaylistName}", playlist.Name); + + CleanupLinkedChildren(playlist, cancellationToken); + progress.Report(50D / playlists.Length * (index + 1)); + } + } + + private void CleanupLinkedChildren(T folder, CancellationToken cancellationToken) where T : Folder + { + var itemsToRemove = new List(); + foreach (var linkedChild in folder.LinkedChildren) + { + if (!File.Exists(folder.Path)) + { + _logger.LogInformation("Item in {FolderName} cannot be found at {ItemPath}", folder.Name, linkedChild.Path); + itemsToRemove.Add(linkedChild); + } + } + + if (itemsToRemove.Count != 0) + { + _logger.LogDebug("Updating {FolderName}", folder.Name); + folder.LinkedChildren = folder.LinkedChildren.Except(itemsToRemove).ToArray(); + folder.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, cancellationToken); + + _providerManager.QueueRefresh( + folder.Id, + new MetadataRefreshOptions(new DirectoryService(_fileSystem)) + { + ForceSave = true + }, + RefreshPriority.High); + + itemsToRemove.Clear(); + } + } + + /// + public IEnumerable GetDefaultTriggers() + { + return new[] { new TaskTriggerInfo() { Type = TaskTriggerInfo.TriggerStartup } }; + } +} diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionPathsTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionPathsTask.cs deleted file mode 100644 index f78fc6f97..000000000 --- a/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionPathsTask.cs +++ /dev/null @@ -1,119 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Controller.Collections; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Movies; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Globalization; -using MediaBrowser.Model.IO; -using MediaBrowser.Model.Tasks; -using Microsoft.Extensions.Logging; - -namespace Emby.Server.Implementations.ScheduledTasks.Tasks; - -/// -/// Deletes Path references from collections that no longer exists. -/// -public class CleanupCollectionPathsTask : IScheduledTask -{ - private readonly ILocalizationManager _localization; - private readonly ICollectionManager _collectionManager; - private readonly ILogger _logger; - private readonly IProviderManager _providerManager; - private readonly IFileSystem _fileSystem; - - /// - /// Initializes a new instance of the class. - /// - /// Instance of the interface. - /// Instance of the interface. - /// The logger. - /// The provider manager. - /// The filesystem. - public CleanupCollectionPathsTask( - ILocalizationManager localization, - ICollectionManager collectionManager, - ILogger logger, - IProviderManager providerManager, - IFileSystem fileSystem) - { - _localization = localization; - _collectionManager = collectionManager; - _logger = logger; - _providerManager = providerManager; - _fileSystem = fileSystem; - } - - /// - public string Name => _localization.GetLocalizedString("TaskCleanCollections"); - - /// - public string Key => "CleanCollections"; - - /// - public string Description => _localization.GetLocalizedString("TaskCleanCollectionsDescription"); - - /// - public string Category => _localization.GetLocalizedString("TasksMaintenanceCategory"); - - /// - public async Task ExecuteAsync(IProgress progress, CancellationToken cancellationToken) - { - var collectionsFolder = await _collectionManager.GetCollectionsFolder(false).ConfigureAwait(false); - if (collectionsFolder is null) - { - _logger.LogDebug("There is no collection folder to be found"); - return; - } - - var collections = collectionsFolder.Children.OfType().ToArray(); - _logger.LogDebug("Found {CollectionLength} Boxsets", collections.Length); - - var itemsToRemove = new List(); - for (var index = 0; index < collections.Length; index++) - { - var collection = collections[index]; - _logger.LogDebug("Check Boxset {CollectionName}", collection.Name); - - foreach (var collectionLinkedChild in collection.LinkedChildren) - { - if (!File.Exists(collectionLinkedChild.Path)) - { - _logger.LogInformation("Item in boxset {CollectionName} cannot be found at {ItemPath}", collection.Name, collectionLinkedChild.Path); - itemsToRemove.Add(collectionLinkedChild); - } - } - - if (itemsToRemove.Count != 0) - { - _logger.LogDebug("Update Boxset {CollectionName}", collection.Name); - collection.LinkedChildren = collection.LinkedChildren.Except(itemsToRemove).ToArray(); - await collection.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, cancellationToken) - .ConfigureAwait(false); - - _providerManager.QueueRefresh( - collection.Id, - new MetadataRefreshOptions(new DirectoryService(_fileSystem)) - { - ForceSave = true - }, - RefreshPriority.High); - - itemsToRemove.Clear(); - } - - progress.Report(100D / collections.Length * (index + 1)); - } - } - - /// - public IEnumerable GetDefaultTriggers() - { - return new[] { new TaskTriggerInfo() { Type = TaskTriggerInfo.TriggerStartup } }; - } -} -- cgit v1.2.3 From 783bb8a8cbd2b105e64d5e33891fd754c5c83182 Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Sat, 16 Sep 2023 17:05:54 +0200 Subject: Apply review suggestions --- .../Tasks/CleanupCollectionAndPlaylistPathsTask.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'Emby.Server.Implementations/ScheduledTasks') diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs index 3daa2b6d0..f30a26863 100644 --- a/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs +++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs @@ -72,7 +72,7 @@ public class CleanupCollectionAndPlaylistPathsTask : IScheduledTask var collectionsFolder = await _collectionManager.GetCollectionsFolder(false).ConfigureAwait(false); if (collectionsFolder is null) { - _logger.LogDebug("There is no collection folder to be found"); + _logger.LogDebug("There is no collections folder to be found"); } else { @@ -92,12 +92,12 @@ public class CleanupCollectionAndPlaylistPathsTask : IScheduledTask var playlistsFolder = _playlistManager.GetPlaylistsFolder(); if (playlistsFolder is null) { - _logger.LogDebug("There is no collection folder to be found"); + _logger.LogDebug("There is no playlists folder to be found"); return; } var playlists = playlistsFolder.Children.OfType().ToArray(); - _logger.LogDebug("Found {PlaylistLength} boxsets", playlists.Length); + _logger.LogDebug("Found {PlaylistLength} playlists", playlists.Length); for (var index = 0; index < playlists.Length; index++) { @@ -109,7 +109,8 @@ public class CleanupCollectionAndPlaylistPathsTask : IScheduledTask } } - private void CleanupLinkedChildren(T folder, CancellationToken cancellationToken) where T : Folder + private void CleanupLinkedChildren(T folder, CancellationToken cancellationToken) + where T : Folder { var itemsToRemove = new List(); foreach (var linkedChild in folder.LinkedChildren) -- cgit v1.2.3 From fccea4625d29feb1b91345c6b944e5dc6f062a85 Mon Sep 17 00:00:00 2001 From: Tim Eisele Date: Sun, 17 Sep 2023 14:13:19 +0200 Subject: Update Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs Co-authored-by: Bond-009 --- .../ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Emby.Server.Implementations/ScheduledTasks') diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs index f30a26863..e5af22b31 100644 --- a/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs +++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs @@ -112,17 +112,17 @@ public class CleanupCollectionAndPlaylistPathsTask : IScheduledTask private void CleanupLinkedChildren(T folder, CancellationToken cancellationToken) where T : Folder { - var itemsToRemove = new List(); + List itemsToRemove = null; foreach (var linkedChild in folder.LinkedChildren) { if (!File.Exists(folder.Path)) { _logger.LogInformation("Item in {FolderName} cannot be found at {ItemPath}", folder.Name, linkedChild.Path); - itemsToRemove.Add(linkedChild); + (itemsToRemove ??= new List()).Add(linkedChild); } } - if (itemsToRemove.Count != 0) + if (itemsToRemove is not null) { _logger.LogDebug("Updating {FolderName}", folder.Name); folder.LinkedChildren = folder.LinkedChildren.Except(itemsToRemove).ToArray(); -- cgit v1.2.3 From 61a49e94c4753eb8dbc421530656962f4a7a33c8 Mon Sep 17 00:00:00 2001 From: Tim Eisele Date: Sun, 17 Sep 2023 14:13:25 +0200 Subject: Update Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs Co-authored-by: Bond-009 --- .../ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'Emby.Server.Implementations/ScheduledTasks') diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs index e5af22b31..91f3c435c 100644 --- a/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs +++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs @@ -136,7 +136,6 @@ public class CleanupCollectionAndPlaylistPathsTask : IScheduledTask }, RefreshPriority.High); - itemsToRemove.Clear(); } } -- cgit v1.2.3 From bce45992d9fa5fd121cbc35af00d2512dbe912fa Mon Sep 17 00:00:00 2001 From: Tim Eisele Date: Sun, 17 Sep 2023 16:35:41 +0200 Subject: Update Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs Co-authored-by: Bond-009 --- .../ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/ScheduledTasks') diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs index 91f3c435c..ef2d1942a 100644 --- a/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs +++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs @@ -112,7 +112,7 @@ public class CleanupCollectionAndPlaylistPathsTask : IScheduledTask private void CleanupLinkedChildren(T folder, CancellationToken cancellationToken) where T : Folder { - List itemsToRemove = null; + List? itemsToRemove = null; foreach (var linkedChild in folder.LinkedChildren) { if (!File.Exists(folder.Path)) -- cgit v1.2.3 From 151d678b0ea344ec589f7ce478911b8e079e4f84 Mon Sep 17 00:00:00 2001 From: Tim Eisele Date: Mon, 18 Sep 2023 19:13:33 +0200 Subject: Update Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs Co-authored-by: Bond-009 --- .../ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'Emby.Server.Implementations/ScheduledTasks') diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs index ef2d1942a..acd4bf905 100644 --- a/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs +++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs @@ -135,7 +135,6 @@ public class CleanupCollectionAndPlaylistPathsTask : IScheduledTask ForceSave = true }, RefreshPriority.High); - } } -- cgit v1.2.3 From 73309f2649778e50709388e5208404c2dc71b30a Mon Sep 17 00:00:00 2001 From: Stepan Goremykin Date: Sat, 7 Oct 2023 23:50:45 +0200 Subject: Pass cancellation token --- Emby.Server.Implementations/Channels/ChannelManager.cs | 2 +- .../ScheduledTasks/Tasks/ChapterImagesTask.cs | 5 +++-- Emby.Server.Implementations/Updates/InstallationManager.cs | 7 ++++--- 3 files changed, 8 insertions(+), 6 deletions(-) (limited to 'Emby.Server.Implementations/ScheduledTasks') diff --git a/Emby.Server.Implementations/Channels/ChannelManager.cs b/Emby.Server.Implementations/Channels/ChannelManager.cs index 961e225e9..9e7b45386 100644 --- a/Emby.Server.Implementations/Channels/ChannelManager.cs +++ b/Emby.Server.Implementations/Channels/ChannelManager.cs @@ -1156,7 +1156,7 @@ namespace Emby.Server.Implementations.Channels if (info.People is not null && info.People.Count > 0) { - _libraryManager.UpdatePeople(item, info.People); + await _libraryManager.UpdatePeopleAsync(item, info.People, cancellationToken).ConfigureAwait(false); } } else if (forceUpdate) diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs index 6ad6c4cbd..c4658c32b 100644 --- a/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs +++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs @@ -115,7 +115,8 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks { try { - previouslyFailedImages = File.ReadAllText(failHistoryPath) + var failHistoryText = await File.ReadAllTextAsync(failHistoryPath, cancellationToken).ConfigureAwait(false); + previouslyFailedImages = failHistoryText .Split('|', StringSplitOptions.RemoveEmptyEntries) .ToList(); } @@ -156,7 +157,7 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks } string text = string.Join('|', previouslyFailedImages); - File.WriteAllText(failHistoryPath, text); + await File.WriteAllTextAsync(failHistoryPath, text, cancellationToken).ConfigureAwait(false); } numComplete++; diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index 6c198b6f9..38c3fb4fa 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -524,14 +524,15 @@ namespace Emby.Server.Implementations.Updates using var md5 = MD5.Create(); cancellationToken.ThrowIfCancellationRequested(); - var hash = Convert.ToHexString(md5.ComputeHash(stream)); - if (!string.Equals(package.Checksum, hash, StringComparison.OrdinalIgnoreCase)) + var hash = await md5.ComputeHashAsync(stream, cancellationToken).ConfigureAwait(false); + var hashHex = Convert.ToHexString(hash); + if (!string.Equals(package.Checksum, hashHex, StringComparison.OrdinalIgnoreCase)) { _logger.LogError( "The checksums didn't match while installing {Package}, expected: {Expected}, got: {Received}", package.Name, package.Checksum, - hash); + hashHex); throw new InvalidDataException("The checksum of the received data doesn't match."); } -- cgit v1.2.3 From a773b43a814e6e849bbb5eb0fa1bccf09a4c1945 Mon Sep 17 00:00:00 2001 From: Stepan Goremykin Date: Thu, 12 Oct 2023 21:28:04 +0200 Subject: Merge reading from file and parsing --- Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'Emby.Server.Implementations/ScheduledTasks') diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs index c4658c32b..5d15c3a21 100644 --- a/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs +++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs @@ -115,8 +115,7 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks { try { - var failHistoryText = await File.ReadAllTextAsync(failHistoryPath, cancellationToken).ConfigureAwait(false); - previouslyFailedImages = failHistoryText + previouslyFailedImages = (await File.ReadAllTextAsync(failHistoryPath, cancellationToken).ConfigureAwait(false)) .Split('|', StringSplitOptions.RemoveEmptyEntries) .ToList(); } -- cgit v1.2.3