mirror of
https://github.com/azaion/annotations.git
synced 2026-04-22 09:46:30 +00:00
added better logging to python
add day / winter / night switcher
This commit is contained in:
@@ -120,8 +120,8 @@ public partial class Annotator
|
||||
TbFolder.Text = _appConfig.DirectoriesConfig.VideosDirectory;
|
||||
|
||||
AnnotationClasses = new ObservableCollection<DetectionClass>(_appConfig.AnnotationConfig.AnnotationClasses);
|
||||
LvClasses.ItemsSource = AnnotationClasses;
|
||||
LvClasses.SelectedIndex = 0;
|
||||
LvClasses.DetectionDataGrid.ItemsSource = AnnotationClasses;
|
||||
LvClasses.SelectNum(0);
|
||||
|
||||
if (LvFiles.Items.IsEmpty)
|
||||
BlinkHelp(HelpTexts.HelpTextsDict[HelpTextEnum.Initial]);
|
||||
@@ -176,9 +176,9 @@ public partial class Annotator
|
||||
await _mediator.Publish(new AnnotatorControlEvent(PlaybackControlEnum.Play));
|
||||
};
|
||||
|
||||
LvClasses.SelectionChanged += (_, _) =>
|
||||
LvClasses.DetectionClassChanged += (_, args) =>
|
||||
{
|
||||
var selectedClass = (DetectionClass)LvClasses.SelectedItem;
|
||||
var selectedClass = args.DetectionClass;
|
||||
Editor.CurrentAnnClass = selectedClass;
|
||||
_mediator.Publish(new AnnClassSelectedEvent(selectedClass));
|
||||
};
|
||||
|
||||
@@ -53,12 +53,12 @@ public class AnnotatorEventHandler(
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void SelectClass(DetectionClass annClass)
|
||||
private void SelectClass(DetectionClass detClass)
|
||||
{
|
||||
mainWindow.Editor.CurrentAnnClass = annClass;
|
||||
mainWindow.Editor.CurrentAnnClass = detClass;
|
||||
foreach (var ann in mainWindow.Editor.CurrentDetections.Where(x => x.IsSelected))
|
||||
ann.DetectionClass = annClass;
|
||||
mainWindow.LvClasses.SelectedIndex = annClass.Id;
|
||||
ann.DetectionClass = detClass;
|
||||
mainWindow.LvClasses.SelectNum(detClass.Id);
|
||||
}
|
||||
|
||||
public async Task Handle(KeyEvent keyEvent, CancellationToken cancellationToken = default)
|
||||
@@ -74,7 +74,7 @@ public class AnnotatorEventHandler(
|
||||
if ((int)key >= (int)Key.NumPad1 && (int)key <= (int)Key.NumPad9)
|
||||
keyNumber = key - Key.NumPad1;
|
||||
if (keyNumber.HasValue)
|
||||
SelectClass((DetectionClass)mainWindow.LvClasses.Items[keyNumber.Value]!);
|
||||
SelectClass((DetectionClass)mainWindow.LvClasses.DetectionDataGrid.Items[keyNumber.Value]!);
|
||||
|
||||
if (_keysControlEnumDict.TryGetValue(key, out var value))
|
||||
await ControlPlayback(value, cancellationToken);
|
||||
|
||||
@@ -1,49 +1,106 @@
|
||||
<DataGrid x:Class="Azaion.Common.Controls.DetectionClasses"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300" d:DesignWidth="300"
|
||||
Background="Black"
|
||||
RowBackground="#252525"
|
||||
Foreground="White"
|
||||
RowHeaderWidth="0"
|
||||
Padding="2 0 0 0"
|
||||
AutoGenerateColumns="False"
|
||||
SelectionMode="Single"
|
||||
CellStyle="{DynamicResource DataGridCellStyle1}"
|
||||
IsReadOnly="True"
|
||||
CanUserResizeRows="False"
|
||||
CanUserResizeColumns="False">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTemplateColumn
|
||||
Width="50"
|
||||
Header="Клавіша"
|
||||
CanUserSort="False">
|
||||
<DataGridTemplateColumn.HeaderStyle>
|
||||
<Style TargetType="DataGridColumnHeader">
|
||||
<Setter Property="Background" Value="#252525"></Setter>
|
||||
</Style>
|
||||
</DataGridTemplateColumn.HeaderStyle>
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<Border Background="{Binding Path=ColorBrush}">
|
||||
<TextBlock Text="{Binding Path=ClassNumber}"></TextBlock>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
<UserControl x:Class="Azaion.Common.Controls.DetectionClasses"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300" d:DesignWidth="300">
|
||||
<UserControl.Resources>
|
||||
<Style x:Key="ButtonRadioButtonStyle" TargetType="RadioButton">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="RadioButton">
|
||||
<Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}"
|
||||
Background="{TemplateBinding Background}" BorderThickness="1"
|
||||
Padding="10,5" CornerRadius="2">
|
||||
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsChecked" Value="True">
|
||||
<Setter TargetName="Border" Property="Background" Value="Gray"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="Border" Property="Background" Value="DarkGray"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="BorderBrush" Value="White"/>
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
<Grid Background="Black">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<!-- Your DataGrid with detection classes -->
|
||||
<DataGrid x:Name="DetectionDataGrid"
|
||||
Grid.Row="0"
|
||||
Background="Black"
|
||||
RowBackground="#252525"
|
||||
Foreground="White"
|
||||
RowHeaderWidth="0"
|
||||
Padding="2 0 0 0"
|
||||
AutoGenerateColumns="False"
|
||||
SelectionMode="Single"
|
||||
CellStyle="{DynamicResource DataGridCellStyle1}"
|
||||
IsReadOnly="True"
|
||||
CanUserResizeRows="False"
|
||||
CanUserResizeColumns="False"
|
||||
SelectionChanged="DetectionDataGrid_SelectionChanged"
|
||||
x:FieldModifier="public">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTemplateColumn Width="50" Header="Клавіша" CanUserSort="False">
|
||||
<DataGridTemplateColumn.HeaderStyle>
|
||||
<Style TargetType="DataGridColumnHeader">
|
||||
<Setter Property="Background" Value="#252525"/>
|
||||
</Style>
|
||||
</DataGridTemplateColumn.HeaderStyle>
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<Border Background="{Binding Path=ColorBrush}">
|
||||
<TextBlock Text="{Binding Path=ClassNumber}"/>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
<DataGridTextColumn
|
||||
Width="*"
|
||||
Header="Назва"
|
||||
Binding="{Binding Path=Name}"
|
||||
CanUserSort="False">
|
||||
<DataGridTextColumn.HeaderStyle>
|
||||
<Style TargetType="DataGridColumnHeader">
|
||||
<Setter Property="Background" Value="#252525"></Setter>
|
||||
</Style>
|
||||
</DataGridTextColumn.HeaderStyle>
|
||||
<DataGridTextColumn Width="*" Header="Назва" Binding="{Binding Path=Name}" CanUserSort="False">
|
||||
<DataGridTextColumn.HeaderStyle>
|
||||
<Style TargetType="DataGridColumnHeader">
|
||||
<Setter Property="Background" Value="#252525"/>
|
||||
</Style>
|
||||
</DataGridTextColumn.HeaderStyle>
|
||||
</DataGridTextColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
<!-- StackPanel with mode switcher RadioButtons -->
|
||||
<StackPanel x:Name="ModeSwitcherPanel"
|
||||
Grid.Row="1"
|
||||
Orientation="Horizontal"
|
||||
HorizontalAlignment="Center"
|
||||
Margin="0,5,0,5">
|
||||
<RadioButton x:Name="NormalModeRadioButton"
|
||||
Tag="0"
|
||||
Content="Звичайний"
|
||||
GroupName="Mode"
|
||||
Checked="ModeRadioButton_Checked"
|
||||
IsChecked="True"
|
||||
Style="{StaticResource ButtonRadioButtonStyle}"/>
|
||||
<RadioButton x:Name="EveningModeRadioButton"
|
||||
Tag="1"
|
||||
Content="Зима"
|
||||
GroupName="Mode"
|
||||
Checked="ModeRadioButton_Checked" Margin="10,0,0,0"
|
||||
Style="{StaticResource ButtonRadioButtonStyle}"/>
|
||||
<RadioButton x:Name="NightModeRadioButton"
|
||||
Tag="2"
|
||||
Content="Ніч"
|
||||
GroupName="Mode"
|
||||
Checked="ModeRadioButton_Checked" Margin="10,0,0,0"
|
||||
Style="{StaticResource ButtonRadioButtonStyle}"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
@@ -1,9 +1,54 @@
|
||||
namespace Azaion.Common.Controls;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Azaion.Common.DTO;
|
||||
|
||||
namespace Azaion.Common.Controls;
|
||||
|
||||
public class DetectionClassChangedEventArgs(DetectionClass? detectionClass, int classNumber) : EventArgs
|
||||
{
|
||||
public DetectionClass? DetectionClass { get; } = detectionClass;
|
||||
public int ClassNumber { get; } = classNumber;
|
||||
}
|
||||
|
||||
public partial class DetectionClasses
|
||||
{
|
||||
public DetectionClasses()
|
||||
public event EventHandler<DetectionClassChangedEventArgs>? DetectionClassChanged;
|
||||
public DetectionClasses() => InitializeComponent();
|
||||
|
||||
public int CurrentClassNumber { get; private set; } = 0;
|
||||
public DetectionClass? CurrentDetectionClass { get; set; }
|
||||
|
||||
private void DetectionDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e) =>
|
||||
RaiseDetectionClassChanged();
|
||||
|
||||
private void ModeRadioButton_Checked(object sender, RoutedEventArgs e) =>
|
||||
RaiseDetectionClassChanged();
|
||||
|
||||
private void RaiseDetectionClassChanged()
|
||||
{
|
||||
InitializeComponent();
|
||||
var detClass = (DetectionClass)DetectionDataGrid.SelectedItem;
|
||||
var baseClassNumber = detClass?.Id ?? 0;
|
||||
|
||||
var modeAmplifier = 0;
|
||||
foreach (var child in ModeSwitcherPanel.Children)
|
||||
if (child is RadioButton { IsChecked: true } rb)
|
||||
if (int.TryParse(rb.Tag?.ToString(), out int modeIndex))
|
||||
{
|
||||
if (detClass != null)
|
||||
detClass.PhotoMode = (PhotoMode)modeIndex;
|
||||
modeAmplifier += modeIndex * 20;
|
||||
}
|
||||
|
||||
CurrentDetectionClass = detClass;
|
||||
CurrentClassNumber = baseClassNumber + modeAmplifier;
|
||||
|
||||
DetectionClassChanged?.Invoke(this, new DetectionClassChangedEventArgs(detClass, CurrentClassNumber));
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void SelectNum(int keyNumber)
|
||||
{
|
||||
DetectionDataGrid.SelectedIndex = keyNumber;
|
||||
}
|
||||
}
|
||||
@@ -11,8 +11,6 @@ public class AnnotationConfig
|
||||
[JsonIgnore]
|
||||
public Dictionary<int, DetectionClass> DetectionClassesDict => _detectionClassesDict ??= AnnotationClasses.ToDictionary(x => x.Id);
|
||||
|
||||
public int? LastSelectedExplorerClass { get; set; }
|
||||
|
||||
public List<string> VideoFormats { get; set; } = null!;
|
||||
public List<string> ImageFormats { get; set; } = null!;
|
||||
|
||||
|
||||
@@ -11,12 +11,21 @@ public class DetectionClass
|
||||
public string Name { get; set; } = null!;
|
||||
public string ShortName { get; set; } = null!;
|
||||
|
||||
public PhotoMode PhotoMode { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public Color Color => Id.ToColor();
|
||||
|
||||
[JsonIgnore]
|
||||
[JsonIgnore] //For UI
|
||||
public int ClassNumber => Id + 1;
|
||||
|
||||
[JsonIgnore]
|
||||
public SolidColorBrush ColorBrush => new(Color);
|
||||
}
|
||||
|
||||
public enum PhotoMode
|
||||
{
|
||||
Regular = 0,
|
||||
Winter = 20,
|
||||
Night = 40
|
||||
}
|
||||
@@ -93,38 +93,20 @@ public partial class DatasetExplorer
|
||||
AllDetectionClasses = new ObservableCollection<DetectionClass>(
|
||||
new List<DetectionClass> { new() {Id = -1, Name = "All", ShortName = "All"}}
|
||||
.Concat(_annotationConfig.AnnotationClasses));
|
||||
LvClasses.ItemsSource = AllDetectionClasses;
|
||||
LvClasses.DetectionDataGrid.ItemsSource = AllDetectionClasses;
|
||||
|
||||
LvClasses.MouseUp += async (_, _) =>
|
||||
LvClasses.DetectionClassChanged += async (_, args) =>
|
||||
{
|
||||
var selectedClass = (DetectionClass)LvClasses.SelectedItem;
|
||||
ExplorerEditor.CurrentAnnClass = selectedClass;
|
||||
_annotationConfig.LastSelectedExplorerClass = selectedClass.Id;
|
||||
ExplorerEditor.CurrentAnnClass = args.DetectionClass;
|
||||
|
||||
if (Switcher.SelectedIndex == 0)
|
||||
await ReloadThumbnails();
|
||||
else
|
||||
foreach (var ann in ExplorerEditor.CurrentDetections.Where(x => x.IsSelected))
|
||||
ann.DetectionClass = selectedClass;
|
||||
ann.DetectionClass = args.DetectionClass;
|
||||
};
|
||||
|
||||
LvClasses.SelectionChanged += (_, _) =>
|
||||
{
|
||||
if (Switcher.SelectedIndex != 1)
|
||||
return;
|
||||
|
||||
var selectedClass = (DetectionClass)LvClasses.SelectedItem;
|
||||
if (selectedClass == null)
|
||||
return;
|
||||
|
||||
ExplorerEditor.CurrentAnnClass = selectedClass;
|
||||
|
||||
foreach (var ann in ExplorerEditor.CurrentDetections.Where(x => x.IsSelected))
|
||||
ann.DetectionClass = selectedClass;
|
||||
};
|
||||
|
||||
LvClasses.SelectedIndex = _annotationConfig.LastSelectedExplorerClass ?? 0;
|
||||
ExplorerEditor.CurrentAnnClass = (DetectionClass)LvClasses.SelectedItem;
|
||||
ExplorerEditor.CurrentAnnClass = (DetectionClass)LvClasses.CurrentDetectionClass;
|
||||
|
||||
await _dbFactory.Run(async db =>
|
||||
{
|
||||
@@ -256,18 +238,18 @@ public partial class DatasetExplorer
|
||||
{
|
||||
AnnotationsTab.Visibility = Visibility.Collapsed;
|
||||
EditorTab.Visibility = Visibility.Visible;
|
||||
_tempSelectedClassIdx = LvClasses.SelectedIndex;
|
||||
LvClasses.ItemsSource = _annotationConfig.AnnotationClasses;
|
||||
_tempSelectedClassIdx = LvClasses.CurrentClassNumber;
|
||||
LvClasses.DetectionDataGrid.ItemsSource = _annotationConfig.AnnotationClasses;
|
||||
|
||||
Switcher.SelectedIndex = 1;
|
||||
LvClasses.SelectedIndex = Math.Max(0, _tempSelectedClassIdx - 1);
|
||||
LvClasses.SelectNum(Math.Max(0, _tempSelectedClassIdx - 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
AnnotationsTab.Visibility = Visibility.Visible;
|
||||
EditorTab.Visibility = Visibility.Collapsed;
|
||||
LvClasses.ItemsSource = AllDetectionClasses;
|
||||
LvClasses.SelectedIndex = _tempSelectedClassIdx;
|
||||
LvClasses.DetectionDataGrid.ItemsSource = AllDetectionClasses;
|
||||
LvClasses.SelectNum(_tempSelectedClassIdx);
|
||||
Switcher.SelectedIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ public class DatasetExplorerEventHandler(
|
||||
if ((int)key >= (int)Key.NumPad1 && (int)key <= (int)Key.NumPad9) keyNumber = key - Key.NumPad1;
|
||||
|
||||
if (keyNumber.HasValue)
|
||||
datasetExplorer.LvClasses.SelectedIndex = keyNumber.Value;
|
||||
datasetExplorer.LvClasses.SelectNum(keyNumber.Value);
|
||||
else
|
||||
{
|
||||
if (datasetExplorer.Switcher.SelectedIndex == 1 && _keysControlEnumDict.TryGetValue(key, out var value))
|
||||
@@ -88,13 +88,11 @@ public class DatasetExplorerEventHandler(
|
||||
public async Task Handle(AnnotationCreatedEvent notification, CancellationToken cancellationToken)
|
||||
{
|
||||
var annotation = notification.Annotation;
|
||||
var selectedClass = ((DetectionClass?)datasetExplorer.LvClasses.SelectedItem)?.Id;
|
||||
if (selectedClass == null)
|
||||
return;
|
||||
var selectedClass = datasetExplorer.LvClasses.CurrentClassNumber;
|
||||
|
||||
//TODO: For editing existing need to handle updates
|
||||
datasetExplorer.AddAnnotationToDict(annotation);
|
||||
if (annotation.Classes.Contains(selectedClass.Value))
|
||||
if (annotation.Classes.Contains(selectedClass))
|
||||
{
|
||||
var annThumb = new AnnotationThumbnail(annotation);
|
||||
datasetExplorer.SelectedAnnotations.Add(annThumb);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import json
|
||||
import os
|
||||
import time
|
||||
from http import HTTPStatus
|
||||
from uuid import UUID
|
||||
import jwt
|
||||
@@ -97,7 +98,7 @@ cdef class ApiClient:
|
||||
|
||||
stream = BytesIO(response.raw.read())
|
||||
data = Security.decrypt_to(stream, key)
|
||||
print(f'loaded file: {filename}, {len(data)} bytes')
|
||||
constants.log(<str>f'Downloaded file: {filename}, {len(data)} bytes')
|
||||
return data
|
||||
|
||||
cdef load_ai_model(self):
|
||||
|
||||
@@ -10,3 +10,6 @@ cdef str AI_MODEL_FILE # AI Model file
|
||||
|
||||
cdef bytes DONE_SIGNAL
|
||||
cdef int MODEL_BATCH_SIZE
|
||||
|
||||
|
||||
cdef log(str log_message, bytes client_id=*)
|
||||
@@ -1,3 +1,5 @@
|
||||
import time
|
||||
|
||||
cdef str CONFIG_FILE = "config.yaml" # Port for the zmq
|
||||
|
||||
cdef int QUEUE_MAXSIZE = 1000 # Maximum size of the command queue
|
||||
@@ -10,3 +12,8 @@ cdef str AI_MODEL_FILE = "azaion.onnx"
|
||||
|
||||
cdef bytes DONE_SIGNAL = b"DONE"
|
||||
cdef int MODEL_BATCH_SIZE = 4
|
||||
|
||||
cdef log(str log_message, bytes client_id=None):
|
||||
local_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
|
||||
client_str = '' if client_id is None else f' {client_id}'
|
||||
print(f'[{local_time}{client_str}]: {log_message}')
|
||||
@@ -29,7 +29,6 @@ cdef class CommandProcessor:
|
||||
self.inference = Inference(self.api_client, self.on_annotation)
|
||||
|
||||
def start(self):
|
||||
print('Started!')
|
||||
while self.running:
|
||||
try:
|
||||
command = self.inference_queue.get(timeout=0.5)
|
||||
|
||||
@@ -13,8 +13,8 @@ cdef class RemoteCommand:
|
||||
40: "STOP_INFERENCE",
|
||||
100: "EXIT"
|
||||
}
|
||||
data_str = f'. Data: {len(self.data)} bytes' if self.data else ''
|
||||
return f'{command_type_names[self.command_type]}: {data_str}'
|
||||
data_str = f'{len(self.data)} bytes' if self.data else ''
|
||||
return f'{command_type_names[self.command_type]} ({data_str})'
|
||||
|
||||
@staticmethod
|
||||
cdef from_msgpack(bytes data):
|
||||
|
||||
@@ -14,7 +14,8 @@ cdef class RemoteCommandHandler:
|
||||
self._router.setsockopt(zmq.LINGER, 0)
|
||||
with open(<str>constants.CONFIG_FILE, "r") as f:
|
||||
config = yaml.safe_load(f)
|
||||
self._router.bind(f'tcp://*:{config["zmq_port"]}')
|
||||
port = config["zmq_port"]
|
||||
self._router.bind(f'tcp://*:{port}')
|
||||
|
||||
self._dealer = self._context.socket(zmq.DEALER)
|
||||
self._dealer.setsockopt(zmq.LINGER, 0)
|
||||
@@ -30,6 +31,7 @@ cdef class RemoteCommandHandler:
|
||||
for _ in range(4): # 4 worker threads
|
||||
worker = Thread(target=self._worker_loop, daemon=True)
|
||||
self._workers.append(worker)
|
||||
print(f'Listening to commands on port {port}...')
|
||||
|
||||
cdef start(self):
|
||||
self._proxy_thread.start()
|
||||
@@ -60,7 +62,7 @@ cdef class RemoteCommandHandler:
|
||||
client_id, message = worker_socket.recv_multipart()
|
||||
cmd = RemoteCommand.from_msgpack(<bytes> message)
|
||||
cmd.client_id = client_id
|
||||
print(f'Received [{cmd}] from the client {client_id}')
|
||||
constants.log(<str>f'{cmd}', client_id)
|
||||
self._on_command(cmd)
|
||||
except Exception as e:
|
||||
if not self._shutdown_event.is_set():
|
||||
@@ -74,7 +76,7 @@ cdef class RemoteCommandHandler:
|
||||
with self._context.socket(zmq.DEALER) as socket:
|
||||
socket.connect("inproc://backend")
|
||||
socket.send_multipart([client_id, data])
|
||||
print(f'{len(data)} bytes was sent to client {client_id}')
|
||||
constants.log(<str>f'Sent {len(data)} bytes.', client_id)
|
||||
|
||||
cdef stop(self):
|
||||
self._shutdown_event.set()
|
||||
|
||||
Reference in New Issue
Block a user