From 6bbe0d7e090538179cb5ff6863b37a1f3e28ae27 Mon Sep 17 00:00:00 2001 From: Alek-ban Date: Thu, 26 Feb 2026 07:50:15 +0300 Subject: [PATCH] feat: ImageStorageService --- GSS2.Core/DependencyInjectionHelper.cs | 11 ++++ GSS2.Core/Hardware/ImageStorageService.cs | 78 +++++++++++++++++++++++ GSS2.Test/PropgramUi.cs | 1 + 3 files changed, 90 insertions(+) create mode 100644 GSS2.Core/Hardware/ImageStorageService.cs diff --git a/GSS2.Core/DependencyInjectionHelper.cs b/GSS2.Core/DependencyInjectionHelper.cs index 1f0a858..ef04319 100644 --- a/GSS2.Core/DependencyInjectionHelper.cs +++ b/GSS2.Core/DependencyInjectionHelper.cs @@ -3,6 +3,7 @@ using Microsoft.IdentityModel.Protocols.Configuration; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; + using GSS2.Core.Hardware; using GSS2.Core.Analysis.AmineContent.Database; @@ -76,6 +77,16 @@ public static class DependencyInjectionHelper ); public static IServiceCollection AddComputeResourcesService(this IServiceCollection services) => services .AddSingleton(); + public static IServiceCollection AddImageStorageService(this IServiceCollection services, DirectoryInfo rootDirectory) => services + .AddSingleton( + serviceProvider => + { + var logger = serviceProvider.GetService>(); + if (logger is null) + throw new Exception("Cannot get logger"); + return new ImageStorageService(logger, rootDirectory); + } + ); public static IServiceCollection AddAmineContentCalibrationContext(this IServiceCollection services, IConfigurationManager configuration) => services .AddDbContext( diff --git a/GSS2.Core/Hardware/ImageStorageService.cs b/GSS2.Core/Hardware/ImageStorageService.cs new file mode 100644 index 0000000..018ff3e --- /dev/null +++ b/GSS2.Core/Hardware/ImageStorageService.cs @@ -0,0 +1,78 @@ +using Microsoft.Extensions.Logging; + +namespace GSS2.Core.Hardware; + +public class ImageStorageService +{ + private readonly ILogger _logger; + private readonly DirectoryInfo _rootDirectory; + + public ImageStorageService(ILogger logger, DirectoryInfo rootDirectory) + { + _logger = logger; + _logger.LogInformation("Initialization"); + + _rootDirectory = rootDirectory; + if (!_rootDirectory.Exists) + { + _rootDirectory.Create(); + _logger.LogInformation("Created directory: {}", _rootDirectory.FullName); + } + + _logger.LogInformation("Initialized"); + } + + public async Task SaveAsync(Stream fileStream, string extension, CancellationToken ct = default) + { + var fileName = GenerateFileName(extension); + var fullPath = GetFullPath(fileName); + + var directory = Path.GetDirectoryName(fullPath)!; + Directory.CreateDirectory(directory); + + await using var file = new FileStream( + fullPath, + FileMode.CreateNew, + FileAccess.Write, + FileShare.None, + 81920, + useAsync: true); + + await fileStream.CopyToAsync(file, ct); + + _logger.LogInformation("File saved: {FileName}", fileName); + + return fileName; + } + + public Stream OpenRead(string fileName) + { + var fullPath = GetFullPath(fileName); + return new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.Read); + } + + public bool Delete(string fileName) + { + var fullPath = GetFullPath(fileName); + + if (!File.Exists(fullPath)) + return false; + + File.Delete(fullPath); + return true; + } + + private string GenerateFileName(string extension) + { + var guid = Guid.NewGuid().ToString("N"); + return $"{guid}{extension}"; + } + + public string GetFullPath(string fileName) + { + var level1 = fileName.Substring(0, 2); + var level2 = fileName.Substring(2, 2); + + return Path.Combine(_rootDirectory.FullName, level1, level2, fileName); + } +} \ No newline at end of file diff --git a/GSS2.Test/PropgramUi.cs b/GSS2.Test/PropgramUi.cs index 5e103cf..d5739c1 100644 --- a/GSS2.Test/PropgramUi.cs +++ b/GSS2.Test/PropgramUi.cs @@ -71,6 +71,7 @@ public partial class Program builder.Services.AddIlluminatorService("Hardware:Illuminator"); builder.Services.AddCameraService("Hardware:Camera", true); builder.Services.AddComputeResourcesService(); + builder.Services.AddImageStorageService(new DirectoryInfo("images")); builder.Services.AddViewsAndModels();