big refactoring. get rid of static properties and coupled architecture. prepare system for integration tests

This commit is contained in:
Oleksandr Bezdieniezhnykh
2025-11-17 13:14:05 +02:00
parent 22529c26ec
commit e7ea5a8ded
38 changed files with 808 additions and 157 deletions
+19 -13
View File
@@ -26,11 +26,15 @@ public class GalleryService(
IOptions<ThumbnailConfig> thumbnailConfig,
IOptions<AnnotationConfig> annotationConfig,
ILogger<GalleryService> logger,
IDbFactory dbFactory) : IGalleryService
IDbFactory dbFactory,
IAnnotationPathResolver pathResolver,
IFileSystem fileSystem) : IGalleryService
{
private readonly DirectoriesConfig _dirConfig = directoriesConfig.Value;
private readonly ThumbnailConfig _thumbnailConfig = thumbnailConfig.Value;
private readonly AnnotationConfig _annotationConfig = annotationConfig.Value;
private readonly IAnnotationPathResolver _pathResolver = pathResolver;
private readonly IFileSystem _fileSystem = fileSystem;
public event ThumbnailsUpdatedEventHandler? ThumbnailsUpdate;
@@ -58,8 +62,9 @@ public class GalleryService(
public async Task ClearThumbnails(CancellationToken cancellationToken = default)
{
foreach(var file in new DirectoryInfo(_dirConfig.ThumbnailsDirectory).GetFiles())
file.Delete();
var thumbDir = _fileSystem.GetDirectoryInfo(_dirConfig.ThumbnailsDirectory);
foreach(var file in thumbDir.GetFiles())
_fileSystem.DeleteFile(file.FullName);
await dbFactory.RunWrite(async db =>
{
await db.Detections.DeleteAsync(x => true, token: cancellationToken);
@@ -83,7 +88,8 @@ public class GalleryService(
.Select(gr => gr.Key)
.ToHashSet();
var files = new DirectoryInfo(_dirConfig.ImagesDirectory).GetFiles();
var imagesDir = _fileSystem.GetDirectoryInfo(_dirConfig.ImagesDirectory);
var files = imagesDir.GetFiles();
var imagesCount = files.Length;
await ParallelExt.ForEachAsync(files, async (file, cancellationToken) =>
@@ -92,9 +98,9 @@ public class GalleryService(
try
{
var labelName = Path.Combine(_dirConfig.LabelsDirectory, $"{fName}.txt");
if (!File.Exists(labelName))
if (!_fileSystem.FileExists(labelName))
{
File.Delete(file.FullName);
_fileSystem.DeleteFile(file.FullName);
logger.LogInformation($"No labels found for image {file.FullName}! Image deleted!");
await dbFactory.DeleteAnnotations([fName], cancellationToken);
return;
@@ -213,7 +219,7 @@ public class GalleryService(
var width = (int)_thumbnailConfig.Size.Width;
var height = (int)_thumbnailConfig.Size.Height;
originalImage ??= Image.FromStream(new MemoryStream(await File.ReadAllBytesAsync(annotation.ImagePath, cancellationToken)));
originalImage ??= Image.FromStream(new MemoryStream(await _fileSystem.ReadAllBytesAsync(_pathResolver.GetImagePath(annotation), cancellationToken)));
var bitmap = new Bitmap(width, height);
@@ -273,7 +279,7 @@ public class GalleryService(
g.DrawRectangle(new Pen(brush, width: 3), (float)((label.Left - frameX) / scale), (float)((label.Top - frameY) / scale), (float)(label.Width / scale), (float)(label.Height / scale));
}
bitmap.Save(annotation.ThumbPath, ImageFormat.Jpeg);
bitmap.Save(_pathResolver.GetThumbPath(annotation), ImageFormat.Jpeg);
}
catch (Exception e)
{
@@ -282,7 +288,7 @@ public class GalleryService(
}
public async Task CreateAnnotatedImage(Annotation annotation, Image? originalImage = null, CancellationToken token = default)
{
originalImage ??= Image.FromStream(new MemoryStream(await File.ReadAllBytesAsync(annotation.ImagePath, token)));
originalImage ??= Image.FromStream(new MemoryStream(await File.ReadAllBytesAsync(_pathResolver.GetImagePath(annotation), token)));
using var g = Graphics.FromImage(originalImage);
foreach (var detection in annotation.Detections)
@@ -297,11 +303,11 @@ public class GalleryService(
g.DrawTextBox(label, new PointF((float)(det.Left + det.Width / 2.0), (float)(det.Top - 24)), brush, Brushes.Black);
}
var imagePath = Path.Combine(_dirConfig.ResultsDirectory, $"{annotation.Name}{Constants.RESULT_PREFIX}.jpg");
if (File.Exists(imagePath))
ResilienceExt.WithRetry(() => File.Delete(imagePath));
var resultPath = Path.Combine(_dirConfig.ResultsDirectory, $"{annotation.Name}{Constants.RESULT_PREFIX}.jpg");
if (_fileSystem.FileExists(resultPath))
ResilienceExt.WithRetry(() => _fileSystem.DeleteFile(resultPath));
originalImage.Save(imagePath, ImageFormat.Jpeg);
originalImage.Save(resultPath, ImageFormat.Jpeg);
}
}