Esempio n. 1
0
    def _instantiate_plugin(self, module, config=None):
        """Creates an instance of the plugin module.

        If the setup() function of the plugin's module takes an argument then
        we will provide the instance of CardinalBot to the plugin. If it takes
        two, we will provide Cardinal, and its config.

        Keyword arguments:
          module -- The module to instantiate.
          config -- A config, if any, belonging to the plugin.

        Returns:
          object -- The instance of the plugin.

        Raises:
          PluginError -- When a plugin's setup function has more than one
            argument.
        """
        if hasattr(module, 'entrypoint'):
            entrypoint = module.entrypoint
        # Old-style - will be deprecated in a future release of Cardinal
        elif hasattr(module, 'setup') and inspect.isfunction(module.setup):
            entrypoint = module.setup
        else:
            raise PluginError(
                "Plugin must define an entrypoint attribute pointing to "
                "the plugin's class definition or factory method/function."
            )

        try:
            signature = inspect.signature(entrypoint)
        except TypeError:
            raise PluginError(
                "Plugin's entrypoint must be a callable returning a new "
                "instance of the plugin."
            )

        # Check whether the setup method on the module accepts an argument. If
        # it does, they are expecting our instance of CardinalBot to be passed
        # in. If not, just call setup. If there is more than one argument
        # accepted, the method is invalid.
        kwargs = {}
        for param in signature.parameters:
            if param == 'cardinal':
                kwargs['cardinal'] = self.cardinal
            elif param == 'config':
                kwargs['config'] = config
            else:
                raise PluginError(
                    "Unknown parameter {} in entrypoint signature"
                    .format(param)
                )

        return entrypoint(**kwargs)
Esempio n. 2
0
    def _close_plugin_instance(self, plugin):
        """Calls the close method on an instance of a plugin.

        If the plugin's module has a close() function, we will check whether
        it expects an instance of CardinalBot or not by checking whether it
        accepts an argument or not. If it does, we will pass in the instance of
        CardinalBot. This method is called just prior to removing the internal
        reference to the plugin's instance.

        Keyword arguments:
          plugin -- The name of the plugin to remove the instance of.

        Raises:
          PluginError -- When a plugin's close function has more than one
            argument.
        """

        instance = self.plugins[plugin]['instance']

        if hasattr(instance, 'close') and inspect.ismethod(instance.close):
            # The plugin has a close method, so we now need to check how
            # many arguments the method has. If it only has one, then the
            # argument must be 'self' and therefore they aren't expecting
            # us to pass in an instance of CardinalBot. If there are two
            # arguments, they expect CardinalBot. Anything else is invalid.
            argspec = inspect.getfullargspec(instance.close)

            if len(argspec.args) == 1:
                instance.close()
            elif len(argspec.args) == 2:
                instance.close(self.cardinal)
            else:
                raise PluginError("Unknown arguments for close function")
Esempio n. 3
0
    def config(self, plugin):
        """Returns a given loaded plugin's config.

        Keyword arguments:
          plugin -- String containing a plugin name.

        Returns:
          dict -- Dictionary containing plugin config.

        Raises:
          ConfigNotFoundError - When config can't be found for the plugin.
        """
        if self.plugin_manager is None:
            self.logger.error(
                "PluginManager has not been initialized! Can't return config "
                "for plugin: %s" % plugin)
            raise PluginError("PluginManager has not yet been initialized")

        try:
            config = self.plugin_manager.get_config(plugin)
        except ConfigNotFoundError:
            # Log and raise the exception again
            self.logger.exception("Couldn't find config for plugin: %s" %
                                  plugin)
            raise

        return config
Esempio n. 4
0
    def _create_plugin_instance(self, module, config=None):
        """Creates an instance of the plugin module.

        If the setup() function of the plugin's module takes an argument then
        we will provide the instance of CardinalBot to the plugin. If it takes
        two, we will provide Cardinal, and its config.

        Keyword arguments:
          module -- The module to instantiate.
          config -- A config, if any, belonging to the plugin.

        Returns:
          object -- The instance of the plugin.

        Raises:
          PluginError -- When a plugin's setup function has more than one
            argument.
        """
        if (not hasattr(module, 'setup')
                or not inspect.isfunction(module.setup)):
            raise PluginError("Plugin does not have a setup function")

        # Check whether the setup method on the module accepts an argument. If
        # it does, they are expecting our instance of CardinalBot to be passed
        # in. If not, just call setup. If there is more than one argument
        # accepted, the method is invalid.
        argspec = inspect.getfullargspec(module.setup)
        if len(argspec.args) == 0:
            instance = module.setup()
        elif len(argspec.args) == 1:
            instance = module.setup(self.cardinal)
        elif len(argspec.args) == 2:
            instance = module.setup(self.cardinal, config)
        else:
            raise PluginError("Unknown arguments for setup function")

        return instance