misc_reactions: add plugin

This commit is contained in:
dece 2020-11-04 22:46:09 +01:00
parent 86c2ce756a
commit 93eddad240
4 changed files with 149 additions and 8 deletions

View file

@ -44,14 +44,14 @@ Missing features
- [x] Command aliases
- [ ] Question aliases
- [x] Sleep
- [ ] Various macros:
- [ ] asks someone to stop doing something
- [ ] king of
- [ ] appreciation
- [ ] detector
- [ ] "???"
- [x] Various macros:
- [x] asks someone to stop doing something
- [x] king of
- [x] appreciation
- [x] detector
- [x] "???"
- [ ] Simple word mappings for fun
- [ ] Lyrics
- ~~[ ] Lyrics~~
- [ ] Phonétique
- [ ] Greet other people joining
- [ ] Mourn other people parting

View file

@ -20,7 +20,8 @@
"sleep": {
"awake": true
}
}
},
"question_mark": "?"
},
"compliments": {
"sentences": ["you're breathtaking"],
@ -42,6 +43,20 @@
"commands": ["journée mondiale"],
"url": "https://www.journee-mondiale.com/"
},
"miscreactions": {
"reactions": [
"stop", "king", "mmm", "ooo", "detector", "question_marks",
"repeat_letters"
],
"rate": 0,
"stop_message": "This was your last {subject}...",
"king_message": "{king} is the king of {subject}.",
"kings": ["*<B^)"],
"detector_message": "/me grabs its {subject} detector",
"detector_process": "...",
"detector_pos": "OK go on...",
"detector_neg": "Halt!"
},
"mood": {
"commands": ["calm down"],
"questions": ["how are you?"],

View file

@ -24,10 +24,15 @@ class Plugin:
on_welcome callback which is called after connecting to a server, and can
disable itself by setting its own `is_ready` flag to false.
A plugin can access its config once the base `__init__` has been called. The
configuration is valid only is `is_ready` is True, else accessing its
content is undefined behaviour.
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
- -10: lowest, e.g. for random reactions usually with a very low rate
"""
REQUIRED_CONFIGS = []

View file

@ -0,0 +1,121 @@
import random
from edmond.plugin import Plugin
from edmond.utils import proc
class MiscReactionsPlugin(Plugin):
"""This plugin implements various reactions to the last message posted.
Enable reactions you want by setting the IDs from REACTIONS in the reactions
field on the plugin configuration. As all reactions are optional,
configurations for each reactions are optional as well and can be safely
removed from the configuration (as usual except fields in REQUIRED_CONFIGS).
"""
REQUIRED_CONFIGS = ["reactions", "rate"]
REACTIONS = set([
"sentence",
"stop",
"king",
"mmm",
"ooo",
"detector",
"repeat_letters",
])
def __init__(self, bot):
super().__init__(bot)
self.priority = -10
self.reactions = self.get_reactions()
def get_reactions(self):
"""Get configured reactions in a dict mapping names to methods."""
reactions = {}
available_reactions = self.REACTIONS & set(self.config["reactions"])
for reaction in available_reactions:
reactions[reaction] = getattr(self, f"react_with_{reaction}")
return reactions
def on_pubmsg(self, event):
if proc(self.config["rate"]):
method = random.choice(list(self.reactions.values()))
method(event)
def react_with_sentence(self, event):
"""React with a random sentence from config list."""
sentences = self.config.get("sentences")
if not sentences:
return
self.bot.say(event.target, random.choice(sentences))
def react_with_stop(self, event):
"""Threaten someone that it did its last... (insert last word here)."""
stop_message = self.config.get("stop_message")
if not stop_message:
return
words = event.arguments[0].split()
if len(words) == 0:
return
self.bot.say(event.target, stop_message.format(subject=words[-1]))
def react_with_king(self, event):
"""Tell the world that some emoji is the king of the last word."""
king_message = self.config.get("king_message")
if not king_message:
return
kings = self.config.get("kings")
if not kings or len(kings) == 0:
return
words = event.arguments[0].split()
if len(words) == 0:
return
king = random.choice(kings)
reply = king_message.format(king=king, subject=words[-1])
self.bot.say(event.target, reply)
def react_with_mmm(self, event):
"""Say a mixed (mm) Skype emote."""
num_chars = random.randint(1, 8)
mmm = ""
for _ in range(num_chars):
mmm += random.choice("(mmm)")
self.bot.say(event.target, mmm)
def react_with_ooo(self, event):
"""Just yell some Os."""
self.bot.say(event.target, "O" * random.randint(1, 10))
def react_with_detector(self, event):
"""Get the last word detector and react to it."""
words = event.arguments[0].split()
if len(words) == 0:
return
detector_message = self.config.get("detector_message")
detector_process = self.config.get("detector_process")
detector_pos = self.config.get("detector_pos")
detector_neg = self.config.get("detector_neg")
if any(
s is None
for s in (detector_message, detector_process, detector_pos,
detector_neg)
):
return
self.bot.say(event.target, detector_message.format(subject=words[-1]))
self.bot.say(event.target, detector_process)
if proc(50):
self.bot.say(event.target, detector_pos)
else:
self.bot.say(event.target, detector_neg)
def react_with_repeat_letters(self, event):
"""Make sure you understood the biggest word in a stupid way."""
words = event.arguments[0].split()
if len(words) == 0:
return
biggest_word = sorted(words, key=lambda w: len(w))[-1]
word = biggest_word[:2] + biggest_word
question_mark = self.config["question_mark"]
reply = f"{word}{question_mark}"
self.bot.say(event.target, reply)