Compare commits
8 Commits
3d13d24116
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
|
78f9508753
|
|||
|
|
11bf344cb5 | ||
| 5ee8eca11b | |||
| f18935f793 | |||
|
d7b136851b
|
|||
|
7e9a9e6eed
|
|||
|
6ed03ab74d
|
|||
|
40c08d0169
|
14
CHANGELOG.md
14
CHANGELOG.md
@@ -2,6 +2,20 @@
|
|||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## [0.7.0-dev.1] - 2026-03-08
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
- [`d7b1368`](https://github.com/pufereq/template-repo/commit/d7b136851bafa2c20e1634bd5568f4bac839177f) **client_details.html**: add temporary initial telemetry display
|
||||||
|
- [`7e9a9e6`](https://github.com/pufereq/template-repo/commit/7e9a9e6eede6cc926fef64c626434e65984befbc) **backend_server.py**: add `initial_telemetry` support
|
||||||
|
- [`6ed03ab`](https://github.com/pufereq/template-repo/commit/6ed03ab74de8e91d13b5f1971a3f4cec890e4fef) **client.py**: add `Client.initial_telemetry` property
|
||||||
|
- [`40c08d0`](https://github.com/pufereq/template-repo/commit/40c08d01693973f29f13c133a11fc5f166891a25) **initial_handler.py**: add handler for `TELEMETRY/INTIIAL` msgs
|
||||||
|
|
||||||
|
### Build
|
||||||
|
|
||||||
|
- [`3d13d24`](https://github.com/pufereq/template-repo/commit/3d13d241168b011c0044eb64db4b0fe70878d748) **uv.lock**: update judas_protocol to 0.9.1
|
||||||
|
- [`28b57b6`](https://github.com/pufereq/template-repo/commit/28b57b6964bfcd6ce78f2a77822f7221f6e4f7e5) **uv.lock**: update judas_protocol to 0.9.0
|
||||||
|
|
||||||
## [0.6.0] - 2026-03-05
|
## [0.6.0] - 2026-03-05
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ build-backend = "uv_build"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "judas_server"
|
name = "judas_server"
|
||||||
version = "0.6.0"
|
version = "0.7.0-dev.1"
|
||||||
description = "The backbone of the remote PC fleet management system."
|
description = "The backbone of the remote PC fleet management system."
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
authors = []
|
authors = []
|
||||||
|
|||||||
@@ -8,11 +8,15 @@ import threading
|
|||||||
import time
|
import time
|
||||||
from typing import TYPE_CHECKING, Any, Final
|
from typing import TYPE_CHECKING, Any, Final
|
||||||
|
|
||||||
|
from judas_protocol.types import TelemetryAction
|
||||||
import yaml
|
import yaml
|
||||||
from judas_protocol import Category, ControlAction, Message
|
from judas_protocol import Category, ControlAction, Message
|
||||||
|
|
||||||
from judas_server.backend.client import Client, ClientStatus
|
from judas_server.backend.client import Client, ClientStatus
|
||||||
from judas_server.backend.handler.hello_handler import HelloHandler
|
from judas_server.backend.handler.hello_handler import HelloHandler
|
||||||
|
from judas_server.backend.handler.telemetry.initial_handler import (
|
||||||
|
InitialTelemetryHandler,
|
||||||
|
)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
@@ -67,11 +71,16 @@ class BackendServer:
|
|||||||
"""Initialize message handlers."""
|
"""Initialize message handlers."""
|
||||||
|
|
||||||
hello_handler = HelloHandler(self)
|
hello_handler = HelloHandler(self)
|
||||||
|
initial_telemetry_handler = InitialTelemetryHandler(self)
|
||||||
|
|
||||||
self.message_handlers[(Category.CONTROL, ControlAction.HELLO)] = (
|
self.message_handlers[(Category.CONTROL, ControlAction.HELLO)] = (
|
||||||
hello_handler.handle
|
hello_handler.handle
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.message_handlers[
|
||||||
|
(Category.TELEMETRY, TelemetryAction.INITIAL)
|
||||||
|
] = initial_telemetry_handler.handle
|
||||||
|
|
||||||
def _load_known_clients(self) -> dict[str, dict[str, str | float]]:
|
def _load_known_clients(self) -> dict[str, dict[str, str | float]]:
|
||||||
"""Load the list of known clients from a YAML file and validate."""
|
"""Load the list of known clients from a YAML file and validate."""
|
||||||
known_clients: dict[str, dict[str, str | float]] = {}
|
known_clients: dict[str, dict[str, str | float]] = {}
|
||||||
@@ -108,6 +117,9 @@ class BackendServer:
|
|||||||
client.last_seen = float(
|
client.last_seen = float(
|
||||||
known_clients[client_id].get("last_seen", 0.0)
|
known_clients[client_id].get("last_seen", 0.0)
|
||||||
)
|
)
|
||||||
|
client.initial_telemetry = known_clients[client_id].get( # type: ignore
|
||||||
|
"initial_telemetry", None
|
||||||
|
)
|
||||||
self.clients[client_id] = client
|
self.clients[client_id] = client
|
||||||
|
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
@@ -399,4 +411,5 @@ class BackendServer:
|
|||||||
"addr": client.addr,
|
"addr": client.addr,
|
||||||
"last_seen": client.last_seen,
|
"last_seen": client.last_seen,
|
||||||
"status": client.status,
|
"status": client.status,
|
||||||
|
"initial_telemetry": client.initial_telemetry,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ from __future__ import annotations
|
|||||||
import logging as lg
|
import logging as lg
|
||||||
import socket
|
import socket
|
||||||
import time
|
import time
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from judas_server.backend.client_status import ClientStatus
|
from judas_server.backend.client_status import ClientStatus
|
||||||
|
|
||||||
@@ -41,6 +42,8 @@ class Client:
|
|||||||
self.inbound: bytes = b""
|
self.inbound: bytes = b""
|
||||||
self.outbound: bytes = b""
|
self.outbound: bytes = b""
|
||||||
|
|
||||||
|
self.initial_telemetry: dict[str, Any] | None = None
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
if self.addr:
|
if self.addr:
|
||||||
return f"Client({self.id} ({self.addr[0]}:{self.addr[1]}))"
|
return f"Client({self.id} ({self.addr[0]}:{self.addr[1]}))"
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""Initial telemetry handler."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
from judas_protocol import Message
|
||||||
|
|
||||||
|
from judas_server.backend.handler.base_handler import BaseHandler
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from judas_server.backend import BackendServer
|
||||||
|
from judas_server.backend.client import Client
|
||||||
|
|
||||||
|
|
||||||
|
class InitialTelemetryHandler(BaseHandler):
|
||||||
|
"""Handles the initial telemetry message from a client."""
|
||||||
|
|
||||||
|
def __init__(self, backend_server: BackendServer) -> None:
|
||||||
|
"""Initialize the handler."""
|
||||||
|
super().__init__(backend_server)
|
||||||
|
|
||||||
|
def handle(self, client: Client, message: Message) -> None:
|
||||||
|
"""Handle the initial telemetry message."""
|
||||||
|
self.logger.debug(
|
||||||
|
f"Handling initial telemetry message from {client}..."
|
||||||
|
)
|
||||||
|
|
||||||
|
client.initial_telemetry = message.payload
|
||||||
|
self.backend_server.known_clients[client.id]["initial_telemetry"] = ( # type: ignore
|
||||||
|
message.payload
|
||||||
|
)
|
||||||
@@ -18,6 +18,10 @@
|
|||||||
<strong>Last Seen:</strong>
|
<strong>Last Seen:</strong>
|
||||||
<span id="last-seen">{{ client.last_seen }}</span>
|
<span id="last-seen">{{ client.last_seen }}</span>
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>Initial:</strong>
|
||||||
|
<pre>{{ client.initial_telemetry | tojson(indent=2) }}</pre>
|
||||||
|
</p>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
@@ -33,11 +33,12 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// load client_details for the client specified in the URL hash
|
// load client_details for the client specified in the URL
|
||||||
const hash = window.location.hash;
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
if (hash) {
|
const clientId = urlParams.get("client");
|
||||||
const clientId = hash.substring(1);
|
if (clientId) {
|
||||||
loadClientDetails(clientId);
|
loadClientDetails(clientId);
|
||||||
|
$(`#client-list a[href="?client=${clientId}"]`).addClass("active");
|
||||||
}
|
}
|
||||||
|
|
||||||
$("#notify").hide();
|
$("#notify").hide();
|
||||||
@@ -141,7 +142,7 @@
|
|||||||
li.append(iconElement);
|
li.append(iconElement);
|
||||||
const a = $("<a></a>")
|
const a = $("<a></a>")
|
||||||
.text(statusText)
|
.text(statusText)
|
||||||
.attr("href", `#${clientId}`);
|
.attr("href", `?client=${clientId}`);
|
||||||
|
|
||||||
li.attr(
|
li.attr(
|
||||||
"title",
|
"title",
|
||||||
@@ -164,19 +165,19 @@
|
|||||||
$("#client-list li > a")
|
$("#client-list li > a")
|
||||||
.off("click")
|
.off("click")
|
||||||
.on("click", function (e) {
|
.on("click", function (e) {
|
||||||
const href = $(this).attr("href");
|
let clientId = $(this).attr("href").substring(1);
|
||||||
if (href.startsWith("#")) {
|
// this is client=clientId
|
||||||
const clientId = href.substring(1);
|
|
||||||
loadClientDetails(clientId);
|
clientId = clientId.replace("client=", "");
|
||||||
$("#client-list li > a").removeClass("active");
|
|
||||||
$(this).addClass("active");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (window.location.hash) {
|
|
||||||
const clientId = window.location.hash.substring(1);
|
|
||||||
loadClientDetails(clientId);
|
loadClientDetails(clientId);
|
||||||
}
|
$("#client-list a").removeClass("active");
|
||||||
|
$(this).addClass("active");
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
let newUrl = `${window.location.pathname}?client=${clientId}`;
|
||||||
|
window.history.pushState({ path: newUrl }, "", newUrl);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
2
uv.lock
generated
2
uv.lock
generated
@@ -363,7 +363,7 @@ source = { git = "https://gitea.pufereq.pl/judas/judas_protocol.git#085c34f232f9
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "judas-server"
|
name = "judas-server"
|
||||||
version = "0.6.0"
|
version = "0.7.0.dev1"
|
||||||
source = { editable = "." }
|
source = { editable = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "flask" },
|
{ name = "flask" },
|
||||||
|
|||||||
Reference in New Issue
Block a user