diff --git a/API/Program.cs b/API/Program.cs index 77fac9e49..852844f2f 100644 --- a/API/Program.cs +++ b/API/Program.cs @@ -20,9 +20,11 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; +using NetVips; using Serilog; using Serilog.Events; using Serilog.Sinks.AspNetCore.SignalR.Extensions; +using Log = Serilog.Log; namespace API; #nullable enable @@ -143,6 +145,8 @@ public class Program var settings = await unitOfWork.SettingsRepository.GetSettingsDtoAsync(); LogLevelOptions.SwitchLogLevel(settings.LoggingLevel); + InitNetVips(); + await host.RunAsync(); } catch (Exception ex) { @@ -225,4 +229,14 @@ public class Program webBuilder.UseStartup(); }); + + /// + /// Ensure NetVips does not cache + /// + /// https://github.com/kleisauke/net-vips/issues/6#issuecomment-394379299 + private static void InitNetVips() + { + Cache.MaxFiles = 0; + + } } diff --git a/API/Services/DirectoryService.cs b/API/Services/DirectoryService.cs index c131a25db..7e308d92e 100644 --- a/API/Services/DirectoryService.cs +++ b/API/Services/DirectoryService.cs @@ -1112,4 +1112,23 @@ public class DirectoryService : IDirectoryService FlattenDirectory(root, subDirectory, ref directoryIndex); } } + + /// + /// If the file is locked or not existing + /// + /// + /// + public static bool IsFileLocked(string filePath) + { + try + { + if (!File.Exists(filePath)) return false; + using var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.None); + return false; // If this works, the file is not locked + } + catch (IOException) + { + return true; // File is locked by another process + } + } } diff --git a/API/Services/Tasks/Metadata/CoverDbService.cs b/API/Services/Tasks/Metadata/CoverDbService.cs index 80028f750..cebf08b97 100644 --- a/API/Services/Tasks/Metadata/CoverDbService.cs +++ b/API/Services/Tasks/Metadata/CoverDbService.cs @@ -643,10 +643,8 @@ public class CoverDbService : ICoverDbService if (choseNewImage) { - - File.Delete(existingPath); - - //_directoryService.DeleteFiles([existingPath]); + // This will fail if Cover gen is done just before this as there is a bug with files getting locked. + _directoryService.DeleteFiles([existingPath]); _directoryService.CopyFile(tempFullPath, finalFullPath); _directoryService.DeleteFiles([tempFullPath]); } @@ -698,11 +696,11 @@ public class CoverDbService : ICoverDbService /// /// /// - /// + /// Filename without extension /// /// Not useable with fromBase64. Allows a different directory to be written to /// - private async Task CreateThumbnail(string url, string filename, bool fromBase64 = true, string? targetDirectory = null) + private async Task CreateThumbnail(string url, string filenameWithoutExtension, bool fromBase64 = true, string? targetDirectory = null) { targetDirectory ??= _directoryService.CoverImageDirectory; @@ -713,9 +711,9 @@ public class CoverDbService : ICoverDbService if (fromBase64) { return _imageService.CreateThumbnailFromBase64(url, - filename, encodeFormat, coverImageSize.GetDimensions().Width); + filenameWithoutExtension, encodeFormat, coverImageSize.GetDimensions().Width); } - return await DownloadImageFromUrl(filename, encodeFormat, url, targetDirectory); + return await DownloadImageFromUrl(filenameWithoutExtension, encodeFormat, url, targetDirectory); } } diff --git a/API/Services/Tasks/Scanner/ProcessSeries.cs b/API/Services/Tasks/Scanner/ProcessSeries.cs index 59721fe61..454c72733 100644 --- a/API/Services/Tasks/Scanner/ProcessSeries.cs +++ b/API/Services/Tasks/Scanner/ProcessSeries.cs @@ -194,8 +194,8 @@ public class ProcessSeries : IProcessSeries if (seriesAdded) { // See if any recommendations can link up to the series and pre-fetch external metadata for the series - BackgroundJob.Enqueue(() => - _externalMetadataService.FetchSeriesMetadata(series.Id, series.Library.Type)); + // BackgroundJob.Enqueue(() => + // _externalMetadataService.FetchSeriesMetadata(series.Id, series.Library.Type)); await _eventHub.SendMessageAsync(MessageFactory.SeriesAdded, MessageFactory.SeriesAddedEvent(series.Id, series.Name, series.LibraryId), false); @@ -214,6 +214,10 @@ public class ProcessSeries : IProcessSeries return; } + if (seriesAdded) + { + await _externalMetadataService.FetchSeriesMetadata(series.Id, series.Library.Type); + } await _metadataService.GenerateCoversForSeries(series.LibraryId, series.Id, false, false); await _wordCountAnalyzerService.ScanSeries(series.LibraryId, series.Id, forceUpdate); }