feat: Implement Face AI functionality and race upload settings in Avalonia UI

This commit is contained in:
MaddoScientisto 2026-02-28 21:34:45 +01:00
commit 6cf0c029fc
4 changed files with 528 additions and 191 deletions

View file

@ -51,8 +51,8 @@ namespace ImageCatalog_2
public List<string> VerticalPositions { get; } = new() { "Alto", "Centro", "Basso" };
public List<string> HorizontalAlignments { get; } = new() { "Sinistra", "Centro", "Destra" };
public DataModel(ITestService testService, ISettingsService settingsService,
ImageCreationService imageCreationService, PicSettings picSettings,
public DataModel(ITestService testService, ISettingsService settingsService,
ImageCreationService imageCreationService, PicSettings picSettings,
IMapper mapper, ILogger<DataModel> logger, MaddoShared.IVersionProvider? versionProvider = null)
{
_service = testService;
@ -70,7 +70,7 @@ namespace ImageCatalog_2
ProcessImagesCommand = new AsyncCommand(ProcessImages);
SelectModelsFolderCommand = new RelayCommand(SelectModelsFolder);
SelectCsvOutputCommand = new RelayCommand(SelectCsvOutput);
SelectSourceFolderCommand = new RelayCommand(SelectSourceFolder);
SelectDestinationFolderCommand = new RelayCommand(SelectDestinationFolder);
SelectLogoFileCommand = new RelayCommand(SelectLogoFile);
@ -251,6 +251,112 @@ namespace ImageCatalog_2
set { _csvOutputPath = value; NotifyPropertyChanged(); }
}
private string _faceExecutablePath = string.Empty;
public string FaceExecutablePath
{
get => _faceExecutablePath;
set { _faceExecutablePath = value; NotifyPropertyChanged(); }
}
private string _faceOutputFolderPath = string.Empty;
public string FaceOutputFolderPath
{
get => _faceOutputFolderPath;
set { _faceOutputFolderPath = value; NotifyPropertyChanged(); }
}
// Race upload settings
private string _apiLogin = string.Empty;
public string ApiLogin
{
get => _apiLogin;
set { _apiLogin = value; NotifyPropertyChanged(); }
}
private string _apiPassword = string.Empty;
public string ApiPassword
{
get => _apiPassword;
set { _apiPassword = value; NotifyPropertyChanged(); }
}
private string _apiRaceDescription = string.Empty;
public string ApiRaceDescription
{
get => _apiRaceDescription;
set { _apiRaceDescription = value; NotifyPropertyChanged(); }
}
private string _apiRaceTypeId = "1";
public string ApiRaceTypeId
{
get => _apiRaceTypeId;
set { _apiRaceTypeId = value; NotifyPropertyChanged(); }
}
private DateTime _apiRaceStartDate = DateTime.Today;
public DateTime ApiRaceStartDate
{
get => _apiRaceStartDate;
set { _apiRaceStartDate = value; NotifyPropertyChanged(); }
}
private DateTime _apiRaceEndDate = DateTime.Today;
public DateTime ApiRaceEndDate
{
get => _apiRaceEndDate;
set { _apiRaceEndDate = value; NotifyPropertyChanged(); }
}
private string _apiPathBase = string.Empty;
public string ApiPathBase
{
get => _apiPathBase;
set { _apiPathBase = value; NotifyPropertyChanged(); }
}
private string _apiLocalita = string.Empty;
public string ApiLocalita
{
get => _apiLocalita;
set { _apiLocalita = value; NotifyPropertyChanged(); }
}
private int _apiEventoInLineaIndex = 0;
public int ApiEventoInLineaIndex
{
get => _apiEventoInLineaIndex;
set { _apiEventoInLineaIndex = value; NotifyPropertyChanged(); }
}
private int _apiTipoIndexValue = 1;
public int ApiTipoIndexValue
{
get => _apiTipoIndexValue;
set { _apiTipoIndexValue = value; NotifyPropertyChanged(); }
}
private int _apiFreeEventIndex = 0;
public int ApiFreeEventIndex
{
get => _apiFreeEventIndex;
set { _apiFreeEventIndex = value; NotifyPropertyChanged(); }
}
private string _apiRaceId = string.Empty;
public string ApiRaceId
{
get => _apiRaceId;
set { _apiRaceId = value; NotifyPropertyChanged(); }
}
private string _apiRemoteProcessedBasePath = string.Empty;
public string ApiRemoteProcessedBasePath
{
get => _apiRemoteProcessedBasePath;
set { _apiRemoteProcessedBasePath = value; NotifyPropertyChanged(); }
}
// Preview results for DataGrid
private System.Collections.ObjectModel.ObservableCollection<AiResult> _previewResults = new();
public System.Collections.ObjectModel.ObservableCollection<AiResult> PreviewResults => _previewResults;
@ -1266,7 +1372,7 @@ namespace ImageCatalog_2
// Fix paths
FixPaths();
// Reset counters
ProcessingStatus = "Elaborazione in corso...";
TotalImagesCount = 0;
@ -1274,7 +1380,7 @@ namespace ImageCatalog_2
SpeedCounter = "-f/s";
ProgressBarValue = 0;
ProgressBarMaximum = 100;
// Update PicSettings from DataModel using AutoMapper
_mapper.Map(this, _picSettings);
// Explicitly ensure thumbnail-related flags are applied to PicSettings
@ -1295,7 +1401,7 @@ namespace ImageCatalog_2
{
// Best-effort; do not fail processing on mapping issues
}
var imageCreationOptions = new ImageCreationService.Options
{
AggiornaSottodirectory = UpdateSubdirectories,
@ -1317,16 +1423,16 @@ namespace ImageCatalog_2
_currentAmount = 0;
_previousAmount = 0;
_processedAtomic = 0;
// Start speed timer (sample every second using lightweight atomic reads)
_speedWatch = Stopwatch.StartNew();
_recentDiffs.Clear();
_speedTimer = new System.Threading.Timer(UpdateSpeedCounter, null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
var time = await _imageCreationService.CreaCatalogoParallel(
imageCreationOptions,
_results,
OnImageProcessed,
imageCreationOptions,
_results,
OnImageProcessed,
token);
// AI integration stub: if ExtractNumbers is enabled, simulate or invoke OCR processing
@ -1345,7 +1451,7 @@ namespace ImageCatalog_2
_logger.LogError(ex, "AI extraction failed");
}
}
// Compute final averages and show only averages (do not show raw seconds)
var finalProcessed = System.Threading.Volatile.Read(ref _processedAtomic);
double overallAvg = 0.0;