commit/galaxy-central: dan: Allow reloading External Display applications without restarting Galaxy.
1 new commit in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/commits/00f4c600b89f/ Changeset: 00f4c600b89f User: dan Date: 2015-02-04 21:12:03+00:00 Summary: Allow reloading External Display applications without restarting Galaxy. Affected #: 5 files diff -r dee88f35c796e413ae071a49716dff1a9238d66c -r 00f4c600b89fdd52b0296e8bfc599a16485838b2 lib/galaxy/datatypes/display_applications/application.py --- a/lib/galaxy/datatypes/display_applications/application.py +++ b/lib/galaxy/datatypes/display_applications/application.py @@ -167,23 +167,21 @@ 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 @@ 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 @@ 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 diff -r dee88f35c796e413ae071a49716dff1a9238d66c -r 00f4c600b89fdd52b0296e8bfc599a16485838b2 lib/galaxy/datatypes/registry.py --- a/lib/galaxy/datatypes/registry.py +++ b/lib/galaxy/datatypes/registry.py @@ -621,6 +621,26 @@ 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 diff -r dee88f35c796e413ae071a49716dff1a9238d66c -r 00f4c600b89fdd52b0296e8bfc599a16485838b2 lib/galaxy/webapps/galaxy/controllers/admin.py --- a/lib/galaxy/webapps/galaxy/controllers/admin.py +++ b/lib/galaxy/webapps/galaxy/controllers/admin.py @@ -883,3 +883,21 @@ 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 ) ) ) diff -r dee88f35c796e413ae071a49716dff1a9238d66c -r 00f4c600b89fdd52b0296e8bfc599a16485838b2 templates/webapps/galaxy/admin/index.mako --- a/templates/webapps/galaxy/admin/index.mako +++ b/templates/webapps/galaxy/admin/index.mako @@ -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> diff -r dee88f35c796e413ae071a49716dff1a9238d66c -r 00f4c600b89fdd52b0296e8bfc599a16485838b2 templates/webapps/galaxy/admin/view_display_applications.mako --- /dev/null +++ b/templates/webapps/galaxy/admin/view_display_applications.mako @@ -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> 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.
participants (1)
-
commits-noreply@bitbucket.org