def wrapper(self, *args, **kwargs): if not getattr(self, '_loaded', False): # This block is executed on the first call to the function. # The return value of the call (or exception raised) is saved # as attributes on the wrapper for future invocations. self._loaded = True self._return = None try: result = func(self, *args, **kwargs) except Exception: self._loaded = False # If any errors occur in loading the plugin, log the information, and # store failure information that can be queried through the api. logprint.exception('Failed to load plugin %s' % self.name) self._pluginFailureInfo = sys.exc_info() raise _pluginLoadOrder.append(self.name) self._return = result self._success = True logprint.success('Loaded plugin "%s"' % self.name) return self._return
def loadPlugins(plugins, root, appconf, apiRoot=None, curConfig=None, buildDag=True): """ Loads a set of plugins into the application. :param plugins: The set of plugins to load, by directory name. :type plugins: list :param root: The root node of the server tree. :type root: object :param appconf: The server's cherrypy configuration object. :type appconf: dict :param apiRoot: The cherrypy api root object. :type apiRoot: object or None :param curConfig: A girder config object to use. :type curConfig: dict or None :param buildDag: If the ``plugins`` parameter is already a topo-sorted list with all dependencies resolved, set this to False and it will skip rebuilding the DAG. Otherwise the dependency resolution and sorting will occur within this method. :type buildDag: bool :returns: A 3-tuple containing the modified root, config, and apiRoot objects. :rtype tuple: """ # Register a pseudo-package for the root of all plugins. This must be # present in the system module list in order to avoid import warnings. if curConfig is None: curConfig = _config.getConfig() if 'plugins' in curConfig and 'plugin_directory' in curConfig['plugins']: logprint.warning( 'Warning: the plugin_directory setting is deprecated. Please use ' 'the `girder-install plugin` command and remove this setting from ' 'your config file.') if ROOT_PLUGINS_PACKAGE not in sys.modules: module = imp.new_module(ROOT_PLUGINS_PACKAGE) girder.plugins = module sys.modules[ROOT_PLUGINS_PACKAGE] = module logprint.info('Resolving plugin dependencies...') if buildDag: plugins = getToposortedPlugins(plugins, curConfig, ignoreMissing=True) for plugin in plugins: try: root, appconf, apiRoot = loadPlugin( plugin, root, appconf, apiRoot, curConfig=curConfig) logprint.success('Loaded plugin "%s"' % plugin) except Exception: logprint.exception( 'ERROR: Failed to load plugin "%s":' % plugin) return root, appconf, apiRoot
def findAllPlugins(): """ Walks the plugin directory to find all of the plugins. If the plugin has a plugin.json/yml file, this reads that file to determine dependencies. """ allPlugins = {} findEntryPointPlugins(allPlugins) pluginDir = getPluginDir() for plugin in os.listdir(pluginDir): path = os.path.join(pluginDir, plugin) if not os.path.isdir( path): # this also allows for symlinked directories continue data = {} configJson = os.path.join(path, 'plugin.json') configYml = os.path.join(path, 'plugin.yml') if os.path.isfile(configJson): with open(configJson) as conf: try: data = json.load(conf) except ValueError: _recordPluginFailureInfo(plugin=plugin, traceback=traceback.format_exc()) logprint.exception( 'ERROR: Plugin "%s": plugin.json is not valid ' 'JSON.' % plugin) elif os.path.isfile(configYml): with open(configYml) as conf: try: data = yaml.safe_load(conf) except yaml.YAMLError: _recordPluginFailureInfo(plugin=plugin, traceback=traceback.format_exc()) logprint.exception( 'ERROR: Plugin "%s": plugin.yml is not valid ' 'YAML.' % plugin) allPlugins[plugin] = { 'name': data.get('name', plugin), 'description': data.get('description', ''), 'url': data.get('url', ''), 'version': data.get('version', ''), 'dependencies': set(data.get('dependencies', [])), 'staticWebDependencies': set(data.get('staticWebDependencies', [])) } return allPlugins
def findAllPlugins(): """ Walks the plugin directory to find all of the plugins. If the plugin has a plugin.json/yml file, this reads that file to determine dependencies. """ allPlugins = {} findEntryPointPlugins(allPlugins) pluginDir = getPluginDir() for plugin in os.listdir(pluginDir): path = os.path.join(pluginDir, plugin) if not os.path.isdir(path): # this also allows for symlinked directories continue data = {} configJson = os.path.join(path, 'plugin.json') configYml = os.path.join(path, 'plugin.yml') if os.path.isfile(configJson): with open(configJson) as conf: try: data = json.load(conf) except ValueError: _recordPluginFailureInfo(plugin=plugin, traceback=traceback.format_exc()) logprint.exception( 'ERROR: Plugin "%s": plugin.json is not valid ' 'JSON.' % plugin) elif os.path.isfile(configYml): with open(configYml) as conf: try: data = yaml.safe_load(conf) except yaml.YAMLError: _recordPluginFailureInfo(plugin=plugin, traceback=traceback.format_exc()) logprint.exception( 'ERROR: Plugin "%s": plugin.yml is not valid ' 'YAML.' % plugin) allPlugins[plugin] = { 'name': data.get('name', plugin), 'description': data.get('description', ''), 'url': data.get('url', ''), 'version': data.get('version', ''), 'dependencies': set(data.get('dependencies', [])), 'staticWebDependencies': set(data.get('staticWebDependencies', [])) } return allPlugins
def findEntryPointPlugins(allPlugins): # look for plugins enabled via setuptools `entry_points` for entry_point in iter_entry_points(group='girder.plugin'): # set defaults allPlugins[entry_point.name] = { 'name': entry_point.name, 'description': '', 'version': '', 'dependencies': set() } configJson = os.path.join('girder', 'plugin.json') configYml = os.path.join('girder', 'plugin.yml') data = {} try: if pkg_resources.resource_exists(entry_point.name, configJson): with pkg_resources.resource_stream( entry_point.name, configJson) as conf: try: data = json.load(codecs.getreader('utf8')(conf)) except ValueError: _recordPluginFailureInfo( plugin=entry_point.name, traceback=traceback.format_exc()) logprint.exception( 'ERROR: Plugin "%s": plugin.json is not valid ' 'JSON.' % entry_point.name) elif pkg_resources.resource_exists(entry_point.name, configYml): with pkg_resources.resource_stream( entry_point.name, configYml) as conf: try: data = yaml.safe_load(conf) except yaml.YAMLError: _recordPluginFailureInfo( plugin=entry_point.name, traceback=traceback.format_exc()) logprint.exception( 'ERROR: Plugin "%s": plugin.yml is not valid ' 'YAML.' % entry_point.name) except ImportError: pass if data == {}: data = getattr(entry_point.load(), 'config', {}) allPlugins[entry_point.name].update(data) allPlugins[entry_point.name]['dependencies'] = set( allPlugins[entry_point.name]['dependencies'])
def findEntryPointPlugins(allPlugins): # look for plugins enabled via setuptools `entry_points` for entry_point in iter_entry_points(group='girder.plugin'): # set defaults allPlugins[entry_point.name] = { 'name': entry_point.name, 'description': '', 'version': '', 'dependencies': set() } configJson = os.path.join('girder', 'plugin.json') configYml = os.path.join('girder', 'plugin.yml') data = {} try: if pkg_resources.resource_exists(entry_point.name, configJson): with pkg_resources.resource_stream(entry_point.name, configJson) as conf: try: data = json.load(codecs.getreader('utf8')(conf)) except ValueError: _recordPluginFailureInfo( plugin=entry_point.name, traceback=traceback.format_exc()) logprint.exception( 'ERROR: Plugin "%s": plugin.json is not valid ' 'JSON.' % entry_point.name) elif pkg_resources.resource_exists(entry_point.name, configYml): with pkg_resources.resource_stream(entry_point.name, configYml) as conf: try: data = yaml.safe_load(conf) except yaml.YAMLError: _recordPluginFailureInfo( plugin=entry_point.name, traceback=traceback.format_exc()) logprint.exception( 'ERROR: Plugin "%s": plugin.yml is not valid ' 'YAML.' % entry_point.name) except ImportError: pass if data == {}: data = getattr(entry_point.load(), 'config', {}) allPlugins[entry_point.name].update(data) allPlugins[entry_point.name]['dependencies'] = set( allPlugins[entry_point.name]['dependencies'])
def findAllPlugins(curConfig=None): """ Walks the plugins directories to find all of the plugins. If the plugin has a plugin.json file, this reads that file to determine dependencies. """ allPlugins = {} findEntryPointPlugins(allPlugins) pluginDirs = getPluginDirs(curConfig) if not pluginDirs: logprint.warning('Plugin directory not found.') return allPlugins for pluginDir in pluginDirs: dirs = [dir for dir in os.listdir(pluginDir) if os.path.isdir( os.path.join(pluginDir, dir))] for plugin in dirs: data = {} configJson = os.path.join(pluginDir, plugin, 'plugin.json') configYml = os.path.join(pluginDir, plugin, 'plugin.yml') if os.path.isfile(configJson): with open(configJson) as conf: try: data = json.load(conf) except ValueError: logprint.exception( 'ERROR: Plugin "%s": plugin.json is not valid ' 'JSON.' % plugin) elif os.path.isfile(configYml): with open(configYml) as conf: try: data = yaml.safe_load(conf) except yaml.YAMLError: logprint.exception( 'ERROR: Plugin "%s": plugin.yml is not valid ' 'YAML.' % plugin) allPlugins[plugin] = { 'name': data.get('name', plugin), 'description': data.get('description', ''), 'version': data.get('version', ''), 'dependencies': set(data.get('dependencies', [])) } return allPlugins
def loadPlugins(plugins, root, appconf, apiRoot=None, buildDag=True): """ Loads a set of plugins into the application. :param plugins: The set of plugins to load, by directory name. :type plugins: list :param root: The root node of the server tree. :type root: object :param appconf: The server's cherrypy configuration object. :type appconf: dict :param apiRoot: The cherrypy api root object. :type apiRoot: object or None :param buildDag: If the ``plugins`` parameter is already a topo-sorted list with all dependencies resolved, set this to False and it will skip rebuilding the DAG. Otherwise the dependency resolution and sorting will occur within this method. :type buildDag: bool :returns: A 3-tuple containing the modified root, config, and apiRoot objects. :rtype tuple: """ # Register a pseudo-package for the root of all plugins. This must be # present in the system module list in order to avoid import warnings. if ROOT_PLUGINS_PACKAGE not in sys.modules: module = imp.new_module(ROOT_PLUGINS_PACKAGE) girder.plugins = module sys.modules[ROOT_PLUGINS_PACKAGE] = module logprint.info('Resolving plugin dependencies...') if buildDag: plugins = getToposortedPlugins(plugins, ignoreMissing=True) for plugin in plugins: try: root, appconf, apiRoot = loadPlugin(plugin, root, appconf, apiRoot) _clearPluginFailureInfo(plugin=plugin) logprint.success('Loaded plugin "%s"' % plugin) except Exception: _recordPluginFailureInfo(plugin=plugin, traceback=traceback.format_exc()) logprint.exception('ERROR: Failed to load plugin "%s":' % plugin) return root, appconf, apiRoot
def loadPlugins(plugins, root, appconf, apiRoot=None, buildDag=True): """ Loads a set of plugins into the application. :param plugins: The set of plugins to load, by directory name. :type plugins: list :param root: The root node of the server tree. :type root: object :param appconf: The server's cherrypy configuration object. :type appconf: dict :param apiRoot: The cherrypy api root object. :type apiRoot: object or None :param buildDag: If the ``plugins`` parameter is already a topo-sorted list with all dependencies resolved, set this to False and it will skip rebuilding the DAG. Otherwise the dependency resolution and sorting will occur within this method. :type buildDag: bool :returns: A 3-tuple containing the modified root, config, and apiRoot objects. :rtype tuple: """ # Register a pseudo-package for the root of all plugins. This must be # present in the system module list in order to avoid import warnings. if ROOT_PLUGINS_PACKAGE not in sys.modules: module = imp.new_module(ROOT_PLUGINS_PACKAGE) girder.plugins = module sys.modules[ROOT_PLUGINS_PACKAGE] = module logprint.info('Resolving plugin dependencies...') if buildDag: plugins = getToposortedPlugins(plugins, ignoreMissing=True) for plugin in plugins: try: root, appconf, apiRoot = loadPlugin(plugin, root, appconf, apiRoot) _clearPluginFailureInfo(plugin=plugin) logprint.success('Loaded plugin "%s"' % plugin) except Exception: _recordPluginFailureInfo(plugin=plugin, traceback=traceback.format_exc()) logprint.exception('ERROR: Failed to load plugin "%s":' % plugin) return root, appconf, apiRoot
def findEntryPointPlugins(allPlugins): # look for plugins enabled via setuptools `entry_points` for entry_point in iter_entry_points(group='girder.plugin'): # set defaults allPlugins[entry_point.name] = { 'name': entry_point.name, 'description': '', 'version': '', 'dependencies': set() } configJson = os.path.join('girder', 'plugin.json') configYml = os.path.join('girder', 'plugin.yml') data = {} try: if pkg_resources.resource_exists(entry_point.name, configJson): with pkg_resources.resource_stream(entry_point.name, configJson) as conf: try: data = json.load(codecs.getreader('utf8')(conf)) except ValueError: _recordPluginFailureInfo( plugin=entry_point.name, traceback=traceback.format_exc()) logprint.exception( 'ERROR: Plugin "%s": plugin.json is not valid ' 'JSON.' % entry_point.name) elif pkg_resources.resource_exists(entry_point.name, configYml): with pkg_resources.resource_stream(entry_point.name, configYml) as conf: try: data = yaml.safe_load(conf) except yaml.YAMLError: _recordPluginFailureInfo( plugin=entry_point.name, traceback=traceback.format_exc()) logprint.exception( 'ERROR: Plugin "%s": plugin.yml is not valid ' 'YAML.' % entry_point.name) except (ImportError, SystemError): # Fall through and just try to load the entry point below. If # there is still an error, we'll log it there. pass if data == {}: try: data = getattr(entry_point.load(), 'config', {}) except (ImportError, SystemError): # If the plugin failed to load via entrypoint, but is in the # plugins directory, it may still load. We mark and report the # failure; if it loads later, the failure will be cleared, but # the report is still desired. _recordPluginFailureInfo(plugin=entry_point.name, traceback=traceback.format_exc()) logprint.exception( 'ERROR: Plugin "%s": could not be loaded by entrypoint.' % entry_point.name) continue allPlugins[entry_point.name].update(data) allPlugins[entry_point.name]['dependencies'] = set( allPlugins[entry_point.name]['dependencies'])
def findEntryPointPlugins(allPlugins): # look for plugins enabled via setuptools `entry_points` for entry_point in iter_entry_points(group='girder.plugin'): # set defaults allPlugins[entry_point.name] = { 'name': entry_point.name, 'description': '', 'version': '', 'dependencies': set() } configJson = os.path.join('girder', 'plugin.json') configYml = os.path.join('girder', 'plugin.yml') data = {} try: if pkg_resources.resource_exists(entry_point.name, configJson): with pkg_resources.resource_stream( entry_point.name, configJson) as conf: try: data = json.load(codecs.getreader('utf8')(conf)) except ValueError: _recordPluginFailureInfo( plugin=entry_point.name, traceback=traceback.format_exc()) logprint.exception( 'ERROR: Plugin "%s": plugin.json is not valid ' 'JSON.' % entry_point.name) elif pkg_resources.resource_exists(entry_point.name, configYml): with pkg_resources.resource_stream( entry_point.name, configYml) as conf: try: data = yaml.safe_load(conf) except yaml.YAMLError: _recordPluginFailureInfo( plugin=entry_point.name, traceback=traceback.format_exc()) logprint.exception( 'ERROR: Plugin "%s": plugin.yml is not valid ' 'YAML.' % entry_point.name) except (ImportError, SystemError): # Fall through and just try to load the entry point below. If # there is still an error, we'll log it there. pass if data == {}: try: data = getattr(entry_point.load(), 'config', {}) except (ImportError, SystemError): # If the plugin failed to load via entrypoint, but is in the # plugins directory, it may still load. We mark and report the # failure; if it loads later, the failure will be cleared, but # the report is still desired. _recordPluginFailureInfo( plugin=entry_point.name, traceback=traceback.format_exc()) logprint.exception( 'ERROR: Plugin "%s": could not be loaded by entrypoint.' % entry_point.name) continue allPlugins[entry_point.name].update(data) allPlugins[entry_point.name]['dependencies'] = set( allPlugins[entry_point.name]['dependencies'])
{'moduleName': '.dummy', 'className': 'DummyTileSource'}, ] for source in sourceList: try: # Don't try to load girder sources if we couldn't import girder if not girder and source.get('girder'): continue # For each of our sources, try to import the named class from the # source module className = source['className'] sourceModule = __import__( source['moduleName'].lstrip('.'), globals(), locals(), [className], len(source['moduleName']) - len(source['moduleName'].lstrip('.'))) sourceClass = getattr(sourceModule, className) # Add the source class to the locals name so that it can be reached by # importing the tilesource module locals().update({className: sourceClass}) # add it to our list of exports __all__.append(className) # add it to our dictionary of available sources if it has a name if getattr(sourceClass, 'name', None): AvailableTileSources[sourceClass.name] = sourceClass except ImportError: logprint.exception('Error: Could not import %s' % className) # Create a partial function that will work through the known functions to get a # tile source. getTileSource = functools.partial(getTileSourceFromDict, AvailableTileSources) __all__.append('getTileSource')