From b9d0fd92a65bd88c5069fd5e5961b1b968ab7039 Mon Sep 17 00:00:00 2001 From: Artur Borecki Date: Mon, 22 Sep 2025 21:02:03 +0200 Subject: [PATCH 01/15] build(uv.lock): update judas_protocol to 0.2.0 --- uv.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/uv.lock b/uv.lock index 737c51a..ca96414 100644 --- a/uv.lock +++ b/uv.lock @@ -292,8 +292,8 @@ test = [ [[package]] name = "judas-protocol" -version = "0.1.0" -source = { git = "https://gitea.pufereq.pl/judas/judas_protocol.git#fd070b176347a0f7b81f937b189d8f50736f3514" } +version = "0.2.0" +source = { git = "https://gitea.pufereq.pl/judas/judas_protocol.git#bc1bf46388eb904738893a2f86b5050b4ce2489e" } [[package]] name = "markdown-it-py" From 21bc86fa8aab7e2fae1b966ee8b831187e7e24e2 Mon Sep 17 00:00:00 2001 From: Artur Borecki Date: Mon, 22 Sep 2025 21:09:45 +0200 Subject: [PATCH 02/15] feat(client.py): add `Client` class --- src/judas_client/client.py | 67 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/judas_client/client.py diff --git a/src/judas_client/client.py b/src/judas_client/client.py new file mode 100644 index 0000000..6937d08 --- /dev/null +++ b/src/judas_client/client.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +"""Client module for handling messages.""" + +from __future__ import annotations + +import logging as lg +import uuid + +from judas_protocol import Message + +from judas_client import Connector + + +class Client: + """Client class for handling messages.""" + + def __init__(self, server_host: str, server_port: int) -> None: + """Initialize the Client. + + Args: + server_host (str): The server host address. + server_port (int): The server port number. + """ + self.logger: lg.Logger = lg.getLogger( + f"{__name__}.{self.__class__.__name__}" + ) + self.logger.debug("Initializing Client...") + + self.server_host: str = server_host + self.server_port: int = server_port + + self.mac_address: str = self._get_mac_address() + self.logger.debug(f"MAC address: {self.mac_address}") + + self.connector: Connector = Connector( + mac_address=self.mac_address, + host=self.server_host, + port=self.server_port, + on_message=self.handle_message, + ) + + def _get_mac_address(self) -> str: + """Get the MAC address of the client. + + Returns: + str: The MAC address in standard lowercase format (e.g., "0a:1b:2c:3d:4e:5f"). + """ + mac_address: str = ":".join( + [ + "{:02x}".format((uuid.getnode() >> ele) & 0xFF) + for ele in range(0, 8 * 6, 8) + ][::-1] + ) + return mac_address + + def handle_message(self, message: Message) -> None: + """Handle incoming messages. + + Args: + message (Message): The incoming message to handle. + """ + self.logger.info(f"[v] Received message: {message}") + + def run(self) -> None: + """Run the client.""" + self.logger.info(f"Starting Client ({self.mac_address})...") + self.connector.run() From cc1145a4acb9b96e75e327d0060706f5f7f871ac Mon Sep 17 00:00:00 2001 From: Artur Borecki Date: Mon, 22 Sep 2025 21:10:47 +0200 Subject: [PATCH 03/15] feat(connector.py): get mac address from init argument --- src/judas_client/connector.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/judas_client/connector.py b/src/judas_client/connector.py index 0187c06..b1b2743 100644 --- a/src/judas_client/connector.py +++ b/src/judas_client/connector.py @@ -12,6 +12,7 @@ from judas_protocol import Message class Connector: def __init__( self, + mac_address: str, host: str, port: int, connect_timeout: float = 5.0, @@ -32,7 +33,7 @@ class Connector: socket.AF_INET, socket.SOCK_STREAM ) - self.mac_address: str = self._get_mac_address() + self.mac_address: str = mac_address def _get_mac_address(self) -> str: mac_address: str = ":".join( From 1182e089bcd74c1811faac2d6514832ba037ab42 Mon Sep 17 00:00:00 2001 From: Artur Borecki Date: Mon, 22 Sep 2025 21:11:32 +0200 Subject: [PATCH 04/15] refactor(connector.py): make `connect_timeout` and `ack_timeout` keyword-only --- src/judas_client/connector.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/judas_client/connector.py b/src/judas_client/connector.py index b1b2743..73156f7 100644 --- a/src/judas_client/connector.py +++ b/src/judas_client/connector.py @@ -15,6 +15,7 @@ class Connector: mac_address: str, host: str, port: int, + *, connect_timeout: float = 5.0, ack_timeout: float | None = None, ) -> None: From 014c4296e0cd91f0920d83e2f0993ba87166a118 Mon Sep 17 00:00:00 2001 From: Artur Borecki Date: Mon, 22 Sep 2025 21:12:19 +0200 Subject: [PATCH 05/15] refactor(connector.py): remove unused `Connector._get_mac_address()` method --- src/judas_client/connector.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/judas_client/connector.py b/src/judas_client/connector.py index 73156f7..4d5e774 100644 --- a/src/judas_client/connector.py +++ b/src/judas_client/connector.py @@ -4,7 +4,6 @@ from __future__ import annotations import logging as lg import socket import time -import uuid from judas_protocol import Message @@ -36,16 +35,6 @@ class Connector: self.mac_address: str = mac_address - def _get_mac_address(self) -> str: - mac_address: str = ":".join( - [ - "{:02x}".format((uuid.getnode() >> ele) & 0xFF) - for ele in range(0, 8 * 6, 8) - ][::-1] - ) - self.logger.debug(f"MAC address: {mac_address}") - return mac_address - def _send_ack(self) -> None: self.logger.debug("[>] Sending ACK...") try: From 3c86a5fefd04ae03cc1503aa552cb3b5e846017b Mon Sep 17 00:00:00 2001 From: Artur Borecki Date: Mon, 22 Sep 2025 21:13:32 +0200 Subject: [PATCH 06/15] feat(connector.py): add `on_message` handler function argument to init --- src/judas_client/connector.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/judas_client/connector.py b/src/judas_client/connector.py index 4d5e774..13facef 100644 --- a/src/judas_client/connector.py +++ b/src/judas_client/connector.py @@ -4,6 +4,7 @@ from __future__ import annotations import logging as lg import socket import time +from typing import Callable from judas_protocol import Message @@ -17,6 +18,7 @@ class Connector: *, connect_timeout: float = 5.0, ack_timeout: float | None = None, + on_message: Callable[[Message], None], ) -> None: self.logger: lg.Logger = lg.getLogger( f"{__name__}.{self.__class__.__name__}" @@ -35,6 +37,8 @@ class Connector: self.mac_address: str = mac_address + self.on_message: Callable[[Message], None] = on_message + def _send_ack(self) -> None: self.logger.debug("[>] Sending ACK...") try: From cf78a4b05b356fda9d31d31002af69143f5121d4 Mon Sep 17 00:00:00 2001 From: Artur Borecki Date: Mon, 22 Sep 2025 21:15:02 +0200 Subject: [PATCH 07/15] chore(connector.py): clarify debug message for connector loop --- src/judas_client/connector.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/judas_client/connector.py b/src/judas_client/connector.py index 13facef..5da23ac 100644 --- a/src/judas_client/connector.py +++ b/src/judas_client/connector.py @@ -160,7 +160,7 @@ class Connector: time.sleep(1) def _loop(self) -> None: - self.logger.debug("Starting main loop...") + self.logger.debug("Starting connector loop...") while True: time.sleep(1) data: bytes = self.receive() From b7562703ddc82456859cb72da59e74b4bddf2dc9 Mon Sep 17 00:00:00 2001 From: Artur Borecki Date: Mon, 22 Sep 2025 21:17:41 +0200 Subject: [PATCH 08/15] fix(connector.py): handle multiple messages in one packet --- src/judas_client/connector.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/judas_client/connector.py b/src/judas_client/connector.py index 5da23ac..67ae1bc 100644 --- a/src/judas_client/connector.py +++ b/src/judas_client/connector.py @@ -167,8 +167,20 @@ class Connector: if not data: self.reconnect() continue - message = Message.from_bytes(data.strip()) - self.logger.info(f"[<] Message received: {message}") + for line in data.split(b"\n"): + line: bytes = line.strip() + + if not line: + continue + + self.logger.debug(f"[.] Raw message data: {line}") + try: + message: Message = Message.from_bytes(line) + except ValueError as e: + self.logger.error(f"[!] Failed to parse message: {e}") + continue + self.logger.info(f"[*] Message received: {message}") + # if self._check_ack(): # self.logger.debug("[.] ACK verified") # else: From 5261ad8e9fe6a07033395e6936713b48c29ae30c Mon Sep 17 00:00:00 2001 From: Artur Borecki Date: Mon, 22 Sep 2025 21:18:28 +0200 Subject: [PATCH 09/15] feat(connector.py): call `on_message()` on receive --- src/judas_client/connector.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/judas_client/connector.py b/src/judas_client/connector.py index 67ae1bc..8fbc173 100644 --- a/src/judas_client/connector.py +++ b/src/judas_client/connector.py @@ -180,6 +180,7 @@ class Connector: self.logger.error(f"[!] Failed to parse message: {e}") continue self.logger.info(f"[*] Message received: {message}") + self.on_message(message) # if self._check_ack(): # self.logger.debug("[.] ACK verified") From 3512608dd19480499e7e03592db6af88c1866e65 Mon Sep 17 00:00:00 2001 From: Artur Borecki Date: Mon, 22 Sep 2025 21:19:14 +0200 Subject: [PATCH 10/15] chore(connector.py): reduce loop interval to 0.1 s in `_loop()` --- src/judas_client/connector.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/judas_client/connector.py b/src/judas_client/connector.py index 8fbc173..2488e37 100644 --- a/src/judas_client/connector.py +++ b/src/judas_client/connector.py @@ -162,7 +162,7 @@ class Connector: def _loop(self) -> None: self.logger.debug("Starting connector loop...") while True: - time.sleep(1) + time.sleep(0.1) data: bytes = self.receive() if not data: self.reconnect() From b887525cf1f6295b41c92dc8415d73c70b51a667 Mon Sep 17 00:00:00 2001 From: Artur Borecki Date: Mon, 22 Sep 2025 21:19:54 +0200 Subject: [PATCH 11/15] feat(__init__.py): import `Client` and `Connector` --- src/judas_client/__init__.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/judas_client/__init__.py b/src/judas_client/__init__.py index c66c5db..73fce9b 100644 --- a/src/judas_client/__init__.py +++ b/src/judas_client/__init__.py @@ -1 +1,6 @@ __version__: str = "0.1.0" + +from judas_client.client import Client +from judas_client.connector import Connector + +__all__ = ["Client", "Connector"] From 7ce32855c49435f31b0c82c7690754ae668f8709 Mon Sep 17 00:00:00 2001 From: Artur Borecki Date: Mon, 22 Sep 2025 21:21:01 +0200 Subject: [PATCH 12/15] refactor(__main__.py): use `Client` --- src/judas_client/__main__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/judas_client/__main__.py b/src/judas_client/__main__.py index 71126fb..989e194 100644 --- a/src/judas_client/__main__.py +++ b/src/judas_client/__main__.py @@ -3,7 +3,7 @@ from __future__ import annotations import logging as lg -from judas_client.connector import Connector +from judas_client import Client if __name__ == "__main__": lg.basicConfig( @@ -12,5 +12,5 @@ if __name__ == "__main__": ) logger = lg.getLogger(__name__) - connector = Connector("127.0.0.1", 3692) - connector.run() + client = Client(server_host="localhost", server_port=3692) + client.run() From 9b077c8c4868e7ef020cb2b25203b04b3fb42554 Mon Sep 17 00:00:00 2001 From: Artur Borecki Date: Mon, 22 Sep 2025 21:24:37 +0200 Subject: [PATCH 13/15] revert: "feat(__init__.py): import `Client` and `Connector`" This reverts commit b887525cf1f6295b41c92dc8415d73c70b51a667. --- src/judas_client/__init__.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/judas_client/__init__.py b/src/judas_client/__init__.py index 73fce9b..c66c5db 100644 --- a/src/judas_client/__init__.py +++ b/src/judas_client/__init__.py @@ -1,6 +1 @@ __version__: str = "0.1.0" - -from judas_client.client import Client -from judas_client.connector import Connector - -__all__ = ["Client", "Connector"] From a00668ecf3e99cf0453a7c333de4f6ab57cbcac3 Mon Sep 17 00:00:00 2001 From: Artur Borecki Date: Mon, 22 Sep 2025 21:26:02 +0200 Subject: [PATCH 14/15] fix(client.py): fix wrong import --- src/judas_client/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/judas_client/client.py b/src/judas_client/client.py index 6937d08..cde27d0 100644 --- a/src/judas_client/client.py +++ b/src/judas_client/client.py @@ -8,7 +8,7 @@ import uuid from judas_protocol import Message -from judas_client import Connector +from judas_client.connector import Connector class Client: From 431d8bb3bb5171a4d12ea306bfc767776bf6fb2a Mon Sep 17 00:00:00 2001 From: Artur Borecki Date: Mon, 22 Sep 2025 21:26:11 +0200 Subject: [PATCH 15/15] fix(__main__.py): fix wrong import --- src/judas_client/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/judas_client/__main__.py b/src/judas_client/__main__.py index 989e194..dac7f6f 100644 --- a/src/judas_client/__main__.py +++ b/src/judas_client/__main__.py @@ -3,7 +3,7 @@ from __future__ import annotations import logging as lg -from judas_client import Client +from judas_client.client import Client if __name__ == "__main__": lg.basicConfig(