CleanupCollectionPathsTask.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Threading;
  6. using System.Threading.Tasks;
  7. using Emby.Server.Implementations.Collections;
  8. using MediaBrowser.Controller.Collections;
  9. using MediaBrowser.Controller.Entities;
  10. using MediaBrowser.Controller.Entities.Movies;
  11. using MediaBrowser.Controller.Library;
  12. using MediaBrowser.Controller.Providers;
  13. using MediaBrowser.Model.Globalization;
  14. using MediaBrowser.Model.IO;
  15. using MediaBrowser.Model.Tasks;
  16. using Microsoft.Extensions.Logging;
  17. namespace Emby.Server.Implementations.ScheduledTasks.Tasks;
  18. /// <summary>
  19. /// Deletes Path references from collections that no longer exists.
  20. /// </summary>
  21. public class CleanupCollectionPathsTask : IScheduledTask
  22. {
  23. private readonly ILocalizationManager _localization;
  24. private readonly ICollectionManager _collectionManager;
  25. private readonly ILogger<CleanupCollectionPathsTask> _logger;
  26. private readonly IProviderManager _providerManager;
  27. private readonly IFileSystem _fileSystem;
  28. /// <summary>
  29. /// Initializes a new instance of the <see cref="CleanupCollectionPathsTask"/> class.
  30. /// </summary>
  31. /// <param name="localization">Instance of the <see cref="ILocalizationManager"/> interface.</param>
  32. /// <param name="collectionManager">Instance of the <see cref="ICollectionManager"/> interface.</param>
  33. /// <param name="logger">The logger.</param>
  34. /// <param name="providerManager">The provider manager.</param>
  35. /// <param name="fileSystem">The filesystem.</param>
  36. public CleanupCollectionPathsTask(
  37. ILocalizationManager localization,
  38. ICollectionManager collectionManager,
  39. ILogger<CleanupCollectionPathsTask> logger,
  40. IProviderManager providerManager,
  41. IFileSystem fileSystem)
  42. {
  43. _localization = localization;
  44. _collectionManager = collectionManager;
  45. _logger = logger;
  46. _providerManager = providerManager;
  47. _fileSystem = fileSystem;
  48. }
  49. /// <inheritdoc />
  50. public string Name => _localization.GetLocalizedString("TaskCleanCollections");
  51. /// <inheritdoc />
  52. public string Key => "CleanCollections";
  53. /// <inheritdoc />
  54. public string Description => _localization.GetLocalizedString("TaskCleanCollectionsDescription");
  55. /// <inheritdoc />
  56. public string Category => _localization.GetLocalizedString("TasksMaintenanceCategory");
  57. /// <inheritdoc />
  58. public async Task ExecuteAsync(IProgress<double> progress, CancellationToken cancellationToken)
  59. {
  60. var collectionsFolder = await _collectionManager.GetCollectionsFolder(false).ConfigureAwait(false);
  61. if (collectionsFolder is null)
  62. {
  63. _logger.LogInformation("There is no collection folder to be found.");
  64. return;
  65. }
  66. var collections = collectionsFolder.Children.OfType<BoxSet>().ToArray();
  67. _logger.LogTrace("Found {CollectionLength} Boxsets.", collections.Length);
  68. for (var index = 0; index < collections.Length; index++)
  69. {
  70. var collection = collections[index];
  71. _logger.LogTrace("Check Boxset {CollectionName}.", collection.Name);
  72. var itemsToRemove = new List<LinkedChild>();
  73. foreach (var collectionLinkedChild in collection.LinkedChildren.ToArray())
  74. {
  75. if (!File.Exists(collectionLinkedChild.Path))
  76. {
  77. _logger.LogInformation("Item in boxset {CollectionName} cannot be found at {ItemPath}.", collection.Name, collectionLinkedChild.Path);
  78. itemsToRemove.Add(collectionLinkedChild);
  79. }
  80. }
  81. if (itemsToRemove.Any())
  82. {
  83. _logger.LogTrace("Update Boxset {CollectionName}.", collection.Name);
  84. collection.LinkedChildren = collection.LinkedChildren.Except(itemsToRemove).ToArray();
  85. await collection.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, cancellationToken)
  86. .ConfigureAwait(false);
  87. _providerManager.QueueRefresh(
  88. collection.Id,
  89. new MetadataRefreshOptions(new DirectoryService(_fileSystem))
  90. {
  91. ForceSave = true
  92. },
  93. RefreshPriority.High);
  94. }
  95. progress.Report(100D / collections.Length * (index + 1));
  96. }
  97. }
  98. /// <inheritdoc />
  99. public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
  100. {
  101. return new[] { new TaskTriggerInfo() { Type = TaskTriggerInfo.TriggerStartup } };
  102. }
  103. }