Source code for scipion.install.inspect_plugins

#!/usr/bin/env python
# **************************************************************************
# *
# * Authors:     J.M. De la Rosa Trevin (delarosatrevin@scilifelab.se) [1]
# *
# * [1] SciLifeLab, Stockholm University
# *
# * This program is free software; you can redistribute it and/or modify
# * it under the terms of the GNU General Public License as published by
# * the Free Software Foundation; either version 3 of the License, or
# * (at your option) any later version.
# *
# * This program is distributed in the hope that it will be useful,
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# * GNU General Public License for more details.
# *
# * You should have received a copy of the GNU General Public License
# * along with this program; if not, write to the Free Software
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
# * 02111-1307  USA
# *
# *  All comments concerning this program package may be sent to the
# *  e-mail address 'scipion@cnb.csic.es'
# *
# **************************************************************************


import sys
from os.path import join, exists, dirname
import importlib
import inspect
import traceback
from collections import OrderedDict

from pwem.protocols import (Prot3D, Prot2D, ProtParticles,
                            ProtMicrographs, ProtImport)
from pwem import Domain
from pyworkflow.protocol import Protocol
import pyworkflow.utils as pwutils

from scipion.install.plugin_funcs import PluginInfo

ERROR_PREFIX = " error -> %s"

[docs]def usage(error=""): exitCode =0 if error: error = "ERROR: %s\n" % error exitCode = 1 print("""%s Usage: scipion3 python -m scipion.install.inspect_plugins [h]|[all]|[PLUGIN-NAME] [info] [--showBase] Without parameters this will show the list of avaialble plugins. With 'all' will print all objects discovered (protocols, viewers, wizards, objects) With 'h' will print this help maessage. If a PLUGIN-NAME is passed, it will inspect that plugin in more detail. Useful to discover loading time errors of the plugin. - 'info' argument will print plugin summary of the plugin, - '-showBase' will print Base class protocols (hidden by default). """ % error) sys.exit(exitCode)
[docs]def getSubmodule(plugin, name, subname): """ Return a tuple: (module, error) If module is None: 1) if error is None is that the submodule does not exist 2) if error is not None, it is an Exception raised when importing the submodule """ try: m = importlib.import_module('%s.%s' % (name, subname)) r = (m, None) except Exception as e: noModuleMsg = 'No module named \'%s.%s\'' % (name, subname) msg = str(e) moduleExists = (exists(join(dirname(plugin.__file__), "%s.py" % subname)) or exists(join(dirname(plugin.__file__), subname))) r = (None, None if msg == noModuleMsg and not moduleExists else traceback.format_exc()) return r
[docs]def getFirstLine(doc): """ Get the first non-empty line from doc. """ if doc: for lines in doc.split('\n'): l = lines.strip() if l: return l return ''
[docs]def inspectPlugin(args): exitWithErrors = False n = len(args) if n > 4: usage("Incorrect number of input parameters") if n == 1: # List all plugins printPlugins() elif n == 2: firstArg = args[1] if firstArg in ['-h', 'h', '--help', 'help']: usage() elif firstArg in ['all', '-all', '--all']: listAllPlugins() pluginName = args[1] exitWithErrors = showPluginInfo(exitWithErrors, pluginName) elif n > 2: exitWithErrors = showInfo(args, exitWithErrors, n) if exitWithErrors: sys.exit(1) else: sys.exit(0)
[docs]def showPluginInfo(exitWithErrors, pluginName): plugin = Domain.getPluginModule(pluginName) print("Plugin: %s" % pluginName) for subName in ['constants', 'convert', 'protocols', 'wizards', 'viewers', 'tests']: sub, error = getSubmodule(plugin, pluginName, subName) if sub is None: if error is None: msg = " missing" else: exitWithErrors = True msg = ERROR_PREFIX % error else: msg = " loaded" print(" >>> %s: %s" % (subName, msg)) return exitWithErrors
[docs]def showInfo(args, anyError, n): pluginName = args[1] showBase = True if (n == 4 and args[3] == '--showBase') else False plugin = Domain.getPluginModule(pluginName) pluginInfo = PluginInfo('scipion-em-%s' % pluginName) version = pluginInfo.pipVersion bin = pluginInfo.printBinInfoStr() print("Plugin name: %s, version: %s" % (pluginName, version)) print("Plugin binaries: %s" % bin) anyError = showReferences(anyError, plugin, pluginName) anyError = showProtocols(anyError, plugin, pluginName, showBase) return anyError
[docs]def showProtocols(anyError, plugin, pluginName, showBase): subclasses=dict() sub, error = getSubmodule(plugin, pluginName, 'protocols') if sub is None: anyError = error is not None else: for name in dir(sub): attr = getattr(sub, name) if inspect.isclass(attr) and issubclass(attr, Protocol): # Set this special property used by Scipion attr._package = plugin attr._plugin = plugin.Plugin() subclasses[name] = attr print("Plugin protocols:\n") print("%-35s %-35s %-s" % ( 'NAME', 'LABEL', 'DESCRIPTION')) prots = OrderedDict(sorted(subclasses.items())) for prot in prots: label = prots[prot].getClassLabel() desc = getFirstLine(prots[prot].__doc__) # skip Base protocols if not requested if prots[prot].isBase() and not showBase: continue else: print("%-35s %-35s %-s" % (prot, label, desc)) return anyError
[docs]def showReferences(anyError, plugin, pluginName): bib, error2 = getSubmodule(plugin, pluginName, 'bibtex') if bib is None: anyError = error2 is not None else: print("Plugin references:") bibtex = pwutils.parseBibTex(bib.__doc__) for citeStr in bibtex: text = Protocol()._getCiteText(bibtex[citeStr]) print(text) return anyError
[docs]def printPlugins(): """ Print all plugins found found """ plugins = Domain.getPlugins() print("Plugins:") print("scipion3 inspect <plugin-name-bellow> for a more detailed information about the plugin") for k, v in plugins.items(): print("-", k)
[docs]def listAllPlugins(): printPlugins() print("Objects") pwutils.prettyDict(Domain.getObjects()) print("Protocols") pwutils.prettyDict(Domain.getProtocols()) print("Viewers") pwutils.prettyDict(Domain.getViewers()) sys.exit(0)
if __name__ == '__main__': inspectPlugin(sys.argv)