mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Allow reloading External Display applications without restarting Galaxy.
This commit is contained in:
@@ -167,23 +167,21 @@ class PopulatedDisplayApplicationLink( object ):
|
||||
class DisplayApplication( object ):
|
||||
@classmethod
|
||||
def from_file( cls, filename, datatypes_registry ):
|
||||
return cls.from_elem( parse_xml( filename ).getroot(), datatypes_registry )
|
||||
return cls.from_elem( parse_xml( filename ).getroot(), datatypes_registry, filename=filename )
|
||||
@classmethod
|
||||
def from_elem( cls, elem, datatypes_registry ):
|
||||
def from_elem( cls, elem, datatypes_registry, filename=None ):
|
||||
att_dict = cls._get_attributes_from_elem( elem )
|
||||
rval = DisplayApplication( att_dict['id'], att_dict['name'], datatypes_registry, att_dict['version'], filename=filename, elem=elem )
|
||||
rval._load_links_from_elem( elem )
|
||||
return rval
|
||||
@classmethod
|
||||
def _get_attributes_from_elem( cls, elem ):
|
||||
display_id = elem.get( 'id', None )
|
||||
assert display_id, "ID tag is required for a Display Application"
|
||||
name = elem.get( 'name', display_id )
|
||||
version = elem.get( 'version', None )
|
||||
rval = DisplayApplication( display_id, name, datatypes_registry, version )
|
||||
for link_elem in elem.findall( 'link' ):
|
||||
link = DisplayApplicationLink.from_elem( link_elem, rval )
|
||||
if link:
|
||||
rval.links[ link.id ] = link
|
||||
for dynamic_links in elem.findall( 'dynamic_links' ):
|
||||
for link in DynamicDisplayApplicationBuilder( dynamic_links, rval, datatypes_registry.build_sites ):
|
||||
rval.links[ link.id ] = link
|
||||
return rval
|
||||
def __init__( self, display_id, name, datatypes_registry, version = None ):
|
||||
return dict( id=display_id, name=name, version=version )
|
||||
def __init__( self, display_id, name, datatypes_registry, version = None, filename=None, elem=None ):
|
||||
self.id = display_id
|
||||
self.name = name
|
||||
self.datatypes_registry = datatypes_registry
|
||||
@@ -191,6 +189,16 @@ class DisplayApplication( object ):
|
||||
version = "1.0.0"
|
||||
self.version = version
|
||||
self.links = odict()
|
||||
self._filename = filename
|
||||
self._elem = elem
|
||||
def _load_links_from_elem( self, elem ):
|
||||
for link_elem in elem.findall( 'link' ):
|
||||
link = DisplayApplicationLink.from_elem( link_elem, self )
|
||||
if link:
|
||||
self.links[ link.id ] = link
|
||||
for dynamic_links in elem.findall( 'dynamic_links' ):
|
||||
for link in DynamicDisplayApplicationBuilder( dynamic_links, self, self.datatypes_registry.build_sites ):
|
||||
self.links[ link.id ] = link
|
||||
def get_link( self, link_name, data, dataset_hash, user_hash, trans, app_kwds ):
|
||||
#returns a link object with data knowledge to generate links
|
||||
return PopulatedDisplayApplicationLink( self.links[ link_name ], data, dataset_hash, user_hash, trans, app_kwds )
|
||||
@@ -200,3 +208,23 @@ class DisplayApplication( object ):
|
||||
if link_value.filter_by_dataset( data, trans ):
|
||||
filtered.links[link_name] = link_value
|
||||
return filtered
|
||||
def reload( self ):
|
||||
if self._filename:
|
||||
elem = parse_xml( self._filename ).getroot()
|
||||
elif self._elem:
|
||||
elem = self._elem
|
||||
else:
|
||||
raise Exception( "Unable to reload DisplayApplication %s." % ( self.name ) )
|
||||
# All toolshed-specific attributes added by e.g the registry will remain
|
||||
attr_dict = self._get_attributes_from_elem( elem )
|
||||
# We will not allow changing the id at this time (we'll need to fix several mappings upstream to handle this case)
|
||||
assert attr_dict.get( 'id' ) == self.id, ValueError( "You cannot reload a Display application where the ID has changed. You will need to restart the server instead." )
|
||||
# clear old links
|
||||
for key in self.links.keys():
|
||||
del self.links[key]
|
||||
# Set new attributes
|
||||
for key, value in attr_dict.iteritems():
|
||||
setattr( self, key, value )
|
||||
# Load new links
|
||||
self._load_links_from_elem( elem )
|
||||
return self
|
||||
|
||||
@@ -621,6 +621,26 @@ class Registry( object ):
|
||||
self.log.debug( "Adding inherited display application '%s' to datatype '%s'" % ( display_app.id, extension ) )
|
||||
d_type1.add_display_application( display_app )
|
||||
|
||||
def reload_display_applications( self, display_application_ids=None ):
|
||||
"""
|
||||
Reloads display applications: by id, or all if no ids provided
|
||||
Returns tuple( [reloaded_ids], [failed_ids] )
|
||||
"""
|
||||
if not display_application_ids:
|
||||
display_application_ids = self.display_applications.keys()
|
||||
elif not isinstance( display_application_ids, list ):
|
||||
display_application_ids = [ display_application_ids ]
|
||||
reloaded = []
|
||||
failed = []
|
||||
for display_application_id in display_application_ids:
|
||||
try:
|
||||
self.display_applications[ display_application_id ].reload()
|
||||
reloaded.append( display_application_id )
|
||||
except Exception, e:
|
||||
self.log.debug( 'Requested to reload display application "%s", but failed: %s.', display_application_id, e )
|
||||
failed.append( display_application_id )
|
||||
return ( reloaded, failed )
|
||||
|
||||
def load_external_metadata_tool( self, toolbox ):
|
||||
"""Adds a tool which is used to set external metadata"""
|
||||
# We need to be able to add a job to the queue to set metadata. The queue will currently only accept jobs with an associated
|
||||
|
||||
@@ -883,3 +883,21 @@ class AdminGalaxy( BaseUIController, Admin, AdminActions, UsesQuotaMixin, QuotaP
|
||||
message = escape( galaxy.util.restore_text( kwd.get( 'message', '' ) ) )
|
||||
status = galaxy.util.restore_text( kwd.get( 'status', 'done' ) )
|
||||
return trans.fill_template( 'admin/view_data_tables_registry.mako', message=message, status=status )
|
||||
|
||||
@web.expose
|
||||
@web.require_admin
|
||||
def display_applications( self, trans, **kwd ):
|
||||
return trans.fill_template( 'admin/view_display_applications.mako', display_applications=trans.app.datatypes_registry.display_applications )
|
||||
|
||||
@web.expose
|
||||
@web.require_admin
|
||||
def reload_display_application( self, trans, **kwd ):
|
||||
reloaded, failed = trans.app.datatypes_registry.reload_display_applications( kwd.get( 'id' ) )
|
||||
if not reloaded and failed:
|
||||
return trans.show_error_message( 'Unable to reload any of the %i requested display applications ("%s").' % ( len( failed ), '", "'.join( failed ) ) )
|
||||
if failed:
|
||||
return trans.show_warn_message( 'Reloaded %i display applications ("%s"), but failed to reload %i display applications ("%s").'
|
||||
% ( len( reloaded ), '", "'.join( reloaded ), len( failed ), '", "'.join( failed ) ) )
|
||||
if not reloaded:
|
||||
return trans.show_warn_message( 'You need to request at least one display application to reload.' )
|
||||
return trans.show_ok_message( 'Reloaded %i requested display applications ("%s").' % ( len( reloaded ), '", "'.join( reloaded ) ) )
|
||||
|
||||
@@ -75,6 +75,7 @@
|
||||
<div class="toolSectionBg">
|
||||
<div class="toolTitle"><a href="${h.url_for( controller='admin', action='view_datatypes_registry' )}" target="galaxy_main">View data types registry</a></div>
|
||||
<div class="toolTitle"><a href="${h.url_for( controller='admin', action='view_tool_data_tables' )}" target="galaxy_main">View data tables registry</a></div>
|
||||
<div class="toolTitle"><a href="${h.url_for( controller='admin', action='display_applications' )}" target="galaxy_main">View display applications</a></div>
|
||||
<div class="toolTitle"><a href="${h.url_for( controller='admin', action='tool_versions' )}" target="galaxy_main">View tool lineage</a></div>
|
||||
<div class="toolTitle"><a href="${h.url_for( controller='admin', action='package_tool' )}" target="galaxy_main">Download tool tarball</a></div>
|
||||
<div class="toolTitle"><a href="${h.url_for( controller='admin', action='reload_tool' )}" target="galaxy_main">Reload a tool's configuration</a></div>
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
<%inherit file="/base.mako"/>
|
||||
<%namespace file="/message.mako" import="render_msg" />
|
||||
|
||||
%if message:
|
||||
${render_msg( message, status )}
|
||||
%endif
|
||||
|
||||
<div class="toolForm">
|
||||
<div class="toolFormTitle">There are currently ${len( display_applications )} <a class="icon-btn" href="${ h.url_for( controller='admin', action='reload_display_application' ) }" title="Reload all display applications" data-placement="bottom">
|
||||
<span class="fa fa-refresh"></span>
|
||||
</a> display applications loaded.</div>
|
||||
<div class="toolFormBody">
|
||||
<table class="manage-table colored" border="0" cellspacing="0" cellpadding="0" width="100%">
|
||||
<tr>
|
||||
<th bgcolor="#D8D8D8">Reload</th>
|
||||
<th bgcolor="#D8D8D8">Name</th>
|
||||
<th bgcolor="#D8D8D8">ID</th>
|
||||
<th bgcolor="#D8D8D8">Version</th>
|
||||
<th bgcolor="#D8D8D8">Links</th>
|
||||
<th bgcolor="#D8D8D8">Filename</th>
|
||||
</tr>
|
||||
<% ctr = 0 %>
|
||||
%for display_app in display_applications.values():
|
||||
%if ctr % 2 == 1:
|
||||
<tr class="odd_row">
|
||||
%else:
|
||||
<tr class="tr">
|
||||
%endif
|
||||
<td>
|
||||
<a class="icon-btn" href="${ h.url_for( controller='admin', action='reload_display_application', id=display_app.id ) }" title="Reload ${ display_app.name | h } display application" data-placement="bottom">
|
||||
<span class="fa fa-refresh"></span>
|
||||
</a>
|
||||
</td>
|
||||
<td>${ display_app.name | h }</td>
|
||||
<td>${ display_app.id | h }</td>
|
||||
<td>${ display_app.version | h }</td>
|
||||
<td><ul>
|
||||
%for link in display_app.links.values():
|
||||
<li>${ link.name | h }</li>
|
||||
%endfor
|
||||
</ul></td>
|
||||
<td>${ display_app._filename | h }</td>
|
||||
</tr>
|
||||
<% ctr += 1 %>
|
||||
%endfor
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user