mirror of
https://github.com/agessaman/meshcore-bot.git
synced 2026-05-25 09:54:00 +00:00
Improve monitor channel handling by adding support for quoted values
- Introduced `strip_optional_quotes` function to handle monitor channel values with optional surrounding quotes. - Updated `load_monitor_channels` method in `CommandManager` to utilize the new function, ensuring compatibility with quoted and unquoted channel configurations. - Modified `generate_samples` function to apply the same logic for consistency. - Added tests for `strip_optional_quotes` to validate behavior with various input cases.
This commit is contained in:
+5
-4
@@ -23,6 +23,7 @@ try:
|
||||
from modules.plugin_loader import PluginLoader
|
||||
from modules.db_manager import DBManager
|
||||
from modules.utils import resolve_path
|
||||
from modules.config_validation import strip_optional_quotes
|
||||
except ImportError as e:
|
||||
print("Error: Missing required dependencies.")
|
||||
print(f"Details: {e}")
|
||||
@@ -2449,8 +2450,8 @@ def generate_samples(config_file):
|
||||
title = get_website_title(config)
|
||||
introduction = get_website_intro(config)
|
||||
|
||||
# Get monitor channels
|
||||
monitor_channels_str = config.get('Channels', 'monitor_channels', fallback='')
|
||||
# Get monitor channels (quoted or unquoted)
|
||||
monitor_channels_str = strip_optional_quotes(config.get('Channels', 'monitor_channels', fallback=''))
|
||||
monitor_channels = [ch.strip() for ch in monitor_channels_str.split(',') if ch.strip()]
|
||||
|
||||
# Load channels from config
|
||||
@@ -2678,8 +2679,8 @@ def main():
|
||||
introduction = get_website_intro(config)
|
||||
title = get_website_title(config)
|
||||
|
||||
# Get monitor channels for channel restriction display
|
||||
monitor_channels_str = config.get('Channels', 'monitor_channels', fallback='')
|
||||
# Get monitor channels for channel restriction display (quoted or unquoted)
|
||||
monitor_channels_str = strip_optional_quotes(config.get('Channels', 'monitor_channels', fallback=''))
|
||||
monitor_channels = [ch.strip() for ch in monitor_channels_str.split(',') if ch.strip()]
|
||||
|
||||
# Load channels from Channels_List section
|
||||
|
||||
@@ -17,6 +17,7 @@ from .models import MeshMessage
|
||||
from .plugin_loader import PluginLoader
|
||||
from .commands.base_command import BaseCommand
|
||||
from .utils import check_internet_connectivity_async, decode_escape_sequences, format_keyword_response_with_placeholders
|
||||
from .config_validation import strip_optional_quotes
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -423,8 +424,11 @@ class CommandManager:
|
||||
return any(sender_id.startswith(entry) for entry in self.banned_users)
|
||||
|
||||
def load_monitor_channels(self) -> List[str]:
|
||||
"""Load monitored channels from config"""
|
||||
channels = self.bot.config.get('Channels', 'monitor_channels', fallback='')
|
||||
"""Load monitored channels from config.
|
||||
Values may be quoted, e.g. \"#bot,#bot-everett,#bots\" or unquoted.
|
||||
"""
|
||||
raw = self.bot.config.get('Channels', 'monitor_channels', fallback='')
|
||||
channels = strip_optional_quotes(raw)
|
||||
return [channel.strip() for channel in channels.split(',') if channel.strip()]
|
||||
|
||||
def load_channel_keywords(self) -> Optional[List[str]]:
|
||||
|
||||
@@ -56,6 +56,21 @@ ADMIN_ACL_SECTION = "Admin_ACL" # admin commands disabled
|
||||
BANNED_USERS_SECTION = "Banned_Users" # empty banned list
|
||||
LOCALIZATION_SECTION = "Localization" # language=en, translation_path=translations/
|
||||
|
||||
def strip_optional_quotes(s: str) -> str:
|
||||
"""Strip one layer of surrounding double or single quotes if present.
|
||||
|
||||
Allows config values like monitor_channels to be written as
|
||||
"#bot,#bot-everett,#bots" so the list does not look like comments.
|
||||
Backward compatible: unquoted values are returned unchanged.
|
||||
"""
|
||||
if not isinstance(s, str):
|
||||
return s
|
||||
s = s.strip()
|
||||
if len(s) >= 2 and s[0] == s[-1] and s[0] in '"\'':
|
||||
return s[1:-1]
|
||||
return s
|
||||
|
||||
|
||||
# Non-standard section name -> suggested canonical name (exact match)
|
||||
SECTION_TYPO_MAP = {
|
||||
"WebViewer": "Web_Viewer",
|
||||
|
||||
@@ -163,6 +163,12 @@ class TestLoadMonitorChannels:
|
||||
manager = make_manager(cm_bot)
|
||||
assert manager.monitor_channels == []
|
||||
|
||||
def test_load_monitor_channels_quoted(self, cm_bot):
|
||||
"""Quoted monitor_channels (e.g. \"#bot,#bot-everett,#bots\") is supported."""
|
||||
cm_bot.config.set("Channels", "monitor_channels", '"#bot,#bot-everett,#bots"')
|
||||
manager = make_manager(cm_bot)
|
||||
assert manager.monitor_channels == ["#bot", "#bot-everett", "#bots"]
|
||||
|
||||
|
||||
class TestLoadChannelKeywords:
|
||||
"""Tests for channel keyword whitelist loading."""
|
||||
|
||||
@@ -7,6 +7,7 @@ from modules.config_validation import (
|
||||
SEVERITY_ERROR,
|
||||
SEVERITY_INFO,
|
||||
SEVERITY_WARNING,
|
||||
strip_optional_quotes,
|
||||
validate_config,
|
||||
_resolve_path,
|
||||
_check_path_writable,
|
||||
@@ -15,6 +16,31 @@ from modules.config_validation import (
|
||||
)
|
||||
|
||||
|
||||
class TestStripOptionalQuotes:
|
||||
"""Tests for strip_optional_quotes (monitor_channels and similar config values)."""
|
||||
|
||||
def test_unquoted_unchanged(self):
|
||||
assert strip_optional_quotes("#bot,#bot-everett,#bots") == "#bot,#bot-everett,#bots"
|
||||
assert strip_optional_quotes("general,test") == "general,test"
|
||||
|
||||
def test_double_quoted_stripped(self):
|
||||
assert strip_optional_quotes('"#bot,#bot-everett,#bots"') == "#bot,#bot-everett,#bots"
|
||||
|
||||
def test_single_quoted_stripped(self):
|
||||
assert strip_optional_quotes("'#bot,#bot-everett,#bots'") == "#bot,#bot-everett,#bots"
|
||||
|
||||
def test_empty_and_whitespace(self):
|
||||
assert strip_optional_quotes("") == ""
|
||||
assert strip_optional_quotes(" ") == ""
|
||||
|
||||
def test_mismatched_quotes_not_stripped(self):
|
||||
assert strip_optional_quotes('"#bot,#bots\'') == '"#bot,#bots\''
|
||||
assert strip_optional_quotes('\'#bot,#bots"') == '\'#bot,#bots"'
|
||||
|
||||
def test_single_char_quoted_stripped(self):
|
||||
assert strip_optional_quotes('"a"') == "a"
|
||||
|
||||
|
||||
class TestValidateConfig:
|
||||
"""Tests for validate_config()."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user