Beispiel #1
0
    def __init__(self, config):
        self.channels = [c.split(' ', 1) for c in config['channels']]
        self.nickname = config['nickname']
        self.password = config.get('password', None)
        self.history = {}
        acl_fname = config.get('acl', None)

        if acl_fname:
            # Bubble up an IOError if they passed a bad file
            with open(acl_fname, 'r') as acl_fd:
                self.acl = ACL(acl_fd.read())
        else:
            self.acl = AllowAllACL()

        self.loader = PluginLoader(config)

        if 'db' in config:
            log.info('Loading db from config: %s', config['db'])
            db_engine = sqlalchemy.create_engine(config['db'])
        else:
            log.info('Using in-memory db')
            db_engine = sqlalchemy.create_engine('sqlite:///:memory:')

        DBSession = orm.sessionmaker(db_engine)
        session = DBSession()
        self.loader.db = DB(db_engine, session)

        self.loader.loadAll()
Beispiel #2
0
    def registerPlugin(self, plugin):
        """Registers a plugin."""

        plugin_types = {
            'presence': IPresencePlugin,
            'chat': IChatPlugin,
            'population': IPopulationPlugin,
            'base_plugin': IPlugin,
        }

        # Everything is, at least, a base plugin.
        valid_types = ['baseplugin']
        # Loop through the types of plugins and check for implentation of each.
        for t, interface in plugin_types.iteritems():
            try:
                verified_plugin = verify_plugin(interface, plugin)
                # If the above succeeded, then `plugin` implementes `interface`.
                self.plugins[t].append(verified_plugin)
                self.plugins[t].sort()
                valid_types.append(t)
            except DoesNotImplement:
                # This means this plugin does not declare to  be a `t`.
                pass
            except PluginException:
                log.error('Plugin %s claims to be a %s, but is not!', plugin.name, t)

        plugin.setup(self)

        log.info('registered plugin %s as %s', plugin.name, valid_types)
Beispiel #3
0
    def registerPlugin(self, plugin):
        """Registers a plugin."""

        plugin_types = {
            'presence': IPresencePlugin,
            'chat': IChatPlugin,
            'population': IPopulationPlugin,
            'base_plugin': IPlugin,
        }

        # Everything is, at least, a base plugin.
        valid_types = ['baseplugin']
        # Loop through the types of plugins and check for implentation of each.
        for t, interface in plugin_types.iteritems():
            try:
                verified_plugin = verify_plugin(interface, plugin)
                # If the above succeeded, then `plugin` implementes `interface`.
                self.plugins[t].append(verified_plugin)
                self.plugins[t].sort()
                valid_types.append(t)
            except DoesNotImplement:
                # This means this plugin does not declare to  be a `t`.
                pass
            except PluginException:
                log.error('Plugin "%s" claims to be a %s, but is not!', plugin.name, t)

        plugin.setup(self)

        log.info('registered plugin %s as %s', plugin.name, valid_types)
Beispiel #4
0
    def loadAll(self):
        plugins_to_load = set()

        # Gather plugins
        for plugin in iter_entry_points(group='hamperbot.plugins', name=None):
            if plugin.name in self.config['plugins']:
                plugins_to_load.add(plugin.load())

        # Sort by priority, highest first
        plugins_to_load = sorted(plugins_to_load, key=lambda p: -p.priority)

        # Check dependencies and load plugins.
        for plugin_class in plugins_to_load:
            plugin_obj = plugin_class()
            if not self.dependencies_satisfied(plugin_obj):
                log.warning('Dependency not satisfied for {0}. Not loading.'
                            .format(plugin_class.__name__))
                continue
            log.info('Loading plugin {0}.'.format(plugin_class.__name__))
            plugin_obj.setup(self)
            self.plugins.append(plugin_obj)

        # Check for missing plugins
        plugin_names = {x.name for x in self.plugins}
        for pattern in self.config['plugins']:
            if pattern not in plugin_names:
                log.warning('Sorry, I couldn\'t find a plugin named "%s"',
                            pattern)
Beispiel #5
0
    def registerPlugin(self, plugin):
        """Registers a plugin."""

        plugin_types = {
            'presence': IPresencePlugin,
            'chat': IChatPlugin,
            'population': IPopulationPlugin,
            'base_plugin': BaseInterface,
        }

        # Everything is, at least, a base plugin.
        valid_types = ['baseplugin']
        # Loop through the types of plugins and check for implentation of each.

        claimed_compliances = list(implementedBy(type(plugin)))
        # Can we use this as a map instead?
        for t, interface in plugin_types.iteritems():
            if interface in claimed_compliances:
                try:
                    verifyObject(interface, plugin)
                    # If the above succeeded, then `plugin` implementes `interface`.
                    self.plugins[t].append(plugin)
                    self.plugins[t].sort()
                    valid_types.append(t)
                except DoesNotImplement:
                    log.error('Plugin %s claims to be a %s, but is not!', plugin.name, t)

        plugin.setup(self)

        log.info('registered plugin %s as %s', plugin.name, valid_types)
Beispiel #6
0
    def registerPlugin(self, plugin):
        """Registers a plugin."""

        plugin_types = {
            'presence': IPresencePlugin,
            'chat': IChatPlugin,
            'population': IPopulationPlugin,
            'base_plugin': BaseInterface,
        }

        # Everything is, at least, a base plugin.
        valid_types = ['baseplugin']
        # Loop through the types of plugins and check for implentation of each.

        claimed_compliances = list(implementedBy(type(plugin)))
        # Can we use this as a map instead?
        for t, interface in plugin_types.iteritems():
            if interface in claimed_compliances:
                try:
                    verifyObject(interface, plugin)
                    # If the above succeeded, then `plugin` implementes `interface`.
                    self.plugins[t].append(plugin)
                    self.plugins[t].sort()
                    valid_types.append(t)
                except DoesNotImplement:
                    log.error('Plugin %s claims to be a %s, but is not!',
                              plugin.name, t)

        plugin.setup(self)

        log.info('registered plugin %s as %s', plugin.name, valid_types)
Beispiel #7
0
    def loadAll(self):
        plugins_to_load = set()

        # Gather plugins
        for plugin in iter_entry_points(group='hamperbot.plugins', name=None):
            if plugin.name in self.config['plugins']:
                plugins_to_load.add(plugin.load())

        # Sort by priority, highest first
        plugins_to_load = sorted(plugins_to_load, key=lambda p: -p.priority)

        # Check dependencies and load plugins.
        for plugin_class in plugins_to_load:
            plugin_obj = plugin_class()
            if not self.dependencies_satisfied(plugin_obj):
                log.warning('Dependency not satisfied for {0}. Not loading.'
                            .format(plugin_class.__name__))
                continue
            log.info('Loading plugin {0}.'.format(plugin_class.__name__))
            plugin_obj.setup(self)
            self.plugins.append(plugin_obj)

        # Check for missing plugins
        plugin_names = {x.name for x in self.plugins}
        # Don't allow karma and karma_adv to be loaded at once
        if ('karma' in self.config['plugins'] and
                'karma_adv' in self.config['plugins']):
            quit(
                "Unable to load both karma and karma_adv at the same time")

        for pattern in self.config['plugins']:
            if pattern not in plugin_names:
                log.warning('Sorry, I couldn\'t find a plugin named "%s"',
                            pattern)
Beispiel #8
0
    def __init__(self, config):
        self.channels = [c.split(' ', 1) for c in config['channels']]
        self.nickname = config['nickname']
        self.password = config.get('password', None)
        self.history = {}
        acl_fname = config.get('acl', None)

        if acl_fname:
            # Bubble up an IOError if they passed a bad file
            with open(acl_fname, 'r') as acl_fd:
                self.acl = ACL(acl_fd.read())
        else:
            self.acl = AllowAllACL()

        self.loader = PluginLoader(config)

        if 'db' in config:
            log.info('Loading db from config: %s', config['db'])
            db_engine = sqlalchemy.create_engine(config['db'])
        else:
            log.info('Using in-memory db')
            db_engine = sqlalchemy.create_engine('sqlite:///:memory:')

        DBSession = orm.sessionmaker(db_engine)
        session = DBSession()
        self.loader.db = DB(db_engine, session)

        self.loader.loadAll()
Beispiel #9
0
 def signedOn(self):
     """Called after successfully signing on to the server."""
     log.info("Signed on as %s.", self.nickname)
     if not self.password:
         # We aren't wating for auth, join all the channels
         self.joinChannels()
     else:
         self.msg("NickServ", "IDENTIFY %s" % self.password)
Beispiel #10
0
 def signedOn(self):
     """Called after successfully signing on to the server."""
     log.info("Signed on as %s.", self.nickname)
     if not self.password:
         # We aren't wating for auth, join all the channels
         self.joinChannels()
     else:
         self.msg("NickServ", "IDENTIFY %s" % self.password)
Beispiel #11
0
    def process_action(self, raw_user, channel, raw_message):
        """Called when a message is received from a channel or user."""
        log.info("%s %s %s", channel, raw_user, raw_message)

        if not raw_user:
            # ignore server messages
            return

        # This monster of a regex extracts msg and target from a message, where
        # the target may not be there, and the target is a valid irc name.
        # Valid ways to target someone are "<nick>: ..." and "<nick>, ..."
        target, message = re.match(
            r'^(?:([a-z_\-\[\]\\^{}|`]'  # First letter can't be a number
            '[a-z0-9_\-\[\]\\^{}|`]*)'   # The rest can be many things
            '[:,] )? *(.*)$',            # The actual message
            raw_message, re.I).groups()

        pm = channel == self.nickname
        if pm:
            directed = True
        if target:
            if target.lower() == self.nickname.lower():
                directed = True
            else:
                directed = False
                message = '{0}: {1}'.format(target, message)
        else:
            directed = False
        if message.startswith('!'):
            message = message[1:]
            directed = True

        if directed:
            message = message.rstrip()

        try:
            user, mask = raw_user.split('!', 1)
        except ValueError:
            user = raw_user
            mask = ''

        comm = {
            'raw_message': raw_message,
            'message': message,
            'raw_user': raw_user,
            'user': user,
            'mask': mask,
            'target': target,
            'channel': channel,
            'directed': directed,
            'pm': pm,
        }

        self.dispatch('chat', 'message', comm)

        self.factory.history.setdefault(
            channel, deque(maxlen=100)).append(comm)
Beispiel #12
0
    def process_action(self, raw_user, channel, raw_message):
        """Called when a message is received from a channel or user."""
        log.info("%s %s %s", channel, raw_user, raw_message)

        if not raw_user:
            # ignore server messages
            return

        # This monster of a regex extracts msg and target from a message, where
        # the target may not be there, and the target is a valid irc name.
        # Valid ways to target someone are "<nick>: ..." and "<nick>, ..."
        target, message = re.match(
            r'^(?:([a-z_\-\[\]\\^{}|`]'  # First letter can't be a number
            '[a-z0-9_\-\[\]\\^{}|`]*)'  # The rest can be many things
            '[:,] )? *(.*)$',  # The actual message
            raw_message,
            re.I).groups()

        pm = channel == self.nickname
        if target:
            if target.lower() == self.nickname.lower():
                directed = True
            else:
                directed = False
                message = '{0}: {1}'.format(target, message)
        else:
            directed = False
        if message.startswith('!'):
            message = message[1:]
            directed = True

        if directed:
            message = message.rstrip()

        try:
            user, mask = raw_user.split('!', 1)
        except ValueError:
            user = raw_user
            mask = ''

        comm = {
            'raw_message': raw_message,
            'message': message,
            'raw_user': raw_user,
            'user': user,
            'mask': mask,
            'target': target,
            'channel': channel,
            'directed': directed,
            'pm': pm,
        }

        self.dispatch('chat', 'message', comm)

        if not channel in self.factory.history:
            self.factory.history[channel] = deque(maxlen=100)
        self.factory.history[channel].append(comm)
Beispiel #13
0
 def noticed(self, user, channel, message):
     log.info("NOTICE %s %s %s" % (user, channel, message))
     # mozilla's nickserv responds as [email protected]
     if (self.password and channel == self.nickname
             and user.startswith('NickServ')):
         if ("Password accepted" in message
                 or "You are now identified" in message):
             self.joinChannels()
         elif "Password incorrect" in message:
             log.info("NickServ AUTH FAILED!!!!!!!")
             reactor.stop()
Beispiel #14
0
 def noticed(self, user, channel, message):
     log.info("NOTICE %s %s %s" % (user, channel, message))
     # mozilla's nickserv responds as [email protected]
     if (self.password and channel == self.nickname and
             user.startswith('NickServ')):
         if ("Password accepted" in message or
                 "You are now identified" in message):
             self.joinChannels()
         elif "Password incorrect" in message:
             log.info("NickServ AUTH FAILED!!!!!!!")
             reactor.stop()
Beispiel #15
0
 def signedOn(self):
     """Called after successfully signing on to the server."""
     log.info("Signed on as %s.", self.nickname)
     self.dispatch('presence', 'signedOn')
     for c in self.factory.channels:
         self.join(c)
Beispiel #16
0
 def removePlugin(self, plugin):
     log.info("Unloading %r" % plugin)
     for plugin_type, plugins in self.factory.plugins.items():
         if plugin in plugins:
             log.debug('plugin is a %s', plugin_type)
             plugins.remove(plugin)
Beispiel #17
0
 def clientConnectionLost(self, connector, reason):
     log.info('Lost connection (%s).', (reason))
     # Reconnect
     connector.connect()
Beispiel #18
0
 def signedOn(self):
     """Called after successfully signing on to the server."""
     log.info("Signed on as %s.", self.nickname)
     self.dispatch('presence', 'signedOn')
     for c in self.factory.channels:
         self.join(c)
Beispiel #19
0
 def clientConnectionFailed(self, connector, reason):
     log.info('Could not connect: %s', (reason, ))
Beispiel #20
0
 def removePlugin(self, plugin):
     log.info("Unloading %r" % plugin)
     for plugin_type, plugins in self.factory.plugins.items():
         if plugin in plugins:
             log.debug('plugin is a %s', plugin_type)
             plugins.remove(plugin)
Beispiel #21
0
 def joined(self, channel):
     """Called after successfully joining a channel."""
     log.info("Joined %s.", channel)
     # ask for the current list of users in the channel
     self.dispatch('presence', 'joined', channel)
Beispiel #22
0
 def left(self, channel):
     """Called after leaving a channel."""
     log.info("Left %s.", channel)
     self.dispatch('presence', 'left', channel)
Beispiel #23
0
 def joined(self, channel):
     """Called after successfully joining a channel."""
     log.info("Joined %s.", channel)
     # ask for the current list of users in the channel
     self.dispatch('presence', 'joined', channel)
Beispiel #24
0
 def clientConnectionFailed(self, connector, reason):
     log.info('Could not connect: %s', (reason,))
Beispiel #25
0
 def clientConnectionLost(self, connector, reason):
     log.info('Lost connection (%s).', (reason))
     # Reconnect
     connector.connect()
Beispiel #26
0
 def left(self, channel):
     """Called after leaving a channel."""
     log.info("Left %s.", channel)
     self.dispatch('presence', 'left', channel)