diff --git a/edmond/plugin.py b/edmond/plugin.py index de65b13..baf0f71 100644 --- a/edmond/plugin.py +++ b/edmond/plugin.py @@ -3,6 +3,32 @@ from pathlib import Path class Plugin: + """Base class for the bot plugins. + + This class provides a lot of tools to facilitate the implementation of + plugins. Callbacks for all events handled by the IRC library can be + implemented here (if the Bot class supports it). Most bot features are put + in plugins to avoid cluttering the Bot class, and no plugins should be + required for the bot to run; plugins can depend on each other though. + + A plugin loads his basic information from the config file. It can use the + bot's runtime values facilities to make runtime values available to other + plugins. It can also save data using the Bot's storage feature to be + available after a restart. + + Initalisation should be very fast, no network connections or anything. They + are initialised before connecting to the server, so their `is_ready` flag is + set at that point. The loading order is more or less random, so a plugin + cannot assume another has been loaded during initialisation. If it wants to + interact with another plugin, the earliest point to do that is in the + on_welcome callback which is called after connecting to a server, and can + disable itself by setting its own `is_ready` flag to false. + + Plugins can have priorities and calling their callbacks will respect it. + For now these levels are used: + - 0: default + - -3: low, misc parsing of messages, answer to various messages + """ REQUIRED_CONFIGS = [] @@ -109,7 +135,14 @@ class Plugin: return first_word_and_rest[1].strip() def should_answer_question(self, message): - """Store Question in object and return True if it should answer it.""" + """Store Question in object and return True if I should answer it. + + To answer a question, the message must start with one of the bot's names + and optionally end with one or more question marks (they are discarded). + The bot checks that answering conditions are respected, and they cannot + be bypassed as with commands. A Question created is checked from the + plugin's registered questions and stored in the instance. + """ words = message.split() # Is the message addressed to me? if len(words) == 0 or words[0].lower() not in self.bot.names: @@ -139,7 +172,7 @@ class Plugin: no_content=False, exclude_conditions=None, ): - """Store Command in object and return True if it should handle it. + """Store Command in object and return True if I should handle it. If no_content is True, the command does not parse command contents and put all the command message (without suffix) to the command identifier. @@ -193,10 +226,10 @@ class Plugin: return False def __parse_command(self, message, no_content=False): - """Return a command ID if this message is a command. + """Return a parsed Command if this message is a command, None otherwise. 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 + empty when no_content is True. The match field is never set by this method. """ words = message.split()