import os from collections import defaultdict from xml.etree import ElementTree as ET # Todo: "" # execute from galaxy root dir tooldict = defaultdict(list) def main(): doc = ET.parse("tool_conf.xml") root = doc.getroot() # index range 1-1000, current sections/tools divided between 250-750 sectionindex = 250 sectionfactor = int(500 / len(root)) for rootchild in root: currentsectionlabel = "" if (rootchild.tag == "section"): sectionname = rootchild.attrib['name'] # per section tool index range 1-1000, current labels/tools # divided between 20 and 750 toolindex = 250 toolfactor = int(500 / len(rootchild)) currentlabel = "" for sectionchild in rootchild: if (sectionchild.tag == "tool"): addToToolDict(sectionchild, sectionname, sectionindex, toolindex, currentlabel) toolindex += toolfactor elif (sectionchild.tag == "label"): currentlabel = sectionchild.attrib["text"] sectionindex += sectionfactor elif (rootchild.tag == "tool"): addToToolDict(rootchild, "", sectionindex, None, currentsectionlabel) sectionindex += sectionfactor elif (rootchild.tag == "label"): currentsectionlabel = rootchild.attrib["text"] sectionindex += sectionfactor # scan galaxy root tools dir for tool-specific xmls toolconffilelist = getfnl(os.path.join(os.getcwd(), "tools")) # foreach tool xml: # check if the tags element exists in the tool xml (as child of ) # if not, add empty tags element for later use # if this tool is in the above tooldict, add the toolboxposition element to the tool xml # if not, then nothing. for toolconffile in toolconffilelist: hastags = False hastoolboxpos = False # parse tool config file into a document structure as defined by the ElementTree tooldoc = ET.parse(toolconffile) # get the root element of the toolconfig file tooldocroot = tooldoc.getroot() # check tags element, set flag tagselement = tooldocroot.find("tags") if (tagselement): hastags = True # check if toolboxposition element already exists in this tooconfig file toolboxposelement = tooldocroot.find("toolboxposition") if (toolboxposelement): hastoolboxpos = True if (not (hastags and hastoolboxpos)): original = open(toolconffile) contents = original.readlines() original.close() # the new elements will be added directly below the root tool element addelementsatposition = 1 # but what's on the first line? Root or not? if (contents[0].startswith("\n ") contents = (contents[0:addelementsatposition] + newelements + contents[addelementsatposition:]) # add .new for testing/safety purposes :P newtoolconffile = open(toolconffile, 'w') newtoolconffile.writelines(contents) newtoolconffile.close() def addToToolDict(tool, sectionname, sectionindex, toolindex, currentlabel): toolfile = tool.attrib["file"] realtoolfile = os.path.join(os.getcwd(), "tools", toolfile) # define attributes for the toolboxposition xml-tag attribdict = {} if (sectionname): attribdict["section"] = sectionname if (currentlabel): attribdict["label"] = currentlabel if (sectionindex): attribdict["sectionorder"] = str(sectionindex) if (toolindex): attribdict["order"] = str(toolindex) tooldict[realtoolfile].append(attribdict) # Build a list of all toolconf xml files in the tools directory def getfnl(startdir): filenamelist = [] for root, dirs, files in os.walk(startdir): for fn in files: fullfn = os.path.join(root, fn) if fn.endswith('.xml'): try: doc = ET.parse(fullfn) except Exception as e: raise Exception(f"Oops, bad XML in '{fullfn}': {e}") rootelement = doc.getroot() # here we check if this xml file actually is a tool conf xml! if rootelement.tag == 'tool': filenamelist.append(fullfn) return filenamelist if __name__ == "__main__": main()