MultiSelect moved to pylib

This commit is contained in:
Dirk Alders 2025-07-25 19:53:43 +02:00
parent 11c187dbb6
commit b3d07b2acb
3 changed files with 13 additions and 83 deletions

3
.gitmodules vendored
View File

@ -4,3 +4,6 @@
[submodule "report"] [submodule "report"]
path = report path = report
url = https://git.mount-mockery.de/pylib/report.git url = https://git.mount-mockery.de/pylib/report.git
[submodule "mytui"]
path = mytui
url = https://git.mount-mockery.de/pylib/mytui.git

View File

@ -11,6 +11,8 @@ from textual.app import App, ComposeResult
from textual.containers import Vertical from textual.containers import Vertical
from textual.widgets import Footer, Header, Input, RichLog, Button, Select from textual.widgets import Footer, Header, Input, RichLog, Button, Select
from mytui import MultiSelect
try: try:
from config import APP_NAME as ROOT_LOGGER_NAME from config import APP_NAME as ROOT_LOGGER_NAME
except ImportError: except ImportError:
@ -41,73 +43,6 @@ class MqttHandler(object):
self.mqtt_client.send(topic, payload) self.mqtt_client.send(topic, payload)
class OptionSelectList(dict):
def __init__(self):
super().__init__(self)
#
self.__default_value__ = True
self.__selection_regex__ = ""
def __sorted_keys__(self):
rv = list(self.keys())
rv.sort()
return rv
def SetSelectionRegEx(self, regex: str) -> None:
self.__selection_regex__ = regex
def AddEntry(self, entry) -> None:
if entry not in self:
self[entry] = self.__default_value__
def Toggle(self, entry_num):
if entry_num < 0:
if not self.__selection_regex__:
self.__default_value__ = entry_num == -1
for key in self:
if self.__match__(key):
self[key] = entry_num == -1
elif entry_num > len(self):
raise ValueError(f"The Entry '{entry} is not in the list")
else:
entry = self.__sorted_keys__()[entry_num]
self[entry] = not self[entry]
def __match__(self, key):
try:
match = len(re.findall(self.__selection_regex__, key)) > 0
except re.error:
match = True # No valid regular expression
return match
def GetSelectList(self):
rv = []
if len(self) > 2:
rv.append(('All', -1))
rv.append(('None', -2))
for index, key in enumerate(self.__sorted_keys__()):
if self.__match__(key):
prefix = "\\[X] " if self[key] else "\\[-] "
rv.append((prefix + key, index))
return rv
def IsSelected(self, entry):
return self.get(entry, False)
class MySelect(Select):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.__new_options__ = []
def set_options(self, options):
self.__new_options__ = options
def _on_enter(self, event):
super().set_options(self.__new_options__)
return super()._on_enter(event)
class MqttSniffer(App): class MqttSniffer(App):
"""a textual application for viewing mqtt messages.""" """a textual application for viewing mqtt messages."""
@ -125,8 +60,7 @@ class MqttSniffer(App):
# #
self.mqtt = None self.mqtt = None
self.all_logs = [] self.all_logs = []
self.__topic_select_list__ = OptionSelectList() self.__topic_selection__ = MultiSelect((), prompt="Full", id="topic_filter")
self.__topic_selection__ = MySelect((), prompt="Full", id="topic_filter")
self.send_topic = "" self.send_topic = ""
self.send_payload = "" self.send_payload = ""
self.log_display = RichLog(highlight=True, markup=True) self.log_display = RichLog(highlight=True, markup=True)
@ -152,8 +86,7 @@ class MqttSniffer(App):
def add_log(self, record) -> None: def add_log(self, record) -> None:
"""Add new mqt messages and update the tui.""" """Add new mqt messages and update the tui."""
asctime = time.asctime() asctime = time.asctime()
self.__topic_select_list__.AddEntry(record.topic) self.__topic_selection__.AddEntry(record.topic)
self.__topic_selection__.set_options(self.__topic_select_list__.GetSelectList())
self.all_logs.append((asctime, record)) self.all_logs.append((asctime, record))
if len(self.all_logs) > self.MAX_LOGS: if len(self.all_logs) > self.MAX_LOGS:
self.all_logs = self.all_logs[-self.MAX_LOGS:] self.all_logs = self.all_logs[-self.MAX_LOGS:]
@ -162,7 +95,7 @@ class MqttSniffer(App):
def _apply_filters_to_log(self, data: logging.LogRecord): def _apply_filters_to_log(self, data: logging.LogRecord):
asctime, record = data asctime, record = data
if self.__topic_select_list__.IsSelected(record.topic): if self.__topic_selection__.IsSelected(record.topic):
message = ( message = (
f"[[dim]{asctime}[/dim]] " f"[[dim]{asctime}[/dim]] "
f"[bold]{record.topic}[/bold] - " f"[bold]{record.topic}[/bold] - "
@ -184,22 +117,15 @@ class MqttSniffer(App):
def on_input_changed(self, message: Input.Changed) -> None: def on_input_changed(self, message: Input.Changed) -> None:
"""Update the tui inputs and execute task, if requireed.""" """Update the tui inputs and execute task, if requireed."""
if message.input.id == "select_filter": if message.input.id == "select_filter":
self.__topic_select_list__.SetSelectionRegEx(message.value) self.__topic_selection__.SetSelectionRegEx(message.value)
self.__topic_selection__.set_options(self.__topic_select_list__.GetSelectList()) elif message.input.id == "send_topic":
self.__topic_selection__.prompt = "Full" if not message.value else "Filtered"
if message.input.id == "send_topic":
self.send_topic = message.value self.send_topic = message.value
elif message.input.id == "send_payload": elif message.input.id == "send_payload":
self.send_payload = message.value self.send_payload = message.value
def on_select_changed(self, message: Select.Changed) -> None: def on_select_changed(self, message: Select.Changed) -> None:
if message.select.id == 'topic_filter': if message.select.id in ('topic_filter', ):
if type(message.value) is int: self._update_display()
self.__topic_select_list__.Toggle(message.value)
self.__topic_selection__.clear()
self.__topic_selection__.set_options(self.__topic_select_list__.GetSelectList())
self._update_display()
def on_button_pressed(self, event: Button.Pressed) -> None: def on_button_pressed(self, event: Button.Pressed) -> None:
"""Event handler called when a button is pressed.""" """Event handler called when a button is pressed."""

1
mytui Submodule

@ -0,0 +1 @@
Subproject commit bd390d27f00147c1305e244fbd6d0650a6bdcec9