diff --git a/Shokofin/Resolvers/LinkGenerationResult.cs b/Shokofin/Resolvers/LinkGenerationResult.cs index 0ba41894..94f98b05 100644 --- a/Shokofin/Resolvers/LinkGenerationResult.cs +++ b/Shokofin/Resolvers/LinkGenerationResult.cs @@ -1,5 +1,6 @@ using System; +using System.Collections.Concurrent; using MediaBrowser.Controller.Entities; using Microsoft.Extensions.Logging; @@ -9,6 +10,8 @@ public class LinkGenerationResult { private DateTime CreatedAt { get; init; } = DateTime.Now; + public ConcurrentBag Paths { get; init; } = new(); + public int Total => TotalVideos + TotalSubtitles + TotalNfos; @@ -83,19 +86,31 @@ public void Print(Folder mediaFolder, ILogger logger) public void MarkSkipped() { - SkippedSubtitles += FixedSubtitles + CreatedSubtitles; - FixedSubtitles = CreatedSubtitles = RemovedSubtitles = 0; - SkippedVideos += FixedVideos + CreatedVideos; - FixedVideos = CreatedVideos = RemovedVideos = 0; - SkippedNfos += CreatedNfos; - CreatedNfos = RemovedNfos = 0; + if (FixedSubtitles > 0 || CreatedSubtitles > 0) { + SkippedSubtitles += FixedSubtitles + CreatedSubtitles; + FixedSubtitles = CreatedSubtitles = 0; + } + if (FixedVideos > 0 || CreatedVideos > 0) { + SkippedVideos += FixedVideos + CreatedVideos; + FixedVideos = CreatedVideos = 0; + } + if (CreatedNfos > 0) { + SkippedNfos += CreatedNfos; + CreatedNfos = 0; + } } public static LinkGenerationResult operator +(LinkGenerationResult a, LinkGenerationResult b) { + // Re-use the same instance so the parallel execution will share the same bag. + var paths = a.Paths; + foreach (var path in b.Paths) + a.Paths.Add(path); + return new() { CreatedAt = a.CreatedAt, + Paths = paths, CreatedVideos = a.CreatedVideos + b.CreatedVideos, FixedVideos = a.FixedVideos + b.FixedVideos, SkippedVideos = a.SkippedVideos + b.SkippedVideos, diff --git a/Shokofin/Resolvers/ShokoResolveManager.cs b/Shokofin/Resolvers/ShokoResolveManager.cs index 59ce6d3b..42c560dd 100644 --- a/Shokofin/Resolvers/ShokoResolveManager.cs +++ b/Shokofin/Resolvers/ShokoResolveManager.cs @@ -626,7 +626,6 @@ private async Task GenerateSymbolicLinks(Folder mediaFolder, IEnumerable<(string var result = new LinkGenerationResult(); var vfsPath = ShokoAPIManager.GetVirtualRootForMediaFolder(mediaFolder); var collectionType = LibraryManager.GetInheritedContentType(mediaFolder); - var allPathsForVFS = new ConcurrentBag(); var semaphore = new SemaphoreSlim(Plugin.Instance.Configuration.VirtualFileSystemThreads); await Task.WhenAll(files.Select(async (tuple) => { var subResult = await DataCache.GetOrCreateAsync( @@ -639,7 +638,7 @@ await Task.WhenAll(files.Select(async (tuple) => { try { // Skip any source files we weren't meant to have in the library. var (sourceLocation, symbolicLinks, nfoFiles) = await GenerateLocationsForFile(vfsPath, collectionType, tuple.sourceLocation, tuple.fileId, tuple.seriesId).ConfigureAwait(false); - return GenerateSymbolicLinks(sourceLocation, symbolicLinks, nfoFiles, allPathsForVFS); + return GenerateSymbolicLinks(sourceLocation, symbolicLinks, nfoFiles, result.Paths); } finally { semaphore.Release(); @@ -660,7 +659,7 @@ await Task.WhenAll(files.Select(async (tuple) => { .ConfigureAwait(false); // Cleanup the structure in the VFS. - result += CleanupStructure(vfsPath, allPathsForVFS, pathToClean); + result += CleanupStructure(vfsPath, result.Paths, pathToClean); result.Print(mediaFolder, Logger); } @@ -793,7 +792,7 @@ private LinkGenerationResult GenerateSymbolicLinks(string? sourceLocation, strin if (!Directory.Exists(symbolicDirectory)) Directory.CreateDirectory(symbolicDirectory); - allPathsForVFS.Add(symbolicLink); + result.Paths.Add(symbolicLink); if (!File.Exists(symbolicLink)) { result.CreatedVideos++; Logger.LogDebug("Linking {Link} → {LinkTarget}", symbolicLink, sourceLocation); @@ -829,7 +828,7 @@ private LinkGenerationResult GenerateSymbolicLinks(string? sourceLocation, strin var extName = subtitleSource[sourcePrefixLength..]; var subtitleLink = Path.Combine(symbolicDirectory, symbolicName + extName); - allPathsForVFS.Add(subtitleLink); + result.Paths.Add(subtitleLink); if (!File.Exists(subtitleLink)) { result.CreatedSubtitles++; Logger.LogDebug("Linking {Link} → {LinkTarget}", subtitleLink, subtitleSource); @@ -865,9 +864,18 @@ private LinkGenerationResult GenerateSymbolicLinks(string? sourceLocation, strin // TODO: Remove these two hacks once we have proper support for adding multiple series at once. foreach (var nfoFile in nfoFiles) { - if (allPathsForVFS.Contains(nfoFile)) + if (allPathsForVFS.Contains(nfoFile)) { + if (!result.Paths.Contains(nfoFile)) + result.Paths.Add(nfoFile); continue; + } + if (result.Paths.Contains(nfoFile)) { + if (!allPathsForVFS.Contains(nfoFile)) + allPathsForVFS.Add(nfoFile); + continue; + } allPathsForVFS.Add(nfoFile); + result.Paths.Add(nfoFile); var nfoDirectory = Path.GetDirectoryName(nfoFile)!; if (!Directory.Exists(nfoDirectory))