plugin: handle aliases for commands

master
dece 4 years ago
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}.")
return True
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…
Cancel
Save