From 15e124edeeffb3fad3efae15e16b47110ab78f74 Mon Sep 17 00:00:00 2001 From: itdominator <1itdominator@gmail.com> Date: Tue, 13 Oct 2026 18:29:32 -0500 Subject: [PATCH] refactor: Moved bridge event handling to use typed DTOs - Introduce event type and action fields in `BaseEvent` - Register common events in the event factory - Default event creation to the generic event type - Improve WebKit bridge logging and update example messages --- src/core/controllers/bridge_controller.py | 48 ++++++++++++------- src/core/widgets/webkit/index.html | 7 ++- src/core/widgets/webkit/webkit_ui.py | 10 ++-- src/libs/dto/__init__.py | 2 +- src/libs/dto/base_event.py | 3 +- src/libs/dto/common/events/__init__.py | 7 +++ .../common/events/display_message_event.py | 13 +++++ src/libs/dto/common/events/generic_event.py | 12 +++++ src/libs/dto/files/events/__init__.py | 2 +- src/libs/event_factory.py | 4 +- 10 files changed, 78 insertions(+), 30 deletions(-) create mode 100644 src/libs/dto/common/events/__init__.py create mode 100644 src/libs/dto/common/events/display_message_event.py create mode 100644 src/libs/dto/common/events/generic_event.py diff --git a/src/core/controllers/bridge_controller.py b/src/core/controllers/bridge_controller.py index bc2c542..1a3f163 100644 --- a/src/core/controllers/bridge_controller.py +++ b/src/core/controllers/bridge_controller.py @@ -1,9 +1,11 @@ # Python imports import base64 +import json # Lib imports # Application imports +from libs.event_factory import Event_Factory, App_Event_Types @@ -21,21 +23,31 @@ class BridgeController: event_system.subscribe("handle-bridge-event", self.handle_bridge_event) - def handle_bridge_event(self, event): - match event.topic: - case "save": - event_system.emit(f"handle-file-event-{event.originator}", (event,)) - case "close": - event_system.emit(f"handle-file-event-{event.originator}", (event,)) - case "load_buffer": - event_system.emit(f"handle-file-event-{event.originator}", (event,)) - case "load_file": - event_system.emit(f"handle-file-event-{event.originator}", (event,)) - case "alert": - content = base64.b64decode( event.content.encode() ).decode("utf-8") - logger.info(f"\nMessage Topic: {event.topic}\nMessage Content: {content}") - case "error": - content = base64.b64decode( event.content.encode() ).decode("utf-8") - logger.info(content) - case _: - ... \ No newline at end of file + def handle_bridge_event(self, event_str: str): + event = Event_Factory.create_event( **json.loads(event_str) ) + + if isinstance(event, App_Event_Types.DisplayMessageEvent): + match event.topic: + case "alert": + message = base64.b64decode( event.message.encode() ).decode("utf-8") + logger.info(f"\nMessage Topic: {event.topic}\nMessage Content: {message}") + case "error": + message = base64.b64decode( event.message.encode() ).decode("utf-8") + logger.info(message) + case _: + ... + elif isinstance(event, App_Event_Types.GenericEvent): + match event.action: + case "save": + event_system.emit(f"handle-file-event-{event.originator}", (event,)) + case "close": + event_system.emit(f"handle-file-event-{event.originator}", (event,)) + case "load_buffer": + event_system.emit(f"handle-file-event-{event.originator}", (event,)) + case "load_file": + event_system.emit(f"handle-file-event-{event.originator}", (event,)) + case "alert": + content = base64.b64decode( event.content.encode() ).decode("utf-8") + logger.info(f"\nEvent Action: {event.action}\nEvent Content: {content}") + case _: + ... diff --git a/src/core/widgets/webkit/index.html b/src/core/widgets/webkit/index.html index ea5c25f..e7b2a93 100644 --- a/src/core/widgets/webkit/index.html +++ b/src/core/widgets/webkit/index.html @@ -28,8 +28,11 @@ window.addEventListener("load", () => { window.webkit.messageHandlers.logger.postMessage("Hello, World!"); - // const message = '{"topic": "alert", "content": "' + btoa("Hello, World!") + '"}'; - // window.webkit.messageHandlers.backend.postMessage(message); + // Note: Events can be generic which means that without 'event_type' + // it's mapped to GenericEvent which is just BaseEvent under the hood. + // const message = '{"action": "alert", "content": "' + btoa("Hello, World!") + '"}'; + const message = '{"event_type": "display_message", "topic": "alert", "message": "' + btoa("Hello, World!") + '"}'; + window.webkit.messageHandlers.backend.postMessage(message); }); diff --git a/src/core/widgets/webkit/webkit_ui.py b/src/core/widgets/webkit/webkit_ui.py index 9bb78c5..755fd25 100644 --- a/src/core/widgets/webkit/webkit_ui.py +++ b/src/core/widgets/webkit/webkit_ui.py @@ -1,6 +1,5 @@ # Python imports from pathlib import Path -import json # Lib imports import gi @@ -13,7 +12,7 @@ from gi.repository import WebKit2 # Application imports from libs.settings.webkit.webkit_ui_settings import WebkitUISettings -from libs.dto.base_event import BaseEvent + class WebkitUI(WebKit2.WebView): @@ -54,8 +53,8 @@ class WebkitUI(WebKit2.WebView): content_manager.register_script_message_handler("backend") def _on_tls_errors(self, webview, uri, certificate, errors): - print("TLS error:", uri) - print("Errors:", errors) + logger.info("TLS error:", uri) + logger.info("Errors:", errors) webview.get_website_data_manager().get_tls_errors_policy() webview.get_context().allow_tls_certificate_for_host( @@ -76,8 +75,7 @@ class WebkitUI(WebKit2.WebView): message = js_value.to_string() try: - event = BaseEvent( **json.loads(message) ) - event_system.emit("handle-bridge-event", (event,)) + event_system.emit("handle-bridge-event", (message,)) except Exception as e: logger.info(e) diff --git a/src/libs/dto/__init__.py b/src/libs/dto/__init__.py index 6e319fb..f5ae947 100644 --- a/src/libs/dto/__init__.py +++ b/src/libs/dto/__init__.py @@ -2,4 +2,4 @@ Libs DTO(s) Package """ -from .base_event import BaseEvent \ No newline at end of file +from .base_event import BaseEvent diff --git a/src/libs/dto/base_event.py b/src/libs/dto/base_event.py index a91c7db..27c6acb 100644 --- a/src/libs/dto/base_event.py +++ b/src/libs/dto/base_event.py @@ -9,7 +9,8 @@ from dataclasses import dataclass, field @dataclass(slots = True) class BaseEvent: - topic: str = None + event_type: str = "base" + action: str = "" content: any = None raw_content: any = None success: callable = None diff --git a/src/libs/dto/common/events/__init__.py b/src/libs/dto/common/events/__init__.py new file mode 100644 index 0000000..6e932e5 --- /dev/null +++ b/src/libs/dto/common/events/__init__.py @@ -0,0 +1,7 @@ +""" + Libs Common DTO(s) Package +""" + + +from .generic_event import GenericEvent +from .display_message_event import DisplayMessageEvent diff --git a/src/libs/dto/common/events/display_message_event.py b/src/libs/dto/common/events/display_message_event.py new file mode 100644 index 0000000..e1c94bc --- /dev/null +++ b/src/libs/dto/common/events/display_message_event.py @@ -0,0 +1,13 @@ +# Python imports +from dataclasses import dataclass, field + +# Lib imports + +# Application imports +from ...base_event import BaseEvent + + + +class DisplayMessageEvent(BaseEvent): + topic: str = None + message: str = None diff --git a/src/libs/dto/common/events/generic_event.py b/src/libs/dto/common/events/generic_event.py new file mode 100644 index 0000000..6f672f9 --- /dev/null +++ b/src/libs/dto/common/events/generic_event.py @@ -0,0 +1,12 @@ +# Python imports +from dataclasses import dataclass, field + +# Lib imports + +# Application imports +from ...base_event import BaseEvent + + + +class GenericEvent(BaseEvent): + event_type: str = "generic" diff --git a/src/libs/dto/files/events/__init__.py b/src/libs/dto/files/events/__init__.py index 6297085..512ab93 100644 --- a/src/libs/dto/files/events/__init__.py +++ b/src/libs/dto/files/events/__init__.py @@ -1,5 +1,5 @@ """ - Libs Code DTO(s) Events Package + Libs Files DTO(s) Events Package """ diff --git a/src/libs/event_factory.py b/src/libs/event_factory.py index ffebbdc..6dea0a4 100644 --- a/src/libs/event_factory.py +++ b/src/libs/event_factory.py @@ -9,6 +9,7 @@ import re from .singleton import Singleton from .dto.base_event import BaseEvent +from .dto.common import events as common from .dto.code import events as code from .dto.files import events as files @@ -19,6 +20,7 @@ class EventFactory(Singleton): self._event_classes: Dict[str, Type[BaseEvent]] = {} + self._auto_register_events( common.__dict__.items() ) self._auto_register_events( files.__dict__.items() ) self._auto_register_events( code.__dict__.items() ) @@ -51,7 +53,7 @@ class EventFactory(Singleton): logger.debug(f"Unregistered {i} event types:") - def create_event(self, event_type: str, **kwargs) -> BaseEvent: + def create_event(self, event_type: str = "generic", **kwargs) -> BaseEvent: if event_type not in self._event_classes: raise ValueError(f"Unknown event type: {event_type}")