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.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<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);
}
}
/// <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)
{
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
///
/// </summary>
/// <param name="url"></param>
/// <param name="filename"></param>
/// <param name="filenameWithoutExtension">Filename without extension</param>
/// <param name="fromBase64"></param>
/// <param name="targetDirectory">Not useable with fromBase64. Allows a different directory to be written to</param>
/// <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;
@ -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);
}
}

View file

@ -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);
}