From 4bbe0d1c792be9a78792589455f8abc4528125c6 Mon Sep 17 00:00:00 2001 From: dece Date: Fri, 9 Oct 2020 12:49:35 +0200 Subject: [PATCH] plugin: check required configs on init --- README.md | 6 +++--- config.json.example | 16 ++++++++++++++++ edmond/bot.py | 2 +- edmond/plugin.py | 34 +++++++++++++++++++++++++--------- edmond/plugins/horoscope.py | 4 ++-- edmond/plugins/mood.py | 19 ++++++++++++------- 6 files changed, 59 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 11ef66d..219e5ce 100644 --- a/README.md +++ b/README.md @@ -8,14 +8,14 @@ New version of the infamous IRC bot. Missing features ---------------- -- [ ] Actions (/me) +- [x] Actions (/me) - [ ] Beers -- [ ] Mood +- [x] Mood - [ ] Random: dice, choice, etc - [ ] Notes - [ ] Handle compliments - [ ] Handle -- [ ] Horoscope +- [x] Horoscope - [ ] "Journee mondiale" - [ ] Mug - [ ] Music diff --git a/config.json.example b/config.json.example index 523f023..d832363 100644 --- a/config.json.example +++ b/config.json.example @@ -6,9 +6,25 @@ "channels": ["#idi0crates"], "speak_delay": 0.5, "plugins": { + "common": { + "command_suffix": "please" + }, "horoscope": { + "commands": ["horoscope"], + "meditation": "/me looks at the starts", "url": "http://zwergf.elynx.fr/bots/horobot/", "delay": 2 + }, + "mood": { + "questions": ["how are you?"], + "greetings": { + "calm": ["Hi!", "Hello!"], + "pissed": ["Pfff..."] + }, + "answer": { + "calm": "Fine!", + "pissed": "Pissed off..." + } } } } diff --git a/edmond/bot.py b/edmond/bot.py index a946c83..5d48f10 100644 --- a/edmond/bot.py +++ b/edmond/bot.py @@ -90,7 +90,7 @@ class Bot(irc.client.SimpleIRCClient, Logger): def run_plugin_callbacks(self, event): etype = event.type - for plugin in self.plugins: + for plugin in filter(lambda p: p.is_ready, self.plugins): callbacks = plugin.callbacks if etype not in callbacks: continue diff --git a/edmond/plugin.py b/edmond/plugin.py index fd130df..1934825 100644 --- a/edmond/plugin.py +++ b/edmond/plugin.py @@ -3,10 +3,13 @@ from dataclasses import dataclass class Plugin: + REQUIRED_CONFIGS = [] + def __init__(self, bot): self.bot = bot self.name = self.__class__.__name__.lower()[:-6] # Remove "Plugin". self.config = self.get_config() + self.is_ready = self.check_config() @property def callbacks(self): @@ -18,15 +21,26 @@ class Plugin: } def get_config(self): - """Return the plugin section from the bot config.""" + """Return the plugin section from the bot config, plus common values.""" plugins_configs = self.bot.config["plugins"] - return plugins_configs.get(self.name, {}) + config = plugins_configs["common"] + config.update(plugins_configs.get(self.name, {})) + return config + + def check_config(self): + """Return True if the plugin config is properly setup.""" + missing = False + for key in self.REQUIRED_CONFIGS: + if key not in self.config: + self.bot.log_w(f"Missing '{key}' in {self.name} configuration.") + missing = True + return missing - def get_runtime_value(self, key, plugin_name=None): + def get_runtime_value(self, key, ns=None): """Get a value from the plugin runtime dict.""" - if plugin_name is None: - plugin_name = self.name - return self.bot.values[self.name].get(key) + if ns is None: + ns = self.name + return self.bot.values[ns].get(key) def set_runtime_value(self, key, value): """Set a value in the plugin runtime dict.""" @@ -39,7 +53,7 @@ class Plugin: return False question = message[len(words[0]):].strip() - for q in self.QUESTIONS: + for q in self.config.get("questions", []): if question.startswith(q): self.question = Question(q, question[len(q):].strip()) return True @@ -48,7 +62,8 @@ class Plugin: def should_handle_command(self, message): """Store Command in object and return True if it should handle it.""" command = self.parse_command(message) - if command and any(c == command.ident for c in self.COMMANDS): + commands = self.config.get("commands", []) + if command and any(c == command.ident for c in commands): self.command = command return True return False @@ -56,7 +71,8 @@ class Plugin: def parse_command(self, message): """Return a command ID if this message is a command.""" words = message.split() - if words[0].lower() in self.bot.names and words[-1] == "please": + command_suffix = self.config["command_suffix"] + if words[0].lower() in self.bot.names and words[-1] == command_suffix: ident = words[1] content = " ".join(words[2:-1]) return Command(ident, content) diff --git a/edmond/plugins/horoscope.py b/edmond/plugins/horoscope.py index 67cb1f9..6c41315 100644 --- a/edmond/plugins/horoscope.py +++ b/edmond/plugins/horoscope.py @@ -6,7 +6,7 @@ from edmond.utils import http_get class HoroscopePlugin(Plugin): - COMMANDS = ["horoscope"] + REQUIRED_CONFIGS = ["commands", "meditation", "delay", "url"] def __init__(self, bot): super().__init__(bot) @@ -14,7 +14,7 @@ class HoroscopePlugin(Plugin): def on_pubmsg(self, event): if not self.should_handle_command(event.arguments[0]): return False - self.bot.say(event.target, "/me looks at the stars") + self.bot.say(event.target, self.config["meditation"]) time.sleep(self.config["delay"]) text = http_get(self.config["url"]) if text: diff --git a/edmond/plugins/mood.py b/edmond/plugins/mood.py index a6eeb28..bd0ff10 100644 --- a/edmond/plugins/mood.py +++ b/edmond/plugins/mood.py @@ -5,13 +5,13 @@ from edmond.plugin import Plugin class Mood(Enum): - CALM = 0 - PISSED = 1 + CALM = "calm" + PISSED = "pissed" class MoodPlugin(Plugin): - QUESTIONS = ["how are you?"] + REQUIRED_CONFIGS = ["questions", "greetings", "answer"] def __init__(self, bot): super().__init__(bot) @@ -20,12 +20,17 @@ class MoodPlugin(Plugin): mood = random.choice(list(Mood)) self.set_runtime_value("mood", mood) + def on_join(self, event): + mood = self.get_runtime_value("mood") + greetings = self.config["greetings"].get(mood.value) + if greetings: + self.bot.say(event.target, random.choice(greetings)) + def on_pubmsg(self, event): if not self.should_answer_question(event.arguments[0]): return False mood = self.get_runtime_value("mood") - if mood == Mood.CALM: - self.bot.say(event.target, "I'm calm.") - elif mood == Mood.PISSED: - self.bot.say(event.target, "I'm pissed off.") + answer = self.config["answer"].get(mood.value) + if answer: + self.bot.say(event.target, answer) return True