76 lines
2.7 KiB
C#
76 lines
2.7 KiB
C#
using System.Threading.Channels;
|
|
using NLog;
|
|
using PiwigoDirectorySync.Persistence;
|
|
|
|
namespace PiwigoDirectorySync.Commands.Scan;
|
|
|
|
public class FileSystemScanner
|
|
{
|
|
private static readonly ILogger Logger = LogManager.GetCurrentClassLogger();
|
|
|
|
private readonly Channel<string> _fileQueue;
|
|
private readonly int _piwigoServerId;
|
|
|
|
public FileSystemScanner(Channel<string> fileQueue, int piwigoServerId)
|
|
{
|
|
_fileQueue = fileQueue ?? throw new ArgumentNullException(nameof(fileQueue));
|
|
_piwigoServerId = piwigoServerId;
|
|
}
|
|
|
|
public async Task ScanAsync(CancellationToken ct)
|
|
{
|
|
await using var db = new PersistenceContext();
|
|
|
|
var piwigoServer = await db.PiwigoServers.GetByIdAsync(_piwigoServerId, ct);
|
|
Logger.Info($"Scanning files for piwigo server {piwigoServer.Name} in directory {piwigoServer.RootDirectory}");
|
|
|
|
await ScanRootDirectory(new DirectoryInfo(piwigoServer.RootDirectory), ct);
|
|
}
|
|
|
|
private async ValueTask ScanRootDirectory(DirectoryInfo directory, CancellationToken ct)
|
|
{
|
|
Logger.Info($"Scanning root directory {directory.FullName} for sidecars to delete");
|
|
var parallelOptions = new ParallelOptions
|
|
{
|
|
CancellationToken = ct
|
|
};
|
|
await Parallel.ForEachAsync(GetDirectories(directory), parallelOptions, FindAndEnqueueFilesToAdd);
|
|
}
|
|
|
|
private async ValueTask FindAndEnqueueFilesToAdd(DirectoryInfo directory, CancellationToken ct)
|
|
{
|
|
try
|
|
{
|
|
Logger.Info($"Scanning directory {directory.FullName} for images");
|
|
|
|
var imageFiles = AppSettings.SupportedExtensions.SelectMany(ext => directory.GetFiles($"*.{ext}", SearchOption.TopDirectoryOnly))
|
|
.Select(f => f.FullName)
|
|
.ToHashSet(StringComparer.OrdinalIgnoreCase);
|
|
|
|
if (!imageFiles.Any())
|
|
{
|
|
Logger.Debug($"No iamges in {directory.FullName} found, skipping");
|
|
return;
|
|
}
|
|
|
|
foreach (var imageFile in imageFiles.Select(f => new FileInfo(f)))
|
|
{
|
|
Logger.Debug($"Found image {imageFile.FullName}, enqueue index");
|
|
await _fileQueue.Writer.WriteAsync(imageFile.FullName, ct);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Error(ex, $"could not scan directory {directory.FullName}");
|
|
}
|
|
}
|
|
|
|
private static IEnumerable<DirectoryInfo> GetDirectories(DirectoryInfo directoryInfo)
|
|
{
|
|
yield return directoryInfo;
|
|
foreach (var directory in directoryInfo.EnumerateDirectories().SelectMany(GetDirectories))
|
|
{
|
|
yield return directory;
|
|
}
|
|
}
|
|
} |