aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Controller/Entities/Folder.cs
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Controller/Entities/Folder.cs')
-rw-r--r--MediaBrowser.Controller/Entities/Folder.cs68
1 files changed, 34 insertions, 34 deletions
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index a2957cdca..b2e5d7263 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -6,6 +6,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Security;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
@@ -269,11 +270,12 @@ namespace MediaBrowser.Controller.Entities
/// <param name="progress">The progress.</param>
/// <param name="metadataRefreshOptions">The metadata refresh options.</param>
/// <param name="recursive">if set to <c>true</c> [recursive].</param>
+ /// <param name="allowRemoveRoot">remove item even this folder is root.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
- public Task ValidateChildren(IProgress<double> progress, MetadataRefreshOptions metadataRefreshOptions, bool recursive = true, CancellationToken cancellationToken = default)
+ public Task ValidateChildren(IProgress<double> progress, MetadataRefreshOptions metadataRefreshOptions, bool recursive = true, bool allowRemoveRoot = false, CancellationToken cancellationToken = default)
{
- return ValidateChildrenInternal(progress, recursive, true, metadataRefreshOptions, metadataRefreshOptions.DirectoryService, cancellationToken);
+ return ValidateChildrenInternal(progress, recursive, true, allowRemoveRoot, metadataRefreshOptions, metadataRefreshOptions.DirectoryService, cancellationToken);
}
private Dictionary<Guid, BaseItem> GetActualChildrenDictionary()
@@ -307,11 +309,12 @@ namespace MediaBrowser.Controller.Entities
/// <param name="progress">The progress.</param>
/// <param name="recursive">if set to <c>true</c> [recursive].</param>
/// <param name="refreshChildMetadata">if set to <c>true</c> [refresh child metadata].</param>
+ /// <param name="allowRemoveRoot">remove item even this folder is root.</param>
/// <param name="refreshOptions">The refresh options.</param>
/// <param name="directoryService">The directory service.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
- protected virtual async Task ValidateChildrenInternal(IProgress<double> progress, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService, CancellationToken cancellationToken)
+ protected virtual async Task ValidateChildrenInternal(IProgress<double> progress, bool recursive, bool refreshChildMetadata, bool allowRemoveRoot, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService, CancellationToken cancellationToken)
{
if (recursive)
{
@@ -320,7 +323,7 @@ namespace MediaBrowser.Controller.Entities
try
{
- await ValidateChildrenInternal2(progress, recursive, refreshChildMetadata, refreshOptions, directoryService, cancellationToken).ConfigureAwait(false);
+ await ValidateChildrenInternal2(progress, recursive, refreshChildMetadata, allowRemoveRoot, refreshOptions, directoryService, cancellationToken).ConfigureAwait(false);
}
finally
{
@@ -331,8 +334,13 @@ namespace MediaBrowser.Controller.Entities
}
}
- private static bool IsLibraryFolderAccessible(IDirectoryService directoryService, BaseItem item)
+ private static bool IsLibraryFolderAccessible(IDirectoryService directoryService, BaseItem item, bool checkCollection)
{
+ if (!checkCollection && (item is BoxSet || string.Equals(item.FileNameWithoutExtension, "collections", StringComparison.OrdinalIgnoreCase)))
+ {
+ return true;
+ }
+
// For top parents i.e. Library folders, skip the validation if it's empty or inaccessible
if (item.IsTopParent && !directoryService.IsAccessible(item.ContainingFolderPath))
{
@@ -343,9 +351,9 @@ namespace MediaBrowser.Controller.Entities
return true;
}
- private async Task ValidateChildrenInternal2(IProgress<double> progress, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService, CancellationToken cancellationToken)
+ private async Task ValidateChildrenInternal2(IProgress<double> progress, bool recursive, bool refreshChildMetadata, bool allowRemoveRoot, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService, CancellationToken cancellationToken)
{
- if (!IsLibraryFolderAccessible(directoryService, this))
+ if (!IsLibraryFolderAccessible(directoryService, this, allowRemoveRoot))
{
return;
}
@@ -357,15 +365,23 @@ namespace MediaBrowser.Controller.Entities
if (IsFileProtocol)
{
- IEnumerable<BaseItem> nonCachedChildren;
+ IEnumerable<BaseItem> nonCachedChildren = [];
try
{
nonCachedChildren = GetNonCachedChildren(directoryService);
}
+ catch (IOException ex)
+ {
+ Logger.LogError(ex, "Error retrieving children from file system");
+ }
+ catch (SecurityException ex)
+ {
+ Logger.LogError(ex, "Error retrieving children from file system");
+ }
catch (Exception ex)
{
- Logger.LogError(ex, "Error retrieving children folder");
+ Logger.LogError(ex, "Error retrieving children");
return;
}
@@ -386,7 +402,7 @@ namespace MediaBrowser.Controller.Entities
foreach (var child in nonCachedChildren)
{
- if (!IsLibraryFolderAccessible(directoryService, child))
+ if (!IsLibraryFolderAccessible(directoryService, child, allowRemoveRoot))
{
continue;
}
@@ -414,12 +430,12 @@ namespace MediaBrowser.Controller.Entities
validChildren.Add(child);
}
+ // That's all the new and changed ones - now see if any have been removed and need cleanup
+ var itemsRemoved = currentChildren.Values.Except(validChildren).ToList();
+ var shouldRemove = !IsRoot || allowRemoveRoot;
// If it's an AggregateFolder, don't remove
- if (!IsRoot && currentChildren.Count != validChildren.Count)
+ if (shouldRemove && itemsRemoved.Count > 0)
{
- // That's all the new and changed ones - now see if there are any that are missing
- var itemsRemoved = currentChildren.Values.Except(validChildren).ToList();
-
foreach (var item in itemsRemoved)
{
if (item.IsFileProtocol)
@@ -460,15 +476,7 @@ namespace MediaBrowser.Controller.Entities
progress.Report(percent);
- // TODO: this is sometimes being called after the refresh has completed.
- try
- {
- ProviderManager.OnRefreshProgress(folder, percent);
- }
- catch (InvalidOperationException e)
- {
- Logger.LogError(e, "Error refreshing folder");
- }
+ ProviderManager.OnRefreshProgress(folder, percent);
});
if (validChildrenNeedGeneration)
@@ -500,15 +508,7 @@ namespace MediaBrowser.Controller.Entities
if (recursive)
{
- // TODO: this is sometimes being called after the refresh has completed.
- try
- {
- ProviderManager.OnRefreshProgress(folder, percent);
- }
- catch (InvalidOperationException e)
- {
- Logger.LogError(e, "Error refreshing folder");
- }
+ ProviderManager.OnRefreshProgress(folder, percent);
}
});
@@ -578,7 +578,7 @@ namespace MediaBrowser.Controller.Entities
private Task ValidateSubFolders(IList<Folder> children, IDirectoryService directoryService, IProgress<double> progress, CancellationToken cancellationToken)
{
return RunTasks(
- (folder, innerProgress) => folder.ValidateChildrenInternal(innerProgress, true, false, null, directoryService, cancellationToken),
+ (folder, innerProgress) => folder.ValidateChildrenInternal(innerProgress, true, false, false, null, directoryService, cancellationToken),
children,
progress,
cancellationToken);
@@ -603,7 +603,7 @@ namespace MediaBrowser.Controller.Entities
}
var fanoutConcurrency = ConfigurationManager.Configuration.LibraryScanFanoutConcurrency;
- var parallelism = fanoutConcurrency > 0 ? fanoutConcurrency : 2 * Environment.ProcessorCount;
+ var parallelism = fanoutConcurrency > 0 ? fanoutConcurrency : Environment.ProcessorCount;
var actionBlock = new ActionBlock<int>(
async i =>