mirror of
https://github.com/azaion/annotations.git
synced 2026-04-22 21: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;
|
Loaded += OnLoaded;
|
||||||
Closed += OnFormClosed;
|
Closed += OnFormClosed;
|
||||||
|
Activated += (_, _) => _formState.ActiveWindow = WindowEnum.Annotator;
|
||||||
Editor.GetTimeFunc = () => TimeSpan.FromMilliseconds(_mediaPlayer.Time);
|
Editor.GetTimeFunc = () => TimeSpan.FromMilliseconds(_mediaPlayer.Time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,12 @@ using System.Runtime.CompilerServices;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Azaion.Common.DTO.Config;
|
using Azaion.Common.DTO.Config;
|
||||||
using LibVLCSharp.Shared;
|
using LibVLCSharp.Shared;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
|
|
||||||
namespace Azaion.Annotator.Extensions;
|
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 uint RGBA_BYTES = 4;
|
||||||
private const int PLAYBACK_RATE = 4;
|
private const int PLAYBACK_RATE = 4;
|
||||||
@@ -105,7 +106,7 @@ public class VLCFrameExtractor(LibVLC libVLC, AIRecognitionConfig config)
|
|||||||
_lastFrameTimestamp = playerTime;
|
_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 msToAdd = (_frameCounter - _lastFrame) * (_lastFrame == 0 ? 0 : _lastFrameTimestamp.TotalMilliseconds / _lastFrame);
|
||||||
var time = _lastFrameTimestamp.Add(TimeSpan.FromMilliseconds(msToAdd));
|
var time = _lastFrameTimestamp.Add(TimeSpan.FromMilliseconds(msToAdd));
|
||||||
|
|||||||
@@ -7,12 +7,12 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CommandLineParser" Version="2.9.1" />
|
|
||||||
<PackageReference Include="MediatR" Version="12.4.1" />
|
<PackageReference Include="MediatR" Version="12.4.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="9.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="9.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.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="Microsoft.Extensions.Options.ConfigurationExtensions" Version="9.0.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
|
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.2.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -13,6 +13,11 @@ public class Constants
|
|||||||
public const string DEFAULT_API_URL = "https://api.azaion.com/";
|
public const string DEFAULT_API_URL = "https://api.azaion.com/";
|
||||||
public const int DEFAULT_API_RETRY_COUNT = 3;
|
public const int DEFAULT_API_RETRY_COUNT = 3;
|
||||||
public const int DEFAULT_API_TIMEOUT_SECONDS = 40;
|
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
|
#endregion ApiConfig
|
||||||
|
|
||||||
#region DirectoriesConfig
|
#region DirectoriesConfig
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using Azaion.Common.DTO;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Azaion.Annotator.DTO;
|
namespace Azaion.Common.DTO;
|
||||||
|
|
||||||
public class AnnotationResult
|
public class AnnotationResult
|
||||||
{
|
{
|
||||||
@@ -1,12 +1,7 @@
|
|||||||
using CommandLine;
|
namespace Azaion.Common.DTO;
|
||||||
|
|
||||||
namespace Azaion.Common.DTO;
|
public class ApiCredentials(string email, string password) : EventArgs
|
||||||
|
|
||||||
public class ApiCredentials
|
|
||||||
{
|
{
|
||||||
[Option('e', "email", Required = true, HelpText = "The email for authorization.")]
|
public string Email { get; set; } = email;
|
||||||
public string Email { get; set; } = null!;
|
public string Password { get; set; } = password;
|
||||||
|
|
||||||
[Option('p', "password", Required = true, HelpText = "The password for authorization.")]
|
|
||||||
public string Password { get; set; } = null!;
|
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
|
||||||
namespace Azaion.Annotator.DTO;
|
namespace Azaion.Common.DTO;
|
||||||
|
|
||||||
public class FormState
|
public class FormState
|
||||||
{
|
{
|
||||||
@@ -18,6 +18,7 @@ public class FormState
|
|||||||
public TimeSpan? BackgroundTime { get; set; }
|
public TimeSpan? BackgroundTime { get; set; }
|
||||||
public int CurrentVolume { get; set; } = 100;
|
public int CurrentVolume { get; set; } = 100;
|
||||||
public ObservableCollection<AnnotationResult> AnnotationResults { get; set; } = [];
|
public ObservableCollection<AnnotationResult> AnnotationResults { get; set; } = [];
|
||||||
|
public WindowEnum ActiveWindow { get; set; }
|
||||||
|
|
||||||
public string GetTimeName(TimeSpan? ts) => $"{VideoName}_{ts:hmmssf}";
|
public string GetTimeName(TimeSpan? ts) => $"{VideoName}_{ts:hmmssf}";
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Azaion.Annotator.DTO;
|
namespace Azaion.Common.DTO;
|
||||||
|
|
||||||
public class MediaFileInfo
|
public class MediaFileInfo
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Azaion.Annotator.DTO;
|
namespace Azaion.Common.DTO;
|
||||||
|
|
||||||
public enum MediaTypes
|
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 System.Text;
|
||||||
using Azaion.Common.DTO;
|
using Azaion.Common.DTO;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
|
|
||||||
namespace Azaion.Common.Services;
|
namespace Azaion.Common.Services;
|
||||||
|
|
||||||
@@ -15,7 +16,9 @@ public class AzaionApiClient(HttpClient httpClient) : IDisposable
|
|||||||
|
|
||||||
private string Email { get; set; } = null!;
|
private string Email { get; set; } = null!;
|
||||||
private SecureString Password { get; set; } = new();
|
private SecureString Password { get; set; } = new();
|
||||||
|
|
||||||
private string JwtToken { get; set; } = null!;
|
private string JwtToken { get; set; } = null!;
|
||||||
|
public User User { get; set; } = null!;
|
||||||
|
|
||||||
public void EnterCredentials(ApiCredentials credentials)
|
public void EnterCredentials(ApiCredentials credentials)
|
||||||
{
|
{
|
||||||
@@ -35,7 +38,7 @@ public class AzaionApiClient(HttpClient httpClient) : IDisposable
|
|||||||
return await response.Content.ReadAsStreamAsync();
|
return await response.Content.ReadAsStreamAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> Authorize()
|
private async Task Authorize()
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(Email) || Password.Length == 0)
|
if (string.IsNullOrEmpty(Email) || Password.Length == 0)
|
||||||
throw new Exception("Email or password is empty! Please do EnterCredentials first!");
|
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))
|
if (string.IsNullOrEmpty(result?.Token))
|
||||||
throw new Exception("JWT Token not found in response");
|
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)
|
private async Task<HttpResponseMessage> Send(HttpClient client, HttpRequestMessage request)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(JwtToken))
|
if (string.IsNullOrEmpty(JwtToken))
|
||||||
JwtToken = await Authorize();
|
await Authorize();
|
||||||
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", JwtToken);
|
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", JwtToken);
|
||||||
var response = await client.SendAsync(request);
|
var response = await client.SendAsync(request);
|
||||||
|
|
||||||
if (response.StatusCode == HttpStatusCode.Unauthorized)
|
if (response.StatusCode == HttpStatusCode.Unauthorized)
|
||||||
{
|
{
|
||||||
JwtToken = await Authorize();
|
await Authorize();
|
||||||
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", JwtToken);
|
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", JwtToken);
|
||||||
response = await client.SendAsync(request);
|
response = await client.SendAsync(request);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ namespace Azaion.Common.Services;
|
|||||||
|
|
||||||
public interface IHardwareService
|
public interface IHardwareService
|
||||||
{
|
{
|
||||||
Task<HardwareInfo> GetHardware();
|
HardwareInfo GetHardware();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class HardwareService : IHardwareService
|
public class HardwareService : IHardwareService
|
||||||
@@ -23,11 +23,11 @@ public class HardwareService : IHardwareService
|
|||||||
"lscpu | grep 'Model name:' | cut -d':' -f2 && " +
|
"lscpu | grep 'Model name:' | cut -d':' -f2 && " +
|
||||||
"lspci | grep VGA | cut -d':' -f3\"";
|
"lspci | grep VGA | cut -d':' -f3\"";
|
||||||
|
|
||||||
public async Task<HardwareInfo> GetHardware()
|
public HardwareInfo GetHardware()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var output = await RunCommand(Environment.OSVersion.Platform == PlatformID.Win32NT
|
var output = RunCommand(Environment.OSVersion.Platform == PlatformID.Win32NT
|
||||||
? WIN32_GET_HARDWARE_COMMAND
|
? WIN32_GET_HARDWARE_COMMAND
|
||||||
: UNIX_GET_HARDWARE_COMMAND);
|
: UNIX_GET_HARDWARE_COMMAND);
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ public class HardwareService : IHardwareService
|
|||||||
return macAddress ?? string.Empty;
|
return macAddress ?? string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> RunCommand(string command)
|
private string RunCommand(string command)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -91,8 +91,8 @@ public class HardwareService : IHardwareService
|
|||||||
process.StartInfo.CreateNoWindow = true;
|
process.StartInfo.CreateNoWindow = true;
|
||||||
|
|
||||||
process.Start();
|
process.Start();
|
||||||
var result = await process.StandardOutput.ReadToEndAsync();
|
var result = process.StandardOutput.ReadToEnd();
|
||||||
await process.WaitForExitAsync();
|
process.WaitForExit();
|
||||||
|
|
||||||
return result.Trim();
|
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)
|
public async Task<MemoryStream> Load(string fileName, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var hardwareService = new HardwareService();
|
var hardwareService = new HardwareService();
|
||||||
var hardwareInfo = await hardwareService.GetHardware();
|
var hardwareInfo = hardwareService.GetHardware();
|
||||||
var encryptedStream = await api.GetResource(fileName, credentials.Password, hardwareInfo);
|
|
||||||
|
var encryptedStream = Task.Run(() => api.GetResource(fileName, credentials.Password, hardwareInfo), cancellationToken).Result;
|
||||||
|
|
||||||
var key = Security.MakeEncryptionKey(credentials.Email, credentials.Password, hardwareInfo.Hash);
|
var key = Security.MakeEncryptionKey(credentials.Email, credentials.Password, hardwareInfo.Hash);
|
||||||
var stream = new MemoryStream();
|
var stream = new MemoryStream();
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ public partial class DatasetExplorer
|
|||||||
|
|
||||||
private int _tempSelectedClassIdx = 0;
|
private int _tempSelectedClassIdx = 0;
|
||||||
private readonly IGalleryManager _galleryManager;
|
private readonly IGalleryManager _galleryManager;
|
||||||
|
private readonly FormState _formState;
|
||||||
|
|
||||||
public bool ThumbnailLoading { get; set; }
|
public bool ThumbnailLoading { get; set; }
|
||||||
|
|
||||||
@@ -33,15 +34,46 @@ public partial class DatasetExplorer
|
|||||||
IOptions<DirectoriesConfig> directoriesConfig,
|
IOptions<DirectoriesConfig> directoriesConfig,
|
||||||
IOptions<AnnotationConfig> annotationConfig,
|
IOptions<AnnotationConfig> annotationConfig,
|
||||||
ILogger<DatasetExplorer> logger,
|
ILogger<DatasetExplorer> logger,
|
||||||
IGalleryManager galleryManager)
|
IGalleryManager galleryManager,
|
||||||
|
FormState formState)
|
||||||
{
|
{
|
||||||
_directoriesConfig = directoriesConfig.Value;
|
_directoriesConfig = directoriesConfig.Value;
|
||||||
_annotationConfig = annotationConfig.Value;
|
_annotationConfig = annotationConfig.Value;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_galleryManager = galleryManager;
|
_galleryManager = galleryManager;
|
||||||
|
_formState = formState;
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
Loaded += async (_, _) =>
|
Loaded += OnLoaded;
|
||||||
|
|
||||||
|
ThumbnailsView.KeyDown += async (sender, args) =>
|
||||||
|
{
|
||||||
|
switch (args.Key)
|
||||||
|
{
|
||||||
|
case Key.Delete:
|
||||||
|
DeleteAnnotations();
|
||||||
|
break;
|
||||||
|
case Key.Enter:
|
||||||
|
await EditAnnotation();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ThumbnailsView.MouseDoubleClick += async (_, _) => await EditAnnotation();
|
||||||
|
|
||||||
|
ThumbnailsView.SelectionChanged += (_, _) =>
|
||||||
|
{
|
||||||
|
StatusText.Text = $"Обрано: {ThumbnailsView.SelectedItems.Count} | {ThumbnailsView.SelectedIndex} / {ThumbnailsDtos.Count}";
|
||||||
|
};
|
||||||
|
|
||||||
|
ExplorerEditor.GetTimeFunc = () => Constants.GetTime(CurrentThumbnail!.ImagePath);
|
||||||
|
galleryManager.ThumbnailsUpdate += thumbnailsPercentage =>
|
||||||
|
{
|
||||||
|
Dispatcher.Invoke(() => RefreshThumbBar.Value = thumbnailsPercentage);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void OnLoaded(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
_ = Task.Run(async () => await _galleryManager.RefreshThumbnails());
|
_ = Task.Run(async () => await _galleryManager.RefreshThumbnails());
|
||||||
|
|
||||||
@@ -77,42 +109,15 @@ public partial class DatasetExplorer
|
|||||||
foreach (var ann in ExplorerEditor.CurrentAnns.Where(x => x.IsSelected))
|
foreach (var ann in ExplorerEditor.CurrentAnns.Where(x => x.IsSelected))
|
||||||
ann.AnnotationClass = selectedClass;
|
ann.AnnotationClass = selectedClass;
|
||||||
};
|
};
|
||||||
|
Activated += (_, _) => _formState.ActiveWindow = WindowEnum.Annotator;
|
||||||
|
|
||||||
LvClasses.SelectedIndex = _annotationConfig.LastSelectedExplorerClass ?? 0;
|
LvClasses.SelectedIndex = _annotationConfig.LastSelectedExplorerClass ?? 0;
|
||||||
ExplorerEditor.CurrentAnnClass = (AnnotationClass)LvClasses.SelectedItem;
|
ExplorerEditor.CurrentAnnClass = (AnnotationClass)LvClasses.SelectedItem;
|
||||||
await ReloadThumbnails();
|
await ReloadThumbnails();
|
||||||
LoadClassDistribution();
|
LoadClassDistribution();
|
||||||
|
|
||||||
RefreshThumbBar.Value = galleryManager.ThumbnailsPercentage;
|
RefreshThumbBar.Value = _galleryManager.ThumbnailsPercentage;
|
||||||
DataContext = this;
|
DataContext = this;
|
||||||
};
|
|
||||||
|
|
||||||
ThumbnailsView.KeyDown += async (sender, args) =>
|
|
||||||
{
|
|
||||||
switch (args.Key)
|
|
||||||
{
|
|
||||||
case Key.Delete:
|
|
||||||
DeleteAnnotations();
|
|
||||||
break;
|
|
||||||
case Key.Enter:
|
|
||||||
await EditAnnotation();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
ThumbnailsView.MouseDoubleClick += async (_, _) => await EditAnnotation();
|
|
||||||
|
|
||||||
ThumbnailsView.SelectionChanged += (_, _) =>
|
|
||||||
{
|
|
||||||
StatusText.Text = $"Обрано: {ThumbnailsView.SelectedItems.Count} | {ThumbnailsView.SelectedIndex} / {ThumbnailsDtos.Count}";
|
|
||||||
};
|
|
||||||
|
|
||||||
ExplorerEditor.GetTimeFunc = () => Constants.GetTime(CurrentThumbnail!.ImagePath);
|
|
||||||
galleryManager.ThumbnailsUpdate += thumbnailsPercentage =>
|
|
||||||
{
|
|
||||||
Dispatcher.Invoke(() => RefreshThumbBar.Value = thumbnailsPercentage);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LoadClassDistribution()
|
private void LoadClassDistribution()
|
||||||
|
|||||||
@@ -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
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azaion.Dataset", "Azaion.Dataset\Azaion.Dataset.csproj", "{01A5CA37-A62E-4EF3-8678-D72CD9525677}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azaion.Dataset", "Azaion.Dataset\Azaion.Dataset.csproj", "{01A5CA37-A62E-4EF3-8678-D72CD9525677}"
|
||||||
EndProject
|
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}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dummy", "Dummy", "{C307BE2E-FFCC-4BD7-AD89-C82D40B65D03}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
Dummy\Azaion.Annotator.dll = Dummy\Azaion.Annotator.dll
|
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}.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.ActiveCfg = Release|Any CPU
|
||||||
{01A5CA37-A62E-4EF3-8678-D72CD9525677}.Release|Any CPU.Build.0 = 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.ActiveCfg = Debug|Any CPU
|
||||||
{32C4747F-F700-44FD-B4ED-21B4A66B5FAB}.Debug|Any CPU.Build.0 = 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
|
{32C4747F-F700-44FD-B4ED-21B4A66B5FAB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
|||||||
+48
-61
@@ -1,10 +1,8 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Input;
|
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
using Azaion.Annotator;
|
using Azaion.Annotator;
|
||||||
using Azaion.Annotator.DTO;
|
|
||||||
using Azaion.Annotator.Extensions;
|
using Azaion.Annotator.Extensions;
|
||||||
using Azaion.Common;
|
using Azaion.Common;
|
||||||
using Azaion.Common.DTO;
|
using Azaion.Common.DTO;
|
||||||
@@ -12,7 +10,6 @@ using Azaion.Common.DTO.Config;
|
|||||||
using Azaion.Common.Extensions;
|
using Azaion.Common.Extensions;
|
||||||
using Azaion.Common.Services;
|
using Azaion.Common.Services;
|
||||||
using Azaion.Dataset;
|
using Azaion.Dataset;
|
||||||
using CommandLine;
|
|
||||||
using LibVLCSharp.Shared;
|
using LibVLCSharp.Shared;
|
||||||
using MediatR;
|
using MediatR;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
@@ -22,31 +19,19 @@ using Microsoft.Extensions.Logging;
|
|||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
using KeyEventArgs = System.Windows.Input.KeyEventArgs;
|
||||||
|
|
||||||
namespace Azaion.Suite;
|
namespace Azaion.Suite;
|
||||||
|
|
||||||
public partial class App
|
public partial class App
|
||||||
{
|
{
|
||||||
private readonly IHost _host;
|
private IHost _host = null!;
|
||||||
private readonly ILogger<App> _logger;
|
private ILogger<App> _logger = null!;
|
||||||
private readonly IMediator _mediator;
|
private IMediator _mediator = null!;
|
||||||
|
private FormState _formState = null!;
|
||||||
|
|
||||||
//Authorize to api and
|
private AzaionApiClient _apiClient = null!;
|
||||||
private static readonly IResourceLoader ResourceLoader;
|
private IResourceLoader _resourceLoader = null!;
|
||||||
|
|
||||||
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)
|
private static AzaionApiClient CreateApiClient(ApiCredentials credentials)
|
||||||
{
|
{
|
||||||
@@ -68,6 +53,7 @@ public partial class App
|
|||||||
TimeoutSeconds = 40
|
TimeoutSeconds = 40
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var api = new AzaionApiClient(new HttpClient
|
var api = new AzaionApiClient(new HttpClient
|
||||||
{
|
{
|
||||||
BaseAddress = new Uri(apiConfig.Url),
|
BaseAddress = new Uri(apiConfig.Url),
|
||||||
@@ -78,7 +64,40 @@ public partial class App
|
|||||||
return api;
|
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()
|
Log.Logger = new LoggerConfiguration()
|
||||||
.Enrich.FromLogContext()
|
.Enrich.FromLogContext()
|
||||||
@@ -97,7 +116,9 @@ public partial class App
|
|||||||
{
|
{
|
||||||
services.AddSingleton<MainSuite>();
|
services.AddSingleton<MainSuite>();
|
||||||
services.AddSingleton<IHardwareService, HardwareService>();
|
services.AddSingleton<IHardwareService, HardwareService>();
|
||||||
services.AddSingleton(ResourceLoader);
|
|
||||||
|
services.AddSingleton(_apiClient);
|
||||||
|
services.AddSingleton(_resourceLoader);
|
||||||
|
|
||||||
services.Configure<AppConfig>(context.Configuration);
|
services.Configure<AppConfig>(context.Configuration);
|
||||||
services.ConfigureSection<ApiConfig>(context.Configuration);
|
services.ConfigureSection<ApiConfig>(context.Configuration);
|
||||||
@@ -141,31 +162,15 @@ public partial class App
|
|||||||
.Build();
|
.Build();
|
||||||
_mediator = _host.Services.GetRequiredService<IMediator>();
|
_mediator = _host.Services.GetRequiredService<IMediator>();
|
||||||
_logger = _host.Services.GetRequiredService<ILogger<App>>();
|
_logger = _host.Services.GetRequiredService<ILogger<App>>();
|
||||||
|
_formState = _host.Services.GetRequiredService<FormState>();
|
||||||
DispatcherUnhandledException += OnDispatcherUnhandledException;
|
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)
|
private void GlobalClick(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
var args = (KeyEventArgs)e;
|
var args = (KeyEventArgs)e;
|
||||||
var windowEnum = GetParentWindow(sender as FrameworkElement);
|
|
||||||
if (windowEnum == WindowEnum.None)
|
var keyEvent = new KeyEvent(sender, args, _formState.ActiveWindow);
|
||||||
return;
|
|
||||||
var keyEvent = new KeyEvent(sender, args, windowEnum);
|
|
||||||
_ = ThrottleExt.Throttle(() => _mediator.Publish(keyEvent), TimeSpan.FromMilliseconds(50));
|
_ = ThrottleExt.Throttle(() => _mediator.Publish(keyEvent), TimeSpan.FromMilliseconds(50));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,27 +181,9 @@ public partial class App
|
|||||||
{ "Azaion.Dataset.DatasetExplorer", WindowEnum.DatasetExplorer }
|
{ "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)
|
protected override async void OnExit(ExitEventArgs e)
|
||||||
{
|
{
|
||||||
base.OnExit(e);
|
base.OnExit(e);
|
||||||
|
|
||||||
await _host.StopAsync();
|
await _host.StopAsync();
|
||||||
//_host.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,6 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CommandLineParser" Version="2.9.1" />
|
|
||||||
<PackageReference Include="LibVLCSharp" Version="3.9.1" />
|
<PackageReference Include="LibVLCSharp" Version="3.9.1" />
|
||||||
<PackageReference Include="LibVLCSharp.WPF" Version="3.9.1" />
|
<PackageReference Include="LibVLCSharp.WPF" Version="3.9.1" />
|
||||||
<PackageReference Include="MediatR" Version="12.4.1" />
|
<PackageReference Include="MediatR" Version="12.4.1" />
|
||||||
@@ -40,6 +39,14 @@
|
|||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="Login.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
<XamlRuntime>Wpf</XamlRuntime>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="Build">
|
<Target Name="PostBuild" AfterTargets="Build">
|
||||||
<MakeDir Directories="$(TargetDir)secure" />
|
<MakeDir Directories="$(TargetDir)secure" />
|
||||||
<Move SourceFiles="$(TargetDir)Azaion.Annotator.dll" DestinationFolder="$(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="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
@@ -97,7 +97,7 @@
|
|||||||
Height="35"
|
Height="35"
|
||||||
Width="280"
|
Width="280"
|
||||||
Cursor="Hand"
|
Cursor="Hand"
|
||||||
Click="RunClick">
|
Click="LoginClick">
|
||||||
<Button.Style>
|
<Button.Style>
|
||||||
<Style TargetType="Button">
|
<Style TargetType="Button">
|
||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
@@ -1,21 +1,22 @@
|
|||||||
using System.Diagnostics;
|
using System.Windows;
|
||||||
using System.Windows;
|
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Input;
|
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();
|
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}");
|
CredentialsEntered?.Invoke(this, new ApiCredentials(TbEmail.Text, TbPassword.Password));
|
||||||
await Task.Delay(2000);
|
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6,10 +6,10 @@ namespace Azaion.Annotator.Test;
|
|||||||
public class HardwareServiceTest
|
public class HardwareServiceTest
|
||||||
{
|
{
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetHardware_Test()
|
public void GetHardware_Test()
|
||||||
{
|
{
|
||||||
var hardwareService = new HardwareService();
|
var hardwareService = new HardwareService();
|
||||||
var hw = await hardwareService.GetHardware();
|
var hw = hardwareService.GetHardware();
|
||||||
Console.WriteLine(hw);
|
Console.WriteLine(hw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user