mirror of
https://github.com/azaion/annotations.git
synced 2026-04-22 11:26:31 +00:00
make python app load a bit eariler, making startup a bit faster
This commit is contained in:
@@ -148,13 +148,13 @@
|
|||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
Name="LvFiles"
|
Name="LvFiles"
|
||||||
Background="Black"
|
Background="Black"
|
||||||
SelectedItem="{Binding Path=SelectedVideo}" Foreground="#FFA4AFCC"
|
SelectedItem="{Binding Path=SelectedVideo}" Foreground="#FFEEEEEE"
|
||||||
>
|
>
|
||||||
<ListView.Resources>
|
<ListView.Resources>
|
||||||
<Style TargetType="{x:Type ListViewItem}">
|
<Style TargetType="{x:Type ListViewItem}">
|
||||||
<Style.Triggers>
|
<Style.Triggers>
|
||||||
<DataTrigger Binding="{Binding HasAnnotations}" Value="true">
|
<DataTrigger Binding="{Binding HasAnnotations}" Value="true">
|
||||||
<Setter Property="Background" Value="Gray"/>
|
<Setter Property="Background" Value="#FF505050"/>
|
||||||
</DataTrigger>
|
</DataTrigger>
|
||||||
</Style.Triggers>
|
</Style.Triggers>
|
||||||
<EventSetter Event="ContextMenuOpening" Handler="LvFilesContextOpening"></EventSetter>
|
<EventSetter Event="ContextMenuOpening" Handler="LvFilesContextOpening"></EventSetter>
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ public partial class Annotator
|
|||||||
private readonly AnnotationService _annotationService;
|
private readonly AnnotationService _annotationService;
|
||||||
private readonly IDbFactory _dbFactory;
|
private readonly IDbFactory _dbFactory;
|
||||||
private readonly IInferenceService _inferenceService;
|
private readonly IInferenceService _inferenceService;
|
||||||
private readonly IResourceLoader _resourceLoader;
|
|
||||||
|
|
||||||
private ObservableCollection<DetectionClass> AnnotationClasses { get; set; } = new();
|
private ObservableCollection<DetectionClass> AnnotationClasses { get; set; } = new();
|
||||||
private bool _suspendLayout;
|
private bool _suspendLayout;
|
||||||
@@ -71,8 +70,7 @@ public partial class Annotator
|
|||||||
ILogger<Annotator> logger,
|
ILogger<Annotator> logger,
|
||||||
AnnotationService annotationService,
|
AnnotationService annotationService,
|
||||||
IDbFactory dbFactory,
|
IDbFactory dbFactory,
|
||||||
IInferenceService inferenceService,
|
IInferenceService inferenceService)
|
||||||
IResourceLoader resourceLoader)
|
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
_appConfig = appConfig.Value;
|
_appConfig = appConfig.Value;
|
||||||
@@ -86,7 +84,6 @@ public partial class Annotator
|
|||||||
_annotationService = annotationService;
|
_annotationService = annotationService;
|
||||||
_dbFactory = dbFactory;
|
_dbFactory = dbFactory;
|
||||||
_inferenceService = inferenceService;
|
_inferenceService = inferenceService;
|
||||||
_resourceLoader = resourceLoader;
|
|
||||||
|
|
||||||
Loaded += OnLoaded;
|
Loaded += OnLoaded;
|
||||||
Closed += OnFormClosed;
|
Closed += OnFormClosed;
|
||||||
@@ -401,7 +398,6 @@ public partial class Annotator
|
|||||||
|
|
||||||
private void OnFormClosed(object? sender, EventArgs e)
|
private void OnFormClosed(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
_resourceLoader.StopPython();
|
|
||||||
MainCancellationSource.Cancel();
|
MainCancellationSource.Cancel();
|
||||||
DetectionCancellationSource.Cancel();
|
DetectionCancellationSource.Cancel();
|
||||||
_mediaPlayer.Stop();
|
_mediaPlayer.Stop();
|
||||||
@@ -454,6 +450,7 @@ public partial class Annotator
|
|||||||
|
|
||||||
_appConfig.DirectoriesConfig.VideosDirectory = dlg.FileName;
|
_appConfig.DirectoriesConfig.VideosDirectory = dlg.FileName;
|
||||||
TbFolder.Text = dlg.FileName;
|
TbFolder.Text = dlg.FileName;
|
||||||
|
await Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TbFilter_OnTextChanged(object sender, TextChangedEventArgs e)
|
private void TbFilter_OnTextChanged(object sender, TextChangedEventArgs e)
|
||||||
@@ -497,8 +494,6 @@ public partial class Annotator
|
|||||||
LvFilesContextMenu.DataContext = listItem!.DataContext;
|
LvFilesContextMenu.DataContext = listItem!.DataContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
private (TimeSpan Time, List<Detection> Detections)? _previousDetection;
|
|
||||||
|
|
||||||
public void AutoDetect(object sender, RoutedEventArgs e)
|
public void AutoDetect(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
if (IsInferenceNow)
|
if (IsInferenceNow)
|
||||||
@@ -560,7 +555,7 @@ public partial class Annotator
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var annotation = await _annotationService.SaveAnnotation(annotationImage);
|
var annotation = await _annotationService.SaveAnnotation(annotationImage);
|
||||||
if (annotation.OriginalMediaName != _formState.CurrentMedia.FName)
|
if (annotation.OriginalMediaName != _formState.CurrentMedia?.FName)
|
||||||
return;
|
return;
|
||||||
AddAnnotation(annotation);
|
AddAnnotation(annotation);
|
||||||
|
|
||||||
|
|||||||
@@ -14,4 +14,5 @@ public class AIRecognitionConfig
|
|||||||
[Key(nameof(TrackingIntersectionThreshold))] public double TrackingIntersectionThreshold { get; set; }
|
[Key(nameof(TrackingIntersectionThreshold))] public double TrackingIntersectionThreshold { get; set; }
|
||||||
|
|
||||||
[Key(nameof(Data))] public byte[] Data { get; set; }
|
[Key(nameof(Data))] public byte[] Data { get; set; }
|
||||||
|
[Key(nameof(Paths))] public List<string> Paths { get; set; }
|
||||||
}
|
}
|
||||||
@@ -26,9 +26,9 @@ public class PythonInferenceService(ILogger<PythonInferenceService> logger, IOpt
|
|||||||
dealer.Options.Identity = Encoding.UTF8.GetBytes(clientId.ToString("N"));
|
dealer.Options.Identity = Encoding.UTF8.GetBytes(clientId.ToString("N"));
|
||||||
dealer.Connect($"tcp://{SecurityConstants.ZMQ_HOST}:{SecurityConstants.ZMQ_PORT}");
|
dealer.Connect($"tcp://{SecurityConstants.ZMQ_HOST}:{SecurityConstants.ZMQ_PORT}");
|
||||||
|
|
||||||
var data = MessagePackSerializer.Serialize(aiConfigOptions.Value);
|
var aiConfig = aiConfigOptions.Value;
|
||||||
var filename = JsonConvert.SerializeObject(mediaPaths);
|
aiConfig.Paths = mediaPaths;
|
||||||
dealer.SendFrame(MessagePackSerializer.Serialize(new RemoteCommand(CommandType.Inference, filename, data)));
|
dealer.SendFrame(RemoteCommand.Serialize(CommandType.Inference, aiConfig));
|
||||||
|
|
||||||
while (!ct.IsCancellationRequested)
|
while (!ct.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,16 @@
|
|||||||
namespace Azaion.CommonSecurity.DTO;
|
using MessagePack;
|
||||||
|
|
||||||
|
namespace Azaion.CommonSecurity.DTO;
|
||||||
|
|
||||||
|
[MessagePackObject]
|
||||||
public class ApiCredentials(string email, string password) : EventArgs
|
public class ApiCredentials(string email, string password) : EventArgs
|
||||||
{
|
{
|
||||||
|
[Key(nameof(Email))]
|
||||||
public string Email { get; set; } = email;
|
public string Email { get; set; } = email;
|
||||||
|
|
||||||
|
[Key(nameof(Password))]
|
||||||
public string Password { get; set; } = password;
|
public string Password { get; set; } = password;
|
||||||
|
|
||||||
|
[Key(nameof(Folder))]
|
||||||
|
public string Folder { get; set; } = null!;
|
||||||
}
|
}
|
||||||
@@ -3,22 +3,36 @@
|
|||||||
namespace Azaion.CommonSecurity.DTO.Commands;
|
namespace Azaion.CommonSecurity.DTO.Commands;
|
||||||
|
|
||||||
[MessagePackObject]
|
[MessagePackObject]
|
||||||
public class RemoteCommand(CommandType commandType, string? filename = null, byte[]? data = null)
|
public class RemoteCommand(CommandType commandType, byte[]? data = null)
|
||||||
{
|
{
|
||||||
[Key("CommandType")]
|
[Key("CommandType")]
|
||||||
public CommandType CommandType { get; set; } = commandType;
|
public CommandType CommandType { get; set; } = commandType;
|
||||||
|
|
||||||
[Key("Filename")]
|
|
||||||
public string? Filename { get; set; } = filename;
|
|
||||||
|
|
||||||
[Key("Data")]
|
[Key("Data")]
|
||||||
public byte[]? Data { get; set; } = data;
|
public byte[]? Data { get; set; } = data;
|
||||||
|
|
||||||
|
public static byte[] Serialize<T>(CommandType commandType, T data) where T : class
|
||||||
|
{
|
||||||
|
var dataBytes = MessagePackSerializer.Serialize(data);
|
||||||
|
return MessagePackSerializer.Serialize(new RemoteCommand(commandType, dataBytes ));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[MessagePackObject]
|
||||||
|
public class LoadFileData(string filename, string? folder = null )
|
||||||
|
{
|
||||||
|
[Key(nameof(Folder))]
|
||||||
|
public string? Folder { get; set; } = folder;
|
||||||
|
|
||||||
|
[Key(nameof(Filename))]
|
||||||
|
public string Filename { get; set; } = filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public enum CommandType
|
public enum CommandType
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
GetUser = 10,
|
Login = 10,
|
||||||
Load = 20,
|
Load = 20,
|
||||||
Inference = 30,
|
Inference = 30,
|
||||||
StopInference = 40,
|
StopInference = 40,
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ namespace Azaion.CommonSecurity.DTO;
|
|||||||
[MessagePackObject]
|
[MessagePackObject]
|
||||||
public class User
|
public class User
|
||||||
{
|
{
|
||||||
[Key("i")]public string Id { get; set; }
|
[Key("i")] public string Id { get; set; } = "";
|
||||||
[Key("e")]public string Email { get; set; }
|
[Key("e")] public string Email { get; set; } = "";
|
||||||
[Key("r")]public RoleEnum Role { get; set; }
|
[Key("r")]public RoleEnum Role { get; set; }
|
||||||
|
|
||||||
//For deserializing
|
//For deserializing
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ namespace Azaion.CommonSecurity.Services;
|
|||||||
|
|
||||||
public interface IResourceLoader
|
public interface IResourceLoader
|
||||||
{
|
{
|
||||||
MemoryStream LoadFileFromPython(string fileName);
|
MemoryStream LoadFileFromPython(string fileName, string? folder = null);
|
||||||
void StopPython();
|
void StopPython();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,29 +25,22 @@ public class PythonResourceLoader : IResourceLoader, IAuthProvider
|
|||||||
private readonly DealerSocket _dealer = new();
|
private readonly DealerSocket _dealer = new();
|
||||||
private readonly Guid _clientId = Guid.NewGuid();
|
private readonly Guid _clientId = Guid.NewGuid();
|
||||||
|
|
||||||
public User CurrentUser { get; }
|
public User CurrentUser { get; set; }
|
||||||
|
|
||||||
public PythonResourceLoader(ApiConfig apiConfig, ApiCredentials credentials, AzaionApiClient api)
|
public PythonResourceLoader()
|
||||||
{
|
{
|
||||||
StartPython(apiConfig, credentials);
|
StartPython();
|
||||||
_dealer.Options.Identity = Encoding.UTF8.GetBytes(_clientId.ToString("N"));
|
_dealer.Options.Identity = Encoding.UTF8.GetBytes(_clientId.ToString("N"));
|
||||||
_dealer.Connect($"tcp://{SecurityConstants.ZMQ_HOST}:{SecurityConstants.ZMQ_PORT}");
|
_dealer.Connect($"tcp://{SecurityConstants.ZMQ_HOST}:{SecurityConstants.ZMQ_PORT}");
|
||||||
|
|
||||||
_dealer.SendFrame(MessagePackSerializer.Serialize(new RemoteCommand(CommandType.GetUser)));
|
|
||||||
var user = _dealer.Get<User>();
|
|
||||||
if (user == null)
|
|
||||||
throw new Exception("Can't get user from Auth provider");
|
|
||||||
|
|
||||||
CurrentUser = user;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StartPython( ApiConfig apiConfig, ApiCredentials credentials)
|
private void StartPython()
|
||||||
{
|
{
|
||||||
using var process = new Process();
|
using var process = new Process();
|
||||||
process.StartInfo = new ProcessStartInfo
|
process.StartInfo = new ProcessStartInfo
|
||||||
{
|
{
|
||||||
FileName = SecurityConstants.AZAION_INFERENCE_PATH,
|
FileName = SecurityConstants.AZAION_INFERENCE_PATH,
|
||||||
Arguments = $"-e {credentials.Email} -p {credentials.Password} -f {apiConfig.ResourcesFolder}",
|
//Arguments = $"-e {credentials.Email} -p {credentials.Password} -f {apiConfig.ResourcesFolder}",
|
||||||
//UseShellExecute = false,
|
//UseShellExecute = false,
|
||||||
//RedirectStandardOutput = true,
|
//RedirectStandardOutput = true,
|
||||||
// RedirectStandardError = true,
|
// RedirectStandardError = true,
|
||||||
@@ -59,17 +52,27 @@ public class PythonResourceLoader : IResourceLoader, IAuthProvider
|
|||||||
process.Start();
|
process.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Login(ApiCredentials credentials)
|
||||||
|
{
|
||||||
|
_dealer.SendFrame(RemoteCommand.Serialize(CommandType.Login, credentials));
|
||||||
|
var user = _dealer.Get<User>();
|
||||||
|
if (user == null)
|
||||||
|
throw new Exception("Can't get user from Auth provider");
|
||||||
|
|
||||||
|
CurrentUser = user;
|
||||||
|
}
|
||||||
|
|
||||||
public void StopPython()
|
public void StopPython()
|
||||||
{
|
{
|
||||||
_dealer.SendFrame(MessagePackSerializer.Serialize(new RemoteCommand(CommandType.Exit)));
|
_dealer.SendFrame(MessagePackSerializer.Serialize(new RemoteCommand(CommandType.Exit)));
|
||||||
_dealer?.Close();
|
_dealer.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public MemoryStream LoadFileFromPython(string fileName)
|
public MemoryStream LoadFileFromPython(string fileName, string? folder = null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_dealer.SendFrame(MessagePackSerializer.Serialize(new RemoteCommand(CommandType.Load, fileName)));
|
_dealer.SendFrame(RemoteCommand.Serialize(CommandType.Load, new LoadFileData(fileName, folder)));
|
||||||
|
|
||||||
if (!_dealer.TryReceiveFrameBytes(TimeSpan.FromSeconds(3), out var bytes))
|
if (!_dealer.TryReceiveFrameBytes(TimeSpan.FromSeconds(3), out var bytes))
|
||||||
throw new Exception($"Unable to receive {fileName}");
|
throw new Exception($"Unable to receive {fileName}");
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
from user cimport User
|
from user cimport User
|
||||||
|
from credentials cimport Credentials
|
||||||
|
from file_data cimport FileData
|
||||||
|
|
||||||
cdef class ApiClient:
|
cdef class ApiClient:
|
||||||
cdef str email, password, token, folder, token_file, api_url
|
cdef public Credentials credentials
|
||||||
|
cdef str token, folder, api_url
|
||||||
cdef User user
|
cdef User user
|
||||||
|
|
||||||
cdef get_encryption_key(self, str hardware_hash)
|
cdef get_encryption_key(self, str hardware_hash)
|
||||||
@@ -9,7 +12,7 @@ cdef class ApiClient:
|
|||||||
cdef set_token(self, str token)
|
cdef set_token(self, str token)
|
||||||
cdef get_user(self)
|
cdef get_user(self)
|
||||||
|
|
||||||
cdef load_bytes(self, str filename)
|
cdef load_bytes(self, FileData file_data)
|
||||||
cdef load_ai_model(self)
|
cdef load_ai_model(self)
|
||||||
cdef load_queue_config(self)
|
cdef load_queue_config(self)
|
||||||
|
|
||||||
|
|||||||
@@ -9,33 +9,25 @@ from hardware_service cimport HardwareService, HardwareInfo
|
|||||||
from security cimport Security
|
from security cimport Security
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from user cimport User, RoleEnum
|
from user cimport User, RoleEnum
|
||||||
|
from file_data cimport FileData
|
||||||
|
|
||||||
cdef class ApiClient:
|
cdef class ApiClient:
|
||||||
"""Handles API authentication and downloading of the AI model."""
|
"""Handles API authentication and downloading of the AI model."""
|
||||||
def __init__(self, str email, str password, str folder):
|
def __init__(self):
|
||||||
self.email = email
|
self.credentials = None
|
||||||
self.password = password
|
|
||||||
self.folder = folder
|
|
||||||
self.user = None
|
self.user = None
|
||||||
|
|
||||||
if os.path.exists(<str>constants.TOKEN_FILE):
|
|
||||||
with open(<str>constants.TOKEN_FILE, "r") as file:
|
|
||||||
self.set_token(<str>file.read().strip())
|
|
||||||
else:
|
|
||||||
self.token = None
|
self.token = None
|
||||||
|
|
||||||
cdef get_encryption_key(self, str hardware_hash):
|
cdef get_encryption_key(self, str hardware_hash):
|
||||||
cdef str key = f'{self.email}-{self.password}-{hardware_hash}-#%@AzaionKey@%#---'
|
cdef str key = f'{self.credentials.email}-{self.credentials.password}-{hardware_hash}-#%@AzaionKey@%#---'
|
||||||
return Security.calc_hash(key)
|
return Security.calc_hash(key)
|
||||||
|
|
||||||
cdef login(self):
|
cdef login(self):
|
||||||
response = requests.post(f"{constants.API_URL}/login",
|
response = requests.post(f"{constants.API_URL}/login",
|
||||||
json={"email": self.email, "password": self.password})
|
json={"email": self.credentials.email, "password": self.credentials.password})
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
token = response.json()["token"]
|
token = response.json()["token"]
|
||||||
self.set_token(token)
|
self.set_token(token)
|
||||||
with open(<str>constants.TOKEN_FILE, 'w') as file:
|
|
||||||
file.write(token)
|
|
||||||
|
|
||||||
cdef set_token(self, str token):
|
cdef set_token(self, str token):
|
||||||
self.token = token
|
self.token = token
|
||||||
@@ -68,14 +60,15 @@ cdef class ApiClient:
|
|||||||
self.login()
|
self.login()
|
||||||
return self.user
|
return self.user
|
||||||
|
|
||||||
cdef load_bytes(self, str filename):
|
cdef load_bytes(self, FileData file_data):
|
||||||
|
folder = file_data.folder or self.credentials.folder
|
||||||
hardware_service = HardwareService()
|
hardware_service = HardwareService()
|
||||||
cdef HardwareInfo hardware = hardware_service.get_hardware_info()
|
cdef HardwareInfo hardware = hardware_service.get_hardware_info()
|
||||||
|
|
||||||
if self.token is None:
|
if self.token is None:
|
||||||
self.login()
|
self.login()
|
||||||
|
|
||||||
url = f"{constants.API_URL}/resources/get/{self.folder}"
|
url = f"{constants.API_URL}/resources/get/{folder}"
|
||||||
headers = {
|
headers = {
|
||||||
"Authorization": f"Bearer {self.token}",
|
"Authorization": f"Bearer {self.token}",
|
||||||
"Content-Type": "application/json"
|
"Content-Type": "application/json"
|
||||||
@@ -83,9 +76,9 @@ cdef class ApiClient:
|
|||||||
|
|
||||||
payload = json.dumps(
|
payload = json.dumps(
|
||||||
{
|
{
|
||||||
"password": self.password,
|
"password": self.credentials.password,
|
||||||
"hardware": hardware.to_json_object(),
|
"hardware": hardware.to_json_object(),
|
||||||
"fileName": filename
|
"fileName": file_data.filename
|
||||||
}, indent=4)
|
}, indent=4)
|
||||||
response = requests.post(url, data=payload, headers=headers, stream=True)
|
response = requests.post(url, data=payload, headers=headers, stream=True)
|
||||||
|
|
||||||
@@ -104,7 +97,7 @@ cdef class ApiClient:
|
|||||||
|
|
||||||
stream = BytesIO(response.raw.read())
|
stream = BytesIO(response.raw.read())
|
||||||
data = Security.decrypt_to(stream, key)
|
data = Security.decrypt_to(stream, key)
|
||||||
print(f'loaded file: {filename}, {len(data)} bytes')
|
print(f'loaded file: {file_data.filename}, {len(data)} bytes')
|
||||||
return data
|
return data
|
||||||
|
|
||||||
cdef load_ai_model(self):
|
cdef load_ai_model(self):
|
||||||
|
|||||||
@@ -7,13 +7,15 @@ pyinstaller --onefile ^
|
|||||||
--collect-all cryptography ^
|
--collect-all cryptography ^
|
||||||
--collect-all cv2 ^
|
--collect-all cv2 ^
|
||||||
--collect-all onnxruntime ^
|
--collect-all onnxruntime ^
|
||||||
|
--hidden-import constants ^
|
||||||
|
--hidden-import annotation ^
|
||||||
|
--hidden-import credentials ^
|
||||||
|
--hidden-import file_data ^
|
||||||
--hidden-import user ^
|
--hidden-import user ^
|
||||||
--hidden-import security ^
|
--hidden-import security ^
|
||||||
--hidden-import secure_model ^
|
--hidden-import secure_model ^
|
||||||
--hidden-import api_client ^
|
--hidden-import api_client ^
|
||||||
--hidden-import hardware_service ^
|
--hidden-import hardware_service ^
|
||||||
--hidden-import constants ^
|
|
||||||
--hidden-import annotation ^
|
|
||||||
--hidden-import remote_command ^
|
--hidden-import remote_command ^
|
||||||
--hidden-import ai_config ^
|
--hidden-import ai_config ^
|
||||||
--hidden-import inference ^
|
--hidden-import inference ^
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ cdef str COMMANDS_QUEUE # Name of the commands queue in rabbit
|
|||||||
cdef str ANNOTATIONS_QUEUE # Name of the annotations queue in rabbit
|
cdef str ANNOTATIONS_QUEUE # Name of the annotations queue in rabbit
|
||||||
|
|
||||||
cdef str API_URL # Base URL for the external API
|
cdef str API_URL # Base URL for the external API
|
||||||
cdef str TOKEN_FILE # Name of the token file where temporary token would be stored
|
|
||||||
cdef str QUEUE_CONFIG_FILENAME # queue config filename to load from api
|
cdef str QUEUE_CONFIG_FILENAME # queue config filename to load from api
|
||||||
cdef str AI_MODEL_FILE # AI Model file
|
cdef str AI_MODEL_FILE # AI Model file
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ cdef str COMMANDS_QUEUE = "azaion-commands"
|
|||||||
cdef str ANNOTATIONS_QUEUE = "azaion-annotations"
|
cdef str ANNOTATIONS_QUEUE = "azaion-annotations"
|
||||||
|
|
||||||
cdef str API_URL = "https://api.azaion.com" # Base URL for the external API
|
cdef str API_URL = "https://api.azaion.com" # Base URL for the external API
|
||||||
cdef str TOKEN_FILE = "token"
|
|
||||||
cdef str QUEUE_CONFIG_FILENAME = "secured-config.json"
|
cdef str QUEUE_CONFIG_FILENAME = "secured-config.json"
|
||||||
cdef str AI_MODEL_FILE = "azaion.onnx"
|
cdef str AI_MODEL_FILE = "azaion.onnx"
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
cdef class Credentials:
|
||||||
|
cdef public str email
|
||||||
|
cdef public str password
|
||||||
|
cdef public str folder
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
cdef from_msgpack(bytes data)
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
from msgpack import unpackb
|
||||||
|
|
||||||
|
cdef class Credentials:
|
||||||
|
|
||||||
|
def __init__(self, str email, str password, str folder):
|
||||||
|
self.email = email
|
||||||
|
self.password = password
|
||||||
|
self.folder = folder
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
cdef from_msgpack(bytes data):
|
||||||
|
unpacked = unpackb(data, strict_map_key=False)
|
||||||
|
return Credentials(
|
||||||
|
unpacked.get("Email"),
|
||||||
|
unpacked.get("Password"),
|
||||||
|
unpacked.get("Folder"))
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
cdef class FileData:
|
||||||
|
cdef public str folder
|
||||||
|
cdef public str filename
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
cdef from_msgpack(bytes data)
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
from msgpack import unpackb
|
||||||
|
|
||||||
|
cdef class FileData:
|
||||||
|
|
||||||
|
def __init__(self, str folder, str filename):
|
||||||
|
self.folder = folder
|
||||||
|
self.filename = filename
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
cdef from_msgpack(bytes data):
|
||||||
|
unpacked = unpackb(data, strict_map_key=False)
|
||||||
|
return FileData(
|
||||||
|
unpacked.get("Folder"),
|
||||||
|
unpacked.get("Filename"))
|
||||||
+15
-15
@@ -9,16 +9,10 @@ from annotation cimport Annotation
|
|||||||
from inference cimport Inference
|
from inference cimport Inference
|
||||||
from remote_command cimport RemoteCommand, CommandType
|
from remote_command cimport RemoteCommand, CommandType
|
||||||
from remote_command_handler cimport RemoteCommandHandler
|
from remote_command_handler cimport RemoteCommandHandler
|
||||||
|
from credentials cimport Credentials
|
||||||
|
from file_data cimport FileData
|
||||||
from user cimport User
|
from user cimport User
|
||||||
|
|
||||||
cdef class ParsedArguments:
|
|
||||||
cdef str email, password, folder;
|
|
||||||
|
|
||||||
def __init__(self, str email, str password, str folder):
|
|
||||||
self.email = email
|
|
||||||
self.password = password
|
|
||||||
self.folder = folder
|
|
||||||
|
|
||||||
cdef class CommandProcessor:
|
cdef class CommandProcessor:
|
||||||
cdef ApiClient api_client
|
cdef ApiClient api_client
|
||||||
cdef RemoteCommandHandler remote_handler
|
cdef RemoteCommandHandler remote_handler
|
||||||
@@ -26,8 +20,8 @@ cdef class CommandProcessor:
|
|||||||
cdef bint running
|
cdef bint running
|
||||||
cdef Inference inference
|
cdef Inference inference
|
||||||
|
|
||||||
def __init__(self, args: ParsedArguments):
|
def __init__(self):
|
||||||
self.api_client = ApiClient(args.email, args.password, args.folder)
|
self.api_client = ApiClient()
|
||||||
self.remote_handler = RemoteCommandHandler(self.on_command)
|
self.remote_handler = RemoteCommandHandler(self.on_command)
|
||||||
self.inference_queue = Queue(maxsize=constants.QUEUE_MAXSIZE)
|
self.inference_queue = Queue(maxsize=constants.QUEUE_MAXSIZE)
|
||||||
self.remote_handler.start()
|
self.remote_handler.start()
|
||||||
@@ -49,11 +43,10 @@ cdef class CommandProcessor:
|
|||||||
|
|
||||||
cdef on_command(self, RemoteCommand command):
|
cdef on_command(self, RemoteCommand command):
|
||||||
try:
|
try:
|
||||||
if command.command_type == CommandType.GET_USER:
|
if command.command_type == CommandType.LOGIN:
|
||||||
self.get_user(command, self.api_client.get_user())
|
self.login(command)
|
||||||
elif command.command_type == CommandType.LOAD:
|
elif command.command_type == CommandType.LOAD:
|
||||||
response = self.api_client.load_bytes(command.filename)
|
self.load_file(command)
|
||||||
self.remote_handler.send(command.client_id, response)
|
|
||||||
elif command.command_type == CommandType.INFERENCE:
|
elif command.command_type == CommandType.INFERENCE:
|
||||||
self.inference_queue.put(command)
|
self.inference_queue.put(command)
|
||||||
elif command.command_type == CommandType.STOP_INFERENCE:
|
elif command.command_type == CommandType.STOP_INFERENCE:
|
||||||
@@ -66,9 +59,16 @@ cdef class CommandProcessor:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error handling client: {e}")
|
print(f"Error handling client: {e}")
|
||||||
|
|
||||||
cdef get_user(self, RemoteCommand command, User user):
|
cdef login(self, RemoteCommand command):
|
||||||
|
cdef User user
|
||||||
|
self.api_client.credentials = Credentials.from_msgpack(command.data)
|
||||||
|
user = self.api_client.get_user()
|
||||||
self.remote_handler.send(command.client_id, user.serialize())
|
self.remote_handler.send(command.client_id, user.serialize())
|
||||||
|
|
||||||
|
cdef load_file(self, RemoteCommand command):
|
||||||
|
response = self.api_client.load_bytes(FileData.from_msgpack(command.data))
|
||||||
|
self.remote_handler.send(command.client_id, response)
|
||||||
|
|
||||||
cdef on_annotation(self, RemoteCommand cmd, Annotation annotation):
|
cdef on_annotation(self, RemoteCommand cmd, Annotation annotation):
|
||||||
data = annotation.serialize()
|
data = annotation.serialize()
|
||||||
self.remote_handler.send(cmd.client_id, data)
|
self.remote_handler.send(cmd.client_id, data)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
cdef enum CommandType:
|
cdef enum CommandType:
|
||||||
GET_USER = 10
|
LOGIN = 10
|
||||||
LOAD = 20
|
LOAD = 20
|
||||||
INFERENCE = 30
|
INFERENCE = 30
|
||||||
STOP_INFERENCE = 40
|
STOP_INFERENCE = 40
|
||||||
@@ -8,7 +8,6 @@ cdef enum CommandType:
|
|||||||
cdef class RemoteCommand:
|
cdef class RemoteCommand:
|
||||||
cdef public bytes client_id
|
cdef public bytes client_id
|
||||||
cdef CommandType command_type
|
cdef CommandType command_type
|
||||||
cdef str filename
|
|
||||||
cdef bytes data
|
cdef bytes data
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|||||||
@@ -1,23 +1,22 @@
|
|||||||
import msgpack
|
import msgpack
|
||||||
|
|
||||||
cdef class RemoteCommand:
|
cdef class RemoteCommand:
|
||||||
def __init__(self, CommandType command_type, str filename, bytes data):
|
def __init__(self, CommandType command_type, bytes data):
|
||||||
self.command_type = command_type
|
self.command_type = command_type
|
||||||
self.filename = filename
|
|
||||||
self.data = data
|
self.data = data
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
command_type_names = {
|
command_type_names = {
|
||||||
10: "GET_USER",
|
10: "LOGIN",
|
||||||
20: "LOAD",
|
20: "LOAD",
|
||||||
30: "INFERENCE",
|
30: "INFERENCE",
|
||||||
40: "STOP_INFERENCE",
|
40: "STOP_INFERENCE",
|
||||||
100: "EXIT"
|
100: "EXIT"
|
||||||
}
|
}
|
||||||
data_str = f'. Data: {len(self.data)} bytes' if self.data else ''
|
data_str = f'. Data: {len(self.data)} bytes' if self.data else ''
|
||||||
return f'{command_type_names[self.command_type]}: {self.filename}{data_str}'
|
return f'{command_type_names[self.command_type]}: {data_str}'
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
cdef from_msgpack(bytes data):
|
cdef from_msgpack(bytes data):
|
||||||
unpacked = msgpack.unpackb(data, strict_map_key=False)
|
unpacked = msgpack.unpackb(data, strict_map_key=False)
|
||||||
return RemoteCommand(unpacked.get("CommandType"), unpacked.get("Filename"), unpacked.get("Data"))
|
return RemoteCommand(unpacked.get("CommandType"), unpacked.get("Data"))
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import numpy as np
|
|||||||
extensions = [
|
extensions = [
|
||||||
Extension('constants', ['constants.pyx']),
|
Extension('constants', ['constants.pyx']),
|
||||||
Extension('annotation', ['annotation.pyx']),
|
Extension('annotation', ['annotation.pyx']),
|
||||||
|
Extension('credentials', ['credentials.pyx']),
|
||||||
|
Extension('file_data', ['file_data.pyx']),
|
||||||
Extension('security', ['security.pyx']),
|
Extension('security', ['security.pyx']),
|
||||||
Extension('hardware_service', ['hardware_service.pyx'], extra_compile_args=["-g"], extra_link_args=["-g"]),
|
Extension('hardware_service', ['hardware_service.pyx'], extra_compile_args=["-g"], extra_link_args=["-g"]),
|
||||||
Extension('remote_command', ['remote_command.pyx']),
|
Extension('remote_command', ['remote_command.pyx']),
|
||||||
|
|||||||
@@ -1,22 +1,13 @@
|
|||||||
import argparse
|
from main import CommandProcessor
|
||||||
from main import ParsedArguments, CommandProcessor
|
|
||||||
|
|
||||||
|
|
||||||
def parse_arguments():
|
def start():
|
||||||
parser = argparse.ArgumentParser(description="Command Processor")
|
processor = CommandProcessor()
|
||||||
parser.add_argument("-e", "--email", type=str, default="", help="Email")
|
|
||||||
parser.add_argument("-p", "--pw", type=str, default="", help="Password")
|
|
||||||
parser.add_argument("-f", "--folder", type=str, default="", help="Folder to API inner folder to download file from")
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
return ParsedArguments(args.email, args.pw, args.folder)
|
|
||||||
|
|
||||||
def start(args: ParsedArguments):
|
|
||||||
processor = CommandProcessor(args)
|
|
||||||
try:
|
try:
|
||||||
processor.start()
|
processor.start()
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
processor.stop()
|
processor.stop()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
start(parse_arguments())
|
start()
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from PyInstaller.utils.hooks import collect_all
|
|||||||
|
|
||||||
datas = []
|
datas = []
|
||||||
binaries = []
|
binaries = []
|
||||||
hiddenimports = ['user', 'security', 'secure_model', 'api_client', 'hardware_service', 'constants', 'annotation', 'remote_command', 'ai_config', 'inference', 'remote_command_handler']
|
hiddenimports = ['constants', 'annotation', 'credentials', 'file_data', 'user', 'security', 'secure_model', 'api_client', 'hardware_service', 'remote_command', 'ai_config', 'inference', 'remote_command_handler']
|
||||||
tmp_ret = collect_all('jwt')
|
tmp_ret = collect_all('jwt')
|
||||||
datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2]
|
datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2]
|
||||||
tmp_ret = collect_all('requests')
|
tmp_ret = collect_all('requests')
|
||||||
|
|||||||
@@ -32,22 +32,27 @@ Global
|
|||||||
{8E0809AF-2920-4267-B14D-84BAB334A46F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{8E0809AF-2920-4267-B14D-84BAB334A46F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{8E0809AF-2920-4267-B14D-84BAB334A46F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{8E0809AF-2920-4267-B14D-84BAB334A46F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{8E0809AF-2920-4267-B14D-84BAB334A46F}.Release|Any CPU.Build.0 = Release|Any CPU
|
{8E0809AF-2920-4267-B14D-84BAB334A46F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{8E0809AF-2920-4267-B14D-84BAB334A46F}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||||
{85359558-FB59-4542-A597-FD9E1B04C8E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{85359558-FB59-4542-A597-FD9E1B04C8E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{85359558-FB59-4542-A597-FD9E1B04C8E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{85359558-FB59-4542-A597-FD9E1B04C8E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{85359558-FB59-4542-A597-FD9E1B04C8E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{85359558-FB59-4542-A597-FD9E1B04C8E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{85359558-FB59-4542-A597-FD9E1B04C8E7}.Release|Any CPU.Build.0 = Release|Any CPU
|
{85359558-FB59-4542-A597-FD9E1B04C8E7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{85359558-FB59-4542-A597-FD9E1B04C8E7}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||||
{BA77500E-8B66-4F31-81B0-E831FC12EDFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{BA77500E-8B66-4F31-81B0-E831FC12EDFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{BA77500E-8B66-4F31-81B0-E831FC12EDFB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{BA77500E-8B66-4F31-81B0-E831FC12EDFB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{BA77500E-8B66-4F31-81B0-E831FC12EDFB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{BA77500E-8B66-4F31-81B0-E831FC12EDFB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{BA77500E-8B66-4F31-81B0-E831FC12EDFB}.Release|Any CPU.Build.0 = Release|Any CPU
|
{BA77500E-8B66-4F31-81B0-E831FC12EDFB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{BA77500E-8B66-4F31-81B0-E831FC12EDFB}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||||
{1D8E6F44-C64E-4DBE-8665-2101EC5BE36E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{1D8E6F44-C64E-4DBE-8665-2101EC5BE36E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{1D8E6F44-C64E-4DBE-8665-2101EC5BE36E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{1D8E6F44-C64E-4DBE-8665-2101EC5BE36E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{1D8E6F44-C64E-4DBE-8665-2101EC5BE36E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{1D8E6F44-C64E-4DBE-8665-2101EC5BE36E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{1D8E6F44-C64E-4DBE-8665-2101EC5BE36E}.Release|Any CPU.Build.0 = Release|Any CPU
|
{1D8E6F44-C64E-4DBE-8665-2101EC5BE36E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{1D8E6F44-C64E-4DBE-8665-2101EC5BE36E}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||||
{01A5CA37-A62E-4EF3-8678-D72CD9525677}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{01A5CA37-A62E-4EF3-8678-D72CD9525677}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{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
|
||||||
|
{01A5CA37-A62E-4EF3-8678-D72CD9525677}.Release|Any CPU.Deploy.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
|
||||||
@@ -60,6 +65,7 @@ Global
|
|||||||
{E0C7176D-2E91-4928-B3C1-55CC91C8F77D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{E0C7176D-2E91-4928-B3C1-55CC91C8F77D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{E0C7176D-2E91-4928-B3C1-55CC91C8F77D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{E0C7176D-2E91-4928-B3C1-55CC91C8F77D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{E0C7176D-2E91-4928-B3C1-55CC91C8F77D}.Release|Any CPU.Build.0 = Release|Any CPU
|
{E0C7176D-2E91-4928-B3C1-55CC91C8F77D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{E0C7176D-2E91-4928-B3C1-55CC91C8F77D}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(NestedProjects) = preSolution
|
GlobalSection(NestedProjects) = preSolution
|
||||||
{32C4747F-F700-44FD-B4ED-21B4A66B5FAB} = {C307BE2E-FFCC-4BD7-AD89-C82D40B65D03}
|
{32C4747F-F700-44FD-B4ED-21B4A66B5FAB} = {C307BE2E-FFCC-4BD7-AD89-C82D40B65D03}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public partial class App
|
|||||||
private IMediator _mediator = null!;
|
private IMediator _mediator = null!;
|
||||||
private FormState _formState = null!;
|
private FormState _formState = null!;
|
||||||
|
|
||||||
private PythonResourceLoader _resourceLoader = null!;
|
private readonly PythonResourceLoader _resourceLoader = new();
|
||||||
private Stream _securedConfig = null!;
|
private Stream _securedConfig = null!;
|
||||||
|
|
||||||
private void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
|
private void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
|
||||||
@@ -54,7 +54,7 @@ public partial class App
|
|||||||
"Azaion.Dataset"
|
"Azaion.Dataset"
|
||||||
];
|
];
|
||||||
|
|
||||||
private ApiConfig ReadConfig()
|
private static ApiConfig ReadConfig()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -70,7 +70,8 @@ public partial class App
|
|||||||
{
|
{
|
||||||
Url = SecurityConstants.DEFAULT_API_URL,
|
Url = SecurityConstants.DEFAULT_API_URL,
|
||||||
RetryCount = SecurityConstants.DEFAULT_API_RETRY_COUNT,
|
RetryCount = SecurityConstants.DEFAULT_API_RETRY_COUNT,
|
||||||
TimeoutSeconds = SecurityConstants.DEFAULT_API_TIMEOUT_SECONDS
|
TimeoutSeconds = SecurityConstants.DEFAULT_API_TIMEOUT_SECONDS,
|
||||||
|
ResourcesFolder = ""
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -81,10 +82,9 @@ public partial class App
|
|||||||
var login = new Login();
|
var login = new Login();
|
||||||
login.CredentialsEntered += (_, credentials) =>
|
login.CredentialsEntered += (_, credentials) =>
|
||||||
{
|
{
|
||||||
var apiConfig = ReadConfig();
|
var config = ReadConfig();
|
||||||
var api = AzaionApiClient.Create(credentials, apiConfig);
|
credentials.Folder = config.ResourcesFolder;
|
||||||
|
_resourceLoader.Login(credentials);
|
||||||
_resourceLoader = new PythonResourceLoader(apiConfig, credentials, api);
|
|
||||||
_securedConfig = _resourceLoader.LoadFileFromPython("secured-config.json");
|
_securedConfig = _resourceLoader.LoadFileFromPython("secured-config.json");
|
||||||
|
|
||||||
AppDomain.CurrentDomain.AssemblyResolve += (_, a) =>
|
AppDomain.CurrentDomain.AssemblyResolve += (_, a) =>
|
||||||
|
|||||||
@@ -30,9 +30,9 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Azaion.Annotator\Azaion.Annotator.csproj" />
|
|
||||||
<ProjectReference Include="..\Azaion.Common\Azaion.Common.csproj" />
|
<ProjectReference Include="..\Azaion.Common\Azaion.Common.csproj" />
|
||||||
<ProjectReference Include="..\Azaion.Dataset\Azaion.Dataset.csproj" />
|
<ProjectReference Include="..\Dummy\Azaion.Annotator\Azaion.Annotator.csproj" />
|
||||||
|
<ProjectReference Include="..\Dummy\Azaion.Dataset\Azaion.Dataset.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -54,9 +54,9 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="Build">
|
<Target Name="PostBuild" AfterTargets="Build">
|
||||||
<MakeDir Directories="$(TargetDir)secure" />
|
<MakeDir Directories="$(TargetDir)dummy" />
|
||||||
<Move SourceFiles="$(TargetDir)Azaion.Annotator.dll" DestinationFolder="$(TargetDir)secure" />
|
<Move SourceFiles="$(TargetDir)Azaion.Annotator.dll" DestinationFolder="$(TargetDir)dummy" />
|
||||||
<Move SourceFiles="$(TargetDir)Azaion.Dataset.dll" DestinationFolder="$(TargetDir)secure" />
|
<Move SourceFiles="$(TargetDir)Azaion.Dataset.dll" DestinationFolder="$(TargetDir)dummy" />
|
||||||
<Exec Command="upload.cmd $(ConfigurationName)" />
|
<Exec Command="upload.cmd $(ConfigurationName)" />
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using Azaion.Common.DTO;
|
|||||||
using Azaion.Common.DTO.Config;
|
using Azaion.Common.DTO.Config;
|
||||||
using Azaion.Common.Extensions;
|
using Azaion.Common.Extensions;
|
||||||
using Azaion.Common.Services;
|
using Azaion.Common.Services;
|
||||||
|
using Azaion.CommonSecurity.Services;
|
||||||
using Azaion.Dataset;
|
using Azaion.Dataset;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
@@ -24,20 +25,22 @@ public partial class MainSuite
|
|||||||
private readonly IGalleryService _galleryService;
|
private readonly IGalleryService _galleryService;
|
||||||
private readonly IDbFactory _dbFactory;
|
private readonly IDbFactory _dbFactory;
|
||||||
private readonly Dictionary<WindowEnum, Window> _openedWindows = new();
|
private readonly Dictionary<WindowEnum, Window> _openedWindows = new();
|
||||||
|
private readonly IResourceLoader _resourceLoader;
|
||||||
|
|
||||||
public MainSuite(IOptions<AppConfig> appConfig,
|
public MainSuite(IOptions<AppConfig> appConfig,
|
||||||
IConfigUpdater configUpdater,
|
IConfigUpdater configUpdater,
|
||||||
IEnumerable<IAzaionModule> modules,
|
IEnumerable<IAzaionModule> modules,
|
||||||
IServiceProvider sp,
|
IServiceProvider sp,
|
||||||
IGalleryService galleryService,
|
IGalleryService galleryService,
|
||||||
IDbFactory dbFactory
|
IDbFactory dbFactory,
|
||||||
)
|
IResourceLoader resourceLoader)
|
||||||
{
|
{
|
||||||
_configUpdater = configUpdater;
|
_configUpdater = configUpdater;
|
||||||
_modules = modules;
|
_modules = modules;
|
||||||
_sp = sp;
|
_sp = sp;
|
||||||
_galleryService = galleryService;
|
_galleryService = galleryService;
|
||||||
_dbFactory = dbFactory;
|
_dbFactory = dbFactory;
|
||||||
|
_resourceLoader = resourceLoader;
|
||||||
_appConfig = appConfig.Value;
|
_appConfig = appConfig.Value;
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
Loaded += OnLoaded;
|
Loaded += OnLoaded;
|
||||||
@@ -107,6 +110,7 @@ public partial class MainSuite
|
|||||||
_openedWindows[module.WindowEnum] = window;
|
_openedWindows[module.WindowEnum] = window;
|
||||||
window.Closed += (_, _) =>
|
window.Closed += (_, _) =>
|
||||||
{
|
{
|
||||||
|
_resourceLoader.StopPython();
|
||||||
_openedWindows.Remove(module.WindowEnum);
|
_openedWindows.Remove(module.WindowEnum);
|
||||||
if (!_openedWindows.Any())
|
if (!_openedWindows.Any())
|
||||||
Close();
|
Close();
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
{
|
{
|
||||||
"ApiConfig": {
|
"ApiConfig": {
|
||||||
"Url": "https://api.azaion.com/",
|
"TimeoutSeconds": 20.0,
|
||||||
"RetryCount": 3,
|
"ResourcesFolder": "stage"
|
||||||
"TimeoutSeconds": 40.0,
|
|
||||||
"ResourcesFolder": "stage",
|
|
||||||
"TokenFile": "token.txt"
|
|
||||||
},
|
},
|
||||||
"DirectoriesConfig": {
|
"DirectoriesConfig": {
|
||||||
"VideosDirectory": "E:\\Azaion6",
|
"VideosDirectory": "E:\\Azaion6",
|
||||||
|
|||||||
@@ -7,11 +7,12 @@ set RESOURCES_FOLDER=stage
|
|||||||
|
|
||||||
set EMAIL=uploader@azaion.com
|
set EMAIL=uploader@azaion.com
|
||||||
set PASSWORD=Az@1on_10Upl0@der
|
set PASSWORD=Az@1on_10Upl0@der
|
||||||
|
echo %cd%
|
||||||
|
|
||||||
set FILE1_TO_UPLOAD=%cd%\bin\%CONFIG%\net8.0-windows\secure\Azaion.Annotator.dll
|
set FILE1_TO_UPLOAD=%cd%\..\Azaion.Annotator\bin\%CONFIG%\net8.0-windows\Azaion.Annotator.dll
|
||||||
set "FILE1_TO_UPLOAD=%FILE1_TO_UPLOAD:\=/%"
|
set "FILE1_TO_UPLOAD=%FILE1_TO_UPLOAD:\=/%"
|
||||||
|
|
||||||
set FILE2_TO_UPLOAD=%cd%\bin\%CONFIG%\net8.0-windows\secure\Azaion.Dataset.dll
|
set FILE2_TO_UPLOAD=%cd%\..\Azaion.Dataset\bin\%CONFIG%\net8.0-windows\Azaion.Dataset.dll
|
||||||
set "FILE2_TO_UPLOAD=%FILE2_TO_UPLOAD:\=/%"
|
set "FILE2_TO_UPLOAD=%FILE2_TO_UPLOAD:\=/%"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ public class DictTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData(null, 0)]
|
|
||||||
[InlineData(new int[]{}, 0)]
|
[InlineData(new int[]{}, 0)]
|
||||||
[InlineData(new int[]{1, 2, 5}, 1)]
|
[InlineData(new int[]{1, 2, 5}, 1)]
|
||||||
[InlineData(new int[]{3, -2, 5}, -2)]
|
[InlineData(new int[]{3, -2, 5}, -2)]
|
||||||
|
|||||||
@@ -27,7 +27,6 @@
|
|||||||
<PackageReference Include="SkiaSharp" Version="2.88.9" />
|
<PackageReference Include="SkiaSharp" Version="2.88.9" />
|
||||||
<PackageReference Include="VideoLAN.LibVLC.Windows" Version="3.0.21" />
|
<PackageReference Include="VideoLAN.LibVLC.Windows" Version="3.0.21" />
|
||||||
<PackageReference Include="WindowsAPICodePack" Version="7.0.4" />
|
<PackageReference Include="WindowsAPICodePack" Version="7.0.4" />
|
||||||
<PackageReference Include="YoloV8.Gpu" Version="5.0.4" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
Reference in New Issue
Block a user