forked from amkovkov/GranuSightSoftware2
feat: ImageSotrage clear
This commit is contained in:
@@ -26,6 +26,7 @@ public class ImageStorageService
|
|||||||
{
|
{
|
||||||
var fileName = GenerateFileName(extension);
|
var fileName = GenerateFileName(extension);
|
||||||
var fullPath = GetFullPath(fileName, subDirectory);
|
var fullPath = GetFullPath(fileName, subDirectory);
|
||||||
|
System.Diagnostics.Debug.Assert(fullPath is not null);
|
||||||
|
|
||||||
var directory = Path.GetDirectoryName(fullPath)!;
|
var directory = Path.GetDirectoryName(fullPath)!;
|
||||||
Directory.CreateDirectory(directory);
|
Directory.CreateDirectory(directory);
|
||||||
@@ -45,20 +46,25 @@ public class ImageStorageService
|
|||||||
return fileName;
|
return fileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Stream OpenRead(string fileName, string subDirectory)
|
public Stream OpenRead(string fileName, string? subDirectory = null)
|
||||||
{
|
{
|
||||||
var fullPath = GetFullPath(fileName, subDirectory);
|
var fullPath = GetFullPath(fileName, subDirectory);
|
||||||
|
if (fullPath is null)
|
||||||
|
throw new FileNotFoundException(null, fullPath);
|
||||||
return new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
return new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Delete(string fileName, string subDirectory)
|
public bool Delete(string fileName, string? subDirectory = null)
|
||||||
{
|
{
|
||||||
var fullPath = GetFullPath(fileName, subDirectory);
|
var fullPath = GetFullPath(fileName, subDirectory);
|
||||||
|
if (fullPath is null)
|
||||||
|
throw new FileNotFoundException(null, fullPath);
|
||||||
|
|
||||||
if (!File.Exists(fullPath))
|
if (!File.Exists(fullPath))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
File.Delete(fullPath);
|
File.Delete(fullPath);
|
||||||
|
_logger.LogInformation("File removed: {}", fileName);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,11 +74,29 @@ public class ImageStorageService
|
|||||||
return $"{guid}{extension}";
|
return $"{guid}{extension}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetFullPath(string fileName, string subDirectory)
|
public string? GetFullPath(string fileName, string? subDirectory = null)
|
||||||
{
|
{
|
||||||
var level1 = fileName.Substring(0, 2);
|
var level1 = fileName.Substring(0, 2);
|
||||||
var level2 = fileName.Substring(2, 2);
|
var level2 = fileName.Substring(2, 2);
|
||||||
|
|
||||||
return Path.Combine(_rootDirectory.FullName, subDirectory, level1, level2, fileName);
|
if (subDirectory is not null)
|
||||||
|
return Path.Combine(_rootDirectory.FullName, subDirectory, level1, level2, fileName);
|
||||||
|
|
||||||
|
return ListFiles()
|
||||||
|
.FirstOrDefault(File.Exists);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<string> ListFiles(string? subDirectory = null)
|
||||||
|
{
|
||||||
|
if (subDirectory is not null)
|
||||||
|
return Directory.GetDirectories(Path.Join(_rootDirectory.FullName, subDirectory))
|
||||||
|
.SelectMany(Directory.GetDirectories)
|
||||||
|
.SelectMany(Directory.GetFiles)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
return Directory.GetDirectories(_rootDirectory.FullName)
|
||||||
|
.Select(Path.GetFileName)
|
||||||
|
.SelectMany(ListFiles)
|
||||||
|
.ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -95,6 +95,12 @@ public partial class Program
|
|||||||
DefaultValueFactory = (_) => 0
|
DefaultValueFactory = (_) => 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static readonly Command _imageStorageClearCommand = new("image-storage-clear")
|
||||||
|
{
|
||||||
|
Description = "Clear image storage from unused images"
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
public static event ConsoleCancelEventHandler? ShutdownRequested;
|
public static event ConsoleCancelEventHandler? ShutdownRequested;
|
||||||
|
|
||||||
[STAThread]
|
[STAThread]
|
||||||
@@ -124,6 +130,9 @@ public partial class Program
|
|||||||
_captureCommand.Add(_captureIntencityUv365nm);
|
_captureCommand.Add(_captureIntencityUv365nm);
|
||||||
_captureCommand.Add(_captureIntencityUv254nm);
|
_captureCommand.Add(_captureIntencityUv254nm);
|
||||||
|
|
||||||
|
_rootCommand.Add(_imageStorageClearCommand);
|
||||||
|
_imageStorageClearCommand.SetAction(ImageStorageClear);
|
||||||
|
|
||||||
Console.CancelKeyPress += new ConsoleCancelEventHandler(OnProgramShutdown);
|
Console.CancelKeyPress += new ConsoleCancelEventHandler(OnProgramShutdown);
|
||||||
Console.WriteLine("Press Ctrl+C to shut down.");
|
Console.WriteLine("Press Ctrl+C to shut down.");
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
using System.CommandLine;
|
||||||
|
|
||||||
|
using GSS2.Core;
|
||||||
|
using GSS2.Core.Analysis.AmineContent.Database.Calibration;
|
||||||
|
using GSS2.Core.Hardware;
|
||||||
|
using GSS2.Core.Logging;
|
||||||
|
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.Logging.Console;
|
||||||
|
|
||||||
|
using OpenCvSharp;
|
||||||
|
|
||||||
|
using ConsoleFormatter = GSS2.Core.Logging.ConsoleFormatter;
|
||||||
|
|
||||||
|
namespace GSS2.Test;
|
||||||
|
|
||||||
|
public partial class Program
|
||||||
|
{
|
||||||
|
private class ImagesStorateClearWorker : BackgroundService
|
||||||
|
{
|
||||||
|
private readonly ILogger<ImagesStorateClearWorker> _logger;
|
||||||
|
private readonly IHostApplicationLifetime _applicationLifetime;
|
||||||
|
private readonly AmineContentCalibrationContext _context;
|
||||||
|
private readonly ImageStorageService _imageStorageService;
|
||||||
|
|
||||||
|
public ImagesStorateClearWorker(ILogger<ImagesStorateClearWorker> logger, IHostApplicationLifetime applicationLifetime, AmineContentCalibrationContext context, ImageStorageService imageStorageService)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_applicationLifetime = applicationLifetime;
|
||||||
|
_context = context;
|
||||||
|
_imageStorageService = imageStorageService;
|
||||||
|
|
||||||
|
_logger.LogInformation("Initialized");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Running images storage clear");
|
||||||
|
|
||||||
|
var unusedFiles = _imageStorageService.ListFiles()
|
||||||
|
.Select(Path.GetFileName)
|
||||||
|
.OfType<string>()
|
||||||
|
.Where(f => !_context.ImageRecords.Any(r => r.ImagePath == f));
|
||||||
|
|
||||||
|
if (unusedFiles is null || unusedFiles.Count() == 0)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Unused images not found");
|
||||||
|
_applicationLifetime.StopApplication();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.LogInformation("Found {} unused image(s):\n\t{}", unusedFiles.Count(), string.Join("\n\t", unusedFiles));
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Delete this files? (y/n) ");
|
||||||
|
var input = Console.ReadLine()?.Trim();
|
||||||
|
if (input == "y")
|
||||||
|
{
|
||||||
|
foreach (var file in unusedFiles)
|
||||||
|
_imageStorageService.Delete(file);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (input == "n")
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
_applicationLifetime.StopApplication();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
private static void ImageStorageClear(ParseResult parseResult)
|
||||||
|
{
|
||||||
|
var builder = Host.CreateApplicationBuilder();
|
||||||
|
|
||||||
|
builder.Logging.ClearProviders();
|
||||||
|
builder.Logging.AddConsole(options => options.FormatterName = nameof(ConsoleFormatter));
|
||||||
|
builder.Logging.AddConsoleFormatter<ConsoleFormatter, ConsoleFormatterOptions>();
|
||||||
|
builder.Logging.AddProvider(new FileLoggerProvider("full.log", true));
|
||||||
|
builder.Logging.AddProvider(new FileLoggerProvider("last_run.log", false));
|
||||||
|
builder.Services.AddSingleton<LibCameraLogSink>();
|
||||||
|
|
||||||
|
builder.Services.AddAmineContentCalibrationContext(builder.Configuration);
|
||||||
|
builder.Services.AddImageStorageService(new DirectoryInfo("images"));
|
||||||
|
|
||||||
|
builder.Services.AddHostedService<ImagesStorateClearWorker>();
|
||||||
|
|
||||||
|
var host = builder.Build();
|
||||||
|
|
||||||
|
using (var scope = host.Services.CreateScope())
|
||||||
|
{
|
||||||
|
var context = scope.ServiceProvider.GetRequiredService<AmineContentCalibrationContext>();
|
||||||
|
context.Database.Migrate();
|
||||||
|
}
|
||||||
|
|
||||||
|
host.Run();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user