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, 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)
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 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 = 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 _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_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_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, 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__(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 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 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 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)