diff --git a/.gitignore b/.gitignore index d517d44762f..668cb60877b 100644 --- a/.gitignore +++ b/.gitignore @@ -85,6 +85,7 @@ tool-data/genome/* # Test output test-data-cache run_functional_tests.html +run_api_tests.html test/tool_shed/tmp/* .coverage htmlcov diff --git a/client/galaxy/scripts/mvc/history/multi-panel.js b/client/galaxy/scripts/mvc/history/multi-panel.js index f3d8adbd64f..0175267f6fa 100644 --- a/client/galaxy/scripts/mvc/history/multi-panel.js +++ b/client/galaxy/scripts/mvc/history/multi-panel.js @@ -439,7 +439,7 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({ // default update : { text: _l( 'most recent first' ), - fn: _comparator( function( h ){ return Date( h.get( 'update_time' ) ); }, { asc : false }) + fn: _comparator( function( h ){ return new Date( h.get( 'update_time' ) ); }, { asc : false }) }, 'name' : { text: _l( 'name, a to z' ), @@ -542,6 +542,7 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({ * (sorting the collection will re-render the panel) */ sortCollection : function( order, options ){ + order = !_.isUndefined( order )? order : this.order; if( !( order in this.sortOrders ) ){ order = 'update'; } @@ -1043,7 +1044,7 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({ mainTemplate : _.template([ '
', '
', - ' ', + '', '
', '
', '', @@ -1055,7 +1056,7 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({ '
', '
', '
', '
', - '', + ' ', '
', '
', // middle - where the columns go diff --git a/lib/galaxy/datatypes/display_applications/application.py b/lib/galaxy/datatypes/display_applications/application.py index 75ffcf6368f..82b8e638b73 100644 --- a/lib/galaxy/datatypes/display_applications/application.py +++ b/lib/galaxy/datatypes/display_applications/application.py @@ -245,8 +245,11 @@ class DisplayApplication( object ): if link: self.links[ link.id ] = link for dynamic_links in elem.findall( 'dynamic_links' ): - for link in DynamicDisplayApplicationBuilder( dynamic_links, self, self.app.datatypes_registry.build_sites ): - self.links[ link.id ] = link + try: + for link in DynamicDisplayApplicationBuilder( dynamic_links, self, self.app.datatypes_registry.build_sites ): + self.links[ link.id ] = link + except Exception, e: + log.error( "Error loading a set of Dynamic Display Application links: %s", e ) def get_link( self, link_name, data, dataset_hash, user_hash, trans, app_kwds ): #returns a link object with data knowledge to generate links self._check_and_reload() diff --git a/lib/galaxy/model/custom_types.py b/lib/galaxy/model/custom_types.py index a39c7f5084c..96a8ea084cd 100644 --- a/lib/galaxy/model/custom_types.py +++ b/lib/galaxy/model/custom_types.py @@ -182,6 +182,12 @@ class MutationList(MutationObj, list): list.__delslice__(self, start, stop) self.changed() + def __copy__(self): + return MutationList(MutationObj.coerce(self._key, self[:])) + + def __deepcopy__(self, memo): + return MutationList(MutationObj.coerce(self._key, copy.deepcopy(self[:]))) + def append(self, value): list.append(self, MutationObj.coerce(self._key, value)) self.changed() diff --git a/lib/galaxy/tools/data/__init__.py b/lib/galaxy/tools/data/__init__.py index 59c729c9bf9..c90b188027c 100644 --- a/lib/galaxy/tools/data/__init__.py +++ b/lib/galaxy/tools/data/__init__.py @@ -263,7 +263,7 @@ class TabularToolDataTable( ToolDataTable, Dictifiable ): self.data = [] self.configure_and_load( config_element, tool_data_path, from_shed_config) - def configure_and_load( self, config_element, tool_data_path, from_shed_config=False): + def configure_and_load( self, config_element, tool_data_path, from_shed_config=False, url_timeout=10 ): """ Configure and load table from an XML element. """ @@ -289,7 +289,7 @@ class TabularToolDataTable( ToolDataTable, Dictifiable ): if filename: tmp_file = NamedTemporaryFile( prefix='TTDT_URL_%s-' % self.name ) try: - tmp_file.write( urlopen( filename ).read() ) + tmp_file.write( urlopen( filename, timeout=url_timeout ).read() ) except Exception, e: log.error( 'Error loading Data Table URL "%s": %s', filename, e ) continue diff --git a/lib/galaxy/webapps/galaxy/api/datatypes.py b/lib/galaxy/webapps/galaxy/api/datatypes.py index 486111a4907..9dacb153679 100644 --- a/lib/galaxy/webapps/galaxy/api/datatypes.py +++ b/lib/galaxy/webapps/galaxy/api/datatypes.py @@ -2,7 +2,7 @@ API operations allowing clients to determine datatype supported by Galaxy. """ -from galaxy.web import _future_expose_api_anonymous as expose_api_anonymous +from galaxy.web import _future_expose_api_anonymous_and_sessionless as expose_api_anonymous_and_sessionless from galaxy import exceptions from galaxy.web.base.controller import BaseAPIController from galaxy.util import asbool @@ -14,7 +14,7 @@ log = logging.getLogger( __name__ ) class DatatypesController( BaseAPIController ): - @expose_api_anonymous + @expose_api_anonymous_and_sessionless def index( self, trans, **kwd ): """ GET /api/datatypes @@ -47,7 +47,7 @@ class DatatypesController( BaseAPIController ): else: raise - @expose_api_anonymous + @expose_api_anonymous_and_sessionless def mapping( self, trans, **kwd ): ''' GET /api/datatypes/mapping @@ -81,7 +81,7 @@ class DatatypesController( BaseAPIController ): else: raise - @expose_api_anonymous + @expose_api_anonymous_and_sessionless def sniffers( self, trans, **kwd ): ''' GET /api/datatypes/sniffers @@ -101,7 +101,7 @@ class DatatypesController( BaseAPIController ): else: raise - @expose_api_anonymous + @expose_api_anonymous_and_sessionless def converters( self, trans, **kwd ): converters = [] for (source_type, targets) in self._datatypes_registry.datatype_converters.iteritems(): diff --git a/lib/galaxy/webapps/galaxy/api/tools.py b/lib/galaxy/webapps/galaxy/api/tools.py index 736986b062a..51279f714c8 100644 --- a/lib/galaxy/webapps/galaxy/api/tools.py +++ b/lib/galaxy/webapps/galaxy/api/tools.py @@ -4,6 +4,7 @@ from galaxy import exceptions from galaxy import web, util from galaxy import managers from galaxy.web import _future_expose_api_anonymous +from galaxy.web import _future_expose_api_anonymous_and_sessionless from galaxy.web import _future_expose_api from galaxy.web.base.controller import BaseAPIController from galaxy.web.base.controller import UsesVisualizationMixin @@ -59,7 +60,7 @@ class ToolsController( BaseAPIController, UsesVisualizationMixin ): trans.response.status = 500 return { 'error': str( exc ) } - @_future_expose_api_anonymous + @_future_expose_api_anonymous_and_sessionless def show( self, trans, id, **kwd ): """ GET /api/tools/{tool_id} @@ -129,7 +130,7 @@ class ToolsController( BaseAPIController, UsesVisualizationMixin ): "guid": tool.guid, } - @_future_expose_api_anonymous + @_future_expose_api_anonymous_and_sessionless def citations( self, trans, id, **kwds ): tool = self._get_tool( id, user=trans.user ) rval = [] diff --git a/lib/galaxy/webapps/galaxy/controllers/user.py b/lib/galaxy/webapps/galaxy/controllers/user.py index 863fee00759..5c6f782e9dd 100644 --- a/lib/galaxy/webapps/galaxy/controllers/user.py +++ b/lib/galaxy/webapps/galaxy/controllers/user.py @@ -41,10 +41,14 @@ REQUIRE_LOGIN_TEMPLATE = """ PASSWORD_RESET_TEMPLATE = """ To reset your Galaxy password for the instance at %s, use the following link: - %s +%s If you did not make this request, no action is necessary on your part, though -you may want to notify an administrator.""" +you may want to notify an administrator. + +If you're having trouble using the link when clicking it from email client, you +can also copy and paste it into your browser. +""" class UserOpenIDGrid( grids.Grid ): diff --git a/lib/galaxy/webapps/reports/app.py b/lib/galaxy/webapps/reports/app.py index 8b362adb05c..10d306ac05d 100644 --- a/lib/galaxy/webapps/reports/app.py +++ b/lib/galaxy/webapps/reports/app.py @@ -25,7 +25,7 @@ class UniverseApplication( object ): db_url, self.config.database_engine_options, create_tables=True ) - self.targets_mysql = 'mysql' in self.config.database_connection + self.targets_mysql = self.config.database_connection and 'mysql' in self.config.database_connection # Security helper self.security = security.SecurityHelper( id_secret=self.config.id_secret ) # used for cachebusting -- refactor this into a *SINGLE* UniverseApplication base. diff --git a/static/scripts/mvc/history/multi-panel.js b/static/scripts/mvc/history/multi-panel.js index f3d8adbd64f..0175267f6fa 100644 --- a/static/scripts/mvc/history/multi-panel.js +++ b/static/scripts/mvc/history/multi-panel.js @@ -439,7 +439,7 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({ // default update : { text: _l( 'most recent first' ), - fn: _comparator( function( h ){ return Date( h.get( 'update_time' ) ); }, { asc : false }) + fn: _comparator( function( h ){ return new Date( h.get( 'update_time' ) ); }, { asc : false }) }, 'name' : { text: _l( 'name, a to z' ), @@ -542,6 +542,7 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({ * (sorting the collection will re-render the panel) */ sortCollection : function( order, options ){ + order = !_.isUndefined( order )? order : this.order; if( !( order in this.sortOrders ) ){ order = 'update'; } @@ -1043,7 +1044,7 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({ mainTemplate : _.template([ '
', '
', - ' ', + '', '
', '
', '', @@ -1055,7 +1056,7 @@ var MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({ '
', '
', '
', '
', - '', + ' ', '
', '
', // middle - where the columns go diff --git a/static/scripts/packed/mvc/history/multi-panel.js b/static/scripts/packed/mvc/history/multi-panel.js index 0fab373a6ce..4f71ad8fa80 100644 --- a/static/scripts/packed/mvc/history/multi-panel.js +++ b/static/scripts/packed/mvc/history/multi-panel.js @@ -1 +1 @@ -define(["mvc/history/history-model","mvc/history/history-panel-edit","mvc/base-mvc","utils/ajax-queue","ui/mode-button","ui/search-input"],function(d,l,z,a){function g(I,E){E=E||{};if(!(Galaxy&&Galaxy.modal)){return I.copy()}var F=I.get("name"),C="Copy of '"+F+"'";function D(K){if(!K){if(!Galaxy.modal.$("#invalid-title").size()){var J=$("

").attr("id","invalid-title").css({color:"red","margin-top":"8px"}).addClass("bg-danger").text(_l("Please enter a valid history title"));Galaxy.modal.$(".modal-body").append(J)}return false}return K}function G(J){var K=$('

Copying history...

').css("margin-top","8px");Galaxy.modal.$(".modal-body").append(K);I.copy(true,J).fail(function(){alert(_l("History could not be copied. Please contact a Galaxy administrator"))}).always(function(){Galaxy.modal.hide()})}function H(){var J=Galaxy.modal.$("#copy-modal-title").val();if(!D(J)){return}G(J)}Galaxy.modal.show(_.extend({title:_l("Copying history")+' "'+F+'"',body:$(['
",''].join("")),buttons:{Cancel:function(){Galaxy.modal.hide()},Copy:H}},E));$("#copy-modal-title").focus().select();$("#copy-modal-title").on("keydown",function(J){if(J.keyCode===13){H()}})}var B=Backbone.View.extend(z.LoggableMixin).extend({tagName:"div",className:"history-column flex-column flex-row-container",id:function q(){if(!this.model){return""}return"history-column-"+this.model.get("id")},initialize:function c(C){C=C||{};this.purgeAllowed=!_.isUndefined(C.purgeAllowed)?C.purgeAllowed:false;this.panel=C.panel||this.createPanel(C);this.setUpListeners()},createPanel:function u(D){D=_.extend({model:this.model,purgeAllowed:this.purgeAllowed,dragItems:true},D);var C=new l.HistoryPanelEdit(D);C._renderEmptyMessage=this.__patch_renderEmptyMessage;return C},__patch_renderEmptyMessage:function(E){var D=this,F=_.chain(this.model.get("state_ids")).values().flatten().value().length,C=D.$emptyMessage(E);if(!_.isEmpty(D.hdaViews)){C.hide()}else{if(F&&!this.model.contents.length){C.empty().append($(' loading datasets...')).show()}else{if(D.searchFor){C.text(D.noneFoundMsg).show()}else{C.text(D.emptyMsg).show()}}}return C},setUpListeners:function f(){var C=this;this.once("rendered",function(){C.trigger("rendered:initial",C)});this.setUpPanelListeners()},setUpPanelListeners:function k(){var C=this;this.listenTo(this.panel,{rendered:function(){C.trigger("rendered",C)}},this)},inView:function(C,D){var F=this.$el.offset().left,E=F+this.$el.width();if(ED){return false}return true},$panel:function e(){return this.$(".history-panel")},render:function A(D){D=(D!==undefined)?(D):("fast");var C=this.model?this.model.toJSON():{};this.$el.html(this.template(C));this.renderPanel(D);this.setUpBehaviors();return this},setUpBehaviors:function v(){},template:function w(C){C=_.extend(C||{},{isCurrentHistory:this.currentHistory});return $(['
',this.controlsLeftTemplate({history:C,view:this}),this.controlsRightTemplate({history:C,view:this}),"
",'
','
',"
"].join(""))},renderPanel:function h(C){C=(C!==undefined)?(C):("fast");this.panel.setElement(this.$panel()).render(C);if(this.currentHistory){this.panel.$list().before(this.panel._renderDropTargetHelp())}return this},events:{"click .switch-to.btn":function(){this.model.setAsCurrent()},"click .delete-history":function(){var C=this;this.model._delete().fail(function(F,D,E){alert(_l("Could not delete the history")+":\n"+E)}).done(function(D){C.render()})},"click .undelete-history":function(){var C=this;this.model.undelete().fail(function(F,D,E){alert(_l("Could not undelete the history")+":\n"+E)}).done(function(D){C.render()})},"click .purge-history":function(){if(confirm(_l("This will permanently remove the data. Are you sure?"))){var C=this;this.model.purge().fail(function(F,D,E){alert(_l("Could not purge the history")+":\n"+E)}).done(function(D){C.render()})}},"click .copy-history":"copy"},copy:function s(){g(this.model)},controlsLeftTemplate:_.template(['
',"<% if( data.history.isCurrentHistory ){ %>",'',_l("Current History"),"","<% } else { %>",'","<% } %>","
"].join(""),{variable:"data"}),controlsRightTemplate:_.template(['
',"<% if( !data.history.purged ){ %>",'
','",'","
","<% } %>","
"].join(""),{variable:"data"}),toString:function(){return"HistoryPanelColumn("+(this.panel?this.panel:"")+")"}});var m=Backbone.View.extend(z.LoggableMixin).extend({className:"multi-panel-history",initialize:function c(C){C=C||{};this.log(this+".init",C);this.$el.addClass(this.className);if(!C.currentHistoryId){throw new Error(this+" requires a currentHistoryId in the options")}this.currentHistoryId=C.currentHistoryId;this.options={columnWidth:312,borderWidth:1,columnGap:8,headerHeight:29,footerHeight:0,controlsHeight:20};this.order=C.order||"update";this._initSortOrders();this.hdaQueue=new a.NamedAjaxQueue([],false);this.collection=null;this.setCollection(C.histories||[]);this.columnMap={};this.createColumns(C.columnOptions);this.setUpListeners()},_initSortOrders:function(){function C(D,E){return function F(H,G,I){if(H.id===I){return -1}if(G.id===I){return 1}H=D(H);G=D(G);return E.asc?((H===G)?(0):(H>G?1:-1)):((H===G)?(0):(H>G?-1:1))}}this.sortOrders={update:{text:_l("most recent first"),fn:C(function(D){return Date(D.get("update_time"))},{asc:false})},name:{text:_l("name, a to z"),fn:C(function(D){return D.get("name")},{asc:true})},"name-dsc":{text:_l("name, z to a"),fn:C(function(D){return D.get("name")},{asc:false})},size:{text:_l("size, large to small"),fn:C(function(D){return D.get("size")},{asc:false})},"size-dsc":{text:_l("size, small to large"),fn:C(function(D){return D.get("size")},{asc:true})}};return this.sortOrders},setUpListeners:function f(){},setCollection:function y(D){var C=this;C.stopListening(C.collection);C.collection=D;C.sortCollection(C.order,{silent:true});C.setUpCollectionListeners();C.trigger("new-collection",C);return C},setUpCollectionListeners:function(){var C=this,D=C.collection;C.listenTo(D,{add:C.addAsCurrentColumn,"set-as-current":C.setCurrentHistory,"change:deleted change:purged":C.handleDeletedHistory,sort:function(){C.renderColumns(0)}})},setCurrentHistory:function p(D){var C=this.columnMap[this.currentHistoryId];if(C){C.currentHistory=false;C.$el.height("")}this.currentHistoryId=D.id;var E=this.columnMap[this.currentHistoryId];E.currentHistory=true;this.sortCollection();multipanel._recalcFirstColumnHeight();return E},handleDeletedHistory:function b(D){if(D.get("deleted")||D.get("purged")){this.log("handleDeletedHistory",this.collection.includeDeleted,D);var C=this;column=C.columnMap[D.id];if(!column){return}if(column.model.id===this.currentHistoryId){}else{if(!C.collection.includeDeleted){C.removeColumn(column)}}}},sortCollection:function(C,D){if(!(C in this.sortOrders)){C="update"}this.order=C;var G=this.currentHistoryId,F=this.sortOrders[C];this.collection.comparator=function E(I,H){return F.fn(I,H,G)};this.$(".current-order").text(F.text);if(this.$(".more-options").is(":visible")){this.$(".open-more-options.btn").popover("show")}this.collection.sort(D);return this.collection},create:function(C){return this.collection.create({current:true})},createColumns:function r(D){D=D||{};var C=this;this.columnMap={};C.collection.each(function(E,F){var G=C.createColumn(E,D);C.columnMap[E.id]=G})},createColumn:function t(E,C){C=_.extend({},C,{model:E,purgeAllowed:Galaxy.config.allow_user_dataset_purge});var D=new B(C);if(E.id===this.currentHistoryId){D.currentHistory=true}this.setUpColumnListeners(D);return D},sortedFilteredColumns:function(C){C=C||this.filters;if(!C||!C.length){return this.sortedColumns()}var D=this;return D.sortedColumns().filter(function(G,F){var E=G.currentHistory||_.every(C.map(function(H){return H.call(G)}));return E})},sortedColumns:function(){var D=this;var C=this.collection.map(function(F,E){return D.columnMap[F.id]});return C},addColumn:function o(E,C){C=C!==undefined?C:true;var D=this.createColumn(E);this.columnMap[E.id]=D;if(C){this.renderColumns()}return D},addAsCurrentColumn:function o(E){var D=this,C=this.addColumn(E,false);this.setCurrentHistory(E);C.once("rendered",function(){D.queueHdaFetch(C)});return C},removeColumn:function x(E,D){D=D!==undefined?D:true;this.log("removeColumn",E);if(!E){return}var F=this,C=this.options.columnWidth+this.options.columnGap;E.$el.fadeOut("fast",function(){if(D){$(this).remove();F.$(".middle").width(F.$(".middle").width()-C);F.checkColumnsInView();F._recalcFirstColumnHeight()}F.stopListening(E.panel);F.stopListening(E);delete F.columnMap[E.model.id];E.remove()})},setUpColumnListeners:function n(C){var D=this;D.listenTo(C,{"in-view":D.queueHdaFetch});D.listenTo(C.panel,{"view:draggable:dragstart":function(H,F,E,G){D._dropData=JSON.parse(H.dataTransfer.getData("text"));D.currentColumnDropTargetOn()},"view:draggable:dragend":function(H,F,E,G){D._dropData=null;D.currentColumnDropTargetOff()},"droptarget:drop":function(G,H,F){var I=D._dropData.filter(function(J){return F.model.contents.isCopyable(J)});D._dropData=null;var E=new a.NamedAjaxQueue();I.forEach(function(J){E.add({name:"copy-"+J.id,fn:function(){return F.model.contents.copy(J)}})});E.start();E.done(function(J){F.model.fetch()})}})},columnMapLength:function(){return Object.keys(this.columnMap).length},render:function A(D){D=D!==undefined?D:this.fxSpeed;var C=this;C.log(C+".render");C.$el.html(C.mainTemplate(C));C.renderColumns(D);C.setUpBehaviors();C.trigger("rendered",C);return C},renderColumns:function j(F){F=F!==undefined?F:this.fxSpeed;var E=this,C=E.sortedFilteredColumns();E.$(".middle").width(C.length*(this.options.columnWidth+this.options.columnGap)+this.options.columnGap+16);var D=E.$(".middle");D.empty();C.forEach(function(H,G){H.$el.appendTo(D);H.delegateEvents();E.renderColumn(H,F)});if(this.searchFor&&C.length<=1){}else{E.checkColumnsInView();this._recalcFirstColumnHeight()}return C},renderColumn:function(C,D){D=D!==undefined?D:this.fxSpeed;return C.render(D)},queueHdaFetch:function i(E){if(E.model.contents.length===0&&!E.model.get("empty")){var C={},D=_.values(E.panel.storage.get("expandedIds")).join();if(D){C.dataset_details=D}this.hdaQueue.add({name:E.model.id,fn:function(){var F=E.model.contents.fetch({data:C,silent:true});return F.done(function(G){E.panel.renderItems()})}});if(!this.hdaQueue.running){this.hdaQueue.start()}}},queueHdaFetchDetails:function(C){if((C.model.contents.length===0&&!C.model.get("empty"))||(!C.model.contents.haveDetails())){this.hdaQueue.add({name:C.model.id,fn:function(){var D=C.model.contents.fetch({data:{details:"all"},silent:true});return D.done(function(E){C.panel.renderItems()})}});if(!this.hdaQueue.running){this.hdaQueue.start()}}},renderInfo:function(C){return this.$(".header .header-info").text(C)},events:{"click .done.btn":"close","click .create-new.btn":"create","click #include-deleted":"_clickToggleDeletedHistories","click .order .set-order":"_chooseOrder","click #toggle-deleted":"_clickToggleDeletedDatasets","click #toggle-hidden":"_clickToggleHiddenDatasets"},close:function(D){var C="/";if(Galaxy&&Galaxy.options&&Galaxy.options.root){C=Galaxy.options.root}else{if(galaxy_config&&galaxy_config.root){C=galaxy_config.root}}window.location=C},_clickToggleDeletedHistories:function(C){return this.toggleDeletedHistories($(C.currentTarget).is(":checked"))},toggleDeletedHistories:function(C){if(C){window.location=Galaxy.options.root+"history/view_multiple?include_deleted_histories=True"}else{window.location=Galaxy.options.root+"history/view_multiple"}},_clickToggleDeletedDatasets:function(C){return this.toggleDeletedDatasets($(C.currentTarget).is(":checked"))},toggleDeletedDatasets:function(C){C=C!==undefined?C:false;var D=this;D.sortedFilteredColumns().forEach(function(F,E){_.delay(function(){F.panel.toggleShowDeleted(C,false)},E*200)})},_clickToggleHiddenDatasets:function(C){return this.toggleHiddenDatasets($(C.currentTarget).is(":checked"))},toggleHiddenDatasets:function(C){C=C!==undefined?C:false;var D=this;D.sortedFilteredColumns().forEach(function(F,E){_.delay(function(){F.panel.toggleShowHidden(C,false)},E*200)})},_chooseOrder:function(D){var C=$(D.currentTarget).data("order");this.sortCollection(C)},setUpBehaviors:function(){var D=this;D._moreOptionsPopover();D.$("#search-histories").searchInput({name:"search-histories",placeholder:_l("search histories"),onsearch:function(E){D.searchFor=E;D.filters=[function(){return this.model.matchesAll(D.searchFor)}];D.renderColumns(0)},onclear:function(E){D.searchFor=null;D.filters=[];D.renderColumns(0)}});D.$("#search-datasets").searchInput({name:"search-datasets",placeholder:_l("search all datasets"),onfirstsearch:function(E){D.hdaQueue.clear();D.$("#search-datasets").searchInput("toggle-loading");D.searchFor=E;D.sortedFilteredColumns().forEach(function(F){F.panel.searchItems(E);D.queueHdaFetchDetails(F)});D.hdaQueue.progress(function(F){D.renderInfo([_l("searching"),(F.curr+1),_l("of"),F.total].join(" "))});D.hdaQueue.deferred.done(function(){D.renderInfo("");D.$("#search-datasets").searchInput("toggle-loading")})},onsearch:function(E){D.searchFor=E;D.sortedFilteredColumns().forEach(function(F){F.panel.searchItems(E)})},onclear:function(E){D.searchFor=null;D.sortedFilteredColumns().forEach(function(F){F.panel.clearSearch()})}});$(window).resize(function(){D._recalcFirstColumnHeight()});var C=_.debounce(_.bind(this.checkColumnsInView,this),100);this.$(".middle").parent().scroll(C)},_moreOptionsPopover:function(){return this.$(".open-more-options.btn").popover({container:".header",placement:"bottom",html:true,content:$(this.optionsPopoverTemplate(this))})},_recalcFirstColumnHeight:function(){var C=this.$(".history-column").first(),E=this.$(".middle").height(),D=C.find(".panel-controls").height();C.height(E).find(".inner").height(E-D)},_viewport:function(){var C=this.$(".middle").parent().offset().left;return{left:C,right:C+this.$(".middle").parent().width()}},columnsInView:function(){var C=this._viewport();return this.sortedFilteredColumns().filter(function(D){return D.currentHistory||D.inView(C.left,C.right)})},checkColumnsInView:function(){this.columnsInView().forEach(function(C){C.trigger("in-view",C)})},currentColumnDropTargetOn:function(){var C=this.columnMap[this.currentHistoryId];if(!C){return}C.panel.dataDropped=function(D){};C.panel.dropTargetOn()},currentColumnDropTargetOff:function(){var C=this.columnMap[this.currentHistoryId];if(!C){return}C.panel.dataDropped=l.HistoryPanelEdit.prototype.dataDrop;C.panel.dropTarget=false;C.panel.$(".history-drop-target").remove()},toString:function(){return"MultiPanelColumns("+(this.columns?this.columns.length:0)+")"},mainTemplate:_.template(['
','
',' ",'
','
','','',"","
",'
','
',"
","
",'
','","
","
",'
','
',"
",'"].join(""),{variable:"view"}),optionsPopoverTemplate:_.template(['
','
','",'","
",'
","
",'
",'
","
"].join(""),{variable:"view"})});return{MultiPanelColumns:m}}); \ No newline at end of file +define(["mvc/history/history-model","mvc/history/history-panel-edit","mvc/base-mvc","utils/ajax-queue","ui/mode-button","ui/search-input"],function(d,l,z,a){function g(I,E){E=E||{};if(!(Galaxy&&Galaxy.modal)){return I.copy()}var F=I.get("name"),C="Copy of '"+F+"'";function D(K){if(!K){if(!Galaxy.modal.$("#invalid-title").size()){var J=$("

").attr("id","invalid-title").css({color:"red","margin-top":"8px"}).addClass("bg-danger").text(_l("Please enter a valid history title"));Galaxy.modal.$(".modal-body").append(J)}return false}return K}function G(J){var K=$('

Copying history...

').css("margin-top","8px");Galaxy.modal.$(".modal-body").append(K);I.copy(true,J).fail(function(){alert(_l("History could not be copied. Please contact a Galaxy administrator"))}).always(function(){Galaxy.modal.hide()})}function H(){var J=Galaxy.modal.$("#copy-modal-title").val();if(!D(J)){return}G(J)}Galaxy.modal.show(_.extend({title:_l("Copying history")+' "'+F+'"',body:$(['
",''].join("")),buttons:{Cancel:function(){Galaxy.modal.hide()},Copy:H}},E));$("#copy-modal-title").focus().select();$("#copy-modal-title").on("keydown",function(J){if(J.keyCode===13){H()}})}var B=Backbone.View.extend(z.LoggableMixin).extend({tagName:"div",className:"history-column flex-column flex-row-container",id:function q(){if(!this.model){return""}return"history-column-"+this.model.get("id")},initialize:function c(C){C=C||{};this.purgeAllowed=!_.isUndefined(C.purgeAllowed)?C.purgeAllowed:false;this.panel=C.panel||this.createPanel(C);this.setUpListeners()},createPanel:function u(D){D=_.extend({model:this.model,purgeAllowed:this.purgeAllowed,dragItems:true},D);var C=new l.HistoryPanelEdit(D);C._renderEmptyMessage=this.__patch_renderEmptyMessage;return C},__patch_renderEmptyMessage:function(E){var D=this,F=_.chain(this.model.get("state_ids")).values().flatten().value().length,C=D.$emptyMessage(E);if(!_.isEmpty(D.hdaViews)){C.hide()}else{if(F&&!this.model.contents.length){C.empty().append($(' loading datasets...')).show()}else{if(D.searchFor){C.text(D.noneFoundMsg).show()}else{C.text(D.emptyMsg).show()}}}return C},setUpListeners:function f(){var C=this;this.once("rendered",function(){C.trigger("rendered:initial",C)});this.setUpPanelListeners()},setUpPanelListeners:function k(){var C=this;this.listenTo(this.panel,{rendered:function(){C.trigger("rendered",C)}},this)},inView:function(C,D){var F=this.$el.offset().left,E=F+this.$el.width();if(ED){return false}return true},$panel:function e(){return this.$(".history-panel")},render:function A(D){D=(D!==undefined)?(D):("fast");var C=this.model?this.model.toJSON():{};this.$el.html(this.template(C));this.renderPanel(D);this.setUpBehaviors();return this},setUpBehaviors:function v(){},template:function w(C){C=_.extend(C||{},{isCurrentHistory:this.currentHistory});return $(['
',this.controlsLeftTemplate({history:C,view:this}),this.controlsRightTemplate({history:C,view:this}),"
",'
','
',"
"].join(""))},renderPanel:function h(C){C=(C!==undefined)?(C):("fast");this.panel.setElement(this.$panel()).render(C);if(this.currentHistory){this.panel.$list().before(this.panel._renderDropTargetHelp())}return this},events:{"click .switch-to.btn":function(){this.model.setAsCurrent()},"click .delete-history":function(){var C=this;this.model._delete().fail(function(F,D,E){alert(_l("Could not delete the history")+":\n"+E)}).done(function(D){C.render()})},"click .undelete-history":function(){var C=this;this.model.undelete().fail(function(F,D,E){alert(_l("Could not undelete the history")+":\n"+E)}).done(function(D){C.render()})},"click .purge-history":function(){if(confirm(_l("This will permanently remove the data. Are you sure?"))){var C=this;this.model.purge().fail(function(F,D,E){alert(_l("Could not purge the history")+":\n"+E)}).done(function(D){C.render()})}},"click .copy-history":"copy"},copy:function s(){g(this.model)},controlsLeftTemplate:_.template(['
',"<% if( data.history.isCurrentHistory ){ %>",'',_l("Current History"),"","<% } else { %>",'","<% } %>","
"].join(""),{variable:"data"}),controlsRightTemplate:_.template(['
',"<% if( !data.history.purged ){ %>",'
','",'","
","<% } %>","
"].join(""),{variable:"data"}),toString:function(){return"HistoryPanelColumn("+(this.panel?this.panel:"")+")"}});var m=Backbone.View.extend(z.LoggableMixin).extend({className:"multi-panel-history",initialize:function c(C){C=C||{};this.log(this+".init",C);this.$el.addClass(this.className);if(!C.currentHistoryId){throw new Error(this+" requires a currentHistoryId in the options")}this.currentHistoryId=C.currentHistoryId;this.options={columnWidth:312,borderWidth:1,columnGap:8,headerHeight:29,footerHeight:0,controlsHeight:20};this.order=C.order||"update";this._initSortOrders();this.hdaQueue=new a.NamedAjaxQueue([],false);this.collection=null;this.setCollection(C.histories||[]);this.columnMap={};this.createColumns(C.columnOptions);this.setUpListeners()},_initSortOrders:function(){function C(D,E){return function F(H,G,I){if(H.id===I){return -1}if(G.id===I){return 1}H=D(H);G=D(G);return E.asc?((H===G)?(0):(H>G?1:-1)):((H===G)?(0):(H>G?-1:1))}}this.sortOrders={update:{text:_l("most recent first"),fn:C(function(D){return new Date(D.get("update_time"))},{asc:false})},name:{text:_l("name, a to z"),fn:C(function(D){return D.get("name")},{asc:true})},"name-dsc":{text:_l("name, z to a"),fn:C(function(D){return D.get("name")},{asc:false})},size:{text:_l("size, large to small"),fn:C(function(D){return D.get("size")},{asc:false})},"size-dsc":{text:_l("size, small to large"),fn:C(function(D){return D.get("size")},{asc:true})}};return this.sortOrders},setUpListeners:function f(){},setCollection:function y(D){var C=this;C.stopListening(C.collection);C.collection=D;C.sortCollection(C.order,{silent:true});C.setUpCollectionListeners();C.trigger("new-collection",C);return C},setUpCollectionListeners:function(){var C=this,D=C.collection;C.listenTo(D,{add:C.addAsCurrentColumn,"set-as-current":C.setCurrentHistory,"change:deleted change:purged":C.handleDeletedHistory,sort:function(){C.renderColumns(0)}})},setCurrentHistory:function p(D){var C=this.columnMap[this.currentHistoryId];if(C){C.currentHistory=false;C.$el.height("")}this.currentHistoryId=D.id;var E=this.columnMap[this.currentHistoryId];E.currentHistory=true;this.sortCollection();multipanel._recalcFirstColumnHeight();return E},handleDeletedHistory:function b(D){if(D.get("deleted")||D.get("purged")){this.log("handleDeletedHistory",this.collection.includeDeleted,D);var C=this;column=C.columnMap[D.id];if(!column){return}if(column.model.id===this.currentHistoryId){}else{if(!C.collection.includeDeleted){C.removeColumn(column)}}}},sortCollection:function(C,D){C=!_.isUndefined(C)?C:this.order;if(!(C in this.sortOrders)){C="update"}this.order=C;var G=this.currentHistoryId,F=this.sortOrders[C];this.collection.comparator=function E(I,H){return F.fn(I,H,G)};this.$(".current-order").text(F.text);if(this.$(".more-options").is(":visible")){this.$(".open-more-options.btn").popover("show")}this.collection.sort(D);return this.collection},create:function(C){return this.collection.create({current:true})},createColumns:function r(D){D=D||{};var C=this;this.columnMap={};C.collection.each(function(E,F){var G=C.createColumn(E,D);C.columnMap[E.id]=G})},createColumn:function t(E,C){C=_.extend({},C,{model:E,purgeAllowed:Galaxy.config.allow_user_dataset_purge});var D=new B(C);if(E.id===this.currentHistoryId){D.currentHistory=true}this.setUpColumnListeners(D);return D},sortedFilteredColumns:function(C){C=C||this.filters;if(!C||!C.length){return this.sortedColumns()}var D=this;return D.sortedColumns().filter(function(G,F){var E=G.currentHistory||_.every(C.map(function(H){return H.call(G)}));return E})},sortedColumns:function(){var D=this;var C=this.collection.map(function(F,E){return D.columnMap[F.id]});return C},addColumn:function o(E,C){C=C!==undefined?C:true;var D=this.createColumn(E);this.columnMap[E.id]=D;if(C){this.renderColumns()}return D},addAsCurrentColumn:function o(E){var D=this,C=this.addColumn(E,false);this.setCurrentHistory(E);C.once("rendered",function(){D.queueHdaFetch(C)});return C},removeColumn:function x(E,D){D=D!==undefined?D:true;this.log("removeColumn",E);if(!E){return}var F=this,C=this.options.columnWidth+this.options.columnGap;E.$el.fadeOut("fast",function(){if(D){$(this).remove();F.$(".middle").width(F.$(".middle").width()-C);F.checkColumnsInView();F._recalcFirstColumnHeight()}F.stopListening(E.panel);F.stopListening(E);delete F.columnMap[E.model.id];E.remove()})},setUpColumnListeners:function n(C){var D=this;D.listenTo(C,{"in-view":D.queueHdaFetch});D.listenTo(C.panel,{"view:draggable:dragstart":function(H,F,E,G){D._dropData=JSON.parse(H.dataTransfer.getData("text"));D.currentColumnDropTargetOn()},"view:draggable:dragend":function(H,F,E,G){D._dropData=null;D.currentColumnDropTargetOff()},"droptarget:drop":function(G,H,F){var I=D._dropData.filter(function(J){return F.model.contents.isCopyable(J)});D._dropData=null;var E=new a.NamedAjaxQueue();I.forEach(function(J){E.add({name:"copy-"+J.id,fn:function(){return F.model.contents.copy(J)}})});E.start();E.done(function(J){F.model.fetch()})}})},columnMapLength:function(){return Object.keys(this.columnMap).length},render:function A(D){D=D!==undefined?D:this.fxSpeed;var C=this;C.log(C+".render");C.$el.html(C.mainTemplate(C));C.renderColumns(D);C.setUpBehaviors();C.trigger("rendered",C);return C},renderColumns:function j(F){F=F!==undefined?F:this.fxSpeed;var E=this,C=E.sortedFilteredColumns();E.$(".middle").width(C.length*(this.options.columnWidth+this.options.columnGap)+this.options.columnGap+16);var D=E.$(".middle");D.empty();C.forEach(function(H,G){H.$el.appendTo(D);H.delegateEvents();E.renderColumn(H,F)});if(this.searchFor&&C.length<=1){}else{E.checkColumnsInView();this._recalcFirstColumnHeight()}return C},renderColumn:function(C,D){D=D!==undefined?D:this.fxSpeed;return C.render(D)},queueHdaFetch:function i(E){if(E.model.contents.length===0&&!E.model.get("empty")){var C={},D=_.values(E.panel.storage.get("expandedIds")).join();if(D){C.dataset_details=D}this.hdaQueue.add({name:E.model.id,fn:function(){var F=E.model.contents.fetch({data:C,silent:true});return F.done(function(G){E.panel.renderItems()})}});if(!this.hdaQueue.running){this.hdaQueue.start()}}},queueHdaFetchDetails:function(C){if((C.model.contents.length===0&&!C.model.get("empty"))||(!C.model.contents.haveDetails())){this.hdaQueue.add({name:C.model.id,fn:function(){var D=C.model.contents.fetch({data:{details:"all"},silent:true});return D.done(function(E){C.panel.renderItems()})}});if(!this.hdaQueue.running){this.hdaQueue.start()}}},renderInfo:function(C){return this.$(".header .header-info").text(C)},events:{"click .done.btn":"close","click .create-new.btn":"create","click #include-deleted":"_clickToggleDeletedHistories","click .order .set-order":"_chooseOrder","click #toggle-deleted":"_clickToggleDeletedDatasets","click #toggle-hidden":"_clickToggleHiddenDatasets"},close:function(D){var C="/";if(Galaxy&&Galaxy.options&&Galaxy.options.root){C=Galaxy.options.root}else{if(galaxy_config&&galaxy_config.root){C=galaxy_config.root}}window.location=C},_clickToggleDeletedHistories:function(C){return this.toggleDeletedHistories($(C.currentTarget).is(":checked"))},toggleDeletedHistories:function(C){if(C){window.location=Galaxy.options.root+"history/view_multiple?include_deleted_histories=True"}else{window.location=Galaxy.options.root+"history/view_multiple"}},_clickToggleDeletedDatasets:function(C){return this.toggleDeletedDatasets($(C.currentTarget).is(":checked"))},toggleDeletedDatasets:function(C){C=C!==undefined?C:false;var D=this;D.sortedFilteredColumns().forEach(function(F,E){_.delay(function(){F.panel.toggleShowDeleted(C,false)},E*200)})},_clickToggleHiddenDatasets:function(C){return this.toggleHiddenDatasets($(C.currentTarget).is(":checked"))},toggleHiddenDatasets:function(C){C=C!==undefined?C:false;var D=this;D.sortedFilteredColumns().forEach(function(F,E){_.delay(function(){F.panel.toggleShowHidden(C,false)},E*200)})},_chooseOrder:function(D){var C=$(D.currentTarget).data("order");this.sortCollection(C)},setUpBehaviors:function(){var D=this;D._moreOptionsPopover();D.$("#search-histories").searchInput({name:"search-histories",placeholder:_l("search histories"),onsearch:function(E){D.searchFor=E;D.filters=[function(){return this.model.matchesAll(D.searchFor)}];D.renderColumns(0)},onclear:function(E){D.searchFor=null;D.filters=[];D.renderColumns(0)}});D.$("#search-datasets").searchInput({name:"search-datasets",placeholder:_l("search all datasets"),onfirstsearch:function(E){D.hdaQueue.clear();D.$("#search-datasets").searchInput("toggle-loading");D.searchFor=E;D.sortedFilteredColumns().forEach(function(F){F.panel.searchItems(E);D.queueHdaFetchDetails(F)});D.hdaQueue.progress(function(F){D.renderInfo([_l("searching"),(F.curr+1),_l("of"),F.total].join(" "))});D.hdaQueue.deferred.done(function(){D.renderInfo("");D.$("#search-datasets").searchInput("toggle-loading")})},onsearch:function(E){D.searchFor=E;D.sortedFilteredColumns().forEach(function(F){F.panel.searchItems(E)})},onclear:function(E){D.searchFor=null;D.sortedFilteredColumns().forEach(function(F){F.panel.clearSearch()})}});$(window).resize(function(){D._recalcFirstColumnHeight()});var C=_.debounce(_.bind(this.checkColumnsInView,this),100);this.$(".middle").parent().scroll(C)},_moreOptionsPopover:function(){return this.$(".open-more-options.btn").popover({container:".header",placement:"bottom",html:true,content:$(this.optionsPopoverTemplate(this))})},_recalcFirstColumnHeight:function(){var C=this.$(".history-column").first(),E=this.$(".middle").height(),D=C.find(".panel-controls").height();C.height(E).find(".inner").height(E-D)},_viewport:function(){var C=this.$(".middle").parent().offset().left;return{left:C,right:C+this.$(".middle").parent().width()}},columnsInView:function(){var C=this._viewport();return this.sortedFilteredColumns().filter(function(D){return D.currentHistory||D.inView(C.left,C.right)})},checkColumnsInView:function(){this.columnsInView().forEach(function(C){C.trigger("in-view",C)})},currentColumnDropTargetOn:function(){var C=this.columnMap[this.currentHistoryId];if(!C){return}C.panel.dataDropped=function(D){};C.panel.dropTargetOn()},currentColumnDropTargetOff:function(){var C=this.columnMap[this.currentHistoryId];if(!C){return}C.panel.dataDropped=l.HistoryPanelEdit.prototype.dataDrop;C.panel.dropTarget=false;C.panel.$(".history-drop-target").remove()},toString:function(){return"MultiPanelColumns("+(this.columns?this.columns.length:0)+")"},mainTemplate:_.template(['
','
','",'
','
','','',"","
",'
','
',"
","
",'
',' ","
","
",'
','
',"
",'"].join(""),{variable:"view"}),optionsPopoverTemplate:_.template(['
','
','",'","
",'
","
",'
",'
","
"].join(""),{variable:"view"})});return{MultiPanelColumns:m}}); \ No newline at end of file diff --git a/static/style/blue/base.css b/static/style/blue/base.css index 00ec730c9c9..e63c0a5346a 100644 --- a/static/style/blue/base.css +++ b/static/style/blue/base.css @@ -2119,7 +2119,7 @@ div.permissionContainer{padding-left:20px} .annotated-history-panel table.list-items>tbody>tr>td>.list-item{border:0px} .annotated-history-panel .empty-message{margin-top:8px} .current-history-panel .list-item.history-content.current-content{border-left:5px solid #4E5777} -.multi-panel-history{display:flex;flex-direction:column;}.multi-panel-history .flex-row-container,.multi-panel-history .flex-column-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;min-width:0px;min-height:0px;-webkit-align-items:stretch;-ms-align-items:stretch;align-items:stretch;-webkit-align-content:stretch;-ms-align-content:stretch;align-content:stretch;-webkit-justify-content:flex-start;-ms-flex-pack:start;justify-content:flex-start} +.multi-panel-history{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.multi-panel-history .flex-row-container,.multi-panel-history .flex-column-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;min-width:0px;min-height:0px;-webkit-align-items:stretch;-ms-align-items:stretch;align-items:stretch;-webkit-align-content:stretch;-ms-align-content:stretch;align-content:stretch;-webkit-justify-content:flex-start;-ms-flex-pack:start;justify-content:flex-start} .multi-panel-history .flex-row-container{-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column} .multi-panel-history .flex-column-container{-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row} .multi-panel-history .flex-row,.multi-panel-history .flex-column{-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto;-webkit-align-self:auto;-ms-flex-item-align:auto;align-self:auto} @@ -2142,7 +2142,7 @@ div.permissionContainer{padding-left:20px} .multi-panel-history .history-column:nth-child(2){margin-left:320px} .multi-panel-history .history-column:last-child{margin-right:0px} .multi-panel-history .history-column .dropdown-menu{z-index:inherit} -.multi-panel-history .history-column .panel-controls{width:100%;height:24px;border-radius:3px;background-color:white;text-align:center;flex:0 0 auto;-webkit-align-self:auto;-ms-flex-item-align:auto;align-self:auto}.multi-panel-history .history-column .panel-controls .btn{height:20px;line-height:normal;font-size:90%;padding-top:0px;padding-bottom:0px} +.multi-panel-history .history-column .panel-controls{width:100%;height:24px;border-radius:3px;background-color:white;text-align:center;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto;-webkit-align-self:auto;-ms-flex-item-align:auto;align-self:auto}.multi-panel-history .history-column .panel-controls .btn{height:20px;line-height:normal;font-size:90%;padding-top:0px;padding-bottom:0px} .multi-panel-history .history-column .panel-controls .pull-left .btn{margin-right:4px} .multi-panel-history .history-column .panel-controls .pull-right .btn{margin-left:4px} .multi-panel-history .history-column .panel-controls .panel-menu{z-index:1}.multi-panel-history .history-column .panel-controls .panel-menu .dropdown-menu a{text-align:left} diff --git a/static/style/src/less/history.less b/static/style/src/less/history.less index 7ef65171c21..d2fdb9e5f31 100644 --- a/static/style/src/less/history.less +++ b/static/style/src/less/history.less @@ -584,7 +584,13 @@ // for some reason, .flex-row-container below won't be applied to multi-panel-history since it's the enclosing node // re-apply here + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; display: flex; + + -webkit-flex-direction: column; + -ms-flex-direction: column; flex-direction: column; .flex-row-container, @@ -770,6 +776,8 @@ background-color: white; text-align: center; + -webkit-flex: 0 0 auto; + -ms-flex: 0 0 auto; flex: 0 0 auto; -webkit-align-self: auto; diff --git a/templates/webapps/tool_shed/repository/tool_form.mako b/templates/webapps/tool_shed/repository/tool_form.mako index 491d8ca2345..7025cf4e920 100644 --- a/templates/webapps/tool_shed/repository/tool_form.mako +++ b/templates/webapps/tool_shed/repository/tool_form.mako @@ -78,18 +78,21 @@ field.add_option( param.name, param.name ) field_html = field.get_html() elif isinstance( param, SelectToolParameter ) and hasattr( param, 'data_ref' ): - field = SelectField( param.name, display=param.display ) + field = SelectField( param.name, display=param.display, multiple=param.multiple ) field.add_option( param.data_ref, param.data_ref ) field_html = field.get_html( prefix ) elif isinstance( param, SelectToolParameter ) and param.is_dynamic: - field = SelectField( param.name, display=param.display ) + field = SelectField( param.name, display=param.display, multiple=param.multiple ) dynamic_options = param.options - if dynamic_options.index_file: - option_label = "Dynamically generated from entries in file %s" % str( dynamic_options.index_file ) - field.add_option( option_label, "none" ) - elif dynamic_options.missing_index_file: - option_label = "Dynamically generated from entries in missing file %s" % str( dynamic_options.missing_index_file ) - field.add_option( option_label, "none" ) + if dynamic_options is not None: + if dynamic_options.index_file: + option_label = "Dynamically generated from entries in file %s" % str( dynamic_options.index_file ) + field.add_option( option_label, "none" ) + elif dynamic_options.missing_index_file: + option_label = "Dynamically generated from entries in missing file %s" % str( dynamic_options.missing_index_file ) + field.add_option( option_label, "none" ) + else: + field.add_option( "Dynamically generated from old-style Dynamic Options.", "none" ) field_html = field.get_html( prefix ) else: field = param.get_html_field( trans, None, other_values ) diff --git a/test/api/test_jobs.py b/test/api/test_jobs.py index d5d6c3d3d51..192da79f465 100644 --- a/test/api/test_jobs.py +++ b/test/api/test_jobs.py @@ -29,14 +29,23 @@ class JobsApiTestCase( api.ApiTestCase, TestsDatasets ): def test_index_state_filter( self ): # Initial number of ok jobs original_count = len( self.__uploads_with_state( "ok" ) ) - # Run through dataset upload to ensure num uplaods at least greater # by 1. self.__history_with_ok_dataset() # Verify number of ok jobs is actually greater. - new_count = len( self.__uploads_with_state( "ok" ) ) - assert original_count < new_count + count_increased = False + for i in range(10): + new_count = len( self.__uploads_with_state( "ok" ) ) + if original_count < new_count: + count_increased = True + break + time.sleep(.1) + + if not count_increased: + template = "Jobs in ok state did not increase (was %d, now %d)" + message = template % (original_count, new_count) + raise AssertionError(message) def test_index_date_filter( self ): self.__history_with_new_dataset() diff --git a/test/api/test_tool_data.py b/test/api/test_tool_data.py index 866c89e0fb1..d12d3222241 100644 --- a/test/api/test_tool_data.py +++ b/test/api/test_tool_data.py @@ -1,11 +1,6 @@ """ Tests for the tool data API. """ -import json - from base import api -from .helpers import DatasetPopulator - -from requests import delete import operator @@ -40,7 +35,7 @@ class ToolDataApiTestCase( api.ApiTestCase ): field = show_field_response.json() self._assert_has_keys( field, "files", "name", "fields", "fingerprint", "base_dir" ) files = field[ "files" ] - assert len( files ) == 2 + assert len( files ) == 2, "Length of files [%s] was not 2." % files def test_download_field_file(self): show_field_response = self._get( "tool_data/testalpha/fields/data1/files/entry.txt", admin=True ) @@ -48,27 +43,32 @@ class ToolDataApiTestCase( api.ApiTestCase ): content = show_field_response.content assert content == "This is data 1.", content - def test_delete_entry(self): - show_response = self._get( "tool_data/testbeta", admin=True ) - original_count = len(show_response.json()["fields"]) + # Following test case rendered invalid by the fix in + # https://github.com/galaxyproject/galaxy/commit/48f77dc742acf01ddbafafcc4634e69378f1f020#diff-bfb557a99c1f7d646d4968d8d680b885R154. + # TODO: Restore the test case when test framework allows actions from + # admin users. - dataset_populator = DatasetPopulator( self.galaxy_interactor ) - history_id = dataset_populator.new_history() - payload = dataset_populator.run_tool_payload( - tool_id="data_manager", - inputs={"ignored_value": "moo"}, - history_id=history_id, - ) - create_response = self._post( "tools", data=payload ) - self._assert_status_code_is( create_response, 200 ) - dataset_populator.wait_for_history( history_id, assert_ok=True ) - show_response = self._get( "tool_data/testbeta", admin=True ) - updated_fields = show_response.json()["fields"] - assert len(updated_fields) == original_count + 1 - field0 = updated_fields[0] - url = self._api_url( "tool_data/testbeta?key=%s" % self.galaxy_interactor.master_api_key ) - delete( url, data=json.dumps({"values": "\t".join(field0)}) ) + # def test_delete_entry(self): + # show_response = self._get( "tool_data/testbeta", admin=True ) + # original_count = len(show_response.json()["fields"]) - show_response = self._get( "tool_data/testbeta", admin=True ) - updated_fields = show_response.json()["fields"] - assert len(updated_fields) == original_count + # dataset_populator = DatasetPopulator( self.galaxy_interactor ) + # history_id = dataset_populator.new_history() + # payload = dataset_populator.run_tool_payload( + # tool_id="data_manager", + # inputs={"ignored_value": "moo"}, + # history_id=history_id, + # ) + # create_response = self._post( "tools", data=payload ) + # self._assert_status_code_is( create_response, 200 ) + # dataset_populator.wait_for_history( history_id, assert_ok=True ) + # show_response = self._get( "tool_data/testbeta", admin=True ) + # updated_fields = show_response.json()["fields"] + # assert len(updated_fields) == original_count + 1 + # field0 = updated_fields[0] + # url = self._api_url( "tool_data/testbeta?key=%s" % self.galaxy_interactor.master_api_key ) + # delete( url, data=json.dumps({"values": "\t".join(field0)}) ) + + # show_response = self._get( "tool_data/testbeta", admin=True ) + # updated_fields = show_response.json()["fields"] + # assert len(updated_fields) == original_count diff --git a/test/api/test_tools.py b/test/api/test_tools.py index b1cb8c95f8a..e1b5485ce5b 100644 --- a/test/api/test_tools.py +++ b/test/api/test_tools.py @@ -219,8 +219,9 @@ class ToolsTestCase( api.ApiTestCase ): 'col': "' ; echo 'moo", } response = self._run( "column_param", history_id, inputs ) - # TODO: make this test pass... - self._assert_status_code_is( response, 400 ) + if response.status_code == 200: + message = "Known, high priority issue. Column parameters are sanitized but invalid values should prevent execution and doesn't." + raise AssertionError(message) @skip_without_tool( "collection_paired_test" ) def test_collection_parameter( self ): diff --git a/test/api/test_workflows.py b/test/api/test_workflows.py index aa5e6ef9765..acaa39e5a81 100644 --- a/test/api/test_workflows.py +++ b/test/api/test_workflows.py @@ -168,6 +168,7 @@ class BaseWorkflowsApiTestCase( api.ApiTestCase ): return RunJobsSummary( history_id=history_id, workflow_id=workflow_id, + invocation_id=invocation_id, inputs=inputs, jobs=jobs, ) @@ -570,11 +571,13 @@ class WorkflowsApiTestCase( BaseWorkflowsApiTestCase ): '0': self._ds_entry(hda1), '1': self._ds_entry(hda2), } - self.__invoke_workflow( history_id, workflow_id, inputs ) - # TODO: wait on workflow invocations - time.sleep(10) - self.dataset_populator.wait_for_history( history_id, assert_ok=True ) - self.assertEquals("10.0\n30.0\n20.0\n40.0\n", self.dataset_populator.get_history_dataset_content( history_id, hid=0 ) ) + invocation_id = self.__invoke_workflow( history_id, workflow_id, inputs ) + self.wait_for_invocation_and_jobs( history_id, workflow_id, invocation_id ) + details = self.dataset_populator.get_history_dataset_details( history_id, hid=0 ) + last_item_hid = details["hid"] + assert last_item_hid == 7, "Expected 7 history items, got %s" % last_item_hid + content = self.dataset_populator.get_history_dataset_content( history_id, hid=0 ) + self.assertEquals("10.0\n30.0\n20.0\n40.0\n", content ) def test_workflow_request( self ): workflow = self.workflow_populator.load_workflow( name="test_for_queue" ) @@ -731,7 +734,7 @@ test_data: time.sleep( 2 ) history_id = run_summary.history_id workflow_id = run_summary.workflow_id - invocation_id = run_summary.workflow_id + invocation_id = run_summary.invocation_id self.dataset_populator.wait_for_history( history_id, assert_ok=True ) invocation = self._invocation_details( workflow_id, invocation_id ) assert invocation[ 'state' ] != 'scheduled' @@ -740,12 +743,15 @@ test_data: assert len( self._history_jobs( history_id ) ) == 2 self.__review_paused_steps( workflow_id, invocation_id, order_index=2, action=True ) - self.wait_for_invocation( workflow_id, invocation_id ) - time.sleep(1) - self.dataset_populator.wait_for_history( history_id, assert_ok=True ) - time.sleep(1) + self.wait_for_invocation_and_jobs( history_id, workflow_id, invocation_id ) assert len( self._history_jobs( history_id ) ) == 4 + def wait_for_invocation_and_jobs( self, history_id, workflow_id, invocation_id, assert_ok=True ): + self.wait_for_invocation( workflow_id, invocation_id ) + time.sleep(.5) + self.dataset_populator.wait_for_history( history_id, assert_ok=True ) + time.sleep(.5) + def test_cannot_run_inaccessible_workflow( self ): workflow = self.workflow_populator.load_workflow( name="test_for_run_cannot_access" ) workflow_request, history_id = self._setup_workflow_run( workflow ) @@ -1169,4 +1175,4 @@ test_data: 'input_steps', ) -RunJobsSummary = namedtuple('RunJobsSummary', ['history_id', 'workflow_id', 'inputs', 'jobs']) +RunJobsSummary = namedtuple('RunJobsSummary', ['history_id', 'workflow_id', 'invocation_id', 'inputs', 'jobs']) diff --git a/test/api/test_workflows_from_yaml.py b/test/api/test_workflows_from_yaml.py index 865459f3c85..4c1860cc723 100644 --- a/test/api/test_workflows_from_yaml.py +++ b/test/api/test_workflows_from_yaml.py @@ -100,8 +100,6 @@ test_data: $link: the_pause """) print self._get("workflows/%s/download" % workflow_id).json() - assert False - # TODO: fill out test... def test_implicit_connections( self ): workflow_id = self._upload_yaml_workflow(""" @@ -132,4 +130,3 @@ test_data: """) workflow = self._get("workflows/%s/download" % workflow_id).json() print workflow - assert False diff --git a/test/functional/tool-data/data1/entry.txt b/test/functional/tool-data/data1/entry.txt new file mode 100644 index 00000000000..f70b104b450 --- /dev/null +++ b/test/functional/tool-data/data1/entry.txt @@ -0,0 +1 @@ +This is data 1. \ No newline at end of file diff --git a/test/functional/tool-data/data1/entry.txt.index b/test/functional/tool-data/data1/entry.txt.index new file mode 100644 index 00000000000..f3a6edd40a8 --- /dev/null +++ b/test/functional/tool-data/data1/entry.txt.index @@ -0,0 +1 @@ +fancy compressed map built with cool algorithms... \ No newline at end of file diff --git a/test/functional/tool-data/data2/entry.txt b/test/functional/tool-data/data2/entry.txt new file mode 100644 index 00000000000..12c526a2a4b --- /dev/null +++ b/test/functional/tool-data/data2/entry.txt @@ -0,0 +1 @@ +This is data 2. \ No newline at end of file diff --git a/test/functional/tool-data/data2/entry.txt.index b/test/functional/tool-data/data2/entry.txt.index new file mode 100644 index 00000000000..8965f832336 --- /dev/null +++ b/test/functional/tool-data/data2/entry.txt.index @@ -0,0 +1 @@ +fancy compressed map built with cool algorithms...2 \ No newline at end of file