plugin: handle aliases for commands
This commit is contained in:
parent
d85d5e054f
commit
3748312c41
|
@ -41,7 +41,7 @@ Missing features
|
|||
- [x] Wikipedia: find definition, get random page
|
||||
- [ ] Wolframalpha
|
||||
- [ ] Youtube: parsing for title, requests for channel or video
|
||||
- [ ] Command aliases
|
||||
- [x] Command aliases
|
||||
- [ ] Question aliases
|
||||
- [x] Sleep
|
||||
- [ ] Various macros:
|
||||
|
|
|
@ -129,33 +129,59 @@ class Plugin:
|
|||
return False
|
||||
|
||||
# Is it a valid command?
|
||||
command = self.parse_command(message, no_content=no_content)
|
||||
if not command:
|
||||
parsed_command = self.__parse_command(message, no_content=no_content)
|
||||
if not parsed_command:
|
||||
return False
|
||||
|
||||
# Is it a command I can handle?
|
||||
commands = self.config.get("commands", [])
|
||||
if (
|
||||
any(command.ident == c for c in commands) or
|
||||
(no_content and any(command.ident.startswith(c) for c in commands))
|
||||
):
|
||||
self.command = command
|
||||
self.bot.log_d(f"Processing command from plugin {self.name}.")
|
||||
available_commands = self.config.get("commands", [])
|
||||
aliases = self.config.get("aliases", {})
|
||||
for ident in available_commands:
|
||||
# Match commands differently according to no_content. If no_content
|
||||
# is True, check the parsed command (pc) raw data as a string that
|
||||
# may contain the available identifier (ai) at its beginning.
|
||||
# If no_content is False (default), simply compare the parsed
|
||||
# identifier with available identifiers.
|
||||
if no_content:
|
||||
match = lambda pc, ai: (
|
||||
pc.raw == ai or pc.raw.startswith(ai + " ")
|
||||
)
|
||||
else:
|
||||
match = lambda pc, ai: pc.ident == ai
|
||||
# First case: the command identifier has been used.
|
||||
if match(parsed_command, ident):
|
||||
parsed_command.ident = ident
|
||||
parsed_command.match = ident
|
||||
self.__save_command(parsed_command)
|
||||
return True
|
||||
# Second case: an alias of the identifier has been used.
|
||||
ident_aliases = aliases.get(ident, [])
|
||||
for alias in ident_aliases:
|
||||
if match(parsed_command, alias):
|
||||
parsed_command.ident = ident
|
||||
parsed_command.match = alias
|
||||
self.__save_command(parsed_command)
|
||||
return True
|
||||
return False
|
||||
|
||||
def parse_command(self, message, no_content=False):
|
||||
"""Return a command ID if this message is a command."""
|
||||
def __parse_command(self, message, no_content=False):
|
||||
"""Return a command ID if this message is a command.
|
||||
|
||||
The command raw field is always set. The ident and content fields are
|
||||
not set when no_content is True. The match field is never set by this
|
||||
method.
|
||||
"""
|
||||
words = message.split()
|
||||
command_suffix = self.config["command_suffix"]
|
||||
if words[0].lower() in self.bot.names and words[-1] == command_suffix:
|
||||
raw = " ".join(words[1:-1])
|
||||
if no_content:
|
||||
ident = " ".join(words[1:-1])
|
||||
ident = ""
|
||||
content = ""
|
||||
else:
|
||||
ident = words[1]
|
||||
content = " ".join(words[2:-1])
|
||||
return Command(ident, content)
|
||||
return Command(ident, content, raw)
|
||||
|
||||
def __respects_handling_conditions(self, exclude_conditions=None):
|
||||
"""Check if question conditions are valid."""
|
||||
|
@ -172,6 +198,11 @@ class Plugin:
|
|||
return False
|
||||
return True
|
||||
|
||||
def __save_command(self, command):
|
||||
"""Save command in instance for further processing by the plugin."""
|
||||
self.command = command
|
||||
self.bot.log_d(f"Processing command from plugin {self.name}: {command}")
|
||||
|
||||
def signal_failure(self, target):
|
||||
"""Signal a plugin failure to target."""
|
||||
self.bot.say(target, self.bot.config["error_message"])
|
||||
|
@ -185,5 +216,11 @@ class Question:
|
|||
|
||||
@dataclass
|
||||
class Command:
|
||||
# Identifier as set in config. Set even when an alias has been used.
|
||||
ident: str
|
||||
# Content of the command when it has been parsed, empty str otherwise.
|
||||
content: str
|
||||
# Raw command content (minus name and suffix), always set.
|
||||
raw: str
|
||||
# Identifier matched, possibly an alias. Set only when matched.
|
||||
match: str = ""
|
||||
|
|
|
@ -44,9 +44,11 @@ class MoodPlugin(Plugin):
|
|||
self.bot.say(event.target, random.choice(greetings))
|
||||
|
||||
def on_pubmsg(self, event):
|
||||
# Only one command: calm down.
|
||||
if self.should_handle_command(event.arguments[0], no_content=True):
|
||||
self.calm_down(event.target)
|
||||
return True
|
||||
# Only one question: what's your mood?
|
||||
if self.should_answer_question(event.arguments[0]):
|
||||
self.say_mood(event.target)
|
||||
return True
|
||||
|
|
|
@ -31,9 +31,8 @@ class NotesPlugin(Plugin):
|
|||
return False
|
||||
|
||||
# "note down" command.
|
||||
command0 = self.config["commands"][0]
|
||||
if self.command.ident.startswith(command0):
|
||||
content = self.command.ident[len(command0):].strip()
|
||||
if self.command.ident == self.config["commands"][0]:
|
||||
content = self.command.raw[len(self.command.match):].strip()
|
||||
match = self.content_re.match(content)
|
||||
if not match:
|
||||
return False
|
||||
|
@ -59,8 +58,7 @@ class NotesPlugin(Plugin):
|
|||
return True
|
||||
|
||||
# "deliver notes for me" command.
|
||||
command1 = self.config["commands"][1]
|
||||
if self.command.ident == command1:
|
||||
if self.command.ident == self.config["commands"][1]:
|
||||
self.deliver_notes(event.target, event.source.nick)
|
||||
return True
|
||||
|
||||
|
|
|
@ -42,14 +42,12 @@ class SleepPlugin(Plugin):
|
|||
return False
|
||||
|
||||
# "sleep" command.
|
||||
command0 = self.config["commands"][0]
|
||||
if self.command.ident.startswith(command0):
|
||||
if self.command.ident == self.config["commands"][0]:
|
||||
self.fall_asleep()
|
||||
return True
|
||||
|
||||
# "wake up" command.
|
||||
command1 = self.config["commands"][1]
|
||||
if self.command.ident.startswith(command1):
|
||||
if self.command.ident == self.config["commands"][1]:
|
||||
self.wake_up()
|
||||
return True
|
||||
|
||||
|
|
Loading…
Reference in a new issue