misc_reactions: add plugin
This commit is contained in:
parent
86c2ce756a
commit
93eddad240
14
README.md
14
README.md
|
@ -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
|
||||
|
|
|
@ -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?"],
|
||||
|
|
|
@ -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 = []
|
||||
|
|
121
edmond/plugins/misc_reactions.py
Normal file
121
edmond/plugins/misc_reactions.py
Normal 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)
|
Loading…
Reference in a new issue