Beispiel #1
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
Beispiel #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
Beispiel #3
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
Beispiel #4
0
    def evaluate(self, dagnodes=[], verbose=False):
        """
        Evalute the Graph, updating networkx graph.
        """
        result = True
        if not dagnodes:
            dagnodes = self.dagnodes.values()

        # update network nodes from dag attributes
        self.updateDagNodes(dagnodes)
        node_ids = []
        invalid_node_ids = []
        for node in dagnodes:
            if self.is_node(node):
                if node.id not in node_ids:
                    node_ids.append(node.id)

        if self.network.edges():
            for edge in self.network.edges_iter(data=True):
                src_id, dest_id, edge_attrs = edge

                source_node = self.dagnodes.get(src_id, None)
                dest_node = self.dagnodes.get(dest_id, None)

        if self.network.nodes():
            for node in self.network.nodes_iter(data=True):
                node_id, node_attrs = node
                if node_id not in node_ids:
                    invalid_node_ids.append(node_id)
                    log.warning('invalid NetworkX node "%s" ( %s )' %
                                (node_attrs.get('name'), node_id))
                    result = False
        return result
Beispiel #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
Beispiel #6
0
    def snapshot(self):
        """
        Returns a snapshot dictionary for writing scenes 
        and updating undo stack.

        .. todo::
            - try using the nxj.adjacency_data() method.

        :returns: dictionary of graph data.
        :rtype: dict
        """
        if not self.evaluate():
            log.warning('graph did not evaluate correctly.')
        attrs = {
            'source': 'source',
            'target': 'target',
            'key': 'key',
            'id': 'id',
            'src_id': 'src_id',
            'dest_id': 'dest_id',
            'src_attr': 'src_attr',
            'dest_attr': 'dest_attr',
            'weight': 'weight',
            'style': 'style'
        }
        graph_data = nxj.node_link_data(self.network, attrs=attrs)
        return graph_data
Beispiel #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
Beispiel #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
Beispiel #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
Beispiel #10
0
    def evaluate(self, dagnodes=[], verbose=False):
        """
        Evalute the Graph, updating networkx graph.
        """
        result = True
        if not dagnodes:
            dagnodes = self.dagnodes.values()

        # update network nodes from dag attributes
        self.updateDagNodes(dagnodes)
        node_ids = []
        invalid_node_ids = []
        for node in dagnodes:
            if self.is_node(node):
                if node.id not in node_ids:
                    node_ids.append(node.id)

        if self.network.edges():
            for edge in self.network.edges_iter(data=True):
                src_id, dest_id, edge_attrs = edge

                source_node = self.dagnodes.get(src_id, None)
                dest_node = self.dagnodes.get(dest_id, None)

        if self.network.nodes():
            for node in self.network.nodes_iter(data=True):
                node_id, node_attrs = node
                if node_id not in node_ids:
                    invalid_node_ids.append(node_id)
                    log.warning('invalid NetworkX node "%s" ( %s )' % (node_attrs.get('name'), node_id))
                    result = False
        return result
Beispiel #11
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
Beispiel #12
0
    def add_edge(self, src, dest, **kwargs):
        """
        Add an edge connecting two nodes.

        :param src: source node
        :type src: DagNode

        :param dest: destination node
        :type dest: DagNode

        :returns: edge dictionary
        :rtype: dict
        """
        src_attr = kwargs.pop('src_attr', 'output')
        dest_attr = kwargs.pop('dest_attr', 'input')
        weight = kwargs.pop('weight', 1.0)
        edge_type = kwargs.pop('edge_type', 'bezier')
        style = kwargs.pop('style', 'solid')

        if src is None or dest is None:
            log.warning('none type passed.')
            return False

        if not src or not dest:
            log.warning('please specify two nodes to connect.')
            return False

        # don't connect the same node
        if src.name == dest.name:
            log.warning('invalid connection: "%s", "%s"' % (src.name, dest.name))
            return

        conn_str = '%s.%s,%s.%s' % (src.name, src_attr, dest.name, dest_attr)
        if conn_str in self.connections():
            log.warning('connection already exists: %s' % conn_str)
            return 
        
        # edge attributes for nx graph
        edge_attrs = dict(src_id=src.id, dest_id=dest.id, src_attr=src_attr, dest_attr=dest_attr, edge_type=edge_type, style=style)

        src_conn = src.get_connection(src_attr)
        dest_conn = dest.get_connection(dest_attr)
        edge_id_str = '(%s,%s)' % (src.id, dest.id)

        #if edge_id_str not in src_conn._edges and edge_id_str not in dest_conn._edges:            
        # add the nx edge - weight should go here        
        self.network.add_edge(src.id, dest.id, key='attributes', weight=weight, attr_dict=edge_attrs)
        log.info('adding edge: "%s"' % self.edge_nice_name(src.id, dest.id))

        # new edge = {'attributes': {'dest_attr': 'input', 'src_attr': 'output', 'weight': 1}}
        new_edge = self.network.edge[src.id][dest.id]
        #print 'new edge: ', new_edge
        src_conn._edges.append(edge_id_str)
        dest_conn._edges.append(edge_id_str)

        # update the scene
        self.edgesAdded([new_edge.get('attributes')])
        return new_edge
Beispiel #13
0
    def setScene(self, filename=None):
        """
        Set the current scene value.

        :param filename: scene file name.
        :type filename: str

        :returns: scene file name.
        :rtype: str
        """
        tmp_dir = os.getenv('TMPDIR')
        if not tmp_dir:
            log.warning('environment "TMPDIR" not set, please set and restart.')
        if tmp_dir not in filename:
            self.network.graph['scene'] = filename
        return self.getScene()
Beispiel #14
0
    def snapshot(self):
        """
        Returns a snapshot dictionary for writing scenes 
        and updating undo stack.

        .. todo::
            - try using the nxj.adjacency_data() method.

        :returns: dictionary of graph data.
        :rtype: dict
        """
        if not self.evaluate():
            log.warning('graph did not evaluate correctly.')
        attrs = {'source': 'source', 'target': 'target', 'key': 'key', 
                'id': 'id', 'src_id': 'src_id', 'dest_id': 'dest_id', 'src_attr': 'src_attr', 'dest_attr': 'dest_attr', 'weight':'weight', 'style':'style'}
        graph_data = nxj.node_link_data(self.network, attrs=attrs)
        return graph_data
Beispiel #15
0
    def setScene(self, filename=None):
        """
        Set the current scene value.

        :param filename: scene file name.
        :type filename: str

        :returns: scene file name.
        :rtype: str
        """
        tmp_dir = os.getenv('TMPDIR')
        if not tmp_dir:
            log.warning(
                'environment "TMPDIR" not set, please set and restart.')
        if tmp_dir not in filename:
            self.network.graph['scene'] = filename
        return self.getScene()
Beispiel #16
0
    def scanNodeTypes(self, path):
        """
        Scan the given directory for node types.

        :param str path: path to scan.
        """
        nodes = dict()
        if not os.path.exists(path):
            log.warning('node path "%s" does not exist.' % path)
            return nodes

        for fn in os.listdir(path):
            if fn not in ['README']:
                node_name = os.path.splitext(os.path.basename(fn))[0]
                node_mod = os.path.join(path, '%s.py' % node_name)
                node_data = os.path.join(path, '%s.mtd' % node_name)
                if os.path.exists(node_mod) and os.path.exists(node_data):
                    node_attrs = dict()
                    node_attrs['module'] = node_mod
                    node_attrs['metadata'] = node_data
                    nodes[node_name] = node_attrs
                else:
                    if not os.path.exists(node_mod):
                        log.warning('cannot find "%s" module %s' %
                                    (node_name, node_mod))
                    if not os.path.exists(node_data):
                        log.warning('cannot find "%s" metadata %s' %
                                    (node_name, node_data))
        return nodes
Beispiel #17
0
    def scanNodeTypes(self, path):
        """
        Scan the given directory for node types.

        :param str path: path to scan.
        """
        nodes = dict()
        if not os.path.exists(path):
            log.warning('node path "%s" does not exist.' % path)
            return nodes

        for fn in os.listdir(path):
            if fn not in ['README']:
                node_name = os.path.splitext(os.path.basename(fn))[0]
                node_mod = os.path.join(path, '%s.py' % node_name)
                node_data = os.path.join(path, '%s.mtd' % node_name)
                if os.path.exists(node_mod) and os.path.exists(node_data):
                    node_attrs = dict()
                    node_attrs['module'] = node_mod
                    node_attrs['metadata'] = node_data
                    nodes[node_name]=node_attrs
                else:
                    if not os.path.exists(node_mod):
                        log.warning('cannot find "%s" module %s' % (node_name, node_mod))
                    if not os.path.exists(node_data):
                        log.warning('cannot find "%s" metadata %s' % (node_name, node_data))
        return nodes
Beispiel #18
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
Beispiel #19
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
Beispiel #20
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
Beispiel #21
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
Beispiel #22
0
    def add_edge(self, src, dest, **kwargs):
        """
        Add an edge connecting two nodes.

        :param src: source node
        :type src: DagNode

        :param dest: destination node
        :type dest: DagNode

        :returns: edge dictionary
        :rtype: dict
        """
        src_attr = kwargs.pop('src_attr', 'output')
        dest_attr = kwargs.pop('dest_attr', 'input')
        weight = kwargs.pop('weight', 1.0)
        edge_type = kwargs.pop('edge_type', 'bezier')
        style = kwargs.pop('style', 'solid')

        if src is None or dest is None:
            log.warning('none type passed.')
            return False

        if not src or not dest:
            log.warning('please specify two nodes to connect.')
            return False

        # don't connect the same node
        if src.name == dest.name:
            log.warning('invalid connection: "%s", "%s"' %
                        (src.name, dest.name))
            return

        conn_str = '%s.%s,%s.%s' % (src.name, src_attr, dest.name, dest_attr)
        if conn_str in self.connections():
            log.warning('connection already exists: %s' % conn_str)
            return

        # edge attributes for nx graph
        edge_attrs = dict(src_id=src.id,
                          dest_id=dest.id,
                          src_attr=src_attr,
                          dest_attr=dest_attr,
                          edge_type=edge_type,
                          style=style)

        src_conn = src.get_connection(src_attr)
        dest_conn = dest.get_connection(dest_attr)
        edge_id_str = '(%s,%s)' % (src.id, dest.id)

        #if edge_id_str not in src_conn._edges and edge_id_str not in dest_conn._edges:
        # add the nx edge - weight should go here
        self.network.add_edge(src.id,
                              dest.id,
                              key='attributes',
                              weight=weight,
                              attr_dict=edge_attrs)
        log.info('adding edge: "%s"' % self.edge_nice_name(src.id, dest.id))

        # new edge = {'attributes': {'dest_attr': 'input', 'src_attr': 'output', 'weight': 1}}
        new_edge = self.network.edge[src.id][dest.id]
        #print 'new edge: ', new_edge
        src_conn._edges.append(edge_id_str)
        dest_conn._edges.append(edge_id_str)

        # update the scene
        self.edgesAdded([new_edge.get('attributes')])
        return new_edge
Beispiel #23
0
    def get_edge(self, *args):
        """
        Return an edge attribute dictionary.

        Pass connection string ie: ('node1.output, node2.input'),
        or source dest (ie: 'node1.output', 'node2.input')

        :returns: list of nx edges (id, id, {attributes})
        :rtype: list
        """
        edges=[]

        cs = lambda x: [y.strip() for y in x.split(',')]

        # variables to match
        src_conn  = None
        dest_conn = None

        src_name  = None
        dest_name = None

        src_attr  = 'output'
        dest_attr = 'input'

        edgeid    = None

        # parse connection strings
        if len(args):
            if len(args) > 1:
                if (args[0], args[1]) in self.network.edges():
                    edgeid = (args[0], args[1])

                if type(args[0]) is str and type(args[1]) is str:

                    src_conn = args[0]
                    dest_conn = args[1]
            else:
                if type(args[0]) is str:
                    if ',' in args[0]:
                        src_conn, dest_conn = cs(args[0])

        if not src_conn or not dest_conn:
            log.warning('invalid arguments passed.')
            return

        if '.' in src_conn:
            src_name, src_attr = src_conn.split('.')

        if '.' in dest_conn:
            dest_name, dest_attr = dest_conn.split('.')

        # loop through nx edges
        # edge: (id, id, {'src_id': id, 'dest_attr': 'input', 'src_attr': 'output', 'dest_id': id, 'weight': 1})
        for edge in self.network.edges(data=True):

            srcid, destid, attrs = edge
            edge_id = (srcid, destid)

            #match two ids
            if edge_id == edgeid:
                edges.append(edge)

            sn_attr = attrs.get('src_attr', None)
            dn_attr = attrs.get('dest_attr', None)

            src_nodes = self.get_node(srcid)
            dest_nodes = self.get_node(destid)

            if not src_nodes or not dest_nodes:
                continue

            if not sn_attr or not dn_attr:
                continue

            src_node  = src_nodes[0]
            dest_node = dest_nodes[0]

            sn_name = src_node.name
            dn_name = dest_node.name

            if src_name == sn_name and dest_name == dn_name:
                if src_attr == sn_attr and dest_attr == dn_attr:
                    edges.append(edge)
        return edges
Beispiel #24
0
    def get_edge(self, *args):
        """
        Return an edge attribute dictionary.

        Pass connection string ie: ('node1.output, node2.input'),
        or source dest (ie: 'node1.output', 'node2.input')

        :returns: list of nx edges (id, id, {attributes})
        :rtype: list
        """
        edges = []

        cs = lambda x: [y.strip() for y in x.split(',')]

        # variables to match
        src_conn = None
        dest_conn = None

        src_name = None
        dest_name = None

        src_attr = 'output'
        dest_attr = 'input'

        edgeid = None

        # parse connection strings
        if len(args):
            if len(args) > 1:
                if (args[0], args[1]) in self.network.edges():
                    edgeid = (args[0], args[1])

                if type(args[0]) is str and type(args[1]) is str:

                    src_conn = args[0]
                    dest_conn = args[1]
            else:
                if type(args[0]) is str:
                    if ',' in args[0]:
                        src_conn, dest_conn = cs(args[0])

        if not src_conn or not dest_conn:
            log.warning('invalid arguments passed.')
            return

        if '.' in src_conn:
            src_name, src_attr = src_conn.split('.')

        if '.' in dest_conn:
            dest_name, dest_attr = dest_conn.split('.')

        # loop through nx edges
        # edge: (id, id, {'src_id': id, 'dest_attr': 'input', 'src_attr': 'output', 'dest_id': id, 'weight': 1})
        for edge in self.network.edges(data=True):

            srcid, destid, attrs = edge
            edge_id = (srcid, destid)

            #match two ids
            if edge_id == edgeid:
                edges.append(edge)

            sn_attr = attrs.get('src_attr', None)
            dn_attr = attrs.get('dest_attr', None)

            src_nodes = self.get_node(srcid)
            dest_nodes = self.get_node(destid)

            if not src_nodes or not dest_nodes:
                continue

            if not sn_attr or not dn_attr:
                continue

            src_node = src_nodes[0]
            dest_node = dest_nodes[0]

            sn_name = src_node.name
            dn_name = dest_node.name

            if src_name == sn_name and dest_name == dn_name:
                if src_attr == sn_attr and dest_attr == dn_attr:
                    edges.append(edge)
        return edges
Beispiel #25
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
Beispiel #26
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
Beispiel #27
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
Beispiel #28
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