Example #1
0
    def test_access(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.assertIn("__end__", hm._access())
        self.assertIn("__end__", hm._access("pre"))
        self.assertIn("__end__", hm._access("pre", "Text"))
        self.assertIn("__end__", hm._access("post", "Text"))

        self.assertFalse(hm._access("inexistant")["__end__"])
        self.assertTrue(hm._access()["__end__"])
        self.assertTrue(hm._access("pre")["__end__"])
        self.assertTrue(hm._access("pre", "Text")["__end__"])
        self.assertTrue(hm._access("post", "Text")["__end__"])
Example #2
0
    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)])
Example #3
0
    def test_delete(self):
        hm = HooksManager()

        h1 = "HOOK1"
        h2 = "HOOK2"
        h3 = "HOOK3"
        h4 = "HOOK4"

        hm.add_hook(h1)
        hm.add_hook(h2, "pre")
        hm.add_hook(h3, "pre", "Text")
        hm.add_hook(h2, "post", "Text")

        hm.del_hooks(hook=h4)

        self.assertTrue(hm._access("pre")["__end__"])
        self.assertTrue(hm._access("pre", "Text")["__end__"])
        hm.del_hooks("pre")
        self.assertFalse(hm._access("pre")["__end__"])

        self.assertTrue(hm._access("post", "Text")["__end__"])
        hm.del_hooks("post", "Text", hook=h2)
        self.assertFalse(hm._access("post", "Text")["__end__"])

        self.assertTrue(hm._access()["__end__"])
        hm.del_hooks(hook=h1)
        self.assertFalse(hm._access()["__end__"])
Example #4
0
    def test_get(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([h1, h2], [h for h in hm.get_hooks("pre")])
        self.assertEqual([h1, h2, h3], [h for h in hm.get_hooks("pre", "Text")])
Example #5
0
    def test_search(self):
        hm = HooksManager()

        h1 = "HOOK1"
        h2 = "HOOK2"
        h3 = "HOOK3"
        h4 = "HOOK4"

        hm.add_hook(h1)
        hm.add_hook(h2, "pre")
        hm.add_hook(h3, "pre", "Text")
        hm.add_hook(h2, "post", "Text")

        self.assertTrue([h for h in hm._search(h1)])
        self.assertFalse([h for h in hm._search(h4)])
        self.assertEqual(2, len([h for h in hm._search(h2)]))
        self.assertEqual([("pre", "Text")], [h for h in hm._search(h3)])
Example #6
0
 def __init__(self):
     from nemubot.hooks.manager import HooksManager
     self.hm = HooksManager()
Example #7
0
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
Example #8
0
 def __init__(self):
     from nemubot.hooks.manager import HooksManager
     self.hm = HooksManager()
Example #9
0
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