I wasn't able to fix the locking of the files, but I reordered the scanner to first perform the metadata download then try and generate cover images.

This commit is contained in:
Joseph Milazzo 2025-05-03 14:23:05 -05:00
parent dab3377ded
commit acdf187fa0
4 changed files with 45 additions and 10 deletions

View file

@ -20,9 +20,11 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using NetVips;
using Serilog; using Serilog;
using Serilog.Events; using Serilog.Events;
using Serilog.Sinks.AspNetCore.SignalR.Extensions; using Serilog.Sinks.AspNetCore.SignalR.Extensions;
using Log = Serilog.Log;
namespace API; namespace API;
#nullable enable #nullable enable
@ -143,6 +145,8 @@ public class Program
var settings = await unitOfWork.SettingsRepository.GetSettingsDtoAsync(); var settings = await unitOfWork.SettingsRepository.GetSettingsDtoAsync();
LogLevelOptions.SwitchLogLevel(settings.LoggingLevel); LogLevelOptions.SwitchLogLevel(settings.LoggingLevel);
InitNetVips();
await host.RunAsync(); await host.RunAsync();
} catch (Exception ex) } catch (Exception ex)
{ {
@ -225,4 +229,14 @@ public class Program
webBuilder.UseStartup<Startup>(); webBuilder.UseStartup<Startup>();
}); });
/// <summary>
/// Ensure NetVips does not cache
/// </summary>
/// <remarks>https://github.com/kleisauke/net-vips/issues/6#issuecomment-394379299</remarks>
private static void InitNetVips()
{
Cache.MaxFiles = 0;
}
} }

View file

@ -1112,4 +1112,23 @@ public class DirectoryService : IDirectoryService
FlattenDirectory(root, subDirectory, ref directoryIndex); FlattenDirectory(root, subDirectory, ref directoryIndex);
} }
} }
/// <summary>
/// If the file is locked or not existing
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
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
}
}
} }

View file

@ -643,10 +643,8 @@ public class CoverDbService : ICoverDbService
if (choseNewImage) if (choseNewImage)
{ {
// This will fail if Cover gen is done just before this as there is a bug with files getting locked.
File.Delete(existingPath); _directoryService.DeleteFiles([existingPath]);
//_directoryService.DeleteFiles([existingPath]);
_directoryService.CopyFile(tempFullPath, finalFullPath); _directoryService.CopyFile(tempFullPath, finalFullPath);
_directoryService.DeleteFiles([tempFullPath]); _directoryService.DeleteFiles([tempFullPath]);
} }
@ -698,11 +696,11 @@ public class CoverDbService : ICoverDbService
/// ///
/// </summary> /// </summary>
/// <param name="url"></param> /// <param name="url"></param>
/// <param name="filename"></param> /// <param name="filenameWithoutExtension">Filename without extension</param>
/// <param name="fromBase64"></param> /// <param name="fromBase64"></param>
/// <param name="targetDirectory">Not useable with fromBase64. Allows a different directory to be written to</param> /// <param name="targetDirectory">Not useable with fromBase64. Allows a different directory to be written to</param>
/// <returns></returns> /// <returns></returns>
private async Task<string> CreateThumbnail(string url, string filename, bool fromBase64 = true, string? targetDirectory = null) private async Task<string> CreateThumbnail(string url, string filenameWithoutExtension, bool fromBase64 = true, string? targetDirectory = null)
{ {
targetDirectory ??= _directoryService.CoverImageDirectory; targetDirectory ??= _directoryService.CoverImageDirectory;
@ -713,9 +711,9 @@ public class CoverDbService : ICoverDbService
if (fromBase64) if (fromBase64)
{ {
return _imageService.CreateThumbnailFromBase64(url, 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);
} }
} }

View file

@ -194,8 +194,8 @@ public class ProcessSeries : IProcessSeries
if (seriesAdded) if (seriesAdded)
{ {
// See if any recommendations can link up to the series and pre-fetch external metadata for the series // See if any recommendations can link up to the series and pre-fetch external metadata for the series
BackgroundJob.Enqueue(() => // BackgroundJob.Enqueue(() =>
_externalMetadataService.FetchSeriesMetadata(series.Id, series.Library.Type)); // _externalMetadataService.FetchSeriesMetadata(series.Id, series.Library.Type));
await _eventHub.SendMessageAsync(MessageFactory.SeriesAdded, await _eventHub.SendMessageAsync(MessageFactory.SeriesAdded,
MessageFactory.SeriesAddedEvent(series.Id, series.Name, series.LibraryId), false); MessageFactory.SeriesAddedEvent(series.Id, series.Name, series.LibraryId), false);
@ -214,6 +214,10 @@ public class ProcessSeries : IProcessSeries
return; return;
} }
if (seriesAdded)
{
await _externalMetadataService.FetchSeriesMetadata(series.Id, series.Library.Type);
}
await _metadataService.GenerateCoversForSeries(series.LibraryId, series.Id, false, false); await _metadataService.GenerateCoversForSeries(series.LibraryId, series.Id, false, false);
await _wordCountAnalyzerService.ScanSeries(series.LibraryId, series.Id, forceUpdate); await _wordCountAnalyzerService.ScanSeries(series.LibraryId, series.Id, forceUpdate);
} }