From 4d58c45c3cde143e8b0f447c860086422179c60e Mon Sep 17 00:00:00 2001 From: KyMAN <0kyman0@gmail.com> Date: Tue, 24 Mar 2026 07:20:38 +0100 Subject: [PATCH] #wip(py): Dispatcher receiptor done. --- Python/Controllers/AgentsController.py | 33 ++++++- Python/Dispatchers/AgentsDispatcher.py | 56 +++++++++-- .../Application/NucelarMonitorInterface.py | 4 + .../Managers/DatabasesManagerInterface.py | 17 ++++ .../Managers/DispatchersManagerInterface.py | 16 ++++ Python/Managers/DispatchersManager.py | 10 +- Python/Models/IterationModel.py | 93 +++++++++++++++++++ 7 files changed, 215 insertions(+), 14 deletions(-) create mode 100644 Python/Interfaces/Managers/DatabasesManagerInterface.py create mode 100644 Python/Interfaces/Managers/DispatchersManagerInterface.py create mode 100644 Python/Models/IterationModel.py diff --git a/Python/Controllers/AgentsController.py b/Python/Controllers/AgentsController.py index dfbd579..4d013ec 100644 --- a/Python/Controllers/AgentsController.py +++ b/Python/Controllers/AgentsController.py @@ -5,6 +5,11 @@ from typing import Self from Abstracts.ControllerAbstract import ControllerAbstract from Models.ResponseModel import ResponseModel from Models.RequestModel import RequestModel +from Models.IterationModel import ( + CPUModel, MemoryModel, NetUseModel, InterfaceModel, DiskModel, + CandleTimeModel, IterationModel +) +from Dispatchers.AgentsDispatcher import AgentsDispatcher from Utils.Utils import Utils class AgentsController(ControllerAbstract): @@ -14,19 +19,37 @@ class AgentsController(ControllerAbstract): key:str = request.get("key") hostnames:list[str] domain:str|None - interfaces:list[list[int, str, bool, str, int]] + interfaces_data:list[list[int, str, bool, str, int]] disks:list[list[str, int, int, str|None]] iterations:int candle_times:list[int, int] - cpu:list[float, float, float, float] + cpu:list[float, float, float, float, float] memory:list[int, int, int, int, int, float] net_use:list[list[list[str, int, int, int, int, int, int]]] + received:list[NetUseModel] = [] + transmitted:list[NetUseModel] = [] + + ( + hostnames, domain, interfaces_data, disks, + iterations, candle_times, cpu, memory, net_use + ) = Utils.json_decode(request.body) print(Utils.json_decode(request.body)) - hostnames, domain, interfaces, disks, iterations, candle_times, cpu, memory, net_use = Utils.json_decode(request.body) + received = {net[0] : NetUseModel(*net[1:]) for i, net in enumerate(net_use[0])} + transmitted = {net[0] : NetUseModel(*net[1:]) for i, net in enumerate(net_use[1])} - print([hostnames, domain, interfaces, disks, iterations, candle_times, cpu, memory, net_use]) + self.nucelar_monitor.dispatchers.get(AgentsDispatcher, "sql_server").save(IterationModel( + key, hostnames, domain, + [InterfaceModel( + i, name, is_ipv6, ip, mask, received[name], transmitted[name] + ) for i, name, is_ipv6, ip, mask in interfaces_data], + [DiskModel(*disk) for disk in disks], + iterations, + CandleTimeModel(*candle_times), + CPUModel(*cpu), + MemoryModel(*memory) + )) def windows(self:Self, request:RequestModel, response:ResponseModel) -> None: @@ -48,7 +71,7 @@ class AgentsController(ControllerAbstract): print([hostnames, domain, interfaces, disks, iterations, candle_times, cpu, memory, net_use]) def test(self:Self, request:RequestModel, response:ResponseModel) -> None: - response.set_data({ + response.set({ "message": "Test successful", "key" : request.get("key") }, "application/json") \ No newline at end of file diff --git a/Python/Dispatchers/AgentsDispatcher.py b/Python/Dispatchers/AgentsDispatcher.py index 2d43587..8f3087c 100644 --- a/Python/Dispatchers/AgentsDispatcher.py +++ b/Python/Dispatchers/AgentsDispatcher.py @@ -2,12 +2,56 @@ # -*- coding: utf-8 -*- from typing import Self -from Interfaces.Application.NucelarMonitorInterface import NucelarMonitorInterface +from Models.IterationModel import InterfaceModel, IterationModel +from Abstracts.DispatcherAbstract import DispatcherAbstract +from Abstracts.DatabaseAbstract import DatabaseAbstract -class AgentsDispatcher: +class AgentsDispatcher(DispatcherAbstract): - def __init__(self:Self, nucelar_monitor:NucelarMonitorInterface) -> None: - super().__init__(nucelar_monitor) + def save(self:Self, iteration:IterationModel) -> None: - def save(self:Self) -> None: - pass \ No newline at end of file + database:DatabaseAbstract = self.nucelar_monitor.databases.get("sql_server") + interface:InterfaceModel + + database.query(( + "execute dbo.set_machine_data " + + "{key}, {candle_start}, {candle_end}, {candle_interations}, " + + "{ram_total}, {ram_in}, {ram_out}, {ram_minimum}, {ram_maximum}, " + + "{ram_average}, {cpu_in}, {cpu_out}, {cpu_minimum}, {cpu_maximum}, " + + "{cpu_average}" + ), { + "key" : iteration.key, + "candle_start" : iteration.candle_time.start, + "candle_end" : iteration.candle_time.end, + "candle_interations" : iteration.iterations, + "ram_total" : iteration.memory.total, + "ram_in" : iteration.memory._in, + "ram_out" : iteration.memory.out, + "ram_minimum" : iteration.memory.minimum, + "ram_maximum" : iteration.memory.maximum, + "ram_average" : iteration.memory.average, + "cpu_in" : iteration.cpu._in, + "cpu_out" : iteration.cpu.out, + "cpu_minimum" : iteration.cpu.minimum, + "cpu_maximum" : iteration.cpu.maximum, + "cpu_average" : iteration.cpu.average + }) + + for interface in iteration.interfaces: + database.query(( + "execute dbo.set_machine_interface_data " + + "{key}, {candle_start}, {candle_end}, {candle_interations}, " + + "{name}, {bytes}, {packages}, {errors}, {is_ipv6}, {ip}, {mask}" + ), { + "key" : iteration.key, + "candle_start" : iteration.candle_time.start, + "candle_end" : iteration.candle_time.end, + "candle_interations" : iteration.iterations, + "name" : interface.name, + "bytes" : interface.received.bytes + interface.transmitted.bytes, + "packages" : interface.received.packets + interface.transmitted.packets, + "errors" : interface.received.errors + interface.transmitted.errors, + "is_ipv6" : interface.is_ipv6, + "ip" : interface.ip, + "mask" : interface.mask + }) \ No newline at end of file diff --git a/Python/Interfaces/Application/NucelarMonitorInterface.py b/Python/Interfaces/Application/NucelarMonitorInterface.py index d6df0e8..ce45ba4 100644 --- a/Python/Interfaces/Application/NucelarMonitorInterface.py +++ b/Python/Interfaces/Application/NucelarMonitorInterface.py @@ -8,6 +8,8 @@ from Interfaces.Managers.I18NManagersInterface import I18NManagerInterface from Interfaces.Managers.SettingsManagersInterface import SettingsManagerInterface from Interfaces.Managers.TerminalManagerInterface import TerminalManagerInterface from Interfaces.Managers.ModelsManagerInterface import ModelsManagerInterface +from Interfaces.Managers.DatabasesManagerInterface import DatabasesManagerInterface +from Interfaces.Managers.DispatchersManagerInterface import DispatchersManagerInterface from Interfaces.Managers.ControllersManagerInterface import ControllersManagerInterface from Interfaces.Managers.RoutesManagerInterface import RoutesManagerInterface from Interfaces.Abstracts.WebSocketAbstractInterface import WebSocketAbstractInterface @@ -20,6 +22,8 @@ class NucelarMonitorInterface(ABC): self.settings:SettingsManagerInterface = None self.terminal:TerminalManagerInterface = None self.models:ModelsManagerInterface = None + self.databases:DatabasesManagerInterface = None + self.dispatchers:DispatchersManagerInterface = None self.controllers:ControllersManagerInterface = None self.routes:RoutesManagerInterface = None self.web_socket:WebSocketAbstractInterface = None diff --git a/Python/Interfaces/Managers/DatabasesManagerInterface.py b/Python/Interfaces/Managers/DatabasesManagerInterface.py new file mode 100644 index 0000000..cbcf32d --- /dev/null +++ b/Python/Interfaces/Managers/DatabasesManagerInterface.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from typing import Self, Any +from abc import ABC, abstractmethod +from Abstracts.DatabaseAbstract import DatabaseAbstract + +class DatabasesManagerInterface(ABC): + + @abstractmethod + def get(self:Self, key:str) -> type[DatabaseAbstract]|None:pass + + @abstractmethod + def add(self:Self, inputs:Any|None, overwrite:bool = False) -> None:pass + + @abstractmethod + def close(self:Self) -> None:pass \ No newline at end of file diff --git a/Python/Interfaces/Managers/DispatchersManagerInterface.py b/Python/Interfaces/Managers/DispatchersManagerInterface.py new file mode 100644 index 0000000..60d2558 --- /dev/null +++ b/Python/Interfaces/Managers/DispatchersManagerInterface.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from typing import Any, Self, TypeVar +from abc import ABC, abstractmethod +from Abstracts.DispatcherAbstract import DispatcherAbstract + +T = TypeVar("T", bound = DispatcherAbstract) + +class DispatchersManagerInterface(ABC): + + @abstractmethod + def get(self:Self, Type:type[T], key:str) -> T|None:pass + + @abstractmethod + def add(self:Self, inputs:Any|None, overwrite:bool = False) -> None:pass \ No newline at end of file diff --git a/Python/Managers/DispatchersManager.py b/Python/Managers/DispatchersManager.py index 23ef42b..50c5aee 100644 --- a/Python/Managers/DispatchersManager.py +++ b/Python/Managers/DispatchersManager.py @@ -1,10 +1,12 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -from typing import Any, Self +from typing import Any, Self, TypeVar from Interfaces.Application.NucelarMonitorInterface import NucelarMonitorInterface from Abstracts.DispatcherAbstract import DispatcherAbstract +T = TypeVar("T", bound = DispatcherAbstract) + class DispatchersManager: def __init__(self:Self, nucelar_monitor:NucelarMonitorInterface) -> None: @@ -20,8 +22,10 @@ class DispatchersManager: ): self.add(self.nucelar_monitor.settings.get(key, None, []), True) - def get(self:Self, key:str) -> DispatcherAbstract|None: - return self.__dispatcher.get(key, None) + def get(self:Self, Type:type[T], key:str) -> T|None: + if key in self.__dispatcher and isinstance(self.__dispatcher[key], Type): + return self.__dispatcher[key] + return None def add(self:Self, inputs:Any|None, overwrite:bool = False) -> None: diff --git a/Python/Models/IterationModel.py b/Python/Models/IterationModel.py new file mode 100644 index 0000000..2628128 --- /dev/null +++ b/Python/Models/IterationModel.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from typing import Self + +class CPUModel: + def __init__(self:Self, + _in:float, + _out:float, + maximum:float, + minimum:float, + average:float + ) -> None: + self._in:float = _in + self.out:float = _out + self.maximum:float = maximum + self.minimum:float = minimum + self.average:float = average + +class MemoryModel: + def __init__(self:Self, + total:int, + _in:int, + _out:int, + maximum:int, + minimum:int, + average:float + ) -> None: + self.total:int = total + self._in:int = _in + self.out:int = _out + self.maximum:int = maximum + self.minimum:int = minimum + self.average:float = average + +class NetUseModel: + def __init__(self:Self, _bytes:int, packets:int, errors:int) -> None: + self.bytes:int = _bytes + self.packets:int = packets + self.errors:int = errors + +class InterfaceModel: + def __init__(self:Self, + position:int, + name:str, + is_ipv6:bool, + ip:str, + mask:int, + received:NetUseModel, + transmitted:NetUseModel + ) -> None: + self.position:int = position + self.name:str = name + self.is_ipv6:bool = is_ipv6 + self.ip:str = ip + self.mask:int = mask + self.name:str = name + self.received:NetUseModel = received + self.transmitted:NetUseModel = transmitted + +class DiskModel: + def __init__(self:Self, name:str, total:int, free:int, mount:str|None) -> None: + self.name:str = name + self.total:int = total + self.free:int = free + self.mount:str|None = mount + +class CandleTimeModel: + def __init__(self:Self, start:int, end:int) -> None: + self.start:int = start + self.end:int = end + +class IterationModel: + def __init__(self:Self, + key:str, + hostnames:list[str], + domain:str|None, + interfaces:list[InterfaceModel], + disks:list[DiskModel], + iterations:int, + candle_time:CandleTimeModel, + cpu:CPUModel, + memory:MemoryModel + ) -> None: + self.key:str = key + self.hostnames:list[str] = hostnames + self.domain:str|None = domain + self.interfaces:list[InterfaceModel] = interfaces + self.disks:list[DiskModel] = disks + self.iterations:int = iterations + self.candle_time:CandleTimeModel = candle_time + self.cpu:CPUModel = cpu + self.memory:MemoryModel = memory \ No newline at end of file