def getEvents(component): """ returns (dict of name -> Events): all the Events in the component with their name """ # like dump_dataflow, but doesn't register them evts = inspect_getmembers(component, lambda x: isinstance(x, _dataflow.EventBase)) return dict(evts)
def update_metadata(comp_name, key_val_str): """ update the metadata of the given component with the given key/value key_val_str (dict str->str): key name -> value as a string """ component = get_component(comp_name) md = {} for key_name, str_val in key_val_str.items(): # Check that the metadata is a valid one. It's a bit tricky as there is no # "official" list. But we look at the ones defined in model.MD_* for n, v in inspect_getmembers(model, lambda m: isinstance(m, str)): if n.startswith("MD_") and v == key_name: key = key_name break else: # fallback to looking for MD_{key_name} try: key = getattr(model, "MD_%s" % key_name) except AttributeError: raise ValueError("Metadata key '%s' is unknown" % key_name) md[key] = convert_to_object(str_val) try: component.updateMetadata(md) except Exception as exc: raise IOError("Failed to update metadata of %s to %s: %s" % (comp_name, md, exc))
def getDataFlows(component): """ returns (dict of name -> DataFlow): all the DataFlows in the component with their name """ # like dump_dataflow, but doesn't register them dfs = inspect_getmembers(component, lambda x: isinstance(x, _dataflow.DataFlowBase)) return dict(dfs)
def getVAs(component): """ returns (dict of name -> VigilantAttributeBase): all the VAs in the component with their name """ # like dump_vigilante_attributes, but doesn't register them vas = inspect_getmembers(component, lambda x: isinstance(x, _vattributes.VigilantAttributeBase)) return dict(vas)
def get_roattributes(self): """ list all roattributes of an instance Note: this only works on an original class, not on a proxy """ members = inspect_getmembers(self.__class__) return [name for name, obj in members if isinstance(obj, roattribute)]
def map_metadata_names(): """ Find the name of each known metadata return dict str->str: the metadata key string -> the name of the metadata (without the "MD_") """ ret = {} for n, v in inspect_getmembers(model, lambda m: isinstance(m, str)): if n.startswith("MD_"): ret[v] = n[3:] return ret
def scan(cls=None): """ Scan for connected devices and list them cls (str or None): the class name to scan (as written in the microscope file) Output like: Classname: 'Name of Device' init={arg: value, arg2: value2} """ # FIXME: need to work when /var/run/odemisd is not available: # => fail to create the container. # only here, to avoid importing everything for other commands from odemis import driver num = 0 cls_found = False # we scan by using every HwComponent class which has a .scan() method for module_name in driver.__all__: try: module = importlib.import_module("." + module_name, "odemis.driver") except ImportError: logging.warning("Cannot try module %s, failed to load." % module_name) except Exception: logging.exception("Failed to load module %s" % module_name) for cls_name, clso in inspect_getmembers(module, inspect.isclass): if issubclass(clso, model.HwComponent) and hasattr(clso, "scan"): if cls: full_name = "%s.%s" % (module_name, cls_name) if cls != full_name: logging.debug("Skipping %s", full_name) continue else: cls_found = True logging.info("Scanning for %s.%s components", module_name, cls_name) # do it in a separate container so that we don't have to load # all drivers in the same process (andor cams don't like it) container_name = "scanner%d" % num num += 1 try: cont, scanner = model.createInNewContainer(container_name, Scanner, {"cls": clso}) devices = scanner.scan() scanner.terminate() cont.terminate() except Exception: logging.exception("Failed to scan %s.%s components", module_name, cls_name) else: if not devices: logging.info("No device found") for name, args in devices: print("%s.%s: '%s' init=%r" % (module_name, cls_name, name, args)) if cls and not cls_found: raise ValueError("Failed to find class %s" % cls)
def dump_vigilant_attributes(self): """ return the names and value of all the VAs added to an object (component) If a VA is not registered yet, it is registered. self (Component): the object (instance of a class). It must already be registered to a Pyro daemon. return (dict string -> value): attribute name -> VigilantAttributeBase """ vas = dict() daemon = self._pyroDaemon for name, value in inspect_getmembers(self, lambda x: isinstance(x, VigilantAttributeBase)): if not hasattr(value, "_pyroDaemon"): value._register(daemon) vas[name] = value return vas
def dump_events(self): """ return the names and value of all the Events added to an object (component). If an Event is not registered yet, it is registered. self (Component): the object (instance of a class). It must already be registered to a Pyro daemon. return (dict string -> value): attribute name -> Event """ events = dict() daemon = self._pyroDaemon for name, value in inspect_getmembers(self, lambda x: isinstance(x, EventBase)): if not hasattr(value, "_pyroDaemon"): daemon.register(value) events[name] = value return events
def dump_dataflows(self): """ return the names and value of all the DataFlows added to an object (component). If a dataflow is not registered yet, it is registered. self (Component): the object (instance of a class). It must already be registered to a Pyro daemon. return (dict string -> value): attribute name -> dataflow """ dataflows = dict() daemon = self._pyroDaemon for name, value in inspect_getmembers(self, lambda x: isinstance(x, DataFlowBase)): if not hasattr(value, "_pyroDaemon"): value._register(daemon) dataflows[name] = value return dataflows
def load_plugin(filename, microscope, main_app): """ Load and instantiate each plugin present in a plugin file Note: if the plugin fails to load, it will not raise an error, but just return an empty list and log the error. Args: filename (str): path to the python file containing one or more Plugin class microscope (Microscope or None): the main back-end component. If the GUI is running as a viewer only, then it is None. main_app (wx.App): the main GUI component. Returns: (list of instances of Plugin): each instance of plugin created """ ret = [] # Load module logging.debug("Searching '%s' for Plugins...", filename) logger = logging.getLogger() prev_loglev = logger.getEffectiveLevel() try: # Use the name of the script as sub-module of this module # eg: aab.py -> odemis.gui.plugin.aab dirn, bsn = os.path.split(filename) mn, ext = os.path.splitext(bsn) if ext == ".pyc": pm = imp.load_compiled(__name__ + "." + mn, filename) elif ext == ".py": pm = imp.load_source(__name__ + "." + mn, filename) else: raise ValueError("Unsupported extension '%s'" % (ext, )) except Exception: logging.info("Skipping script %s, which failed to load", filename, exc_info=True) return ret if logger.getEffectiveLevel() != prev_loglev: # It's easy to put a line at the top of a script that changes the logging # level, but after importing that script, the whole GUI log level would # be modified, so put it back. logging.info("Resetting logging level that was modified during import") logger.setLevel(prev_loglev) # For each subclass of Plugin in the module, start it by instantiating it found_plugin = False for n, pc in inspect_getmembers(pm, inspect.isclass): # We only want Plugin subclasses, not even the Plugin class itself if not issubclass(pc, Plugin) or pc is Plugin: continue # Don't try to instantiate abstract classes # TODO: the issue with this test is that if the plugin doesn't provide # one of the abstract method or property (due to a programming error), # it's considered an abstract class # if inspect.isabstract(pc): # continue if microscope: logging.debug( "Trying to instantiate %s (%s) of '%s' with microscope %s", pc.name, n, filename, microscope.name) else: logging.debug( "Trying to instantiate %s (%s) of '%s' without microscope", pc.name, n, filename) found_plugin = True try: ip = pc(microscope, main_app) except Exception: logging.warning("Failed to instantiate %s of '%s'", n, filename, exc_info=True) else: logging.info("Created Plugin %s from '%s'", ip, os.path.basename(filename)) ret.append(ip) if not found_plugin: logging.info("Script %s contains no plugin", filename) return ret
def unregister_vigilant_attributes(self): for _, value in inspect_getmembers( self, lambda x: isinstance(x, VigilantAttribute)): value._unregister()
def unregister_events(self): for name, value in inspect_getmembers(self, lambda x: isinstance(x, Event)): daemon = getattr(value, "_pyroDaemon", None) if daemon: daemon.unregister(value)
def unregister_dataflows(self): # Only for the "DataFlow"s, the real objects, not the proxys for name, value in inspect_getmembers(self, lambda x: isinstance(x, DataFlow)): value._unregister()