fix: skip library folders that are inaccessible or empty (#9291)

This commit is contained in:
Claus Vium 2024-03-18 16:09:00 +01:00 committed by GitHub
parent 7c141b9709
commit 239727e896
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 44 additions and 3 deletions

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Security;
using Jellyfin.Extensions; using Jellyfin.Extensions;
using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Configuration;
using MediaBrowser.Model.IO; using MediaBrowser.Model.IO;
@ -643,7 +644,15 @@ namespace Emby.Server.Implementations.IO
/// <inheritdoc /> /// <inheritdoc />
public virtual IEnumerable<string> GetFileSystemEntryPaths(string path, bool recursive = false) public virtual IEnumerable<string> GetFileSystemEntryPaths(string path, bool recursive = false)
{ {
return Directory.EnumerateFileSystemEntries(path, "*", GetEnumerationOptions(recursive)); try
{
return Directory.EnumerateFileSystemEntries(path, "*", GetEnumerationOptions(recursive));
}
catch (Exception ex) when (ex is UnauthorizedAccessException or DirectoryNotFoundException or SecurityException)
{
_logger.LogError(ex, "Failed to enumerate path {Path}", path);
return Enumerable.Empty<string>();
}
} }
/// <inheritdoc /> /// <inheritdoc />

View File

@ -331,8 +331,25 @@ namespace MediaBrowser.Controller.Entities
} }
} }
private static bool IsLibraryFolderAccessible(IDirectoryService directoryService, BaseItem item)
{
// For top parents i.e. Library folders, skip the validation if it's empty or inaccessible
if (item.IsTopParent && !directoryService.IsAccessible(item.ContainingFolderPath))
{
Logger.LogWarning("Library folder {LibraryFolderPath} is inaccessible or empty, skipping", item.ContainingFolderPath);
return false;
}
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, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService, CancellationToken cancellationToken)
{ {
if (!IsLibraryFolderAccessible(directoryService, this))
{
return;
}
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
var validChildren = new List<BaseItem>(); var validChildren = new List<BaseItem>();
@ -369,6 +386,11 @@ namespace MediaBrowser.Controller.Entities
foreach (var child in nonCachedChildren) foreach (var child in nonCachedChildren)
{ {
if (!IsLibraryFolderAccessible(directoryService, child))
{
continue;
}
if (currentChildren.TryGetValue(child.Id, out BaseItem currentChild)) if (currentChildren.TryGetValue(child.Id, out BaseItem currentChild))
{ {
validChildren.Add(currentChild); validChildren.Add(currentChild);
@ -392,8 +414,8 @@ namespace MediaBrowser.Controller.Entities
validChildren.Add(child); validChildren.Add(child);
} }
// If any items were added or removed.... // If it's an AggregateFolder, don't remove
if (newItems.Count > 0 || currentChildren.Count != validChildren.Count) if (!IsRoot && currentChildren.Count != validChildren.Count)
{ {
// That's all the new and changed ones - now see if there are any that are missing // That's all the new and changed ones - now see if there are any that are missing
var itemsRemoved = currentChildren.Values.Except(validChildren).ToList(); var itemsRemoved = currentChildren.Values.Except(validChildren).ToList();
@ -408,7 +430,10 @@ namespace MediaBrowser.Controller.Entities
LibraryManager.DeleteItem(item, new DeleteOptions { DeleteFileLocation = false }, this, false); LibraryManager.DeleteItem(item, new DeleteOptions { DeleteFileLocation = false }, this, false);
} }
} }
}
if (newItems.Count > 0)
{
LibraryManager.CreateItems(newItems, this, cancellationToken); LibraryManager.CreateItems(newItems, this, cancellationToken);
} }
} }

View File

@ -78,5 +78,10 @@ namespace MediaBrowser.Controller.Providers
return filePaths; return filePaths;
} }
public bool IsAccessible(string path)
{
return _fileSystem.GetFileSystemEntryPaths(path).Any();
}
} }
} }

View File

@ -16,5 +16,7 @@ namespace MediaBrowser.Controller.Providers
IReadOnlyList<string> GetFilePaths(string path); IReadOnlyList<string> GetFilePaths(string path);
IReadOnlyList<string> GetFilePaths(string path, bool clearCache, bool sort = false); IReadOnlyList<string> GetFilePaths(string path, bool clearCache, bool sort = false);
bool IsAccessible(string path);
} }
} }