import os import sys from xml.etree import ElementTree as ET def prettify(elem): from xml.dom import minidom rough_string = ET.tostring(elem, 'utf-8') repaired = minidom.parseString(rough_string) return repaired.toprettyxml(indent=' ') # Build a list of all toolconf xml files in the tools directory def getfilenamelist(startdir): filenamelist = [] for root, dirs, files in os.walk(startdir): for fn in files: fullfn = os.path.join(root, fn) if fn.endswith('toolconf.xml'): filenamelist.append(fullfn) elif fn.endswith('.xml'): try: doc = ET.parse(fullfn) except: print "An OOPS on", fullfn raise rootelement = doc.getroot() # Only interpret those 'tool' XML files that have # the 'section' element. if rootelement.tag == 'tool': if rootelement.findall('toolboxposition'): filenamelist.append(fullfn) else: print "DBG> tool config does not have a
:", fullfn return filenamelist class ToolBox(object): def __init__(self): from collections import defaultdict self.tools = defaultdict(list) self.sectionorders = {} def add(self, toolelement, toolboxpositionelement): section = toolboxpositionelement.attrib.get('section','') label = toolboxpositionelement.attrib.get('label','') order = int(toolboxpositionelement.attrib.get('order', '0')) sectionorder = int(toolboxpositionelement.attrib.get('sectionorder', '0')) # If this is the first time we encounter the section, store its order # number. If we have seen it before, ignore the given order and use # the stored one instead if not self.sectionorders.has_key(section): self.sectionorders[section] = sectionorder else: sectionorder = self.sectionorders[section] # Sortorder: add intelligent mix to the front self.tools[("%05d-%s"%(sectionorder,section), label, order, section)].append(toolelement) def addElementsTo(self, rootelement): toolkeys = self.tools.keys() toolkeys.sort() # Initialize the loop: IDs to zero, current section and label to '' currentsection = '' sectionnumber = 0 currentlabel = '' labelnumber = 0 for toolkey in toolkeys: section = toolkey[3] # If we change sections, add the new section to the XML tree, # and start adding stuff to the new section. If the new section # is '', start adding stuff to the root again. if currentsection != section: currentsection = section # Start the section with empty label currentlabel = '' if section: sectionnumber += 1 attrib = {'name': section, 'id': "section%d"% sectionnumber} sectionelement = ET.Element('section', attrib) rootelement.append(sectionelement) currentelement = sectionelement else: currentelement = rootelement label = toolkey[1] # If we change labels, add the new label to the XML tree if currentlabel != label: currentlabel = label if label: labelnumber += 1 attrib = {'text': label, 'id': "label%d"% labelnumber} labelelement = ET.Element('label', attrib) currentelement.append(labelelement) # Add the tools that are in this place for toolelement in self.tools[toolkey]: currentelement.append(toolelement) # Analyze all the toolconf xml files given in the filenamelist # Build a list of all sections def scanfiles(filenamelist): # Build an empty tool box toolbox = ToolBox() # Read each of the files in the list for fn in filenamelist: doc = ET.parse(fn) root = doc.getroot() if root.tag == 'tool': toolelements = [root] else: toolelements = doc.findall('tool') for toolelement in toolelements: # Figure out where the tool XML file is, absolute path. if toolelement.attrib.has_key('file'): # It is mentioned, we need to make it absolute fileattrib = os.path.join(os.getcwd(), os.path.dirname(fn), toolelement.attrib['file']) else: # It is the current file fileattrib = os.path.join(os.getcwd(), fn) # Store the file in the attibutes of the new tool element attrib = {'file': fileattrib} # Add the tags into the attributes tags = toolelement.find('tags') if tags: tagarray = [] for tag in tags.findall('tag'): tagarray.append(tag.text) attrib['tags'] = ",".join(tagarray) else: print "DBG> No tags in",fn # Build the tool element newtoolelement = ET.Element('tool', attrib) toolboxpositionelements = toolelement.findall('toolboxposition') if not toolboxpositionelements: print "DBG> %s has no toolboxposition" % fn else: for toolboxpositionelement in toolboxpositionelements: toolbox.add(newtoolelement, toolboxpositionelement) return toolbox def assemble(): filenamelist = [] for directorytree in ['tools']: filenamelist.extend(getfilenamelist('tools')) filenamelist.sort() toolbox = scanfiles(filenamelist) toolboxelement = ET.Element('toolbox') toolbox.addElementsTo(toolboxelement) print prettify(toolboxelement) if __name__ == "__main__": assemble()