Add a ToolPanelManager for Galaxy installs from the Tool Shed.

This commit is contained in:
Greg Von Kuster
2014-07-21 11:36:29 -04:00
parent 6d4cce5afe
commit 76d0960467
9 changed files with 611 additions and 546 deletions
@@ -30,6 +30,7 @@ from tool_shed.galaxy_install.grids import admin_toolshed_grids
from tool_shed.galaxy_install.metadata.installed_repository_metadata_manager import InstalledRepositoryMetadataManager
from tool_shed.galaxy_install.repair_repository_manager import RepairRepositoryManager
from tool_shed.galaxy_install.repository_dependencies import repository_dependency_manager
from tool_shed.galaxy_install.tools import tool_panel_manager
log = logging.getLogger( __name__ )
@@ -244,10 +245,10 @@ class AdminToolshed( AdminGalaxy ):
if kwd.get( 'deactivate_or_uninstall_repository_button', False ):
if tool_shed_repository.includes_tools_for_display_in_tool_panel:
# Handle tool panel alterations.
tool_util.remove_from_tool_panel( trans.app,
tool_shed_repository,
shed_tool_conf,
uninstall=remove_from_disk_checked )
tpm = tool_panel_manager.ToolPanelManager( trans.app )
tpm.remove_from_tool_panel( tool_shed_repository,
shed_tool_conf,
uninstall=remove_from_disk_checked )
if tool_shed_repository.includes_data_managers:
data_manager_util.remove_from_data_manager( trans.app, tool_shed_repository )
if tool_shed_repository.includes_datatypes:
@@ -1336,13 +1337,14 @@ class AdminToolshed( AdminGalaxy ):
# its repository dependencies.
includes_tool_dependencies = tool_shed_repository.includes_tool_dependencies
if tool_shed_repository.includes_tools_for_display_in_tool_panel:
tpm = tool_panel_manager.ToolPanelManager( trans.app )
# Handle the selected tool panel location for loading tools included in the tool shed repository.
tool_section, tool_panel_section_key = \
tool_util.handle_tool_panel_selection( toolbox=trans.app.toolbox,
metadata=metadata,
no_changes_checked=no_changes_checked,
tool_panel_section_id=tool_panel_section_id,
new_tool_panel_section_label=new_tool_panel_section_label )
tpm.handle_tool_panel_selection( toolbox=trans.app.toolbox,
metadata=metadata,
no_changes_checked=no_changes_checked,
tool_panel_section_id=tool_panel_section_id,
new_tool_panel_section_label=new_tool_panel_section_label )
if tool_section is not None:
# Just in case the tool_section.id differs from tool_panel_section_id, which it shouldn't...
tool_panel_section_id = str( tool_section.id )
@@ -1942,19 +1944,19 @@ class AdminToolshed( AdminGalaxy ):
updating_installed_repository=True,
persist=True )
if 'tools' in metadata_dict:
tpm = tool_panel_manager.ToolPanelManager( trans.app )
tool_panel_dict = metadata_dict.get( 'tool_panel_section', None )
if tool_panel_dict is None:
tool_panel_dict = suc.generate_tool_panel_dict_from_shed_tool_conf_entries( trans.app, repository )
repository_tools_tups = suc.get_repository_tools_tups( trans.app, metadata_dict )
tool_util.add_to_tool_panel( app=trans.app,
repository_name=str( repository.name ),
repository_clone_url=repository_clone_url,
changeset_revision=str( repository.installed_changeset_revision ),
repository_tools_tups=repository_tools_tups,
owner=str( repository.owner ),
shed_tool_conf=shed_tool_conf,
tool_panel_dict=tool_panel_dict,
new_install=False )
tpm.add_to_tool_panel( repository_name=str( repository.name ),
repository_clone_url=repository_clone_url,
changeset_revision=str( repository.installed_changeset_revision ),
repository_tools_tups=repository_tools_tups,
owner=str( repository.owner ),
shed_tool_conf=shed_tool_conf,
tool_panel_dict=tool_panel_dict,
new_install=False )
# Add new Data Manager entries
if 'data_manager' in metadata_dict:
new_data_managers = data_manager_util.install_data_managers( trans.app,
+19 -14
View File
@@ -33,6 +33,7 @@ from tool_shed.galaxy_install.tool_dependencies.recipe.env_file_builder import E
from tool_shed.galaxy_install.tool_dependencies.recipe.install_environment import InstallEnvironment
from tool_shed.galaxy_install.tool_dependencies.recipe.recipe_manager import StepManager
from tool_shed.galaxy_install.tool_dependencies.recipe.recipe_manager import TagManager
from tool_shed.galaxy_install.tools import tool_panel_manager
log = logging.getLogger( __name__ )
@@ -535,7 +536,8 @@ class InstallRepositoryManager( object ):
self.app.config.shed_tool_data_table_config,
persist=True )
if 'tools' in metadata_dict:
tool_panel_dict = tool_util.generate_tool_panel_dict_for_new_install( metadata_dict[ 'tools' ], tool_section )
tpm = tool_panel_manager.ToolPanelManager( self.app )
tool_panel_dict = tpm.generate_tool_panel_dict_for_new_install( metadata_dict[ 'tools' ], tool_section )
sample_files = metadata_dict.get( 'sample_files', [] )
tool_index_sample_files = tool_util.get_tool_index_sample_files( sample_files )
tool_util.copy_sample_files( self.app, tool_index_sample_files, tool_path=tool_path )
@@ -555,16 +557,18 @@ class InstallRepositoryManager( object ):
sample_files_copied )
# Copy remaining sample files included in the repository to the ~/tool-data directory of the
# local Galaxy instance.
tool_util.copy_sample_files( self.app, sample_files, tool_path=tool_path, sample_files_copied=sample_files_copied )
tool_util.add_to_tool_panel( app=self.app,
repository_name=tool_shed_repository.name,
repository_clone_url=repository_clone_url,
changeset_revision=tool_shed_repository.installed_changeset_revision,
repository_tools_tups=repository_tools_tups,
owner=tool_shed_repository.owner,
shed_tool_conf=shed_tool_conf,
tool_panel_dict=tool_panel_dict,
new_install=True )
tool_util.copy_sample_files( self.app,
sample_files,
tool_path=tool_path,
sample_files_copied=sample_files_copied )
tpm.add_to_tool_panel( repository_name=tool_shed_repository.name,
repository_clone_url=repository_clone_url,
changeset_revision=tool_shed_repository.installed_changeset_revision,
repository_tools_tups=repository_tools_tups,
owner=tool_shed_repository.owner,
shed_tool_conf=shed_tool_conf,
tool_panel_dict=tool_panel_dict,
new_install=True )
if 'data_manager' in metadata_dict:
new_data_managers = data_manager_util.install_data_managers( self.app,
self.app.config.shed_data_manager_config_file,
@@ -644,10 +648,11 @@ class InstallRepositoryManager( object ):
tool_shed_url = installation_dict[ 'tool_shed_url' ]
# Handle contained tools.
if includes_tools_for_display_in_tool_panel and ( new_tool_panel_section_label or tool_panel_section_id ):
tpm = tool_panel_manager.ToolPanelManager( self.app )
tool_panel_section_key, tool_section = \
tool_util.handle_tool_panel_section( self.app.toolbox,
tool_panel_section_id=tool_panel_section_id,
new_tool_panel_section_label=new_tool_panel_section_label )
tpm.handle_tool_panel_section( self.app.toolbox,
tool_panel_section_id=tool_panel_section_id,
new_tool_panel_section_label=new_tool_panel_section_label )
else:
tool_panel_section_key = None
tool_section = None
@@ -11,11 +11,11 @@ from tool_shed.util import data_manager_util
from tool_shed.util import datatype_util
from tool_shed.util import shed_util_common as suc
from tool_shed.util import tool_dependency_util
from tool_shed.util import tool_util
from tool_shed.util import xml_util
from galaxy.model.orm import and_
from tool_shed.galaxy_install.repository_dependencies import repository_dependency_manager
from tool_shed.galaxy_install.tools import tool_panel_manager
log = logging.getLogger( __name__ )
@@ -80,19 +80,19 @@ class InstalledRepositoryManager( object ):
repository.deleted = False
repository.status = self.install_model.ToolShedRepository.installation_status.INSTALLED
if repository.includes_tools_for_display_in_tool_panel:
tpm = tool_panel_manager.ToolPanelManager( self.app )
metadata = repository.metadata
repository_tools_tups = suc.get_repository_tools_tups( self.app, metadata )
# Reload tools into the appropriate tool panel section.
tool_panel_dict = repository.metadata[ 'tool_panel_section' ]
tool_util.add_to_tool_panel( self.app,
repository.name,
repository_clone_url,
repository.installed_changeset_revision,
repository_tools_tups,
repository.owner,
shed_tool_conf,
tool_panel_dict,
new_install=False )
tpm.add_to_tool_panel( repository.name,
repository_clone_url,
repository.installed_changeset_revision,
repository_tools_tups,
repository.owner,
shed_tool_conf,
tool_panel_dict,
new_install=False )
if repository.includes_data_managers:
tp, data_manager_relative_install_dir = repository.get_tool_relative_path( self.app )
# Hack to add repository.name here, which is actually the root of the installed repository
@@ -5,13 +5,14 @@ log = logging.getLogger( __name__ )
from tool_shed.galaxy_install import install_manager
from tool_shed.galaxy_install.repository_dependencies import repository_dependency_manager
from tool_shed.galaxy_install.tools import tool_panel_manager
from tool_shed.util import common_util
from tool_shed.util import container_util
from tool_shed.util import shed_util_common as suc
from tool_shed.util import repository_maintenance_util
from tool_shed.util import tool_dependency_util
from tool_shed.util import tool_util
class RepairRepositoryManager():
@@ -119,10 +120,11 @@ class RepairRepositoryManager():
tool_panel_section_id = section_dict[ 'id' ]
tool_panel_section_name = section_dict[ 'name' ]
if tool_panel_section_id:
tpm = tool_panel_manager.ToolPanelManager( self.app )
tool_panel_section_key, tool_panel_section = \
tool_util.get_or_create_tool_section( self.app.toolbox,
tool_panel_section_id=tool_panel_section_id,
new_tool_panel_section_label=tool_panel_section_name )
tpm.get_or_create_tool_section( self.app.toolbox,
tool_panel_section_id=tool_panel_section_id,
new_tool_panel_section_label=tool_panel_section_name )
else:
tool_dependencies = None
repo_info_dict = repository_maintenance_util.create_repo_info_dict( app=self.app,
@@ -156,15 +158,17 @@ class RepairRepositoryManager():
log.debug( error_message )
repair_dict [ repository.name ] = error_message
elif repository.status not in [ self.app.install_model.ToolShedRepository.installation_status.INSTALLED ]:
shed_tool_conf, tool_path, relative_install_dir = suc.get_tool_panel_config_tool_path_install_dir( self.app, repository )
shed_tool_conf, tool_path, relative_install_dir = \
suc.get_tool_panel_config_tool_path_install_dir( self.app, repository )
# Reset the repository attributes to the New state for installation.
if metadata:
tpm = tool_panel_manager.ToolPanelManager( self.app )
tool_section, tool_panel_section_key = \
tool_util.handle_tool_panel_selection( self.app.toolbox,
metadata,
no_changes_checked=True,
tool_panel_section_id=None,
new_tool_panel_section_label=None )
tpm.handle_tool_panel_selection( self.app.toolbox,
metadata,
no_changes_checked=True,
tool_panel_section_id=None,
new_tool_panel_section_label=None )
else:
# The tools will be loaded outside of any sections in the tool panel.
tool_panel_section_key = None
@@ -10,11 +10,12 @@ import urllib2
from galaxy.util import asbool
from tool_shed.galaxy_install.tools import tool_panel_manager
from tool_shed.util import common_util
from tool_shed.util import container_util
from tool_shed.util import encoding_util
from tool_shed.util import shed_util_common as suc
from tool_shed.util import tool_util
log = logging.getLogger( __name__ )
@@ -216,19 +217,20 @@ class RepositoryDependencyInstallManager( object ):
if can_update_db_record:
# The database record for the tool shed repository currently being processed can be updated.
# Get the repository metadata to see where it was previously located in the tool panel.
tpm = tool_panel_manager.ToolPanelManager( self.app )
if repository_db_record and repository_db_record.metadata:
tool_section, tool_panel_section_key = \
tool_util.handle_tool_panel_selection( toolbox=self.app.toolbox,
metadata=repository_db_record.metadata,
no_changes_checked=no_changes_checked,
tool_panel_section_id=tool_panel_section_id,
new_tool_panel_section_label=new_tool_panel_section_label )
tpm.handle_tool_panel_selection( toolbox=self.app.toolbox,
metadata=repository_db_record.metadata,
no_changes_checked=no_changes_checked,
tool_panel_section_id=tool_panel_section_id,
new_tool_panel_section_label=new_tool_panel_section_label )
else:
# We're installing a new tool shed repository that does not yet have a database record.
tool_panel_section_key, tool_section = \
tool_util.handle_tool_panel_section( self.app.toolbox,
tool_panel_section_id=tool_panel_section_id,
new_tool_panel_section_label=new_tool_panel_section_label )
tpm.handle_tool_panel_section( self.app.toolbox,
tool_panel_section_id=tool_panel_section_id,
new_tool_panel_section_label=new_tool_panel_section_label )
tool_shed_repository = \
suc.create_or_update_tool_shed_repository( app=self.app,
name=name,
@@ -14,6 +14,7 @@ from galaxy.tools import ToolSection
from tool_shed.galaxy_install import install_manager
from tool_shed.galaxy_install.metadata.installed_repository_metadata_manager import InstalledRepositoryMetadataManager
from tool_shed.galaxy_install.tools import tool_panel_manager
from tool_shed.util import basic_util
from tool_shed.util import common_util
@@ -30,23 +31,31 @@ log = logging.getLogger( __name__ )
class ToolMigrationManager( object ):
def __init__( self, app, latest_migration_script_number, tool_shed_install_config, migrated_tools_config, install_dependencies ):
def __init__( self, app, latest_migration_script_number, tool_shed_install_config, migrated_tools_config,
install_dependencies ):
"""
Check tool settings in tool_shed_install_config and install all repositories that are not already installed. The tool
panel configuration file is the received migrated_tools_config, which is the reserved file named migrated_tools_conf.xml.
Check tool settings in tool_shed_install_config and install all repositories
that are not already installed. The tool panel configuration file is the received
migrated_tools_config, which is the reserved file named migrated_tools_conf.xml.
"""
self.app = app
self.toolbox = self.app.toolbox
self.migrated_tools_config = migrated_tools_config
# If install_dependencies is True but tool_dependency_dir is not set, do not attempt to install but print informative error message.
self.tpm = tool_panel_manager.ToolPanelManager( self.app )
# If install_dependencies is True but tool_dependency_dir is not set, do not attempt
# to install but print informative error message.
if install_dependencies and app.config.tool_dependency_dir is None:
message = 'You are attempting to install tool dependencies but do not have a value for "tool_dependency_dir" set in your universe_wsgi.ini '
message += 'file. Set this location value to the path where you want tool dependencies installed and rerun the migration script.'
message = 'You are attempting to install tool dependencies but do not have a value '
message += 'for "tool_dependency_dir" set in your universe_wsgi.ini file. Set this '
message += 'location value to the path where you want tool dependencies installed and '
message += 'rerun the migration script.'
raise Exception( message )
# Get the local non-shed related tool panel configs (there can be more than one, and the default name is tool_conf.xml).
# Get the local non-shed related tool panel configs (there can be more than one, and the
# default name is tool_conf.xml).
self.proprietary_tool_confs = self.non_shed_tool_panel_configs
self.proprietary_tool_panel_elems = self.get_proprietary_tool_panel_elems( latest_migration_script_number )
# Set the location where the repositories will be installed by retrieving the tool_path setting from migrated_tools_config.
# Set the location where the repositories will be installed by retrieving the tool_path
# setting from migrated_tools_config.
tree, error_message = xml_util.parse_xml( migrated_tools_config )
if tree is None:
print error_message
@@ -66,21 +75,24 @@ class ToolMigrationManager( object ):
self.tool_shed = common_util.remove_protocol_and_port_from_tool_shed_url( self.tool_shed_url )
self.repository_owner = common_util.REPOSITORY_OWNER
index, self.shed_config_dict = suc.get_shed_tool_conf_dict( app, self.migrated_tools_config )
# Since tool migration scripts can be executed any number of times, we need to make sure the appropriate tools are defined in
# tool_conf.xml. If no tools associated with the migration stage are defined, no repositories will be installed on disk.
# The default behavior is that the tool shed is down.
# Since tool migration scripts can be executed any number of times, we need to
# make sure the appropriate tools are defined in tool_conf.xml. If no tools
# associated with the migration stage are defined, no repositories will be installed
# on disk. The default behavior is that the tool shed is down.
tool_shed_accessible = False
tool_panel_configs = common_util.get_non_shed_tool_panel_configs( app )
if tool_panel_configs:
# The missing_tool_configs_dict contents are something like:
# {'emboss_antigenic.xml': [('emboss', '5.0.0', 'package', '\nreadme blah blah blah\n')]}
tool_shed_accessible, missing_tool_configs_dict = common_util.check_for_missing_tools( app,
tool_panel_configs,
latest_migration_script_number )
tool_shed_accessible, missing_tool_configs_dict = \
common_util.check_for_missing_tools( app,
tool_panel_configs,
latest_migration_script_number )
else:
# It doesn't matter if the tool shed is accessible since there are no migrated tools defined in the local Galaxy instance, but
# we have to set the value of tool_shed_accessible to True so that the value of migrate_tools.version can be correctly set in
# the database.
# It doesn't matter if the tool shed is accessible since there are no migrated
# tools defined in the local Galaxy instance, but we have to set the value of
# tool_shed_accessible to True so that the value of migrate_tools.version can
# be correctly set in the database.
tool_shed_accessible = True
missing_tool_configs_dict = odict()
if tool_shed_accessible:
@@ -93,15 +105,18 @@ class ToolMigrationManager( object ):
if missing_tool_configs_dict:
for proprietary_tool_conf in self.proprietary_tool_confs:
# Create a backup of the tool configuration in the un-migrated state.
shutil.copy( proprietary_tool_conf, '%s-pre-stage-%04d' % ( proprietary_tool_conf, latest_migration_script_number ) )
shutil.copy( proprietary_tool_conf, '%s-pre-stage-%04d' % ( proprietary_tool_conf,
latest_migration_script_number ) )
for repository_elem in root:
# Make sure we have a valid repository tag.
if self.__is_valid_repository_tag( repository_elem ):
# Get all repository dependencies for the repository defined by the current repository_elem. Repository dependency
# definitions contained in tool shed repositories with migrated tools must never define a relationship to a repository
# dependency that contains a tool. The repository dependency can only contain items that are not loaded into the Galaxy
# tool panel (e.g., tool dependency definitions, custom datatypes, etc). This restriction must be followed down the
# entire dependency hierarchy.
# Get all repository dependencies for the repository defined by the
# current repository_elem. Repository dependency definitions contained
# in tool shed repositories with migrated tools must never define a
# relationship to a repository dependency that contains a tool. The
# repository dependency can only contain items that are not loaded into
# the Galaxy tool panel (e.g., tool dependency definitions, custom datatypes,
# etc). This restriction must be followed down the entire dependency hierarchy.
name = repository_elem.get( 'name' )
changeset_revision = repository_elem.get( 'changeset_revision' )
tool_shed_accessible, repository_dependencies_dict = \
@@ -110,30 +125,38 @@ class ToolMigrationManager( object ):
name,
self.repository_owner,
changeset_revision )
# Make sure all repository dependency records exist (as tool_shed_repository table rows) in the Galaxy database.
created_tool_shed_repositories = self.create_or_update_tool_shed_repository_records( name,
changeset_revision,
repository_dependencies_dict )
# Make sure all repository dependency records exist (as tool_shed_repository
# table rows) in the Galaxy database.
created_tool_shed_repositories = \
self.create_or_update_tool_shed_repository_records( name,
changeset_revision,
repository_dependencies_dict )
# Order the repositories for proper installation. This process is similar to the
# process used when installing tool shed repositories, but does not handle managing
# tool panel sections and other components since repository dependency definitions
# contained in tool shed repositories with migrated tools must never define a relationship
# to a repository dependency that contains a tool.
ordered_tool_shed_repositories = self.order_repositories_for_installation( created_tool_shed_repositories,
repository_dependencies_dict )
ordered_tool_shed_repositories = \
self.order_repositories_for_installation( created_tool_shed_repositories,
repository_dependencies_dict )
for tool_shed_repository in ordered_tool_shed_repositories:
is_repository_dependency = self.__is_repository_dependency( name, changeset_revision, tool_shed_repository )
is_repository_dependency = self.__is_repository_dependency( name,
changeset_revision,
tool_shed_repository )
self.install_repository( repository_elem,
tool_shed_repository,
install_dependencies,
is_repository_dependency=is_repository_dependency )
else:
message = "\nNo tools associated with migration stage %s are defined in your " % str( latest_migration_script_number )
message += "file%s named %s,\nso no repositories will be installed on disk.\n" % ( plural, file_names )
message = "\nNo tools associated with migration stage %s are defined in your " % \
str( latest_migration_script_number )
message += "file%s named %s,\nso no repositories will be installed on disk.\n" % \
( plural, file_names )
print message
else:
message = "\nThe main Galaxy tool shed is not currently available, so skipped migration stage %s.\n" % str( latest_migration_script_number )
message = "\nThe main Galaxy tool shed is not currently available, so skipped migration stage %s.\n" % \
str( latest_migration_script_number )
message += "Try again later.\n"
print message
@@ -354,16 +377,21 @@ class ToolMigrationManager( object ):
repo_install_dir = relative_install_dir
if not is_repository_dependency:
for tool_elem in repository_elem:
# The tool_elem looks something like this: <tool id="EMBOSS: antigenic1" version="5.0.0" file="emboss_antigenic.xml" />
# The tool_elem looks something like this:
# <tool id="EMBOSS: antigenic1" version="5.0.0" file="emboss_antigenic.xml" />
tool_config = tool_elem.get( 'file' )
guid = self.get_guid( repository_clone_url, relative_install_dir, tool_config )
# See if tool_config is defined inside of a section in self.proprietary_tool_panel_elems.
is_displayed, tool_sections = self.get_containing_tool_sections( tool_config )
if is_displayed:
tool_panel_dict_for_tool_config = \
tool_util.generate_tool_panel_dict_for_tool_config( guid, tool_config, tool_sections=tool_sections )
self.tpm.generate_tool_panel_dict_for_tool_config( guid,
tool_config,
tool_sections=tool_sections )
# The tool-panel_dict has the following structure.
# {<Tool guid> : [{ tool_config : <tool_config_file>, id: <ToolSection id>, version : <ToolSection version>,
# {<Tool guid> : [{ tool_config : <tool_config_file>,
# id: <ToolSection id>,
# version : <ToolSection version>,
# name : <TooSection name>}]}
for k, v in tool_panel_dict_for_tool_config.items():
tool_panel_dict_for_display[ k ] = v
@@ -433,15 +461,14 @@ class ToolMigrationManager( object ):
tool_path=self.tool_path,
sample_files_copied=sample_files_copied )
if not is_repository_dependency:
tool_util.add_to_tool_panel( self.app,
tool_shed_repository.name,
repository_clone_url,
tool_shed_repository.installed_changeset_revision,
repository_tools_tups,
self.repository_owner,
self.migrated_tools_config,
tool_panel_dict=tool_panel_dict_for_display,
new_install=True )
self.tpm.add_to_tool_panel( tool_shed_repository.name,
repository_clone_url,
tool_shed_repository.installed_changeset_revision,
repository_tools_tups,
self.repository_owner,
self.migrated_tools_config,
tool_panel_dict=tool_panel_dict_for_display,
new_install=True )
if install_dependencies and tool_dependencies and has_tool_dependencies:
# Install tool dependencies.
suc.update_tool_shed_repository_status( self.app,
@@ -0,0 +1,465 @@
import logging
import os
import galaxy.tools
from galaxy.tools.search import ToolBoxSearch
from xml.etree import ElementTree as XmlET
from tool_shed.util import basic_util
from tool_shed.util import common_util
from tool_shed.util import shed_util_common as suc
from tool_shed.util import xml_util
log = logging.getLogger( __name__ )
class ToolPanelManager( object ):
def __init__( self, app ):
self.app = app
def add_to_shed_tool_config( self, shed_tool_conf_dict, elem_list ):
# A tool shed repository is being installed so change the shed_tool_conf file. Parse the
# config file to generate the entire list of config_elems instead of using the in-memory list
# since it will be a subset of the entire list if one or more repositories have been deactivated.
shed_tool_conf = shed_tool_conf_dict[ 'config_filename' ]
tool_path = shed_tool_conf_dict[ 'tool_path' ]
config_elems = []
tree, error_message = xml_util.parse_xml( shed_tool_conf )
if tree:
root = tree.getroot()
for elem in root:
config_elems.append( elem )
# Add the elements to the in-memory list of config_elems.
for elem_entry in elem_list:
config_elems.append( elem_entry )
# Persist the altered shed_tool_config file.
suc.config_elems_to_xml_file( self.app, config_elems, shed_tool_conf, tool_path )
def add_to_tool_panel( self, repository_name, repository_clone_url, changeset_revision, repository_tools_tups, owner,
shed_tool_conf, tool_panel_dict, new_install=True ):
"""A tool shed repository is being installed or updated so handle tool panel alterations accordingly."""
# We need to change the in-memory version and the file system version of the shed_tool_conf file.
index, shed_tool_conf_dict = suc.get_shed_tool_conf_dict( self.app, shed_tool_conf )
tool_path = shed_tool_conf_dict[ 'tool_path' ]
# Generate the list of ElementTree Element objects for each section or tool.
elem_list = self.generate_tool_panel_elem_list( repository_name,
repository_clone_url,
changeset_revision,
tool_panel_dict,
repository_tools_tups,
owner=owner )
if new_install:
# Add the new elements to the shed_tool_conf file on disk.
self.add_to_shed_tool_config( 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':
self.app.toolbox.load_section_tag_set( config_elem, tool_path, load_panel_dict=True )
elif config_elem.tag == 'workflow':
self.app.toolbox.load_workflow_tag_set( config_elem,
self.app.toolbox.tool_panel,
self.app.toolbox.integrated_tool_panel,
load_panel_dict=True )
elif config_elem.tag == 'tool':
guid = config_elem.get( 'guid' )
self.app.toolbox.load_tool_tag_set( config_elem,
self.app.toolbox.tool_panel,
self.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
self.app.toolbox.shed_tool_confs[ index ] = shed_tool_conf_dict
if self.app.config.update_integrated_tool_panel:
# Write the current in-memory version of the integrated_tool_panel.xml file to disk.
self.app.toolbox.write_integrated_tool_panel_config_file()
self.app.toolbox_search = ToolBoxSearch( self.app.toolbox )
def generate_tool_panel_dict_for_new_install( self, tool_dicts, tool_section=None ):
"""
When installing a repository that contains tools, all tools must currently be defined
within the same tool section in the tool panel or outside of any sections.
"""
tool_panel_dict = {}
if tool_section:
section_id = tool_section.id
section_name = tool_section.name
section_version = tool_section.version or ''
else:
section_id = ''
section_name = ''
section_version = ''
for tool_dict in tool_dicts:
if tool_dict.get( 'add_to_tool_panel', True ):
guid = tool_dict[ 'guid' ]
tool_config = tool_dict[ 'tool_config' ]
tool_section_dict = dict( tool_config=tool_config, id=section_id, name=section_name, version=section_version )
if guid in tool_panel_dict:
tool_panel_dict[ guid ].append( tool_section_dict )
else:
tool_panel_dict[ guid ] = [ tool_section_dict ]
return tool_panel_dict
def generate_tool_panel_dict_for_tool_config( self, guid, tool_config, tool_sections=None ):
"""
Create a dictionary of the following type for a single tool config file name.
The intent is to call this method for every tool config in a repository and
append each of these as entries to a tool panel dictionary for the repository.
This enables each tool to be loaded into a different section in the tool panel.
{<Tool guid> :
[{ tool_config : <tool_config_file>,
id: <ToolSection id>,
version : <ToolSection version>,
name : <TooSection name>}]}
"""
tool_panel_dict = {}
file_name = basic_util.strip_path( tool_config )
tool_section_dicts = self. generate_tool_section_dicts( tool_config=file_name,
tool_sections=tool_sections )
tool_panel_dict[ guid ] = tool_section_dicts
return tool_panel_dict
def generate_tool_panel_elem_list( self, repository_name, repository_clone_url, changeset_revision,
tool_panel_dict, repository_tools_tups, owner='' ):
"""Generate a list of ElementTree Element objects for each section or tool."""
elem_list = []
tool_elem = None
cleaned_repository_clone_url = common_util.remove_protocol_and_user_from_clone_url( repository_clone_url )
if not owner:
owner = suc.get_repository_owner( cleaned_repository_clone_url )
tool_shed = cleaned_repository_clone_url.split( '/repos/' )[ 0 ].rstrip( '/' )
for guid, tool_section_dicts in tool_panel_dict.items():
for tool_section_dict in tool_section_dicts:
tool_section = None
inside_section = False
section_in_elem_list = False
if tool_section_dict[ 'id' ]:
inside_section = True
# Create a new section element only if we haven't already created it.
for index, elem in enumerate( elem_list ):
if elem.tag == 'section':
section_id = elem.get( 'id', None )
if section_id == tool_section_dict[ 'id' ]:
section_in_elem_list = True
tool_section = elem
break
if tool_section is None:
tool_section = self.generate_tool_section_element_from_dict( tool_section_dict )
# Find the tuple containing the current guid from the list of repository_tools_tups.
for repository_tool_tup in repository_tools_tups:
tool_file_path, tup_guid, tool = repository_tool_tup
if tup_guid == guid:
break
if inside_section:
tool_elem = suc.generate_tool_elem( tool_shed,
repository_name,
changeset_revision,
owner,
tool_file_path,
tool,
tool_section )
else:
tool_elem = suc.generate_tool_elem( tool_shed,
repository_name,
changeset_revision,
owner,
tool_file_path,
tool,
None )
if inside_section:
if section_in_elem_list:
elem_list[ index ] = tool_section
else:
elem_list.append( tool_section )
else:
elem_list.append( tool_elem )
return elem_list
def generate_tool_section_dicts( self, tool_config=None, tool_sections=None ):
tool_section_dicts = []
if tool_config is None:
tool_config = ''
if tool_sections:
for tool_section in tool_sections:
# The value of tool_section will be None if the tool is displayed outside
# of any sections in the tool panel.
if tool_section:
section_id = tool_section.id or ''
section_version = tool_section.version or ''
section_name = tool_section.name or ''
else:
section_id = ''
section_version = ''
section_name = ''
tool_section_dicts.append( dict( tool_config=tool_config,
id=section_id,
version=section_version,
name=section_name ) )
else:
tool_section_dicts.append( dict( tool_config=tool_config, id='', version='', name='' ) )
return tool_section_dicts
def generate_tool_section_element_from_dict( self, tool_section_dict ):
# The value of tool_section_dict looks like the following.
# { id: <ToolSection id>, version : <ToolSection version>, name : <TooSection name>}
if tool_section_dict[ 'id' ]:
# Create a new tool section.
tool_section = XmlET.Element( 'section' )
tool_section.attrib[ 'id' ] = tool_section_dict[ 'id' ]
tool_section.attrib[ 'name' ] = tool_section_dict[ 'name' ]
tool_section.attrib[ 'version' ] = tool_section_dict[ 'version' ]
else:
tool_section = None
return tool_section
def get_or_create_tool_section( self, toolbox, tool_panel_section_id, new_tool_panel_section_label=None ):
tool_panel_section_key = str( tool_panel_section_id )
if tool_panel_section_key in toolbox.tool_panel:
# Appending a tool to an existing section in toolbox.tool_panel
tool_section = toolbox.tool_panel[ tool_panel_section_key ]
log.debug( "Appending to tool panel section: %s" % str( tool_section.name ) )
else:
# Appending a new section to toolbox.tool_panel
if new_tool_panel_section_label is None:
# This might add an ugly section label to the tool panel, but, oh well...
new_tool_panel_section_label = tool_panel_section_id
elem = XmlET.Element( 'section' )
elem.attrib[ 'name' ] = new_tool_panel_section_label
elem.attrib[ 'id' ] = tool_panel_section_id
elem.attrib[ 'version' ] = ''
tool_section = galaxy.tools.ToolSection( elem )
toolbox.tool_panel[ tool_panel_section_key ] = tool_section
log.debug( "Loading new tool panel section: %s" % str( tool_section.name ) )
return tool_panel_section_key, tool_section
def handle_tool_panel_section( self, toolbox, tool_panel_section_id=None, new_tool_panel_section_label=None ):
"""Return a ToolSection object retrieved from the current in-memory tool_panel."""
# If tool_panel_section_id is received, the section exists in the tool panel. In this
# case, the value of the received tool_panel_section_id must be the id retrieved from a
# tool panel config (e.g., tool_conf.xml, which may have getext). If new_tool_panel_section_label
# is received, a new section will be added to the tool panel.
if new_tool_panel_section_label:
section_id = str( new_tool_panel_section_label.lower().replace( ' ', '_' ) )
tool_panel_section_key, tool_section = \
self.get_or_create_tool_section( toolbox,
tool_panel_section_id=section_id,
new_tool_panel_section_label=new_tool_panel_section_label )
elif tool_panel_section_id:
tool_panel_section_key = str( tool_panel_section_id )
tool_section = toolbox.tool_panel[ tool_panel_section_key ]
else:
return None, None
return tool_panel_section_key, tool_section
def handle_tool_panel_selection( self, toolbox, metadata, no_changes_checked, tool_panel_section_id,
new_tool_panel_section_label ):
"""
Handle the selected tool panel location for loading tools included in tool shed
repositories when installing or reinstalling them.
"""
# Get the location in the tool panel in which each tool was originally loaded.
tool_section = None
tool_panel_section_key = None
if 'tools' in metadata:
# This forces everything to be loaded into the same section (or no section)
# in the tool panel.
if no_changes_checked:
# Make sure the no_changes check box overrides the new_tool_panel_section_label
# if the user checked the check box and entered something into the field.
new_tool_panel_section_label = None
if 'tool_panel_section' in metadata:
tool_panel_dict = metadata[ 'tool_panel_section' ]
if not tool_panel_dict:
tool_panel_dict = self.generate_tool_panel_dict_for_new_install( metadata[ 'tools' ] )
else:
tool_panel_dict = self.generate_tool_panel_dict_for_new_install( metadata[ 'tools' ] )
if tool_panel_dict:
# The tool_panel_dict is empty when tools exist but are not installed into a tool panel section.
tool_section_dicts = tool_panel_dict[ tool_panel_dict.keys()[ 0 ] ]
tool_section_dict = tool_section_dicts[ 0 ]
original_section_id = tool_section_dict[ 'id' ]
original_section_name = tool_section_dict[ 'name' ]
if original_section_id:
tool_panel_section_key, tool_section = \
self.get_or_create_tool_section( toolbox,
tool_panel_section_id=original_section_id,
new_tool_panel_section_label=new_tool_panel_section_label )
else:
# The user elected to change the tool panel section to contain the tools.
tool_panel_section_key, tool_section = \
self.handle_tool_panel_section( toolbox,
tool_panel_section_id=tool_panel_section_id,
new_tool_panel_section_label=new_tool_panel_section_label )
return tool_section, tool_panel_section_key
def remove_from_shed_tool_config( self, shed_tool_conf_dict, guids_to_remove ):
# A tool shed repository is being uninstalled so change the shed_tool_conf file.
# Parse the config file to generate the entire list of config_elems instead of
# using the in-memory list since it will be a subset of the entire list if one
# or more repositories have been deactivated.
shed_tool_conf = shed_tool_conf_dict[ 'config_filename' ]
tool_path = shed_tool_conf_dict[ 'tool_path' ]
config_elems = []
tree, error_message = xml_util.parse_xml( shed_tool_conf )
if tree:
root = tree.getroot()
for elem in root:
config_elems.append( elem )
config_elems_to_remove = []
for config_elem in config_elems:
if config_elem.tag == 'section':
tool_elems_to_remove = []
for tool_elem in config_elem:
if tool_elem.get( 'guid' ) in guids_to_remove:
tool_elems_to_remove.append( tool_elem )
for tool_elem in tool_elems_to_remove:
# Remove all of the appropriate tool sub-elements from the section element.
config_elem.remove( tool_elem )
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 )
elif config_elem.tag == 'tool':
if config_elem.get( 'guid' ) in guids_to_remove:
config_elems_to_remove.append( config_elem )
for config_elem in config_elems_to_remove:
config_elems.remove( config_elem )
# Persist the altered in-memory version of the tool config.
suc.config_elems_to_xml_file( self.app, config_elems, shed_tool_conf, tool_path )
def remove_from_tool_panel( self, repository, shed_tool_conf, uninstall ):
"""
A tool shed repository is being deactivated or uninstalled, so handle tool panel
alterations accordingly.
"""
# Determine where the tools are currently defined in the tool panel and store this
# information so the tools can be displayed in the same way when the repository is
# activated or reinstalled.
tool_panel_dict = suc.generate_tool_panel_dict_from_shed_tool_conf_entries( self.app, repository )
repository.metadata[ 'tool_panel_section' ] = tool_panel_dict
self.app.install_model.context.add( repository )
self.app.install_model.context.flush()
# Create a list of guids for all tools that will be removed from the in-memory tool panel
# and config file on disk.
guids_to_remove = [ k for k in tool_panel_dict.keys() ]
# Remove the tools from the toolbox's tools_by_id dictionary.
for guid_to_remove in guids_to_remove:
if guid_to_remove in self.app.toolbox.tools_by_id:
del self.app.toolbox.tools_by_id[ guid_to_remove ]
index, shed_tool_conf_dict = suc.get_shed_tool_conf_dict( self.app, shed_tool_conf )
if uninstall:
# Remove from the shed_tool_conf file on disk.
self.remove_from_shed_tool_config( shed_tool_conf_dict, guids_to_remove )
config_elems = shed_tool_conf_dict[ 'config_elems' ]
config_elems_to_remove = []
for config_elem in config_elems:
if config_elem.tag == 'section':
# Get the section key for the in-memory tool panel.
section_key = str( config_elem.get( "id" ) )
# Generate the list of tool elements to remove.
tool_elems_to_remove = []
for tool_elem in config_elem:
if tool_elem.get( 'guid' ) in guids_to_remove:
tool_elems_to_remove.append( tool_elem )
for tool_elem in tool_elems_to_remove:
if tool_elem in config_elem:
# Remove the tool sub-element from the section element.
config_elem.remove( tool_elem )
# Remove the tool from the section in the in-memory tool panel.
if section_key in self.app.toolbox.tool_panel:
tool_section = self.app.toolbox.tool_panel[ section_key ]
guid = tool_elem.get( 'guid' )
tool_key = 'tool_%s' % str( guid )
# Get the list of versions of this tool that are currently available in the toolbox.
available_tool_versions = self.app.toolbox.get_loaded_tools_by_lineage( guid )
if tool_key in tool_section.elems:
if available_tool_versions:
available_tool_versions.reverse()
replacement_tool_key = None
replacement_tool_version = None
# Since we are going to remove the tool from the section, replace it with the
# newest loaded version of the tool.
for available_tool_version in available_tool_versions:
available_tool_section_id, available_tool_section_name = available_tool_version.get_panel_section()
if available_tool_version.id in tool_section.elems.keys() or section_key == available_tool_section_id:
replacement_tool_key = 'tool_%s' % str( available_tool_version.id )
replacement_tool_version = available_tool_version
break
if replacement_tool_key and replacement_tool_version:
# Get the index of the tool_key in the tool_section.
for tool_section_elems_index, key in enumerate( tool_section.elems.keys() ):
if key == tool_key:
break
# Remove the tool from the tool section.
del tool_section.elems[ tool_key ]
# Add the replacement tool at the same location in the tool section.
tool_section.elems.insert( tool_section_elems_index,
replacement_tool_key,
replacement_tool_version )
else:
del tool_section.elems[ tool_key ]
else:
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 self.app.toolbox.integrated_tool_panel:
tool_section = self.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 )
elif config_elem.tag == 'tool':
guid = config_elem.get( 'guid' )
if guid in guids_to_remove:
tool_key = 'tool_%s' % str( config_elem.get( 'guid' ) )
# Get the list of versions of this tool that are currently available in the toolbox.
available_tool_versions = self.app.toolbox.get_loaded_tools_by_lineage( guid )
if tool_key in self.app.toolbox.tool_panel:
if available_tool_versions:
available_tool_versions.reverse()
replacement_tool_key = None
replacement_tool_version = None
# Since we are going to remove the tool from the section, replace it with
# the newest loaded version of the tool.
for available_tool_version in available_tool_versions:
available_tool_section_id, available_tool_section_name = available_tool_version.get_panel_section()
if available_tool_version.id in self.app.toolbox.tool_panel.keys() or not available_tool_section_id:
replacement_tool_key = 'tool_%s' % str( available_tool_version.id )
replacement_tool_version = available_tool_version
break
if replacement_tool_key and replacement_tool_version:
# Get the index of the tool_key in the tool_section.
for tool_panel_index, key in enumerate( self.app.toolbox.tool_panel.keys() ):
if key == tool_key:
break
# Remove the tool from the tool panel.
del self.app.toolbox.tool_panel[ tool_key ]
# Add the replacement tool at the same location in the tool panel.
self.app.toolbox.tool_panel.insert( tool_panel_index,
replacement_tool_key,
replacement_tool_version )
else:
del self.app.toolbox.tool_panel[ tool_key ]
else:
del self.app.toolbox.tool_panel[ tool_key ]
if uninstall:
if tool_key in self.app.toolbox.integrated_tool_panel:
del self.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.
config_elems.remove( config_elem )
# Update the config_elems of the in-memory shed_tool_conf_dict.
shed_tool_conf_dict[ 'config_elems' ] = config_elems
self.app.toolbox.shed_tool_confs[ index ] = shed_tool_conf_dict
self.app.toolbox_search = ToolBoxSearch( self.app.toolbox )
if uninstall and self.app.config.update_integrated_tool_panel:
# Write the current in-memory version of the integrated_tool_panel.xml file to disk.
self.app.toolbox.write_integrated_tool_panel_config_file()
-440
View File
@@ -19,69 +19,6 @@ from xml.etree import ElementTree as XmlET
log = logging.getLogger( __name__ )
def add_to_shed_tool_config( app, shed_tool_conf_dict, elem_list ):
# A tool shed repository is being installed so change the shed_tool_conf file. Parse the
# config file to generate the entire list of config_elems instead of using the in-memory list
# since it will be a subset of the entire list if one or more repositories have been deactivated.
shed_tool_conf = shed_tool_conf_dict[ 'config_filename' ]
tool_path = shed_tool_conf_dict[ 'tool_path' ]
config_elems = []
tree, error_message = xml_util.parse_xml( shed_tool_conf )
if tree:
root = tree.getroot()
for elem in root:
config_elems.append( elem )
# Add the elements to the in-memory list of config_elems.
for elem_entry in elem_list:
config_elems.append( elem_entry )
# Persist the altered shed_tool_config file.
suc.config_elems_to_xml_file( app, config_elems, shed_tool_conf, tool_path )
def add_to_tool_panel( app, repository_name, repository_clone_url, changeset_revision, repository_tools_tups, owner,
shed_tool_conf, tool_panel_dict, new_install=True ):
"""A tool shed repository is being installed or updated so handle tool panel alterations accordingly."""
# We need to change the in-memory version and the file system version of the shed_tool_conf file.
index, shed_tool_conf_dict = suc.get_shed_tool_conf_dict( app, shed_tool_conf )
tool_path = shed_tool_conf_dict[ 'tool_path' ]
# Generate the list of ElementTree Element objects for each section or tool.
elem_list = generate_tool_panel_elem_list( repository_name,
repository_clone_url,
changeset_revision,
tool_panel_dict,
repository_tools_tups,
owner=owner )
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, 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,
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
if app.config.update_integrated_tool_panel:
# Write the current in-memory version of the integrated_tool_panel.xml file to disk.
app.toolbox.write_integrated_tool_panel_config_file()
app.toolbox_search = ToolBoxSearch( app.toolbox )
def build_shed_tool_conf_select_field( app ):
"""Build a SelectField whose options are the keys in app.toolbox.shed_tool_confs."""
options = []
@@ -192,142 +129,6 @@ def generate_message_for_invalid_tools( app, invalid_file_tups, repository, meta
message += "%s%s%s - %s%s" % ( bold_start, tool_file, bold_end, correction_msg, new_line )
return message
def generate_tool_panel_dict_for_new_install( tool_dicts, tool_section=None ):
"""
When installing a repository that contains tools, all tools must currently be defined
within the same tool section in the tool panel or outside of any sections.
"""
tool_panel_dict = {}
if tool_section:
section_id = tool_section.id
section_name = tool_section.name
section_version = tool_section.version or ''
else:
section_id = ''
section_name = ''
section_version = ''
for tool_dict in tool_dicts:
if tool_dict.get( 'add_to_tool_panel', True ):
guid = tool_dict[ 'guid' ]
tool_config = tool_dict[ 'tool_config' ]
tool_section_dict = dict( tool_config=tool_config, id=section_id, name=section_name, version=section_version )
if guid in tool_panel_dict:
tool_panel_dict[ guid ].append( tool_section_dict )
else:
tool_panel_dict[ guid ] = [ tool_section_dict ]
return tool_panel_dict
def generate_tool_panel_dict_for_tool_config( guid, tool_config, tool_sections=None ):
"""
Create a dictionary of the following type for a single tool config file name.
The intent is to call this method for every tool config in a repository and
append each of these as entries to a tool panel dictionary for the repository.
This allows for each tool to be loaded into a different section in the tool panel.
{<Tool guid> :
[{ tool_config : <tool_config_file>,
id: <ToolSection id>,
version : <ToolSection version>,
name : <TooSection name>}]}
"""
tool_panel_dict = {}
file_name = basic_util.strip_path( tool_config )
tool_section_dicts = generate_tool_section_dicts( tool_config=file_name, tool_sections=tool_sections )
tool_panel_dict[ guid ] = tool_section_dicts
return tool_panel_dict
def generate_tool_panel_elem_list( repository_name, repository_clone_url, changeset_revision, tool_panel_dict,
repository_tools_tups, owner='' ):
"""Generate a list of ElementTree Element objects for each section or tool."""
elem_list = []
tool_elem = None
cleaned_repository_clone_url = common_util.remove_protocol_and_user_from_clone_url( repository_clone_url )
if not owner:
owner = suc.get_repository_owner( cleaned_repository_clone_url )
tool_shed = cleaned_repository_clone_url.split( '/repos/' )[ 0 ].rstrip( '/' )
for guid, tool_section_dicts in tool_panel_dict.items():
for tool_section_dict in tool_section_dicts:
tool_section = None
inside_section = False
section_in_elem_list = False
if tool_section_dict[ 'id' ]:
inside_section = True
# Create a new section element only if we haven't already created it.
for index, elem in enumerate( elem_list ):
if elem.tag == 'section':
section_id = elem.get( 'id', None )
if section_id == tool_section_dict[ 'id' ]:
section_in_elem_list = True
tool_section = elem
break
if tool_section is None:
tool_section = generate_tool_section_element_from_dict( tool_section_dict )
# Find the tuple containing the current guid from the list of repository_tools_tups.
for repository_tool_tup in repository_tools_tups:
tool_file_path, tup_guid, tool = repository_tool_tup
if tup_guid == guid:
break
if inside_section:
tool_elem = suc.generate_tool_elem( tool_shed,
repository_name,
changeset_revision,
owner,
tool_file_path,
tool,
tool_section )
else:
tool_elem = suc.generate_tool_elem( tool_shed,
repository_name,
changeset_revision,
owner,
tool_file_path,
tool,
None )
if inside_section:
if section_in_elem_list:
elem_list[ index ] = tool_section
else:
elem_list.append( tool_section )
else:
elem_list.append( tool_elem )
return elem_list
def generate_tool_section_dicts( tool_config=None, tool_sections=None ):
tool_section_dicts = []
if tool_config is None:
tool_config = ''
if tool_sections:
for tool_section in tool_sections:
# The value of tool_section will be None if the tool is displayed outside
# of any sections in the tool panel.
if tool_section:
section_id = tool_section.id or ''
section_version = tool_section.version or ''
section_name = tool_section.name or ''
else:
section_id = ''
section_version = ''
section_name = ''
tool_section_dicts.append( dict( tool_config=tool_config,
id=section_id,
version=section_version,
name=section_name ) )
else:
tool_section_dicts.append( dict( tool_config=tool_config, id='', version='', name='' ) )
return tool_section_dicts
def generate_tool_section_element_from_dict( tool_section_dict ):
# The value of tool_section_dict looks like the following.
# { id: <ToolSection id>, version : <ToolSection version>, name : <TooSection name>}
if tool_section_dict[ 'id' ]:
# Create a new tool section.
tool_section = XmlET.Element( 'section' )
tool_section.attrib[ 'id' ] = tool_section_dict[ 'id' ]
tool_section.attrib[ 'name' ] = tool_section_dict[ 'name' ]
tool_section.attrib[ 'version' ] = tool_section_dict[ 'version' ]
else:
tool_section = None
return tool_section
def get_headers( fname, sep, count=60, is_multi_byte=False ):
"""Returns a list with the first 'count' lines split by 'sep'."""
headers = []
@@ -341,26 +142,6 @@ def get_headers( fname, sep, count=60, is_multi_byte=False ):
break
return headers
def get_or_create_tool_section( toolbox, tool_panel_section_id, new_tool_panel_section_label=None ):
tool_panel_section_key = str( tool_panel_section_id )
if tool_panel_section_key in toolbox.tool_panel:
# Appending a tool to an existing section in toolbox.tool_panel
tool_section = toolbox.tool_panel[ tool_panel_section_key ]
log.debug( "Appending to tool panel section: %s" % str( tool_section.name ) )
else:
# Appending a new section to toolbox.tool_panel
if new_tool_panel_section_label is None:
# This might add an ugly section label to the tool panel, but, oh well...
new_tool_panel_section_label = tool_panel_section_id
elem = XmlET.Element( 'section' )
elem.attrib[ 'name' ] = new_tool_panel_section_label
elem.attrib[ 'id' ] = tool_panel_section_id
elem.attrib[ 'version' ] = ''
tool_section = galaxy.tools.ToolSection( elem )
toolbox.tool_panel[ tool_panel_section_key ] = tool_section
log.debug( "Loading new tool panel section: %s" % str( tool_section.name ) )
return tool_panel_section_key, tool_section
def get_tool_path_install_dir( partial_install_dir, shed_tool_conf_dict, tool_dict, config_elems ):
for elem in config_elems:
if elem.tag == 'tool':
@@ -514,63 +295,6 @@ def handle_sample_tool_data_table_conf_file( app, filename, persist=False ):
error = True
return error, message
def handle_tool_panel_selection( toolbox, metadata, no_changes_checked, tool_panel_section_id, new_tool_panel_section_label ):
"""
Handle the selected tool panel location for loading tools included in tool shed repositories when installing
or reinstalling them.
"""
# Get the location in the tool panel in which each tool was originally loaded.
tool_section = None
tool_panel_section_key = None
if 'tools' in metadata:
# This forces everything to be loaded into the same section (or no section) in the tool panel.
if no_changes_checked:
# Make sure the no_changes check box overrides the new_tool_panel_section_label if the user checked the check
# box and entered something into the field.
new_tool_panel_section_label = None
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:
tool_panel_dict = generate_tool_panel_dict_for_new_install( metadata[ 'tools' ] )
if tool_panel_dict:
# The tool_panel_dict is empty when tools exist but are not installed into a tool panel section.
tool_section_dicts = tool_panel_dict[ tool_panel_dict.keys()[ 0 ] ]
tool_section_dict = tool_section_dicts[ 0 ]
original_section_id = tool_section_dict[ 'id' ]
original_section_name = tool_section_dict[ 'name' ]
if original_section_id:
tool_panel_section_key, tool_section = \
get_or_create_tool_section( toolbox,
tool_panel_section_id=original_section_id,
new_tool_panel_section_label=new_tool_panel_section_label )
else:
# The user elected to change the tool panel section to contain the tools.
tool_panel_section_key, tool_section = handle_tool_panel_section( toolbox,
tool_panel_section_id=tool_panel_section_id,
new_tool_panel_section_label=new_tool_panel_section_label )
return tool_section, tool_panel_section_key
def handle_tool_panel_section( toolbox, tool_panel_section_id=None, new_tool_panel_section_label=None ):
"""Return a ToolSection object retrieved from the current in-memory tool_panel."""
# If tool_panel_section_id is received, the section exists in the tool panel. In this
# case, the value of the received tool_panel_section_id must be the id retrieved from a
# tool panel config (e.g., tool_conf.xml, which may have getext). If new_tool_panel_section_label
# is received, a new section will be added to the tool panel.
if new_tool_panel_section_label:
section_id = str( new_tool_panel_section_label.lower().replace( ' ', '_' ) )
tool_panel_section_key, tool_section = \
get_or_create_tool_section( toolbox,
tool_panel_section_id=section_id,
new_tool_panel_section_label=new_tool_panel_section_label )
elif tool_panel_section_id:
tool_panel_section_key = str( tool_panel_section_id )
tool_section = toolbox.tool_panel[ tool_panel_section_key ]
else:
return None, None
return tool_panel_section_key, tool_section
def handle_tool_versions( app, tool_version_dicts, tool_shed_repository ):
"""
Using the list of tool_version_dicts retrieved from the tool shed (one per changeset
@@ -741,170 +465,6 @@ def reload_upload_tools( app ):
if isinstance( tool.tool_action, UploadToolAction ):
app.toolbox.reload_tool_by_id( tool_id )
def remove_from_shed_tool_config( app, shed_tool_conf_dict, guids_to_remove ):
# A tool shed repository is being uninstalled so change the shed_tool_conf file.
# Parse the config file to generate the entire list of config_elems instead of
# using the in-memory list since it will be a subset of the entire list if one
# or more repositories have been deactivated.
shed_tool_conf = shed_tool_conf_dict[ 'config_filename' ]
tool_path = shed_tool_conf_dict[ 'tool_path' ]
config_elems = []
tree, error_message = xml_util.parse_xml( shed_tool_conf )
if tree:
root = tree.getroot()
for elem in root:
config_elems.append( elem )
config_elems_to_remove = []
for config_elem in config_elems:
if config_elem.tag == 'section':
tool_elems_to_remove = []
for tool_elem in config_elem:
if tool_elem.get( 'guid' ) in guids_to_remove:
tool_elems_to_remove.append( tool_elem )
for tool_elem in tool_elems_to_remove:
# Remove all of the appropriate tool sub-elements from the section element.
config_elem.remove( tool_elem )
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 )
elif config_elem.tag == 'tool':
if config_elem.get( 'guid' ) in guids_to_remove:
config_elems_to_remove.append( config_elem )
for config_elem in config_elems_to_remove:
config_elems.remove( config_elem )
# Persist the altered in-memory version of the tool config.
suc.config_elems_to_xml_file( app, config_elems, shed_tool_conf, tool_path )
def remove_from_tool_panel( app, repository, shed_tool_conf, uninstall ):
"""
A tool shed repository is being deactivated or uninstalled, so handle tool panel
alterations accordingly.
"""
# Determine where the tools are currently defined in the tool panel and store this
# information so the tools can be displayed in the same way when the repository is
# activated or reinstalled.
tool_panel_dict = suc.generate_tool_panel_dict_from_shed_tool_conf_entries( app, repository )
repository.metadata[ 'tool_panel_section' ] = tool_panel_dict
app.install_model.context.add( repository )
app.install_model.context.flush()
# Create a list of guids for all tools that will be removed from the in-memory tool panel
# and config file on disk.
guids_to_remove = [ k for k in tool_panel_dict.keys() ]
# Remove the tools from the toolbox's tools_by_id dictionary.
for guid_to_remove in guids_to_remove:
if guid_to_remove in app.toolbox.tools_by_id:
del app.toolbox.tools_by_id[ guid_to_remove ]
index, shed_tool_conf_dict = suc.get_shed_tool_conf_dict( app, shed_tool_conf )
if uninstall:
# Remove from the shed_tool_conf file on disk.
remove_from_shed_tool_config( app, shed_tool_conf_dict, guids_to_remove )
config_elems = shed_tool_conf_dict[ 'config_elems' ]
config_elems_to_remove = []
for config_elem in config_elems:
if config_elem.tag == 'section':
# Get the section key for the in-memory tool panel.
section_key = str( config_elem.get( "id" ) )
# Generate the list of tool elements to remove.
tool_elems_to_remove = []
for tool_elem in config_elem:
if tool_elem.get( 'guid' ) in guids_to_remove:
tool_elems_to_remove.append( tool_elem )
for tool_elem in tool_elems_to_remove:
if tool_elem in config_elem:
# Remove the tool sub-element from the section element.
config_elem.remove( tool_elem )
# Remove the tool from the section in the in-memory tool panel.
if section_key in app.toolbox.tool_panel:
tool_section = app.toolbox.tool_panel[ section_key ]
guid = tool_elem.get( 'guid' )
tool_key = 'tool_%s' % str( guid )
# Get the list of versions of this tool that are currently available in the toolbox.
available_tool_versions = app.toolbox.get_loaded_tools_by_lineage( guid )
if tool_key in tool_section.elems:
if available_tool_versions:
available_tool_versions.reverse()
replacement_tool_key = None
replacement_tool_version = None
# Since we are going to remove the tool from the section, replace it with the
# newest loaded version of the tool.
for available_tool_version in available_tool_versions:
available_tool_section_id, available_tool_section_name = available_tool_version.get_panel_section()
if available_tool_version.id in tool_section.elems.keys() or section_key == available_tool_section_id:
replacement_tool_key = 'tool_%s' % str( available_tool_version.id )
replacement_tool_version = available_tool_version
break
if replacement_tool_key and replacement_tool_version:
# Get the index of the tool_key in the tool_section.
for tool_section_elems_index, key in enumerate( tool_section.elems.keys() ):
if key == tool_key:
break
# Remove the tool from the tool section.
del tool_section.elems[ tool_key ]
# Add the replacement tool at the same location in the tool section.
tool_section.elems.insert( tool_section_elems_index,
replacement_tool_key,
replacement_tool_version )
else:
del tool_section.elems[ tool_key ]
else:
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 app.toolbox.integrated_tool_panel:
tool_section = 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 )
elif config_elem.tag == 'tool':
guid = config_elem.get( 'guid' )
if guid in guids_to_remove:
tool_key = 'tool_%s' % str( config_elem.get( 'guid' ) )
# Get the list of versions of this tool that are currently available in the toolbox.
available_tool_versions = app.toolbox.get_loaded_tools_by_lineage( guid )
if tool_key in app.toolbox.tool_panel:
if available_tool_versions:
available_tool_versions.reverse()
replacement_tool_key = None
replacement_tool_version = None
# Since we are going to remove the tool from the section, replace it with
# the newest loaded version of the tool.
for available_tool_version in available_tool_versions:
available_tool_section_id, available_tool_section_name = available_tool_version.get_panel_section()
if available_tool_version.id in app.toolbox.tool_panel.keys() or not available_tool_section_id:
replacement_tool_key = 'tool_%s' % str( available_tool_version.id )
replacement_tool_version = available_tool_version
break
if replacement_tool_key and replacement_tool_version:
# Get the index of the tool_key in the tool_section.
for tool_panel_index, key in enumerate( app.toolbox.tool_panel.keys() ):
if key == tool_key:
break
# Remove the tool from the tool panel.
del app.toolbox.tool_panel[ tool_key ]
# Add the replacement tool at the same location in the tool panel.
app.toolbox.tool_panel.insert( tool_panel_index, replacement_tool_key, replacement_tool_version )
else:
del app.toolbox.tool_panel[ tool_key ]
else:
del app.toolbox.tool_panel[ tool_key ]
if uninstall:
if tool_key in app.toolbox.integrated_tool_panel:
del 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.
config_elems.remove( config_elem )
# Update the config_elems of the in-memory shed_tool_conf_dict.
shed_tool_conf_dict[ 'config_elems' ] = config_elems
app.toolbox.shed_tool_confs[ index ] = shed_tool_conf_dict
app.toolbox_search = ToolBoxSearch( app.toolbox )
if uninstall and app.config.update_integrated_tool_panel:
# Write the current in-memory version of the integrated_tool_panel.xml file to disk.
app.toolbox.write_integrated_tool_panel_config_file()
def reset_tool_data_tables( app ):
# Reset the tool_data_tables to an empty dictionary.
app.tool_data_tables.data_tables = {}