Files
annotations/Azaion.Suite/App.xaml.cs
T
Oleksandr Bezdieniezhnykh 067f02cc63 update AI initializing
rework AIAvailabilityStatus events to mediatr
2025-09-01 20:12:13 +03:00

215 lines
8.7 KiB
C#

using System.IO;
using System.Net.Http;
using System.Text;
using System.Windows;
using System.Windows.Threading;
using Azaion.Annotator;
using Azaion.Common;
using Azaion.Common.Database;
using Azaion.Common.DTO;
using Azaion.Common.DTO.Config;
using Azaion.Common.Events;
using Azaion.Common.Extensions;
using Azaion.Common.Services;
using Azaion.Common.Services.Inference;
using Azaion.Dataset;
using CommandLine;
using LibVLCSharp.Shared;
using MediatR;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Serilog;
using KeyEventArgs = System.Windows.Input.KeyEventArgs;
namespace Azaion.Suite;
public partial class App
{
private IMediator _mediator = null!;
private FormState _formState = null!;
private IHost _host = null!;
private static readonly Guid KeyPressTaskId = Guid.NewGuid();
private LoaderClient _loaderClient = null!;
private readonly ICache _cache = new MemoryCache();
private readonly CancellationTokenSource _mainCTokenSource = new();
private void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
Log.Logger.Error(e.Exception, "Unhandled exception");
e.Handled = true;
}
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.MinimumLevel.Information()
.WriteTo.Console()
.WriteTo.File(
path: "Logs/log.txt",
rollingInterval: RollingInterval.Day)
.CreateLogger();
Parser.Default.ParseArguments<ApiCredentials, ApiCredentialsEncrypted>(e.Args)
.WithParsed<ApiCredentials>(Start)
.WithParsed<ApiCredentialsEncrypted>(StartEncrypted)
.WithNotParsed(ErrorHandling);
}
private void ErrorHandling(IEnumerable<Error> obj)
{
Log.Fatal($"Error happened: {string.Join(",", obj.Select(x =>
{
if (x is MissingRequiredOptionError err)
return $"{err.Tag} {err.NameInfo.NameText}";
return x.Tag.ToString();
} ))}");
Current.Shutdown();
}
private Stream GetConfig(LoaderClient loaderClient, string filename, string? apiDir)
{
try
{
return loaderClient.LoadFile(filename, apiDir ?? "");
}
catch (Exception e)
{
Log.Logger.Error(e, e.Message);
throw;
}
}
private void StartEncrypted(ApiCredentialsEncrypted credsEncrypted)
{
Log.Logger.Information(credsEncrypted.Creds);
Start(Security.Decrypt<ApiCredentials>(credsEncrypted.Creds));
}
private void Start(ApiCredentials credentials)
{
try
{
new ConfigUpdater().CheckConfig();
var initConfig = Constants.ReadInitConfig(Log.Logger);
var apiDir = initConfig.DirectoriesConfig.ApiResourcesDirectory;
_loaderClient = new LoaderClient(initConfig.LoaderClientConfig, Log.Logger, _mainCTokenSource.Token);
_loaderClient.StartClient();
_loaderClient.Connect();
_loaderClient.Login(credentials);
var azaionApi = new AzaionApi(Log.Logger, new HttpClient { BaseAddress = new Uri(initConfig.InferenceClientConfig.ApiUrl) }, _cache, credentials);
_host = Host.CreateDefaultBuilder()
.ConfigureAppConfiguration((_, config) => config
.AddCommandLine(Environment.GetCommandLineArgs())
.AddJsonFile(Constants.CONFIG_PATH, optional: true, reloadOnChange: true)
.AddJsonStream(GetConfig(_loaderClient, "config.system.json", apiDir))
.AddJsonStream(GetConfig(_loaderClient, "config.secured.json", apiDir)))
.UseSerilog()
.ConfigureServices((context, services) =>
{
services.AddSingleton<MainSuite>();
services.Configure<AppConfig>(context.Configuration);
services.ConfigureSection<QueueConfig>(context.Configuration);
services.ConfigureSection<DirectoriesConfig>(context.Configuration);
services.ConfigureSection<AnnotationConfig>(context.Configuration);
services.ConfigureSection<AIRecognitionConfig>(context.Configuration);
services.ConfigureSection<GpsDeniedConfig>(context.Configuration);
services.ConfigureSection<ThumbnailConfig>(context.Configuration);
services.ConfigureSection<UIConfig>(context.Configuration);
services.ConfigureSection<MapConfig>(context.Configuration);
#region External Services
services.ConfigureSection<LoaderClientConfig>(context.Configuration);
services.AddSingleton(_loaderClient);
services.ConfigureSection<InferenceClientConfig>(context.Configuration);
services.AddSingleton<IInferenceClient, InferenceClient>();
services.AddSingleton<IInferenceService, InferenceService>();
services.ConfigureSection<GpsDeniedClientConfig>(context.Configuration);
services.AddSingleton<IGpsMatcherClient, GpsMatcherClient>();
services.AddSingleton<IGpsMatcherService, GpsMatcherService>();
services.AddSingleton<ISatelliteDownloader, SatelliteDownloader>();
services.AddHttpClient();
services.AddSingleton<IAzaionApi>(azaionApi);
#endregion
services.AddSingleton<IConfigUpdater, ConfigUpdater>();
services.AddSingleton<Annotator.Annotator>();
services.AddSingleton<DatasetExplorer>();
services.AddSingleton<HelpWindow>();
services.AddMediatR(c => c.RegisterServicesFromAssemblies(
typeof(Annotator.Annotator).Assembly,
typeof(DatasetExplorer).Assembly,
typeof(AnnotationService).Assembly));
services.AddSingleton<LibVLC>(_ => new LibVLC("--no-osd", "--no-video-title-show", "--no-snapshot-preview"));
services.AddSingleton<FormState>();
services.AddSingleton<MediaPlayer>(sp =>
{
var libVlc = sp.GetRequiredService<LibVLC>();
return new MediaPlayer(libVlc);
});
services.AddSingleton<AnnotatorEventHandler>();
services.AddSingleton<IDbFactory, DbFactory>();
services.AddSingleton<FailsafeAnnotationsProducer>();
services.AddSingleton<IAnnotationService, AnnotationService>();
services.AddSingleton<DatasetExplorer>();
services.AddSingleton<IGalleryService, GalleryService>();
services.AddSingleton<IAzaionModule, AnnotatorModule>();
services.AddSingleton<IAzaionModule, DatasetExplorerModule>();
})
.Build();
Annotation.Init(_host.Services.GetRequiredService<IOptions<DirectoriesConfig>>().Value,
_host.Services.GetRequiredService<IOptions<AnnotationConfig>>().Value.DetectionClassesDict);
_host.Services.GetRequiredService<DatasetExplorer>();
_mediator = _host.Services.GetRequiredService<IMediator>();
_formState = _host.Services.GetRequiredService<FormState>();
DispatcherUnhandledException += OnDispatcherUnhandledException;
_host.Start();
EventManager.RegisterClassHandler(typeof(UIElement), UIElement.PreviewKeyDownEvent, new RoutedEventHandler(GlobalKeyHandler));
_host.Services.GetRequiredService<MainSuite>().Show();
}
catch (Exception e)
{
Log.Logger.Error(e, e.Message);
throw;
}
}
private void GlobalKeyHandler(object sender, RoutedEventArgs e)
{
var args = (KeyEventArgs)e;
var keyEvent = new KeyEvent(sender, args, _formState.ActiveWindow);
ThrottleExt.Throttle(() => _mediator.Publish(keyEvent, _mainCTokenSource.Token), KeyPressTaskId, TimeSpan.FromMilliseconds(50));
//e.Handled = true;
}
protected override async void OnExit(ExitEventArgs e)
{
base.OnExit(e);
_loaderClient.Stop();
_loaderClient.Dispose();
await _host.StopAsync();
}
}