Files
annotations/Azaion.Suite/App.xaml.cs
T
Alex Bezdieniezhnykh 9e0bb1e82e add resolve
2024-11-25 16:11:40 +02:00

196 lines
7.0 KiB
C#

using System.IO;
using System.Net.Http;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Threading;
using Azaion.Annotator;
using Azaion.Annotator.DTO;
using Azaion.Annotator.Extensions;
using Azaion.Common;
using Azaion.Common.DTO;
using Azaion.Common.DTO.Config;
using Azaion.Common.Extensions;
using Azaion.Common.Services;
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.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Serilog;
namespace Azaion.Suite;
public partial class App
{
private readonly IHost _host;
private readonly ILogger<App> _logger;
private readonly IMediator _mediator;
//Authorize to api and
private static readonly IResourceLoader ResourceLoader;
static App()
{
new ConfigUpdater().CheckConfig();
var result = Parser.Default.ParseArguments<ApiCredentials>(Environment.GetCommandLineArgs());
var apiCreds = !result.Errors.Any()
? result.Value
: new ApiCredentials();
ResourceLoader = new ResourceLoader(CreateApiClient(apiCreds), apiCreds);
AppDomain.CurrentDomain.AssemblyResolve += (_, args) => ResourceLoader.LoadAssembly(args.Name);
}
private static AzaionApiClient CreateApiClient(ApiCredentials credentials)
{
ApiConfig apiConfig;
try
{
if (!File.Exists(Constants.CONFIG_PATH))
throw new FileNotFoundException(Constants.CONFIG_PATH);
var configStr = File.ReadAllText(Constants.CONFIG_PATH);
apiConfig = JsonConvert.DeserializeObject<AppConfig>(configStr)!.ApiConfig;
}
catch (Exception e)
{
Console.WriteLine(e);
apiConfig = new ApiConfig
{
Url = "https://api.azaion.com",
RetryCount = 3,
TimeoutSeconds = 40
};
}
var api = new AzaionApiClient(new HttpClient
{
BaseAddress = new Uri(apiConfig.Url),
Timeout = TimeSpan.FromSeconds(apiConfig.TimeoutSeconds)
});
api.EnterCredentials(credentials);
return api;
}
public App()
{
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(Constants.CONFIG_PATH, optional: true, reloadOnChange: true))
.ConfigureServices((context, services) =>
{
services.AddSingleton<MainSuite>();
services.AddSingleton<IHardwareService, HardwareService>();
services.AddSingleton(ResourceLoader);
services.Configure<AppConfig>(context.Configuration);
services.ConfigureSection<ApiConfig>(context.Configuration);
services.ConfigureSection<DirectoriesConfig>(context.Configuration);
services.ConfigureSection<AnnotationConfig>(context.Configuration);
services.ConfigureSection<WindowConfig>(context.Configuration);
services.ConfigureSection<AIRecognitionConfig>(context.Configuration);
services.ConfigureSection<ThumbnailConfig>(context.Configuration);
services.AddSingleton<IConfigUpdater, ConfigUpdater>();
services.AddSingleton<Annotator.Annotator>();
services.AddSingleton<DatasetExplorer>();
services.AddSingleton<HelpWindow>();
services.AddSingleton<IAIDetector, YOLODetector>();
services.AddMediatR(c => c.RegisterServicesFromAssemblies(
typeof(Annotator.Annotator).Assembly,
typeof(DatasetExplorer).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<VLCFrameExtractor>();
services.AddHttpClient<AzaionApiClient>((sp, client) =>
{
var apiConfig = sp.GetRequiredService<IOptions<ApiConfig>>().Value;
client.BaseAddress = new Uri(apiConfig.Url);
client.Timeout = TimeSpan.FromSeconds(apiConfig.TimeoutSeconds);
});
services.AddSingleton<DatasetExplorer>();
services.AddSingleton<IGalleryManager, GalleryManager>();
services.AddSingleton<IAzaionModule, AnnotatorModule>();
services.AddSingleton<IAzaionModule, DatasetExplorerModule>();
})
.Build();
_mediator = _host.Services.GetRequiredService<IMediator>();
_logger = _host.Services.GetRequiredService<ILogger<App>>();
DispatcherUnhandledException += OnDispatcherUnhandledException;
}
private void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
_logger.LogError(e.Exception, e.Exception.Message);
e.Handled = true;
}
protected override async void OnStartup(StartupEventArgs e)
{
EventManager.RegisterClassHandler(typeof(UIElement), UIElement.KeyDownEvent, new RoutedEventHandler(GlobalClick));
await _host.StartAsync();
_host.Services.GetRequiredService<MainSuite>().Show();
base.OnStartup(e);
}
private void GlobalClick(object sender, RoutedEventArgs e)
{
var args = (KeyEventArgs)e;
var windowEnum = GetParentWindow(sender as FrameworkElement);
if (windowEnum == WindowEnum.None)
return;
var keyEvent = new KeyEvent(sender, args, windowEnum);
_ = ThrottleExt.Throttle(() => _mediator.Publish(keyEvent), TimeSpan.FromMilliseconds(50));
}
private WindowEnum GetParentWindow(FrameworkElement? element)
{
if (element?.GetType().Name == "LibVLCSharp.WPF.ForegroundWindow")
return WindowEnum.Annotator;
while (element != null && element is not TabItem)
element = element.Parent as FrameworkElement;
if (element is not TabItem || element.Tag == null)
return WindowEnum.None;
return (WindowEnum)element.Tag;
}
protected override async void OnExit(ExitEventArgs e)
{
base.OnExit(e);
await _host.StopAsync();
//_host.Dispose();
}
}