diff --git a/contact/localisations/en.ini b/contact/localisations/en.ini index e29ad52..f9663e9 100644 --- a/contact/localisations/en.ini +++ b/contact/localisations/en.ini @@ -96,8 +96,6 @@ bot.status.disabled, "Disabled", "" bot.dialog.title, "Bot Responder", "" bot.dialog.body, "Bot responder is now {status}.", "" bot.status.message, "Bot responder is now {status}.", "" -bot.catch_words, "ping; test", "Semicolon-separated bot trigger words." -bot.response.word, "Pong!", "Bot response word." [User Settings] user, "User" @@ -124,10 +122,16 @@ nak_str, "NAK", "" ack_unknown_str, "ACK (unknown)", "" node_sort, "Node sort", "" theme, "Theme", "" +ping_bot, "Ping Bot", "" COLOR_CONFIG_DARK, "Theme colors (dark)", "" COLOR_CONFIG_LIGHT, "Theme colors (light)", "" COLOR_CONFIG_GREEN, "Theme colors (green)", "" +[app_settings.ping_bot] +title, "Ping Bot", "" +catch_words, "Catch words", "Semicolon-separated bot trigger words." +response_word, "Response word", "Bot response word." + [app_settings.color_config] default, "Default", "" background, "Background", "" diff --git a/contact/localisations/fr.ini b/contact/localisations/fr.ini index f8cc042..e59762a 100644 --- a/contact/localisations/fr.ini +++ b/contact/localisations/fr.ini @@ -88,8 +88,6 @@ bot.status.disabled, "Désactivé", "" bot.dialog.title, "Bot répondeur", "" bot.dialog.body, "Le bot répondeur est maintenant {status}.", "" bot.status.message, "Le bot répondeur est maintenant {status}.", "" -bot.catch_words, "ping", "Mots déclencheurs du bot séparés par des virgules." -bot.response.word, "Pong!", "Mot de reponse du bot (orthographe preferee)." [User Settings] user, "Utilisateur", "" @@ -116,6 +114,12 @@ nak_str, "NAK", "" ack_unknown_str, "ACK (inconnu)", "" node_sort, "Tri des nœuds", "" theme, "Thème", "" +ping_bot, "Bot Ping", "" + +[app_settings.ping_bot] +title, "Bot Ping", "" +catch_words, "Mots déclencheurs", "Mots déclencheurs du bot séparés par des points-virgules." +response_word, "Mot de réponse", "Mot de réponse du bot." [config.device] title, "Appareil", "" diff --git a/contact/localisations/ru.ini b/contact/localisations/ru.ini index 7c01ad4..feca158 100644 --- a/contact/localisations/ru.ini +++ b/contact/localisations/ru.ini @@ -96,8 +96,6 @@ bot.status.disabled, "Выключен", "" bot.dialog.title, "Автоответчик", "" bot.dialog.body, "Автоответчик теперь {status}.", "" bot.status.message, "Автоответчик теперь {status}.", "" -bot.catch_words, "ping; пинг", "Слова для активации бота, разделенные точкой с запятой." -bot.response.word, "Понг!", "Ответное слово бота (предпочтительное написание)." [User Settings] user, "Пользователь" @@ -124,10 +122,16 @@ nak_str, "NAK", "" ack_unknown_str, "ACK (неизвестный)", "" node_sort, "Сортировка нод", "" theme, "Тема", "" +ping_bot, "Пинг-бот", "" COLOR_CONFIG_DARK, "Цвета темы (темная)", "" COLOR_CONFIG_LIGHT, "Цвета темы (светлая)", "" COLOR_CONFIG_GREEN, "Цвета темы (зеленая)", "" +[app_settings.ping_bot] +title, "Пинг-бот", "" +catch_words, "Слова-триггеры", "Слова для активации бота, разделенные точкой с запятой." +response_word, "Ответное слово", "Ответное слово бота." + [app_settings.color_config] default, "По умолчанию", "" background, "Фон", "" diff --git a/contact/message_handlers/bot_handler.py b/contact/message_handlers/bot_handler.py index 3d91cac..e2f193f 100644 --- a/contact/message_handlers/bot_handler.py +++ b/contact/message_handlers/bot_handler.py @@ -4,15 +4,15 @@ import threading import time from typing import Any, Dict +import contact.ui.default_config as config from contact.utilities.singleton import app_state, interface_state, ui_state from contact.message_handlers.tx_handler import send_message -from contact.utilities.i18n import t BOT_RESPONSE_DELAY_SECONDS = 2.3 def _get_bot_catch_words() -> set[str]: - """Return normalized bot trigger words from localisation settings.""" - raw_words = t("ui.bot.catch_words", default="ping") + """Return normalized bot trigger words from app settings.""" + raw_words = getattr(config, "ping_bot_catch_words", "ping; test") words = { word.strip().casefold() for word in raw_words.replace(";", ",").split(",") @@ -60,7 +60,7 @@ def bot_respond(packet: Dict[str, Any], message: str, send_channel: int) -> bool if transport_name in transport_text: details.append(f"Via: {transport_name}") - response_data_string = t("ui.bot.response.word", default="Pong!") + response_data_string = getattr(config, "ping_bot_response_word", "Pong!") if details: response_data_string += f" {', '.join(details)}" @@ -84,4 +84,4 @@ def bot_respond(packet: Dict[str, Any], message: str, send_channel: int) -> bool threading.Thread(target=send_response_delayed, name="bot-response", daemon=True).start() - return True \ No newline at end of file + return True diff --git a/contact/ui/default_config.py b/contact/ui/default_config.py index 6b56f57..6bbb9b2 100644 --- a/contact/ui/default_config.py +++ b/contact/ui/default_config.py @@ -238,6 +238,10 @@ def initialize_config() -> Dict[str, object]: "ack_unknown_str": "[…]", "node_sort": "lastHeard", "theme": "dark", + "ping_bot": { + "catch_words": "ping; test", + "response_word": "Pong!", + }, "COLOR_CONFIG_DARK": COLOR_CONFIG_DARK, "COLOR_CONFIG_LIGHT": COLOR_CONFIG_LIGHT, "COLOR_CONFIG_GREEN": COLOR_CONFIG_GREEN, @@ -272,7 +276,7 @@ def assign_config_variables(loaded_config: Dict[str, object]) -> None: global notification_symbol, ack_implicit_str, ack_str, nak_str, ack_unknown_str global node_list_16ths, channel_list_16ths, single_pane_mode global theme, COLOR_CONFIG, language - global node_sort, notification_sound + global node_sort, notification_sound, ping_bot_catch_words, ping_bot_response_word channel_list_16ths = loaded_config["channel_list_16ths"] node_list_16ths = loaded_config["node_list_16ths"] @@ -291,6 +295,9 @@ def assign_config_variables(loaded_config: Dict[str, object]) -> None: ack_unknown_str = loaded_config["ack_unknown_str"] node_sort = loaded_config["node_sort"] theme = loaded_config["theme"] + ping_bot = loaded_config.get("ping_bot", {}) + ping_bot_catch_words = ping_bot.get("catch_words", "ping; test") + ping_bot_response_word = ping_bot.get("response_word", "Pong!") if theme == "dark": COLOR_CONFIG = loaded_config["COLOR_CONFIG_DARK"] elif theme == "light": diff --git a/contact/ui/user_config.py b/contact/ui/user_config.py index 47c45b8..ac35f6a 100644 --- a/contact/ui/user_config.py +++ b/contact/ui/user_config.py @@ -309,7 +309,10 @@ def display_menu() -> tuple[Any, Any, List[str]]: else: display_key = key display_key = f"{display_key}"[: w // 2 - 2] - display_value = f"{value}"[: w // 2 - 8] + if isinstance(value, dict) or (isinstance(value, list) and len(value) != 2): + display_value = ">" + else: + display_value = f"{value}"[: w // 2 - 8] color = get_color("settings_default", reverse=(idx == menu_state.selected_index)) menu_pad.addstr(idx, 0, f"{display_key:<{w // 2 - 2}} {display_value}".ljust(w - 8), color) diff --git a/tests/test_bot_handler.py b/tests/test_bot_handler.py new file mode 100644 index 0000000..250082c --- /dev/null +++ b/tests/test_bot_handler.py @@ -0,0 +1,31 @@ +import unittest +import importlib +import sys +import types +from unittest import mock + +import contact.ui.default_config as config + + +class BotHandlerTests(unittest.TestCase): + @classmethod + def setUpClass(cls) -> None: + sys.modules.setdefault( + "contact.message_handlers.tx_handler", + types.SimpleNamespace(send_message=mock.Mock()), + ) + cls.bot_handler = importlib.import_module("contact.message_handlers.bot_handler") + + def test_is_bot_message_uses_configured_catch_words(self) -> None: + with mock.patch.object(config, "ping_bot_catch_words", "ping; test; pong"): + self.assertTrue(self.bot_handler.is_bot_message("PING")) + self.assertTrue(self.bot_handler.is_bot_message("test")) + self.assertFalse(self.bot_handler.is_bot_message("hello")) + + def test_is_bot_message_ignores_empty_config_values(self) -> None: + with mock.patch.object(config, "ping_bot_catch_words", " ; ; "): + self.assertTrue(self.bot_handler.is_bot_message("ping")) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_i18n.py b/tests/test_i18n.py index 5f81885..7c029fe 100644 --- a/tests/test_i18n.py +++ b/tests/test_i18n.py @@ -65,8 +65,9 @@ class I18nTests(unittest.TestCase): "ui.bot.dialog.title", "ui.bot.dialog.body", "ui.bot.status.message", - "ui.bot.catch_words", - "ui.bot.response.word", + "app_settings.ping_bot", + "app_settings.ping_bot.catch_words", + "app_settings.ping_bot.response_word", } for language in config.get_localisation_options():