Beispiel #1
0
    def __init__(self, nick, connections, *args, **kwargs):
        """
        acts as a connection manager, middle man for incoming events, and processor of outgoing actions.
        """
        #TODO: maybe support a custom internal key to keep track of bots, not just by 'name'...
        #TODO: if we do it by name, make sure we don't have name dupes, even between networks :-/

        # bot id
        self.nick = nick
        self.id = str(uuid.uuid1())
        self.log = logging.getLogger('{0}.{1}.{2}'.format(
            self.__class__.__module__, self.__class__.__name__, self.nick))
        self.log.info('starting bot')

        #bot manager instance
        self.bot_manager = None

        # setup this bots event queue / consumer, action queue/consumer
        self.event_queue = defer.DeferredQueue()
        self._consume_events(self.event_queue)

        self.action_queue = defer.DeferredQueue()
        self._consume_actions(self.action_queue)

        # setup plugins
        self.enabled_plugins = kwargs.get('enabled_plugins')
        self.plugin_manager = PluginManager(bot=self)
        # self.manager.config.PLUGINS:

        # build connections
        # TODO: create connection manager
        self.connection_manager = ConnectionManager(config=connections,
                                                    bot=self)
        self.log.debug('connections on {0!r}: {1!r}'.format(
            self.nick, self.connection_manager))

        # should have a 'ready' state that we should check before starting?
        self.state = OFF
        self.party_line = None
Beispiel #2
0
    def __init__(self, nick, connections, *args, **kwargs):
        """
        acts as a connection manager, middle man for incoming events, and processor of outgoing actions.
        """
        #TODO: maybe support a custom internal key to keep track of bots, not just by 'name'...
        #TODO: if we do it by name, make sure we don't have name dupes, even between networks :-/

        # bot id
        self.nick = nick
        self.id = str(uuid.uuid1())
        self.log = logging.getLogger('{0}.{1}.{2}'.format(self.__class__.__module__, self.__class__.__name__,
                                                          self.nick))
        self.log.info('starting bot')

        #bot manager instance
        self.bot_manager = None

        # setup this bots event queue / consumer, action queue/consumer
        self.event_queue = defer.DeferredQueue()
        self._consume_events(self.event_queue)

        self.action_queue = defer.DeferredQueue()
        self._consume_actions(self.action_queue)

        # setup plugins
        self.enabled_plugins = kwargs.get('enabled_plugins')
        self.plugin_manager = PluginManager(bot=self)
        # self.manager.config.PLUGINS:

        # build connections
        # TODO: create connection manager
        self.connection_manager = ConnectionManager(config=connections, bot=self)
        self.log.debug('connections on {0!r}: {1!r}'.format(self.nick, self.connection_manager))

        # should have a 'ready' state that we should check before starting?
        self.state = OFF
        self.party_line = None
Beispiel #3
0
class Bot(object):
    def __init__(self, nick, connections, *args, **kwargs):
        """
        acts as a connection manager, middle man for incoming events, and processor of outgoing actions.
        """
        #TODO: maybe support a custom internal key to keep track of bots, not just by 'name'...
        #TODO: if we do it by name, make sure we don't have name dupes, even between networks :-/

        # bot id
        self.nick = nick
        self.id = str(uuid.uuid1())
        self.log = logging.getLogger('{0}.{1}.{2}'.format(
            self.__class__.__module__, self.__class__.__name__, self.nick))
        self.log.info('starting bot')

        #bot manager instance
        self.bot_manager = None

        # setup this bots event queue / consumer, action queue/consumer
        self.event_queue = defer.DeferredQueue()
        self._consume_events(self.event_queue)

        self.action_queue = defer.DeferredQueue()
        self._consume_actions(self.action_queue)

        # setup plugins
        self.enabled_plugins = kwargs.get('enabled_plugins')
        self.plugin_manager = PluginManager(bot=self)
        # self.manager.config.PLUGINS:

        # build connections
        # TODO: create connection manager
        self.connection_manager = ConnectionManager(config=connections,
                                                    bot=self)
        self.log.debug('connections on {0!r}: {1!r}'.format(
            self.nick, self.connection_manager))

        # should have a 'ready' state that we should check before starting?
        self.state = OFF
        self.party_line = None

    def __repr__(self):
        return '<{0}: {1!r} ({2!s})>'.format(self.__class__.__name__,
                                             self.nick, self.id)

    def __str__(self):
        return repr(self)

    # CORE

    def start(self):
        #TODO: catch failures?
        #TODO: pass enabled plugins
        self.plugin_manager.start(self.enabled_plugins)
        self.connection_manager.connect()
        self.state = ON

    # review
    def stop(self):
        """
        TODO: placeholder
        """
        if self.state >= ON:
            self.state = OFF

    # review
    def pause(self):
        """
        placeholder
        """
        pass

    def default_destination(self):
        """
        if no destination room is defined, and no event triggered an action, determine where to send results

        NOTE: for now send everywhere...
        """
        pass

    # EVENT QUEUE
    # default event consumer queue.
    def _consume_events(self, queue):
        def consumer(event):
            # check if Event, else try to make it one
            if not isinstance(event, Event):
                try:
                    event = self.build_event(event)
                except Exception as e:
                    self.log.exception(
                        'unable to parse data to Event, {0!r}: {1!r}'.format(
                            event, e))
                    event = None

            if event is not None:
                self.log.debug('EVENT on {0!r} {1!r}'.format(self, event))
                responses = self.plugin_manager.process_event(event)
                # this is going to be a list of deferreds,
                # TODO: should probably do this differently
                #self.log.debug('HERE: {0!r}'.format(responses))
                for response in responses:
                    #self.log.debug('adding response router')
                    response.addCallback(self.route_response, event)

            queue.get().addCallback(consumer)

        queue.get().addCallback(consumer)

    def new_event(self, event):
        """
        this is what protocol backends call when they get an event.
        """
        self.event_queue.put(event)

    def build_event(self, event_data):
        #todo: needs to be safe
        try:
            e = Event(source_bot=self, raw_details=event_data)
        except Exception as e:
            self.log.exception(
                'failed to build event from {0!r}: {1!r}'.format(
                    event_data, e))
        else:
            return e

    # ACTION QUEUE
    # default action consumer
    def _consume_actions(self, queue):
        def consumer(action):
            # check if Action, else try to make it one
            if not isinstance(action, Action):
                try:
                    action = self.build_action(action)
                except Exception as e:
                    self.log.exception(
                        'unable to build Action with {0!r}: {1!r}'.format(
                            action, e))

            if action is not None:
                res = defer.maybeDeferred(self.process_action, action)

            queue.get().addCallback(consumer)

        queue.get().addCallback(consumer)

    def build_action(self, action_data, event=None):
        if type(action_data) in (str, unicode):
            try:
                a = Action(source_bot=self,
                           source_event=event).msg(action_data)
            except Exception as e:
                self.log.exception(
                    'failed to build action from {0!r}, for {1!r}: {2!r}'.
                    format(action_data, event, e))
            else:
                return a

    # PLUGIN SYSTEM #################################################
    def route_response(self, response, event):
        if response is not None:
            self.log.debug('got {0!r} from {1!r}'.format(response, event))
            #TODO: update to actually route to correct bot, for now we just assume its ours
            if isinstance(response, Action):
                self.action_queue.put(response)
            else:
                self.log.error('got invalid response type')

    def process_action(self, action):
        #self.log.debug('routing response: {0}'.format(action))
        self.connection_manager.route_action(action)
Beispiel #4
0
class Bot(object):
    def __init__(self, nick, connections, *args, **kwargs):
        """
        acts as a connection manager, middle man for incoming events, and processor of outgoing actions.
        """
        #TODO: maybe support a custom internal key to keep track of bots, not just by 'name'...
        #TODO: if we do it by name, make sure we don't have name dupes, even between networks :-/

        # bot id
        self.nick = nick
        self.id = str(uuid.uuid1())
        self.log = logging.getLogger('{0}.{1}.{2}'.format(self.__class__.__module__, self.__class__.__name__,
                                                          self.nick))
        self.log.info('starting bot')

        #bot manager instance
        self.bot_manager = None

        # setup this bots event queue / consumer, action queue/consumer
        self.event_queue = defer.DeferredQueue()
        self._consume_events(self.event_queue)

        self.action_queue = defer.DeferredQueue()
        self._consume_actions(self.action_queue)

        # setup plugins
        self.enabled_plugins = kwargs.get('enabled_plugins')
        self.plugin_manager = PluginManager(bot=self)
        # self.manager.config.PLUGINS:

        # build connections
        # TODO: create connection manager
        self.connection_manager = ConnectionManager(config=connections, bot=self)
        self.log.debug('connections on {0!r}: {1!r}'.format(self.nick, self.connection_manager))

        # should have a 'ready' state that we should check before starting?
        self.state = OFF
        self.party_line = None

    def __repr__(self):
        return '<{0}: {1!r} ({2!s})>'.format(self.__class__.__name__, self.nick, self.id)

    def __str__(self):
        return repr(self)

    # CORE

    def start(self):
        #TODO: catch failures?
        #TODO: pass enabled plugins
        self.plugin_manager.start(self.enabled_plugins)
        self.connection_manager.connect()
        self.state = ON

    # review
    def stop(self):
        """
        TODO: placeholder
        """
        if self.state >= ON:
            self.state = OFF

    # review
    def pause(self):
        """
        placeholder
        """
        pass

    def default_destination(self):
        """
        if no destination room is defined, and no event triggered an action, determine where to send results

        NOTE: for now send everywhere...
        """
        pass

    # EVENT QUEUE
    # default event consumer queue.
    def _consume_events(self, queue):
        def consumer(event):
            # check if Event, else try to make it one
            if not isinstance(event, Event):
                try:
                    event = self.build_event(event)
                except Exception as e:
                    self.log.exception('unable to parse data to Event, {0!r}: {1!r}'.format(event, e))
                    event = None

            if event is not None:
                self.log.debug('EVENT on {0!r} {1!r}'.format(self, event))
                responses = self.plugin_manager.process_event(event)
                # this is going to be a list of deferreds,
                # TODO: should probably do this differently
                #self.log.debug('HERE: {0!r}'.format(responses))
                for response in responses:
                    #self.log.debug('adding response router')
                    response.addCallback(self.route_response, event)

            queue.get().addCallback(consumer)
        queue.get().addCallback(consumer)

    def new_event(self, event):
        """
        this is what protocol backends call when they get an event.
        """
        self.event_queue.put(event)

    def build_event(self, event_data):
        #todo: needs to be safe
        try:
            e = Event(source_bot=self, raw_details=event_data)
        except Exception as e:
            self.log.exception('failed to build event from {0!r}: {1!r}'.format(event_data, e))
        else:
            return e

    # ACTION QUEUE
    # default action consumer
    def _consume_actions(self, queue):
        def consumer(action):
            # check if Action, else try to make it one
            if not isinstance(action, Action):
                try:
                    action = self.build_action(action)
                except Exception as e:
                    self.log.exception('unable to build Action with {0!r}: {1!r}'.format(action, e))

            if action is not None:
                res = defer.maybeDeferred(self.process_action, action)

            queue.get().addCallback(consumer)
        queue.get().addCallback(consumer)

    def build_action(self, action_data, event=None):
        if type(action_data) in (str, unicode):
            try:
                a = Action(source_bot=self, source_event=event).msg(action_data)
            except Exception as e:
                self.log.exception('failed to build action from {0!r}, for {1!r}: {2!r}'.format(action_data, event, e))
            else:
                return a

    # PLUGIN SYSTEM #################################################
    def route_response(self, response, event):
        if response is not None:
            self.log.debug('got {0!r} from {1!r}'.format(response, event))
            #TODO: update to actually route to correct bot, for now we just assume its ours
            if isinstance(response, Action):
                self.action_queue.put(response)
            else:
                self.log.error('got invalid response type')

    def process_action(self, action):
        #self.log.debug('routing response: {0}'.format(action))
        self.connection_manager.route_action(action)