def init_plugin_manager(self): # Configuring plugin locator plugin_locator = PluginFileLocator() plugin_locator.setPluginPlaces(PLUGIN_PLACES) # Initializing plugin manager... # categories_filter={"Default": IPlugin, "Custom": ICustomPlugin}, self._plmanager = PluginManager( categories_filter={"Default": IAlgorithmPlugin}, plugin_locator=plugin_locator) # decorate plugin manager with configurable feature self._cpmanager = ConfigurablePluginManager( decorated_manager=self._plmanager) # create parser for config file config_parser = ConfigParser() # set config file location config_parser.read(get_config_file_path()) # set parser to configurable decorator self._cpmanager.setConfigParser( configparser_instance=config_parser, config_change_trigger=config_change_trigger) # plugin_manager.collectPlugins() # configurable_plugin_manager.loadPlugins() self._cpmanager.collectPlugins() self.plugins_info() for plugin_info in self._plmanager.getAllPlugins(): if plugin_info.is_activated: plugin_info.plugin_object.set_image_manager(self._immanager)
def __init__(self, config): self._config = config # set a locator that gets every possible backends as a first discovery pass. self._locator = PluginFileLocator(analyzers=[ PluginFileAnalyzerWithInfoFile('AllBackendLocator', 'plug') ]) self._locator.disableRecursiveScan( ) # This is done below correctly with find_roots_with_extra super().__init__(plugin_locator=self._locator) self.setCategoriesFilter({'backend': ErrBot}) if hasattr(config, 'BOT_EXTRA_BACKEND_DIR'): extra = config.BOT_EXTRA_BACKEND_DIR else: extra = [] all_backends_paths = find_roots_with_extra(CORE_BACKENDS, extra) log.info('Backends search paths %s', all_backends_paths) self.setPluginPlaces(all_backends_paths) for entry in all_backends_paths: if entry not in sys.path: sys.path.append( entry ) # so backends can relatively import their submodules self.locatePlugins() log.info('Found those backends available:') for (_, _, plug) in self.getPluginCandidates(): log.info('\t%10s (%s)' % (plug.name, plug.path + '.py'))
def __init__(self, storage_plugin, repo_manager, extra, autoinstall_deps, core_plugins, plugins_callback_order): self.bot = None self.autoinstall_deps = autoinstall_deps self.extra = extra self.open_storage(storage_plugin, 'core') self.core_plugins = core_plugins self.plugins_callback_order = plugins_callback_order self.repo_manager = repo_manager # if this is the old format migrate the entries in repo_manager ex_entry = 'repos' if ex_entry in self: log.info('You are migrating from v3 to v4, porting your repo info...') for name, url in self[ex_entry].items(): log.info('Plugin %s from URL %s.', (name, url)) repo_manager.add_plugin_repo(name, url) log.info('update successful, removing old entry.') del(self[ex_entry]) # be sure we have a configs entry for the plugin configurations if self.CONFIGS not in self: self[self.CONFIGS] = {} locator = PluginFileLocator([PluginFileAnalyzerWithInfoFile("info_ext", 'plug'), PluginFileAnalyzerWithInfoFile("info_ext", 'flow')]) locator.disableRecursiveScan() # We do that ourselves super().__init__(categories_filter={BOTPLUGIN_TAG: BotPlugin, BOTFLOW_TAG: BotFlow}, plugin_locator=locator)
def __init__(self): analyzer = PluginFileAnalyzerWithInfoFile( name="rdiffweb-info", extensions="plugin") PluginFileLocator.__init__(self, analyzers=[analyzer]) # Disable recursive search. self.recursive = False
def __init__(self, storage_plugin, repo_manager, extra, autoinstall_deps, core_plugins, plugins_callback_order): self.bot = None self.autoinstall_deps = autoinstall_deps self.extra = extra self.open_storage(storage_plugin, 'core') self.core_plugins = core_plugins self.plugins_callback_order = plugins_callback_order self.repo_manager = repo_manager # if this is the old format migrate the entries in repo_manager ex_entry = 'repos' if ex_entry in self: log.info( 'You are migrating from v3 to v4, porting your repo info...') for name, url in self[ex_entry].items(): log.info('Plugin %s from URL %s.', (name, url)) repo_manager.add_plugin_repo(name, url) log.info('update successful, removing old entry.') del (self[ex_entry]) # be sure we have a configs entry for the plugin configurations if self.CONFIGS not in self: self[self.CONFIGS] = {} locator = PluginFileLocator([ PluginFileAnalyzerWithInfoFile("info_ext", 'plug'), PluginFileAnalyzerWithInfoFile("info_ext", 'flow') ]) locator.disableRecursiveScan() # We do that ourselves super().__init__(categories_filter={ BOTPLUGIN_TAG: BotPlugin, BOTFLOW_TAG: BotFlow }, plugin_locator=locator)
def test_locatePlugins_recursively_when_plugin_is_a_symlinked_directory( self): temp_dir = tempfile.mkdtemp() try: temp_sub_dir = os.path.join(temp_dir, "plugins") os.mkdir(temp_sub_dir) plugin_info_file = "simpleplugin.yapsy-plugin" plugin_impl_dir = "SimplePlugin" os.symlink( os.path.join(self.plugin_as_dir_directory, plugin_info_file), os.path.join(temp_sub_dir, plugin_info_file)) os.symlink( os.path.join(self.plugin_as_dir_directory, plugin_impl_dir), os.path.join(temp_sub_dir, plugin_impl_dir)) pl = PluginFileLocator() pl.setPluginPlaces([temp_dir]) candidates, num = pl.locatePlugins() self.assertEqual(num, 1) self.assertEqual(len(candidates), num) self.assertEqual(os.path.join(temp_sub_dir, self.plugin_info_file), candidates[0][0]) self.assertEqual( os.path.join(temp_sub_dir, self.plugin_name, "__init__"), candidates[0][1]) self.assertTrue(isinstance(candidates[0][2], PluginInfo)) finally: shutil.rmtree(temp_dir)
def __init__(self, bot_config, category, base_class, base_search_dir, extra_search_dirs=()): self._config = bot_config # set a locator that gets every possible backends as a first discovery pass. self._locator = PluginFileLocator(analyzers=[ PluginFileAnalyzerWithInfoFile('SpecificLocator', 'plug') ]) self._locator.disableRecursiveScan( ) # This is done below correctly with find_roots_with_extra super().__init__(plugin_locator=self._locator) self.setCategoriesFilter({category: base_class}) all_plugins_paths = collect_roots((base_search_dir, extra_search_dirs)) log.info('%s search paths %s', category, all_plugins_paths) self.setPluginPlaces(all_plugins_paths) for entry in all_plugins_paths: if entry not in sys.path: sys.path.append( entry ) # so backends can relatively import their submodules self.locatePlugins() log.info('Found those plugings available:') for (_, _, plug) in self.getPluginCandidates(): log.info('\t%10s (%s)' % (plug.name, plug.path + '.py'))
def test_gatherCorePluginInfo(self): pl = PluginFileLocator() plugin_info,cf_parser = pl.gatherCorePluginInfo(self.plugin_directory,"simpleplugin.yapsy-plugin") self.assertTrue(plugin_info.name,"Simple Plugin") self.assertTrue(isinstance(cf_parser,ConfigParser)) plugin_info,cf_parser = pl.gatherCorePluginInfo(self.plugin_directory,"notaplugin.atall") self.assertEqual(plugin_info,None) self.assertEqual(cf_parser,None)
def init_manager(): anl = PluginFileAnalyzerMathingRegex('custom_res_handler_plugins', r'^[A-Za-z0-9]+\.py$') res = PluginFileLocator(plugin_info_cls=CFCustomResourceHandler) res.setAnalyzers([anl]) manager = PluginManager(plugin_locator=res, categories_filter={'CFHandlers' : CFCustomResourceHandler}) manager.setPluginPlaces([dirname(__file__) + '/plugins']) manager.collectPlugins() return manager
class BackendManager(PluginManager): """ BackendManager is a customized plugin manager to enumerate backends and load only one. """ def __init__(self, config): self._config = config # set a locator that gets every possible backends as a first discovery pass. self._locator = PluginFileLocator(analyzers=[PluginFileAnalyzerWithInfoFile('AllBackendLocator', 'plug')]) self._locator.disableRecursiveScan() # This is done below correctly with find_roots_with_extra super().__init__(plugin_locator=self._locator) self.setCategoriesFilter({'backend': ErrBot}) if hasattr(config, 'BOT_EXTRA_BACKEND_DIR'): extra = config.BOT_EXTRA_BACKEND_DIR else: extra = [] all_backends_paths = find_roots_with_extra(CORE_BACKENDS, extra) log.info('Backends search paths %s', all_backends_paths) self.setPluginPlaces(all_backends_paths) for entry in all_backends_paths: if entry not in sys.path: sys.path.append(entry) # so backends can relatively import their submodules self.locatePlugins() log.info('Found those backends available:') for (_, _, plug) in self.getPluginCandidates(): log.info('\t%10s (%s)' % (plug.name, plug.path + '.py')) def instanciateElement(self, element): """ Override the loading method to inject config :param element: plugin class to load. """ log.debug("Class to load %s" % element.__name__) return element(self._config) def get_candidate(self, name): """ Find the backend plugin by name. :param name: The name of the plugin you are looking for. :return: :raise Exception: """ for (_, _, plug) in self.getPluginCandidates(): if plug.name == name: return plug raise Exception("Backend '%s' not found." % name) def get_backend_by_name(self, name): # set a locator to narrow it to only one. self._locator.setAnalyzers([SpecificBackendLocator(name)]) log.debug("Refilter the backend plugins...") self.locatePlugins() log.debug("Load the one remaining...") self.loadPlugins() log.debug("Find it back...") plugins = self.getAllPlugins() if len(plugins) == 0: raise Exception("Could not find the backend '%s'." % name) if len(plugins) != 1: raise Exception("There are 2 backends with the name '%s'." % name) return plugins[0].plugin_object
class SpecificPluginManager(PluginManager): """ SpecificPluginManager is a customized plugin manager to enumerate plugins and load only a specific one. """ def __init__(self, bot_config, category, base_class, base_search_dir, extra_search_dirs=()): self._config = bot_config # set a locator that gets every possible backends as a first discovery pass. self._locator = PluginFileLocator(analyzers=[PluginFileAnalyzerWithInfoFile('SpecificLocator', 'plug')]) self._locator.disableRecursiveScan() # This is done below correctly with find_roots_with_extra super().__init__(plugin_locator=self._locator) self.setCategoriesFilter({category: base_class}) all_plugins_paths = collect_roots((base_search_dir, extra_search_dirs)) log.info('%s search paths %s', category, all_plugins_paths) self.setPluginPlaces(all_plugins_paths) for entry in all_plugins_paths: if entry not in sys.path: sys.path.append(entry) # so backends can relatively import their submodules self.locatePlugins() log.info('Found those plugings available:') for (_, _, plug) in self.getPluginCandidates(): log.info('\t%10s (%s)' % (plug.name, plug.path + '.py')) def instanciateElement(self, element): """ Override the loading method to inject config :param element: plugin class to load. """ log.debug("Class to load %s" % element.__name__) return element(self._config) def get_candidate(self, name): """ Find the plugin by name. :param name: The name of the plugin you are looking for. :return: :raise Exception: """ for (_, _, plug) in self.getPluginCandidates(): if plug.name == name: return plug raise Exception("Plugin '%s' not found." % name) def get_plugin_by_name(self, name): # set a locator to narrow it to only one. self._locator.setAnalyzers([SpecificPluginLocator(name)]) log.debug("Refilter the plugins...") self.locatePlugins() log.debug("Load the one remaining...") plugins = self.loadPlugins() if len(plugins) == 0: raise Exception("Could not find the plugin '%s'." % name) if len(plugins) != 1: raise Exception("There are 2 plugins with the name '%s'." % name) if plugins[0].error is not None: reason = plugins[0].error formatted_error = "%s:\n%s" % (reason[0], ''.join(traceback.format_tb(plugins[0].error[2]))) raise Exception('Error loading plugin %s:\nError:\n%s\n' % (name, formatted_error)) return plugins[0].plugin_object
class SpecificPluginManager(PluginManager): """ SpecificPluginManager is a customized plugin manager to enumerate plugins and load only a specific one. """ def __init__(self, bot_config, category, base_class, base_search_dir, extra_search_dirs=()): self._config = bot_config # set a locator that gets every possible backends as a first discovery pass. self._locator = PluginFileLocator(analyzers=[PluginFileAnalyzerWithInfoFile('SpecificLocator', 'plug')]) self._locator.disableRecursiveScan() # This is done below correctly with find_roots_with_extra super().__init__(plugin_locator=self._locator) self.setCategoriesFilter({category: base_class}) all_plugins_paths = find_roots_with_extra(base_search_dir, extra_search_dirs) log.info('%s search paths %s', category, all_plugins_paths) self.setPluginPlaces(all_plugins_paths) for entry in all_plugins_paths: if entry not in sys.path: sys.path.append(entry) # so backends can relatively import their submodules self.locatePlugins() log.info('Found those plugings available:') for (_, _, plug) in self.getPluginCandidates(): log.info('\t%10s (%s)' % (plug.name, plug.path + '.py')) def instanciateElement(self, element): """ Override the loading method to inject config :param element: plugin class to load. """ log.debug("Class to load %s" % element.__name__) return element(self._config) def get_candidate(self, name): """ Find the plugin by name. :param name: The name of the plugin you are looking for. :return: :raise Exception: """ for (_, _, plug) in self.getPluginCandidates(): if plug.name == name: return plug raise Exception("Plugin '%s' not found." % name) def get_plugin_by_name(self, name): # set a locator to narrow it to only one. self._locator.setAnalyzers([SpecificPluginLocator(name)]) log.debug("Refilter the plugins...") self.locatePlugins() log.debug("Load the one remaining...") plugins = self.loadPlugins() if len(plugins) == 0: raise Exception("Could not find the plugin '%s'." % name) if len(plugins) != 1: raise Exception("There are 2 plugins with the name '%s'." % name) if plugins[0].error is not None: reason = plugins[0].error formatted_error = "%s:\n%s" % (reason[0], ''.join(traceback.format_tb(plugins[0].error[2]))) raise Exception('Error loading plugin %s:\nError:\n%s\n' % (name, formatted_error)) return plugins[0].plugin_object
class BackendManager(PluginManager): """ BackendManager is a customized plugin manager to enumerate backends and load only one. """ def __init__(self, config): self._config = config # set a locator that gets every possible backends as a first discovery pass. self._locator = PluginFileLocator(analyzers=[PluginFileAnalyzerWithInfoFile('AllBackendLocator', 'plug')]) self._locator.disableRecursiveScan() # This is done below correctly with find_roots_with_extra super().__init__(plugin_locator=self._locator) self.setCategoriesFilter({'backend': ErrBot}) if hasattr(config, 'BOT_EXTRA_BACKEND_DIR'): extra = config.BOT_EXTRA_BACKEND_DIR else: extra = [] all_backends_paths = find_roots_with_extra(CORE_BACKENDS, extra) log.info('Backends search paths %s', all_backends_paths) self.setPluginPlaces(all_backends_paths) for entry in all_backends_paths: if entry not in sys.path: sys.path.append(entry) # so backends can relatively import their submodules self.locatePlugins() log.info('Found those backends available:') for (_, _, plug) in self.getPluginCandidates(): log.info('\t%10s (%s)' % (plug.name, plug.path + '.py')) def instanciateElement(self, element): """ Override the loading method to inject config """ log.debug("Class to load %s" % element.__name__) return element(self._config) def get_candidate(self, name): """ Find the backend plugin by name. :param name: The name of the plugin you are looking for. :return: :raise Exception: """ for (_, _, plug) in self.getPluginCandidates(): if plug.name == name: return plug raise Exception("Backend '%s' not found." % name) def get_backend_by_name(self, name): # set a locator to narrow it to only one. self._locator.setAnalyzers([SpecificBackendLocator(name)]) log.debug("Refilter the backend plugins...") self.locatePlugins() log.debug("Load the one remaining...") self.loadPlugins() log.debug("Find it back...") plugins = self.getAllPlugins() if len(plugins) == 0: raise Exception("Could not find the backend '%s'." % name) if len(plugins) != 1: raise Exception("There are 2 backends with the name '%s'." % name) return plugins[0].plugin_object
def test_setPluginInfoClass_for_named_analyzer(self): class SpecificPluginInfo(PluginInfo): pass pl = PluginFileLocator() pl.setPluginPlaces([self.plugin_directory]) newAnalyzer = PluginFileAnalyzerMathingRegex( "mouf", r".*VersionedPlugin\d+\.py$") pl.appendAnalyzer(newAnalyzer) pl.setPluginInfoClass(SpecificPluginInfo, "info_ext") candidates, num = pl.locatePlugins() self.assertEqual(num, 5) self.assertEqual(len(candidates), num) versioned_plugins = [ c for c in candidates if "VersionedPlugin" in c[0] ] self.assertEqual(4, len(versioned_plugins)) for p in versioned_plugins: self.assertTrue(isinstance(p[2], PluginInfo)) simple_plugins = [ c for c in candidates if "VersionedPlugin" not in c[0] ] self.assertEqual(1, len(simple_plugins)) for p in simple_plugins: self.assertTrue(isinstance(p[2], SpecificPluginInfo))
def test_locatePlugins(self): pl = PluginFileLocator() pl.setPluginPlaces([self.plugin_directory]) candidates, num = pl.locatePlugins() self.assertEqual(num,1) self.assertEqual(len(candidates),num) self.assertEqual(os.path.join(self.plugin_directory,self.plugin_info_file), candidates[0][0]) self.assertEqual(os.path.join(self.plugin_directory,self.plugin_name), candidates[0][1]) self.assertTrue(isinstance(candidates[0][2],PluginInfo))
def init_manager(): anl = PluginFileAnalyzerMathingRegex('custom_res_handler_plugins', r'^[A-Za-z0-9]+\.py$') res = PluginFileLocator(plugin_info_cls=CFCustomResourceHandler) res.setAnalyzers([anl]) manager = PluginManager( plugin_locator=res, categories_filter={'CFHandlers': CFCustomResourceHandler}) manager.setPluginPlaces([dirname(__file__) + '/plugins']) manager.collectPlugins() return manager
def _init_plugin_manager(self, bot_config): self.plugin_dir = os.path.join(bot_config.BOT_DATA_DIR, PLUGINS_SUBDIR) self.open_storage(os.path.join(bot_config.BOT_DATA_DIR, 'core.db')) # be sure we have a configs entry for the plugin configurations if self.CONFIGS not in self: self[self.CONFIGS] = {} self.setCategoriesFilter({"bots": BotPlugin}) locator = PluginFileLocator([PluginFileAnalyzerWithInfoFile("info_ext", 'plug')]) locator.disableRecursiveScan() # We do that ourselves self.setPluginLocator(locator)
def test_removeAnalyzers(self): pl = PluginFileLocator() pl.setPluginPlaces([self.plugin_directory]) newAnalyzer = PluginFileAnalyzerMathingRegex("mouf",r".*VersionedPlugin\d+\.py$") pl.appendAnalyzer(newAnalyzer) pl.removeAnalyzers("info_ext") candidates, num = pl.locatePlugins() self.assertEqual(num,4) self.assertEqual(len(candidates),num)
def __init__(self): # Parse configuration files and command line options parseoptions.parse_all_conf() # Define the directories to be scanned for candidate plugins # First find plugins located in current directory this_dir = os.path.join(os.getcwd(), 'plugins') # Then find plugins located in the user's home directory home_dir = os.path.join(os.path.expanduser('~'), '.' + globalvars.PROGRAM_NAME + '/plugins') # Last find system wide plugins located in /etc system_dir = os.path.join('/etc/' + globalvars.PROGRAM_NAME + '/plugins') globalvars.plugin_directories.append(this_dir) globalvars.plugin_directories.append(home_dir) globalvars.plugin_directories.append(system_dir) # Create plugin analyzers for different types of plugins # Do not add a dot before the extension. DataCollectorsPA = PluginFileAnalyzerWithInfoFile('DataCollectors', extensions='metaconf') PluginAnalyzers = [DataCollectorsPA] # Configure Plugin Locator PL = PluginFileLocator(analyzers=PluginAnalyzers) PL.setPluginPlaces(globalvars.plugin_directories) # Create plugin manager self.plugin_manager.setPluginLocator(PL) self.plugin_manager.setCategoriesFilter({ "DataCollectors": DataCollector }) # Load available plugins LOG.debug('Locating plugins') candidates, num = self.plugin_manager.locatePlugins() self.plugin_manager.loadPlugins() # Check if any plugins were found if(num == 0): LOG.critical('No plugins found. The following directories were checked:') for dir_ in globalvars.plugin_directories: LOG.critical("'" + dir_ + "'") LOG.critical('for the following plugin extensions:') for PA in PluginAnalyzers: for ext in PA.expectedExtensions: LOG.critical("'*" + ext + "'") LOG.critical('Please check if your plugins are placed in the proper directory and make sure they have the proper extension.') LOG.critical('The program will now exit.') exit(globalvars.exitCode.FAILURE) self.get_available_plugins()
def __init__(self, storage_plugin, repo_manager, extra, autoinstall_deps, core_plugins): self.bot = None self.autoinstall_deps = autoinstall_deps self.extra = extra self.open_storage(storage_plugin, 'core') self.core_plugins = core_plugins self.repo_manager = repo_manager # be sure we have a configs entry for the plugin configurations if self.CONFIGS not in self: self[self.CONFIGS] = {} locator = PluginFileLocator([PluginFileAnalyzerWithInfoFile("info_ext", 'plug')]) locator.disableRecursiveScan() # We do that ourselves super().__init__(categories_filter={"bots": BotPlugin}, plugin_locator=locator)
def init_plugin_manager(self): locator = PluginFileLocator( [PluginFileAnalyzerWithInfoFile('info_ext', 'plug')]) plugin_manager = PluginManager(plugin_locator=locator) plugin_manager.setPluginPlaces(self.config.PLUGIN_PATHS) plugin_manager.collectPlugins() return plugin_manager
def test_removeAllAnalyzers(self): pl = PluginFileLocator() pl.setPluginPlaces([self.plugin_directory]) pl.removeAllAnalyzer() candidates, num = pl.locatePlugins() self.assertEqual(num, 0) self.assertEqual(len(candidates), num)
def __init__(self, storage_plugin, plugin_dir, extra, autoinstall_deps, core_plugins): self.bot = None self.autoinstall_deps = autoinstall_deps self.extra = extra self.open_storage(storage_plugin, 'core') self.plugin_dir = plugin_dir self.core_plugins = core_plugins # be sure we have a configs entry for the plugin configurations if self.CONFIGS not in self: self[self.CONFIGS] = {} locator = PluginFileLocator( [PluginFileAnalyzerWithInfoFile("info_ext", 'plug')]) locator.disableRecursiveScan() # We do that ourselves super().__init__(categories_filter={"bots": BotPlugin}, plugin_locator=locator)
def test_locatePlugins_recursively_when_plugin_is_a_directory(self): temp_dir = tempfile.mkdtemp() try: temp_sub_dir = os.path.join(temp_dir,"plugins") shutil.copytree(self.plugin_as_dir_directory,temp_sub_dir) pl = PluginFileLocator() pl.setPluginPlaces([temp_dir]) candidates, num = pl.locatePlugins() self.assertEqual(num,1) self.assertEqual(len(candidates),num) self.assertEqual(os.path.join(temp_sub_dir,self.plugin_info_file), candidates[0][0]) self.assertEqual(os.path.join(temp_sub_dir,self.plugin_name, "__init__"), candidates[0][1]) self.assertTrue(isinstance(candidates[0][2],PluginInfo)) finally: shutil.rmtree(temp_dir)
def test_locatePlugins_recursively_when_plugin_is_a_directory(self): temp_dir = tempfile.mkdtemp() try: temp_sub_dir = os.path.join(temp_dir, "plugins") shutil.copytree(self.plugin_as_dir_directory, temp_sub_dir) pl = PluginFileLocator() pl.setPluginPlaces([temp_dir]) candidates, num = pl.locatePlugins() self.assertEqual(num, 1) self.assertEqual(len(candidates), num) self.assertEqual(os.path.join(temp_sub_dir, self.plugin_info_file), candidates[0][0]) self.assertEqual( os.path.join(temp_sub_dir, self.plugin_name, "__init__"), candidates[0][1]) self.assertTrue(isinstance(candidates[0][2], PluginInfo)) finally: shutil.rmtree(temp_dir)
def testNonRecursivePluginlocationNotFound(self): """ Test detection of plugins when the detection is non recursive. Here we test that it cannot look into subdirectories of the test directory. """ pluginLocator = PluginFileLocator() pluginLocator.setPluginPlaces([ os.path.dirname(os.path.abspath(__file__))]) pluginLocator.disableRecursiveScan() spm = PluginManager() spm.setPluginLocator(pluginLocator) # load the plugins that may be found spm.collectPlugins() # check that the getCategories works self.assertEqual(len(spm.getCategories()),1) sole_category = spm.getCategories()[0] # check the getPluginsOfCategory self.assertEqual(len(spm.getPluginsOfCategory(sole_category)),0)
def testDisablingRecursivePluginLocationAllowsFindingTopLevelPlugins(self): """ Test detection of plugins when the detection is non recursive. Here we test that if we give test/plugin as the directory to scan it can find the plugin. """ pluginLocator = PluginFileLocator() pluginLocator.setPluginPlaces([ os.path.join( os.path.dirname(os.path.abspath(__file__)),"plugins")]) pluginLocator.disableRecursiveScan() spm = PluginManager() spm.setPluginLocator(pluginLocator) # load the plugins that may be found spm.collectPlugins() # check that the getCategories works self.assertEqual(len(spm.getCategories()),1) sole_category = spm.getCategories()[0] # check the getPluginsOfCategory self.assertEqual(len(spm.getPluginsOfCategory(sole_category)),1)
def test_locatePlugins_recursively_when_plugin_parent_dir_is_a_symlinked_directory(self): # This actually reproduced the "Plugin detection doesn't follow symlinks" bug # at http://sourceforge.net/p/yapsy/bugs/19/ temp_dir = tempfile.mkdtemp() try: temp_sub_dir = os.path.join(temp_dir,"plugins") os.symlink(self.plugin_as_dir_directory,temp_sub_dir) pl = PluginFileLocator() pl.setPluginPlaces([temp_dir]) candidates, num = pl.locatePlugins() self.assertEqual(num,1) self.assertEqual(len(candidates),num) self.assertEqual(os.path.join(temp_sub_dir,self.plugin_info_file), candidates[0][0]) self.assertEqual(os.path.join(temp_sub_dir,self.plugin_name, "__init__"), candidates[0][1]) self.assertTrue(isinstance(candidates[0][2],PluginInfo)) finally: shutil.rmtree(temp_dir)
def test_locatePlugins_recursively_when_plugin_parent_dir_is_a_symlinked_directory( self): # This actually reproduced the "Plugin detection doesn't follow symlinks" bug # at http://sourceforge.net/p/yapsy/bugs/19/ temp_dir = tempfile.mkdtemp() try: temp_sub_dir = os.path.join(temp_dir, "plugins") os.symlink(self.plugin_as_dir_directory, temp_sub_dir) pl = PluginFileLocator() pl.setPluginPlaces([temp_dir]) candidates, num = pl.locatePlugins() self.assertEqual(num, 1) self.assertEqual(len(candidates), num) self.assertEqual(os.path.join(temp_sub_dir, self.plugin_info_file), candidates[0][0]) self.assertEqual( os.path.join(temp_sub_dir, self.plugin_name, "__init__"), candidates[0][1]) self.assertTrue(isinstance(candidates[0][2], PluginInfo)) finally: shutil.rmtree(temp_dir)
def _locatorDecide(self, plugin_info_ext, plugin_locator): """ For backward compatibility, we kept the *plugin_info_ext* argument. Thus we may use it if provided. Returns the (possibly modified) *plugin_locator*. """ specific_info_ext = plugin_info_ext is not None specific_locator = plugin_locator is not None if not specific_info_ext and not specific_locator: # use the default behavior res = PluginFileLocator() elif not specific_info_ext and specific_locator: # plugin_info_ext not used res = plugin_locator elif not specific_locator and specific_info_ext: # plugin_locator not used, and plugin_info_ext provided # -> compatibility mode res = PluginFileLocator() res.setAnalyzers([PluginFileAnalyzerWithInfoFile("info_ext",plugin_info_ext)]) elif specific_info_ext and specific_locator: # both provided... issue a warning that tells "plugin_info_ext" # will be ignored msg = ("Two incompatible arguments (%s) provided:", "'plugin_info_ext' and 'plugin_locator'). Ignoring", "'plugin_info_ext'.") raise ValueError(" ".join(msg) % self.__class__.__name__) return res
def test_removeAllAnalyzers(self): pl = PluginFileLocator() pl.setPluginPlaces([self.plugin_directory]) pl.removeAllAnalyzer() candidates, num = pl.locatePlugins() self.assertEqual(num,0) self.assertEqual(len(candidates),num)
def test_locatePlugins_when_plugin_is_a_symlinked_directory(self): if "win" in sys.platform: return temp_dir = tempfile.mkdtemp() try: plugin_info_file = "simpleplugin.yapsy-plugin" plugin_impl_dir = "SimplePlugin" os.symlink(os.path.join(self.plugin_as_dir_directory,plugin_info_file), os.path.join(temp_dir,plugin_info_file)) os.symlink(os.path.join(self.plugin_as_dir_directory,plugin_impl_dir), os.path.join(temp_dir,plugin_impl_dir)) pl = PluginFileLocator() pl.setPluginPlaces([temp_dir]) candidates, num = pl.locatePlugins() self.assertEqual(num,1) self.assertEqual(len(candidates),num) self.assertEqual(os.path.join(temp_dir,self.plugin_info_file), candidates[0][0]) self.assertEqual(os.path.join(temp_dir,self.plugin_name,"__init__"), candidates[0][1]) self.assertTrue(isinstance(candidates[0][2],PluginInfo)) finally: shutil.rmtree(temp_dir)
def test_locatePlugins_when_plugin_is_symlinked(self): if "win" in sys.platform: return temp_dir = tempfile.mkdtemp() try: plugin_info_file = "simpleplugin.yapsy-plugin" plugin_impl_file = "SimplePlugin.py" os.symlink(os.path.join(self.plugin_directory, plugin_info_file), os.path.join(temp_dir, plugin_info_file)) os.symlink(os.path.join(self.plugin_directory, plugin_impl_file), os.path.join(temp_dir, plugin_impl_file)) pl = PluginFileLocator() pl.setPluginPlaces([temp_dir]) candidates, num = pl.locatePlugins() self.assertEqual(num, 1) self.assertEqual(len(candidates), num) self.assertEqual(os.path.join(temp_dir, self.plugin_info_file), candidates[0][0]) self.assertEqual(os.path.join(temp_dir, self.plugin_name), candidates[0][1]) self.assertTrue(isinstance(candidates[0][2], PluginInfo)) finally: shutil.rmtree(temp_dir)
def test_locatePlugins_recursively_fails_when_recursion_is_disabled(self): temp_dir = tempfile.mkdtemp() try: temp_sub_dir = os.path.join(temp_dir, "plugins") shutil.copytree(self.plugin_as_dir_directory, temp_sub_dir) pl = PluginFileLocator() pl.disableRecursiveScan() pl.setPluginPlaces([temp_dir]) candidates, num = pl.locatePlugins() self.assertEqual(num, 0) self.assertEqual(len(candidates), num) finally: shutil.rmtree(temp_dir)
def test_setPluginInfoClass_for_named_analyzer(self): class SpecificPluginInfo(PluginInfo): pass pl = PluginFileLocator() pl.setPluginPlaces([self.plugin_directory]) newAnalyzer = PluginFileAnalyzerMathingRegex("mouf",r".*VersionedPlugin\d+\.py$") pl.appendAnalyzer(newAnalyzer) pl.setPluginInfoClass(SpecificPluginInfo,"info_ext") candidates, num = pl.locatePlugins() self.assertEqual(num,5) self.assertEqual(len(candidates),num) versioned_plugins = [c for c in candidates if "VersionedPlugin" in c[0]] self.assertEqual(4,len(versioned_plugins)) for p in versioned_plugins: self.assertTrue(isinstance(p[2],PluginInfo)) simple_plugins = [c for c in candidates if "VersionedPlugin" not in c[0]] self.assertEqual(1,len(simple_plugins)) for p in simple_plugins: self.assertTrue(isinstance(p[2],SpecificPluginInfo))
def __init__(self, bot_config, category, base_class, base_search_dir, extra_search_dirs=()): self._config = bot_config # set a locator that gets every possible backends as a first discovery pass. self._locator = PluginFileLocator(analyzers=[PluginFileAnalyzerWithInfoFile('SpecificLocator', 'plug')]) self._locator.disableRecursiveScan() # This is done below correctly with find_roots_with_extra super().__init__(plugin_locator=self._locator) self.setCategoriesFilter({category: base_class}) all_plugins_paths = collect_roots((base_search_dir, extra_search_dirs)) log.info('%s search paths %s', category, all_plugins_paths) self.setPluginPlaces(all_plugins_paths) for entry in all_plugins_paths: if entry not in sys.path: sys.path.append(entry) # so backends can relatively import their submodules self.locatePlugins() log.info('Found those plugings available:') for (_, _, plug) in self.getPluginCandidates(): log.info('\t%10s (%s)' % (plug.name, plug.path + '.py'))
def test_locatePlugins_recursively_fails_when_recursion_is_disabled(self): temp_dir = tempfile.mkdtemp() try: temp_sub_dir = os.path.join(temp_dir,"plugins") shutil.copytree(self.plugin_as_dir_directory,temp_sub_dir) pl = PluginFileLocator() pl.disableRecursiveScan() pl.setPluginPlaces([temp_dir]) candidates, num = pl.locatePlugins() self.assertEqual(num,0) self.assertEqual(len(candidates),num) finally: shutil.rmtree(temp_dir)
def __init__(self, config): self._config = config # set a locator that gets every possible backends as a first discovery pass. self._locator = PluginFileLocator(analyzers=[PluginFileAnalyzerWithInfoFile('AllBackendLocator', 'plug')]) super().__init__(plugin_locator=self._locator) self.setCategoriesFilter({'backend': ErrBot}) if hasattr(config, 'BOT_EXTRA_BACKEND_DIR'): extra = config.BOT_EXTRA_BACKEND_DIR else: extra = [] all_backends_paths = find_roots_with_extra(CORE_BACKENDS, extra) log.info('Backends search paths %s', all_backends_paths) self.setPluginPlaces(all_backends_paths) for entry in all_backends_paths: if entry not in sys.path: sys.path.append(entry) # so backends can relatively import their submodules self.locatePlugins() log.info('Found those backends available:') for (_, _, plug) in self.getPluginCandidates(): log.info('\t%10s (%s)' % (plug.name, plug.path + '.py'))
def scan_plugins(): global _plugin_toc _plugin_toc = {} # Load the plugins from the plugin directory. analyzer = PluginFileAnalyzerMathingRegex('', '.*\\.py$') plugin_locator = PluginFileLocator(analyzers=[analyzer]) manager = PluginManager(plugin_locator=plugin_locator) plugin_dirs = _get_plugin_dirs() logging.info('Loading plugins in %s' % str(plugin_dirs)) manager.setPluginPlaces(plugin_dirs) manager.collectPlugins() # Loop round the plugins and print their names. for plugin in manager.getAllPlugins(): plugin_info = plugin.plugin_object.get_plugin_info() for item in plugin_info: k = _get_item_key(item['class_type'], item['class_name']) _plugin_toc[k] = item logging.debug('p3_plugin_manager: _plugin_toc=%s' % _plugin_toc)
def testEnforcingPluginDirsDoesNotKeepDefaultDir(self): """ Test that providing the directories list override the default search directory instead of extending the default list. """ class AcceptAllPluginFileAnalyzer(IPluginFileAnalyzer): def __init__(self): IPluginFileAnalyzer.__init__(self, "AcceptAll") def isValidPlugin(self, filename): return True def getInfosDictFromPlugin(self, dirpath, filename): return {"name": filename, "path": dirpath}, ConfigParser() pluginLocator = PluginFileLocator() pluginLocator.setAnalyzers([AcceptAllPluginFileAnalyzer()]) spm_default_dirs = PluginManager(plugin_locator=pluginLocator) spm_default_dirs.locatePlugins() candidates_in_default_dir = spm_default_dirs.getPluginCandidates() candidates_files_in_default_dir = set( [c[0] for c in candidates_in_default_dir]) pluginLocator = PluginFileLocator() pluginLocator.setAnalyzers([AcceptAllPluginFileAnalyzer()]) spm = PluginManager(plugin_locator=pluginLocator, directories_list=[ os.path.dirname(os.path.abspath(__file__)), "does-not-exists" ]) spm.locatePlugins() candidates = spm.getPluginCandidates() candidates_files = set([c[0] for c in candidates]) self.assertFalse( set(candidates_files_in_default_dir).issubset( set(candidates_files)))
def testNonRecursivePluginlocationNotFound(self): """ Test detection of plugins when the detection is non recursive. Here we test that it cannot look into subdirectories of the test directory. """ pluginLocator = PluginFileLocator() pluginLocator.setPluginPlaces( [os.path.dirname(os.path.abspath(__file__))]) pluginLocator.disableRecursiveScan() spm = PluginManager() spm.setPluginLocator(pluginLocator) # load the plugins that may be found spm.collectPlugins() # check that the getCategories works self.assertEqual(len(spm.getCategories()), 1) sole_category = spm.getCategories()[0] # check the getPluginsOfCategory self.assertEqual(len(spm.getPluginsOfCategory(sole_category)), 0)
def testDisablingRecursivePluginLocationAllowsFindingTopLevelPlugins(self): """ Test detection of plugins when the detection is non recursive. Here we test that if we give test/plugin as the directory to scan it can find the plugin. """ pluginLocator = PluginFileLocator() pluginLocator.setPluginPlaces([ os.path.join(os.path.dirname(os.path.abspath(__file__)), "plugins") ]) pluginLocator.disableRecursiveScan() spm = PluginManager() spm.setPluginLocator(pluginLocator) # load the plugins that may be found spm.collectPlugins() # check that the getCategories works self.assertEqual(len(spm.getCategories()), 1) sole_category = spm.getCategories()[0] # check the getPluginsOfCategory self.assertEqual(len(spm.getPluginsOfCategory(sole_category)), 1)
def test_locatePlugins(self): pl = PluginFileLocator() pl.setPluginPlaces([self.plugin_directory]) candidates, num = pl.locatePlugins() self.assertEqual(num,1) self.assertEqual(len(candidates),num)
def test_removeAnalyzers_when_analyzer_is_unknown(self): pl = PluginFileLocator() pl.setPluginPlaces([self.plugin_directory]) pl.removeAnalyzers("nogo")
def test_given_string_as_plugin_places_raises_error(self): pl = PluginFileLocator() self.assertRaises(ValueError, pl.setPluginPlaces, "/mouf")
def _getInfoForPluginFromAnalyzer(self, analyzer, dirpath, filename): try: return PluginFileLocator._getInfoForPluginFromAnalyzer(self, analyzer, dirpath, filename) except ValueError: logger.exception("fail to load plugin [%s]" % (filename,))
:raises DeviceError: if a bootloader installation command has an error. """ pass def get_help(self): """Returns the help message for this plugin. It is optional to override this. :returns: a string representing the help message for this plugin.""" return "Installs the {0} bootloader.".format(self.prettyName) dirs = [ "/usr/local/weresync/plugins", os.path.dirname(__file__), get_python_lib() ] regex_analyzer = PluginFileAnalyzerMathingRegex("regex", "^weresync_.*\.py$") locator = PluginFileLocator([regex_analyzer]) __manager = PluginManager(categories_filter={"bootloader": IBootPlugin}, directories_list=dirs, plugin_locator=locator) def get_manager(): """Returns the PluginManager for this instance of WereSync""" return __manager
def test_default_plugins_place_is_parent_dir(self): """Test a non-trivial default behaviour introduced some time ago :S""" pl = PluginFileLocator() expected_yapsy_module_path = os.path.dirname(yapsy.__file__) first_plugin_place = pl.plugins_places[0] self.assertEqual(expected_yapsy_module_path, first_plugin_place)
def test_default_plugins_place_is_parent_dir(self): """Test a non-trivial default behaviour introduced some time ago :S""" pl = PluginFileLocator() self.assertTrue("package/yapsy" in pl.plugins_places[0])