class StoqPluginManager: """ stoQ Plugin Manager Class """ def __init__(self): # Define the plugin categories and the associated class. # If we need to add a new plugin category, it must be done here. self.plugin_categories = { "worker": StoqWorkerPlugin, "connector": StoqConnectorPlugin, "reader": StoqReaderPlugin, "source": StoqSourcePlugin, "extractor": StoqExtractorPlugin, "carver": StoqCarverPlugin, "decoder": StoqDecoderPlugin } self.manager = PluginManager() self.manager.setPluginInfoExtension("stoq") self.manager.setPluginPlaces([self.plugin_dir]) self.manager.setCategoriesFilter(self.plugin_categories) # Setup our plugin filter self.manager = FilteredPluginManager(self.manager) @property def __plugindict__(self): """ Create a dict() of plugin class name and the plugin category """ plugins = {} for category, category_class in self.plugin_categories.items(): class_str = re.search('(?<=<class \'stoq\.plugins\.)(.+)(?=.*\'>)', str(category_class)).group(0) plugins[class_str] = category return plugins def collect_plugins(self): """ Wrapper for yapsy.PluginManager.collectPlugins() """ self.manager.collectPlugins() def get_categories(self): """ Wrapper for yapsy.PluginManager.getCategories() """ return self.manager.getCategories() def get_plugins_of_category(self, category): """ Wrapper for yapsy.PluginManager.getPluginsOfCategory() """ return self.manager.getPluginsOfCategory(category) def get_plugin_names_of_category(self, category): """ Lists plugin name of a specific category :param str category: Category to discover plugins in :returns: A list of discovered plugins :rtype: list """ return [p.name for p in self.get_plugins_of_category(category)] def get_plugin(self, name, category): """ Initializes a plugin within a specific category :param str name: Name of plugin to get :param str category: Category of the named plugin :returns: plugin object :rtype: object """ return self.manager.getPluginByName(name, category) def deactivate_plugin(self, name, category): """ Deactivate a plugin within a specific category :param str name: Name of plugin to deactivate :param str category: Category of the named plugin """ self.manager.deactivatePluginByName(name, category) def load_plugin(self, name, category): """ Load the desired plugin :param str name: Plugin name to be loaded :param str category: The category of plugin to be loaded :returns: The loaded plugin object :rtype: object """ # We are going to dynamically reimplement the isPluginOk method # so only the needed plugins are loaded into memory. Much faster # and efficient self.manager.isPluginOk = lambda x: x.name == name # Gather, filter, and load plugin self.manager.locatePlugins() self.manager.filterPlugins() self.manager.loadPlugins() # Initialize our plugin plugin = self.get_plugin(name, category) if not plugin: self.stoq.log.warn("Plugin {}:{} failed to load".format( category, name)) return None for sect in plugin.details.sections(): # Let's skip over the sections that are required by our # plugin manager. No sense in trying to overwrite. if any([s in sect for s in ['Core', 'Documentation']]): next for opt in plugin.details.options(sect): # define each configuration option as an object within # plugin class. # Note: In order to reduce logic, we attempt to load # the option as a boolean. By default, this will raise # an error which in turn will cause us to load it as # a string. try: setattr(plugin.plugin_object, opt, plugin.details.getboolean(sect, opt)) except ValueError: value = plugin.details.get(sect, opt) if opt.endswith("_list"): # If our option ends with a list, let's turn it # into one # Example: # worker_list = this, is, a, list # Becomes: # worker.worker_list = ['this', 'is', 'a', 'list'] value = [i.strip() for i in value.split(",")] elif opt.endswith("_dict"): value = self.loads(value) elif opt.endswith("_tuple"): value = tuple(i.strip() for i in value.split(",")) setattr(plugin.plugin_object, opt, value) setattr(plugin.plugin_object, 'category', category) plugin_path = "{}/{}/{}".format(self.plugin_dir, category, name) setattr(plugin.plugin_object, 'plugin_path', plugin_path) # Make sure we attempt to activate the plugin after we setattr # from the plugin config file plugin.plugin_object.activate(self) return plugin.plugin_object def get_all_plugin_names(self): """ List all plugin names :returns: All plugin names :rtype: list """ return [p.name for p in self.get_all_plugins()] def get_all_plugins(self): """ Wrapper for yapsy.PluginManager.getAllPlugins() """ return self.manager.getAllPlugins() def list_plugins(self): """ List all available plugins and their category """ # Make sure we update the filter, otherwise all plugins won't be # visible. self.manager.isPluginOk = lambda x: x.name != "" self.collect_plugins() print("Available Plugins:") for category in self.get_categories(): print(" {0}s".format(category)) for plugin in self.get_plugins_of_category(category): print(" - {0}v{1}{2}".format(plugin.name.ljust(20), str(plugin.version).ljust(7), plugin.description))
class StoqPluginManager: """ stoQ Plugin Manager Class """ def __init__(self): # Define the plugin categories and the associated class. # If we need to add a new plugin category, it must be done here. self.plugin_categories = {"worker": StoqWorkerPlugin, "connector": StoqConnectorPlugin, "reader": StoqReaderPlugin, "source": StoqSourcePlugin, "extractor": StoqExtractorPlugin, "carver": StoqCarverPlugin, "decoder": StoqDecoderPlugin } self.manager = PluginManager() self.manager.setPluginInfoExtension("stoq") self.manager.setPluginPlaces([self.plugin_dir]) self.manager.setCategoriesFilter(self.plugin_categories) # Setup our plugin filter self.manager = FilteredPluginManager(self.manager) @property def __plugindict__(self): """ Create a dict() of plugin class name and the plugin category """ plugins = {} for category, category_class in self.plugin_categories.items(): class_str = re.search(r'(?<=<class \'stoq\.plugins\.)(.+)(?=.*\'>)', str(category_class)).group(0) plugins[class_str] = category return plugins def collect_plugins(self): """ Wrapper for yapsy.PluginManager.collectPlugins() """ self.manager.collectPlugins() def get_categories(self): """ Wrapper for yapsy.PluginManager.getCategories() """ return self.manager.getCategories() def get_plugins_of_category(self, category): """ Wrapper for yapsy.PluginManager.getPluginsOfCategory() """ return self.manager.getPluginsOfCategory(category) def get_plugin_names_of_category(self, category): """ Lists plugin name of a specific category :param str category: Category to discover plugins in :returns: A list of discovered plugins :rtype: list """ return [p.name for p in self.get_plugins_of_category(category)] def get_plugin(self, name, category): """ Initializes a plugin within a specific category :param str name: Name of plugin to get :param str category: Category of the named plugin :returns: plugin object :rtype: object """ return self.manager.getPluginByName(name, category) def deactivate_plugin(self, name, category): """ Deactivate a plugin within a specific category :param str name: Name of plugin to deactivate :param str category: Category of the named plugin """ self.manager.deactivatePluginByName(name, category) def load_plugin(self, name, category): """ Load the desired plugin :param str name: Plugin name to be loaded :param str category: The category of plugin to be loaded :returns: The loaded plugin object :rtype: object """ # We are going to dynamically reimplement the isPluginOk method # so only the needed plugins are loaded into memory. Much faster # and efficient self.manager.isPluginOk = lambda x: x.name == name # Gather, filter, and load plugin self.manager.locatePlugins() self.manager.filterPlugins() self.manager.loadPlugins() # Initialize our plugin plugin = self.get_plugin(name, category) if not plugin: self.log.warn("Plugin {}:{} failed to load".format(category, name)) return False for sect in plugin.details.sections(): # Let's skip over the sections that are required by our # plugin manager. No sense in trying to overwrite. if any([s in sect for s in ['Core', 'Documentation']]): next for opt in plugin.details.options(sect): # define each configuration option as an object within # plugin class. # Note: In order to reduce logic, we attempt to load # the option as a boolean. By default, this will raise # an error which in turn will cause us to load it as # a string. try: setattr(plugin.plugin_object, opt, plugin.details.getboolean(sect, opt)) except ValueError: value = plugin.details.get(sect, opt) if opt.endswith("_list"): # If our option ends with a list, let's turn it # into one # Example: # worker_list = this, is, a, list # Becomes: # worker.worker_list = ['this', 'is', 'a', 'list'] value = [i.strip() for i in value.split(",")] elif opt.endswith("_dict"): value = self.loads(value) elif opt.endswith("_tuple"): value = tuple(i.strip() for i in value.split(",")) setattr(plugin.plugin_object, opt, value) setattr(plugin.plugin_object, 'category', category) plugin_path = "{}/{}/{}".format(self.plugin_dir, category, name) setattr(plugin.plugin_object, 'plugin_path', plugin_path) # Make sure we attempt to activate the plugin after we setattr # from the plugin config file plugin.plugin_object.activate(self) return plugin.plugin_object def get_all_plugin_names(self): """ List all plugin names :returns: All plugin names :rtype: list """ return [p.name for p in self.get_all_plugins()] def get_all_plugins(self): """ Wrapper for yapsy.PluginManager.getAllPlugins() """ return self.manager.getAllPlugins() def list_plugins(self): """ List all available plugins and their category """ # Make sure we update the filter, otherwise all plugins won't be # visible. self.manager.isPluginOk = lambda x: x.name != "" self.collect_plugins() print("Available Plugins:") for category in self.get_categories(): print(" {0}s".format(category)) for plugin in self.get_plugins_of_category(category): print(" - {0}v{1}{2}".format(plugin.name.ljust(20), str(plugin.version).ljust(7), plugin.description))