mirror of
https://github.com/agessaman/meshcore-bot.git
synced 2026-04-26 10:58:04 +00:00
feat: add RandomLine command support for website generation
Introduced a new command structure for RandomLine entries in the website generation process, allowing for dynamic rendering of random lines based on configuration. Updated the configuration file to include a new category option for commands and enhanced documentation to reflect these changes. This addition improves the command reference organization and user experience on the website.
This commit is contained in:
@@ -393,6 +393,7 @@ pong = "Ping!"
|
||||
# file.<key> = path to text file
|
||||
# prefix.<key> = string prepended to the chosen line (often an emoji)
|
||||
# channel.<key> or channels.<key> = comma-separated channel names; if set, trigger only works in those channels (e.g. channel.momjoke = #jokes)
|
||||
# category.<key> = command reference category for website generation (default: fun/Fun Commands)
|
||||
|
||||
# default prefix (blank = no prefix)
|
||||
prefix.default =
|
||||
@@ -402,16 +403,19 @@ triggers.momjoke = momjoke,momjokes,mom joke,mom jokes,mom-joke,mom-jokes
|
||||
file.momjoke = data/randomlines/momjokes.txt
|
||||
prefix.momjoke = 🥸
|
||||
# channel.momjoke = #jokes
|
||||
# category.momjoke = fun
|
||||
|
||||
# Fun Facts
|
||||
triggers.funfact = funfact,funfacts,fun fact,fun facts,fun-fact,fun-facts
|
||||
file.funfact = data/randomlines/funfacts.txt
|
||||
prefix.funfact = 💡
|
||||
category.funfact = fun
|
||||
|
||||
# Example: fortunes via RandomLine
|
||||
#triggers.fortune = fortune,fortunes
|
||||
#file.fortune = data/randomlines/fortunes.txt
|
||||
#prefix.fortune = 🥠
|
||||
#category.fortune = fun
|
||||
|
||||
[Scheduled_Messages]
|
||||
# Scheduled message format: HHMM = channel:message
|
||||
|
||||
@@ -108,6 +108,7 @@ Examples of sections that configure specific commands or features:
|
||||
- **`[Alert_Command]`** – Emergency alerts (agency IDs, etc.).
|
||||
- **`[Sports_Command]`** – Sports scores (teams, leagues).
|
||||
- **`[Joke_Command]`**, **`[DadJoke_Command]`** – Joke sources and options.
|
||||
- **`[RandomLine]`** – Trigger-based random-line responses via `triggers.<key>`, `file.<key>`, optional `prefix.<key>`, optional channel restriction (`channel.<key>`/`channels.<key>`), and optional website category override (`category.<key>`). Website command reference groups RandomLine entries under **Fun Commands** by default unless `category.<key>` is set.
|
||||
|
||||
Common per-command options (when supported by that command):
|
||||
|
||||
|
||||
@@ -965,6 +965,85 @@ def get_website_title(config: configparser.ConfigParser) -> str:
|
||||
return f"{bot_name} - Command Reference"
|
||||
|
||||
|
||||
class WebsiteRandomLineCommand:
|
||||
"""Command-like object used to render RandomLine entries on the website."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
key: str,
|
||||
triggers: list[str],
|
||||
category: str,
|
||||
usage: str,
|
||||
description: str,
|
||||
allowed_channels: Optional[list[str]] = None
|
||||
):
|
||||
self.name = key
|
||||
self.keywords = triggers
|
||||
self.category = category
|
||||
self.description = description
|
||||
self.allowed_channels = allowed_channels
|
||||
self._usage = usage
|
||||
|
||||
def get_usage_info(self) -> dict[str, Any]:
|
||||
return {
|
||||
'usage': self._usage,
|
||||
'short_description': self.description,
|
||||
'description': self.description,
|
||||
'examples': [],
|
||||
'parameters': [],
|
||||
'subcommands': [],
|
||||
}
|
||||
|
||||
|
||||
def normalize_category_name(category_name: str) -> str:
|
||||
"""Normalize category names to lowercase underscore style."""
|
||||
return category_name.strip().lower().replace('-', '_').replace(' ', '_')
|
||||
|
||||
|
||||
def get_randomline_commands(config: configparser.ConfigParser) -> dict[str, Any]:
|
||||
"""Build website command entries from [RandomLine] triggers."""
|
||||
randomline_commands: dict[str, Any] = {}
|
||||
if not config.has_section('RandomLine'):
|
||||
return randomline_commands
|
||||
|
||||
command_prefix = config.get('Bot', 'command_prefix', fallback='').strip()
|
||||
|
||||
for option, value in config.items('RandomLine'):
|
||||
if not option.startswith('triggers.'):
|
||||
continue
|
||||
|
||||
key = option.split('.', 1)[1].strip()
|
||||
if not key:
|
||||
continue
|
||||
|
||||
triggers = [trigger.strip() for trigger in value.split(',') if trigger.strip()]
|
||||
if not triggers:
|
||||
continue
|
||||
|
||||
category_override = config.get('RandomLine', f'category.{key}', fallback='').strip()
|
||||
category = normalize_category_name(category_override) if category_override else 'fun'
|
||||
|
||||
display_trigger = triggers[0]
|
||||
usage = f"{command_prefix}{display_trigger}" if command_prefix else display_trigger
|
||||
|
||||
channel_opt = config.get('RandomLine', f'channel.{key}', fallback='').strip()
|
||||
if not channel_opt:
|
||||
channel_opt = config.get('RandomLine', f'channels.{key}', fallback='').strip()
|
||||
allowed_channels = [ch.strip() for ch in channel_opt.split(',') if ch.strip()] if channel_opt else None
|
||||
|
||||
description = "Returns a random line from a configured text list."
|
||||
randomline_commands[f"randomline.{key}"] = WebsiteRandomLineCommand(
|
||||
key=key,
|
||||
triggers=triggers,
|
||||
category=category,
|
||||
usage=usage,
|
||||
description=description,
|
||||
allowed_channels=allowed_channels,
|
||||
)
|
||||
|
||||
return randomline_commands
|
||||
|
||||
|
||||
def load_channels_from_config(config: configparser.ConfigParser) -> dict[str, dict[str, str]]:
|
||||
"""Load channels from Channels_List section, grouped by category
|
||||
|
||||
@@ -2479,6 +2558,7 @@ def generate_samples(config_file):
|
||||
name: cmd for name, cmd in commands.items()
|
||||
if name not in admin_commands and not getattr(cmd, 'hidden', False)
|
||||
}
|
||||
public_commands.update(get_randomline_commands(config))
|
||||
|
||||
# Sort commands
|
||||
sorted_commands = sorted(public_commands.items(), key=lambda x: x[0])
|
||||
@@ -2714,6 +2794,7 @@ def main():
|
||||
|
||||
# Filter out admin and hidden commands
|
||||
filtered_commands = filter_commands(commands, admin_commands)
|
||||
filtered_commands.update(get_randomline_commands(config))
|
||||
logger.info(f"Filtered to {len(filtered_commands)} public commands")
|
||||
|
||||
# Log which commands are included
|
||||
|
||||
58
tests/test_generate_website_randomline.py
Normal file
58
tests/test_generate_website_randomline.py
Normal file
@@ -0,0 +1,58 @@
|
||||
import configparser
|
||||
|
||||
from generate_website import generate_html, get_randomline_commands
|
||||
|
||||
|
||||
def _build_config() -> configparser.ConfigParser:
|
||||
config = configparser.ConfigParser()
|
||||
config.add_section("Bot")
|
||||
config.set("Bot", "command_prefix", "!")
|
||||
config.add_section("RandomLine")
|
||||
config.set("RandomLine", "prefix.default", "")
|
||||
return config
|
||||
|
||||
|
||||
def test_get_randomline_commands_defaults_to_fun_category():
|
||||
config = _build_config()
|
||||
config.set("RandomLine", "triggers.momjoke", "momjoke,mom joke")
|
||||
config.set("RandomLine", "file.momjoke", "data/randomlines/momjokes.txt")
|
||||
|
||||
randomline_commands = get_randomline_commands(config)
|
||||
command = randomline_commands["randomline.momjoke"]
|
||||
|
||||
assert command.name == "momjoke"
|
||||
assert command.category == "fun"
|
||||
assert command.keywords == ["momjoke", "mom joke"]
|
||||
assert command.get_usage_info()["usage"] == "!momjoke"
|
||||
|
||||
|
||||
def test_get_randomline_commands_applies_category_override():
|
||||
config = _build_config()
|
||||
config.set("RandomLine", "triggers.funfact", "funfact,fun fact")
|
||||
config.set("RandomLine", "file.funfact", "data/randomlines/funfacts.txt")
|
||||
config.set("RandomLine", "category.funfact", "Games And Entertainment")
|
||||
|
||||
randomline_commands = get_randomline_commands(config)
|
||||
command = randomline_commands["randomline.funfact"]
|
||||
|
||||
assert command.category == "games_and_entertainment"
|
||||
|
||||
|
||||
def test_generate_html_includes_randomline_commands_in_fun_section():
|
||||
config = _build_config()
|
||||
config.set("RandomLine", "triggers.momjoke", "momjoke,mom joke")
|
||||
config.set("RandomLine", "file.momjoke", "data/randomlines/momjokes.txt")
|
||||
|
||||
randomline_commands = get_randomline_commands(config)
|
||||
html_content = generate_html(
|
||||
bot_name="TestBot",
|
||||
title="TestBot - Command Reference",
|
||||
introduction="Intro",
|
||||
commands=list(randomline_commands.items()),
|
||||
monitor_channels=[],
|
||||
channels_data={},
|
||||
style="default",
|
||||
)
|
||||
|
||||
assert "Fun Commands" in html_content
|
||||
assert "momjoke" in html_content
|
||||
Reference in New Issue
Block a user