Platform.py

Go to the documentation of this file.
00001 """
00002 Copyright 2008 Free Software Foundation, Inc.
00003 This file is part of GNU Radio
00004 
00005 GNU Radio Companion is free software; you can redistribute it and/or
00006 modify it under the terms of the GNU General Public License
00007 as published by the Free Software Foundation; either version 2
00008 of the License, or (at your option) any later version.
00009 
00010 GNU Radio Companion is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 GNU General Public License for more details.
00014 
00015 You should have received a copy of the GNU General Public License
00016 along with this program; if not, write to the Free Software
00017 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
00018 """
00019 ##@package grc.elements.Platform
00020 #A Platform contains all blocks in platform.
00021 #@author Josh Blum
00022 
00023 import os
00024 from grc import ParseXML
00025 from grc import Utils
00026 from grc.elements.Element import Element as _Element
00027 from grc.elements.FlowGraph import FlowGraph as _FlowGraph
00028 from grc.elements.Connection import Connection as _Connection
00029 from grc.elements.Block import Block as _Block
00030 from grc.elements.Port import Port as _Port
00031 from grc.elements.Param import Param as _Param
00032 from grc.Constants import DATA_DIR
00033 
00034 class Platform(_Element):
00035 
00036         def __init__(self, name, key, block_paths, block_dtd, block_tree, default_flow_graph, generator):
00037                 """!
00038                 Make a platform from the arguments.
00039                 @param name the platform name
00040                 @param key the unique platform key
00041                 @param block_paths the file paths to blocks in this platform
00042                 @param block_dtd the dtd validator for xml block wrappers
00043                 @param block_tree the nested tree of block keys and categories
00044                 @param default_flow_graph the default flow graph file path
00045                 @param load_one a single file to load into this platform or None
00046                 @return a platform object
00047                 """
00048                 _Element.__init__(self)
00049                 self._name = name
00050                 self._key = key
00051                 self._block_paths = block_paths
00052                 self._block_dtd = block_dtd
00053                 self._block_tree = block_tree
00054                 self._default_flow_graph = default_flow_graph
00055                 self._generator = generator
00056                 #create a dummy flow graph for the blocks
00057                 self._flow_graph = _Element(self)
00058                 #load the blocks
00059                 self._blocks = dict()
00060                 self._blocks_n = dict()
00061                 for block_path in self._block_paths:
00062                         if os.path.isfile(block_path): self._load_block(block_path)
00063                         elif os.path.isdir(block_path):
00064                                 for dirpath,dirnames,filenames in os.walk(block_path):
00065                                         for filename in filter(lambda f: f.endswith('.xml'), filenames):
00066                                                 self._load_block(os.path.join(dirpath, filename))
00067 
00068         def get_prefs_block(self): return self.get_new_flow_graph().get_new_block('preferences')
00069 
00070         def _load_block(self, f):
00071                 """!
00072                 Load the block wrapper from the file path.
00073                 The block wrapper must pass validation, and have a unique block key.
00074                 If any of the checks fail, exit with error.
00075                 @param f the file path
00076                 """
00077                 try: ParseXML.validate_dtd(f, self._block_dtd)
00078                 except ParseXML.XMLSyntaxError, e: self._exit_with_error('Block definition "%s" failed: \n\t%s'%(f, e))
00079                 n = ParseXML.from_file(f)['block']
00080                 block = self.Block(self._flow_graph, n)
00081                 key = block.get_key()
00082                 #test against repeated keys
00083                 try: assert(key not in self.get_block_keys())
00084                 except AssertionError: self._exit_with_error('Key "%s" already exists in blocks'%key)
00085                 #store the block
00086                 self._blocks[key] = block
00087                 self._blocks_n[key] = n
00088 
00089         def load_block_tree(self, block_tree):
00090                 """!
00091                 Load a block tree with categories and blocks.
00092                 Step 1: Load all blocks from the xml specification.
00093                 Step 2: Load blocks with builtin category specifications.
00094                 @param block_tree the block tree object
00095                 """
00096                 #recursive function to load categories and blocks
00097                 def load_category(cat_n, parent=''):
00098                         #add this category
00099                         parent = '%s/%s'%(parent, cat_n['name'])
00100                         block_tree.add_block(parent)
00101                         #recursive call to load sub categories
00102                         map(lambda c: load_category(c, parent), Utils.listify(cat_n, 'cat'))
00103                         #add blocks in this category
00104                         for block_key in Utils.listify(cat_n, 'block'): 
00105                                 block_tree.add_block(parent, self.get_block(block_key))
00106                 #load the block tree
00107                 f = self._block_tree
00108                 try: ParseXML.validate_dtd(f, os.path.join(DATA_DIR, 'block_tree.dtd'))
00109                 except ParseXML.XMLSyntaxError, e: self._exit_with_error('Block tree "%s" failed: \n\t%s'%(f, e))
00110                 #add all blocks in the tree
00111                 load_category(ParseXML.from_file(f)['cat'])
00112                 #add all other blocks, use the catgory
00113                 for block in self.get_blocks():
00114                         #blocks with empty categories are in the xml block tree or hidden
00115                         if block.get_category(): block_tree.add_block(block.get_category(), block)
00116 
00117         def __str__(self): return 'Platform - %s(%s)'%(self.get_key(), self.get_name())
00118 
00119         def is_platform(self): return True
00120 
00121         def get_new_flow_graph(self): return self.FlowGraph(self)
00122 
00123         def get_default_flow_graph(self): return self._default_flow_graph
00124 
00125         def get_generator(self): return self._generator
00126 
00127         ##############################################
00128         # Access Blocks
00129         ##############################################
00130         def get_block_keys(self): return self._blocks.keys()
00131         def get_block(self, key): return self._blocks[key]
00132         def get_blocks(self): return self._blocks.values()
00133         def get_new_block(self, flow_graph, key): return self.Block(flow_graph, n=self._blocks_n[key])
00134 
00135         def get_name(self): return self._name
00136 
00137         def get_key(self): return self._key
00138 
00139         ##############################################
00140         # Constructors
00141         ##############################################
00142         FlowGraph = _FlowGraph
00143         Connection = _Connection
00144         Block = _Block
00145         Source = _Port
00146         Sink = _Port
00147         Param = _Param

Generated on Sat Aug 23 02:00:11 2008 for GNU Radio Companion by  doxygen 1.5.4