1 new commit in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/changeset/cb74fddd002a/ changeset: cb74fddd002a user: greg date: 2012-03-06 20:50:55 summary: Introduce a new integrated_tool_panle.xml file which is initially created by parsing all tool panel config files (e.g., tool_conf.xml, shed_tool_conf.xml, migrated_tools.xml, etc). After the file is created, the order of the items displayed in the tool panel is defined by integrated_tool_panel.xml. Galaxy admins can easily edit the file to change the order of items in the tool panel. After it is generated, all tool panel config files (e.g., tool_conf.xml, shed_tool_conf.xml, migrated_tools.xml, etc) will be used to load tools, workflows, etc, while integrated tool_panel.xml will define where they are displayed. affected #: 3 files diff -r 0ad94cd9dd3a6e718f835d38a84afd2c8fe21cb4 -r cb74fddd002a417f015f262d6a8b4ebedf21f7db lib/galaxy/tools/__init__.py --- a/lib/galaxy/tools/__init__.py +++ b/lib/galaxy/tools/__init__.py @@ -46,17 +46,24 @@ Create a toolbox from the config files named by `config_filenames`, using `tool_root_dir` as the base directory for finding individual tool config files. """ - # The shed_tool_confs list contains dictionaries storing information about - # the tools defined in the tool config xml files used when installing tool - # shed repositories (see the init_tools() method below). The config_elems - # list contains the in-memory elements resulting from parsing the xml config. + # The shed_tool_confs list contains dictionaries storing information about the tools defined in each + # shed-related shed_tool_conf.xml file. self.shed_tool_confs = [] self.tools_by_id = {} self.workflows_by_id = {} + # In-memory dictionary that defines the layout of the tool panel. self.tool_panel = odict() - # The following refers to the tool_path config setting for backward compatibility. - # Additional newer (e.g., shed_tool_conf.xml) files include the tool_path attribute - # within the <toolbox> tag. + # File that contains the XML section and tool tags from all tool panel config files integrated into a + # single file that defines the tool panel layout. This file can be changed by the Galaxy administrator + # (in a way similar to the single tool_conf.xml file in the past) to alter the layout of the tool panel. + self.integrated_tool_panel_config = os.path.join( app.config.root, 'integrated_tool_panel.xml' ) + # In-memory dictionary that defines the layout of the tool_panel.xml file on disk. + self.integrated_tool_panel = odict() + self.integrated_tool_panel_config_has_contents = os.path.exists( self.integrated_tool_panel_config ) and os.stat( self.integrated_tool_panel_config ).st_size > 0 + if self.integrated_tool_panel_config_has_contents: + self.load_integrated_tool_panel_keys() + # The following refers to the tool_path config setting for backward compatibility. The shed-related + # (e.g., shed_tool_conf.xml) files include the tool_path attribute within the <toolbox> tag. self.tool_root_dir = tool_root_dir self.app = app self.init_dependency_manager() @@ -67,8 +74,7 @@ log.exception( "Error loading tools defined in config %s", config_filename ) def init_tools( self, config_filename ): """ - Read the configuration file and load each tool. - The following tags are currently supported: + Read the configuration file and load each tool. The following tags are currently supported: <toolbox><tool file="data_source/upload.xml"/> # tools outside sections <label text="Basic Tools" id="basic_tools" /> # labels outside sections @@ -81,7 +87,7 @@ </toolbox> """ if self.app.config.get_bool( 'enable_tool_tags', False ): - log.info("removing all tool tag associations (" + str( self.sa_session.query( self.app.model.ToolTagAssociation ).count() ) + ")") + log.info("removing all tool tag associations (" + str( self.sa_session.query( self.app.model.ToolTagAssociation ).count() ) + ")" ) self.sa_session.query( self.app.model.ToolTagAssociation ).delete() self.sa_session.flush() log.info( "Parsing the tool configuration %s" % config_filename ) @@ -97,40 +103,149 @@ parsing_shed_tool_conf = False # Default to backward compatible config setting. tool_path = self.tool_root_dir + # Only load the panel_dict under certain conditions. + load_panel_dict = not self.integrated_tool_panel_config_has_contents for elem in root: if parsing_shed_tool_conf: config_elems.append( elem ) if elem.tag == 'tool': - self.load_tool_tag_set( elem, self.tool_panel, tool_path, guid=elem.get( 'guid' ), section=None ) + self.load_tool_tag_set( elem, self.tool_panel, self.integrated_tool_panel, tool_path, load_panel_dict, guid=elem.get( 'guid' ) ) elif elem.tag == 'workflow': - self.load_workflow_tag_set( elem, self.tool_panel ) + self.load_workflow_tag_set( elem, self.tool_panel, self.integrated_tool_panel, load_panel_dict ) elif elem.tag == 'section': - self.load_section_tag_set( elem, self.tool_panel, tool_path ) + self.load_section_tag_set( elem, tool_path, load_panel_dict ) elif elem.tag == 'label': - self.load_label_tag_set( elem, self.tool_panel ) + self.load_label_tag_set( elem, self.tool_panel, self.integrated_tool_panel ) if parsing_shed_tool_conf: shed_tool_conf_dict = dict( config_filename=config_filename, tool_path=tool_path, config_elems=config_elems ) self.shed_tool_confs.append( shed_tool_conf_dict ) + if self.integrated_tool_panel_config_has_contents: + # Load self.tool_panel based on the order in self.integrated_tool_panel. + self.load_tool_panel() + # Always write the current in-memory integrated_tool_panel to the integrated_tool_panel.xml file. + # This will cover cases where the Galaxy administrator manually edited one or more of the tool panel + # config files, adding or removing locally developed tools or workflows. + self.write_integrated_tool_panel_config_file() + def load_tool_panel( self ): + for key, val in self.integrated_tool_panel.items(): + if key.startswith( 'tool_' ): + tool_id = key.replace( 'tool_', '', 1 ) + if tool_id in self.tools_by_id: + tool = self.tools_by_id[ tool_id ] + self.tool_panel[ key ] = tool + log.debug( "Loaded tool id: %s, version: %s." % ( tool.id, tool.version ) ) + elif key.startswith( 'workflow_' ): + workflow_id = key.replace( 'workflow_', '', 1 ) + if workflow_id in self.workflows_by_id: + workflow = self.workflows_by_id[ workflow_id ] + self.tool_panel[ key ] = workflow + log.debug( "Loaded workflow: %s %s" % ( workflow_id, workflow.name ) ) + elif key.startswith( 'label_' ): + self.tool_panel[ key ] = val + elif key.startswith( 'section_' ): + elem = Element( 'section' ) + elem.attrib[ 'id' ] = val.id or '' + elem.attrib[ 'name' ] = val.name or '' + elem.attrib[ 'version' ] = val.version or '' + section = ToolSection( elem ) + log.debug( "Loading section: %s" % elem.get( 'name' ) ) + for section_key, section_val in val.elems.items(): + if section_key.startswith( 'tool_' ): + tool_id = section_key.replace( 'tool_', '', 1 ) + if tool_id in self.tools_by_id: + tool = self.tools_by_id[ tool_id ] + section.elems[ section_key ] = tool + log.debug( "Loaded tool id: %s, version: %s." % ( tool.id, tool.version ) ) + elif section_key.startswith( 'workflow_' ): + workflow_id = section_key.replace( 'workflow_', '', 1 ) + if workflow_id in self.workflows_by_id: + workflow = self.workflows_by_id[ workflow_id ] + section.elems[ section_key ] = workflow + log.debug( "Loaded workflow: %s %s" % ( workflow_id, workflow.name ) ) + elif section_key.startswith( 'label_' ): + section.elems[ section_key ] = section_val + self.tool_panel[ key ] = section + def load_integrated_tool_panel_keys( self ): + """ + Load the integrated tool panel keys, setting values for tools and workflows to None. The values will + be reset when the various tool panel config files are parsed, at which time the tools and workflows are + loaded. + """ + tree = util.parse_xml( self.integrated_tool_panel_config ) + root = tree.getroot() + for elem in root: + if elem.tag == 'tool': + key = 'tool_%s' % elem.get( 'id' ) + self.integrated_tool_panel[ key ] = None + elif elem.tag == 'workflow': + key = 'workflow_%s' % elem.get( 'id' ) + self.integrated_tool_panel[ key ] = None + elif elem.tag == 'section': + section = ToolSection( elem ) + for section_elem in elem: + if section_elem.tag == 'tool': + key = 'tool_%s' % section_elem.get( 'id' ) + section.elems[ key ] = None + elif section_elem.tag == 'workflow': + key = 'workflow_%s' % section_elem.get( 'id' ) + section.elems[ key ] = None + elif section_elem.tag == 'label': + key = 'label_%s' % section_elem.get( 'id' ) + section.elems[ key ] = ToolSectionLabel( section_elem ) + key = 'section_%s' % elem.get( 'id' ) + self.integrated_tool_panel[ key ] = section + elif elem.tag == 'label': + key = 'label_%s' % elem.get( 'id' ) + self.integrated_tool_panel[ key ] = ToolSectionLabel( elem ) + def write_integrated_tool_panel_config_file( self ): + """ + Write the current in-memory version of the integrated_tool_panel.xml file to disk. Since Galaxy administrators + use this file to manage the tool panel, we'll not use util.xml_to_string() since it doesn't write XML quite right. + """ + fd, filename = tempfile.mkstemp() + os.write( fd, '<?xml version="1.0"?>\n' ) + os.write( fd, '<toolbox>\n' ) + for key, item in self.integrated_tool_panel.items(): + if key.startswith( 'tool_' ): + if item: + os.write( fd, ' <tool id="%s" />\n' % item.id ) + elif key.startswith( 'workflow_' ): + if item: + os.write( fd, ' <workflow id="%s" />\n' % item.id ) + elif key.startswith( 'label_' ): + label_id = item.id or '' + label_text = item.text or '' + label_version = item.version or '' + os.write( fd, ' <label id="%s" text="%s" version="%s" />\n' % ( label_id, label_text, label_version ) ) + elif key.startswith( 'section_' ): + section_id = item.id or '' + section_name = item.name or '' + section_version = item.version or '' + os.write( fd, ' <section id="%s" name="%s" version="%s">\n' % ( section_id, section_name, section_version ) ) + for section_key, section_item in item.elems.items(): + if section_key.startswith( 'tool_' ): + if section_item: + os.write( fd, ' <tool id="%s" />\n' % section_item.id ) + elif section_key.startswith( 'workflow_' ): + if section_item: + os.write( fd, ' <workflow id="%s" />\n' % section_item.id ) + elif section_key.startswith( 'label_' ): + os.write( fd, ' <label id="%s" text="%s" version="%s" />\n' % ( label_id, label_text, label_version ) ) + os.write( fd, ' </section>\n' ) + os.write( fd, '</toolbox>\n' ) + os.close( fd ) + shutil.move( filename, os.path.abspath( self.integrated_tool_panel_config ) ) + os.chmod( self.integrated_tool_panel_config, 0644 ) def get_tool( self, tool_id, tool_version=None ): - # Attempt to locate the tool in our in-memory dictionary. + """Attempt to locate a tool in the tool box.""" if tool_id in self.tools_by_id: tool = self.tools_by_id[ tool_id ] if tool_version and tool.version == tool_version: return tool else: return tool - # Handle the case where the received tool_id has a tool_version. In this case, one of the following - # conditions is true. - # 1. The tool was used when it was included in the Galaxy distribution, but now the tool is contained - # in an installed tool shed repository. In this case, the original tool id can be mapped to the new - # tool id, which is the tool's guid in the tool shed repository. This scenarios can occur in - # workflows and in a history item when the rerun icon is clicked. The weakness here is that workflows - # currently handle only tool ids and not versions. - # 2. A proprietary tool was initially developed and hosted in a local Galaxy instance, but the developer - # later uploaded the tool to a Galaxy tool shed, removed the original tool from the local Galaxy - # instance and installed the tool's repository from the tool shed. tv = self.__get_tool_version( tool_id ) if tv: tool_version_ids = tv.get_version_ids( self.app ) @@ -143,7 +258,7 @@ return tool return None def __get_tool_version( self, tool_id ): - """Return a ToolVersion if one exists for our tool_id""" + """Return a ToolVersion if one exists for the tool_id""" return self.sa_session.query( self.app.model.ToolVersion ) \ .filter( self.app.model.ToolVersion.table.c.tool_id == tool_id ) \ .first() @@ -154,12 +269,12 @@ self.app.model.ToolShedRepository.table.c.owner == owner, self.app.model.ToolShedRepository.table.c.installed_changeset_revision == installed_changeset_revision ) ) \ .first() - def load_tool_tag_set( self, elem, panel_dict, tool_path, guid=None, section=None ): + def load_tool_tag_set( self, elem, panel_dict, integrated_panel_dict, tool_path, load_panel_dict, guid=None ): try: path = elem.get( "file" ) if guid is None: tool_shed_repository = None - can_load = True + can_load_into_panel_dict = True else: # The tool is contained in an installed tool shed repository, so load # the tool only if the repository has not been marked deleted. @@ -174,13 +289,14 @@ tool_shed_repository = self.__get_tool_shed_repository( tool_shed, repository_name, repository_owner, installed_changeset_revision ) if tool_shed_repository: # Only load tools if the repository is not deactivated or uninstalled. - can_load = not tool_shed_repository.deleted + can_load_into_panel_dict = not tool_shed_repository.deleted else: # If there is not yet a tool_shed_repository record, we're in the process of installing # a new repository, so any included tools can be loaded into the tool panel. - can_load = True - if can_load: - tool = self.load_tool( os.path.join( tool_path, path ), guid=guid ) + can_load_into_panel_dict = True + tool = self.load_tool( os.path.join( tool_path, path ), guid=guid ) + key = 'tool_%s' % str( tool.id ) + if can_load_into_panel_dict: if guid is not None: tool.tool_shed = tool_shed tool.repository_name = repository_name @@ -218,52 +334,58 @@ if tool.id not in self.tools_by_id: # Allow for the same tool to be loaded into multiple places in the tool panel. self.tools_by_id[ tool.id ] = tool - key = 'tool_' + tool.id - panel_dict[ key ] = tool - log.debug( "Loaded tool id: %s, version: %s." % ( tool.id, tool.version ) ) + if load_panel_dict: + panel_dict[ key ] = tool + # Always load the tool into the integrated_panel_dict, or it will not be included in the integrated_tool_panel.xml file. + integrated_panel_dict[ key ] = tool except: - log.exception( "error reading tool from path: %s" % path ) - def load_workflow_tag_set( self, elem, panel_dict ): + log.exception( "Error reading tool from path: %s" % path ) + def load_workflow_tag_set( self, elem, panel_dict, integrated_panel_dict, load_panel_dict ): try: # TODO: should id be encoded? workflow_id = elem.get( 'id' ) workflow = self.load_workflow( workflow_id ) self.workflows_by_id[ workflow_id ] = workflow key = 'workflow_' + workflow_id - panel_dict[ key ] = workflow - log.debug( "Loaded workflow: %s %s" % ( workflow_id, workflow.name ) ) + if load_panel_dict: + panel_dict[ key ] = workflow + # Always load workflows into the integrated_panel_dict. + integrated_panel_dict[ key ] = workflow except: - log.exception( "error loading workflow: %s" % workflow_id ) - def load_label_tag_set( self, elem, panel_dict ): + log.exception( "Error loading workflow: %s" % workflow_id ) + def load_label_tag_set( self, elem, panel_dict, integrated_panel_dict ): label = ToolSectionLabel( elem ) key = 'label_' + label.id - panel_dict[ key ] = label - def load_section_tag_set( self, elem, panel_dict, tool_path ): + if not self.integrated_tool_panel_config_has_contents: + panel_dict[ key ] = label + integrated_panel_dict[ key ] = label + def load_section_tag_set( self, elem, tool_path, load_panel_dict ): key = 'section_' + elem.get( "id" ) - if key in panel_dict: - # Loading an existing section in self.tool_panel - section = panel_dict[ key ] + if key in self.tool_panel: + section = self.tool_panel[ key ] elems = section.elems - log.debug( "Reloading section: %s" % elem.get( "name" ) ) else: - # Adding a new section to self.tool_panel section = ToolSection( elem ) elems = section.elems - log.debug( "Loading section: %s" % section.name ) + if key in self.integrated_tool_panel: + integrated_section = self.integrated_tool_panel[ key ] + integrated_elems = integrated_section.elems + else: + integrated_section = ToolSection( elem ) + integrated_elems = integrated_section.elems for sub_elem in elem: if sub_elem.tag == 'tool': - self.load_tool_tag_set( sub_elem, elems, tool_path, guid=sub_elem.get( 'guid' ), section=section ) + self.load_tool_tag_set( sub_elem, elems, integrated_elems, tool_path, load_panel_dict, guid=sub_elem.get( 'guid' ) ) elif sub_elem.tag == 'workflow': - self.load_workflow_tag_set( sub_elem, elems ) + self.load_workflow_tag_set( sub_elem, elems, integrated_elems, load_panel_dict ) elif sub_elem.tag == 'label': - self.load_label_tag_set( sub_elem, elems ) - if key not in panel_dict: - panel_dict[ key ] = section + self.load_label_tag_set( sub_elem, elems, integrated_elems ) + if load_panel_dict: + self.tool_panel[ key ] = section + # Always load sections into the integrated_tool_panel. + self.integrated_tool_panel[ key ] = integrated_section def load_tool( self, config_file, guid=None ): - """ - Load a single tool from the file named by `config_file` and return - an instance of `Tool`. - """ + """Load a single tool from the file named by `config_file` and return an instance of `Tool`.""" # Parse XML configuration file and get the root element tree = util.parse_xml( config_file ) root = tree.getroot() @@ -344,7 +466,7 @@ def __init__( self, elem ): self.name = elem.get( "name" ) self.id = elem.get( "id" ) - self.version = elem.get( "version" ) + self.version = elem.get( "version" ) or '' self.elems = odict() class ToolSectionLabel( object ): @@ -355,7 +477,7 @@ def __init__( self, elem ): self.text = elem.get( "text" ) self.id = elem.get( "id" ) - self.version = elem.get( "version" ) + self.version = elem.get( "version" ) or '' class DefaultToolState( object ): """ diff -r 0ad94cd9dd3a6e718f835d38a84afd2c8fe21cb4 -r cb74fddd002a417f015f262d6a8b4ebedf21f7db lib/galaxy/util/shed_util.py --- a/lib/galaxy/util/shed_util.py +++ b/lib/galaxy/util/shed_util.py @@ -43,19 +43,29 @@ if new_install: # Add the new elements to the shed_tool_conf file on disk. add_to_shed_tool_config( app, shed_tool_conf_dict, elem_list ) + # Use the new elements to add entries to the config_elems = shed_tool_conf_dict[ 'config_elems' ] for config_elem in elem_list: # Add the new elements to the in-memory list of config_elems. config_elems.append( config_elem ) # Load the tools into the in-memory tool panel. if config_elem.tag == 'section': - app.toolbox.load_section_tag_set( config_elem, app.toolbox.tool_panel, tool_path ) + app.toolbox.load_section_tag_set( config_elem, tool_path, load_panel_dict=True ) + elif config_elem.tag == 'workflow': + app.toolbox.load_workflow_tag_set( config_elem, app.toolbox.tool_panel, app.toolbox.integrated_tool_panel, load_panel_dict=True ) elif config_elem.tag == 'tool': guid = config_elem.get( 'guid' ) - app.toolbox.load_tool_tag_set( config_elem, app.toolbox.tool_panel, tool_path=tool_path, guid=guid ) + app.toolbox.load_tool_tag_set( config_elem, + app.toolbox.tool_panel, + app.toolbox.integrated_tool_panel, + tool_path, + load_panel_dict=True, + guid=guid ) # Replace the old list of in-memory config_elems with the new list for this shed_tool_conf_dict. shed_tool_conf_dict[ 'config_elems' ] = config_elems app.toolbox.shed_tool_confs[ index ] = shed_tool_conf_dict + # Write the current in-memory version of the integrated_tool_panel.xml file to disk. + app.toolbox.write_integrated_tool_panel_config_file() if app.toolbox_search.enabled: # If search support for tools is enabled, index the new installed tools. app.toolbox_search = ToolBoxSearch( app.toolbox ) @@ -446,7 +456,7 @@ if tool_section: section_id = tool_section.id section_name = tool_section.name - section_version = tool_section.version + section_version = tool_section.version or '' else: section_id = '' section_name = '' @@ -921,6 +931,8 @@ # {<Tool guid> : [{ tool_config : <tool_config_file>, id: <ToolSection id>, version : <ToolSection version>, name : <TooSection name>}]} # But not like this. # { id: <ToolSection id>, version : <ToolSection version>, name : <TooSection name>} + if not tool_section_dict: + return False if len( tool_section_dict ) != 3: return True for k, v in tool_section_dict: @@ -1001,11 +1013,17 @@ # Remove the tool from the section in the in-memory tool panel. if section_key in trans.app.toolbox.tool_panel: tool_section = trans.app.toolbox.tool_panel[ section_key ] - tool_key = key = 'tool_%s' % str( tool_elem.get( 'guid' ) ) - # Remove empty sections only from the in-memory config_elems, but leave - # the in-memory tool panel alone. + tool_key = 'tool_%s' % str( tool_elem.get( 'guid' ) ) + # Remove empty sections only from the in-memory config_elems, but leave the in-memory tool panel alone. if tool_key in tool_section.elems: del tool_section.elems[ tool_key ] + if uninstall: + # Remove the tool from the section in the in-memory integrated tool panel. + if section_key in trans.app.toolbox.integrated_tool_panel: + tool_section = trans.app.toolbox.integrated_tool_panel[ section_key ] + tool_key = 'tool_%s' % str( tool_elem.get( 'guid' ) ) + if tool_key in tool_section.elems: + del tool_section.elems[ tool_key ] if len( config_elem ) < 1: # Keep a list of all empty section elements so they can be removed. config_elems_to_remove.append( config_elem ) @@ -1014,6 +1032,9 @@ tool_key = key = 'tool_%s' % str( config_elem.get( 'guid' ) ) if tool_key in trans.app.toolbox.tool_panel: del trans.app.toolbox.tool_panel[ tool_key ] + if uninstall: + if tool_key in trans.app.toolbox.integrated_tool_panel: + del trans.app.toolbox.integrated_tool_panel[ tool_key ] config_elems_to_remove.append( config_elem ) for config_elem in config_elems_to_remove: # Remove the element from the in-memory list of elements. @@ -1024,6 +1045,9 @@ if trans.app.toolbox_search.enabled: # If search support for tools is enabled, index tools. trans.app.toolbox_search = ToolBoxSearch( trans.app.toolbox ) + if uninstall: + # Write the current in-memory version of the integrated_tool_panel.xml file to disk. + trans.app.toolbox.write_integrated_tool_panel_config_file() def update_repository( current_working_dir, repo_files_dir, changeset_revision ): # Update the cloned repository to changeset_revision. It is imperative that the # installed repository is updated to the desired changeset_revision before metadata diff -r 0ad94cd9dd3a6e718f835d38a84afd2c8fe21cb4 -r cb74fddd002a417f015f262d6a8b4ebedf21f7db lib/galaxy/web/controllers/admin_toolshed.py --- a/lib/galaxy/web/controllers/admin_toolshed.py +++ b/lib/galaxy/web/controllers/admin_toolshed.py @@ -427,8 +427,9 @@ metadata = repository.metadata if 'tool_panel_section' in metadata: tool_panel_dict = metadata[ 'tool_panel_section' ] + if not tool_panel_dict: + tool_panel_dict = generate_tool_panel_dict_for_new_install( metadata[ 'tools' ] ) else: - # This should never happen. tool_panel_dict = generate_tool_panel_dict_for_new_install( metadata[ 'tools' ] ) # TODO: Fix this to handle the case where the tools are distributed across in more than 1 ToolSection. The # following assumes everything was loaded into 1 section (or no section) in the tool panel. @@ -474,6 +475,8 @@ elif tool_panel_section: section_key = 'section_%s' % tool_panel_section tool_section = trans.app.toolbox.tool_panel[ section_key ] + else: + tool_section = None tool_shed_repository, metadata_dict = load_repository_contents( trans, repository_name=repository.name, description=repository.description, @@ -505,14 +508,17 @@ metadata = repository.metadata if 'tool_panel_section' in metadata: tool_panel_dict = metadata[ 'tool_panel_section' ] - if panel_entry_per_tool( tool_panel_dict ): - # TODO: Fix this to handle the case where the tools are distributed across in more than 1 ToolSection. The - # following assumes everything was loaded into 1 section (or no section) in the tool panel. - tool_section_dicts = tool_panel_dict[ tool_panel_dict.keys()[ 0 ] ] - tool_section_dict = tool_section_dicts[ 0 ] - original_section_name = tool_section_dict[ 'name' ] + if tool_panel_dict: + if panel_entry_per_tool( tool_panel_dict ): + # TODO: Fix this to handle the case where the tools are distributed across in more than 1 ToolSection. The + # following assumes everything was loaded into 1 section (or no section) in the tool panel. + tool_section_dicts = tool_panel_dict[ tool_panel_dict.keys()[ 0 ] ] + tool_section_dict = tool_section_dicts[ 0 ] + original_section_name = tool_section_dict[ 'name' ] + else: + original_section_name = tool_panel_dict[ 'name' ] else: - original_section_name = tool_panel_dict[ 'name' ] + original_section_name = '' else: original_section_name = '' tool_panel_section_select_field = build_tool_panel_section_select_field( trans ) Repository URL: https://bitbucket.org/galaxy/galaxy-central/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.