mirror of
https://github.com/azaion/annotations.git
synced 2026-04-22 23:06:31 +00:00
252 lines
9.9 KiB
C#
252 lines
9.9 KiB
C#
using System.IO;
|
|
using System.Net.Http;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using System.Text.Unicode;
|
|
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.CommonSecurity;
|
|
using Azaion.CommonSecurity.DTO;
|
|
using Azaion.CommonSecurity.DTO.Commands;
|
|
using Azaion.CommonSecurity.Services;
|
|
using Azaion.Dataset;
|
|
using LazyCache;
|
|
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 Stream _securedConfig = null!;
|
|
private Stream _systemConfig = null!;
|
|
private static readonly Guid KeyPressTaskId = Guid.NewGuid();
|
|
|
|
private readonly ICache _cache = new MemoryCache();
|
|
private IAzaionApi _azaionApi = null!;
|
|
|
|
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();
|
|
var apiDir = secureAppConfig.DirectoriesConfig.ApiResourcesDirectory;
|
|
_inferenceClient = new InferenceClient(new OptionsWrapper<InferenceClientConfig>(secureAppConfig.InferenceClientConfig));
|
|
_resourceLoader = new ResourceLoader(_inferenceClient);
|
|
var login = new Login();
|
|
|
|
login.CredentialsEntered += (_, credentials) =>
|
|
{
|
|
_inferenceClient.Send(RemoteCommand.Create(CommandType.Login, credentials));
|
|
_azaionApi = new AzaionApi(new HttpClient { BaseAddress = new Uri(secureAppConfig.InferenceClientConfig.ApiUrl) }, _cache, credentials);
|
|
|
|
try
|
|
{
|
|
_securedConfig = _resourceLoader.LoadFile("config.secured.json", apiDir);
|
|
_systemConfig = _resourceLoader.LoadFile("config.system.json", apiDir);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Console.WriteLine(e);
|
|
_securedConfig = new MemoryStream("{}"u8.ToArray());
|
|
var systemConfig = new
|
|
{
|
|
AnnotationConfig = Constants.DefaultAnnotationConfig,
|
|
AIRecognitionConfig = Constants.DefaultAIRecognitionConfig,
|
|
ThumbnailConfig = Constants.DefaultThumbnailConfig,
|
|
};
|
|
_systemConfig = new MemoryStream(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(systemConfig)));
|
|
}
|
|
|
|
AppDomain.CurrentDomain.AssemblyResolve += (_, a) =>
|
|
{
|
|
var assemblyName = a.Name.Split(',').First();
|
|
if (_encryptedResources.Contains(assemblyName))
|
|
{
|
|
try
|
|
{
|
|
var stream = _resourceLoader.LoadFile($"{assemblyName}.dll", apiDir);
|
|
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.Closed += (sender, args) =>
|
|
{
|
|
if (!login.MainSuiteOpened)
|
|
_inferenceClient.Stop();
|
|
};
|
|
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.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);
|
|
services.ConfigureSection<MapConfig>(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<IInferenceService, InferenceService>();
|
|
services.AddSingleton<IGpsMatcherService, GpsMatcherService>();
|
|
services.AddSingleton<ISatelliteDownloader, SatelliteDownloader>();
|
|
services.AddHttpClient();
|
|
services.AddSingleton(_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());
|
|
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.Throttle(() => _mediator.Publish(keyEvent), KeyPressTaskId, TimeSpan.FromMilliseconds(50));
|
|
}
|
|
|
|
protected override async void OnExit(ExitEventArgs e)
|
|
{
|
|
base.OnExit(e);
|
|
await _host.StopAsync();
|
|
}
|
|
}
|