2 new commits in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/changeset/d77454603237/ changeset: d77454603237 user: jgoecks date: 2012-04-03 22:00:17 summary: Prettify tool section show/hide using sliding. affected #: 2 files diff -r a0f64b544cc6412516a62459808e0026d2897dc0 -r d774546032374648823f29aad4fb178086e169e4 static/scripts/backbone/tools.js --- a/static/scripts/backbone/tools.js +++ b/static/scripts/backbone/tools.js @@ -285,7 +285,6 @@ * Toggle visibility of tool section. */ toggle: function() { - this.$el.children(".toolSectionBody").toggle("fast"); this.model.set("open", !this.model.attributes.open); }, @@ -294,8 +293,8 @@ */ update_open: function() { (this.model.attributes.open ? - this.$el.children(".toolSectionBody").show("fast") : - this.$el.children(".toolSectionBody").hide("fast") + this.$el.children(".toolSectionBody").slideDown("fast") : + this.$el.children(".toolSectionBody").slideUp("fast") ); } }); diff -r a0f64b544cc6412516a62459808e0026d2897dc0 -r d774546032374648823f29aad4fb178086e169e4 static/scripts/packed/backbone/tools.js --- a/static/scripts/packed/backbone/tools.js +++ b/static/scripts/packed/backbone/tools.js @@ -1,1 +1,1 @@ -var BaseModel=Backbone.Model.extend({defaults:{id:null,name:null,hidden:false},show:function(){this.set("hidden",false)},hide:function(){this.set("hidden",true)},is_visible:function(){return !this.attributes.hidden}});var Tool=BaseModel.extend({defaults:{description:null,target:null,params:[]},apply_search_results:function(a){(_.indexOf(a,this.attributes.id)!==-1?this.show():this.hide());return this.is_visible()}});var ToolPanelLabel=BaseModel.extend({});var ToolPanelSection=BaseModel.extend({defaults:{elems:[],open:false},clear_search_results:function(){_.each(this.attributes.elems,function(a){a.show()});this.show();this.set("open",false)},apply_search_results:function(b){var c=true,a;_.each(this.attributes.elems,function(d){if(d instanceof ToolPanelLabel){a=d;a.hide()}else{if(d instanceof Tool){if(d.apply_search_results(b)){c=false;if(a){a.show()}}}}});if(c){this.hide()}else{this.show();this.set("open",true)}}});var ToolSearch=BaseModel.extend({defaults:{spinner_url:"",search_url:"",visible:true,query:"",results:null},initialize:function(){this.on("change:query",this.do_search)},do_search:function(){var c=this.attributes.query;if(c.length<3){this.set("results",null);return}var b=c+"*";if(this.timer){clearTimeout(this.timer)}$("#search-spinner").show();var a=this;this.timer=setTimeout(function(){$.get(a.attributes.search_url,{query:b},function(d){a.set("results",d);$("#search-spinner").hide()},"json")},200)}});var ToolPanel=Backbone.Collection.extend({url:"/tools",parse:function(a){var b=function(e){var d=e.type;if(d==="tool"){return new Tool(e)}else{if(d==="section"){var c=_.map(e.elems,b);e.elems=c;return new ToolPanelSection(e)}else{if(d==="label"){return new ToolPanelLabel(e)}}}};return _.map(a,b)},initialize:function(a){this.tool_search=a.tool_search;this.tool_search.on("change:results",this.apply_search_results,this)},clear_search_results:function(){this.each(function(a){a.clear_search_results()})},apply_search_results:function(){var a=this.tool_search.attributes.results;if(a===null){this.clear_search_results();return}this.each(function(b){b.apply_search_results(a)})}});var BaseView=Backbone.View.extend({initialize:function(){this.model.on("change:hidden",this.update_visible,this)},update_visible:function(){(this.model.attributes.hidden?this.$el.hide():this.$el.show())}});var ToolLinkView=BaseView.extend({tagName:"div",template:Handlebars.templates.tool_link,render:function(){this.$el.append(this.template(this.model.toJSON()));return this}});var ToolPanelLabelView=BaseView.extend({tagName:"div",className:"toolPanelLabel",template:Handlebars.templates.panel_label,render:function(){this.$el.append(this.template(this.model.toJSON()));return this},});var ToolPanelSectionView=BaseView.extend({tagName:"div",className:"toolSectionWrapper",template:Handlebars.templates.panel_section,initialize:function(){BaseView.prototype.initialize.call(this);this.model.on("change:open",this.update_open,this)},render:function(){this.$el.append(this.template(this.model.toJSON()));var a=this.$el.find(".toolSectionBody");_.each(this.model.attributes.elems,function(b){if(b instanceof Tool){var c=new ToolLinkView({model:b,className:"toolTitle"});c.render();a.append(c.$el)}else{if(b instanceof ToolPanelLabel){var d=new ToolPanelLabelView({model:b});d.render();a.append(d.$el)}else{}}});return this},events:{"click .toolSectionTitle > a":"toggle"},toggle:function(){this.$el.children(".toolSectionBody").toggle("fast");this.model.set("open",!this.model.attributes.open)},update_open:function(){(this.model.attributes.open?this.$el.children(".toolSectionBody").show("fast"):this.$el.children(".toolSectionBody").hide("fast"))}});var ToolSearchView=Backbone.View.extend({tagName:"div",id:"tool-search",className:"bar",template:Handlebars.templates.tool_search,events:{click:"focus_and_select","keyup :input":"query_changed"},render:function(){this.$el.append(this.template(this.model.toJSON()));if(!this.model.is_visible()){this.$el.hide()}return this},focus_and_select:function(){this.$el.find(":input").focus().select()},query_changed:function(){this.model.set("query",this.$el.find(":input").val())}});var ToolPanelView=Backbone.View.extend({tagName:"div",className:"toolMenu",initialize:function(a){this.collection.tool_search.on("change:results",this.handle_search_results,this)},render:function(){var b=this.$el;var a=new ToolSearchView({model:this.collection.tool_search});a.render();b.append(a.$el);this.collection.each(function(d){if(d instanceof ToolPanelSection){var c=new ToolPanelSectionView({model:d});c.render();b.append(c.$el)}else{if(d instanceof Tool){var e=new ToolLinkView({model:d,className:"toolTitleNoSection"});e.render();b.append(e.$el)}}});return this},handle_search_results:function(){var a=this.collection.tool_search.attributes.results;if(a&&a.length===0){$("#search-no-results").show()}else{$("#search-no-results").hide()}}}); \ No newline at end of file +var BaseModel=Backbone.Model.extend({defaults:{id:null,name:null,hidden:false},show:function(){this.set("hidden",false)},hide:function(){this.set("hidden",true)},is_visible:function(){return !this.attributes.hidden}});var Tool=BaseModel.extend({defaults:{description:null,target:null,params:[]},apply_search_results:function(a){(_.indexOf(a,this.attributes.id)!==-1?this.show():this.hide());return this.is_visible()}});var ToolPanelLabel=BaseModel.extend({});var ToolPanelSection=BaseModel.extend({defaults:{elems:[],open:false},clear_search_results:function(){_.each(this.attributes.elems,function(a){a.show()});this.show();this.set("open",false)},apply_search_results:function(b){var c=true,a;_.each(this.attributes.elems,function(d){if(d instanceof ToolPanelLabel){a=d;a.hide()}else{if(d instanceof Tool){if(d.apply_search_results(b)){c=false;if(a){a.show()}}}}});if(c){this.hide()}else{this.show();this.set("open",true)}}});var ToolSearch=BaseModel.extend({defaults:{spinner_url:"",search_url:"",visible:true,query:"",results:null},initialize:function(){this.on("change:query",this.do_search)},do_search:function(){var c=this.attributes.query;if(c.length<3){this.set("results",null);return}var b=c+"*";if(this.timer){clearTimeout(this.timer)}$("#search-spinner").show();var a=this;this.timer=setTimeout(function(){$.get(a.attributes.search_url,{query:b},function(d){a.set("results",d);$("#search-spinner").hide()},"json")},200)}});var ToolPanel=Backbone.Collection.extend({url:"/tools",parse:function(a){var b=function(e){var d=e.type;if(d==="tool"){return new Tool(e)}else{if(d==="section"){var c=_.map(e.elems,b);e.elems=c;return new ToolPanelSection(e)}else{if(d==="label"){return new ToolPanelLabel(e)}}}};return _.map(a,b)},initialize:function(a){this.tool_search=a.tool_search;this.tool_search.on("change:results",this.apply_search_results,this)},clear_search_results:function(){this.each(function(a){a.clear_search_results()})},apply_search_results:function(){var a=this.tool_search.attributes.results;if(a===null){this.clear_search_results();return}this.each(function(b){b.apply_search_results(a)})}});var BaseView=Backbone.View.extend({initialize:function(){this.model.on("change:hidden",this.update_visible,this)},update_visible:function(){(this.model.attributes.hidden?this.$el.hide():this.$el.show())}});var ToolLinkView=BaseView.extend({tagName:"div",template:Handlebars.templates.tool_link,render:function(){this.$el.append(this.template(this.model.toJSON()));return this}});var ToolPanelLabelView=BaseView.extend({tagName:"div",className:"toolPanelLabel",template:Handlebars.templates.panel_label,render:function(){this.$el.append(this.template(this.model.toJSON()));return this},});var ToolPanelSectionView=BaseView.extend({tagName:"div",className:"toolSectionWrapper",template:Handlebars.templates.panel_section,initialize:function(){BaseView.prototype.initialize.call(this);this.model.on("change:open",this.update_open,this)},render:function(){this.$el.append(this.template(this.model.toJSON()));var a=this.$el.find(".toolSectionBody");_.each(this.model.attributes.elems,function(b){if(b instanceof Tool){var c=new ToolLinkView({model:b,className:"toolTitle"});c.render();a.append(c.$el)}else{if(b instanceof ToolPanelLabel){var d=new ToolPanelLabelView({model:b});d.render();a.append(d.$el)}else{}}});return this},events:{"click .toolSectionTitle > a":"toggle"},toggle:function(){this.model.set("open",!this.model.attributes.open)},update_open:function(){(this.model.attributes.open?this.$el.children(".toolSectionBody").slideDown("fast"):this.$el.children(".toolSectionBody").slideUp("fast"))}});var ToolSearchView=Backbone.View.extend({tagName:"div",id:"tool-search",className:"bar",template:Handlebars.templates.tool_search,events:{click:"focus_and_select","keyup :input":"query_changed"},render:function(){this.$el.append(this.template(this.model.toJSON()));if(!this.model.is_visible()){this.$el.hide()}return this},focus_and_select:function(){this.$el.find(":input").focus().select()},query_changed:function(){this.model.set("query",this.$el.find(":input").val())}});var ToolPanelView=Backbone.View.extend({tagName:"div",className:"toolMenu",initialize:function(a){this.collection.tool_search.on("change:results",this.handle_search_results,this)},render:function(){var b=this.$el;var a=new ToolSearchView({model:this.collection.tool_search});a.render();b.append(a.$el);this.collection.each(function(d){if(d instanceof ToolPanelSection){var c=new ToolPanelSectionView({model:d});c.render();b.append(c.$el)}else{if(d instanceof Tool){var e=new ToolLinkView({model:d,className:"toolTitleNoSection"});e.render();b.append(e.$el)}}});return this},handle_search_results:function(){var a=this.collection.tool_search.attributes.results;if(a&&a.length===0){$("#search-no-results").show()}else{$("#search-no-results").hide()}}}); \ No newline at end of file https://bitbucket.org/galaxy/galaxy-central/changeset/4ae471a236a3/ changeset: 4ae471a236a3 user: jgoecks date: 2012-04-03 22:00:48 summary: Merge affected #: 9 files diff -r d774546032374648823f29aad4fb178086e169e4 -r 4ae471a236a381022d87779b033e49d2f8b321bd lib/galaxy/util/shed_util.py --- a/lib/galaxy/util/shed_util.py +++ b/lib/galaxy/util/shed_util.py @@ -24,35 +24,73 @@ class ShedCounter( object ): def __init__( self, model ): self.model = model - self.count_time = strftime( "%b %d, %Y", gmtime() ) - self.valid_tools = self.count_valid_tools() + self.generation_time = strftime( "%b %d, %Y", gmtime() ) + self.repositories = 0 + self.new_repositories = 0 + self.deleted_repositories = 0 + self.invalid_tools = 0 + self.valid_tools = 0 + self.workflows = 0 + self.proprietary_datatypes = 0 + self.total_clones = 0 + self.generate_statistics() @property def sa_session( self ): """Returns a SQLAlchemy session""" return self.model.context - def count_valid_tools( self ): - valid_tools = 0 - processed_repository_ids = [] - for repository_metadata in self.sa_session.query( self.model.RepositoryMetadata ) \ - .filter( and_( self.model.RepositoryMetadata.table.c.malicious == False, - self.model.RepositoryMetadata.table.c.metadata is not None, - self.model.RepositoryMetadata.table.c.tool_versions is not None ) ): - processed_guids = [] - repository = repository_metadata.repository - if repository.id not in processed_repository_ids: - for revision_metadata in repository.downloadable_revisions: - metadata = revision_metadata.metadata + def generate_statistics( self ): + self.repositories = 0 + self.new_repositories = 0 + self.deleted_repositories = 0 + self.invalid_tools = 0 + self.valid_tools = 0 + self.workflows = 0 + self.proprietary_datatypes = 0 + self.total_clones = 0 + for repository in self.sa_session.query( self.model.Repository ): + self.repositories += 1 + self.total_clones += repository.times_downloaded + if repository.deleted: + self.deleted_repositories += 1 + elif repository.is_new: + self.new_repositories += 1 + else: + processed_guids = [] + processed_invalid_tool_configs = [] + processed_relative_workflow_paths = [] + processed_datatypes = [] + for downloadable_revision in repository.downloadable_revisions: + metadata = downloadable_revision.metadata if 'tools' in metadata: tool_dicts = metadata[ 'tools' ] for tool_dict in tool_dicts: if 'guid' in tool_dict: guid = tool_dict[ 'guid' ] if guid not in processed_guids: - valid_tools += 1 + self.valid_tools += 1 processed_guids.append( guid ) - processed_repository_ids.append( repository.id ) - return valid_tools - + if 'invalid_tools' in metadata: + invalid_tool_configs = metadata[ 'invalid_tools' ] + for invalid_tool_config in invalid_tool_configs: + if invalid_tool_config not in processed_invalid_tool_configs: + self.invalid_tools += 1 + processed_invalid_tool_configs.append( invalid_tool_config ) + if 'datatypes' in metadata: + datatypes = metadata[ 'datatypes' ] + for datatypes_dict in datatypes: + if 'extension' in datatypes_dict: + extension = datatypes_dict[ 'extension' ] + if extension not in processed_datatypes: + self.proprietary_datatypes += 1 + processed_datatypes.append( extension ) + if 'workflows' in metadata: + workflows = metadata[ 'workflows' ] + for workflow_tup in workflows: + relative_path, exported_workflow_dict = workflow_tup + if relative_path not in processed_relative_workflow_paths: + self.workflows += 1 + processed_relative_workflow_paths.append( relative_path ) + self.generation_time = strftime( "%b %d, %Y", gmtime() ) 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 diff -r d774546032374648823f29aad4fb178086e169e4 -r 4ae471a236a381022d87779b033e49d2f8b321bd lib/galaxy/webapps/community/controllers/admin.py --- a/lib/galaxy/webapps/community/controllers/admin.py +++ b/lib/galaxy/webapps/community/controllers/admin.py @@ -457,6 +457,27 @@ status=status ) ) @web.expose @web.require_admin + def reset_all_repository_metadata( self, trans, **kwd ): + params = util.Params( kwd ) + message = util.restore_text( params.get( 'message', '' ) ) + status = params.get( 'status', 'done' ) + count = 0 + for repository in trans.sa_session.query( trans.model.Repository ) \ + .filter( trans.model.Repository.table.c.deleted == False ): + try: + reset_all_repository_metadata( trans, trans.security.encode_id( repository.id ) ) + log.debug( "Reset metadata on repository %s" % repository.name ) + count += 1 + except Exception, e: + log.debug( "Error attempting to reset metadata on repository %s: %s" % ( repository.name, str( e ) ) ) + message = "Reset metadata on %d repositories" % count + trans.response.send_redirect( web.url_for( controller='admin', + action='browse_repository_metadata', + webapp='community', + message=util.sanitize_text( message ), + status=status ) ) + @web.expose + @web.require_admin def browse_repositories( self, trans, **kwd ): # We add params to the keyword dict in this method in order to rename the param # with an "f-" prefix, simulating filtering by clicking a search link. We have @@ -527,6 +548,15 @@ return self.repository_list_grid( trans, **kwd ) @web.expose @web.require_admin + def regenerate_statistics( self, trans, **kwd ): + if 'regenerate_statistics_button' in kwd: + trans.app.shed_counter.generate_statistics() + message = "Successfully regenerated statistics" + return trans.fill_template( '/webapps/community/admin/statistics.mako', + message=message, + status='done' ) + @web.expose + @web.require_admin def delete_repository( self, trans, **kwd ): params = util.Params( kwd ) message = util.restore_text( params.get( 'message', '' ) ) diff -r d774546032374648823f29aad4fb178086e169e4 -r 4ae471a236a381022d87779b033e49d2f8b321bd lib/galaxy/webapps/community/controllers/common.py --- a/lib/galaxy/webapps/community/controllers/common.py +++ b/lib/galaxy/webapps/community/controllers/common.py @@ -201,7 +201,7 @@ can_set_metadata = False correction_msg = "This file requires an entry in the tool_data_table_conf.xml file. " correction_msg += "Upload a file named tool_data_table_conf.xml.sample to the repository " - correction_msg += "that includes the required entry to resolve this issue.<br/>" + correction_msg += "that includes the required entry to correct this error.<br/>" invalid_files.append( ( name, correction_msg ) ) if options.index_file or options.missing_index_file: # Make sure the repository contains the required xxx.loc.sample file. @@ -290,6 +290,7 @@ # repository tip, we handle things like .loc.sample files here. metadata_dict = {} invalid_files = [] + invalid_tool_configs = [] sample_files = [] datatypes_config = None # Find datatypes_conf.xml if it exists. @@ -324,6 +325,7 @@ except Exception, e: valid = False invalid_files.append( ( name, str( e ) ) ) + invalid_tool_configs.append( name ) if valid and tool is not None: can_set_metadata, invalid_files = check_tool_input_params( trans, name, tool, sample_files, invalid_files ) if can_set_metadata: @@ -331,6 +333,8 @@ tool_config = os.path.join( root, name ) repository_clone_url = generate_clone_url( trans, id ) metadata_dict = generate_tool_metadata( tool_config, tool, repository_clone_url, metadata_dict ) + else: + invalid_tool_configs.append( name ) # Find all exported workflows elif name.endswith( '.ga' ): try: @@ -344,11 +348,14 @@ metadata_dict = generate_workflow_metadata( relative_path, exported_workflow_dict, metadata_dict ) except Exception, e: invalid_files.append( ( name, str( e ) ) ) + if invalid_tool_configs: + metadata_dict[ 'invalid_tools' ] = invalid_tool_configs return metadata_dict, invalid_files def generate_metadata_for_changeset_revision( trans, id, ctx, changeset_revision, repo_dir ): # Browse repository files within a change set to generate metadata. metadata_dict = {} invalid_files = [] + invalid_tool_configs = [] sample_files = [] tmp_datatypes_config = None # Find datatypes_conf.xml if it exists. @@ -392,6 +399,7 @@ valid = True except Exception, e: invalid_files.append( ( filename, str( e ) ) ) + invalid_tool_configs.append( filename ) valid = False if valid and tool is not None: # Update the list of metadata dictionaries for tools in metadata_dict. Note that filename @@ -403,6 +411,8 @@ # tip, we do not have to handle any .loc.sample files since they would have been handled previously. repository_clone_url = generate_clone_url( trans, id ) metadata_dict = generate_tool_metadata( filename, tool, repository_clone_url, metadata_dict ) + else: + invalid_tool_configs.append( filename ) try: os.unlink( tmp_filename ) except: @@ -417,6 +427,8 @@ metadata_dict = generate_workflow_metadata( '', exported_workflow_dict, metadata_dict ) except Exception, e: invalid_files.append( ( name, str( e ) ) ) + if invalid_tool_configs: + metadata_dict[ 'invalid_tools' ] = invalid_tool_configs return metadata_dict, invalid_files def set_repository_metadata( trans, id, changeset_revision, content_alert_str='', **kwd ): """Set repository metadata""" diff -r d774546032374648823f29aad4fb178086e169e4 -r 4ae471a236a381022d87779b033e49d2f8b321bd lib/galaxy/webapps/community/controllers/repository.py --- a/lib/galaxy/webapps/community/controllers/repository.py +++ b/lib/galaxy/webapps/community/controllers/repository.py @@ -770,15 +770,14 @@ """ If the received changeset_revision includes a file named readme (case ignored), return it's contents. """ - name = kwd[ 'name' ] - owner = kwd[ 'owner' ] + repository_name = kwd[ 'name' ] + repository_owner = kwd[ 'owner' ] changeset_revision = kwd[ 'changeset_revision' ] - repository = get_repository_by_name_and_owner( trans, name, owner ) + repository = get_repository_by_name_and_owner( trans, repository_name, repository_owner ) repo_dir = repository.repo_path - repo = hg.repository( get_configured_ui(), repo_dir ) for root, dirs, files in os.walk( repo_dir ): for name in files: - if name.lower() in [ 'readme', 'readme.txt', 'read_me', 'read_me.txt' ]: + if name.lower() in [ 'readme', 'readme.txt', 'read_me', 'read_me.txt', '%s.txt' % repository_name ]: f = open( os.path.join( root, name ), 'r' ) text = f.read() f.close() @@ -1814,6 +1813,81 @@ changeset_revision=changeset_revision, message=message, status='error' ) ) + @web.expose + def load_invalid_tool( self, trans, repository_id, tool_config, changeset_revision, **kwd ): + params = util.Params( kwd ) + message = util.restore_text( params.get( 'message', '' ) ) + status = params.get( 'status', 'error' ) + webapp = params.get( 'webapp', 'community' ) + repository = get_repository( trans, repository_id ) + repo_dir = repository.repo_path + repo = hg.repository( get_configured_ui(), repo_dir ) + ctx = get_changectx_for_changeset( repo, changeset_revision ) + invalid_message = '' + if changeset_revision == repository.tip: + for root, dirs, files in os.walk( repo_dir ): + found = False + for name in files: + if name == tool_config: + tool_config_path = os.path.join( root, name ) + found = True + break + if found: + break + else: + for filename in ctx: + if filename == tool_config: + fctx = ctx[ filename ] + # Write the contents of datatypes_config.xml to a temporary file. + fh = tempfile.NamedTemporaryFile( 'w' ) + tool_config_path = fh.name + fh.close() + fh = open( tool_config_path, 'w' ) + fh.write( fctx.data() ) + fh.close() + break + metadata_dict, invalid_files = generate_metadata_for_repository_tip( trans, repository_id, ctx, changeset_revision, repo_dir ) + for invalid_file_tup in invalid_files: + invalid_tool_config, invalid_msg = invalid_file_tup + if tool_config == invalid_tool_config: + invalid_message = invalid_msg + break + tool, message = load_tool_from_changeset_revision( trans, repository_id, changeset_revision, tool_config_path ) + tool_state = self.__new_state( trans ) + is_malicious = change_set_is_malicious( trans, repository_id, repository.tip ) + if changeset_revision != repository.tip: + try: + os.unlink( tool_config_path ) + except: + pass + try: + if invalid_message: + message = invalid_message + return trans.fill_template( "/webapps/community/repository/tool_form.mako", + repository=repository, + changeset_revision=changeset_revision, + tool=tool, + tool_state=tool_state, + is_malicious=is_malicious, + webapp=webapp, + message=message, + status='error' ) + except Exception, e: + message = "This tool is invalid because: %s." % str( e ) + if webapp == 'galaxy': + return trans.response.send_redirect( web.url_for( controller='repository', + action='preview_tools_in_changeset', + repository_id=repository_id, + changeset_revision=changeset_revision, + message=message, + status='error' ) ) + return trans.response.send_redirect( web.url_for( controller='repository', + action='browse_repositories', + operation='view_or_manage_repository', + id=repository_id, + changeset_revision=changeset_revision, + message=message, + status='error' ) ) def __new_state( self, trans, all_pages=False ): """ Create a new `DefaultToolState` for this tool. It will not be initialized diff -r d774546032374648823f29aad4fb178086e169e4 -r 4ae471a236a381022d87779b033e49d2f8b321bd templates/base_panels.mako --- a/templates/base_panels.mako +++ b/templates/base_panels.mako @@ -84,6 +84,7 @@ $("iframe#galaxy_main").contents().find("body").find("div[class='errormessage']").text( msg ); } } + var uploads_in_progress = 0; jQuery( function() { $("iframe#galaxy_main").load( function() { $(this).contents().find("form").each( function() { @@ -134,7 +135,16 @@ $(this).append("<input type='hidden' name='ajax_upload' value='true'>"); } // iframe submit is required for nginx (otherwise the encoding is wrong) - $(this).ajaxSubmit( { iframe: true } ); + $(this).ajaxSubmit( { iframe: true, + complete: function (xhr, stat) { + uploads_in_progress--; + if (uploads_in_progress == 0) { + window.onbeforeunload = null; + } + } + } ); + uploads_in_progress++; + window.onbeforeunload = function() { return "Navigating away from the Galaxy analysis interface will interrupt the file upload(s) currently in progress. Do you really want to do this?"; } if ( $(this).find("input[name='folder_id']").val() != undefined ) { var library_id = $(this).find("input[name='library_id']").val(); var show_deleted = $(this).find("input[name='show_deleted']").val(); diff -r d774546032374648823f29aad4fb178086e169e4 -r 4ae471a236a381022d87779b033e49d2f8b321bd templates/webapps/community/admin/index.mako --- a/templates/webapps/community/admin/index.mako +++ b/templates/webapps/community/admin/index.mako @@ -55,6 +55,9 @@ <a target="galaxy_main" href="${h.url_for( controller='admin', action='browse_repositories', webapp='community' )}">Browse all repositories</a></div><div class="toolTitle"> + <a target="galaxy_main" href="${h.url_for( controller='admin', action='reset_all_repository_metadata', webapp='community' )}">Reset all metadata</a> + </div> + <div class="toolTitle"><a target="galaxy_main" href="${h.url_for( controller='admin', action='browse_repository_metadata', webapp='community' )}">Browse metadata</a></div></div> @@ -86,6 +89,12 @@ </div></div></div> + <div class="toolSectionTitle"> + Statistics + </div> + <div class="toolTitle"> + <a target="galaxy_main" href="${h.url_for( controller='admin', action='regenerate_statistics', webapp='community' )}">View shed statistics</a> + </div></div></div></div> diff -r d774546032374648823f29aad4fb178086e169e4 -r 4ae471a236a381022d87779b033e49d2f8b321bd templates/webapps/community/admin/statistics.mako --- /dev/null +++ b/templates/webapps/community/admin/statistics.mako @@ -0,0 +1,56 @@ +<%inherit file="/base.mako"/> +<%namespace file="/message.mako" import="render_msg" /> + +%if message: + ${render_msg( message, status )} +%endif + +<div class="toolForm"> + <div class="toolFormTitle">Tool shed statistics generated on ${trans.app.shed_counter.generation_time}</div> + <form name="regenerate_statistics" id="regenerate_statistics" action="${h.url_for( controller='admin', action='regenerate_statistics', webapp='community' )}" method="post" > + <div class="form-row"> + <table class="grid"> + <tr> + <th>Item</th> + <th>Count</th> + </tr> + <tr> + <td>Total repositories</td> + <td>${trans.app.shed_counter.repositories}</td> + </tr> + <tr> + <td>New repositories</td> + <td>${trans.app.shed_counter.new_repositories}</td> + </tr> + <tr> + <td>Deleted repositories</td> + <td>${trans.app.shed_counter.deleted_repositories}</td> + </tr> + <tr> + <td>Valid tools</td> + <td>${trans.app.shed_counter.valid_tools}</td> + </tr> + <tr> + <td>Invalid tools</td> + <td>${trans.app.shed_counter.invalid_tools}</td> + </tr> + <tr> + <td>Workflows</td> + <td>${trans.app.shed_counter.workflows}</td> + </tr> + <tr> + <td>Proprietary datatypes</td> + <td>${trans.app.shed_counter.proprietary_datatypes}</td> + </tr> + <tr> + <td>Total clones</td> + <td>${trans.app.shed_counter.total_clones}</td> + </tr> + </table> + </div> + <div class="form-row"> + <input type="submit" name="regenerate_statistics_button" value="Regenerate statistics"/> + </div> + </form> + </div> +</div> diff -r d774546032374648823f29aad4fb178086e169e4 -r 4ae471a236a381022d87779b033e49d2f8b321bd templates/webapps/community/index.mako --- a/templates/webapps/community/index.mako +++ b/templates/webapps/community/index.mako @@ -39,7 +39,7 @@ <%def name="left_panel()"><div class="unified-panel-header" unselectable="on"> - <div class='unified-panel-header-inner'>${trans.app.shed_counter.valid_tools} valid tools on ${trans.app.shed_counter.count_time}</div> + <div class='unified-panel-header-inner'>${trans.app.shed_counter.valid_tools} valid tools on ${trans.app.shed_counter.generation_time}</div></div><div class="page-container" style="padding: 10px;"><div class="toolMenu"> diff -r d774546032374648823f29aad4fb178086e169e4 -r 4ae471a236a381022d87779b033e49d2f8b321bd templates/webapps/community/repository/common.mako --- a/templates/webapps/community/repository/common.mako +++ b/templates/webapps/community/repository/common.mako @@ -95,7 +95,7 @@ <div class="form-row"><table width="100%"><tr bgcolor="#D8D8D8" width="100%"> - <td><b>Tools</b><i> - click the name to preview the tool and use the pop-up menu to inspect all metadata</i></td> + <td><b>Valid tools</b><i> - click the name to preview the tool and use the pop-up menu to inspect all metadata</i></td></tr></table></div> @@ -147,6 +147,31 @@ </div><div style="clear: both"></div> %endif + %if 'invalid_tools' in metadata: + <div class="form-row"> + <table width="100%"> + <tr bgcolor="#D8D8D8" width="100%"> + <td><b>Invalid tools</b><i> - click the tool config file name to see why the tool is invalid</i></td> + </tr> + </table> + </div> + <div style="clear: both"></div> + <div class="form-row"> + <% invalid_tool_configs = metadata[ 'invalid_tools' ] %> + <table class="grid"> + %for invalid_tool_config in invalid_tool_configs: + <tr> + <td> + <a class="view-info" href="${h.url_for( controller='repository', action='load_invalid_tool', repository_id=trans.security.encode_id( repository.id ), tool_config=invalid_tool_config, changeset_revision=changeset_revision, webapp=webapp )}"> + ${invalid_tool_config} + </a> + </td> + </tr> + %endfor + </table> + </div> + <div style="clear: both"></div> + %endif %if 'workflows' in metadata: ## metadata[ 'workflows' ] is a list of tuples where each contained tuple is ## [ <relative path to the .ga file in the repository>, <exported workflow dict> ] 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.