mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-01 15:37:32 +08:00
3d57c22b63
Also fix Python3 compatibility. Remove unused method galaxy.tools.parameters.sanitize.ToolParameterSanitizer.restore_param() .
174 lines
6.1 KiB
Python
174 lines
6.1 KiB
Python
from __future__ import print_function
|
|
|
|
import os
|
|
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 <section>:", 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 section not in self.sectionorders:
|
|
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 = list(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 'file' in toolelement.attrib:
|
|
# 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()
|