def get_ui(self, version): actual_version = "1.0.0" if Utility.compare_versions(version, actual_version) > 0: raise NotImplementedError( "API requested version %s is greater than %s." % (version, actual_version)) return Declarative.DeclarativeUI()
def get_interactive(self, version=None): actual_version = "1.0.0" if Utility.compare_versions(version, actual_version) > 0: raise NotImplementedError( "API requested version %s is greater than %s." % (version, actual_version)) return interactive_session
def get_api(self, version): actual_version = "1.0.0" if Utility.compare_versions(version, actual_version) > 0: raise NotImplementedError("Camera API requested version %s is greater than %s." % (version, actual_version)) class CameraFacade: def __init__(self): pass return CameraFacade()
def load_plug_ins(document_location: str, data_location: str, root_dir: typing.Optional[str]) -> None: """Load plug-ins.""" global extensions # a list of directories in which sub-directories PlugIns will be searched. subdirectories = [] # the default location is where the directory main packages are located. if root_dir: subdirectories.append(root_dir) # also search the default data location; create directory there if it doesn't exist to make it easier for user. # default data location will be application specific. if data_location is not None: subdirectories.append(data_location) # create directories here if they don't exist plugins_dir = os.path.abspath(os.path.join(data_location, "PlugIns")) if not os.path.exists(plugins_dir): logging.info("Creating plug-ins directory %s", plugins_dir) os.makedirs(plugins_dir) # search the Nion/Swift subdirectory of the default document location too, # but don't create directories here - avoid polluting user visible directories. if document_location is not None: subdirectories.append(os.path.join(document_location, "Nion", "Swift")) # do not create them in documents if they don't exist. this location is optional. # build a list of directories that will be loaded as plug-ins. PlugInDir = collections.namedtuple("PlugInDir", ["directory", "relative_path"]) plugin_dirs = list() # track directories that have already been searched. seen_plugin_dirs = list() # for each subdirectory, look in PlugIns for sub-directories that represent the plug-ins. for subdirectory in subdirectories: plugins_dir = os.path.abspath(os.path.join(subdirectory, "PlugIns")) if os.path.exists(plugins_dir) and not plugins_dir in seen_plugin_dirs: logging.info("Loading plug-ins from %s", plugins_dir) # add the PlugIns directory to the system import path. sys.path.append(plugins_dir) # now build a list of sub-directories representing plug-ins within plugins_dir. sorted_relative_paths = sorted([d for d in os.listdir(plugins_dir) if os.path.isdir(os.path.join(plugins_dir, d))]) plugin_dirs.extend([PlugInDir(plugins_dir, sorted_relative_path) for sorted_relative_path in sorted_relative_paths]) # mark plugins_dir as 'seen' to avoid search it twice. seen_plugin_dirs.append(plugins_dir) else: logging.info("NOT Loading plug-ins from %s (missing)", plugins_dir) version_map: PersistentDictType = dict() module_exists_map: typing.Dict[str, bool] = dict() plugin_adapters: typing.List[typing.Union[ModuleAdapter, PlugInAdapter]] = list() import nionswift_plugin for module_info in pkgutil.iter_modules(getattr(nionswift_plugin, "__path__")): plugin_adapters.append(ModuleAdapter(getattr(nionswift_plugin, "__name__"), module_info)) for directory, relative_path in plugin_dirs: plugin_adapters.append(PlugInAdapter(directory, relative_path)) progress = True while progress: progress = False plugin_adapters_copy = copy.deepcopy(plugin_adapters) plugin_adapters = list() for plugin_adapter in plugin_adapters_copy: manifest_path = plugin_adapter.manifest_path manifest = plugin_adapter.manifest if manifest: manifest_valid = True if not "name" in manifest: logging.info("Invalid manifest (missing 'name'): %s", manifest_path) manifest_valid = False if not "identifier" in manifest: logging.info("Invalid manifest (missing 'identifier'): %s", manifest_path) manifest_valid = False if "identifier" in manifest and not re.match("[_\-a-zA-Z][_\-a-zA-Z0-9.]*$", manifest["identifier"]): logging.info("Invalid manifest (invalid 'identifier': '%s'): %s", manifest["identifier"], manifest_path) manifest_valid = False if not "version" in manifest: logging.info("Invalid manifest (missing 'version'): %s", manifest_path) manifest_valid = False if "requires" in manifest and not isinstance(manifest["requires"], list): logging.info("Invalid manifest ('requires' not a list): %s", manifest_path) manifest_valid = False if not manifest_valid: continue for module in manifest.get("modules", list()): if module in module_exists_map: module_exists = module_exists_map.get(module) else: module_exists = importlib.util.find_spec(module) is not None module_exists_map[module] = module_exists if not module_exists: logging.info("Plug-in '" + plugin_adapter.module_name + "' NOT loaded (" + plugin_adapter.module_path + ").") logging.info("Cannot satisfy requirement (%s): %s", module, manifest_path) manifest_valid = False break for requirement in manifest.get("requires", list()): # TODO: see https://packaging.pypa.io/en/latest/ requirement_components = requirement.split() if len(requirement_components) != 3 or requirement_components[1] != "~=": logging.info("Invalid manifest (requirement '%s' invalid): %s", requirement, manifest_path) manifest_valid = False break identifier, operator, version_specifier = requirement_components[0], requirement_components[1], requirement_components[2] if identifier in version_map: if Utility.compare_versions("~" + version_specifier, version_map[identifier]) != 0: logging.info("Plug-in '" + plugin_adapter.module_name + "' NOT loaded (" + plugin_adapter.module_path + ").") logging.info("Cannot satisfy requirement (%s): %s", requirement, manifest_path) manifest_valid = False break else: # requirements not loaded yet; add back to plugin_adapters, but don't mark progress since nothing was loaded. logging.info("Plug-in '" + plugin_adapter.module_name + "' delayed (%s) (" + plugin_adapter.module_path + ").", requirement) plugin_adapters.append(plugin_adapter) manifest_valid = False break if not manifest_valid: continue version_map[manifest["identifier"]] = manifest["version"] # read the manifests, if any # repeat loop of plug-ins until no plug-ins left in the list # if all dependencies satisfied for a plug-in, load it # otherwise defer until next round # stop if no plug-ins loaded in the round # count on the user to have correct dependencies module = plugin_adapter.load() if module: __modules.append(module) progress = True for plugin_adapter in plugin_adapters: logging.info("Plug-in '" + plugin_adapter.module_name + "' NOT loaded (requirements) (" + plugin_adapter.module_path + ").") notify_modules("run")
def get_interactive(self, version: typing.Optional[str] = None) -> typing.Any: actual_version = "1.0.0" if Utility.compare_versions(version or str(), actual_version) > 0: raise NotImplementedError("API requested version %s is greater than %s." % (version, actual_version)) return interactive_session