def test_get_rev(self): hm = HooksManager() h1 = "HOOK1" h2 = "HOOK2" h3 = "HOOK3" hm.add_hook(h1) hm.add_hook(h2, "pre") hm.add_hook(h3, "pre", "Text") hm.add_hook(h2, "post", "Text") self.assertEqual([h2, h3], [h for h in hm.get_reverse_hooks("pre")]) self.assertEqual([h3], [h for h in hm.get_reverse_hooks("pre", exclude_first=True)])
class MessageTreater: """Treat a message""" def __init__(self): from nemubot.hooks.manager import HooksManager self.hm = HooksManager() def treat_msg(self, msg): """Treat a given message Arguments: msg -- the message to treat """ try: handled = False # Run pre-treatment: from Message to [ Message ] msg_gen = self._pre_treat(msg) m = next(msg_gen, None) # Run in-treatment: from Message to [ Response ] while m is not None: hook_gen = self._in_hooks(m) hook = next(hook_gen, None) if hook is not None: handled = True for response in self._in_treat(m, hook, hook_gen): # Run post-treatment: from Response to [ Response ] yield from self._post_treat(response) m = next(msg_gen, None) if not handled: for m in self._in_miss(msg): yield from self._post_treat(m) except BaseException as e: logger.exception("Error occurred during the processing of the %s: " "%s", type(msg).__name__, msg) from nemubot.message import Text yield from self._post_treat(Text("Sorry, an error occured (%s). Feel free to open a new issue at https://github.com/nemunaire/nemubot/issues/new" % type(e).__name__, to=msg.to_response)) def _pre_treat(self, msg): """Modify input Messages Arguments: msg -- message to treat """ for h in self.hm.get_hooks("pre", type(msg).__name__): if h.can_read(msg.to, msg.server) and h.match(msg): for res in flatify(h.run(msg)): if res is not None and res != msg: yield from self._pre_treat(res) elif res is None or res is False: break else: yield msg def _in_hooks(self, msg): for h in self.hm.get_hooks("in", type(msg).__name__): if h.can_read(msg.to, msg.server) and h.match(msg): yield h def _in_treat(self, msg, hook, hook_gen): """Treats Messages and returns Responses Arguments: msg -- message to treat """ if hasattr(msg, "frm_owner"): msg.frm_owner = (not hasattr(msg.server, "owner") or msg.server.owner == msg.frm) while hook is not None: for res in flatify(hook.run(msg)): if not hasattr(res, "server") or res.server is None: res.server = msg.server yield res hook = next(hook_gen, None) def _in_miss(self, msg): from nemubot.message.command import Command as CommandMessage from nemubot.message.directask import DirectAsk as DirectAskMessage if isinstance(msg, CommandMessage): from nemubot.hooks import Command as CommandHook from nemubot.tools.human import guess hooks = self.hm.get_reverse_hooks("in", type(msg).__name__) suggest = [s for s in guess(msg.cmd, [h.name for h in hooks if isinstance(h, CommandHook) and h.name is not None])] if len(suggest) >= 1: yield DirectAskMessage(msg.frm, "Unknown command %s. Would you mean: %s?" % (msg.cmd, ", ".join(suggest)), to=msg.to_response) elif isinstance(msg, DirectAskMessage): yield DirectAskMessage(msg.frm, "Sorry, I'm just a bot and your sentence is too complex for me :( But feel free to teach me some tricks at https://github.com/nemunaire/nemubot/!", to=msg.to_response) def _post_treat(self, msg): """Modify output Messages Arguments: msg -- response to treat """ for h in self.hm.get_hooks("post", type(msg).__name__): if h.can_write(msg.to, msg.server) and h.match(msg): for res in flatify(h.run(msg)): if res is not None and res != msg: yield from self._post_treat(res) elif res is None or res is False: break else: yield msg
class MessageTreater: """Treat a message""" def __init__(self): from nemubot.hooks.manager import HooksManager self.hm = HooksManager() def treat_msg(self, msg): """Treat a given message Arguments: msg -- the message to treat """ try: handled = False # Run pre-treatment: from Message to [ Message ] msg_gen = self._pre_treat(msg) m = next(msg_gen, None) # Run in-treatment: from Message to [ Response ] while m is not None: hook_gen = self._in_hooks(m) hook = next(hook_gen, None) if hook is not None: handled = True for response in self._in_treat(m, hook, hook_gen): # Run post-treatment: from Response to [ Response ] yield from self._post_treat(response) m = next(msg_gen, None) if not handled: for m in self._in_miss(msg): yield from self._post_treat(m) except BaseException as e: logger.exception( "Error occurred during the processing of the %s: " "%s", type(msg).__name__, msg) from nemubot.message import Text yield from self._post_treat( Text( "Sorry, an error occured (%s). Feel free to open a new issue at https://github.com/nemunaire/nemubot/issues/new" % type(e).__name__, to=msg.to_response)) def _pre_treat(self, msg): """Modify input Messages Arguments: msg -- message to treat """ for h in self.hm.get_hooks("pre", type(msg).__name__): if h.can_read(msg.to, msg.server) and h.match(msg): for res in flatify(h.run(msg)): if res is not None and res != msg: yield from self._pre_treat(res) elif res is None or res is False: break else: yield msg def _in_hooks(self, msg): for h in self.hm.get_hooks("in", type(msg).__name__): if h.can_read(msg.to, msg.server) and h.match(msg): yield h def _in_treat(self, msg, hook, hook_gen): """Treats Messages and returns Responses Arguments: msg -- message to treat """ if hasattr(msg, "frm_owner"): msg.frm_owner = (not hasattr(msg.server, "owner") or msg.server.owner == msg.frm) while hook is not None: for res in flatify(hook.run(msg)): if not hasattr(res, "server") or res.server is None: res.server = msg.server yield res hook = next(hook_gen, None) def _in_miss(self, msg): from nemubot.message.command import Command as CommandMessage from nemubot.message.directask import DirectAsk as DirectAskMessage if isinstance(msg, CommandMessage): from nemubot.hooks import Command as CommandHook from nemubot.tools.human import guess hooks = self.hm.get_reverse_hooks("in", type(msg).__name__) suggest = [ s for s in guess(msg.cmd, [ h.name for h in hooks if isinstance(h, CommandHook) and h.name is not None ]) ] if len(suggest) >= 1: yield DirectAskMessage( msg.frm, "Unknown command %s. Would you mean: %s?" % (msg.cmd, ", ".join(suggest)), to=msg.to_response) elif isinstance(msg, DirectAskMessage): yield DirectAskMessage( msg.frm, "Sorry, I'm just a bot and your sentence is too complex for me :( But feel free to teach me some tricks at https://github.com/nemunaire/nemubot/!", to=msg.to_response) def _post_treat(self, msg): """Modify output Messages Arguments: msg -- response to treat """ for h in self.hm.get_hooks("post", type(msg).__name__): if h.can_write(msg.to, msg.server) and h.match(msg): for res in flatify(h.run(msg)): if res is not None and res != msg: yield from self._post_treat(res) elif res is None or res is False: break else: yield msg