import re from edmond.plugin import Plugin class NotesPlugin(Plugin): REQUIRED_CONFIGS = [ "commands", "content_regex", "confirmation", "deliver_format", "limit", "too_many_notes", ] def __init__(self, bot): super().__init__(bot) self._content_re = None @property def content_re(self): if self._content_re is None: self._content_re = re.compile(self.config["content_regex"]) return self._content_re def on_join(self, event): nick = event.source.nick if nick == self.bot.nick: return self.deliver_notes(event.target, nick) def on_pubmsg(self, event): if not self.should_handle_command(event.arguments[0], no_content=True): return False # "note down" command. if self.command.ident == self.config["commands"][0]: content = self.command.raw[len(self.command.matched) :].strip() matched = self.content_re.match(content) if not matched: return False groups = matched.groupdict() if any(k not in groups for k in ("target", "note")): return False target = groups["target"] # Check we did not reach our note limits. if self.count_user_notes(target) >= self.config["limit"]: self.bot.say(event.target, self.config["too_many_notes"]) return True message = groups["note"] self.bot.log_d(f"Noting for {target}: {message}") note = { "sender": event.source.nick, "dest": target, "message": message, } self.append_storage_list_value("notes", note) self.bot.say(event.target, self.config["confirmation"]) return True # "deliver notes for me" command. if self.command.ident == self.config["commands"][1]: self.deliver_notes(event.target, event.source.nick) return True return False def deliver_notes(self, target, nick): """Deliver all notes for this user in the target channel/user.""" notes = self.get_storage_value("notes", []) notes = list(filter(lambda n: n["dest"] == nick, notes)) self.bot.log_d(f"Delivering {len(notes)} notes to {nick}.") for note in notes: message = self.config["deliver_format"].format( sender=note["sender"], dest=nick, message=note["message"], ) self.bot.say(target, message) self.remove_storage_list_value("notes", note) def count_user_notes(self, nick): """Count the number of undelivered notes this user has.""" notes = self.get_storage_value("notes", []) return sum(note["dest"] == nick for note in notes)