Example #1
0
    def test_process_returns_unicode(self):
        plugin = Mock()
        plugin.process.return_value = ['foo', 'bar', self.snowman]

        with patch.object(registry, 'prioritized') as prio:
            prio.return_value = [plugin]
            responses = registry.process('', '', '', '')
            assert all(map(lambda x: isinstance(x, unicode), responses))
Example #2
0
    def test_process_ignores_exception(self):
        settings.PLUGIN_FIRST_RESPONDER_ONLY = True
        things = [Mock(), Mock()]

        # Make the middle one raise
        things[0].process.side_effect = Exception
        things[1].process.return_value = 'foo'

        with patch.object(registry, 'prioritized') as prio:
            prio.return_value = things
            response = registry.process(None, '#bots', 'me', 'foobar')
            assert response == [u'foo']
Example #3
0
    def test_process_ignores_exception(self):
        settings.PLUGIN_FIRST_RESPONDER_ONLY = True
        things = [Mock(), Mock()]

        # Make the middle one raise
        things[0].process.side_effect = Exception
        things[1].process.return_value = 'foo'

        with patch.object(registry, 'prioritized') as prio:
            prio.return_value = things
            response = registry.process(None, '#bots', 'me', 'foobar')
            assert response == [u'foo']
Example #4
0
    def test_process_returns_first_response(self):
        settings.PLUGIN_FIRST_RESPONDER_ONLY = True
        things = [Mock(), Mock(), Mock()]

        # Make the middle one raise
        things[0].process.return_value = ['foo', 'bar', None]
        things[1].process.return_value = self.snowman
        things[2].process.return_value = 'baz'

        with patch.object(registry, 'prioritized') as prio:
            prio.return_value = things
            response = registry.process(None, '#bots', 'me', 'foobar')
            assert response == [u'foo', u'bar']
Example #5
0
    def test_process_stops_when_async(self):
        things = [Mock(), Mock(), Mock()]

        # Make the middle one raise
        things[0].process.return_value = None
        things[1].process.side_effect = ResponseNotReady
        things[2].process.return_value = None

        with patch.object(registry, 'prioritized') as prio:
            prio.return_value = things
            assert [] == registry.process(None, '#bots', 'me', 'foobar')
            assert things[1].process.called
            assert not things[2].process.called
Example #6
0
    def test_process_stops_when_async(self):
        things = [Mock(), Mock(), Mock()]

        # Make the middle one raise
        things[0].process.return_value = None
        things[1].process.side_effect = ResponseNotReady
        things[2].process.return_value = None

        with patch.object(registry, 'prioritized') as prio:
            prio.return_value = things
            assert [] == registry.process(None, '#bots', 'me', 'foobar')
            assert things[1].process.called
            assert not things[2].process.called
Example #7
0
    def test_process_returns_first_response(self):
        settings.PLUGIN_FIRST_RESPONDER_ONLY = True
        things = [Mock(), Mock(), Mock()]

        # Make the middle one raise
        things[0].process.return_value = ['foo', 'bar', None]
        things[1].process.return_value = self.snowman
        things[2].process.return_value = 'baz'

        with patch.object(registry, 'prioritized') as prio:
            prio.return_value = things
            response = registry.process(None, '#bots', 'me', 'foobar')
            assert response == [u'foo', u'bar']
Example #8
0
    def on_message(self, element):
        """
        Handler for an XMPP message. This method handles logging channel messages (if it occurs
        on a public channel) as well as allowing the plugin manager to send the message to all
        registered plugins. Should the plugin manager yield a response, it will be sent back.

        :param message: A <message/> element, instance of `twisted.words.xish.domish.Element`
        """
        nick = self.parse_nick(element)
        channel = self.parse_channel(element)
        message = self.parse_message(element)

        # This will be empty for messages that were delayed
        if not message:
            return

        # If we don't ignore this, we'll get infinite replies
        if nick == self.nickname:
            return

        # Log the incoming message and notify message subscribers
        logger.debug('[<--] %s/%s - %s', channel, nick, message)
        is_public = self.is_public_channel(channel)

        # When we get a priv msg, the channel is our current nick, so we need to
        # respond to the user that is talking to us
        if is_public:
            # Only log convos on public channels
            self.log_channel_message(channel, nick, message)
        else:
            channel = nick

        # Some things should go first
        try:
            channel, nick, message = registry.preprocess(
                self, channel, nick, message)
        except (TypeError, ValueError):
            pass

        # if not message.has_response:
        responses = registry.process(self, channel, nick, message)

        if responses:
            message = u'\n'.join(responses)
            self.msg(channel, message)

            if is_public:
                self.log_channel_message(channel, self.nickname, message)

        # Update last message
        self.last_message[channel][nick] = message
Example #9
0
    def on_message(self, element):
        """
        Handler for an XMPP message. This method handles logging channel messages (if it occurs
        on a public channel) as well as allowing the plugin manager to send the message to all
        registered plugins. Should the plugin manager yield a response, it will be sent back.

        :param message: A <message/> element, instance of `twisted.words.xish.domish.Element`
        """
        nick = self.parse_nick(element)
        channel = self.parse_channel(element)
        message = self.parse_message(element)

        # This will be empty for messages that were delayed
        if not message:
            return

        # If we don't ignore this, we'll get infinite replies
        if nick == self.nickname:
            return

        # Log the incoming message and notify message subscribers
        logger.debug('[<--] %s/%s - %s', channel, nick, message)
        is_public = self.is_public_channel(channel)

        # When we get a priv msg, the channel is our current nick, so we need to
        # respond to the user that is talking to us
        if is_public:
            # Only log convos on public channels
            self.log_channel_message(channel, nick, message)
        else:
            channel = nick

        # Some things should go first
        try:
            channel, nick, message = registry.preprocess(self, channel, nick, message)
        except (TypeError, ValueError):
            pass

        # if not message.has_response:
        responses = registry.process(self, channel, nick, message)

        if responses:
            message = u'\n'.join(responses)
            self.msg(channel, message)

            if is_public:
                self.log_channel_message(channel, self.nickname, message)

        # Update last message
        self.last_message[channel][nick] = message
Example #10
0
    def test_process_async_honors_first_response(self):
        things = [Mock(), Mock(), Mock()]

        # Make the middle one raise
        things[0].process.side_effect = ResponseNotReady
        things[1].process.return_value = None
        things[2].process.return_value = None

        with patch.object(registry, 'prioritized') as prio:
            with patch.object(settings, 'PLUGIN_FIRST_RESPONDER_ONLY', True):
                prio.return_value = things
                assert [] == registry.process(None, '#bots', 'me', 'foobar')
                assert things[0].process.called
                assert not things[1].process.called
                assert not things[2].process.called
Example #11
0
    def test_process_async_honors_all_responses(self):
        things = [Mock(), Mock(), Mock()]

        # Make the middle one raise
        things[0].process.return_value = None
        things[1].process.side_effect = ResponseNotReady
        things[2].process.return_value = None

        with patch.object(registry, 'prioritized') as prio:
            with patch.object(settings, 'PLUGIN_FIRST_RESPONDER_ONLY', False):
                prio.return_value = things
                assert [] == registry.process(None, '#bots', 'me', 'foobar')
                assert things[0].process.called
                assert things[1].process.called
                assert things[2].process.called
Example #12
0
    def privmsg(self, user, channel, message):
        """
        Handler for an IRC message. This method handles logging channel messages (if it occurs
        on a public channel) as well as allowing the plugin manager to send the message to all
        registered plugins. Should the plugin manager yield a response, it will be sent back
        over IRC.

        :param user: IRC user string of the form ``{nick}!~{user}@{host}``
        :param channel: the channel from which the message came
        :param message: the message contents
        """
        user = self.parse_nick(user)
        message = message.strip()

        # Log the incoming message and notify message subscribers
        logger.debug('[<--] %s/%s - %s', channel, user, message)
        is_public = self.is_public_channel(channel)

        # When we get a priv msg, the channel is our current nick, so we need to
        # respond to the user that is talking to us
        if is_public:
            # Only log convos on public channels
            self.log_channel_message(channel, user, message)
        else:
            channel = user

        # Some things should go first
        try:
            channel, user, message = registry.preprocess(
                self, channel, user, message)
        except (TypeError, ValueError):
            pass

        # if not message.has_response:
        responses = registry.process(self, channel, user, message)

        if responses:
            message = u'\n'.join(responses)
            self.msg(channel, message)

            if is_public:
                self.log_channel_message(channel, self.nickname, message)

        # Update last message
        self.last_message[channel][user] = message
Example #13
0
File: irc.py Project: bigjust/helga
    def privmsg(self, user, channel, message):
        """
        Handler for an IRC message. This method handles logging channel messages (if it occurs
        on a public channel) as well as allowing the plugin manager to send the message to all
        registered plugins. Should the plugin manager yield a response, it will be sent back
        over IRC.

        :param user: IRC user string of the form ``{nick}!~{user}@{host}``
        :param channel: the channel from which the message came
        :param message: the message contents
        """
        user = self.parse_nick(user)
        message = message.strip()

        # Log the incoming message and notify message subscribers
        logger.debug('[<--] %s/%s - %s', channel, user, message)
        is_public = self.is_public_channel(channel)

        # When we get a priv msg, the channel is our current nick, so we need to
        # respond to the user that is talking to us
        if is_public:
            # Only log convos on public channels
            self.log_channel_message(channel, user, message)
        else:
            channel = user

        # Some things should go first
        try:
            channel, user, message = registry.preprocess(self, channel, user, message)
        except (TypeError, ValueError):
            pass

        # if not message.has_response:
        responses = registry.process(self, channel, user, message)

        if responses:
            message = u'\n'.join(responses)
            self.msg(channel, message)

            if is_public:
                self.log_channel_message(channel, self.nickname, message)

        # Update last message
        self.last_message[channel][user] = message
Example #14
0
    def slack_message(self, data):
        """
        Handler for an incoming Slack message event. This method allows the
        plugin manager to send the message to all registered plugins. Should
        the plugin manager yield a response, it will be sent back over Slack.

        :param data: dict from JSON received in WebSocket message
        """
        # Look up the human-readable name for this user ID.
        user = self._get_user_name(data['user'])

        # If we don't ignore this, we'll get infinite replies
        if user == self.nickname:
            return

        channel = self._get_channel_name(data['channel'])

        if channel:
            # If this was a legit channel, prefix it with a hash for later consistency
            channel = u'#{}'.format(channel)

        # I'm not sure if 100% of all messages have a "text" value. Use a blank
        # string fallback to be safe.
        message = data.get('text', '')

        message = self._parse_incoming_message(message)

        # Log the incoming message
        logger.debug('[<--] %s/%s - %s', channel, user, message)

        # Some things should go first
        try:
            channel, user, message = registry.preprocess(
                self, channel, user, message)
        except (TypeError, ValueError):
            pass

        # Update last message
        self.last_message[channel][user] = message

        responses = registry.process(self, channel, user, message)

        if responses:
            return self.msg(channel, u'\n'.join(responses))
Example #15
0
    def slack_message(self, data):
        """
        Handler for an incoming Slack message event. This method allows the
        plugin manager to send the message to all registered plugins. Should
        the plugin manager yield a response, it will be sent back over Slack.

        :param data: dict from JSON received in WebSocket message
        """
        # Look up the human-readable name for this user ID.
        user = self._get_user_name(data['user'])

        # If we don't ignore this, we'll get infinite replies
        if user == self.nickname:
            return

        channel = self._get_channel_name(data['channel'])

        if channel:
            # If this was a legit channel, prefix it with a hash for later consistency
            channel = u'#{}'.format(channel)

        # I'm not sure if 100% of all messages have a "text" value. Use a blank
        # string fallback to be safe.
        message = data.get('text', '')

        message = self._parse_incoming_message(message)

        # Log the incoming message
        logger.debug('[<--] %s/%s - %s', channel, user, message)

        # Some things should go first
        try:
            channel, user, message = registry.preprocess(self, channel, user, message)
        except (TypeError, ValueError):
            pass

        # Update last message
        self.last_message[channel][user] = message

        responses = registry.process(self, channel, user, message)

        if responses:
            return self.msg(channel, u'\n'.join(responses))