mirror of
https://github.com/azaion/annotations.git
synced 2026-04-22 09:46:30 +00:00
rework to have only 1 exe!
This commit is contained in:
@@ -80,7 +80,7 @@ public partial class Annotator
|
||||
|
||||
Loaded += OnLoaded;
|
||||
Closed += OnFormClosed;
|
||||
|
||||
Activated += (_, _) => _formState.ActiveWindow = WindowEnum.Annotator;
|
||||
Editor.GetTimeFunc = () => TimeSpan.FromMilliseconds(_mediaPlayer.Time);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,11 +4,12 @@ using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using Azaion.Common.DTO.Config;
|
||||
using LibVLCSharp.Shared;
|
||||
using Microsoft.Extensions.Options;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace Azaion.Annotator.Extensions;
|
||||
|
||||
public class VLCFrameExtractor(LibVLC libVLC, AIRecognitionConfig config)
|
||||
public class VLCFrameExtractor(LibVLC libVLC, IOptions<AIRecognitionConfig> config)
|
||||
{
|
||||
private const uint RGBA_BYTES = 4;
|
||||
private const int PLAYBACK_RATE = 4;
|
||||
@@ -105,7 +106,7 @@ public class VLCFrameExtractor(LibVLC libVLC, AIRecognitionConfig config)
|
||||
_lastFrameTimestamp = playerTime;
|
||||
}
|
||||
|
||||
if (_frameCounter > 20 && _frameCounter % config.FramePeriodRecognition == 0)
|
||||
if (_frameCounter > 20 && _frameCounter % config.Value.FramePeriodRecognition == 0)
|
||||
{
|
||||
var msToAdd = (_frameCounter - _lastFrame) * (_lastFrame == 0 ? 0 : _lastFrameTimestamp.TotalMilliseconds / _lastFrame);
|
||||
var time = _lastFrameTimestamp.Add(TimeSpan.FromMilliseconds(msToAdd));
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommandLineParser" Version="2.9.1" />
|
||||
<PackageReference Include="MediatR" Version="12.4.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="9.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="9.0.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.2.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -13,6 +13,11 @@ public class Constants
|
||||
public const string DEFAULT_API_URL = "https://api.azaion.com/";
|
||||
public const int DEFAULT_API_RETRY_COUNT = 3;
|
||||
public const int DEFAULT_API_TIMEOUT_SECONDS = 40;
|
||||
|
||||
public const string CLAIM_NAME_ID = "nameid";
|
||||
public const string CLAIM_EMAIL = "unique_name";
|
||||
public const string CLAIM_ROLE = "role";
|
||||
|
||||
#endregion ApiConfig
|
||||
|
||||
#region DirectoriesConfig
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
using System.Windows.Media;
|
||||
using Azaion.Common.DTO;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Azaion.Annotator.DTO;
|
||||
namespace Azaion.Common.DTO;
|
||||
|
||||
public class AnnotationResult
|
||||
{
|
||||
@@ -1,12 +1,7 @@
|
||||
using CommandLine;
|
||||
namespace Azaion.Common.DTO;
|
||||
|
||||
namespace Azaion.Common.DTO;
|
||||
|
||||
public class ApiCredentials
|
||||
public class ApiCredentials(string email, string password) : EventArgs
|
||||
{
|
||||
[Option('e', "email", Required = true, HelpText = "The email for authorization.")]
|
||||
public string Email { get; set; } = null!;
|
||||
|
||||
[Option('p', "password", Required = true, HelpText = "The password for authorization.")]
|
||||
public string Password { get; set; } = null!;
|
||||
public string Email { get; set; } = email;
|
||||
public string Password { get; set; } = password;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
|
||||
namespace Azaion.Annotator.DTO;
|
||||
namespace Azaion.Common.DTO;
|
||||
|
||||
public class FormState
|
||||
{
|
||||
@@ -18,6 +18,7 @@ public class FormState
|
||||
public TimeSpan? BackgroundTime { get; set; }
|
||||
public int CurrentVolume { get; set; } = 100;
|
||||
public ObservableCollection<AnnotationResult> AnnotationResults { get; set; } = [];
|
||||
public WindowEnum ActiveWindow { get; set; }
|
||||
|
||||
public string GetTimeName(TimeSpan? ts) => $"{VideoName}_{ts:hmmssf}";
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Azaion.Annotator.DTO;
|
||||
namespace Azaion.Common.DTO;
|
||||
|
||||
public class MediaFileInfo
|
||||
{
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Azaion.Annotator.DTO;
|
||||
namespace Azaion.Common.DTO;
|
||||
|
||||
public enum MediaTypes
|
||||
{
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace Azaion.Common.DTO;
|
||||
|
||||
public enum RoleEnum
|
||||
{
|
||||
None = 0,
|
||||
Operator = 10, //only annotator is available. Could send annotations to queue.
|
||||
Validator = 20, //annotator + dataset explorer. This role allows to receive annotations from the queue.
|
||||
CompanionPC = 30,
|
||||
Admin = 40, //
|
||||
ResourceUploader = 50, //Uploading dll and ai models
|
||||
ApiAdmin = 1000 //everything
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace Azaion.Common.DTO;
|
||||
|
||||
public class User
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string Email { get; set; }
|
||||
public RoleEnum Role { get; set; }
|
||||
|
||||
public User(IEnumerable<Claim> claims)
|
||||
{
|
||||
var claimDict = claims.ToDictionary(x => x.Type, x => x.Value);
|
||||
|
||||
Id = Guid.Parse(claimDict[Constants.CLAIM_NAME_ID]);
|
||||
Email = claimDict[Constants.CLAIM_EMAIL];
|
||||
if (!Enum.TryParse(claimDict[Constants.CLAIM_ROLE], out RoleEnum role))
|
||||
role = RoleEnum.None;
|
||||
Role = role;
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ using System.Security;
|
||||
using System.Text;
|
||||
using Azaion.Common.DTO;
|
||||
using Newtonsoft.Json;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
|
||||
namespace Azaion.Common.Services;
|
||||
|
||||
@@ -15,7 +16,9 @@ public class AzaionApiClient(HttpClient httpClient) : IDisposable
|
||||
|
||||
private string Email { get; set; } = null!;
|
||||
private SecureString Password { get; set; } = new();
|
||||
|
||||
private string JwtToken { get; set; } = null!;
|
||||
public User User { get; set; } = null!;
|
||||
|
||||
public void EnterCredentials(ApiCredentials credentials)
|
||||
{
|
||||
@@ -35,7 +38,7 @@ public class AzaionApiClient(HttpClient httpClient) : IDisposable
|
||||
return await response.Content.ReadAsStreamAsync();
|
||||
}
|
||||
|
||||
private async Task<string> Authorize()
|
||||
private async Task Authorize()
|
||||
{
|
||||
if (string.IsNullOrEmpty(Email) || Password.Length == 0)
|
||||
throw new Exception("Email or password is empty! Please do EnterCredentials first!");
|
||||
@@ -59,19 +62,23 @@ public class AzaionApiClient(HttpClient httpClient) : IDisposable
|
||||
if (string.IsNullOrEmpty(result?.Token))
|
||||
throw new Exception("JWT Token not found in response");
|
||||
|
||||
return result.Token;
|
||||
var handler = new JwtSecurityTokenHandler();
|
||||
var token = handler.ReadJwtToken(result.Token);
|
||||
|
||||
User = new User(token.Claims);
|
||||
JwtToken = result.Token;
|
||||
}
|
||||
|
||||
private async Task<HttpResponseMessage> Send(HttpClient client, HttpRequestMessage request)
|
||||
{
|
||||
if (string.IsNullOrEmpty(JwtToken))
|
||||
JwtToken = await Authorize();
|
||||
await Authorize();
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", JwtToken);
|
||||
var response = await client.SendAsync(request);
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.Unauthorized)
|
||||
{
|
||||
JwtToken = await Authorize();
|
||||
await Authorize();
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", JwtToken);
|
||||
response = await client.SendAsync(request);
|
||||
}
|
||||
@@ -88,4 +95,4 @@ public class AzaionApiClient(HttpClient httpClient) : IDisposable
|
||||
httpClient.Dispose();
|
||||
Password.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ namespace Azaion.Common.Services;
|
||||
|
||||
public interface IHardwareService
|
||||
{
|
||||
Task<HardwareInfo> GetHardware();
|
||||
HardwareInfo GetHardware();
|
||||
}
|
||||
|
||||
public class HardwareService : IHardwareService
|
||||
@@ -23,11 +23,11 @@ public class HardwareService : IHardwareService
|
||||
"lscpu | grep 'Model name:' | cut -d':' -f2 && " +
|
||||
"lspci | grep VGA | cut -d':' -f3\"";
|
||||
|
||||
public async Task<HardwareInfo> GetHardware()
|
||||
public HardwareInfo GetHardware()
|
||||
{
|
||||
try
|
||||
{
|
||||
var output = await RunCommand(Environment.OSVersion.Platform == PlatformID.Win32NT
|
||||
var output = RunCommand(Environment.OSVersion.Platform == PlatformID.Win32NT
|
||||
? WIN32_GET_HARDWARE_COMMAND
|
||||
: UNIX_GET_HARDWARE_COMMAND);
|
||||
|
||||
@@ -77,7 +77,7 @@ public class HardwareService : IHardwareService
|
||||
return macAddress ?? string.Empty;
|
||||
}
|
||||
|
||||
private async Task<string> RunCommand(string command)
|
||||
private string RunCommand(string command)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -91,8 +91,8 @@ public class HardwareService : IHardwareService
|
||||
process.StartInfo.CreateNoWindow = true;
|
||||
|
||||
process.Start();
|
||||
var result = await process.StandardOutput.ReadToEndAsync();
|
||||
await process.WaitForExitAsync();
|
||||
var result = process.StandardOutput.ReadToEnd();
|
||||
process.WaitForExit();
|
||||
|
||||
return result.Trim();
|
||||
}
|
||||
|
||||
@@ -46,8 +46,9 @@ public class ResourceLoader(AzaionApiClient api, ApiCredentials credentials) : I
|
||||
public async Task<MemoryStream> Load(string fileName, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var hardwareService = new HardwareService();
|
||||
var hardwareInfo = await hardwareService.GetHardware();
|
||||
var encryptedStream = await api.GetResource(fileName, credentials.Password, hardwareInfo);
|
||||
var hardwareInfo = hardwareService.GetHardware();
|
||||
|
||||
var encryptedStream = Task.Run(() => api.GetResource(fileName, credentials.Password, hardwareInfo), cancellationToken).Result;
|
||||
|
||||
var key = Security.MakeEncryptionKey(credentials.Email, credentials.Password, hardwareInfo.Hash);
|
||||
var stream = new MemoryStream();
|
||||
|
||||
@@ -24,6 +24,7 @@ public partial class DatasetExplorer
|
||||
|
||||
private int _tempSelectedClassIdx = 0;
|
||||
private readonly IGalleryManager _galleryManager;
|
||||
private readonly FormState _formState;
|
||||
|
||||
public bool ThumbnailLoading { get; set; }
|
||||
|
||||
@@ -33,60 +34,17 @@ public partial class DatasetExplorer
|
||||
IOptions<DirectoriesConfig> directoriesConfig,
|
||||
IOptions<AnnotationConfig> annotationConfig,
|
||||
ILogger<DatasetExplorer> logger,
|
||||
IGalleryManager galleryManager)
|
||||
IGalleryManager galleryManager,
|
||||
FormState formState)
|
||||
{
|
||||
_directoriesConfig = directoriesConfig.Value;
|
||||
_annotationConfig = annotationConfig.Value;
|
||||
_logger = logger;
|
||||
_galleryManager = galleryManager;
|
||||
_formState = formState;
|
||||
|
||||
InitializeComponent();
|
||||
Loaded += async (_, _) =>
|
||||
{
|
||||
_ = Task.Run(async () => await _galleryManager.RefreshThumbnails());
|
||||
|
||||
AllAnnotationClasses = new ObservableCollection<AnnotationClass>(
|
||||
new List<AnnotationClass> { new() {Id = -1, Name = "All", ShortName = "All"}}
|
||||
.Concat(_annotationConfig.AnnotationClasses));
|
||||
LvClasses.ItemsSource = AllAnnotationClasses;
|
||||
|
||||
LvClasses.MouseUp += async (_, _) =>
|
||||
{
|
||||
var selectedClass = (AnnotationClass)LvClasses.SelectedItem;
|
||||
ExplorerEditor.CurrentAnnClass = selectedClass;
|
||||
_annotationConfig.LastSelectedExplorerClass = selectedClass.Id;
|
||||
|
||||
if (Switcher.SelectedIndex == 0)
|
||||
await ReloadThumbnails();
|
||||
else
|
||||
foreach (var ann in ExplorerEditor.CurrentAnns.Where(x => x.IsSelected))
|
||||
ann.AnnotationClass = selectedClass;
|
||||
};
|
||||
|
||||
LvClasses.SelectionChanged += (_, _) =>
|
||||
{
|
||||
if (Switcher.SelectedIndex != 1)
|
||||
return;
|
||||
|
||||
var selectedClass = (AnnotationClass)LvClasses.SelectedItem;
|
||||
if (selectedClass == null)
|
||||
return;
|
||||
|
||||
ExplorerEditor.CurrentAnnClass = selectedClass;
|
||||
|
||||
foreach (var ann in ExplorerEditor.CurrentAnns.Where(x => x.IsSelected))
|
||||
ann.AnnotationClass = selectedClass;
|
||||
};
|
||||
|
||||
|
||||
LvClasses.SelectedIndex = _annotationConfig.LastSelectedExplorerClass ?? 0;
|
||||
ExplorerEditor.CurrentAnnClass = (AnnotationClass)LvClasses.SelectedItem;
|
||||
await ReloadThumbnails();
|
||||
LoadClassDistribution();
|
||||
|
||||
RefreshThumbBar.Value = galleryManager.ThumbnailsPercentage;
|
||||
DataContext = this;
|
||||
};
|
||||
Loaded += OnLoaded;
|
||||
|
||||
ThumbnailsView.KeyDown += async (sender, args) =>
|
||||
{
|
||||
@@ -115,6 +73,53 @@ public partial class DatasetExplorer
|
||||
|
||||
}
|
||||
|
||||
private async void OnLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_ = Task.Run(async () => await _galleryManager.RefreshThumbnails());
|
||||
|
||||
AllAnnotationClasses = new ObservableCollection<AnnotationClass>(
|
||||
new List<AnnotationClass> { new() {Id = -1, Name = "All", ShortName = "All"}}
|
||||
.Concat(_annotationConfig.AnnotationClasses));
|
||||
LvClasses.ItemsSource = AllAnnotationClasses;
|
||||
|
||||
LvClasses.MouseUp += async (_, _) =>
|
||||
{
|
||||
var selectedClass = (AnnotationClass)LvClasses.SelectedItem;
|
||||
ExplorerEditor.CurrentAnnClass = selectedClass;
|
||||
_annotationConfig.LastSelectedExplorerClass = selectedClass.Id;
|
||||
|
||||
if (Switcher.SelectedIndex == 0)
|
||||
await ReloadThumbnails();
|
||||
else
|
||||
foreach (var ann in ExplorerEditor.CurrentAnns.Where(x => x.IsSelected))
|
||||
ann.AnnotationClass = selectedClass;
|
||||
};
|
||||
|
||||
LvClasses.SelectionChanged += (_, _) =>
|
||||
{
|
||||
if (Switcher.SelectedIndex != 1)
|
||||
return;
|
||||
|
||||
var selectedClass = (AnnotationClass)LvClasses.SelectedItem;
|
||||
if (selectedClass == null)
|
||||
return;
|
||||
|
||||
ExplorerEditor.CurrentAnnClass = selectedClass;
|
||||
|
||||
foreach (var ann in ExplorerEditor.CurrentAnns.Where(x => x.IsSelected))
|
||||
ann.AnnotationClass = selectedClass;
|
||||
};
|
||||
Activated += (_, _) => _formState.ActiveWindow = WindowEnum.Annotator;
|
||||
|
||||
LvClasses.SelectedIndex = _annotationConfig.LastSelectedExplorerClass ?? 0;
|
||||
ExplorerEditor.CurrentAnnClass = (AnnotationClass)LvClasses.SelectedItem;
|
||||
await ReloadThumbnails();
|
||||
LoadClassDistribution();
|
||||
|
||||
RefreshThumbBar.Value = _galleryManager.ThumbnailsPercentage;
|
||||
DataContext = this;
|
||||
}
|
||||
|
||||
private void LoadClassDistribution()
|
||||
{
|
||||
var data = _galleryManager.LabelsCache
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
<Application x:Class="Azaion.Launcher.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
StartupUri="Loader.xaml">
|
||||
<Application.Resources>
|
||||
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
@@ -1,3 +0,0 @@
|
||||
namespace Azaion.Launcher;
|
||||
|
||||
public partial class App;
|
||||
@@ -1,10 +0,0 @@
|
||||
using System.Windows;
|
||||
|
||||
[assembly: ThemeInfo(
|
||||
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||
//(used if a resource is not found in the page,
|
||||
// or application resource dictionaries)
|
||||
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||
//(used if a resource is not found in the page,
|
||||
// app, or any theme specific resource dictionaries)
|
||||
)]
|
||||
@@ -1,19 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Update="Loader.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<XamlRuntime>Wpf</XamlRuntime>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -10,8 +10,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azaion.Common", "Azaion.Com
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azaion.Dataset", "Azaion.Dataset\Azaion.Dataset.csproj", "{01A5CA37-A62E-4EF3-8678-D72CD9525677}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azaion.Launcher", "Azaion.Launcher\Azaion.Launcher.csproj", "{00CC9AFE-2952-4943-BCBA-976AE03DE841}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dummy", "Dummy", "{C307BE2E-FFCC-4BD7-AD89-C82D40B65D03}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
Dummy\Azaion.Annotator.dll = Dummy\Azaion.Annotator.dll
|
||||
@@ -48,10 +46,6 @@ Global
|
||||
{01A5CA37-A62E-4EF3-8678-D72CD9525677}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{01A5CA37-A62E-4EF3-8678-D72CD9525677}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{01A5CA37-A62E-4EF3-8678-D72CD9525677}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{00CC9AFE-2952-4943-BCBA-976AE03DE841}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{00CC9AFE-2952-4943-BCBA-976AE03DE841}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{00CC9AFE-2952-4943-BCBA-976AE03DE841}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{00CC9AFE-2952-4943-BCBA-976AE03DE841}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{32C4747F-F700-44FD-B4ED-21B4A66B5FAB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{32C4747F-F700-44FD-B4ED-21B4A66B5FAB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{32C4747F-F700-44FD-B4ED-21B4A66B5FAB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
||||
+48
-61
@@ -1,10 +1,8 @@
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
using System.Windows;
|
||||
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;
|
||||
@@ -12,7 +10,6 @@ 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;
|
||||
@@ -22,31 +19,19 @@ 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 readonly IHost _host;
|
||||
private readonly ILogger<App> _logger;
|
||||
private readonly IMediator _mediator;
|
||||
private IHost _host = null!;
|
||||
private ILogger<App> _logger = null!;
|
||||
private IMediator _mediator = null!;
|
||||
private FormState _formState = null!;
|
||||
|
||||
//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 AzaionApiClient _apiClient = null!;
|
||||
private IResourceLoader _resourceLoader = null!;
|
||||
|
||||
private static AzaionApiClient CreateApiClient(ApiCredentials credentials)
|
||||
{
|
||||
@@ -68,6 +53,7 @@ public partial class App
|
||||
TimeoutSeconds = 40
|
||||
};
|
||||
}
|
||||
|
||||
var api = new AzaionApiClient(new HttpClient
|
||||
{
|
||||
BaseAddress = new Uri(apiConfig.Url),
|
||||
@@ -78,7 +64,40 @@ public partial class App
|
||||
return api;
|
||||
}
|
||||
|
||||
public App()
|
||||
|
||||
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 void StartLogin()
|
||||
{
|
||||
new ConfigUpdater().CheckConfig();
|
||||
var login = new Login();
|
||||
login.CredentialsEntered += async (s, args) =>
|
||||
{
|
||||
_apiClient = CreateApiClient(args);
|
||||
_resourceLoader = new ResourceLoader(_apiClient, args);
|
||||
AppDomain.CurrentDomain.AssemblyResolve += (_, a) => _resourceLoader.LoadAssembly(a.Name);
|
||||
|
||||
StartMain();
|
||||
|
||||
EventManager.RegisterClassHandler(typeof(UIElement), UIElement.KeyDownEvent, new RoutedEventHandler(GlobalClick));
|
||||
await _host.StartAsync();
|
||||
_host.Services.GetRequiredService<MainSuite>().Show();
|
||||
};
|
||||
|
||||
login.ShowDialog();
|
||||
}
|
||||
|
||||
private void StartMain()
|
||||
{
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
.Enrich.FromLogContext()
|
||||
@@ -97,7 +116,9 @@ public partial class App
|
||||
{
|
||||
services.AddSingleton<MainSuite>();
|
||||
services.AddSingleton<IHardwareService, HardwareService>();
|
||||
services.AddSingleton(ResourceLoader);
|
||||
|
||||
services.AddSingleton(_apiClient);
|
||||
services.AddSingleton(_resourceLoader);
|
||||
|
||||
services.Configure<AppConfig>(context.Configuration);
|
||||
services.ConfigureSection<ApiConfig>(context.Configuration);
|
||||
@@ -141,31 +162,15 @@ public partial class App
|
||||
.Build();
|
||||
_mediator = _host.Services.GetRequiredService<IMediator>();
|
||||
_logger = _host.Services.GetRequiredService<ILogger<App>>();
|
||||
_formState = _host.Services.GetRequiredService<FormState>();
|
||||
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);
|
||||
|
||||
var keyEvent = new KeyEvent(sender, args, _formState.ActiveWindow);
|
||||
_ = ThrottleExt.Throttle(() => _mediator.Publish(keyEvent), TimeSpan.FromMilliseconds(50));
|
||||
}
|
||||
|
||||
@@ -176,27 +181,9 @@ public partial class App
|
||||
{ "Azaion.Dataset.DatasetExplorer", WindowEnum.DatasetExplorer }
|
||||
};
|
||||
|
||||
private WindowEnum GetParentWindow(FrameworkElement? element)
|
||||
{
|
||||
while (element != null)
|
||||
{
|
||||
var windowEnum = _uiElementToWindowEnum!.GetValueOrDefault(element.GetType().FullName);
|
||||
|
||||
if (windowEnum != WindowEnum.None)
|
||||
return windowEnum;
|
||||
|
||||
element = (element.Parent ?? element.TemplatedParent) as FrameworkElement;
|
||||
}
|
||||
|
||||
return WindowEnum.None;
|
||||
}
|
||||
|
||||
|
||||
protected override async void OnExit(ExitEventArgs e)
|
||||
{
|
||||
base.OnExit(e);
|
||||
|
||||
await _host.StopAsync();
|
||||
//_host.Dispose();
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,6 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommandLineParser" Version="2.9.1" />
|
||||
<PackageReference Include="LibVLCSharp" Version="3.9.1" />
|
||||
<PackageReference Include="LibVLCSharp.WPF" Version="3.9.1" />
|
||||
<PackageReference Include="MediatR" Version="12.4.1" />
|
||||
@@ -40,6 +39,14 @@
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Update="Login.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<XamlRuntime>Wpf</XamlRuntime>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="Build">
|
||||
<MakeDir Directories="$(TargetDir)secure" />
|
||||
<Move SourceFiles="$(TargetDir)Azaion.Annotator.dll" DestinationFolder="$(TargetDir)secure" />
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<Window x:Class="Azaion.Launcher.Loader"
|
||||
<Window x:Class="Azaion.Suite.Login"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
@@ -97,7 +97,7 @@
|
||||
Height="35"
|
||||
Width="280"
|
||||
Cursor="Hand"
|
||||
Click="RunClick">
|
||||
Click="LoginClick">
|
||||
<Button.Style>
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="Template">
|
||||
@@ -1,21 +1,22 @@
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using Azaion.Common.DTO;
|
||||
|
||||
namespace Azaion.Launcher;
|
||||
namespace Azaion.Suite;
|
||||
|
||||
public partial class Loader : Window
|
||||
public partial class Login
|
||||
{
|
||||
public Loader()
|
||||
public Login()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private async void RunClick(object sender, RoutedEventArgs e)
|
||||
public event EventHandler<ApiCredentials>? CredentialsEntered;
|
||||
|
||||
private void LoginClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Process.Start("Azaion.Suite.exe", $"-e {TbEmail.Text} -p {TbPassword.Password}");
|
||||
await Task.Delay(2000);
|
||||
CredentialsEntered?.Invoke(this, new ApiCredentials(TbEmail.Text, TbPassword.Password));
|
||||
Close();
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@ namespace Azaion.Annotator.Test;
|
||||
public class HardwareServiceTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task GetHardware_Test()
|
||||
public void GetHardware_Test()
|
||||
{
|
||||
var hardwareService = new HardwareService();
|
||||
var hw = await hardwareService.GetHardware();
|
||||
var hw = hardwareService.GetHardware();
|
||||
Console.WriteLine(hw);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user