示例#1
0
    def remove_edge(self, *args):
        """
        Removes an edge from the graph.

        :param str UUID: edge UUID
        :param str conn: connection string (ie "node1.output,node2.input")

        :returns: edge removal was successful.
        :rtype: bool
        """
        edges = self.get_edge(*args)
        if not edges:
            log.warning('cannot find edge.')
            return

        for edge in edges:
            edge_id = (edge[0], edge[1])

            if edge_id in self.network.edges():
                log.debug('Removing edge: "%s"' %
                          self.edge_nice_name(*edge_id))
                self.network.remove_edge(*edge_id)
                self.remove_node_edge(*edge_id)

                # update the scene
                self.graphUpdated(edge_id)
                return True
        return False
示例#2
0
    def remove_edge(self, *args): 
        """
        Removes an edge from the graph.

        :param str UUID: edge UUID
        :param str conn: connection string (ie "node1.output,node2.input")

        :returns: edge removal was successful.
        :rtype: bool
        """
        edges = self.get_edge(*args)
        if not edges:
            log.warning('cannot find edge.')
            return

        for edge in edges:
            edge_id = (edge[0], edge[1])

            if edge_id in self.network.edges():
                log.debug('Removing edge: "%s"' % self.edge_nice_name(*edge_id))
                self.network.remove_edge(*edge_id)                
                self.remove_node_edge(*edge_id)        

                # update the scene
                self.graphUpdated(edge_id)
                return True
        return False
示例#3
0
    def _get_qss_files(self, paths=[]):
        """
        Get qss files.

        :param list path: ist of paths to add to the scan.

        :returns: dictionary of stylesheet names/filenames.
        :rtype: dict
        """
        qss_files = dict()
        if not paths:
            return []

        for path in paths:
            for fn in os.listdir(path):
                bn, fext = os.path.splitext(fn)
                if fext.lower() in ['.qss', '.css']:
                    qss_file = os.path.join(path, fn)
                    if qss_file not in qss_files.values():
                        style_name = self._parse_stylesheet_name(qss_file)
                        if style_name is None:
                            log.warning('cannot parse style name from "%s".' %
                                        qss_file)
                            style_name = 'no-style'

                        log.debug('adding stylesheet "%s" from "%s".' %
                                  (style_name, qss_file))

                        if style_name not in qss_files:
                            qss_files[style_name] = qss_file
        return qss_files
示例#4
0
    def updateDagNodes(self, dagnodes, debug=False):
        """
        Update the networkx nodes and links attributes from scene values.

        :param dagnodes: list of dag node objects.
        :type dagnodes: list
        """
        if type(dagnodes) not in [list, tuple]:
            dagnodes = [
                dagnodes,
            ]

        for dag in dagnodes:
            log.debug('Graph: updating dag node "%s"' % dag.name)
            nid = dag.id
            if nid in self.network.nodes():
                #self.network.node[nid].update(dag.data)
                dag_data = json.loads(str(dag), object_pairs_hook=dict)
                nx_data = self.network.node[nid]
                nx_data.update(dag_data)

                if debug:
                    # write temp file
                    filename = os.path.join(
                        os.path.dirname(self.autosave_path),
                        '%s.json' % dag.name)
                    fn = open(filename, 'w')
                    json.dump(dag_data, fn, indent=4)
                    fn.close()
示例#5
0
    def _get_qss_files(self, paths=[]):
        """
        Get qss files.

        :param list path: ist of paths to add to the scan.

        :returns: dictionary of stylesheet names/filenames.
        :rtype: dict
        """
        qss_files = dict()
        if not paths:
            return []

        for path in paths:
            for fn in os.listdir(path):
                bn, fext = os.path.splitext(fn)
                if fext.lower() in ['.qss', '.css']:
                    qss_file = os.path.join(path, fn)
                    if qss_file not in qss_files.values():
                        style_name = self._parse_stylesheet_name(qss_file)
                        if style_name is None:
                            log.warning('cannot parse style name from "%s".' % qss_file)
                            style_name = 'no-style'

                        log.debug('adding stylesheet "%s" from "%s".' % (style_name, qss_file))

                        if style_name not in qss_files:
                            qss_files[style_name] = qss_file
        return qss_files
示例#6
0
    def updateDagNodes(self, dagnodes, debug=False):
        """
        Update the networkx nodes and links attributes from scene values.

        :param dagnodes: list of dag node objects.
        :type dagnodes: list
        """
        if type(dagnodes) not in [list, tuple]:
            dagnodes=[dagnodes,]

        for dag in dagnodes:
            log.debug('Graph: updating dag node "%s"' % dag.name)
            nid = dag.id
            if nid in self.network.nodes():
                #self.network.node[nid].update(dag.data)
                dag_data = json.loads(str(dag), object_pairs_hook=dict)
                nx_data = self.network.node[nid]
                nx_data.update(dag_data)
                
                if debug:
                    # write temp file
                    filename = os.path.join(os.path.dirname(self.autosave_path), '%s.json' % dag.name)
                    fn = open(filename, 'w')
                    json.dump(dag_data, fn, indent=4)
                    fn.close()                
示例#7
0
    def _get_config_files(self, paths=[]):
        """
        Get config files.

        :param list path: ist of paths to add to the scan.

        :returns: dictionary of config names/filenames.
        :rtype: dict
        """
        cfg_files = dict()
        if not paths:
            return []

        for path in paths:
            for fn in os.listdir(path):
                bn, fext = os.path.splitext(fn)
                if fext.lower() in ['.ini', '.cfg']:
                    cfg_file = os.path.join(path, fn)

                    names = bn.split('-')
                    if len(names) < 2:
                        log.warning('improperly named config file: "%s"' % cfg_file)
                        continue

                    style_name, cfg_type = names
                    if style_name not in cfg_files:
                        cfg_files[style_name] = dict(fonts=None, palette=None)

                    log.debug('adding %s config "%s" from "%s".' % (cfg_type, style_name, cfg_file))
                    cfg_files[style_name][cfg_type] = cfg_file
        return cfg_files
示例#8
0
    def _get_qss_paths(self, paths=[]):
        """
        Read stylesheets from config paths.

        :param list paths: list of paths to add to the scan.

        :returns: array of search paths.
        :rtype: tuple
        """
        if paths and type(paths) in [str, unicode]:
            paths = [paths,]

        qss_paths = ()
        qss_paths = qss_paths + (options.SCENEGRAPH_STYLESHEET_PATH,)

        # read external paths
        if 'SCENEGRAPH_STYLESHEET_PATH' in os.environ:
            qpaths = os.getenv('SCENEGRAPH_STYLESHEET_PATH').split(':')
            if paths:
                for p in paths:
                    if p not in qpaths:
                        qpaths.append(p)

            for path in qpaths:
                if path not in qss_paths:
                    if not os.path.exists(path):
                        log.warning('stylesheet path "%s" does not exist, skipping.' % path)
                        continue
                    log.debug('reading external stylesheet path: "%s".' % path)
                    qss_paths = qss_paths + (path,)

        return qss_paths
示例#9
0
    def _get_config_paths(self, paths=[]):
        """
        Read configs from config paths.

        :param list paths: list of paths to add to the scan.

        :returns: array of search paths.
        :rtype: tuple
        """
        if paths and type(paths) in [str, unicode]:
            paths = [paths,]

        cfg_paths = ()
        cfg_paths = cfg_paths + (options.SCENEGRAPH_CONFIG_PATH,)

        # read external paths
        if 'SCENEGRAPH_CONFIG_PATH' in os.environ:
            spaths = os.getenv('SCENEGRAPH_CONFIG_PATH').split(':')
            if paths:
                for p in paths:
                    if p not in spaths:
                        spaths.append(p)

            for path in spaths:
                if path not in cfg_paths:
                    if not os.path.exists(path):
                        log.warning('config path "%s" does not exist, skipping.' % path)
                        continue
                    log.debug('reading config external path: "%s".' % path)
                    cfg_paths = cfg_paths + (path,)

        return cfg_paths
示例#10
0
    def _get_config_files(self, paths=[]):
        """
        Get config files.

        :param list path: ist of paths to add to the scan.

        :returns: dictionary of config names/filenames.
        :rtype: dict
        """
        cfg_files = dict()
        if not paths:
            return []

        for path in paths:
            for fn in os.listdir(path):
                bn, fext = os.path.splitext(fn)
                if fext.lower() in ['.ini', '.cfg']:
                    cfg_file = os.path.join(path, fn)

                    names = bn.split('-')
                    if len(names) < 2:
                        log.warning('improperly named config file: "%s"' %
                                    cfg_file)
                        continue

                    style_name, cfg_type = names
                    if style_name not in cfg_files:
                        cfg_files[style_name] = dict(fonts=None, palette=None)

                    log.debug('adding %s config "%s" from "%s".' %
                              (cfg_type, style_name, cfg_file))
                    cfg_files[style_name][cfg_type] = cfg_file
        return cfg_files
示例#11
0
def get_modules(path):
    """
    Returns all sub-modules of this package.

    :returns: list of module names in the current package.
    :rtype: list
    """
    mod_names = []
    modules = pkgutil.iter_modules(path=[path])
    for loader, mod_name, ispkg in modules:
        mod_names.append(mod_name)
        log.debug('reading module: "%s"' % mod_name)
    return sorted(mod_names)
示例#12
0
def get_modules(path):
    """
    Returns all sub-modules of this package.

    :returns: list of module names in the current package.
    :rtype: list
    """
    mod_names = []
    modules = pkgutil.iter_modules(path=[path])
    for loader, mod_name, ispkg in modules:
        mod_names.append(mod_name)
        log.debug('reading module: "%s"' % mod_name)
    return sorted(mod_names)
示例#13
0
    def _get_qss_paths(self, paths=[]):
        """
        Read stylesheets from config paths.

        :param list paths: list of paths to add to the scan.

        :returns: array of search paths.
        :rtype: tuple
        """
        if paths and type(paths) in [str, unicode]:
            paths = [
                paths,
            ]

        qss_paths = ()
        qss_paths = qss_paths + (options.SCENEGRAPH_STYLESHEET_PATH, )

        # read external paths
        if 'SCENEGRAPH_STYLESHEET_PATH' in os.environ:
            qpaths = os.getenv('SCENEGRAPH_STYLESHEET_PATH').split(':')
            if paths:
                for p in paths:
                    if p not in qpaths:
                        qpaths.append(p)

            for path in qpaths:
                if path not in qss_paths:
                    if not os.path.exists(path):
                        log.warning(
                            'stylesheet path "%s" does not exist, skipping.' %
                            path)
                        continue
                    log.debug('reading external stylesheet path: "%s".' % path)
                    qss_paths = qss_paths + (path, )

        return qss_paths
示例#14
0
    def _get_config_paths(self, paths=[]):
        """
        Read configs from config paths.

        :param list paths: list of paths to add to the scan.

        :returns: array of search paths.
        :rtype: tuple
        """
        if paths and type(paths) in [str, unicode]:
            paths = [
                paths,
            ]

        cfg_paths = ()
        cfg_paths = cfg_paths + (options.SCENEGRAPH_CONFIG_PATH, )

        # read external paths
        if 'SCENEGRAPH_CONFIG_PATH' in os.environ:
            spaths = os.getenv('SCENEGRAPH_CONFIG_PATH').split(':')
            if paths:
                for p in paths:
                    if p not in spaths:
                        spaths.append(p)

            for path in spaths:
                if path not in cfg_paths:
                    if not os.path.exists(path):
                        log.warning(
                            'config path "%s" does not exist, skipping.' %
                            path)
                        continue
                    log.debug('reading config external path: "%s".' % path)
                    cfg_paths = cfg_paths + (path, )

        return cfg_paths
示例#15
0
    def parse(self, filename):
        """
        Parses a single template file. Data is structured into groups
        of attributes (ie: 'Transform', 'Attributes')

        :param str filename: file on disk to read.

        :returns: dictionary of metadata parameters.
        :rtype: dict
        """
        if self._initialized:
            self.initialize()

        log.debug('reading metadata file: "%s"' % filename)
        data = dict()
        if filename is not None:
            if os.path.exists(filename):

                parent = data
                attr_name = None  

                for line in open(filename,'r'):
                    
                    #remove newlines
                    line = line.rstrip('\n')
                    rline = line.lstrip(' ')
                    rline = rline.rstrip()

                    if not rline.startswith("#") and not rline.startswith(';') and rline.strip() != "":
                        # parse sections
                        # remove leading spaces


                        # section/attribute header match
                        if re.match(regex.get("section"), rline):                            
                              
                            section_obj = re.search(regex.get("section_value"), rline)

                            if section_obj:
                                section_type = section_obj.group('attr')
                                section_value = section_obj.group('value')

                                # parse groups
                                if section_type == 'group':
                                    if section_value not in parent:
                                        parent = data
                                        group_data = dict()
                                        # set the current parent
                                        parent[section_value] = group_data
                                        parent = parent[section_value]
                                        #print '\nGroup: "%s"' % section_value

                                if section_type == 'attr':            
                                    attr_data = dict()
                                    # connection attributes
                                    #attr_data.update(connectable=False)
                                    #attr_data.update(connection_type=None)
                                    parent[section_value] = attr_data
                                    attr_name = section_value
                                    #print '   Attribute: "%s"' % attr_name

                                if section_type in ['input', 'output']:            
                                    conn_data = dict()
                                    conn_data.update(connectable=True)
                                    conn_data.update(connection_type=section_type)
                                    parent[section_value] = conn_data
                                    attr_name = section_value
                                    #print '   Connection: "%s"' % attr_name

                        else:
                            prop_obj = re.search(regex.get("properties"), rline)

                            if prop_obj:

                                pname = prop_obj.group('name')
                                ptype = prop_obj.group('type')
                                pvalu = prop_obj.group('value')

                                #print 'property: "%s" (%s)' % (pname, rline)
                                value = pvalu
                                if ptype in ['BOOL', 'INPUT', 'OUTPUT']:
                                    if ptype == 'BOOL':
                                        value = True if pvalu == 'true' else False

                                    # return connection types
                                    if ptype in ['INPUT', 'OUTPUT']:

                                        # data type: pvalu = FILE, DIRECTORY, ETC.
                                        value = pvalu.lower()

                                # try and get the actual value
                                else:
                                    try:
                                        value = eval(pvalu)
                                    except:
                                        log.warning('cannot parse default value of "%s.%s": "%s" (%s)' % (attr_name, pname, pvalu, filename))
                                #print '     property: %s (%s)' % (prop_obj.group('name'), attr_name)
                                properties = {pname: {'type':ptype, 'value':value}}
                                parent[attr_name].update(properties)
                    else:
                        if rline:
                            log.debug('skipping: "%s"' % rline)
        return data
示例#16
0
    def restore(self, data, nodes=True, graph=True):
        """
        Restore current DAG state from data. Also used for restoring graph state for the undo stack.

        :param dict data: dictionary of scene graph data.
        :param bool nodes: restore nodes/edges.
        :param bool graph: restore scene attributes/preferences.
        """
        self.reset()

        graph_data = data.get('graph', [])
        node_data = data.get('nodes', [])
        edge_data = data.get('links', [])

        self.updateConsole(msg='restoring %d nodes' % len(node_data))

        # update graph attributes
        for gdata in graph_data:
            if len(gdata):
                if graph or gdata[0] in ['scene', 'api_version']:
                    if len(gdata) > 1:
                        self.network.graph[gdata[0]] = gdata[1]

        # build nodes from data
        if nodes:
            for node_attrs in node_data:
                # get the node type
                node_type = node_attrs.pop('node_type', 'default')

                # add the dag node/widget
                dag_node = self.add_node(node_type, **node_attrs)
                log.debug('building node "%s"' % node_attrs.get('name'))

            # edge : ['src_attr', 'target', 'weight', 'dest_id', 'source', 'dest_attr', 'key', 'src_id']
            for edge in edge_data:

                src_id = edge.get('src_id')
                dest_id = edge.get('dest_id')

                src_attr = edge.get('src_attr')
                dest_attr = edge.get('dest_attr')

                weight = edge.get('weight', 1.0)

                src_dag_nodes = self.get_node(src_id)
                dest_dag_nodes = self.get_node(dest_id)

                if not src_dag_nodes or not dest_dag_nodes:
                    log.warning('cannot parse nodes.')
                    return

                src_dag_node = src_dag_nodes[0]
                dest_dag_node = dest_dag_nodes[0]
                src_string = '%s.%s' % (src_dag_node.name, src_attr)
                dest_string = '%s.%s' % (dest_dag_node.name, dest_attr)

                # TODO: need to get connection node here
                log.info('connecting nodes: "%s" "%s"' %
                         (src_string, dest_string))
                dag_edge = self.add_edge(src_dag_node,
                                         dest_dag_node,
                                         src_attr=src_attr,
                                         dest_attr=dest_attr,
                                         weight=weight)

        #self.handler.scene.clear()
        scene_pos = self.network.graph.get('view_center', (0, 0))
        view_scale = self.network.graph.get('view_scale', (1.0, 1.0))

        # update the UI.
        if self.mode == 'ui':
            if graph:
                self.handler.restoreGeometry(pos=scene_pos, scale=view_scale)

        self._initialized = 1
示例#17
0
    def restore(self, data, nodes=True, graph=True):
        """
        Restore current DAG state from data. Also used for restoring graph state for the undo stack.

        :param dict data: dictionary of scene graph data.
        :param bool nodes: restore nodes/edges.
        :param bool graph: restore scene attributes/preferences.
        """
        self.reset()

        graph_data = data.get('graph', [])
        node_data = data.get('nodes', [])
        edge_data = data.get('links', [])
        
        self.updateConsole(msg='restoring %d nodes' % len(node_data))

        # update graph attributes
        for gdata in graph_data:
            if len(gdata):
                if graph or gdata[0] in ['scene', 'api_version']:
                    if len(gdata) > 1:
                        self.network.graph[gdata[0]]=gdata[1]

        # build nodes from data
        if nodes:
            for node_attrs in node_data:
                # get the node type
                node_type = node_attrs.pop('node_type', 'default')

                # add the dag node/widget
                dag_node = self.add_node(node_type, **node_attrs)
                log.debug('building node "%s"' % node_attrs.get('name'))

            # edge : ['src_attr', 'target', 'weight', 'dest_id', 'source', 'dest_attr', 'key', 'src_id']
            for edge in edge_data:

                src_id = edge.get('src_id')
                dest_id = edge.get('dest_id')

                src_attr = edge.get('src_attr')
                dest_attr = edge.get('dest_attr')

                weight = edge.get('weight', 1.0)

                src_dag_nodes = self.get_node(src_id)
                dest_dag_nodes = self.get_node(dest_id)

                if not src_dag_nodes or not dest_dag_nodes:
                    log.warning('cannot parse nodes.')
                    return

                src_dag_node = src_dag_nodes[0]
                dest_dag_node = dest_dag_nodes[0]
                src_string = '%s.%s' % (src_dag_node.name, src_attr)
                dest_string = '%s.%s' % (dest_dag_node.name, dest_attr)

                # TODO: need to get connection node here
                log.info('connecting nodes: "%s" "%s"' % (src_string, dest_string))            
                dag_edge = self.add_edge(src_dag_node, dest_dag_node, src_attr=src_attr, dest_attr=dest_attr, weight=weight)

        #self.handler.scene.clear()
        scene_pos = self.network.graph.get('view_center', (0,0))
        view_scale = self.network.graph.get('view_scale', (1.0, 1.0))

        # update the UI.
        if self.mode == 'ui':
            if graph:
                self.handler.restoreGeometry(pos=scene_pos, scale=view_scale)
                
        self._initialized = 1
示例#18
0
    def parse(self, filename):
        """
        Parses a single template file. Data is structured into groups
        of attributes (ie: 'Transform', 'Attributes')

        :param str filename: file on disk to read.

        :returns: dictionary of metadata parameters.
        :rtype: dict
        """
        if self._initialized:
            self.initialize()

        log.debug('reading metadata file: "%s"' % filename)
        data = dict()
        if filename is not None:
            if os.path.exists(filename):

                parent = data
                attr_name = None

                for line in open(filename, 'r'):

                    #remove newlines
                    line = line.rstrip('\n')
                    rline = line.lstrip(' ')
                    rline = rline.rstrip()

                    if not rline.startswith("#") and not rline.startswith(
                            ';') and rline.strip() != "":
                        # parse sections
                        # remove leading spaces

                        # section/attribute header match
                        if re.match(regex.get("section"), rline):

                            section_obj = re.search(regex.get("section_value"),
                                                    rline)

                            if section_obj:
                                section_type = section_obj.group('attr')
                                section_value = section_obj.group('value')

                                # parse groups
                                if section_type == 'group':
                                    if section_value not in parent:
                                        parent = data
                                        group_data = dict()
                                        # set the current parent
                                        parent[section_value] = group_data
                                        parent = parent[section_value]
                                        #print '\nGroup: "%s"' % section_value

                                if section_type == 'attr':
                                    attr_data = dict()
                                    # connection attributes
                                    #attr_data.update(connectable=False)
                                    #attr_data.update(connection_type=None)
                                    parent[section_value] = attr_data
                                    attr_name = section_value
                                    #print '   Attribute: "%s"' % attr_name

                                if section_type in ['input', 'output']:
                                    conn_data = dict()
                                    conn_data.update(connectable=True)
                                    conn_data.update(
                                        connection_type=section_type)
                                    parent[section_value] = conn_data
                                    attr_name = section_value
                                    #print '   Connection: "%s"' % attr_name

                        else:
                            prop_obj = re.search(regex.get("properties"),
                                                 rline)

                            if prop_obj:

                                pname = prop_obj.group('name')
                                ptype = prop_obj.group('type')
                                pvalu = prop_obj.group('value')

                                #print 'property: "%s" (%s)' % (pname, rline)
                                value = pvalu
                                if ptype in ['BOOL', 'INPUT', 'OUTPUT']:
                                    if ptype == 'BOOL':
                                        value = True if pvalu == 'true' else False

                                    # return connection types
                                    if ptype in ['INPUT', 'OUTPUT']:

                                        # data type: pvalu = FILE, DIRECTORY, ETC.
                                        value = pvalu.lower()

                                # try and get the actual value
                                else:
                                    try:
                                        value = eval(pvalu)
                                    except:
                                        log.warning(
                                            'cannot parse default value of "%s.%s": "%s" (%s)'
                                            % (attr_name, pname, pvalu,
                                               filename))
                                #print '     property: %s (%s)' % (prop_obj.group('name'), attr_name)
                                properties = {
                                    pname: {
                                        'type': ptype,
                                        'value': value
                                    }
                                }
                                parent[attr_name].update(properties)
                    else:
                        if rline:
                            log.debug('skipping: "%s"' % rline)
        return data
示例#19
0
    def read_metadata(self, verbose=False):
        """
        Initialize node metadata from metadata files on disk.
        Metadata is parsed by looking at the __bases__ of each node
        class (ie: all DagNode subclasses will inherit all of the default
        DagNode attributes).
        """
        import inspect
        parser = MetadataParser()

        node_metadata = dict()
        if verbose:
            print '\n# DEBUG: building metadata for: "%s" ' % self.Class()
        # query the base classes
        result = [
            self.__class__,
        ]
        for pc in self.ParentClasses():
            if pc.__name__ != 'Node':
                result.append(pc)

        sg_core_path = os.path.join(SCENEGRAPH_CORE, 'nodes.py')

        for cls in reversed(result):
            cname = cls.__name__
            src_file = inspect.getfile(cls)

            node_type = None
            if hasattr(cls, 'node_type'):
                node_type = cls.node_type

            py_src = src_file.rstrip('c')
            if verbose:
                print '   - base class "%s" source file: "%s"' % (cname,
                                                                  py_src)

            dirname = os.path.dirname(src_file)
            basename = os.path.splitext(os.path.basename(src_file))[0]

            # return the source .py file if it exists
            if os.path.exists(py_src):
                src_file = py_src

            metadata_filename = os.path.join(dirname, '%s.mtd' % basename)

            # look for code node metadata in ../mtd
            if py_src == sg_core_path:
                if node_type:
                    metadata_filename = os.path.join(SCENEGRAPH_METADATA_PATH,
                                                     '%s.mtd' % node_type)
                    if verbose:
                        print '     - metadata file for "%s": "%s"' % (
                            cname, metadata_filename)

            if not os.path.exists(metadata_filename):
                if not verbose:
                    log.warning(
                        'plugin description file "%s" does not exist.' %
                        metadata_filename)
                else:
                    print '       WARNING: metadata file for "%s": "%s" not found' % (
                        cname, metadata_filename)
                continue

            log.debug('reading plugin metadata file: "%s".' %
                      metadata_filename)
            # parse the metadata
            parsed = parser.parse(metadata_filename)

            for section in parsed:
                if section not in node_metadata:
                    node_metadata[section] = dict()

                attributes = parsed.get(section)

                # parse out input/output here?
                for attr in attributes:
                    if attr not in node_metadata[section]:
                        node_metadata.get(section)[attr] = dict()

                    attr_properties = attributes.get(attr)
                    node_metadata.get(section).get(attr).update(
                        attr_properties)

        return node_metadata
示例#20
0
    def read_metadata(self, verbose=False):
        """
        Initialize node metadata from metadata files on disk.
        Metadata is parsed by looking at the __bases__ of each node
        class (ie: all DagNode subclasses will inherit all of the default
        DagNode attributes).
        """
        import inspect
        parser = MetadataParser()

        node_metadata = dict()
        if verbose:
            print '\n# DEBUG: building metadata for: "%s" ' % self.Class()
        # query the base classes
        result = [self.__class__,]
        for pc in self.ParentClasses():
            if pc.__name__ != 'Node':
                result.append(pc)
        
        sg_core_path = os.path.join(SCENEGRAPH_CORE, 'nodes.py')

        for cls in reversed(result):
            cname = cls.__name__
            src_file = inspect.getfile(cls)

            node_type = None
            if hasattr(cls, 'node_type'):
                node_type = cls.node_type

            py_src = src_file.rstrip('c')
            if verbose:
                print '   - base class "%s" source file: "%s"' % (cname, py_src)

            dirname = os.path.dirname(src_file)
            basename = os.path.splitext(os.path.basename(src_file))[0]
            
            # return the source .py file if it exists
            if os.path.exists(py_src):
                src_file = py_src

            metadata_filename = os.path.join(dirname, '%s.mtd' % basename)

            # look for code node metadata in ../mtd
            if py_src == sg_core_path:
                if node_type:             
                    metadata_filename = os.path.join(SCENEGRAPH_METADATA_PATH, '%s.mtd' % node_type)
                    if verbose:
                        print '     - metadata file for "%s": "%s"' % (cname, metadata_filename)

            if not os.path.exists(metadata_filename):
                if not verbose:
                    log.warning('plugin description file "%s" does not exist.' % metadata_filename)
                else:
                    print '       WARNING: metadata file for "%s": "%s" not found' % (cname, metadata_filename)
                continue

            log.debug('reading plugin metadata file: "%s".' % metadata_filename)
            # parse the metadata 
            parsed = parser.parse(metadata_filename)

            for section in parsed:
                if section not in node_metadata:
                    node_metadata[section] = dict()

                attributes = parsed.get(section)
                

                # parse out input/output here?
                for attr in attributes:
                    if attr not in node_metadata[section]:
                        node_metadata.get(section)[attr] = dict()

                    attr_properties = attributes.get(attr)
                    node_metadata.get(section).get(attr).update(attr_properties)

        return node_metadata