From 7f7fa2f91467fdb2b11312be8562e7b51fdeb199 Mon Sep 17 00:00:00 2001
From: Sebastian Koslowski <sebastian.koslowski@gmail.com>
Date: Tue, 3 May 2016 17:13:08 +0200
Subject: grc: added yaml/mako support

Includes basic converter from XML/Cheetah to YAML/Mako based block format.
---
 grc/converter/flow_graph.py | 131 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 131 insertions(+)
 create mode 100644 grc/converter/flow_graph.py

(limited to 'grc/converter/flow_graph.py')

diff --git a/grc/converter/flow_graph.py b/grc/converter/flow_graph.py
new file mode 100644
index 0000000000..d20c67703c
--- /dev/null
+++ b/grc/converter/flow_graph.py
@@ -0,0 +1,131 @@
+# Copyright 2017 Free Software Foundation, Inc.
+# This file is part of GNU Radio
+#
+# GNU Radio Companion is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# GNU Radio Companion is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+
+from __future__ import absolute_import, division
+
+import ast
+from collections import OrderedDict
+
+from ..core.io import yaml
+from . import xml
+
+
+def from_xml(filename):
+    """Load flow graph from xml file"""
+    element, version_info = xml.load(filename, 'flow_graph.dtd')
+
+    data = convert_flow_graph_xml(element)
+    try:
+        file_format = int(version_info['format'])
+    except KeyError:
+        file_format = _guess_file_format_1(data)
+
+    data['metadata'] = {'file_format': file_format}
+
+    return data
+
+
+def dump(data, stream):
+    out = yaml.dump(data, indent=2)
+
+    replace = [
+        ('blocks:', '\nblocks:'),
+        ('connections:', '\nconnections:'),
+        ('metadata:', '\nmetadata:'),
+    ]
+    for r in replace:
+        out = out.replace(*r)
+    prefix = '# auto-generated by grc.converter\n\n'
+    stream.write(prefix + out)
+
+
+def convert_flow_graph_xml(node):
+    blocks = [
+        convert_block(block_data)
+        for block_data in node.findall('block')
+    ]
+
+    options = next(b for b in blocks if b['id'] == 'options')
+    blocks.remove(options)
+    options.pop('id')
+
+    connections = [
+        convert_connection(connection)
+        for connection in node.findall('connection')
+        ]
+
+    flow_graph = OrderedDict()
+    flow_graph['options'] = options
+    flow_graph['blocks'] = blocks
+    flow_graph['connections'] = connections
+    return flow_graph
+
+
+def convert_block(data):
+    block_id = data.findtext('key')
+
+    params = OrderedDict(sorted(
+        (param.findtext('key'), param.findtext('value'))
+        for param in data.findall('param')
+    ))
+    states = OrderedDict()
+    x, y = ast.literal_eval(params.pop('_coordinate', '(10, 10)'))
+    states['coordinate'] = yaml.ListFlowing([x, y])
+    states['rotation'] = int(params.pop('_rotation', '0'))
+    enabled = params.pop('_enabled', 'True')
+    states['state'] = (
+        'enabled' if enabled in ('1', 'True') else
+        'bypassed' if enabled == '2' else
+        'disabled'
+    )
+
+    block = OrderedDict()
+    if block_id != 'options':
+        block['name'] = params.pop('id')
+    block['id'] = block_id
+    block['parameters'] = params
+    block['states'] = states
+
+    return block
+
+
+def convert_connection(data):
+    src_blk_id = data.findtext('source_block_id')
+    src_port_id = data.findtext('source_key')
+    snk_blk_id = data.findtext('sink_block_id')
+    snk_port_id = data.findtext('sink_key')
+
+    if src_port_id.isdigit():
+        src_port_id = 'out' + src_port_id
+    if snk_port_id.isdigit():
+        snk_port_id = 'in' + snk_port_id
+
+    return yaml.ListFlowing([src_blk_id, src_port_id, snk_blk_id, snk_port_id])
+
+
+def _guess_file_format_1(data):
+    """Try to guess the file format for flow-graph files without version tag"""
+
+    def has_numeric_port_ids(src_id, src_port_id, snk_id, snk_port_id):
+        return src_port_id.isdigit() and snk_port_id.is_digit()
+
+    try:
+        if any(not has_numeric_port_ids(*con) for con in data['connections']):
+            return 1
+    except:
+        pass
+    return 0
-- 
cgit v1.2.3