plugin: check required configs on init

This commit is contained in:
dece 2020-10-09 12:49:35 +02:00
parent dc941c1985
commit 4bbe0d1c79
6 changed files with 59 additions and 22 deletions

View file

@ -8,14 +8,14 @@ New version of the infamous IRC bot.
Missing features Missing features
---------------- ----------------
- [ ] Actions (/me) - [x] Actions (/me)
- [ ] Beers - [ ] Beers
- [ ] Mood - [x] Mood
- [ ] Random: dice, choice, etc - [ ] Random: dice, choice, etc
- [ ] Notes - [ ] Notes
- [ ] Handle compliments - [ ] Handle compliments
- [ ] Handle - [ ] Handle
- [ ] Horoscope - [x] Horoscope
- [ ] "Journee mondiale" - [ ] "Journee mondiale"
- [ ] Mug - [ ] Mug
- [ ] Music - [ ] Music

View file

@ -6,9 +6,25 @@
"channels": ["#idi0crates"], "channels": ["#idi0crates"],
"speak_delay": 0.5, "speak_delay": 0.5,
"plugins": { "plugins": {
"common": {
"command_suffix": "please"
},
"horoscope": { "horoscope": {
"commands": ["horoscope"],
"meditation": "/me looks at the starts",
"url": "http://zwergf.elynx.fr/bots/horobot/", "url": "http://zwergf.elynx.fr/bots/horobot/",
"delay": 2 "delay": 2
},
"mood": {
"questions": ["how are you?"],
"greetings": {
"calm": ["Hi!", "Hello!"],
"pissed": ["Pfff..."]
},
"answer": {
"calm": "Fine!",
"pissed": "Pissed off..."
}
} }
} }
} }

View file

@ -90,7 +90,7 @@ class Bot(irc.client.SimpleIRCClient, Logger):
def run_plugin_callbacks(self, event): def run_plugin_callbacks(self, event):
etype = event.type etype = event.type
for plugin in self.plugins: for plugin in filter(lambda p: p.is_ready, self.plugins):
callbacks = plugin.callbacks callbacks = plugin.callbacks
if etype not in callbacks: if etype not in callbacks:
continue continue

View file

@ -3,10 +3,13 @@ from dataclasses import dataclass
class Plugin: class Plugin:
REQUIRED_CONFIGS = []
def __init__(self, bot): def __init__(self, bot):
self.bot = bot self.bot = bot
self.name = self.__class__.__name__.lower()[:-6] # Remove "Plugin". self.name = self.__class__.__name__.lower()[:-6] # Remove "Plugin".
self.config = self.get_config() self.config = self.get_config()
self.is_ready = self.check_config()
@property @property
def callbacks(self): def callbacks(self):
@ -18,15 +21,26 @@ class Plugin:
} }
def get_config(self): 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"] 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 get_runtime_value(self, key, plugin_name=None): 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, ns=None):
"""Get a value from the plugin runtime dict.""" """Get a value from the plugin runtime dict."""
if plugin_name is None: if ns is None:
plugin_name = self.name ns = self.name
return self.bot.values[self.name].get(key) return self.bot.values[ns].get(key)
def set_runtime_value(self, key, value): def set_runtime_value(self, key, value):
"""Set a value in the plugin runtime dict.""" """Set a value in the plugin runtime dict."""
@ -39,7 +53,7 @@ class Plugin:
return False return False
question = message[len(words[0]):].strip() question = message[len(words[0]):].strip()
for q in self.QUESTIONS: for q in self.config.get("questions", []):
if question.startswith(q): if question.startswith(q):
self.question = Question(q, question[len(q):].strip()) self.question = Question(q, question[len(q):].strip())
return True return True
@ -48,7 +62,8 @@ class Plugin:
def should_handle_command(self, message): def should_handle_command(self, message):
"""Store Command in object and return True if it should handle it.""" """Store Command in object and return True if it should handle it."""
command = self.parse_command(message) 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 self.command = command
return True return True
return False return False
@ -56,7 +71,8 @@ class Plugin:
def parse_command(self, message): def parse_command(self, message):
"""Return a command ID if this message is a command.""" """Return a command ID if this message is a command."""
words = message.split() 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] ident = words[1]
content = " ".join(words[2:-1]) content = " ".join(words[2:-1])
return Command(ident, content) return Command(ident, content)

View file

@ -6,7 +6,7 @@ from edmond.utils import http_get
class HoroscopePlugin(Plugin): class HoroscopePlugin(Plugin):
COMMANDS = ["horoscope"] REQUIRED_CONFIGS = ["commands", "meditation", "delay", "url"]
def __init__(self, bot): def __init__(self, bot):
super().__init__(bot) super().__init__(bot)
@ -14,7 +14,7 @@ class HoroscopePlugin(Plugin):
def on_pubmsg(self, event): def on_pubmsg(self, event):
if not self.should_handle_command(event.arguments[0]): if not self.should_handle_command(event.arguments[0]):
return False 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"]) time.sleep(self.config["delay"])
text = http_get(self.config["url"]) text = http_get(self.config["url"])
if text: if text:

View file

@ -5,13 +5,13 @@ from edmond.plugin import Plugin
class Mood(Enum): class Mood(Enum):
CALM = 0 CALM = "calm"
PISSED = 1 PISSED = "pissed"
class MoodPlugin(Plugin): class MoodPlugin(Plugin):
QUESTIONS = ["how are you?"] REQUIRED_CONFIGS = ["questions", "greetings", "answer"]
def __init__(self, bot): def __init__(self, bot):
super().__init__(bot) super().__init__(bot)
@ -20,12 +20,17 @@ class MoodPlugin(Plugin):
mood = random.choice(list(Mood)) mood = random.choice(list(Mood))
self.set_runtime_value("mood", 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): def on_pubmsg(self, event):
if not self.should_answer_question(event.arguments[0]): if not self.should_answer_question(event.arguments[0]):
return False return False
mood = self.get_runtime_value("mood") mood = self.get_runtime_value("mood")
if mood == Mood.CALM: answer = self.config["answer"].get(mood.value)
self.bot.say(event.target, "I'm calm.") if answer:
elif mood == Mood.PISSED: self.bot.say(event.target, answer)
self.bot.say(event.target, "I'm pissed off.")
return True return True