Files
annotations/Azaion.Suite/App.xaml.cs
T
Alex Bezdieniezhnykh 80de2ad4d0 add gps matcher service
2025-04-14 10:20:01 +03:00

229 lines
8.8 KiB
C#

using System.IO;
using System.Reflection;
using System.Windows;
using System.Windows.Threading;
using Azaion.Annotator;
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.CommonSecurity;
using Azaion.CommonSecurity.DTO;
using Azaion.CommonSecurity.Services;
using Azaion.Dataset;
using LibVLCSharp.Shared;
using MediatR;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Serilog;
using KeyEventArgs = System.Windows.Input.KeyEventArgs;
namespace Azaion.Suite;
public partial class App
{
private IHost _host = null!;
private ILogger<App> _logger = null!;
private IMediator _mediator = null!;
private FormState _formState = null!;
private IInferenceClient _inferenceClient = null!;
private IResourceLoader _resourceLoader = null!;
private IAuthProvider _authProvider = null!;
private Stream _securedConfig = null!;
private Stream _systemConfig = null!;
private static readonly Guid KeyPressTaskId = Guid.NewGuid();
private void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
_logger.LogError(e.Exception, e.Exception.Message);
e.Handled = true;
}
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
StartLogin();
}
private readonly List<string> _encryptedResources =
[
"Azaion.Annotator",
"Azaion.Dataset"
];
private static SecureAppConfig ReadSecureAppConfig()
{
try
{
if (!File.Exists(SecurityConstants.CONFIG_PATH))
throw new FileNotFoundException(SecurityConstants.CONFIG_PATH);
var configStr = File.ReadAllText(SecurityConstants.CONFIG_PATH);
var config = JsonConvert.DeserializeObject<SecureAppConfig>(configStr);
return config ?? SecurityConstants.DefaultSecureAppConfig;
}
catch (Exception e)
{
Console.WriteLine(e);
return SecurityConstants.DefaultSecureAppConfig;
}
}
private void StartLogin()
{
new ConfigUpdater().CheckConfig();
var secureAppConfig = ReadSecureAppConfig();
_inferenceClient = new InferenceClient(new OptionsWrapper<InferenceClientConfig>(secureAppConfig.InferenceClientConfig));
_resourceLoader = new ResourceLoader(_inferenceClient);
_authProvider = new AuthProvider(_inferenceClient);
var login = new Login();
login.Closed += (sender, args) =>
{
if (!login.MainSuiteOpened)
_inferenceClient.Stop();
};
login.CredentialsEntered += (_, credentials) =>
{
credentials.Folder = secureAppConfig.InferenceClientConfig.ResourcesFolder;
_authProvider.Login(credentials);
_securedConfig = _resourceLoader.LoadFile("config.secured.json");
_systemConfig = _resourceLoader.LoadFile("config.system.json");
AppDomain.CurrentDomain.AssemblyResolve += (_, a) =>
{
var assemblyName = a.Name.Split(',').First();
if (_encryptedResources.Contains(assemblyName))
{
try
{
var stream = _resourceLoader.LoadFile($"{assemblyName}.dll");
return Assembly.Load(stream.ToArray());
}
catch (Exception e)
{
Console.WriteLine(e);
var currentLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!;
var dllPath = Path.Combine(currentLocation, SecurityConstants.DUMMY_DIR, $"{assemblyName}.dll");
return Assembly.LoadFile(dllPath);
}
}
var loadedAssembly = AppDomain.CurrentDomain.GetAssemblies()
.FirstOrDefault(a => a.GetName().Name == assemblyName);
return loadedAssembly;
};
StartMain();
_host.Start();
EventManager.RegisterClassHandler(typeof(UIElement), UIElement.KeyDownEvent, new RoutedEventHandler(GlobalClick));
_host.Services.GetRequiredService<MainSuite>().Show();
};
login.ShowDialog();
}
private void StartMain()
{
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.MinimumLevel.Information()
.WriteTo.Console()
.WriteTo.File(
path: "Logs/log.txt",
rollingInterval: RollingInterval.Day)
.CreateLogger();
_host = Host.CreateDefaultBuilder()
.ConfigureAppConfiguration((context, config) => config
.AddCommandLine(Environment.GetCommandLineArgs())
.AddJsonFile(SecurityConstants.CONFIG_PATH, optional: true, reloadOnChange: true)
.AddJsonStream(_securedConfig)
.AddJsonStream(_systemConfig))
.UseSerilog()
.ConfigureServices((context, services) =>
{
services.AddSingleton<MainSuite>();
services.AddSingleton<IHardwareService, HardwareService>();
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<ThumbnailConfig>(context.Configuration);
services.ConfigureSection<UIConfig>(context.Configuration);
#region External Services
services.ConfigureSection<InferenceClientConfig>(context.Configuration);
services.ConfigureSection<GpsDeniedClientConfig>(context.Configuration);
services.AddSingleton<IInferenceClient>(_inferenceClient);
services.AddSingleton<IGpsMatcherClient, GpsMatcherClient>();
services.AddSingleton<IResourceLoader>(_resourceLoader);
services.AddSingleton<IAuthProvider>(_authProvider);
services.AddSingleton<IInferenceService, InferenceService>();
#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());
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<AnnotationService>();
services.AddSingleton<DatasetExplorer>();
services.AddSingleton<IGalleryService, GalleryService>();
services.AddSingleton<IAzaionModule, AnnotatorModule>();
services.AddSingleton<IAzaionModule, DatasetExplorerModule>();
})
.Build();
Annotation.InitializeDirs(_host.Services.GetRequiredService<IOptions<DirectoriesConfig>>().Value);
_mediator = _host.Services.GetRequiredService<IMediator>();
_logger = _host.Services.GetRequiredService<ILogger<App>>();
_formState = _host.Services.GetRequiredService<FormState>();
DispatcherUnhandledException += OnDispatcherUnhandledException;
}
private void GlobalClick(object sender, RoutedEventArgs e)
{
var args = (KeyEventArgs)e;
var keyEvent = new KeyEvent(sender, args, _formState.ActiveWindow);
_ = ThrottleExt.ThrottleRunFirst(() => _mediator.Publish(keyEvent), KeyPressTaskId, TimeSpan.FromMilliseconds(50));
}
protected override async void OnExit(ExitEventArgs e)
{
base.OnExit(e);
await _host.StopAsync();
}
}