CleanupCollectionPathsTask.cs 4.5 KB

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