Exemple #1
0
        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
Exemple #2
0
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'])
Exemple #7
0
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
Exemple #10
0
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'])
Exemple #12
0
    {'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')