Allow uninstalling multiple toolshed repositories at a time within the Galaxy UI, using checkboxes with grid multi-actions.

This commit is contained in:
Daniel Blankenberg
2015-07-28 16:22:16 -04:00
parent 16928704e6
commit 1e6c49b277
4 changed files with 117 additions and 84 deletions
@@ -228,94 +228,104 @@ class AdminToolshed( AdminGalaxy ):
but we may choose to do so in the future if it becomes necessary.
"""
message = escape( kwd.get( 'message', '' ) )
statuses = [ None, '' 'info', 'done', 'warning', 'error' ]
status = kwd.get( 'status', 'done' )
if status in statuses:
status = statuses.index( status )
else:
status = 1
remove_from_disk = kwd.get( 'remove_from_disk', '' )
remove_from_disk_checked = CheckboxField.is_checked( remove_from_disk )
tool_shed_repository = repository_util.get_installed_tool_shed_repository( trans.app, kwd[ 'id' ] )
shed_tool_conf, tool_path, relative_install_dir = \
suc.get_tool_panel_config_tool_path_install_dir( trans.app, tool_shed_repository )
if relative_install_dir:
if tool_path:
relative_install_dir = os.path.join( tool_path, relative_install_dir )
repository_install_dir = os.path.abspath( relative_install_dir )
else:
repository_install_dir = None
errors = ''
if kwd.get( 'deactivate_or_uninstall_repository_button', False ):
if tool_shed_repository.includes_tools_for_display_in_tool_panel:
# Handle tool panel alterations.
tpm = tool_panel_manager.ToolPanelManager( trans.app )
tpm.remove_repository_contents( tool_shed_repository,
shed_tool_conf,
uninstall=remove_from_disk_checked )
if tool_shed_repository.includes_data_managers:
dmh = data_manager.DataManagerHandler( trans.app )
dmh.remove_from_data_manager( tool_shed_repository )
if tool_shed_repository.includes_datatypes:
# Deactivate proprietary datatypes.
cdl = custom_datatype_manager.CustomDatatypeLoader( trans.app )
installed_repository_dict = cdl.load_installed_datatypes( tool_shed_repository,
repository_install_dir,
deactivate=True )
if installed_repository_dict:
converter_path = installed_repository_dict.get( 'converter_path' )
if converter_path is not None:
cdl.load_installed_datatype_converters( installed_repository_dict, deactivate=True )
display_path = installed_repository_dict.get( 'display_path' )
if display_path is not None:
cdl.load_installed_display_applications( installed_repository_dict, deactivate=True )
if remove_from_disk_checked:
try:
# Remove the repository from disk.
shutil.rmtree( repository_install_dir )
log.debug( "Removed repository installation directory: %s" % str( repository_install_dir ) )
removed = True
except Exception, e:
log.debug( "Error removing repository installation directory %s: %s" % ( str( repository_install_dir ), str( e ) ) )
if isinstance( e, OSError ) and not os.path.exists( repository_install_dir ):
tool_shed_repositories = repository_util.get_installed_tool_shed_repository( trans.app, kwd[ 'id' ] )
if not isinstance( tool_shed_repositories, list ):
tool_shed_repositories = [tool_shed_repositories]
for tool_shed_repository in tool_shed_repositories:
shed_tool_conf, tool_path, relative_install_dir = \
suc.get_tool_panel_config_tool_path_install_dir( trans.app, tool_shed_repository )
if relative_install_dir:
if tool_path:
relative_install_dir = os.path.join( tool_path, relative_install_dir )
repository_install_dir = os.path.abspath( relative_install_dir )
else:
repository_install_dir = None
errors = ''
if kwd.get( 'deactivate_or_uninstall_repository_button', False ):
if tool_shed_repository.includes_tools_for_display_in_tool_panel:
# Handle tool panel alterations.
tpm = tool_panel_manager.ToolPanelManager( trans.app )
tpm.remove_repository_contents( tool_shed_repository,
shed_tool_conf,
uninstall=remove_from_disk_checked )
if tool_shed_repository.includes_data_managers:
dmh = data_manager.DataManagerHandler( trans.app )
dmh.remove_from_data_manager( tool_shed_repository )
if tool_shed_repository.includes_datatypes:
# Deactivate proprietary datatypes.
cdl = custom_datatype_manager.CustomDatatypeLoader( trans.app )
installed_repository_dict = cdl.load_installed_datatypes( tool_shed_repository,
repository_install_dir,
deactivate=True )
if installed_repository_dict:
converter_path = installed_repository_dict.get( 'converter_path' )
if converter_path is not None:
cdl.load_installed_datatype_converters( installed_repository_dict, deactivate=True )
display_path = installed_repository_dict.get( 'display_path' )
if display_path is not None:
cdl.load_installed_display_applications( installed_repository_dict, deactivate=True )
if remove_from_disk_checked:
try:
# Remove the repository from disk.
shutil.rmtree( repository_install_dir )
log.debug( "Removed repository installation directory: %s" % str( repository_install_dir ) )
removed = True
log.debug( "Repository directory does not exist on disk, marking as uninstalled." )
else:
removed = False
if removed:
tool_shed_repository.uninstalled = True
# Remove all installed tool dependencies and tool dependencies stuck in the INSTALLING state, but don't touch any
# repository dependencies.
tool_dependencies_to_uninstall = tool_shed_repository.tool_dependencies_installed_or_in_error
tool_dependencies_to_uninstall.extend( tool_shed_repository.tool_dependencies_being_installed )
for tool_dependency in tool_dependencies_to_uninstall:
uninstalled, error_message = tool_dependency_util.remove_tool_dependency( trans.app, tool_dependency )
if error_message:
errors = '%s %s' % ( errors, error_message )
tool_shed_repository.deleted = True
if remove_from_disk_checked:
tool_shed_repository.status = trans.install_model.ToolShedRepository.installation_status.UNINSTALLED
tool_shed_repository.error_message = None
if trans.app.config.manage_dependency_relationships:
# Remove the uninstalled repository and any tool dependencies from the in-memory dictionaries in the
# installed_repository_manager.
trans.app.installed_repository_manager.handle_repository_uninstall( tool_shed_repository )
else:
tool_shed_repository.status = trans.install_model.ToolShedRepository.installation_status.DEACTIVATED
trans.install_model.context.add( tool_shed_repository )
trans.install_model.context.flush()
if remove_from_disk_checked:
message = 'The repository named <b>%s</b> has been uninstalled. ' % escape( tool_shed_repository.name )
if errors:
message += 'Attempting to uninstall tool dependencies resulted in errors: %s' % errors
status = 'error'
except Exception, e:
log.debug( "Error removing repository installation directory %s: %s" % ( str( repository_install_dir ), str( e ) ) )
if isinstance( e, OSError ) and not os.path.exists( repository_install_dir ):
removed = True
log.debug( "Repository directory does not exist on disk, marking as uninstalled." )
else:
removed = False
if removed:
tool_shed_repository.uninstalled = True
# Remove all installed tool dependencies and tool dependencies stuck in the INSTALLING state, but don't touch any
# repository dependencies.
tool_dependencies_to_uninstall = tool_shed_repository.tool_dependencies_installed_or_in_error
tool_dependencies_to_uninstall.extend( tool_shed_repository.tool_dependencies_being_installed )
for tool_dependency in tool_dependencies_to_uninstall:
uninstalled, error_message = tool_dependency_util.remove_tool_dependency( trans.app, tool_dependency )
if error_message:
errors = '%s %s' % ( errors, error_message )
tool_shed_repository.deleted = True
if remove_from_disk_checked:
tool_shed_repository.status = trans.install_model.ToolShedRepository.installation_status.UNINSTALLED
tool_shed_repository.error_message = None
if trans.app.config.manage_dependency_relationships:
# Remove the uninstalled repository and any tool dependencies from the in-memory dictionaries in the
# installed_repository_manager.
trans.app.installed_repository_manager.handle_repository_uninstall( tool_shed_repository )
else:
status = 'done'
else:
message = 'The repository named <b>%s</b> has been deactivated. ' % escape( tool_shed_repository.name )
status = 'done'
tool_shed_repository.status = trans.install_model.ToolShedRepository.installation_status.DEACTIVATED
trans.install_model.context.add( tool_shed_repository )
trans.install_model.context.flush()
if remove_from_disk_checked:
message += 'The repository named <b>%s</b> has been uninstalled. ' % escape( tool_shed_repository.name )
if errors:
message += 'Attempting to uninstall tool dependencies resulted in errors: %s' % errors
status = max( status, statuses.index( 'error' ) )
else:
status = max( status, statuses.index( 'done' ) )
else:
message = 'The repository named <b>%s</b> has been deactivated. ' % escape( tool_shed_repository.name )
status = max( status, statuses.index( 'done' ) )
status = statuses[ status ]
if kwd.get( 'deactivate_or_uninstall_repository_button', False ):
return trans.response.send_redirect( web.url_for( controller='admin_toolshed',
action='browse_repositories',
message=message,
status=status ) )
remove_from_disk_check_box = CheckboxField( 'remove_from_disk', checked=remove_from_disk_checked )
return trans.fill_template( '/admin/tool_shed_repository/deactivate_or_uninstall_repository.mako',
repository=tool_shed_repository,
repository=tool_shed_repositories,
remove_from_disk_check_box=remove_from_disk_check_box,
message=message,
status=status )
@@ -196,7 +196,7 @@ class InstalledRepositoryGrid( grids.Grid ):
condition=( lambda item:
not item.deleted and
item.status != tool_shed_install.ToolShedRepository.installation_status.NEW ),
allow_multiple=False,
allow_multiple=True,
url_args=dict( controller='admin_toolshed',
action='browse_repositories',
operation='deactivate or uninstall' ) ),
+11 -2
View File
@@ -275,8 +275,17 @@ def create_repository_admin_role( app, repository ):
def get_installed_tool_shed_repository( app, id ):
"""Get a tool shed repository record from the Galaxy database defined by the id."""
return app.install_model.context.query( app.install_model.ToolShedRepository ) \
.get( app.security.decode_id( id ) )
rval = []
if isinstance( id, list ):
return_list = True
else:
id = [ id ]
return_list = False
for i in id:
rval.append( app.install_model.context.query( app.install_model.ToolShedRepository ).get( app.security.decode_id( i ) ) )
if return_list:
return rval
return rval[0]
def get_repo_info_dict( app, user, repository_id, changeset_revision ):
@@ -3,16 +3,28 @@
<%namespace file="/admin/tool_shed_repository/common.mako" import="*" />
<%namespace file="/admin/tool_shed_repository/repository_actions_menu.mako" import="*" />
${render_galaxy_repository_actions( repository )}
<%
repository = context.get( 'repository', None )
if isinstance( repository, list ):
repositories = repository
else:
repositories = [ repository ]
%>
%if len( repositories ) == 1:
${render_galaxy_repository_actions( repositories[0] )}
%endif
%if message:
${render_msg( message, status )}
%endif
<div class="toolForm">
<form name="deactivate_or_uninstall_repository" id="deactivate_or_uninstall_repository" action="${ h.url_for( controller='admin_toolshed', action='deactivate_or_uninstall_repository' ) }" method="post" >
%for repository in repositories:
<input type="hidden" name="id" value="${ trans.security.encode_id( repository.id ) | h }" />
<div class="toolFormTitle">${repository.name|h}</div>
<div class="toolFormBody">
<form name="deactivate_or_uninstall_repository" id="deactivate_or_uninstall_repository" action="${h.url_for( controller='admin_toolshed', action='deactivate_or_uninstall_repository', id=trans.security.encode_id( repository.id ) )}" method="post" >
<div class="form-row">
<label>Description:</label>
${repository.description|h}
@@ -169,10 +181,12 @@ ${render_galaxy_repository_actions( repository )}
%endif
%endif
</div>
</div>
%endfor
<div class="form-row">
<%
can_deactivate_repository = repository.can_deactivate
can_uninstall_repository = repository.can_uninstall
can_deactivate_repository = True in map( lambda x: x.can_deactivate, repositories )
can_uninstall_repository = True in map( lambda x: x.can_uninstall, repositories )
%>
%if can_deactivate_repository and can_uninstall_repository:
<% deactivate_uninstall_button_text = "Deactivate or Uninstall" %>