mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Client-build: add the webpack task file, merge dev
This commit is contained in:
+1
-1
@@ -86,7 +86,7 @@ tool-data/genome/*
|
||||
tool-data/*.sample
|
||||
tool-data/testtoolshed.g2.bx.psu.edu/
|
||||
tool-data/toolshed.g2.bx.psu.edu/
|
||||
|
||||
tool-data/**/*.fa
|
||||
|
||||
# Test output
|
||||
test-data-cache
|
||||
|
||||
@@ -173,7 +173,7 @@ var Collection = Backbone.Collection.extend({
|
||||
if ( !Galaxy.user.id ){
|
||||
var userTab = {
|
||||
id : 'user',
|
||||
icon : 'fa-user',
|
||||
title : 'User',
|
||||
cls : 'loggedout-only',
|
||||
tooltip : 'Account registration or login',
|
||||
menu : [{
|
||||
@@ -191,7 +191,7 @@ var Collection = Backbone.Collection.extend({
|
||||
} else {
|
||||
var userTab = {
|
||||
id : 'user',
|
||||
icon : 'fa-user',
|
||||
title : 'User',
|
||||
cls : 'loggedin-only',
|
||||
tooltip : 'Account preferences and saved data',
|
||||
menu : [{
|
||||
@@ -243,77 +243,64 @@ var Collection = Backbone.Collection.extend({
|
||||
/** Masthead tab **/
|
||||
var Tab = Backbone.View.extend({
|
||||
initialize: function ( options ) {
|
||||
var self = this;
|
||||
this.model = options.model;
|
||||
this.setElement( this._template() );
|
||||
this.$dropdown = this.$( '.dropdown' );
|
||||
this.$toggle = this.$( '.dropdown-toggle' );
|
||||
this.$menu = this.$( '.dropdown-menu' );
|
||||
this.$note = this.$( '.dropdown-note' );
|
||||
this.model = options.model;
|
||||
this.$el.attr( 'id', this.model.id );
|
||||
this.model.on( 'init change:title', function() {
|
||||
this.get( 'title' ) && self.$toggle.html( this.get( 'title' ) );
|
||||
}).on( 'init change:visible', function() {
|
||||
self.$el.css( { visibility : this.get( 'visible' ) && 'visible' || 'hidden' } );
|
||||
}).on( 'init change:note', function() {
|
||||
self.$note.html( this.get( 'note' ) );
|
||||
}).on( 'init change:note_cls', function() {
|
||||
this._prevNoteCls && self.$note.removeClass( this._prevNoteCls );
|
||||
this.get( 'note_cls' ) && self.$note.addClass( this._prevNoteCls = this.get( 'note_cls' ) );
|
||||
}).on( 'init change:show_note', function() {
|
||||
self.$note.css( { 'display' : this.get( 'show_note' ) && 'block' || 'none' } );
|
||||
}).on( 'init change:target', function() {
|
||||
self.$toggle.attr( 'target', this.get( 'target' ) );
|
||||
}).on( 'init change:url', function() {
|
||||
this.set( 'url', self._formatUrl( this.get( 'url' ) ) );
|
||||
self.$toggle.attr( 'href', this.get( 'url' ) );
|
||||
}).on( 'init change:tooltip', function() {
|
||||
$( '.tooltip' ).remove();
|
||||
self.$toggle.tooltip( 'destroy' ).attr( 'title', this.get( 'tooltip' ) );
|
||||
this.get( 'tooltip' ) && self.$toggle.tooltip( { placement: 'bottom' } );
|
||||
}).on( 'init change:cls', function() {
|
||||
this._prevCls && self.$toggle.removeClass( this._prevCls );
|
||||
this.get( 'cls' ) && self.$toggle.addClass( this._prevCls = this.get( 'cls' ) );
|
||||
}).on( 'init change:icon', function() {
|
||||
this._prevIcon && self.$toggle.removeClass( this._prevIcon );
|
||||
this.get( 'icon' ) && self.$toggle.addClass( this._prevIcon = 'fa fa-2x ' + this.get( 'icon' ) );
|
||||
}).on( 'init change:toggle', function() {
|
||||
self.$toggle[ this.get( 'toggle' ) && 'addClass' || 'removeClass' ]( 'toggle' );
|
||||
}).on( 'init change:disabled', function() {
|
||||
self.$toggle[ this.get( 'disabled' ) && 'addClass' || 'removeClass' ]( 'disabled' );
|
||||
self._configurePopover();
|
||||
}).on( 'init change:active', function() {
|
||||
self.$dropdown[ this.get( 'active' ) && 'addClass' || 'removeClass' ]( 'active' );
|
||||
}).on( 'init change:show_menu', function() {
|
||||
if ( this.get( 'menu' ) && this.get( 'show_menu' ) ) {
|
||||
self.$menu.show();
|
||||
$( '#dd-helper' ).show().off().on( 'click', function() {
|
||||
$( '#dd-helper' ).hide();
|
||||
self.model.set( 'show_menu', false );
|
||||
});
|
||||
} else {
|
||||
self.$menu.hide();
|
||||
$( '#dd-helper' ).hide();
|
||||
}
|
||||
}).on( 'init change:menu', function() {
|
||||
self.$menu.empty().removeClass( 'dropdown-menu' );
|
||||
self.$toggle.find( 'b' ).remove();
|
||||
if ( this.get( 'menu' ) ) {
|
||||
_.each( this.get( 'menu' ), function( menuItem ) {
|
||||
self.$menu.append( self._buildMenuItem( menuItem ) );
|
||||
menuItem.divider && self.$menu.append( $( '<li/>' ).addClass( 'divider' ) );
|
||||
});
|
||||
self.$menu.addClass( 'dropdown-menu' );
|
||||
self.$toggle.append( $( '<b/>' ).addClass( 'caret' ) );
|
||||
}
|
||||
}).trigger( 'init' );
|
||||
this.listenTo( this.model, 'change', this.render, this );
|
||||
},
|
||||
|
||||
/** Attach events */
|
||||
events: {
|
||||
'click .dropdown-toggle' : '_toggleClick'
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var self = this;
|
||||
$( '.tooltip' ).remove();
|
||||
this.$el.attr( 'id', this.model.id )
|
||||
.css( { visibility : this.model.get( 'visible' ) && 'visible' || 'hidden' } );
|
||||
this.model.set( 'url', this._formatUrl( this.model.get( 'url' ) ) );
|
||||
this.$note.html( this.model.get( 'note' ) || '' )
|
||||
.removeClass().addClass( 'dropdown-note' )
|
||||
.addClass( this.model.get( 'note_cls' ) )
|
||||
.css( { 'display' : this.model.get( 'show_note' ) && 'block' || 'none' } )
|
||||
this.$toggle.html( this.model.get( 'title' ) || '' )
|
||||
.removeClass().addClass( 'dropdown-toggle' )
|
||||
.addClass( this.model.get( 'cls' ) )
|
||||
.addClass( this.model.get( 'icon' ) && 'fa fa-2x ' + this.model.get( 'icon' ) )
|
||||
.addClass( this.model.get( 'toggle' ) && 'toggle' )
|
||||
.attr( 'target', this.model.get( 'target' ) )
|
||||
.attr( 'href', this.model.get( 'url' ) )
|
||||
.attr( 'title', this.model.get( 'tooltip' ) )
|
||||
.tooltip( 'destroy' );
|
||||
this.model.get( 'tooltip' ) && this.$toggle.tooltip( { placement: 'bottom' } );
|
||||
this.$dropdown.removeClass().addClass( 'dropdown' )
|
||||
.addClass( this.model.get( 'disabled' ) && 'disabled' )
|
||||
.addClass( this.model.get( 'active' ) && 'active' );
|
||||
if ( this.model.get( 'menu' ) && this.model.get( 'show_menu' ) ) {
|
||||
this.$menu.show();
|
||||
$( '#dd-helper' ).show().off().on( 'click', function() {
|
||||
$( '#dd-helper' ).hide();
|
||||
self.model.set( 'show_menu', false );
|
||||
});
|
||||
} else {
|
||||
self.$menu.hide();
|
||||
$( '#dd-helper' ).hide();
|
||||
}
|
||||
this.$menu.empty().removeClass( 'dropdown-menu' );
|
||||
if ( this.model.get( 'menu' ) ) {
|
||||
_.each( this.model.get( 'menu' ), function( menuItem ) {
|
||||
self.$menu.append( self._buildMenuItem( menuItem ) );
|
||||
menuItem.divider && self.$menu.append( $( '<li/>' ).addClass( 'divider' ) );
|
||||
});
|
||||
self.$menu.addClass( 'dropdown-menu' );
|
||||
self.$toggle.append( $( '<b/>' ).addClass( 'caret' ) );
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
/** Add new menu item */
|
||||
_buildMenuItem: function ( options ) {
|
||||
var self = this;
|
||||
@@ -354,26 +341,21 @@ var Tab = Backbone.View.extend({
|
||||
} else {
|
||||
model.set( 'show_menu', true );
|
||||
}
|
||||
} else {
|
||||
function buildLink( label, url ) {
|
||||
return $( '<div/>' ).append( $( '<a/>' ).attr( 'href', Galaxy.root + url ).html( label ) ).html()
|
||||
}
|
||||
this.$toggle.popover && this.$toggle.popover( 'destroy' );
|
||||
this.$toggle.popover({
|
||||
html : true,
|
||||
placement : 'bottom',
|
||||
content : 'Please ' + buildLink( 'login', 'user/login?use_panels=True' ) + ' or ' +
|
||||
buildLink( 'register', 'user/create?use_panels=True' ) + ' to use this feature.'
|
||||
}).popover( 'show' );
|
||||
setTimeout( function() { self.$toggle.popover( 'destroy' ) }, 5000 );
|
||||
}
|
||||
},
|
||||
|
||||
/** Configures login notification/popover */
|
||||
_configurePopover: function() {
|
||||
var self = this;
|
||||
function buildLink( label, url ) {
|
||||
return $( '<div/>' ).append( $( '<a/>' ).attr( 'href', Galaxy.root + url ).html( label ) ).html()
|
||||
}
|
||||
this.$toggle.popover && this.$toggle.popover( 'destroy' );
|
||||
this.model.get( 'disabled' ) && this.$toggle.popover({
|
||||
html : true,
|
||||
placement : 'bottom',
|
||||
content : 'Please ' + buildLink( 'login', 'user/login?use_panels=True' ) + ' or ' +
|
||||
buildLink( 'register', 'user/create?use_panels=True' ) + ' to use this feature.'
|
||||
}).on( 'shown.bs.popover', function() {
|
||||
setTimeout( function() { self.$toggle.popover( 'hide' ) }, 5000 );
|
||||
});
|
||||
},
|
||||
|
||||
/** Url formatting */
|
||||
_formatUrl: function( url ) {
|
||||
return typeof url == 'string' && url.indexOf( '//' ) === -1 && url.charAt( 0 ) != '/' ? Galaxy.root + url : url;
|
||||
|
||||
@@ -4,6 +4,9 @@ define([
|
||||
'utils/add-logging',
|
||||
'utils/localization'
|
||||
], function( _, Backbone, addLogging, _l ){
|
||||
|
||||
'use strict';
|
||||
|
||||
//==============================================================================
|
||||
/** @class Mixin to add logging capabilities to an object.
|
||||
* Designed to allow switching an objects log output off/on at one central
|
||||
|
||||
@@ -4,7 +4,8 @@ define([
|
||||
"mvc/base-mvc",
|
||||
"utils/localization"
|
||||
], function( DC_LI, DATASET_LI_EDIT, BASE_MVC, _l ){
|
||||
/* global Backbone */
|
||||
|
||||
'use strict';
|
||||
//==============================================================================
|
||||
var DCListItemView = DC_LI.DCListItemView;
|
||||
/** @class Edit view for DatasetCollection.
|
||||
|
||||
@@ -4,7 +4,8 @@ define([
|
||||
"mvc/base-mvc",
|
||||
"utils/localization"
|
||||
], function( LIST_ITEM, DATASET_LI, BASE_MVC, _l ){
|
||||
/* global Backbone */
|
||||
|
||||
'use strict';
|
||||
//==============================================================================
|
||||
var FoldoutListItemView = LIST_ITEM.FoldoutListItemView,
|
||||
ListItemView = LIST_ITEM.ListItemView;
|
||||
@@ -33,11 +34,11 @@ var DCListItemView = FoldoutListItemView.extend(
|
||||
_setUpListeners : function(){
|
||||
FoldoutListItemView.prototype._setUpListeners.call( this );
|
||||
// re-rendering on deletion
|
||||
this.model.on( 'change', function( model, options ){
|
||||
this.listenTo( this.model, 'change', function( model, options ){
|
||||
if( _.isEqual( _.keys( model.changed ), [ 'deleted' ] ) ){
|
||||
this.render();
|
||||
}
|
||||
}, this );
|
||||
});
|
||||
},
|
||||
|
||||
// ......................................................................... rendering
|
||||
|
||||
@@ -4,6 +4,8 @@ define([
|
||||
"utils/localization"
|
||||
], function( DATASET_MODEL, BASE_MVC, _l ){
|
||||
|
||||
'use strict';
|
||||
|
||||
var logNamespace = 'collections';
|
||||
//==============================================================================
|
||||
/*
|
||||
|
||||
@@ -6,6 +6,8 @@ define([
|
||||
"utils/localization",
|
||||
"ui/editable-text",
|
||||
], function( DC_VIEW, DC_MODEL, DC_EDIT, BASE_MVC, _l ){
|
||||
|
||||
'use strict';
|
||||
/* =============================================================================
|
||||
TODO:
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ define([
|
||||
"utils/localization"
|
||||
], function( LIST_VIEW, DC_MODEL, DC_LI, BASE_MVC, _l ){
|
||||
|
||||
'use strict';
|
||||
|
||||
var logNamespace = 'collections';
|
||||
/* =============================================================================
|
||||
TODO:
|
||||
@@ -83,12 +85,14 @@ var CollectionView = _super.extend(
|
||||
_super.prototype._setUpItemViewListeners.call( panel, view );
|
||||
|
||||
// use pub-sub to: handle drilldown expansion and collapse
|
||||
view.on( 'expanded:drilldown', function( v, drilldown ){
|
||||
this._expandDrilldownPanel( drilldown );
|
||||
}, this );
|
||||
view.on( 'collapsed:drilldown', function( v, drilldown ){
|
||||
this._collapseDrilldownPanel( drilldown );
|
||||
}, this );
|
||||
panel.listenTo( view, {
|
||||
'expanded:drilldown': function( v, drilldown ){
|
||||
this._expandDrilldownPanel( drilldown );
|
||||
},
|
||||
'collapsed:drilldown': function( v, drilldown ){
|
||||
this._collapseDrilldownPanel( drilldown );
|
||||
}
|
||||
});
|
||||
return this;
|
||||
},
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ define([
|
||||
"ui/hoverhighlight"
|
||||
], function( HDCA, STATES, BASE_MVC, UI_MODAL, naturalSort, _l ){
|
||||
|
||||
'use strict';
|
||||
|
||||
var logNamespace = 'collections';
|
||||
/*==============================================================================
|
||||
TODO:
|
||||
@@ -1008,7 +1010,7 @@ var collectionCreatorModal = function _collectionCreatorModal( elements, options
|
||||
title : options.title || _l( 'Create a collection' ),
|
||||
body : creator.$el,
|
||||
width : '80%',
|
||||
height : 'min-content',
|
||||
height : '100%',
|
||||
closing_events: true
|
||||
});
|
||||
creator.render();
|
||||
|
||||
@@ -7,6 +7,8 @@ define([
|
||||
"ui/hoverhighlight"
|
||||
], function( levenshteinDistance, naturalSort, LIST_COLLECTION_CREATOR, baseMVC, _l ){
|
||||
|
||||
'use strict';
|
||||
|
||||
var logNamespace = 'collections';
|
||||
/* ============================================================================
|
||||
TODO:
|
||||
|
||||
@@ -5,6 +5,8 @@ define([
|
||||
"utils/localization"
|
||||
], function( LIST_CREATOR, HDCA, BASE_MVC, _l ){
|
||||
|
||||
'use strict';
|
||||
|
||||
var logNamespace = 'collections';
|
||||
/*==============================================================================
|
||||
TODO:
|
||||
|
||||
@@ -5,6 +5,7 @@ define([
|
||||
'mvc/base-mvc',
|
||||
'utils/localization'
|
||||
], function( DATASET, DATASET_LIST, MODAL, BASE_MVC, _l ){
|
||||
'use strict';
|
||||
|
||||
var logNamespace = 'dataset';
|
||||
/* ============================================================================
|
||||
|
||||
@@ -7,6 +7,8 @@ define([
|
||||
"mvc/base-mvc",
|
||||
"utils/localization"
|
||||
], function( STATES, DATASET_LI, TAGS, ANNOTATIONS, faIconButton, BASE_MVC, _l ){
|
||||
|
||||
'use strict';
|
||||
//==============================================================================
|
||||
var _super = DATASET_LI.DatasetListItemView;
|
||||
/** @class Editing view for DatasetAssociation.
|
||||
|
||||
@@ -5,7 +5,7 @@ define([
|
||||
"mvc/base-mvc",
|
||||
"utils/localization"
|
||||
], function( LIST_ITEM, STATES, faIconButton, BASE_MVC, _l ){
|
||||
/* global Backbone */
|
||||
'use strict';
|
||||
|
||||
var logNamespace = 'dataset';
|
||||
/*==============================================================================
|
||||
@@ -44,7 +44,7 @@ var DatasetListItemView = _super.extend(
|
||||
_super.prototype._setUpListeners.call( this );
|
||||
|
||||
// re-rendering on any model changes
|
||||
this.model.on( 'change', function( model, options ){
|
||||
this.listenTo( this.model, 'change', function( model, options ){
|
||||
// if the model moved into the ready state and is expanded without details, fetch those details now
|
||||
if( this.model.changedAttributes().state && this.model.inReadyState()
|
||||
&& this.expanded && !this.model.hasDetails() ){
|
||||
@@ -54,7 +54,7 @@ var DatasetListItemView = _super.extend(
|
||||
} else {
|
||||
this.render();
|
||||
}
|
||||
}, this );
|
||||
});
|
||||
},
|
||||
|
||||
// ......................................................................... expandable
|
||||
|
||||
@@ -4,6 +4,7 @@ define([
|
||||
"mvc/base-mvc",
|
||||
"utils/localization"
|
||||
], function( LIST_VIEW, DATASET_LI, BASE_MVC, _l ){
|
||||
'use strict';
|
||||
|
||||
var logNamespace = 'dataset';
|
||||
/* =============================================================================
|
||||
|
||||
@@ -3,6 +3,7 @@ define([
|
||||
"mvc/base-mvc",
|
||||
"utils/localization"
|
||||
], function( STATES, BASE_MVC, _l ){
|
||||
'use strict';
|
||||
|
||||
var logNamespace = 'dataset';
|
||||
//==============================================================================
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
define([
|
||||
], function(){
|
||||
|
||||
'use strict';
|
||||
//==============================================================================
|
||||
/** Map of possible HDA/collection/job states to their string equivalents.
|
||||
* A port of galaxy.model.Dataset.states.
|
||||
|
||||
@@ -31,14 +31,14 @@ define([ 'utils/utils' ], function( Utils ) {
|
||||
var dict = {};
|
||||
this._iterate( this.app.section.$el, dict );
|
||||
|
||||
// add to result dictionary
|
||||
// add to result dictionary, label elements
|
||||
var result_dict = {};
|
||||
this.flat_dict = {};
|
||||
function add( flat_id, input_id, input_value ) {
|
||||
self.flat_dict[ flat_id ] = input_id;
|
||||
result_dict[ flat_id ] = input_value;
|
||||
};
|
||||
|
||||
self.app.element_list[ input_id ] && self.app.element_list[ input_id ].$el.attr( 'tour_id', flat_id );
|
||||
}
|
||||
// converter between raw dictionary and job dictionary
|
||||
function convert( identifier, head ) {
|
||||
for ( var index in head ) {
|
||||
@@ -73,7 +73,7 @@ define([ 'utils/utils' ], function( Utils ) {
|
||||
break;
|
||||
case 'conditional':
|
||||
var value = self.app.field_list[ input.id ].value();
|
||||
add ( flat_id + '|' + input.test_param.name, input.id, value );
|
||||
add( flat_id + '|' + input.test_param.name, input.id, value );
|
||||
var selectedCase = matchCase( input, value );
|
||||
if ( selectedCase != -1 ) {
|
||||
convert( flat_id, head[ input.id + '-section-' + selectedCase ] );
|
||||
@@ -90,10 +90,10 @@ define([ 'utils/utils' ], function( Utils ) {
|
||||
if ( field.collapsed && input.collapsible_value ) {
|
||||
value = input.collapsible_value;
|
||||
}
|
||||
add ( flat_id, input.id, value );
|
||||
add( flat_id, input.id, value );
|
||||
if ( input.payload ) {
|
||||
for ( var p_id in input.payload ) {
|
||||
add ( p_id, input.id, input.payload[ p_id ] );
|
||||
add( p_id, input.id, input.payload[ p_id ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ define([], function() {
|
||||
/** Main Template
|
||||
*/
|
||||
_template: function(options) {
|
||||
var tmp = '<div class="ui-form-element input-name-' + options.name + '">' +
|
||||
var tmp = '<div class="ui-form-element">' +
|
||||
'<div class="ui-form-error ui-error">' +
|
||||
'<span class="fa fa-arrow-down"/><span class="ui-form-error-text"/>' +
|
||||
'</div>' +
|
||||
|
||||
@@ -179,14 +179,13 @@ define(['utils/utils',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// create input element
|
||||
var self = this;
|
||||
return new Ui.Input({
|
||||
id : 'field-' + input_def.id,
|
||||
area : input_def.area,
|
||||
onchange : function() {
|
||||
self.app.trigger('change');
|
||||
onchange : function( new_value ) {
|
||||
input_def.onchange ? input_def.onchange( new_value ) : self.app.trigger( 'change' );
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
@@ -5,9 +5,8 @@ define(['utils/utils', 'mvc/ui/ui-table', 'mvc/ui/ui-portlet', 'mvc/ui/ui-misc']
|
||||
/** This class creates a ui component which enables the dynamic creation of portlets
|
||||
*/
|
||||
var View = Backbone.View.extend({
|
||||
/** Initialize
|
||||
*/
|
||||
initialize : function(options) {
|
||||
var self = this;
|
||||
this.options = Utils.merge(options, {
|
||||
title : 'Section',
|
||||
empty_text : 'Not available.',
|
||||
@@ -15,13 +14,12 @@ var View = Backbone.View.extend({
|
||||
min : null
|
||||
});
|
||||
this.setElement('<div/>');
|
||||
var self = this;
|
||||
|
||||
// create button
|
||||
this.button_new = new Ui.ButtonIcon({
|
||||
icon : 'fa-plus',
|
||||
title : 'Insert ' + options.title_new,
|
||||
tooltip : 'Add new ' + options.title_new + ' block',
|
||||
title : 'Insert ' + this.options.title_new,
|
||||
tooltip : 'Add new ' + this.options.title_new + ' block',
|
||||
floating: 'clear',
|
||||
onclick : function() {
|
||||
if (options.onnew) {
|
||||
|
||||
@@ -190,7 +190,7 @@ define(['utils/utils', 'mvc/ui/ui-portlet', 'mvc/ui/ui-misc', 'mvc/form/form-sec
|
||||
});
|
||||
|
||||
// append message
|
||||
this.portlet.append(this.message.$el.addClass('ui-margin-top'));
|
||||
this.portlet.append(this.message.$el);
|
||||
|
||||
// append tool section
|
||||
this.portlet.append(this.section.$el);
|
||||
|
||||
@@ -3,7 +3,8 @@ define([
|
||||
"utils/localization"
|
||||
], function( MODAL, _l ){
|
||||
|
||||
"use strict";
|
||||
'use strict';
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
* A dialog/modal that allows copying a user history or 'importing' from user
|
||||
|
||||
@@ -4,6 +4,9 @@ define([
|
||||
"mvc/base-mvc",
|
||||
"utils/localization"
|
||||
], function( DATASET_LI_EDIT, HDA_LI, BASE_MVC, _l ){
|
||||
|
||||
'use strict';
|
||||
|
||||
//==============================================================================
|
||||
var _super = DATASET_LI_EDIT.DatasetListItemEdit;
|
||||
/** @class Editing view for HistoryDatasetAssociation.
|
||||
|
||||
@@ -3,7 +3,9 @@ define([
|
||||
"mvc/base-mvc",
|
||||
"utils/localization"
|
||||
], function( DATASET_LI, BASE_MVC, _l ){
|
||||
/* global Backbone */
|
||||
|
||||
'use strict';
|
||||
|
||||
//==============================================================================
|
||||
var _super = DATASET_LI.DatasetListItemView;
|
||||
/** @class Read only view for HistoryDatasetAssociation.
|
||||
|
||||
@@ -4,6 +4,9 @@ define([
|
||||
"mvc/base-mvc",
|
||||
"utils/localization"
|
||||
], function( DATASET, HISTORY_CONTENT, BASE_MVC, _l ){
|
||||
|
||||
'use strict';
|
||||
|
||||
//==============================================================================
|
||||
var _super = DATASET.DatasetAssociation,
|
||||
hcontentMixin = HISTORY_CONTENT.HistoryContentMixin;
|
||||
|
||||
@@ -4,6 +4,9 @@ define([
|
||||
"ui/fa-icon-button",
|
||||
"utils/localization"
|
||||
], function( HDCA_LI, DC_VIEW_EDIT, faIconButton, _l ){
|
||||
|
||||
'use strict';
|
||||
|
||||
//==============================================================================
|
||||
var _super = HDCA_LI.HDCAListItemView;
|
||||
/** @class Editing view for HistoryDatasetCollectionAssociation.
|
||||
|
||||
@@ -5,7 +5,9 @@ define([
|
||||
"mvc/base-mvc",
|
||||
"utils/localization"
|
||||
], function( STATES, DC_LI, DC_VIEW, BASE_MVC, _l ){
|
||||
/* global Backbone */
|
||||
|
||||
'use strict';
|
||||
|
||||
//==============================================================================
|
||||
var _super = DC_LI.DCListItemView;
|
||||
/** @class Read only view for HistoryDatasetCollectionAssociation (a dataset collection inside a history).
|
||||
@@ -22,9 +24,9 @@ var HDCAListItemView = _super.extend(
|
||||
_setUpListeners : function(){
|
||||
_super.prototype._setUpListeners.call( this );
|
||||
|
||||
this.model.on({
|
||||
this.listenTo( this.model, {
|
||||
'change:populated change:visible' : function( model, options ){ this.render(); },
|
||||
}, this );
|
||||
});
|
||||
},
|
||||
|
||||
/** Override to provide the proper collections panels as the foldout */
|
||||
|
||||
@@ -3,6 +3,9 @@ define([
|
||||
"mvc/history/history-content-model",
|
||||
"utils/localization"
|
||||
], function( DC_MODEL, HISTORY_CONTENT, _l ){
|
||||
|
||||
'use strict';
|
||||
|
||||
/*==============================================================================
|
||||
|
||||
Models for DatasetCollections contained within a history.
|
||||
|
||||
@@ -4,6 +4,8 @@ define([
|
||||
"utils/localization"
|
||||
], function( STATES, BASE_MVC, _l ){
|
||||
|
||||
'use strict';
|
||||
|
||||
var logNamespace = 'history';
|
||||
//==============================================================================
|
||||
/** How the type_id attribute is built for the history's mixed contents collection */
|
||||
|
||||
@@ -6,6 +6,8 @@ define([
|
||||
"utils/localization"
|
||||
], function( HISTORY_CONTENT, HDA_MODEL, HDCA_MODEL, BASE_MVC, _l ){
|
||||
|
||||
'use strict';
|
||||
|
||||
var logNamespace = 'history';
|
||||
//==============================================================================
|
||||
/** @class Backbone collection for history content.
|
||||
|
||||
@@ -6,6 +6,8 @@ define([
|
||||
"utils/localization"
|
||||
], function( HISTORY_CONTENTS, UTILS, BASE_MVC, _l ){
|
||||
|
||||
'use strict';
|
||||
|
||||
var logNamespace = 'history';
|
||||
//==============================================================================
|
||||
/** @class Model for a Galaxy history resource - both a record of user
|
||||
@@ -78,7 +80,7 @@ var History = Backbone.Model
|
||||
if( this.contents ){
|
||||
this.contents.historyId = newId;
|
||||
}
|
||||
}, this );
|
||||
});
|
||||
},
|
||||
|
||||
//TODO: see base-mvc
|
||||
@@ -540,7 +542,7 @@ var HistoryCollection = Backbone.Collection
|
||||
this.trigger( 'no-longer-current', oldCurrentId );
|
||||
this.currentHistoryId = history.id;
|
||||
}
|
||||
}, this );
|
||||
});
|
||||
},
|
||||
|
||||
/** override to allow passing options.order and setting the sort order to one of sortOrders */
|
||||
|
||||
@@ -9,6 +9,8 @@ define([
|
||||
'libs/d3'
|
||||
], function( JobDAG, JOB, JOB_LI, HISTORY_CONTENT, DATASET_LI, BASE_MVC, _l ){
|
||||
|
||||
'use strict';
|
||||
|
||||
var logNamespace = 'history';
|
||||
// ============================================================================
|
||||
/*
|
||||
@@ -157,8 +159,8 @@ var HistoryStructureComponent = Backbone.View.extend( BASE_MVC.LoggableMixin ).e
|
||||
|
||||
// create the bbone view for the job (to be positioned later accrd. to the layout) and cache
|
||||
var li = new view.JobItemClass({ model: job, tool: jobData.tool, jobData: jobData });
|
||||
li.on( 'expanding expanded collapsing collapsed', view.renderGraph, view );
|
||||
li.foldout.on( 'view:expanding view:expanded view:collapsing view:collapsed', view.renderGraph, view );
|
||||
view.listenTo( li, 'expanding expanded collapsing collapsed', view.renderGraph );
|
||||
view.listenTo( li.foldout, 'view:expanding view:expanded view:collapsing view:collapsed', view.renderGraph );
|
||||
return li;
|
||||
},
|
||||
|
||||
@@ -169,7 +171,7 @@ var HistoryStructureComponent = Backbone.View.extend( BASE_MVC.LoggableMixin ).e
|
||||
typeId = HISTORY_CONTENT.typeIdStr( content.history_content_type, content.id );
|
||||
content = view.model.contents.get( typeId );
|
||||
var li = new view.ContentItemClass({ model: content });
|
||||
li.on( 'expanding expanded collapsing collapsed', view.renderGraph, view );
|
||||
view.listenTo( li, 'expanding expanded collapsing collapsed', view.renderGraph );
|
||||
return li;
|
||||
},
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@ define([
|
||||
"mvc/base-mvc",
|
||||
"utils/localization"
|
||||
], function( HISTORY_VIEW, HDA_LI, HDCA_LI, BASE_MVC, _l ){
|
||||
|
||||
'use strict';
|
||||
|
||||
/* =============================================================================
|
||||
TODO:
|
||||
|
||||
|
||||
@@ -4,6 +4,9 @@ define([
|
||||
"mvc/base-mvc",
|
||||
"utils/localization"
|
||||
], function( HISTORY_MODEL, HISTORY_VIEW_EDIT, BASE_MVC, _l ){
|
||||
|
||||
'use strict';
|
||||
|
||||
// ============================================================================
|
||||
/** session storage for history panel preferences (and to maintain state)
|
||||
*/
|
||||
@@ -158,12 +161,12 @@ var CurrentHistoryView = _super.extend(
|
||||
//TODO:?? may not be needed? see history-view-edit, 369
|
||||
// if a hidden item is created (gen. by a workflow), moves thru the updater to the ready state,
|
||||
// then: remove it from the collection if the panel is set to NOT show hidden datasets
|
||||
this.collection.on( 'state:ready', function( model, newState, oldState ){
|
||||
this.listenTo( this.collection, 'state:ready', function( model, newState, oldState ){
|
||||
if( ( !model.get( 'visible' ) )
|
||||
&& ( !this.storage.get( 'show_hidden' ) ) ){
|
||||
this.removeItemView( model );
|
||||
}
|
||||
}, this );
|
||||
});
|
||||
},
|
||||
|
||||
/** listening for history events */
|
||||
@@ -257,27 +260,28 @@ var CurrentHistoryView = _super.extend(
|
||||
_renderTags : function( $where ){
|
||||
var panel = this;
|
||||
// render tags and show/hide based on preferences
|
||||
_super.prototype._renderTags.call( this, $where );
|
||||
if( this.preferences.get( 'tagsEditorShown' ) ){
|
||||
this.tagsEditor.toggle( true );
|
||||
_super.prototype._renderTags.call( panel, $where );
|
||||
if( panel.preferences.get( 'tagsEditorShown' ) ){
|
||||
panel.tagsEditor.toggle( true );
|
||||
}
|
||||
// store preference when shown or hidden
|
||||
this.tagsEditor.on( 'hiddenUntilActivated:shown hiddenUntilActivated:hidden',
|
||||
panel.listenTo( panel.tagsEditor, 'hiddenUntilActivated:shown hiddenUntilActivated:hidden',
|
||||
function( tagsEditor ){
|
||||
panel.preferences.set( 'tagsEditorShown', tagsEditor.hidden );
|
||||
});
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
/** In this override, get and set current panel preferences when editor is used */
|
||||
_renderAnnotation : function( $where ){
|
||||
var panel = this;
|
||||
// render annotation and show/hide based on preferences
|
||||
_super.prototype._renderAnnotation.call( this, $where );
|
||||
if( this.preferences.get( 'annotationEditorShown' ) ){
|
||||
this.annotationEditor.toggle( true );
|
||||
_super.prototype._renderAnnotation.call( panel, $where );
|
||||
if( panel.preferences.get( 'annotationEditorShown' ) ){
|
||||
panel.annotationEditor.toggle( true );
|
||||
}
|
||||
// store preference when shown or hidden
|
||||
this.annotationEditor.on( 'hiddenUntilActivated:shown hiddenUntilActivated:hidden',
|
||||
panel.listenTo( panel.annotationEditor, 'hiddenUntilActivated:shown hiddenUntilActivated:hidden',
|
||||
function( annotationEditor ){
|
||||
panel.preferences.set( 'annotationEditorShown', annotationEditor.hidden );
|
||||
}
|
||||
@@ -325,12 +329,12 @@ var CurrentHistoryView = _super.extend(
|
||||
_super.prototype._setUpItemViewListeners.call( panel, view );
|
||||
|
||||
// use pub-sub to: handle drilldown expansion and collapse
|
||||
view.on( 'expanded:drilldown', function( v, drilldown ){
|
||||
panel.listenTo( view, 'expanded:drilldown', function( v, drilldown ){
|
||||
this._expandDrilldownPanel( drilldown );
|
||||
}, this );
|
||||
view.on( 'collapsed:drilldown', function( v, drilldown ){
|
||||
});
|
||||
panel.listenTo( view, 'collapsed:drilldown', function( v, drilldown ){
|
||||
this._collapseDrilldownPanel( drilldown );
|
||||
}, this );
|
||||
});
|
||||
|
||||
// when content is manipulated, make it the current-content
|
||||
// view.on( 'visualize', function( v, ev ){
|
||||
@@ -376,7 +380,7 @@ var CurrentHistoryView = _super.extend(
|
||||
// ........................................................................ external objects/MVC
|
||||
listenToGalaxy : function( galaxy ){
|
||||
// TODO: MEM: questionable reference island / closure practice
|
||||
galaxy.on( 'galaxy_main:load', function( data ){
|
||||
this.listenTo( galaxy, 'galaxy_main:load', function( data ){
|
||||
var pathToMatch = data.fullpath,
|
||||
useToURLRegexMap = {
|
||||
'display' : /datasets\/([a-f0-9]+)\/display/,
|
||||
@@ -401,7 +405,7 @@ var CurrentHistoryView = _super.extend(
|
||||
// need to type mangle to go from web route to history contents
|
||||
hdaId = 'dataset-' + hdaId;
|
||||
this._setCurrentContentById( hdaId );
|
||||
}, this );
|
||||
});
|
||||
},
|
||||
|
||||
//TODO: remove quota meter from panel and remove this
|
||||
|
||||
@@ -30,6 +30,9 @@ define([
|
||||
PopupMenu,
|
||||
_l
|
||||
){
|
||||
|
||||
'use strict';
|
||||
|
||||
/* =============================================================================
|
||||
TODO:
|
||||
|
||||
@@ -90,7 +93,7 @@ var HistoryViewEdit = _super.extend(
|
||||
});
|
||||
panel.on( 'view:attached view:removed', function(){
|
||||
panel._renderCounts();
|
||||
}, panel );
|
||||
});
|
||||
},
|
||||
|
||||
// ------------------------------------------------------------------------ listeners
|
||||
@@ -98,19 +101,21 @@ var HistoryViewEdit = _super.extend(
|
||||
_setUpCollectionListeners : function(){
|
||||
_super.prototype._setUpCollectionListeners.call( this );
|
||||
|
||||
this.collection.on( 'change:deleted', this._handleHdaDeletionChange, this );
|
||||
this.collection.on( 'change:visible', this._handleHdaVisibleChange, this );
|
||||
this.collection.on( 'change:purged', function( model ){
|
||||
// hafta get the new nice-size w/o the purged model
|
||||
this.model.fetch();
|
||||
}, this );
|
||||
this.listenTo( this.collection, {
|
||||
'change:deleted': this._handleHdaDeletionChange,
|
||||
'change:visible': this._handleHdaVisibleChange,
|
||||
'change:purged' : function( model ){
|
||||
// hafta get the new nice-size w/o the purged model
|
||||
this.model.fetch();
|
||||
}
|
||||
});
|
||||
return this;
|
||||
},
|
||||
|
||||
/** listening for history and HDA events */
|
||||
_setUpModelListeners : function(){
|
||||
_super.prototype._setUpModelListeners.call( this );
|
||||
this.model.on( 'change:size', this.updateHistoryDiskSize, this );
|
||||
this.listenTo( this.model, 'change:size', this.updateHistoryDiskSize );
|
||||
return this;
|
||||
},
|
||||
|
||||
@@ -497,16 +502,14 @@ var HistoryViewEdit = _super.extend(
|
||||
},
|
||||
/** */
|
||||
drop : function( ev ){
|
||||
//console.warn( 'dataTransfer:', ev.dataTransfer.getData( 'text' ) );
|
||||
//console.warn( 'dataTransfer:', ev.originalEvent.dataTransfer.getData( 'text' ) );
|
||||
ev.preventDefault();
|
||||
//ev.stopPropagation();
|
||||
ev.dataTransfer.dropEffect = 'move';
|
||||
|
||||
//console.debug( 'ev.dataTransfer:', ev.dataTransfer );
|
||||
var dataTransfer = ev.originalEvent.dataTransfer;
|
||||
dataTransfer.dropEffect = 'move';
|
||||
|
||||
var panel = this,
|
||||
data = ev.dataTransfer.getData( "text" );
|
||||
data = dataTransfer.getData( "text" );
|
||||
try {
|
||||
data = JSON.parse( data );
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@ define([
|
||||
_l
|
||||
){
|
||||
|
||||
'use strict';
|
||||
|
||||
var logNamespace = 'history';
|
||||
|
||||
// ============================================================================
|
||||
@@ -377,11 +379,13 @@ var HistoryView = _super.extend(
|
||||
|
||||
//TODO:?? could use 'view:expanded' here?
|
||||
// maintain a list of items whose bodies are expanded
|
||||
view.on( 'expanded', function( v ){
|
||||
panel.storage.addExpanded( v.model );
|
||||
});
|
||||
view.on( 'collapsed', function( v ){
|
||||
panel.storage.removeExpanded( v.model );
|
||||
panel.listenTo( view, {
|
||||
'expanded': function( v ){
|
||||
panel.storage.addExpanded( v.model );
|
||||
},
|
||||
'collapsed': function( v ){
|
||||
panel.storage.removeExpanded( v.model );
|
||||
}
|
||||
});
|
||||
return this;
|
||||
},
|
||||
|
||||
@@ -2,6 +2,9 @@ define([
|
||||
'utils/graph',
|
||||
'utils/add-logging'
|
||||
],function( GRAPH, addLogging ){
|
||||
|
||||
'use strict';
|
||||
|
||||
// ============================================================================
|
||||
var _super = GRAPH.Graph;
|
||||
/** A Directed acyclic Graph built from a history's job data.
|
||||
|
||||
@@ -8,6 +8,8 @@ define([
|
||||
"ui/search-input"
|
||||
], function( HISTORY_MODEL, HISTORY_VIEW_EDIT, historyCopyDialog, baseMVC, ajaxQueue ){
|
||||
|
||||
'use strict';
|
||||
|
||||
var logNamespace = 'history';
|
||||
/* ==============================================================================
|
||||
TODO:
|
||||
|
||||
@@ -5,7 +5,8 @@ define([
|
||||
"utils/localization"
|
||||
], function( PopupMenu, historyCopyDialog, BASE_MVC, _l ){
|
||||
|
||||
"use strict";
|
||||
'use strict';
|
||||
|
||||
// ============================================================================
|
||||
var menu = [
|
||||
{
|
||||
|
||||
@@ -550,7 +550,11 @@ var FolderToolbarView = Backbone.View.extend({
|
||||
},
|
||||
error: function(model, response){
|
||||
if (typeof response.responseJSON !== "undefined"){
|
||||
mod_toastr.error(response.responseJSON.err_msg);
|
||||
if (response.responseJSON.err_code === 404001){
|
||||
mod_toastr.warning(response.responseJSON.err_msg);
|
||||
} else{
|
||||
mod_toastr.error(response.responseJSON.err_msg);
|
||||
}
|
||||
} else {
|
||||
mod_toastr.error('An error ocurred.');
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ define([
|
||||
'utils/localization'
|
||||
], function( BASE_MVC, _l ){
|
||||
|
||||
'use strict';
|
||||
|
||||
var logNamespace = 'list';
|
||||
//==============================================================================
|
||||
/** A view which, when first rendered, shows only summary data/attributes, but
|
||||
@@ -475,7 +477,7 @@ var FoldoutListItemView = ListItemView.extend({
|
||||
_expandByDrilldown : function(){
|
||||
var view = this;
|
||||
// attachment and rendering done by listener
|
||||
view.foldout.on( 'close', function(){
|
||||
view.listenTo( view.foldout, 'close', function(){
|
||||
view.trigger( 'collapsed:drilldown', view, view.foldout );
|
||||
});
|
||||
view.trigger( 'expanded:drilldown', view, view.foldout );
|
||||
|
||||
@@ -6,6 +6,8 @@ define([
|
||||
"ui/search-input"
|
||||
], function( LIST_ITEM, LoadingIndicator, BASE_MVC, _l ){
|
||||
|
||||
'use strict';
|
||||
|
||||
var logNamespace = 'list';
|
||||
/* ============================================================================
|
||||
TODO:
|
||||
@@ -120,29 +122,30 @@ var ListPanel = Backbone.View.extend( BASE_MVC.LoggableMixin ).extend(/** @lends
|
||||
|
||||
//TODO: move errorHandler down into list-view from history-view or
|
||||
// pass to global error handler (Galaxy)
|
||||
this.on( 'error', function( model, xhr, options, msg, details ){
|
||||
//this.errorHandler( model, xhr, options, msg, details );
|
||||
console.error( model, xhr, options, msg, details );
|
||||
}, this );
|
||||
|
||||
// show hide the loading indicator
|
||||
this.on( 'loading', function(){
|
||||
this._showLoadingIndicator( 'loading...', 40 );
|
||||
}, this );
|
||||
this.on( 'loading-done', function(){
|
||||
this._hideLoadingIndicator( 40 );
|
||||
}, this );
|
||||
this.on({
|
||||
error: function( model, xhr, options, msg, details ){
|
||||
//this.errorHandler( model, xhr, options, msg, details );
|
||||
console.error( model, xhr, options, msg, details );
|
||||
},
|
||||
// show hide the loading indicator
|
||||
loading: function(){
|
||||
this._showLoadingIndicator( 'loading...', 40 );
|
||||
},
|
||||
'loading-done': function(){
|
||||
this._hideLoadingIndicator( 40 );
|
||||
},
|
||||
});
|
||||
|
||||
// throw the first render up as a diff namespace using once (for outside consumption)
|
||||
this.once( 'rendered', function(){
|
||||
this.trigger( 'rendered:initial', this );
|
||||
}, this );
|
||||
});
|
||||
|
||||
// debugging
|
||||
if( this.logger ){
|
||||
this.on( 'all', function( event ){
|
||||
this.log( this + '', arguments );
|
||||
}, this );
|
||||
});
|
||||
}
|
||||
|
||||
this._setUpCollectionListeners();
|
||||
@@ -156,21 +159,22 @@ var ListPanel = Backbone.View.extend( BASE_MVC.LoggableMixin ).extend(/** @lends
|
||||
this.collection.off();
|
||||
|
||||
// bubble up error events
|
||||
this.collection.on( 'error', function( model, xhr, options, msg, details ){
|
||||
this.trigger( 'error', model, xhr, options, msg, details );
|
||||
}, this );
|
||||
|
||||
this.collection.on( 'reset', function(){
|
||||
this.renderItems();
|
||||
}, this );
|
||||
this.collection.on( 'add', this.addItemView, this );
|
||||
this.collection.on( 'remove', this.removeItemView, this );
|
||||
this.listenTo( this.collection, {
|
||||
error : function( model, xhr, options, msg, details ){
|
||||
this.trigger( 'error', model, xhr, options, msg, details );
|
||||
},
|
||||
reset : function(){
|
||||
this.renderItems();
|
||||
},
|
||||
add : this.addItemView,
|
||||
remove : this.removeItemView
|
||||
});
|
||||
|
||||
// debugging
|
||||
if( this.logger ){
|
||||
this.collection.on( 'all', function( event ){
|
||||
this.listenTo( this.collection, 'all', function( event ){
|
||||
this.info( this + '(collection)', arguments );
|
||||
}, this );
|
||||
});
|
||||
}
|
||||
return this;
|
||||
},
|
||||
@@ -180,23 +184,25 @@ var ListPanel = Backbone.View.extend( BASE_MVC.LoggableMixin ).extend(/** @lends
|
||||
this.log( this + '._setUpViewListeners' );
|
||||
|
||||
// shift to select a range
|
||||
this.on( 'view:selected', function( view, ev ){
|
||||
if( ev && ev.shiftKey && this.lastSelected ){
|
||||
var lastSelectedView = this.viewFromModelId( this.lastSelected );
|
||||
if( lastSelectedView ){
|
||||
this.selectRange( view, lastSelectedView );
|
||||
this.on({
|
||||
'view:selected': function( view, ev ){
|
||||
if( ev && ev.shiftKey && this.lastSelected ){
|
||||
var lastSelectedView = this.viewFromModelId( this.lastSelected );
|
||||
if( lastSelectedView ){
|
||||
this.selectRange( view, lastSelectedView );
|
||||
}
|
||||
} else if( ev && ev.altKey && !this.selecting ){
|
||||
this.showSelectors();
|
||||
}
|
||||
} else if( ev && ev.altKey && !this.selecting ){
|
||||
this.showSelectors();
|
||||
}
|
||||
this.selected.push( view.model.id );
|
||||
this.lastSelected = view.model.id;
|
||||
}, this );
|
||||
this.selected.push( view.model.id );
|
||||
this.lastSelected = view.model.id;
|
||||
},
|
||||
|
||||
this.on( 'view:de-selected', function( view, ev ){
|
||||
this.selected = _.without( this.selected, view.model.id );
|
||||
//this.lastSelected = view.model.id;
|
||||
}, this );
|
||||
'view:de-selected': function( view, ev ){
|
||||
this.selected = _.without( this.selected, view.model.id );
|
||||
//this.lastSelected = view.model.id;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// ------------------------------------------------------------------------ rendering
|
||||
@@ -426,14 +432,14 @@ var ListPanel = Backbone.View.extend( BASE_MVC.LoggableMixin ).extend(/** @lends
|
||||
_setUpItemViewListeners : function( view ){
|
||||
var panel = this;
|
||||
// send all events to the panel, re-namspaceing them with the view prefix
|
||||
view.on( 'all', function(){
|
||||
this.listenTo( view, 'all', function(){
|
||||
var args = Array.prototype.slice.call( arguments, 0 );
|
||||
args[0] = 'view:' + args[0];
|
||||
panel.trigger.apply( panel, args );
|
||||
});
|
||||
|
||||
// drag multiple - hijack ev.setData to add all selected items
|
||||
view.on( 'draggable:dragstart', function( ev, v ){
|
||||
this.listenTo( view, 'draggable:dragstart', function( ev, v ){
|
||||
//TODO: set multiple drag data here
|
||||
var json = {},
|
||||
selected = this.getSelectedModels();
|
||||
@@ -912,7 +918,7 @@ var ModelListPanel = ListPanel.extend({
|
||||
// override
|
||||
this.log( this + '._setUpModelListeners', this.model );
|
||||
// bounce model errors up to the panel
|
||||
this.model.on( 'error', function(){
|
||||
this.listenTo( this.model, 'error', function(){
|
||||
var args = Array.prototype.slice.call( arguments, 0 );
|
||||
//args.unshift( 'model:error' );
|
||||
args.unshift( 'error' );
|
||||
|
||||
@@ -291,4 +291,4 @@ define(['utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view',
|
||||
return $el;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -7,9 +7,8 @@ define(['utils/utils', 'mvc/tool/tool-form-base'],
|
||||
// create form view
|
||||
var View = ToolFormBase.extend({
|
||||
initialize: function(options) {
|
||||
// link this
|
||||
var self = this;
|
||||
this.hasLabelListeners = false;
|
||||
this.workflow = options.workflow;
|
||||
|
||||
// link with node representation in workflow module
|
||||
this.node = options.node;
|
||||
@@ -40,7 +39,6 @@ define(['utils/utils', 'mvc/tool/tool-form-base'],
|
||||
// module information for the tool to update the workflow
|
||||
// state stored on the client with. User needs to save
|
||||
// for this to take effect.
|
||||
self.initializeLabelListener();
|
||||
self.node.update_field_data(data);
|
||||
self.errors(data && data.tool_model)
|
||||
}
|
||||
@@ -73,29 +71,6 @@ define(['utils/utils', 'mvc/tool/tool-form-base'],
|
||||
ToolFormBase.prototype.initialize.call(this, options);
|
||||
},
|
||||
|
||||
initializeLabelListener: function() {
|
||||
var self = this;
|
||||
if(this.hasLabelListeners !== false) {
|
||||
return;
|
||||
}
|
||||
this.hasLabelListeners = [];
|
||||
var outputSections = _.where(this.options.inputs, {outputSection: true});
|
||||
var labelInputs = outputSections.map(function(entry) {
|
||||
var sectionId = entry.id;
|
||||
var outputId = entry.outputId;
|
||||
var $section = $("#" + sectionId);
|
||||
var $labelRow = $section.find(".section-row").first();
|
||||
var labelTextInput = $labelRow.find("input")[0];
|
||||
$(labelTextInput).bind('input propertychange', function() {
|
||||
var newLabel = $(labelTextInput).val();
|
||||
var workflow = self.node.app.workflow;
|
||||
workflow.attemptUpdateOutputLabel( self.node, outputId, newLabel );
|
||||
});
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
|
||||
/** Builds all sub sections
|
||||
*/
|
||||
_makeSections: function(options){
|
||||
@@ -150,6 +125,7 @@ define(['utils/utils', 'mvc/tool/tool-form-base'],
|
||||
*/
|
||||
_makeSection: function(output_id, datatypes){
|
||||
// format datatypes
|
||||
var self = this;
|
||||
var extensions = [];
|
||||
var input_terminal_names = [];
|
||||
|
||||
@@ -188,15 +164,14 @@ define(['utils/utils', 'mvc/tool/tool-form-base'],
|
||||
title : 'Configure Output: \'' + output_id + '\'',
|
||||
type : 'section',
|
||||
flat : true,
|
||||
outputSection: true,
|
||||
outputId : output_id,
|
||||
inputs : [{
|
||||
action : 'Label',
|
||||
label : 'Label',
|
||||
type : 'text',
|
||||
value : '',
|
||||
ignore : '',
|
||||
help : 'This will provide a short name to describe the output - this must be unique across workflows.'
|
||||
value : ( output = this.node.getWorkflowOutput( output_id ) ) && output.label || '',
|
||||
help : 'This will provide a short name to describe the output - this must be unique across workflows.',
|
||||
onchange : function( new_value ) {
|
||||
self.workflow.attemptUpdateOutputLabel( self.node, output_id, new_value );
|
||||
}
|
||||
},{
|
||||
action : 'RenameDatasetAction',
|
||||
pja_arg : 'newname',
|
||||
@@ -267,21 +242,13 @@ define(['utils/utils', 'mvc/tool/tool-form-base'],
|
||||
};
|
||||
|
||||
// visit input nodes and enrich by name/value pairs from server data
|
||||
var self = this;
|
||||
function visit (head, head_list) {
|
||||
head_list = head_list || [];
|
||||
head_list.push(head);
|
||||
for (var i in head.inputs) {
|
||||
var input = head.inputs[i];
|
||||
var action = input.action;
|
||||
if ( action == "Label") {
|
||||
var workflowOutput = self.node.getWorkflowOutput(output_id);
|
||||
if ( workflowOutput ) {
|
||||
input.value = workflowOutput['label'] || '';
|
||||
} else{
|
||||
input.value = '';
|
||||
}
|
||||
} else if (action) {
|
||||
if (action) {
|
||||
// construct identifier as expected by backend
|
||||
input.name = 'pja__' + output_id + '__' + input.action;
|
||||
if (input.pja_arg) {
|
||||
|
||||
@@ -14,7 +14,7 @@ var View = Backbone.View.extend({
|
||||
this.multiple = options.multiple || false;
|
||||
|
||||
// create message handler
|
||||
this.message = new Ui.Message({ cls: 'ui-margin-top' });
|
||||
this.message = new Ui.Message();
|
||||
|
||||
// create portlet
|
||||
this.portlet = new Portlet.View({ cls: 'ui-portlet-section' });
|
||||
|
||||
@@ -10,257 +10,141 @@ define(['utils/utils',
|
||||
'mvc/ui/ui-modal'],
|
||||
function( Utils, Select, Slider, Options, Drilldown, Buttons, Modal ) {
|
||||
|
||||
/** Image wrapper */
|
||||
var Image = Backbone.View.extend({
|
||||
initialize : function(options) {
|
||||
this.options = Utils.merge(options, {
|
||||
url : '',
|
||||
cls : ''
|
||||
});
|
||||
this.setElement(this._template(this.options));
|
||||
},
|
||||
_template: function(options) {
|
||||
return '<img class="ui-image ' + options.cls + '" src="' + options.url + '"/>';
|
||||
}
|
||||
});
|
||||
|
||||
/** Label wrapper */
|
||||
var Label = Backbone.View.extend({
|
||||
initialize : function(options) {
|
||||
this.options = Utils.merge(options, {
|
||||
title : '',
|
||||
cls : '',
|
||||
tagname : 'label'
|
||||
});
|
||||
this.setElement(this._template(this.options));
|
||||
tagName: 'label',
|
||||
initialize: function( options ) {
|
||||
this.model = options && options.model || new Backbone.Model( options );
|
||||
this.tagName = options.tagName || this.tagName;
|
||||
this.setElement( $( '<' + this.tagName + '/>' ) );
|
||||
this.listenTo( this.model, 'change', this.render, this );
|
||||
this.render();
|
||||
},
|
||||
title: function(new_title) {
|
||||
this.$el.html(new_title);
|
||||
title: function( new_title ) {
|
||||
this.model.set( 'title', new_title );
|
||||
},
|
||||
value: function() {
|
||||
return options.title;
|
||||
return this.model.get( 'title' );
|
||||
},
|
||||
_template: function(options) {
|
||||
return $( '<' + options.tagname + '/>' ).addClass( 'ui-label' ).addClass( options.cls ).html( options.title );
|
||||
}
|
||||
});
|
||||
|
||||
/** Displays an icon with title */
|
||||
var Icon = Backbone.View.extend({
|
||||
initialize : function(options) {
|
||||
this.options = Utils.merge(options, {
|
||||
floating : 'right',
|
||||
icon : '',
|
||||
tooltip : '',
|
||||
placement : 'bottom',
|
||||
title : '',
|
||||
cls : ''
|
||||
});
|
||||
this.setElement(this._template(this.options));
|
||||
$(this.el).tooltip({title: options.tooltip, placement: 'bottom'});
|
||||
},
|
||||
_template: function(options) {
|
||||
return '<div>' +
|
||||
'<span class="fa ' + options.icon + '" class="ui-icon"/> ' +
|
||||
options.title +
|
||||
'</div>';
|
||||
}
|
||||
});
|
||||
|
||||
/** Renders an anchor element */
|
||||
var Anchor = Backbone.View.extend({
|
||||
initialize : function(options) {
|
||||
this.options = Utils.merge(options, {
|
||||
title : '',
|
||||
cls : ''
|
||||
});
|
||||
this.setElement(this._template(this.options));
|
||||
$(this.el).on('click', options.onclick);
|
||||
},
|
||||
_template: function(options) {
|
||||
return '<div><a href="javascript:void(0)" class="ui-anchor ' + options.cls + '">' + options.title + '</a></div>';
|
||||
render: function() {
|
||||
this.$el.removeClass()
|
||||
.addClass( 'ui-label' )
|
||||
.addClass( this.model.get( 'cls' ) )
|
||||
.html( this.model.get( 'title' ) );
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
/** Displays messages used e.g. in the tool form */
|
||||
var Message = Backbone.View.extend({
|
||||
initialize : function(options) {
|
||||
this.options = Utils.merge(options, {
|
||||
initialize: function( options ) {
|
||||
this.model = options && options.model || new Backbone.Model({
|
||||
message : null,
|
||||
status : 'info',
|
||||
cls : '',
|
||||
persistent : false
|
||||
});
|
||||
this.setElement('<div class="' + this.options.cls + '"/>');
|
||||
this.options.message && this.update(this.options);
|
||||
}).set( options );
|
||||
this.listenTo( this.model, 'change', this.render, this );
|
||||
this.render();
|
||||
},
|
||||
|
||||
// update
|
||||
update: function(options) {
|
||||
// get options
|
||||
this.options = Utils.merge(options, this.options);
|
||||
|
||||
// show message
|
||||
if (options.message != '') {
|
||||
this.$el.html(this._template(this.options));
|
||||
update: function( options ) {
|
||||
this.model.set( options );
|
||||
},
|
||||
render: function() {
|
||||
this.$el.removeClass().addClass( 'ui-message' ).addClass( this.model.get( 'cls' ) );
|
||||
var status = this.model.get( 'status' );
|
||||
if ( this.model.get( 'large' ) ) {
|
||||
this.$el.addClass((( status == 'success' && 'done' ) ||
|
||||
( status == 'danger' && 'error' ) ||
|
||||
status ) + 'messagelarge' );
|
||||
} else {
|
||||
this.$el.addClass( 'alert' ).addClass( 'alert-' + status );
|
||||
}
|
||||
if ( this.model.get( 'message' ) ) {
|
||||
this.$el.html( this.model.get( 'message' ) );
|
||||
this.$el.fadeIn();
|
||||
|
||||
// clear previous timeouts
|
||||
if (this.timeout) {
|
||||
window.clearTimeout(this.timeout);
|
||||
}
|
||||
|
||||
// set timeout if message is not persistent
|
||||
if (!options.persistent) {
|
||||
this.timeout && window.clearTimeout( this.timeout );
|
||||
if ( !this.model.get( 'persistent' ) ) {
|
||||
var self = this;
|
||||
this.timeout = window.setTimeout(function() {
|
||||
if (self.$el.is(':visible')) {
|
||||
self.$el.fadeOut();
|
||||
} else {
|
||||
self.$el.hide();
|
||||
}
|
||||
}, 3000);
|
||||
this.timeout = window.setTimeout( function() {
|
||||
self.$el.fadeOut();
|
||||
}, 3000 );
|
||||
}
|
||||
} else {
|
||||
this.$el.fadeOut();
|
||||
}
|
||||
},
|
||||
|
||||
// template
|
||||
_template: function(options) {
|
||||
var cls_status = 'ui-message alert alert-' + options.status;
|
||||
if (options.large) {
|
||||
cls_status = ( ( options.status == 'success' && 'done' ) ||
|
||||
( options.status == 'danger' && 'error' ) ||
|
||||
options.status ) + 'messagelarge';
|
||||
}
|
||||
return '<div class="' + cls_status + '" >' +
|
||||
options.message +
|
||||
'</div>';
|
||||
}
|
||||
});
|
||||
|
||||
/** Render a search box */
|
||||
var Searchbox = Backbone.View.extend({
|
||||
initialize : function(options) {
|
||||
this.options = Utils.merge(options, {
|
||||
onclick : null,
|
||||
searchword : ''
|
||||
});
|
||||
this.setElement(this._template(this.options));
|
||||
var self = this;
|
||||
if (this.options.onclick) {
|
||||
this.$el.on('submit', function(e) {
|
||||
var search_field = self.$el.find('#search');
|
||||
self.options.onclick(search_field.val());
|
||||
});
|
||||
}
|
||||
},
|
||||
_template: function(options) {
|
||||
return '<div class="ui-search">' +
|
||||
'<form onsubmit="return false;">' +
|
||||
'<input id="search" class="form-control input-sm" type="text" name="search" placeholder="Search..." value="' + options.searchword + '">' +
|
||||
'<button type="submit" class="btn search-btn">' +
|
||||
'<i class="fa fa-search"></i>' +
|
||||
'</button>' +
|
||||
'</form>' +
|
||||
'</div>';
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
/** Renders an input element used e.g. in the tool form */
|
||||
var Input = Backbone.View.extend({
|
||||
initialize : function(options) {
|
||||
// configure options
|
||||
this.options = Utils.merge(options, {
|
||||
initialize: function( options ) {
|
||||
this.model = options && options.model || new Backbone.Model({
|
||||
type : 'text',
|
||||
placeholder : '',
|
||||
disabled : false,
|
||||
visible : true,
|
||||
cls : '',
|
||||
area : false
|
||||
});
|
||||
|
||||
// create new element
|
||||
this.setElement(this._template(this.options));
|
||||
|
||||
// set initial value
|
||||
if (this.options.value !== undefined) {
|
||||
this.value(this.options.value);
|
||||
}
|
||||
|
||||
// disable input field
|
||||
if (this.options.disabled) {
|
||||
this.$el.prop('disabled', true);
|
||||
}
|
||||
|
||||
// hide input field
|
||||
if (!this.options.visible) {
|
||||
this.$el.hide();
|
||||
}
|
||||
|
||||
// onchange event handler. fires on user activity.
|
||||
var self = this;
|
||||
this.$el.on('input', function() {
|
||||
if (self.options.onchange) {
|
||||
self.options.onchange(self.$el.val());
|
||||
}
|
||||
});
|
||||
}).set( options );
|
||||
this.tagName = this.model.get( 'area' ) ? 'textarea' : 'input';
|
||||
this.setElement( $( '<' + this.tagName + '/>' ) );
|
||||
this.listenTo( this.model, 'change', this.render, this );
|
||||
this.render();
|
||||
},
|
||||
|
||||
// value
|
||||
value : function (new_val) {
|
||||
if (new_val !== undefined) {
|
||||
this.$el.val( ( typeof new_val === 'string' && new_val ) || '' );
|
||||
}
|
||||
return this.$el.val();
|
||||
events: {
|
||||
'input': '_onchange'
|
||||
},
|
||||
|
||||
// template
|
||||
_template: function(options) {
|
||||
if (options.area) {
|
||||
return '<textarea id="' + options.id + '" class="ui-textarea ' + options.cls + '"></textarea>';
|
||||
} else {
|
||||
return '<input id="' + options.id + '" type="' + options.type + '" value="' + options.value + '" placeholder="' + options.placeholder + '" class="ui-input ' + options.cls + '">';
|
||||
}
|
||||
value: function( new_val ) {
|
||||
new_val !== undefined && this.model.set( 'value', typeof new_val === 'string' ? new_val : '' );
|
||||
return this.model.get( 'value' );
|
||||
},
|
||||
render: function() {
|
||||
this.$el.removeClass()
|
||||
.addClass( 'ui-' + this.tagName )
|
||||
.addClass( this.model.get( 'cls' ) )
|
||||
.attr( 'id', this.model.id )
|
||||
.attr( 'type', this.model.get( 'type' ) )
|
||||
.attr( 'placeholder', this.model.get( 'placeholder' ) )
|
||||
.val( this.model.get( 'value' ) );
|
||||
this.model.get( 'disabled' ) ? this.$el.attr( 'disabled', true ) : this.$el.removeAttr( 'disabled' );
|
||||
this.$el[ this.model.get( 'visible' ) ? 'show' : 'hide' ]();
|
||||
return this;
|
||||
},
|
||||
_onchange: function() {
|
||||
this.value( this.$el.val() );
|
||||
this.model.get( 'onchange' ) && this.model.get( 'onchange' )( this.model.get( 'value' ) );
|
||||
}
|
||||
});
|
||||
|
||||
/** Creates a hidden element input field used e.g. in the tool form */
|
||||
var Hidden = Backbone.View.extend({
|
||||
initialize : function(options) {
|
||||
this.options = options;
|
||||
this.setElement(this._template(this.options));
|
||||
if (this.options.value !== undefined) {
|
||||
this.value(this.options.value);
|
||||
}
|
||||
initialize: function( options ) {
|
||||
this.model = options && options.model || new Backbone.Model( options );
|
||||
this.setElement( $ ( '<div/>' ).append( this.$info = $( '<div/>' ) )
|
||||
.append( this.$hidden = $( '<div/>' ) ) );
|
||||
this.listenTo( this.model, 'change', this.render, this );
|
||||
this.render();
|
||||
},
|
||||
value : function (new_val) {
|
||||
if (new_val !== undefined) {
|
||||
this.$('hidden').val(new_val);
|
||||
}
|
||||
return this.$('hidden').val();
|
||||
value: function( new_val ) {
|
||||
new_val !== undefined && this.model.set( 'value', new_val );
|
||||
return this.model.get( 'value' );
|
||||
},
|
||||
_template: function(options) {
|
||||
var tmpl = '<div id="' + options.id + '" >';
|
||||
if (options.info) {
|
||||
tmpl += '<div>' + options.info + '</div>';
|
||||
}
|
||||
tmpl += '<hidden value="' + options.value + '"/>' +
|
||||
'</div>';
|
||||
return tmpl;
|
||||
render: function() {
|
||||
this.$el.attr( 'id', this.model.id );
|
||||
this.$hidden.val( this.model.get( 'value' ) );
|
||||
this.model.get( 'info' ) ? this.$info.show().html( this.model.get( 'info' ) ) : this.$info.hide();
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
Anchor : Anchor,
|
||||
Button : Buttons.ButtonDefault,
|
||||
ButtonIcon : Buttons.ButtonIcon,
|
||||
ButtonCheck : Buttons.ButtonCheck,
|
||||
ButtonMenu : Buttons.ButtonMenu,
|
||||
ButtonLink : Buttons.ButtonLink,
|
||||
Icon : Icon,
|
||||
Image : Image,
|
||||
Input : Input,
|
||||
Label : Label,
|
||||
Message : Message,
|
||||
@@ -268,7 +152,6 @@ define(['utils/utils',
|
||||
RadioButton : Options.RadioButton,
|
||||
Checkbox : Options.Checkbox,
|
||||
Radio : Options.Radio,
|
||||
Searchbox : Searchbox,
|
||||
Select : Select,
|
||||
Hidden : Hidden,
|
||||
Slider : Slider,
|
||||
|
||||
@@ -322,7 +322,7 @@ return Backbone.View.extend({
|
||||
'<td>' +
|
||||
'<div id="genome" class="upload-genome"/>' +
|
||||
'</td>' +
|
||||
'<td><div id="settings" class="upload-icon-button fa fa-gear"/></td>' +
|
||||
'<td><div id="settings" class="upload-settings upload-icon-button fa fa-gear"/></td>' +
|
||||
'<td>' +
|
||||
'<div id="info" class="upload-info">' +
|
||||
'<div class="progress">' +
|
||||
|
||||
@@ -1,93 +1,43 @@
|
||||
/** This renders the content of the settings popup, allowing users to specify flags i.e. for space-to-tab conversion **/
|
||||
define(['utils/utils'], function(Utils) {
|
||||
define( [ 'utils/utils' ], function( Utils ) {
|
||||
return Backbone.View.extend({
|
||||
// options
|
||||
options: {
|
||||
class_check : 'upload-icon-button fa fa-check-square-o',
|
||||
class_uncheck : 'upload-icon-button fa fa-square-o'
|
||||
class_check : 'fa-check-square-o',
|
||||
class_uncheck : 'fa-square-o',
|
||||
parameters : [{
|
||||
id : 'space_to_tab',
|
||||
title : 'Convert spaces to tabs',
|
||||
},{
|
||||
id : 'to_posix_lines',
|
||||
title : 'Use POSIX standard'
|
||||
}]
|
||||
},
|
||||
|
||||
// initialize
|
||||
initialize: function(app) {
|
||||
// link app
|
||||
this.app = app;
|
||||
|
||||
// link this
|
||||
initialize: function( options ) {
|
||||
var self = this;
|
||||
|
||||
// set template
|
||||
this.setElement(this._template());
|
||||
|
||||
// link model
|
||||
this.model = this.app.model;
|
||||
|
||||
// ui event: space-to-tab
|
||||
this.$('#upload-space-to-tab').on('click', function() {
|
||||
self._switchState('#upload-space-to-tab', 'space_to_tab');
|
||||
});
|
||||
|
||||
// ui event: to-posix-lines
|
||||
this.$('#upload-to-posix-lines').on('click', function() {
|
||||
self._switchState('#upload-to-posix-lines', 'to_posix_lines');
|
||||
});
|
||||
|
||||
// render
|
||||
this.render();
|
||||
this.model = options.model;
|
||||
this.setElement( $( '<div/>' ).addClass( 'upload-settings' ) );
|
||||
this.$el.append( $( '<div/>' ).addClass( 'upload-settings-cover' ) );
|
||||
this.$el.append( $( '<table/>' ).addClass( 'upload-settings-table ui-table-striped' ).append( '<tbody/>' ) );
|
||||
this.$cover = this.$( '.upload-settings-cover' );
|
||||
this.$table = this.$( '.upload-settings-table > tbody' );
|
||||
this.listenTo ( this.model, 'change', this.render, this );
|
||||
this.model.trigger( 'change' );
|
||||
},
|
||||
|
||||
// render
|
||||
render: function() {
|
||||
// render states
|
||||
this._renderState('#upload-space-to-tab', this.model.get('space_to_tab'));
|
||||
this._renderState('#upload-to-posix-lines', this.model.get('to_posix_lines'));
|
||||
|
||||
// disable options
|
||||
var $cover = this.$('#upload-settings-cover');
|
||||
if (!this.model.get('enabled')) {
|
||||
$cover.show();
|
||||
} else {
|
||||
$cover.hide();
|
||||
}
|
||||
},
|
||||
|
||||
// switch state
|
||||
_switchState: function (element_id, parameter_id) {
|
||||
if (this.model.get('enabled')) {
|
||||
var checked = !this.model.get(parameter_id);
|
||||
this.model.set(parameter_id, checked);
|
||||
this._renderState(element_id, checked);
|
||||
}
|
||||
},
|
||||
|
||||
// render state
|
||||
_renderState: function (element_id, checked) {
|
||||
var $it = this.$(element_id);
|
||||
$it.removeClass();
|
||||
if (checked) {
|
||||
$it.addClass(this.options.class_check);
|
||||
} else {
|
||||
$it.addClass(this.options.class_uncheck);
|
||||
}
|
||||
},
|
||||
|
||||
// load template
|
||||
_template: function() {
|
||||
return '<div class="upload-settings" style="position: relative;">' +
|
||||
'<div id="upload-settings-cover" class="upload-settings-cover"/>' +
|
||||
'<table class="ui-table-striped">' +
|
||||
'<tbody>' +
|
||||
'<tr>' +
|
||||
'<td><div id="upload-space-to-tab"/></td>' +
|
||||
'<td>Convert spaces to tabs</td>' +
|
||||
'</tr>' +
|
||||
'<tr>' +
|
||||
'<td><div id="upload-to-posix-lines"/></td>' +
|
||||
'<td>Use POSIX standard</td>' +
|
||||
'</tr>' +
|
||||
'</tbody>' +
|
||||
'</table>' +
|
||||
'</div>';
|
||||
var self = this;
|
||||
this.$table.empty();
|
||||
_.each( this.options.parameters, function( parameter ) {
|
||||
var $checkbox = $( '<div/>' ).addClass( 'upload-' + parameter.id + ' upload-icon-button fa' )
|
||||
.addClass( self.model.get( parameter.id ) && self.options.class_check || self.options.class_uncheck )
|
||||
.on( 'click', function() {
|
||||
self.model.get( 'enabled' ) && self.model.set( parameter.id, !self.model.get( parameter.id ) )
|
||||
});
|
||||
self.$table.append( $( '<tr/>' ).append( $( '<td/>' ).append( $checkbox ) )
|
||||
.append( $( '<td/>' ).append( parameter.title ) ) )
|
||||
});
|
||||
this.$cover[ this.model.get( 'enabled' ) && 'hide' || 'show' ]();
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
@@ -4,6 +4,7 @@ define([
|
||||
'mvc/base-mvc',
|
||||
'utils/localization'
|
||||
], function( _, Backbone, baseMVC, _l ){
|
||||
'use strict';
|
||||
|
||||
var logNamespace = 'user';
|
||||
//==============================================================================
|
||||
|
||||
@@ -2,6 +2,7 @@ define([
|
||||
"mvc/base-mvc",
|
||||
"utils/localization"
|
||||
], function( baseMVC, _l ){
|
||||
'use strict';
|
||||
|
||||
var logNamespace = 'user';
|
||||
//==============================================================================
|
||||
@@ -27,7 +28,7 @@ var UserQuotaMeter = Backbone.View.extend( baseMVC.LoggableMixin ).extend(
|
||||
_.extend( this.options, options );
|
||||
|
||||
//this.bind( 'all', function( event, data ){ this.log( this + ' event:', event, data ); }, this );
|
||||
this.model.bind( 'change:quota_percent change:total_disk_usage', this.render, this );
|
||||
this.listenTo( this.model, 'change:quota_percent change:total_disk_usage', this.render );
|
||||
},
|
||||
|
||||
/** Re-load user model data from the api */
|
||||
|
||||
@@ -617,9 +617,7 @@ EditorFormView = Backbone.View.extend({
|
||||
|
||||
// Global state for the whole workflow
|
||||
reset: function() {
|
||||
if ( this.workflow ) {
|
||||
this.workflow.remove_all();
|
||||
}
|
||||
this.workflow && this.workflow.remove_all();
|
||||
this.workflow = Globals.workflow = new Workflow( this, $("#canvas-container") );
|
||||
},
|
||||
|
||||
@@ -795,6 +793,7 @@ EditorFormView = Backbone.View.extend({
|
||||
if (node.type == 'tool' && Utils.isJSON(text)) {
|
||||
var options = JSON.parse(text);
|
||||
options.node = node;
|
||||
options.workflow = this.workflow;
|
||||
options.datatypes = this.datatypes;
|
||||
formView = new ToolForm.View(options);
|
||||
} else {
|
||||
|
||||
@@ -123,16 +123,13 @@ function request (options) {
|
||||
data : options.data || {},
|
||||
url : options.url
|
||||
}
|
||||
|
||||
// encode data into url
|
||||
if (ajaxConfig.type == 'GET' || ajaxConfig.type == 'DELETE') {
|
||||
if (ajaxConfig.url.indexOf('?') == -1) {
|
||||
ajaxConfig.url += '?';
|
||||
} else {
|
||||
ajaxConfig.url += '&';
|
||||
if ( ajaxConfig.type == 'GET' || ajaxConfig.type == 'DELETE' ) {
|
||||
if ( !$.isEmptyObject(ajaxConfig.data) ) {
|
||||
ajaxConfig.url += ajaxConfig.url.indexOf('?') == -1 ? '?' : '&';
|
||||
ajaxConfig.url += $.param(ajaxConfig.data, true);
|
||||
}
|
||||
ajaxConfig.url = ajaxConfig.url + $.param(ajaxConfig.data, true);
|
||||
ajaxConfig.data = null;
|
||||
ajaxConfig.data = null;
|
||||
} else {
|
||||
ajaxConfig.dataType = 'json';
|
||||
ajaxConfig.url = ajaxConfig.url;
|
||||
|
||||
@@ -64,7 +64,11 @@
|
||||
|
||||
.ui-message {
|
||||
padding: 2px 10px 2px 10px;
|
||||
margin: 0px;
|
||||
margin-top: @ui-margin-vertical-large;
|
||||
margin-bottom: 0px;
|
||||
float: left;
|
||||
width: 100%;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ui-modal {
|
||||
|
||||
@@ -227,6 +227,7 @@
|
||||
}
|
||||
|
||||
.upload-settings {
|
||||
position: relative;
|
||||
.upload-settings-cover {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Grunt task to bundle apps using webpack (see also ../webpack.config.js).
|
||||
*/
|
||||
module.exports = function( grunt ){
|
||||
"use strict";
|
||||
|
||||
var path = require( 'path' );
|
||||
|
||||
// there is a taskrunner specifically for this - but it's not straightforward
|
||||
// and duplicates some of the config/code in webpack.config,
|
||||
// https://github.com/webpack/grunt-webpack
|
||||
// http://webpack.github.io/docs/usage-with-grunt.html
|
||||
|
||||
// so we'll use grunt-exec and call the webpack cli instead (until CLI and runner are unified a bit more?)
|
||||
|
||||
grunt.loadNpmTasks( 'grunt-exec' );
|
||||
|
||||
function webpackCLI(){
|
||||
var args = Array.prototype.slice.call( arguments );
|
||||
args.unshift( path.join( __dirname, '../node_modules/webpack/bin/webpack.js' ) );
|
||||
return args.join( ' ' );
|
||||
}
|
||||
grunt.registerTask( 'webpack', function(){
|
||||
grunt.log.writeln( 'bundling webpack apps for production...' );
|
||||
grunt.config( 'exec.webpack-production.command', webpackCLI( '-p' ) );
|
||||
grunt.task.run( 'exec:webpack-production' );
|
||||
});
|
||||
grunt.registerTask( 'webpack-dev', function(){
|
||||
grunt.log.writeln( 'bundling webpack apps for development...' );
|
||||
grunt.config( 'exec.webpack-dev.command', webpackCLI( '-d' ) );
|
||||
grunt.task.run( 'exec:webpack-dev' );
|
||||
});
|
||||
grunt.registerTask( 'webpack-watch', function(){
|
||||
grunt.log.writeln( 'bundling webpack apps for development and watching for changes...' );
|
||||
grunt.config( 'exec.webpack-watch.command', webpackCLI( '-d', '--watch' ) );
|
||||
grunt.task.run( 'exec:webpack-watch' );
|
||||
});
|
||||
};
|
||||
@@ -172,7 +172,7 @@ paste.app_factory = galaxy.web.buildapp:app_factory
|
||||
# from the Tool Shed will fail.
|
||||
#tool_dependency_dir = None
|
||||
|
||||
# The dependency resolves config file specifies an ordering and options for how
|
||||
# The dependency resolves config file specifies an ordering and options for how
|
||||
# Galaxy resolves tool dependencies (requirement tags in Tool XML). The default
|
||||
# ordering is to the use the tool shed for tools installed that way, use local
|
||||
# Galaxy packages, and then use conda if available.
|
||||
@@ -301,6 +301,19 @@ paste.app_factory = galaxy.web.buildapp:app_factory
|
||||
# Set to false to disable various checks Galaxy will do to ensure it
|
||||
# can run job scripts before attempting to execute or submit them.
|
||||
#check_job_script_integrity = True
|
||||
# Number of checks to execute if check_job_script_integrity is enabled.
|
||||
#check_job_script_integrity_count = 35
|
||||
# Time to sleep between checks if check_job_script_integrity is enabled (in seconds).
|
||||
#check_job_script_integrity_sleep = .25
|
||||
|
||||
|
||||
# Set the default shell used by jobs Galaxy-wide. This defaults to
|
||||
# sh and can be overidden at the destination level for
|
||||
# heterogenous clusters. conda job resolution requires bash or zsh
|
||||
# so if this is not switched to /bin/bash for instance - conda resolution
|
||||
# should be disabled. (16.01 will likely be the last release with a
|
||||
# default of /bin/sh instead of /bin/bash).
|
||||
#default_job_shell = /bin/sh
|
||||
|
||||
# Citation related caching. Tool citations information maybe fetched from
|
||||
# external sources such as http://dx.doi.org/ by Galaxy - the following
|
||||
@@ -662,6 +675,14 @@ nglims_config_file = tool-data/nglims.yaml
|
||||
# by setting the following option to True.
|
||||
#serve_xss_vulnerable_mimetypes = False
|
||||
|
||||
# Return a Access-Control-Allow-Origin response header that matches the Origin
|
||||
# header of the request if that Origin hostname matches one of the strings or
|
||||
# regular expressions listed here. This is a comma separated list of hostname
|
||||
# strings or regular expressions beginning and ending with /.
|
||||
# E.g. mysite.com,google.com,usegalaxy.org,/^[\w\.]*example\.com/
|
||||
# See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
|
||||
#allowed_origin_hostnames = None
|
||||
|
||||
# Set the following to True to use IPython nbconvert to build HTML from IPython
|
||||
# notebooks in Galaxy histories. This process may allow users to execute
|
||||
# arbitrary code or serve arbitrary HTML. If enabled, IPython must be
|
||||
@@ -878,8 +899,8 @@ use_interactive = True
|
||||
# Set the following to a number of threads greater than 1 to spawn
|
||||
# a Python task queue for dealing with large tool submissions (either
|
||||
# through the tool form or as part of an individual workflow step across
|
||||
# large collection). The size of a "large" tool request is controlled by
|
||||
# the second parameter below and defaults to 10. This affects workflow
|
||||
# large collection). The size of a "large" tool request is controlled by
|
||||
# the second parameter below and defaults to 10. This affects workflow
|
||||
# scheduling and web processes, not job handlers.
|
||||
#tool_submission_burst_threads = 1
|
||||
#tool_submission_burst_at = 10
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
[main]
|
||||
# Following options are ignored if using the Galaxy dynamic proxy but
|
||||
# are useful if mapping a range of ports for environment consumption.
|
||||
#password_auth = False
|
||||
#ssl = False
|
||||
|
||||
[docker]
|
||||
# Command to launch docker container. For example `sudo docker` or `docker-lxc`.
|
||||
# If you need to use a command like `sg` you can do that here, just be sure to
|
||||
# wrap all of the docker portion in single quotes. E.g. `sg 'docker' 'docker {docker_args}'`
|
||||
#
|
||||
# It is recommended that you use command_inject if you need to inject
|
||||
# additional parameters. This command string is re-used for a `docker inspect`
|
||||
# command and will likely cause errors if it is extensively modified, past the
|
||||
# usual group/sudo changes.
|
||||
#command = docker {docker_args}
|
||||
|
||||
# The docker image name that should be started.
|
||||
image = bgruening/docker-ipython-notebook:15.10.1
|
||||
|
||||
# Additional arguments that are passed to the `docker run` command.
|
||||
#command_inject = --sig-proxy=true -e DEBUG=false
|
||||
|
||||
# URL to access the Galaxy API with from the spawn Docker containter, if empty
|
||||
# this falls back to galaxy.ini's galaxy_infrastructure_url and finally to the
|
||||
# Docker host of the spawned container if that is also not set.
|
||||
#galaxy_url =
|
||||
|
||||
# The Docker hostname. It can be useful to run the Docker daemon on a different
|
||||
# host than Galaxy.
|
||||
#docker_hostname = localhost
|
||||
|
||||
# Try to set the tempdirectory to world execute - this can fix the issue
|
||||
# where 'sudo docker' is not able to mount the folder otherwise.
|
||||
# "finalize namespace chdir to /import permission denied"
|
||||
#wx_tempdir = False
|
||||
|
||||
# Overwride the IE tempdirectory. This can be useful if you regular tempdir is
|
||||
# located on an NFS share, which does not work well as Docker volume. In this case
|
||||
# you can have a shared sshfs share which you can use as temporary directory to
|
||||
# share data between the IE and Galaxy.
|
||||
#docker_galaxy_temp_dir = None
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE interactive_environment SYSTEM "../../interactive_environments.dtd">
|
||||
<interactive_environment name="IPython">
|
||||
<data_sources>
|
||||
<data_source>
|
||||
<model_class>HistoryDatasetAssociation</model_class>
|
||||
<test type="isinstance" test_attr="datatype" result_type="datatype">tabular.Tabular</test>
|
||||
<test type="isinstance" test_attr="datatype" result_type="datatype">data.Text</test>
|
||||
<to_param param_attr="id">dataset_id</to_param>
|
||||
</data_source>
|
||||
</data_sources>
|
||||
<params>
|
||||
<param type="dataset" var_name_in_template="hda" required="true">dataset_id</param>
|
||||
</params>
|
||||
<entry_point entry_point_type="mako">ipython.mako</entry_point>
|
||||
</interactive_environment>
|
||||
@@ -1,85 +0,0 @@
|
||||
function message_failed_auth(password){
|
||||
toastr.info(
|
||||
"Automatic authorization failed. You can manually login with:<br>" + password + "<br> <a href='https://github.com/bgruening/galaxy-ipython/wiki/Automatic-Authorization-Failed' target='_blank'>More details ...</a>",
|
||||
"Please login manually",
|
||||
{'closeButton': true, 'timeOut': 100000, 'tapToDismiss': false}
|
||||
);
|
||||
}
|
||||
|
||||
function message_failed_connection(){
|
||||
toastr.error(
|
||||
"Could not connect to IPython Notebook. Please contact your administrator. <a href='https://github.com/bgruening/galaxy-ipython/wiki/Could-not-connect-to-IPython-Notebook' target='_blank'>More details ...</a>",
|
||||
"Security warning",
|
||||
{'closeButton': true, 'timeOut': 20000, 'tapToDismiss': true}
|
||||
);
|
||||
}
|
||||
|
||||
function message_no_auth(){
|
||||
// No longer a security issue, proxy validates Galaxy session token.
|
||||
/*
|
||||
toastr.warning(
|
||||
"IPython Notebook was lunched without authentication. This is a security issue. <a href='https://github.com/bgruening/galaxy-ipython/wiki/IPython-Notebook-was-lunched-without-authentication' target='_blank'>More details ...</a>",
|
||||
"Security warning",
|
||||
{'closeButton': true, 'timeOut': 20000, 'tapToDismiss': false}
|
||||
);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load an interactive environment (IE) from a remote URL
|
||||
* @param {String} password: password used to authenticate to the remote resource
|
||||
* @param {String} notebook_login_url: URL that should be POSTed to for login
|
||||
* @param {String} notebook_access_url: the URL embeded in the page and loaded
|
||||
*
|
||||
*/
|
||||
function load_notebook(password, notebook_login_url, notebook_access_url){
|
||||
$( document ).ready(function() {
|
||||
// Test notebook_login_url for accessibility, executing the login+load function whenever
|
||||
// we've successfully connected to the IE.
|
||||
test_ie_availability(notebook_login_url, function(){
|
||||
_handle_notebook_loading(password, notebook_login_url, notebook_access_url);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Must be implemented by IEs
|
||||
*/
|
||||
function _handle_notebook_loading(password, notebook_login_url, notebook_access_url){
|
||||
if ( ie_password_auth ) {
|
||||
// Make an AJAX POST
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
// to the Login URL
|
||||
url: notebook_login_url,
|
||||
// With our password
|
||||
data: {
|
||||
'password': password
|
||||
},
|
||||
xhrFields: {
|
||||
withCredentials: true
|
||||
},
|
||||
// If that is successful, load the notebook
|
||||
success: function(){
|
||||
append_notebook(notebook_access_url);
|
||||
},
|
||||
error: function(jqxhr, status, error){
|
||||
if(ie_password_auth){
|
||||
// Failure happens due to CORS
|
||||
message_failed_auth(password);
|
||||
append_notebook(notebook_access_url);
|
||||
}else{
|
||||
message_failed_connection();
|
||||
// Do we want to try and load the notebook anyway? Just in case?
|
||||
append_notebook(notebook_access_url);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
// Not using password auth, just embed it to avoid content-origin issues.
|
||||
message_no_auth();
|
||||
append_notebook(notebook_access_url);
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
<%namespace name="ie" file="ie.mako" />
|
||||
|
||||
<%
|
||||
import os
|
||||
import shutil
|
||||
import hashlib
|
||||
|
||||
# Sets ID and sets up a lot of other variables
|
||||
ie_request.load_deploy_config()
|
||||
ie_request.attr.docker_port = 6789
|
||||
ie_request.attr.import_volume = False
|
||||
|
||||
if ie_request.attr.PASSWORD_AUTH:
|
||||
m = hashlib.sha1()
|
||||
m.update( ie_request.notebook_pw + ie_request.notebook_pw_salt )
|
||||
PASSWORD = 'sha1:%s:%s' % (ie_request.notebook_pw_salt, m.hexdigest())
|
||||
else:
|
||||
PASSWORD = "none"
|
||||
|
||||
## IPython Specific
|
||||
if hda.datatype.__class__.__name__ == "Ipynb":
|
||||
DATASET_HID = hda.hid
|
||||
else:
|
||||
DATASET_HID = None
|
||||
|
||||
# Add all environment variables collected from Galaxy's IE infrastructure
|
||||
ie_request.launch(env_override={
|
||||
'notebook_password': PASSWORD,
|
||||
'dataset_hid': DATASET_HID,
|
||||
})
|
||||
|
||||
## General IE specific
|
||||
# Access URLs for the notebook from within galaxy.
|
||||
notebook_access_url = ie_request.url_template('${PROXY_URL}/ipython/notebooks/ipython_galaxy_notebook.ipynb')
|
||||
notebook_login_url = ie_request.url_template('${PROXY_URL}/ipython/login?next=${PROXY_PREFIX}%2Fipython%2Ftree')
|
||||
|
||||
%>
|
||||
<html>
|
||||
<head>
|
||||
${ ie.load_default_js() }
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script type="text/javascript">
|
||||
${ ie.default_javascript_variables() }
|
||||
var notebook_login_url = '${ notebook_login_url }';
|
||||
var notebook_access_url = '${ notebook_access_url }';
|
||||
${ ie.plugin_require_config() }
|
||||
|
||||
// Load notebook
|
||||
|
||||
requirejs(['interactive_environments', 'plugin/ipython'], function(){
|
||||
load_notebook(ie_password, notebook_login_url, notebook_access_url);
|
||||
});
|
||||
</script>
|
||||
<div id="main" width="100%" height="100%">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,43 +0,0 @@
|
||||
{
|
||||
"metadata": {
|
||||
"name": "",
|
||||
"signature": "sha256:%s"
|
||||
},
|
||||
"nbformat": 3,
|
||||
"nbformat_minor": 0,
|
||||
"worksheets": [
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "heading",
|
||||
"level": 1,
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Welcome to the interactive Galaxy IPython Notebook."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"You can access your data via the dataset number. For example, ``handle = open(get(42), 'r')``.",
|
||||
"To save data, write your data to a file, and then call ``put('filename.txt')``. The dataset will then be available in your galaxy history.",
|
||||
"Notebooks can be saved to Galaxy by clicking the large green button at the top right of the IPython interface.<br>",
|
||||
"More help and informations can be found on the project [website](https://github.com/bgruening/galaxy-ipython)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"prompt_number": 1
|
||||
}
|
||||
],
|
||||
"metadata": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,96 +1,216 @@
|
||||
id: galaxy_ui
|
||||
name: Galaxy UI
|
||||
description: A gentle introduction to the Galaxy User Interface
|
||||
title_default: "Welcome to Galaxy"
|
||||
|
||||
# A tour is made of several steps, each of them beginning with a dash '-'
|
||||
steps:
|
||||
# 'title's will be displayed in the header of each step-container
|
||||
# If you don't specify any title, a default title is used, defined above.
|
||||
- title: "Welcome to Galaxy"
|
||||
content: "This short tour will walk you through Galaxy's user interface."
|
||||
# 'content' is the actual text that is shown to the user
|
||||
content: "This short tour will guide you through Galaxy's user interface.<br>
|
||||
You can navigate with your arrow keys and leave the tour at any time point with 'Escape' or the 'End tour' button."
|
||||
# backdrop is just one of many properties you can attach to one step-container,
|
||||
# a full reference can be found at http://bootstraptour.com/api/
|
||||
backdrop: true
|
||||
|
||||
- element: ".upload-button"
|
||||
intro: "Use this button to upload your data."
|
||||
# 'element' is the JQuery Selector (http://api.jquery.com/category/selectors/) of the element you want to describe
|
||||
# In this case we want to highlight the Upload button with the `.upload-button` selector
|
||||
- title: "Upload your data"
|
||||
element: ".upload-button"
|
||||
intro: "Galaxy supports many ways to get in your data.<br>
|
||||
Use this button to upload your data."
|
||||
# position of the text box relative to the selected element
|
||||
position: "right"
|
||||
# You can trigger click() events on arbitrary elements before (preclick) or after (postclick) the element is shown
|
||||
postclick:
|
||||
- ".upload-button"
|
||||
|
||||
- element: "button#btn-local"
|
||||
intro: "Upload data from your computer."
|
||||
- title: "Upload your data"
|
||||
element: "button#btn-local"
|
||||
intro: "You can upload data from your computer."
|
||||
position: "top"
|
||||
postclick:
|
||||
- "button#btn-new"
|
||||
- element: "button#btn-new"
|
||||
intro: "Copy and Paste data or include URLs."
|
||||
|
||||
- title: "Upload your data"
|
||||
element: "button#btn-new"
|
||||
intro: "Copy and paste data directly into Galaxy or include URLs that lead to your data"
|
||||
position: "top"
|
||||
preclick:
|
||||
- ".upload-button"
|
||||
|
||||
- element: "textarea#text-content"
|
||||
intro: "Insert data into Galaxy."
|
||||
- title: "Insert URLs"
|
||||
element: "textarea#text-content"
|
||||
intro: "URLs separated by a line break are automatically downloaded by Galaxy."
|
||||
position: "top"
|
||||
textinsert: |
|
||||
https://raw.githubusercontent.com/arq5x/bedtools/master/test/merge/a.full.bed
|
||||
https://raw.githubusercontent.com/arq5x/bedtools/master/test/merge/a.full.bed
|
||||
https://raw.githubusercontent.com/arq5x/bedtools/master/test/merge/a.full.bed
|
||||
https://raw.githubusercontent.com/bgruening/galaxytools/adf077b912ddebd97b07b947b855cdd2862ed8ef/tools/augustus/test-data/human_augustus.fa
|
||||
https://raw.githubusercontent.com/bgruening/galaxytools/adf077b912ddebd97b07b947b855cdd2862ed8ef/tools/sailfish/test-data/reads_2.fastq
|
||||
https://raw.githubusercontent.com/bgruening/galaxytools/adf077b912ddebd97b07b947b855cdd2862ed8ef/tools/statistics/test-data/anderson.tabular
|
||||
|
||||
- element: "button#btn-start"
|
||||
- title: "Start the upload"
|
||||
element: "button#btn-start"
|
||||
intro: "Upload the data into your Galaxy history."
|
||||
position: "bottom"
|
||||
position: "top"
|
||||
postclick:
|
||||
- "button#btn-start"
|
||||
|
||||
- element: "button#btn-close"
|
||||
intro: "Hit the close button in upload."
|
||||
position: "bottom"
|
||||
- title: "Close upload/download manager"
|
||||
element: "button#btn-close"
|
||||
intro: "Close the upload manager with this button or with a click outside of the manager window."
|
||||
position: "top"
|
||||
postclick:
|
||||
- "#btn-close"
|
||||
|
||||
- title: "Tools"
|
||||
element: "#left"
|
||||
intro: "This is your ToolBox. All tools available in your Galaxy instance you can find here."
|
||||
position: "right"
|
||||
|
||||
- element: 'a[href$="tool_runner?tool_id=Filter1"]'
|
||||
- title: "Tool search bar"
|
||||
element: '#tool-search-query'
|
||||
intro: "You can search for tools by keywords."
|
||||
position: "right"
|
||||
textinsert: 'filter'
|
||||
|
||||
- title: "Tool categories"
|
||||
element: '#title_filter > a'
|
||||
intro: "Tools are grouped into categories to make them easier to find."
|
||||
position: "right"
|
||||
preclick:
|
||||
- 'a[href$="tool_runner?tool_id=Filter1"]'
|
||||
postclick:
|
||||
- "#title_filter a"
|
||||
|
||||
- element: '#center-panel'
|
||||
intro: "This is your Filter tool."
|
||||
- title: "Select a tool"
|
||||
element: 'a[href$="tool_runner?tool_id=Filter1"]'
|
||||
intro: "Select and load a tool for your analysis by clicking the underlined link."
|
||||
position: "right"
|
||||
preclick:
|
||||
- '#center-panel'
|
||||
postclick:
|
||||
- 'a[href$="tool_runner?tool_id=Filter1"]'
|
||||
|
||||
- element: '#uid-0'
|
||||
intro: "Your tool parameters."
|
||||
- title: "Filter Tool"
|
||||
element: '#center-panel'
|
||||
intro: "Your tool is loaded into the main Galaxy page and ready for use."
|
||||
position: "right"
|
||||
#backdropContainer: 'background'
|
||||
#backdrop: true
|
||||
|
||||
- title: "Tool parameters"
|
||||
element: '#uid-0'
|
||||
intro: "Here you can choose your tool parameters. Select your input dataset from your history and specify parameters for your analysis."
|
||||
position: "right"
|
||||
|
||||
- element: 'div.toolHelp'
|
||||
intro: "Your tool parameters."
|
||||
- title: "Tool help"
|
||||
element: 'div.ui-form-help'
|
||||
intro: "Every Galaxy tool has a help section with detailed information about the tool and its parameters.
|
||||
Have a look and study your tool in depth by reading it."
|
||||
position: "top"
|
||||
|
||||
- title: "Run your tool"
|
||||
element: '#execute'
|
||||
intro: "Click on 'Execute' to run your tool and send it to the compute cluster.
|
||||
Don't be afraid to test different settings in parallel. Galaxy can handle multiple runs of the same tool."
|
||||
position: "right"
|
||||
- element: '#execute'
|
||||
intro: "Send your tool to the Compute Cluster."
|
||||
position: "right"
|
||||
preclick:
|
||||
postclick:
|
||||
- '#execute'
|
||||
- element: "#right"
|
||||
intro: "This is your history! All anylysis steps will be recorded and can be redone at any time."
|
||||
|
||||
- title: "History"
|
||||
element: "#right"
|
||||
intro: "This is your Galaxy history! All analysis steps with results of the tools and their parameters will be recorded here and can be redone at any time.<br>
|
||||
A running tool is shown in yellow and if your calculation is done, it turns green. If your dataset is
|
||||
grey this means you are queued and need to wait until your tool can be started. If your dataset turns into red, an error has occurred. Please report the bug to the Galaxy team with the bug report button."
|
||||
position: "left"
|
||||
- element: "#masthead"
|
||||
intro: "Your top panel will give you access to a lot of useful things."
|
||||
|
||||
- title: "Rename history"
|
||||
element: "#current-history-panel > div.controls > div.title > div"
|
||||
intro: "Name your history here and press enter."
|
||||
position: "left"
|
||||
preclick:
|
||||
- "#current-history-panel > div.controls > div.title > div"
|
||||
|
||||
- title: "View dataset"
|
||||
element: ".fa-eye:eq(0)"
|
||||
intro: "View your dataset by clicking the eye button."
|
||||
position: "left"
|
||||
#preclick:
|
||||
# - ".fa-eye:eq(0)"
|
||||
|
||||
- title: "Rename dataset"
|
||||
element: ".fa-pencil:eq(0)"
|
||||
intro: "Rename your dataset by clicking the pencil button."
|
||||
position: "left"
|
||||
#preclick:
|
||||
# - ".fa-pencil:eq(0)"
|
||||
|
||||
- title: "Remove dataset"
|
||||
element: ".fa-times:eq(0)"
|
||||
intro: "Delete your dataset by clicking the x-button."
|
||||
position: "left"
|
||||
#postclick:
|
||||
# - ".fa-times:eq(0)"
|
||||
|
||||
- title: "Dataset information"
|
||||
element: "div.title-bar.clear:eq(0)"
|
||||
intro: "Clicking on your dataset provides you with more information regarding your dataset (e.g. filetype or size)."
|
||||
position: "left"
|
||||
preclick:
|
||||
- "div.title-bar.clear:eq(0)"
|
||||
|
||||
- title: "Re-run tool"
|
||||
element: ".fa-refresh:eq(1)"
|
||||
intro: "By clicking the reload button, you can re-run your tool again (e.g. with different parameters or on another dataset)."
|
||||
position: "left"
|
||||
preclick:
|
||||
- ".fa-refresh:eq(1)"
|
||||
|
||||
|
||||
- title: "Panel collaps"
|
||||
element: "#left > div.unified-panel-footer > div.panel-collapse.left"
|
||||
intro: "To extend the view for your main Galaxy page in the middle, you can collapse the tool panel on the left hand side. Clicking the panel arrow on the right hand side, collapses the history."
|
||||
position: "top"
|
||||
postclick:
|
||||
- "#left > div.unified-panel-footer > div.panel-collapse.left"
|
||||
|
||||
- title: 'Top panel'
|
||||
element: "#masthead"
|
||||
intro: "The top panel will give you access to a lot of useful things."
|
||||
position: "bottom"
|
||||
- element: "#analysis"
|
||||
intro: "Start your <b>analysis</b> from here."
|
||||
|
||||
- title: 'Analyze data'
|
||||
element: "#analysis"
|
||||
intro: "This is the current view. Start your <b>analysis</b> from here."
|
||||
position: "bottom"
|
||||
- element: "#workflow"
|
||||
intro: "Manage, Import, Export and Share your <b>Workflows</b>."
|
||||
|
||||
- title: 'Workflow'
|
||||
element: "#workflow"
|
||||
intro: "Create, manage, import, export and share your <b>Workflows</b>."
|
||||
position: "bottom"
|
||||
- element: "#shared"
|
||||
intro: "Get access to all <b>Workflows, <b>Histories</b>, <b>Pages</b>, <b>Visualizations</b> and you <b>Data Library</b> that are shared with you."
|
||||
|
||||
- title: 'Shared data'
|
||||
element: "#shared"
|
||||
intro: "Get access to all <b>Workflows</b>, <b>Histories</b>, <b>Pages</b>, <b>Visualizations</b> and your <b>Data Library</b> that are shared with you."
|
||||
position: "bottom"
|
||||
- element: "#visualization"
|
||||
intro: "Want to start visualize your data in Trackster? Start here!"
|
||||
|
||||
- title: 'Visualization'
|
||||
element: "#visualization"
|
||||
intro: "Do you want to start to visualize your data in Trackster? Start here!<br>Galaxy offers a lot more visualizations!"
|
||||
position: "bottom"
|
||||
- element: "#help"
|
||||
intro: "Here you get more help from the Galaxy <b>Community</b> with Videos and a QA board."
|
||||
|
||||
- title: 'Help'
|
||||
element: "#help"
|
||||
intro: "Here you get more help from the Galaxy <b>Community</b> with Videos, a QA board and more tours."
|
||||
position: "bottom"
|
||||
- element: "#user"
|
||||
|
||||
- title: 'User Preferences'
|
||||
element: "#user"
|
||||
intro: "Login and start your analysis!"
|
||||
position: "bottom"
|
||||
|
||||
- title: 'Scratchbook'
|
||||
element: "#enable-scratchbook"
|
||||
intro: "Scratchbook offers you multiple visualizations next to each other. Have a look at our Scratchbook tour to learn more about it."
|
||||
position: "bottom"
|
||||
|
||||
- title: "Enjoy Galaxy"
|
||||
intro: "Thanks for taking this tour! Happy research with Galaxy!"
|
||||
|
||||
@@ -1,90 +1,95 @@
|
||||
name: History Introduction
|
||||
description: A detailed introduction to the <b>Galaxy History</b>
|
||||
description: A detailed introduction to the Galaxy History
|
||||
title_default: "Galaxy History Introduction"
|
||||
steps:
|
||||
- content: "This short tour will walk you through <b>Galaxy's History</b> and datasets."
|
||||
- content: "This short tour will guide you through <b>Galaxy's History</b> and datasets."
|
||||
|
||||
- element: ".upload-button"
|
||||
- title: "Upload data"
|
||||
element: ".upload-button"
|
||||
intro: |
|
||||
At first we get some data into your Galaxy and into your History.<br>
|
||||
Use this button to upload your data.
|
||||
"At first we upload some data into your Galaxy history.<br>
|
||||
Use this button to upload your data."
|
||||
position: "right"
|
||||
postclick:
|
||||
- ".upload-button"
|
||||
|
||||
- element: "button#btn-local"
|
||||
intro: "Upload data from your computer."
|
||||
- title: "Upload your data"
|
||||
element: "button#btn-local"
|
||||
intro: "You can upload data from your computer."
|
||||
position: "top"
|
||||
postclick:
|
||||
- "button#btn-new"
|
||||
|
||||
- element: "button#btn-new"
|
||||
intro: "Copy and Paste data or include URLs to data which will be fetched automatically by Galaxy."
|
||||
- title: "Upload your data"
|
||||
element: "button#btn-new"
|
||||
intro: "Copy and paste data directly into Galaxy or include URLs that lead to your data."
|
||||
position: "top"
|
||||
|
||||
- element: "textarea#text-content"
|
||||
intro: "We insert some URLs to get example data in Galaxy."
|
||||
- title: "Insert URLs"
|
||||
element: "textarea#text-content"
|
||||
intro: "URLs separated by a line break are automatically downloaded by Galaxy."
|
||||
position: "bottom"
|
||||
textinsert: |
|
||||
file://home/bag/Bilder/Python-Programming-in-Galaxy.png
|
||||
file://home/bag/Downloads/a.tab
|
||||
https://wiki.galaxyproject.org/Images/GalaxyLogo?action=AttachFile&do=get&target=galaxy_project_logo.jpg
|
||||
https://raw.githubusercontent.com/bgruening/galaxytools/adf077b912ddebd97b07b947b855cdd2862ed8ef/tools/statistics/test-data/anderson.tabular
|
||||
|
||||
- element: "button#btn-start"
|
||||
- title: "Upload your data"
|
||||
element: "button#btn-start"
|
||||
intro: "Upload the data into your Galaxy <b>History</b>."
|
||||
position: "bottom"
|
||||
position: "top"
|
||||
postclick:
|
||||
- "button#btn-start"
|
||||
- "button#btn-close"
|
||||
|
||||
- element: "#right"
|
||||
intro: "This is your history! All anylysis steps will be recorded and can be redone at any time."
|
||||
- title: "History"
|
||||
element: "#right"
|
||||
intro: "This is your history! All analysis steps will be recorded and can be redone at any time."
|
||||
position: "left"
|
||||
|
||||
- element: "#dataset-2d9035b3fc152403"
|
||||
- title: "Dataset information"
|
||||
element: "div.title-bar.clear:eq(0)"
|
||||
intro: "This is one of your uploaded datasets. You can get more informations and options like different visualizations by clicking on it."
|
||||
position: "left"
|
||||
postclick:
|
||||
- "#dataset-2d9035b3fc152403 > div.title-bar.clear > div > span.name"
|
||||
- "div.title-bar.clear:eq(0)"
|
||||
|
||||
- element: "#dataset-2d9035b3fc152403 > div.details > div.summary > div.datatype > label"
|
||||
title: "Metadata"
|
||||
intro: "Galaxy has assigned a datatype too your dataset during upload, which you can see here."
|
||||
- title: "Metadata"
|
||||
element: "#current-history-panel > div.list-items > div:nth-child(1) > div.details > div.summary > div.datatype > label"
|
||||
intro: "Galaxy has assigned a datatype to your dataset during upload, which you can see here."
|
||||
position: "left"
|
||||
|
||||
- element: "#dataset-2d9035b3fc152403 > div.details > div.actions.clear > div.left > a.download-btn.icon-btn"
|
||||
- element: "#current-history-panel > div.list-items > div:nth-child(1) > div.details > div.actions.clear > div.left > a.download-btn.icon-btn"
|
||||
title: "Download your dataset"
|
||||
intro: "You can download every dataset by using the floppy disc symbol."
|
||||
position: "left"
|
||||
|
||||
- element: "#dataset-2d9035b3fc152403 > div.details > div.actions.clear > div.left > a.icon-btn.params-btn"
|
||||
- element: "#current-history-panel > div.list-items > div:nth-child(1) > div.details > div.actions.clear > div.left > a.icon-btn.params-btn"
|
||||
title: "Even more information"
|
||||
intro: "Get an overview of all metadata associated with your dataset by using the Information symbol."
|
||||
position: "left"
|
||||
preclick:
|
||||
- "#dataset-2d9035b3fc152403 > div.details > div.actions.clear > div.left > a.icon-btn.params-btn"
|
||||
- "#current-history-panel > div.list-items > div:nth-child(1) > div.details > div.actions.clear > div.left > a.icon-btn.params-btn"
|
||||
|
||||
|
||||
|
||||
- element: "#dataset-2d9035b3fc152403 > div.primary-actions > a.icon-btn.display-btn"
|
||||
- element: "#current-history-panel > div.list-items > div:nth-child(1) > div.primary-actions > a.icon-btn.display-btn"
|
||||
title: "Inspect your data"
|
||||
intro: "The eye symbol can be used to look at your data."
|
||||
position: "left"
|
||||
preclick:
|
||||
- "#dataset-2d9035b3fc152403 > div.primary-actions > a.icon-btn.display-btn"
|
||||
- "#current-history-panel > div.list-items > div:nth-child(1) > div.primary-actions > a.icon-btn.display-btn"
|
||||
|
||||
- element: "#dataset-2d9035b3fc152403 > div.primary-actions > a.icon-btn.edit-btn"
|
||||
- element: "#current-history-panel > div.list-items > div:nth-child(1) > div.primary-actions > a.icon-btn.edit-btn"
|
||||
title: "Edit metadata"
|
||||
intro: "With the pencil button you can edit metadata attributes of your dataset, like the associated filetype or the dataset name."
|
||||
position: "left"
|
||||
preclick:
|
||||
- "#dataset-2d9035b3fc152403 > div.primary-actions > a.icon-btn.edit-btn"
|
||||
- "#current-history-panel > div.list-items > div:nth-child(1) > div.primary-actions > a.icon-btn.edit-btn"
|
||||
|
||||
- element: "#dataset-2d9035b3fc152403 > div.primary-actions > a.icon-btn.delete-btn"
|
||||
- element: "#current-history-panel > div.list-items > div:nth-child(1) > div.primary-actions > a.icon-btn.delete-btn"
|
||||
title: "Remove datasets"
|
||||
intro: "You can remove a dataset from the history with the cross symbol."
|
||||
position: "left"
|
||||
postclick:
|
||||
- "#dataset-2d9035b3fc152403 > div.primary-actions > a.icon-btn.delete-btn"
|
||||
- "#current-history-panel > div.list-items > div:nth-child(1) > div.primary-actions > a.icon-btn.delete-btn"
|
||||
|
||||
- element: "#current-history-panel > div.controls > div.subtitle > a"
|
||||
title: "Include all deleted datasets"
|
||||
@@ -93,14 +98,14 @@ steps:
|
||||
postclick:
|
||||
- "#current-history-panel > div.controls > div.subtitle > a"
|
||||
|
||||
- element: "#dataset-2d9035b3fc152403 > div.warnings > div > a"
|
||||
- element: "#current-history-panel > div.list-items > div:nth-child(1) > div.warnings > div > a"
|
||||
title: "Undeleting a dataset"
|
||||
intro: |
|
||||
"Galaxy datasets are only marked as deleled and can be recovered by exeecuting this link.
|
||||
Please note that datasets marked as deleted can be purged by your administrator at any time. :beer: "
|
||||
Galaxy datasets are only marked as deleled and can be recovered by clicking this link.
|
||||
Please note that datasets marked as deleted can be purged by your administrator at any time.
|
||||
position: "bottom"
|
||||
postclick:
|
||||
- "#dataset-2d9035b3fc152403 > div.warnings > div > a"
|
||||
- "#current-history-panel > div.list-items > div:nth-child(1) > div.warnings > div > a"
|
||||
|
||||
- element: "#current-history-panel > div.controls > div.subtitle > a"
|
||||
title: "Hiding all deleted datasets"
|
||||
@@ -111,7 +116,7 @@ steps:
|
||||
|
||||
- element: "#current-history-panel > div.controls > div.title > div"
|
||||
title: "Change your History name"
|
||||
intro: "You can change the history name clicking on the title"
|
||||
intro: "You can change the history name clicking on the title."
|
||||
position: "bottom"
|
||||
preclick:
|
||||
- "#current-history-panel > div.controls > div.title > div"
|
||||
@@ -122,11 +127,11 @@ steps:
|
||||
position: "left"
|
||||
textinsert: "WWFSMD"
|
||||
preclick:
|
||||
- "#current-history-panel > div.controls > div.search > div > input"
|
||||
- "#current-history-panel > div.controls > div.search > div > input"
|
||||
|
||||
- element: "#history-options-button"
|
||||
title: "History Options"
|
||||
intro: "In the History menue you will find a lot more usful History options."
|
||||
intro: "In the History menu you will find a lot more useful History options."
|
||||
position: "left"
|
||||
postclick:
|
||||
- "#history-options-button"
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
name: Scratchbook - Introduction
|
||||
title_default: "Scratchbook Introduction"
|
||||
description: "An introduction on how to display multiple datasets and visualizations next to each other."
|
||||
steps:
|
||||
- content: "This short tour will walk you through <b>Galaxy's Scratchbook</b> feature"
|
||||
|
||||
- element: "#tool-panel-upload-button"
|
||||
intro: "Before using the Scratchbook, we will upload some tabular data."
|
||||
position: "right"
|
||||
postclick:
|
||||
- "#tool-panel-upload-button"
|
||||
|
||||
- element: "#btn-new"
|
||||
intro: "We will be using the paste feature to create a new dataset."
|
||||
position: "top"
|
||||
postclick:
|
||||
- "#btn-new"
|
||||
|
||||
- element: ".text-content:first"
|
||||
intro: "...and paste content into the text area field."
|
||||
position: "top"
|
||||
textinsert: |
|
||||
1 0.039 0.000
|
||||
2 0.455 0.000
|
||||
3 0.472 0.000
|
||||
4 0.030 0.000
|
||||
5 0.000 0.000
|
||||
6 0.000 0.000
|
||||
7 0.000 0.000
|
||||
8 0.000 0.000
|
||||
|
||||
- element: ".upload-settings:first"
|
||||
intro: "Now, we may further configure the upload content."
|
||||
position: "right"
|
||||
postclick:
|
||||
- ".upload-settings:first"
|
||||
|
||||
- element: ".upload-space_to_tab:first"
|
||||
intro: "...by specifying that all spaces in our table should be converted into tabs."
|
||||
position: "left"
|
||||
postclick:
|
||||
- ".upload-space_to_tab:first"
|
||||
|
||||
- element: "#btn-start"
|
||||
intro: "Upload the data into your Galaxy history."
|
||||
position: "top"
|
||||
postclick:
|
||||
- "#btn-start"
|
||||
|
||||
- element: "#btn-close"
|
||||
intro: "Hit the close button to close the upload dialog."
|
||||
position: "top"
|
||||
postclick:
|
||||
- "#btn-close"
|
||||
|
||||
- element: "#enable-scratchbook > .dropdown > .dropdown-toggle"
|
||||
intro: "Clicking this button will enable Galaxy's Scratchbook mode."
|
||||
position: "right"
|
||||
postclick:
|
||||
- "#enable-scratchbook > .dropdown > .dropdown-toggle"
|
||||
|
||||
- element: "#right"
|
||||
intro: "This is your history. It contains all datasets you are currently working with including our uploaded table."
|
||||
position: "left"
|
||||
|
||||
- element: ".fa-eye:first"
|
||||
intro: "Clicking the eye-icon usually displays a dataset in the center panel."
|
||||
position: "left"
|
||||
postclick:
|
||||
- ".fa-eye:first"
|
||||
|
||||
- element: "#frame-0"
|
||||
intro: "However while in Scratchbook mode, the dataset will be shown as resizable window."
|
||||
position: "right"
|
||||
|
||||
- title: "Done."
|
||||
intro: "You have created a Scratchbook view. Click on the background and select more datasets."
|
||||
File diff suppressed because one or more lines are too long
+24
-2
@@ -169,6 +169,7 @@ class Configuration( object ):
|
||||
self.job_queue_cleanup_interval = int( kwargs.get("job_queue_cleanup_interval", "5") )
|
||||
self.cluster_files_directory = os.path.abspath( kwargs.get( "cluster_files_directory", "database/pbs" ) )
|
||||
self.job_working_directory = resolve_path( kwargs.get( "job_working_directory", "database/job_working_directory" ), self.root )
|
||||
self.default_job_shell = kwargs.get( "default_job_shell", "/bin/sh" )
|
||||
self.cleanup_job = kwargs.get( "cleanup_job", "always" )
|
||||
self.container_image_cache_path = self.resolve_path( kwargs.get( "container_image_cache_path", "database/container_images" ) )
|
||||
self.outputs_to_working_directory = string_as_bool( kwargs.get( 'outputs_to_working_directory', False ) )
|
||||
@@ -258,8 +259,11 @@ class Configuration( object ):
|
||||
self.log_events = string_as_bool( kwargs.get( 'log_events', 'False' ) )
|
||||
self.sanitize_all_html = string_as_bool( kwargs.get( 'sanitize_all_html', True ) )
|
||||
self.sanitize_whitelist_file = resolve_path( kwargs.get( 'sanitize_whitelist_file', "config/sanitize_whitelist.txt" ), self.root )
|
||||
self.reload_sanitize_whitelist()
|
||||
self.sanitize_whitelist = []
|
||||
if kwargs.get('sanitize_whitelist_file', None) is not None:
|
||||
self.reload_sanitize_whitelist()
|
||||
self.serve_xss_vulnerable_mimetypes = string_as_bool( kwargs.get( 'serve_xss_vulnerable_mimetypes', False ) )
|
||||
self.allowed_origin_hostnames = self._parse_allowed_origin_hostnames( kwargs )
|
||||
self.trust_ipython_notebook_conversion = string_as_bool( kwargs.get( 'trust_ipython_notebook_conversion', False ) )
|
||||
self.enable_old_display_applications = string_as_bool( kwargs.get( "enable_old_display_applications", "True" ) )
|
||||
self.brand = kwargs.get( 'brand', None )
|
||||
@@ -480,7 +484,7 @@ class Configuration( object ):
|
||||
if not line.startswith("#"):
|
||||
self.sanitize_whitelist.append(line.strip())
|
||||
except IOError:
|
||||
log.warning("Sanitize log file %s does not exist, continuing with no tools whitelisted.")
|
||||
log.warning("Sanitize log file %s does not exist, continuing with no tools whitelisted.", self.sanitize_whitelist_file)
|
||||
|
||||
def __parse_config_file_options( self, kwargs ):
|
||||
"""
|
||||
@@ -669,6 +673,24 @@ class Configuration( object ):
|
||||
port = None
|
||||
return port
|
||||
|
||||
def _parse_allowed_origin_hostnames( self, kwargs ):
|
||||
"""
|
||||
Parse a CSV list of strings/regexp of hostnames that should be allowed
|
||||
to use CORS and will be sent the Access-Control-Allow-Origin header.
|
||||
"""
|
||||
allowed_origin_hostnames = listify( kwargs.get( 'allowed_origin_hostnames', None ) )
|
||||
if not allowed_origin_hostnames:
|
||||
return None
|
||||
|
||||
def parse( string ):
|
||||
# a string enclosed in fwd slashes will be parsed as a regexp: e.g. /<some val>/
|
||||
if string[0] == '/' and string[-1] == '/':
|
||||
string = string[1:-1]
|
||||
return re.compile( string, flags=( re.UNICODE | re.LOCALE ) )
|
||||
return string
|
||||
|
||||
return [ parse( v ) for v in allowed_origin_hostnames if v ]
|
||||
|
||||
|
||||
def get_database_engine_options( kwargs, model_prefix='' ):
|
||||
"""
|
||||
|
||||
@@ -81,6 +81,7 @@ class TabularData( data.Text ):
|
||||
# For now, default to the old behavior, ugly as it is. Remove this after adding 'matrix'.
|
||||
max_peek_size = 1000000 # 1 MB
|
||||
if os.stat( dataset.file_name ).st_size < max_peek_size:
|
||||
self._clean_and_set_mime_type( trans, dataset.get_mime() )
|
||||
return open( dataset.file_name )
|
||||
else:
|
||||
trans.response.set_content_type( "text/html" )
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
# packages with C extensions
|
||||
bx-python==0.7.3 --hash:sha256=0a0fd962edd0f9afdf5d7ccbdf46dc220a0cb652073a93411dd6f7f649f07d91 \
|
||||
--hash:sha256=46dc3042c7e475363830fa92d4a613ae10b58db7f114ff8193d2ee0bc3c4607e \
|
||||
--hash:sha256=b93a9378a5d0e29ea8a13e026c170f48bf1f8316a39c342b1eb54f557b4fb3c4 \
|
||||
--hash:sha256=d06c7bf0ae7f019521aeb5ffe4df48bb5fdd4d75d7ad00e0059b997c4f13ca3a \
|
||||
--hash:sha256=05d0ab8fd13319d5ef9edb246dc6805640ea7574bb885a0b8607474271ac5793 \
|
||||
--hash:sha256=5a026869227a6464eba23835765a36ffc2910f7af51b81f672a97c0d005e04a3 \
|
||||
--hash:sha256=85be43a6b94f0c841d9954f820133db35067854504c1de87dd0089bb06eca18d \
|
||||
--hash:sha256=d085824eb33c54d333b99dca29b49890457a8263f431b54b17ae3052be191d2b \
|
||||
--hash:sha256=41bcf85b9be9f61ba7c7bae48c5a5ae3251868a1b25f02b6eb93b29bcabfd00c \
|
||||
--hash:sha256=c9b71aee26ee85fbcbb3060109d79531bfa8991f4924bdcfed63d909a5937290
|
||||
MarkupSafe==0.23 --hash:sha256=3a79d9650b7e79943be51a045c7c39a77ebbe9a337e8af51a5575e39332dce87 \
|
||||
--hash:sha256=e0a4155493d1cfa72e985dbe1660a44d64a173282801563956e061b24371266a \
|
||||
--hash:sha256=147013ed157f1423a0d0047043c6bbccbef31a52d82e2a10dfc3c6de9392765c \
|
||||
--hash:sha256=d25d14cb01284aed33690b85bfde8de206ffcfdc52351588bcf17480839bef6f \
|
||||
--hash:sha256=29958f81958e0dd9f5dd36d52f2ac549d875dde3559b783578118c9005693852 \
|
||||
--hash:sha256=287a1c6b0d2a08cb76be6e584bf119649405f015598cf8b78d4a592cc80700a0 \
|
||||
--hash:sha256=973cadf7b9907f9c81d9b898817d6a485b37325176befec2389fa2ced4c61a51 \
|
||||
--hash:sha256=a365fd3468c86741aec5901f4b07990aaa0b458fb79e9f3557378a63e6d627e9 \
|
||||
--hash:sha256=ba7af558b18ba9c05bb0d36f22a5ea65ee11ba44a6cf8a2950f2f80c08260e11 \
|
||||
--hash:sha256=51bf7f077938c64dd00de6732996ccee8ceba2206c69acfb07f66430ca76372f
|
||||
PyYAML==3.11 --hash:sha256=2912c1fb56c316461d003a8b8f1f41e1ed8387b2e47a4523f8a4eec8aa85e241 \
|
||||
--hash:sha256=f4437443dc014c04ceee8cc94d4165f01ba23643991fd2c6b919f26cf9997474 \
|
||||
--hash:sha256=b62cde962d41377c175831fa3fd6ac41585d2e2111ca4c45a6ee80a832457e92 \
|
||||
--hash:sha256=aad37be9d524ba2dba9a3114b620b2800b40e67e455c9741a5cb81a6a0e882f6 \
|
||||
--hash:sha256=03e0f4ac96599c1d687b080f1610ab0469e8785bb48cfdf860f2076a08ea6406 \
|
||||
--hash:sha256=7dc97b5b1b920f6bbe0e47cfa6ff112f6eede35924a63354f80d672354f25160 \
|
||||
--hash:sha256=ceb5dccec2045d4a864c6e808b397b10830476c44bdc64b80c18bf29e481ba07 \
|
||||
--hash:sha256=9b184a4a7d3d383b39cb73429d3798370facaee4263465b575f243c7ede3f9c3 \
|
||||
--hash:sha256=f90314e2ed46ea2da980aff88b91c3cc8ce93edd4658011dd462a8f28399533b \
|
||||
--hash:sha256=80936dca10b611cd54ca52939aac938d59653830a6a6265bef5d11896de8e249
|
||||
SQLAlchemy==1.0.8 --hash:sha256=3c357f36c141205cea2b5ec4c4e9885602452fea06428d6c20596c66c9a43243 \
|
||||
--hash:sha256=17fad7f37f902dbec37ca2777af3021f9a4ed31079d64f7f888e7b29517240a3 \
|
||||
--hash:sha256=e177904a384b9bc68914afb32a6ed2cc73ed7787444e3e1fdf85e3b9cfe5f847 \
|
||||
--hash:sha256=91ed10baf56b6e29665f2b9fcb0c690afc6cc2c2e8e19c7f92b58092a4002e14 \
|
||||
--hash:sha256=f5d6156d1d7865cd23b76ddad3f53ec07a3009a2cd8082a829cd1f24b366db5c \
|
||||
--hash:sha256=3c3f3baf07f868c1c3f86d63dc2efa4455e95d76745f1af561f1ccf0fd9e8c81 \
|
||||
--hash:sha256=a9fb8061aa767ca2ad22983a11e074ac231f44a56709721c60cc1992f2a92350 \
|
||||
--hash:sha256=884b522d2d067cffd103f4e1a5342c678803cd6903da24a3f757b57b00eb188b \
|
||||
--hash:sha256=d5dde66c1603853aebbfbbd74d79c60678f7d98c17abce4be4ebbb697dfd7265 \
|
||||
--hash:sha256=42346d5e91c5e0a5a975352d8af3cfd8b2dad602dd07ec41b6b848ac5205cf5b
|
||||
# Mercurial >= 3.5 changed the bundle format, which breaks hg push of TS repositories
|
||||
mercurial==3.4.2 --hash:sha256=7851864b03929c09e07670bf8ab7d59f3529650c935a70d09fb6ce7f6a84e2a5 \
|
||||
--hash:sha256=c23b02b4c32edc2d0799221a9d35abd916fb8a1acd1c07d64c16a235ef677b9e \
|
||||
--hash:sha256=ca72ddfaea681a070b62edcb8e41d58bd24a2b04f73e66658565d189a76f3819 \
|
||||
--hash:sha256=fdad4496f3d7f3e7eced771fa46e21c074989f8437ddf3e0ff6c0eee964e4c29 \
|
||||
--hash:sha256=964a10ec1114dbee3696134bafed676f66038759b73de8593f92616f0e53f371 \
|
||||
--hash:sha256=c6ca6fbe56a8919dfc521e80ab781ab565760d87f4a6170e788d67eb6d69d30f \
|
||||
--hash:sha256=69540318fa9f7a3a0428647003d4f1fa8865d29648e73999b921cae039145ce9 \
|
||||
--hash:sha256=b3de0ee851cf8750f53102437c9a04c7217a8c6f7411030ab3bb5534885f3315 \
|
||||
--hash:sha256=46f67af52c7b1aed68b67daa33c26eafc0fb1d371954d3266fce739446cfcb1d \
|
||||
--hash:sha256=000afb932f0ae45c365cbc0457044e8800811fdad7eee9332b6403b83423ab0a
|
||||
numpy==1.9.2 --hash:sha256=931ce6fd1180a10d58a925b614775706c05de35bca5805e705e1da17e1326862 \
|
||||
--hash:sha256=2340c4b72fdab79ac0fc04bb6629b26eeb93d10f4945b6b1f07d9be8663cab84 \
|
||||
--hash:sha256=83fe34ff67653a639c57cfd04a0d48dda5913250fd95c8466af1d8416b58af59 \
|
||||
--hash:sha256=aeb182d95ddb2dfd81683907be193cfc11c4d0ba744faf457013499fa14a131e \
|
||||
--hash:sha256=d6f1eec7ae250892a2b142af406e43760042badae8e2f168136eace5dd9f05c3 \
|
||||
--hash:sha256=0b0883cac08e3c0999159ba7f34c9b94d26d7d1a2be4017b792145d722646fb7 \
|
||||
--hash:sha256=a124d11b1bec5c517d60ad9414564b5af0828421112d2a00771d22715eab1c3c \
|
||||
--hash:sha256=fabc2f76266de7396e2752baabf287cdd0cc2ed23c1f36ca3c3e8b094e86b87c \
|
||||
--hash:sha256=f83a667d3a38643b3bf6361904cd6c4f2a18d1420c2204c7f269cd36b730c404 \
|
||||
--hash:sha256=dab9bd8c867403340b370ea383c8eda3dc984dd5efc91904a5695e00b1762fc9
|
||||
pycrypto==2.6.1 --hash:sha256=44c20785a1057b8d5e190d6a1847f7c62a8180b9b27a3aca7c3ec920bfb8e7b7 \
|
||||
--hash:sha256=785ba61251cda6e574e0affc4412c346ef615455b81287fe0d6a2e1c5aed5172 \
|
||||
--hash:sha256=5ec40d95520a665843915763c8cbbf40457330bd7ebf2a55ffea1b10a519d12b \
|
||||
--hash:sha256=2cb43f0b293a18e6d5818287150994cf6083b1a9cdff65c19d1150a34aa813bc \
|
||||
--hash:sha256=d48e46f4ccd5c21f3e01bbdbd8e7a86443fc7abdf3f93829c3d04ed684ec22c5 \
|
||||
--hash:sha256=30312bd39f45c91f287f3e6e54c40988d30b1be9a9f332585e3cc00ee5f91554 \
|
||||
--hash:sha256=d129d6d3441efecf2bc7e6b36cb35e99642248d72dbf59b992e6940b9359dabc \
|
||||
--hash:sha256=8884b92835a1c0c763099981d19c990fdc3ae2b7011eb93b1f96e34a346b2d2f \
|
||||
--hash:sha256=7e7e9abc0ae522ae86772d98b7144e0d2ef7791d124936f283680f84fe8cce6c \
|
||||
--hash:sha256=61d3b42eaf89108b8a24c3736fb770f768efb89b1efaf0825efb5c316f0bffdc
|
||||
|
||||
# Install python_lzo if you want to support indexed access to lzo-compressed
|
||||
# locally cached maf files via bx-python
|
||||
#python_lzo==1.8 --hash:sha256=638b38bc1d83561a9807365676f5b2ba6f18491753a673e6a9c5913bd542fe1a \
|
||||
# --hash:sha256=cda3d6c27e69a9d04eb96db6b4b96fbe7facdd11dc2b9a82fe3c65b84b40fe44 \
|
||||
# --hash:sha256=7ededfdb65b4eb282a7cc1600c6f5b4f483b39a70b3460c2f4651ee8fc431f77 \
|
||||
# --hash:sha256=86a61008a8ab5f8ca973bd7e7b1d031c89637257dcf7215bff1913f17d3c596f \
|
||||
# --hash:sha256=1d6af33e40383dba0c3ee26eee3e501e805fe42537dd0096788190bbc8fd7aae \
|
||||
# --hash:sha256=6d08ad35322a5969dfd8ef5af7ff4cdf625d6a7bfa8e915b77f5935f58e1c7b1 \
|
||||
# --hash:sha256=99b7e0c186c5b84d80de6e7b70359b6fc456c02bd2b31fc598140fbc6618d651 \
|
||||
# --hash:sha256=be967c38c4e33f66823d10fb5efca42a0a23269459ce41239c173ccc114b603e \
|
||||
# --hash:sha256=a34d7431e30c6d61c22b92d51224ea34d68be51aa42ec95a053b7f19be3fef0d \
|
||||
# --hash:sha256=be76281c1c7f24d44e3415787d2a05688f6bbda2dc9bba92155ae3ca0d6716e7
|
||||
|
||||
# pure Python packages
|
||||
Paste==2.0.2 --hash:sha256=4e7bb2d8cbdc47ab46e4af0cb61d2af91fccc620a08415d9c4da9e499f0455fd
|
||||
PasteDeploy==1.5.2 --hash:sha256=3922127d3acc6e274a800978b9293c874b3ef4ac2eb8bf485e2c85b22d1f260a
|
||||
docutils==0.12 --hash:sha256=732dfc2d706ea390c264bc69110d3d6c7c3a520628a052ccc5998466f95d5c29
|
||||
wchartype==0.1 --hash:sha256=2932471fe3a4e5cac4539c1b49bbc2bbd24ec3f00532c7f27c80b7756fdc177d
|
||||
repoze.lru==0.6 --hash:sha256=731cc0b0a184c9fd270a4f29d9635099bb0398823e9a1a39bf4f488d1ead57b3
|
||||
Routes==2.2 --hash:sha256=1d61dc9f1bbd86504de221568743133fbdfeb70f11cee4222cef72aa108e834c
|
||||
WebOb==1.4.1 --hash:sha256=dc3c45ac0b56a3c65f47f1da6c23760dfe0139e8a84caaf1cfc9276b3e10875a
|
||||
WebHelpers==1.3 --hash:sha256=8969ec3fb851872096067a805d512c3bed1952e6fc66f1ef1d1c6a7470937688
|
||||
Mako==1.0.2 --hash:sha256=d3f372cbc2e7de080b5f7056d160f3ac8279353a2ea8f1ef8fd5b0cf0a6a3b17
|
||||
pytz==2015.4 --hash:sha256=3bec70eef120ad0bf9143e59bbf36715ec1232fb0550ae2b8aa6c107aacfa6f2
|
||||
Babel==2.0 --hash:sha256=aa725635ef189f77b6b0579efe1e91602d7cf63a31f6dd719a88ee53642bb5ab
|
||||
Beaker==1.7.0 --hash:sha256=334427853ac291e4ecd1e03addb48e231681ab9b6c2bc793c0f0fb98024b70b1
|
||||
|
||||
# Cheetah and dependencies
|
||||
Cheetah==2.4.4 --hash:sha256=24cf67789b7a9f1e0a55cba266b6aad16e97aaf25810fd6f2f7e7b36005c1161 \
|
||||
--hash:sha256=30c6dd32c066f483462cebc7fc37feb454d6a3d35e8b599da17624b2541761ab \
|
||||
--hash:sha256=fcbff7d96509419cbcefa231d6fee4aca98d2f04f8339848c19da3e82aebcf27 \
|
||||
--hash:sha256=5c758550b8170b01e016b75ec05dbd2c32b56513d6e1ef9177c5290f4e166ad2 \
|
||||
--hash:sha256=6aaeef7f742df6a23c4132bb33000196053b661a150fdd98311f25f09d3730c1 \
|
||||
--hash:sha256=469e7ddc2f4a9b147b2b5c258fc9f97cee9842790c1849b941bae165b390da92 \
|
||||
--hash:sha256=75f05eda3b16c621b5b570f9c5b317f6ea94b01296b9e1ef2583560d153578bd \
|
||||
--hash:sha256=6da983e9d189a3c389e98506871ff836a83df1792dba5e4a684d27d948402d7a \
|
||||
--hash:sha256=55b0c2696eb321415a9eca86303e3c359dee550d7f6fc719bc960f23422d2290 \
|
||||
--hash:sha256=2caf567b6cdd54f806ce12d98302e380d4bbbed8990663f9bce52d69358fc488
|
||||
Markdown==2.6.3 --hash:sha256=59417f5eb3dace08309d81e48fc903217d12d66677f367674b22c317b0f04284
|
||||
|
||||
# BioBlend and dependencies
|
||||
bioblend==0.6.1 --hash:sha256=f5eea1f6c31264ef7bfab8c70deac2b9229a10e5c56508a6542f5643ad9e2a5b
|
||||
boto==2.38.0 --hash:sha256=1760584368da0c3861dbed448dcb439334ce831044262a5ca5188167f8bba585
|
||||
requests==2.8.1 --hash:sha256=70e285122c97b1d104824482cb929246b2b8a2b9858897c4fab3acec83f1e03c
|
||||
requests-toolbelt==0.4.0 --hash:sha256=94694e32845b84ed2186fdf56219b949582ebd08dc3abc55c0549958f2029643
|
||||
|
||||
# kombu and dependencies
|
||||
kombu==3.0.30 --hash:sha256=562010f0deb1f04e3abd154b0ef5e246d606b54cb2c5f29e8c4651b354d0b082 \
|
||||
--hash:sha256=5baff23a2b2d78eecb7c97700ea359ab80744c719e311fb446513d7b72ddbc96
|
||||
amqp==1.4.8 --hash:sha256=c7874d845c9bdffbf754ce84f105a1b8c7a6cffb61f362ac67591536ba8c0c1a \
|
||||
--hash:sha256=caada1c29d5e73e13ed8706442ee0fbb1440de9b6fca4df12fc8ff59dd61f6f6
|
||||
anyjson==0.3.3 --hash:sha256=2c84f23be20e3c465151a55917b8e38a04c579394057e232c16fb5ca0c6ae108
|
||||
|
||||
# sqlalchemy-migrate and dependencies
|
||||
sqlalchemy-migrate==0.10.0 --hash:sha256=2aaa4e7070c8447d564f1c173937c2c5a45f889eb31a0fc80add5fc175c45a5e
|
||||
decorator==4.0.2 --hash:sha256=d8c3f7e18efba558084648d6dd6c6b0850e6f5c08c392975ae196c4b4eb7be2a
|
||||
Tempita==0.5.3dev --hash:sha256=df0c6513e565b213733b3f8bf7bcca75998f166042692e1712e3fe36568db234
|
||||
sqlparse==0.1.16 --hash:sha256=221d383f1236f9c05aadd2c4edf4274144279ad06821d7d9bf5a70751157f75d
|
||||
pbr==1.8.0 --hash:sha256=355a0c2ba71120dce1c522387e494c60eb4f44fa9d03067cb9816187e6e803e9
|
||||
# six is also a Pulsar client dep
|
||||
six==1.9.0 --hash:sha256=cf806ab65d5e16561df30c2cea2fb2cf3e6aa82e48f22036dff177e20f61e188
|
||||
Parsley==1.3 --hash:sha256=32fd648334146e4005dae41d559d32edfff9f3d5f503f8b5d233dbfe3a15a28b
|
||||
nose==1.3.7 --hash:sha256=f36054c5786e84ff6b131f3249a3cce82787f1a930ab053287c0edaa9f840d0f
|
||||
SVGFig==1.1.6 --hash:sha256=300cf4b37b4773498d4ea96c703cdb5f09215978b02828dadb786fb248e0b54b
|
||||
|
||||
# Fabric and dependencies
|
||||
Fabric==1.10.2 --hash:sha256=8fe1eb0b0f271e2d41445e7da4470548d3bdf882aab1c1f143505c599996793b
|
||||
paramiko==1.15.2 --hash:sha256=c92b168c8db94a9e1362f3fc27bc21e8c20794885bf2f7d303b5ad717c044ebc
|
||||
ecdsa==0.13 --hash:sha256=89f149066e4a1e419892cef830fd0db85c227d5d427f7075422ace83429e2d26
|
||||
# pycrypto, but it is a direct Galaxy dependency as well
|
||||
|
||||
# Can't use Whoosh latest due to a bug but need to backport a bugfix from a
|
||||
# newer release.
|
||||
#
|
||||
# https://bitbucket.org/mchaput/whoosh/pull-requests/50/fix-lru-thread-safety/diff
|
||||
Whoosh==2.4.1+gx1 --hash:sha256=98897e796c048810d71f7f4fc174914869f1b3b77f44e5a19a5e649b078d5e0e \
|
||||
--hash:sha256=5ec3c22e782c86e981fab62a24ac9feea09e42c43b763a6493c78b82a3b6e3fd
|
||||
|
||||
# Flexible BAM index naming
|
||||
pysam==0.8.3+gx1 --hash:sha256=020aa9101579ac1e82a194fdb08f49f517c634911409e9a2cda4d0a1c72a8c7c \
|
||||
--hash:sha256=1a3d86849b9bd962979b65aaa9af236030dcc1db40296c88d2aa436a0c9df79b \
|
||||
--hash:sha256=0fc55fb252eb0e7914679e9e22672fdc6a1e09804cbcc62769f004ebbed9b4c1 \
|
||||
--hash:sha256=dde8f5037661d7be42e2c3f50c01566dcaedbf2f88133a3bb50c6ae3f75e6e13 \
|
||||
--hash:sha256=7809fd926a071519c0a2b220346e45c094577877e5b2adba2903e7b52490c736 \
|
||||
--hash:sha256=021070ed70a89e19eee6a989933d69d0bdb076c02342e2987bb5fab43f63ad17 \
|
||||
--hash:sha256=374ea868bf64daa4665e8743db1be2e88712953a923020225f57a589b790537c \
|
||||
--hash:sha256=9884b6904face1977649847261e7c984120adaa169a0d62e07820a44c71e18c5 \
|
||||
--hash:sha256=873b81951e9d572b53ab4c7a0d3ef915f7d0e1db5f75603d8861cf1d3810491e \
|
||||
--hash:sha256=37d0ba3880b5a517f354281159f6751f6f9f1c1074ea48bf5f4c424e6ec488dd \
|
||||
--hash:sha256=db99cb20cb5e07998b2acfd29e34c367ef408a184a7b3150586212175a0719bf \
|
||||
--hash:sha256=a1fcb2a6459b799bff7a046e190452b151c5985dea404eaee82bd645b1bfe34d \
|
||||
--hash:sha256=306e4d900dfb582cf87bc21904e2193ef81db76173e976b74152c95ddd93bdc6 \
|
||||
--hash:sha256=2341438d636b8e3cb51b219aab1cc909142d3af176042d12b128d4177682b1ab \
|
||||
--hash:sha256=0f33df9eba7b079b7489ac3dd908a6e44b0e98d094e633b29035d33bfc990b9e \
|
||||
--hash:sha256=faa8aae3f8f105c5c823a7d570dd3caba31ece69b8f3325106435b9f1fcb68d2 \
|
||||
--hash:sha256=2db995758d666c51fecf11cbee1afda357477e01077aacf68ae0c00304c7bc51 \
|
||||
--hash:sha256=2de7a2098f64672d0396ac727633285f3562f804e7845e105ee19da544d7da8a
|
||||
@@ -1,170 +1,69 @@
|
||||
# packages with C extensions
|
||||
bx-python==0.7.3 --hash:sha256=0a0fd962edd0f9afdf5d7ccbdf46dc220a0cb652073a93411dd6f7f649f07d91 \
|
||||
--hash:sha256=46dc3042c7e475363830fa92d4a613ae10b58db7f114ff8193d2ee0bc3c4607e \
|
||||
--hash:sha256=b93a9378a5d0e29ea8a13e026c170f48bf1f8316a39c342b1eb54f557b4fb3c4 \
|
||||
--hash:sha256=d06c7bf0ae7f019521aeb5ffe4df48bb5fdd4d75d7ad00e0059b997c4f13ca3a \
|
||||
--hash:sha256=05d0ab8fd13319d5ef9edb246dc6805640ea7574bb885a0b8607474271ac5793 \
|
||||
--hash:sha256=5a026869227a6464eba23835765a36ffc2910f7af51b81f672a97c0d005e04a3 \
|
||||
--hash:sha256=85be43a6b94f0c841d9954f820133db35067854504c1de87dd0089bb06eca18d \
|
||||
--hash:sha256=d085824eb33c54d333b99dca29b49890457a8263f431b54b17ae3052be191d2b \
|
||||
--hash:sha256=41bcf85b9be9f61ba7c7bae48c5a5ae3251868a1b25f02b6eb93b29bcabfd00c \
|
||||
--hash:sha256=c9b71aee26ee85fbcbb3060109d79531bfa8991f4924bdcfed63d909a5937290
|
||||
MarkupSafe==0.23 --hash:sha256=3a79d9650b7e79943be51a045c7c39a77ebbe9a337e8af51a5575e39332dce87 \
|
||||
--hash:sha256=e0a4155493d1cfa72e985dbe1660a44d64a173282801563956e061b24371266a \
|
||||
--hash:sha256=147013ed157f1423a0d0047043c6bbccbef31a52d82e2a10dfc3c6de9392765c \
|
||||
--hash:sha256=d25d14cb01284aed33690b85bfde8de206ffcfdc52351588bcf17480839bef6f \
|
||||
--hash:sha256=29958f81958e0dd9f5dd36d52f2ac549d875dde3559b783578118c9005693852 \
|
||||
--hash:sha256=287a1c6b0d2a08cb76be6e584bf119649405f015598cf8b78d4a592cc80700a0 \
|
||||
--hash:sha256=973cadf7b9907f9c81d9b898817d6a485b37325176befec2389fa2ced4c61a51 \
|
||||
--hash:sha256=a365fd3468c86741aec5901f4b07990aaa0b458fb79e9f3557378a63e6d627e9 \
|
||||
--hash:sha256=ba7af558b18ba9c05bb0d36f22a5ea65ee11ba44a6cf8a2950f2f80c08260e11 \
|
||||
--hash:sha256=51bf7f077938c64dd00de6732996ccee8ceba2206c69acfb07f66430ca76372f
|
||||
PyYAML==3.11 --hash:sha256=2912c1fb56c316461d003a8b8f1f41e1ed8387b2e47a4523f8a4eec8aa85e241 \
|
||||
--hash:sha256=f4437443dc014c04ceee8cc94d4165f01ba23643991fd2c6b919f26cf9997474 \
|
||||
--hash:sha256=b62cde962d41377c175831fa3fd6ac41585d2e2111ca4c45a6ee80a832457e92 \
|
||||
--hash:sha256=aad37be9d524ba2dba9a3114b620b2800b40e67e455c9741a5cb81a6a0e882f6 \
|
||||
--hash:sha256=03e0f4ac96599c1d687b080f1610ab0469e8785bb48cfdf860f2076a08ea6406 \
|
||||
--hash:sha256=7dc97b5b1b920f6bbe0e47cfa6ff112f6eede35924a63354f80d672354f25160 \
|
||||
--hash:sha256=ceb5dccec2045d4a864c6e808b397b10830476c44bdc64b80c18bf29e481ba07 \
|
||||
--hash:sha256=9b184a4a7d3d383b39cb73429d3798370facaee4263465b575f243c7ede3f9c3 \
|
||||
--hash:sha256=f90314e2ed46ea2da980aff88b91c3cc8ce93edd4658011dd462a8f28399533b \
|
||||
--hash:sha256=80936dca10b611cd54ca52939aac938d59653830a6a6265bef5d11896de8e249
|
||||
SQLAlchemy==1.0.8 --hash:sha256=3c357f36c141205cea2b5ec4c4e9885602452fea06428d6c20596c66c9a43243 \
|
||||
--hash:sha256=17fad7f37f902dbec37ca2777af3021f9a4ed31079d64f7f888e7b29517240a3 \
|
||||
--hash:sha256=e177904a384b9bc68914afb32a6ed2cc73ed7787444e3e1fdf85e3b9cfe5f847 \
|
||||
--hash:sha256=91ed10baf56b6e29665f2b9fcb0c690afc6cc2c2e8e19c7f92b58092a4002e14 \
|
||||
--hash:sha256=f5d6156d1d7865cd23b76ddad3f53ec07a3009a2cd8082a829cd1f24b366db5c \
|
||||
--hash:sha256=3c3f3baf07f868c1c3f86d63dc2efa4455e95d76745f1af561f1ccf0fd9e8c81 \
|
||||
--hash:sha256=a9fb8061aa767ca2ad22983a11e074ac231f44a56709721c60cc1992f2a92350 \
|
||||
--hash:sha256=884b522d2d067cffd103f4e1a5342c678803cd6903da24a3f757b57b00eb188b \
|
||||
--hash:sha256=d5dde66c1603853aebbfbbd74d79c60678f7d98c17abce4be4ebbb697dfd7265 \
|
||||
--hash:sha256=42346d5e91c5e0a5a975352d8af3cfd8b2dad602dd07ec41b6b848ac5205cf5b
|
||||
bx-python==0.7.3
|
||||
MarkupSafe==0.23
|
||||
PyYAML==3.11
|
||||
SQLAlchemy==1.0.8
|
||||
# Mercurial >= 3.5 changed the bundle format, which breaks hg push of TS repositories
|
||||
mercurial==3.4.2 --hash:sha256=7851864b03929c09e07670bf8ab7d59f3529650c935a70d09fb6ce7f6a84e2a5 \
|
||||
--hash:sha256=c23b02b4c32edc2d0799221a9d35abd916fb8a1acd1c07d64c16a235ef677b9e \
|
||||
--hash:sha256=ca72ddfaea681a070b62edcb8e41d58bd24a2b04f73e66658565d189a76f3819 \
|
||||
--hash:sha256=fdad4496f3d7f3e7eced771fa46e21c074989f8437ddf3e0ff6c0eee964e4c29 \
|
||||
--hash:sha256=964a10ec1114dbee3696134bafed676f66038759b73de8593f92616f0e53f371 \
|
||||
--hash:sha256=c6ca6fbe56a8919dfc521e80ab781ab565760d87f4a6170e788d67eb6d69d30f \
|
||||
--hash:sha256=69540318fa9f7a3a0428647003d4f1fa8865d29648e73999b921cae039145ce9 \
|
||||
--hash:sha256=b3de0ee851cf8750f53102437c9a04c7217a8c6f7411030ab3bb5534885f3315 \
|
||||
--hash:sha256=46f67af52c7b1aed68b67daa33c26eafc0fb1d371954d3266fce739446cfcb1d \
|
||||
--hash:sha256=000afb932f0ae45c365cbc0457044e8800811fdad7eee9332b6403b83423ab0a
|
||||
numpy==1.9.2 --hash:sha256=931ce6fd1180a10d58a925b614775706c05de35bca5805e705e1da17e1326862 \
|
||||
--hash:sha256=2340c4b72fdab79ac0fc04bb6629b26eeb93d10f4945b6b1f07d9be8663cab84 \
|
||||
--hash:sha256=83fe34ff67653a639c57cfd04a0d48dda5913250fd95c8466af1d8416b58af59 \
|
||||
--hash:sha256=aeb182d95ddb2dfd81683907be193cfc11c4d0ba744faf457013499fa14a131e \
|
||||
--hash:sha256=d6f1eec7ae250892a2b142af406e43760042badae8e2f168136eace5dd9f05c3 \
|
||||
--hash:sha256=0b0883cac08e3c0999159ba7f34c9b94d26d7d1a2be4017b792145d722646fb7 \
|
||||
--hash:sha256=a124d11b1bec5c517d60ad9414564b5af0828421112d2a00771d22715eab1c3c \
|
||||
--hash:sha256=fabc2f76266de7396e2752baabf287cdd0cc2ed23c1f36ca3c3e8b094e86b87c \
|
||||
--hash:sha256=f83a667d3a38643b3bf6361904cd6c4f2a18d1420c2204c7f269cd36b730c404 \
|
||||
--hash:sha256=dab9bd8c867403340b370ea383c8eda3dc984dd5efc91904a5695e00b1762fc9
|
||||
pycrypto==2.6.1 --hash:sha256=44c20785a1057b8d5e190d6a1847f7c62a8180b9b27a3aca7c3ec920bfb8e7b7 \
|
||||
--hash:sha256=785ba61251cda6e574e0affc4412c346ef615455b81287fe0d6a2e1c5aed5172 \
|
||||
--hash:sha256=5ec40d95520a665843915763c8cbbf40457330bd7ebf2a55ffea1b10a519d12b \
|
||||
--hash:sha256=2cb43f0b293a18e6d5818287150994cf6083b1a9cdff65c19d1150a34aa813bc \
|
||||
--hash:sha256=d48e46f4ccd5c21f3e01bbdbd8e7a86443fc7abdf3f93829c3d04ed684ec22c5 \
|
||||
--hash:sha256=30312bd39f45c91f287f3e6e54c40988d30b1be9a9f332585e3cc00ee5f91554 \
|
||||
--hash:sha256=d129d6d3441efecf2bc7e6b36cb35e99642248d72dbf59b992e6940b9359dabc \
|
||||
--hash:sha256=8884b92835a1c0c763099981d19c990fdc3ae2b7011eb93b1f96e34a346b2d2f \
|
||||
--hash:sha256=7e7e9abc0ae522ae86772d98b7144e0d2ef7791d124936f283680f84fe8cce6c \
|
||||
--hash:sha256=61d3b42eaf89108b8a24c3736fb770f768efb89b1efaf0825efb5c316f0bffdc
|
||||
mercurial==3.4.2
|
||||
numpy==1.9.2
|
||||
pycrypto==2.6.1
|
||||
|
||||
# Install python_lzo if you want to support indexed access to lzo-compressed
|
||||
# locally cached maf files via bx-python
|
||||
#python_lzo==1.8 --hash:sha256=638b38bc1d83561a9807365676f5b2ba6f18491753a673e6a9c5913bd542fe1a \
|
||||
# --hash:sha256=cda3d6c27e69a9d04eb96db6b4b96fbe7facdd11dc2b9a82fe3c65b84b40fe44 \
|
||||
# --hash:sha256=7ededfdb65b4eb282a7cc1600c6f5b4f483b39a70b3460c2f4651ee8fc431f77 \
|
||||
# --hash:sha256=86a61008a8ab5f8ca973bd7e7b1d031c89637257dcf7215bff1913f17d3c596f \
|
||||
# --hash:sha256=1d6af33e40383dba0c3ee26eee3e501e805fe42537dd0096788190bbc8fd7aae \
|
||||
# --hash:sha256=6d08ad35322a5969dfd8ef5af7ff4cdf625d6a7bfa8e915b77f5935f58e1c7b1 \
|
||||
# --hash:sha256=99b7e0c186c5b84d80de6e7b70359b6fc456c02bd2b31fc598140fbc6618d651 \
|
||||
# --hash:sha256=be967c38c4e33f66823d10fb5efca42a0a23269459ce41239c173ccc114b603e \
|
||||
# --hash:sha256=a34d7431e30c6d61c22b92d51224ea34d68be51aa42ec95a053b7f19be3fef0d \
|
||||
# --hash:sha256=be76281c1c7f24d44e3415787d2a05688f6bbda2dc9bba92155ae3ca0d6716e7
|
||||
#python_lzo==1.8
|
||||
|
||||
# pure Python packages
|
||||
Paste==2.0.2 --hash:sha256=4e7bb2d8cbdc47ab46e4af0cb61d2af91fccc620a08415d9c4da9e499f0455fd
|
||||
PasteDeploy==1.5.2 --hash:sha256=3922127d3acc6e274a800978b9293c874b3ef4ac2eb8bf485e2c85b22d1f260a
|
||||
docutils==0.12 --hash:sha256=732dfc2d706ea390c264bc69110d3d6c7c3a520628a052ccc5998466f95d5c29
|
||||
wchartype==0.1 --hash:sha256=2932471fe3a4e5cac4539c1b49bbc2bbd24ec3f00532c7f27c80b7756fdc177d
|
||||
repoze.lru==0.6 --hash:sha256=731cc0b0a184c9fd270a4f29d9635099bb0398823e9a1a39bf4f488d1ead57b3
|
||||
Routes==2.2 --hash:sha256=1d61dc9f1bbd86504de221568743133fbdfeb70f11cee4222cef72aa108e834c
|
||||
WebOb==1.4.1 --hash:sha256=dc3c45ac0b56a3c65f47f1da6c23760dfe0139e8a84caaf1cfc9276b3e10875a
|
||||
WebHelpers==1.3 --hash:sha256=8969ec3fb851872096067a805d512c3bed1952e6fc66f1ef1d1c6a7470937688
|
||||
Mako==1.0.2 --hash:sha256=d3f372cbc2e7de080b5f7056d160f3ac8279353a2ea8f1ef8fd5b0cf0a6a3b17
|
||||
pytz==2015.4 --hash:sha256=3bec70eef120ad0bf9143e59bbf36715ec1232fb0550ae2b8aa6c107aacfa6f2
|
||||
Babel==2.0 --hash:sha256=aa725635ef189f77b6b0579efe1e91602d7cf63a31f6dd719a88ee53642bb5ab
|
||||
Beaker==1.7.0 --hash:sha256=334427853ac291e4ecd1e03addb48e231681ab9b6c2bc793c0f0fb98024b70b1
|
||||
Paste==2.0.2
|
||||
PasteDeploy==1.5.2
|
||||
docutils==0.12
|
||||
wchartype==0.1
|
||||
repoze.lru==0.6
|
||||
Routes==2.2
|
||||
WebOb==1.4.1
|
||||
WebHelpers==1.3
|
||||
Mako==1.0.2
|
||||
pytz==2015.4
|
||||
Babel==2.0
|
||||
Beaker==1.7.0
|
||||
|
||||
# Cheetah and dependencies
|
||||
Cheetah==2.4.4 --hash:sha256=24cf67789b7a9f1e0a55cba266b6aad16e97aaf25810fd6f2f7e7b36005c1161 \
|
||||
--hash:sha256=30c6dd32c066f483462cebc7fc37feb454d6a3d35e8b599da17624b2541761ab \
|
||||
--hash:sha256=fcbff7d96509419cbcefa231d6fee4aca98d2f04f8339848c19da3e82aebcf27 \
|
||||
--hash:sha256=5c758550b8170b01e016b75ec05dbd2c32b56513d6e1ef9177c5290f4e166ad2 \
|
||||
--hash:sha256=6aaeef7f742df6a23c4132bb33000196053b661a150fdd98311f25f09d3730c1 \
|
||||
--hash:sha256=469e7ddc2f4a9b147b2b5c258fc9f97cee9842790c1849b941bae165b390da92 \
|
||||
--hash:sha256=75f05eda3b16c621b5b570f9c5b317f6ea94b01296b9e1ef2583560d153578bd \
|
||||
--hash:sha256=6da983e9d189a3c389e98506871ff836a83df1792dba5e4a684d27d948402d7a \
|
||||
--hash:sha256=55b0c2696eb321415a9eca86303e3c359dee550d7f6fc719bc960f23422d2290 \
|
||||
--hash:sha256=2caf567b6cdd54f806ce12d98302e380d4bbbed8990663f9bce52d69358fc488
|
||||
Markdown==2.6.3 --hash:sha256=59417f5eb3dace08309d81e48fc903217d12d66677f367674b22c317b0f04284
|
||||
Cheetah==2.4.4
|
||||
Markdown==2.6.3
|
||||
|
||||
# BioBlend and dependencies
|
||||
bioblend==0.6.1 --hash:sha256=f5eea1f6c31264ef7bfab8c70deac2b9229a10e5c56508a6542f5643ad9e2a5b
|
||||
boto==2.38.0 --hash:sha256=1760584368da0c3861dbed448dcb439334ce831044262a5ca5188167f8bba585
|
||||
requests==2.8.1 --hash:sha256=70e285122c97b1d104824482cb929246b2b8a2b9858897c4fab3acec83f1e03c
|
||||
requests-toolbelt==0.4.0 --hash:sha256=94694e32845b84ed2186fdf56219b949582ebd08dc3abc55c0549958f2029643
|
||||
bioblend==0.6.1
|
||||
boto==2.38.0
|
||||
requests==2.8.1
|
||||
requests-toolbelt==0.4.0
|
||||
|
||||
# kombu and dependencies
|
||||
kombu==3.0.30 --hash:sha256=562010f0deb1f04e3abd154b0ef5e246d606b54cb2c5f29e8c4651b354d0b082 \
|
||||
--hash:sha256=5baff23a2b2d78eecb7c97700ea359ab80744c719e311fb446513d7b72ddbc96
|
||||
amqp==1.4.8 --hash:sha256=c7874d845c9bdffbf754ce84f105a1b8c7a6cffb61f362ac67591536ba8c0c1a \
|
||||
--hash:sha256=caada1c29d5e73e13ed8706442ee0fbb1440de9b6fca4df12fc8ff59dd61f6f6
|
||||
anyjson==0.3.3 --hash:sha256=2c84f23be20e3c465151a55917b8e38a04c579394057e232c16fb5ca0c6ae108
|
||||
kombu==3.0.30
|
||||
amqp==1.4.8
|
||||
anyjson==0.3.3
|
||||
|
||||
# sqlalchemy-migrate and dependencies
|
||||
sqlalchemy-migrate==0.10.0 --hash:sha256=2aaa4e7070c8447d564f1c173937c2c5a45f889eb31a0fc80add5fc175c45a5e
|
||||
decorator==4.0.2 --hash:sha256=d8c3f7e18efba558084648d6dd6c6b0850e6f5c08c392975ae196c4b4eb7be2a
|
||||
Tempita==0.5.3dev --hash:sha256=df0c6513e565b213733b3f8bf7bcca75998f166042692e1712e3fe36568db234
|
||||
sqlparse==0.1.16 --hash:sha256=221d383f1236f9c05aadd2c4edf4274144279ad06821d7d9bf5a70751157f75d
|
||||
pbr==1.8.0 --hash:sha256=355a0c2ba71120dce1c522387e494c60eb4f44fa9d03067cb9816187e6e803e9
|
||||
sqlalchemy-migrate==0.10.0
|
||||
decorator==4.0.2
|
||||
Tempita==0.5.3dev
|
||||
sqlparse==0.1.16
|
||||
pbr==1.8.0
|
||||
# six is also a Pulsar client dep
|
||||
six==1.9.0 --hash:sha256=cf806ab65d5e16561df30c2cea2fb2cf3e6aa82e48f22036dff177e20f61e188
|
||||
Parsley==1.3 --hash:sha256=32fd648334146e4005dae41d559d32edfff9f3d5f503f8b5d233dbfe3a15a28b
|
||||
nose==1.3.7 --hash:sha256=f36054c5786e84ff6b131f3249a3cce82787f1a930ab053287c0edaa9f840d0f
|
||||
SVGFig==1.1.6 --hash:sha256=300cf4b37b4773498d4ea96c703cdb5f09215978b02828dadb786fb248e0b54b
|
||||
six==1.9.0
|
||||
Parsley==1.3
|
||||
nose==1.3.7
|
||||
SVGFig==1.1.6
|
||||
|
||||
# Fabric and dependencies
|
||||
Fabric==1.10.2 --hash:sha256=8fe1eb0b0f271e2d41445e7da4470548d3bdf882aab1c1f143505c599996793b
|
||||
paramiko==1.15.2 --hash:sha256=c92b168c8db94a9e1362f3fc27bc21e8c20794885bf2f7d303b5ad717c044ebc
|
||||
ecdsa==0.13 --hash:sha256=89f149066e4a1e419892cef830fd0db85c227d5d427f7075422ace83429e2d26
|
||||
Fabric==1.10.2
|
||||
paramiko==1.15.2
|
||||
ecdsa==0.13
|
||||
# pycrypto, but it is a direct Galaxy dependency as well
|
||||
|
||||
# Can't use Whoosh latest due to a bug but need to backport a bugfix from a
|
||||
# newer release.
|
||||
#
|
||||
# https://bitbucket.org/mchaput/whoosh/pull-requests/50/fix-lru-thread-safety/diff
|
||||
Whoosh==2.4.1+gx1 --hash:sha256=98897e796c048810d71f7f4fc174914869f1b3b77f44e5a19a5e649b078d5e0e \
|
||||
--hash:sha256=5ec3c22e782c86e981fab62a24ac9feea09e42c43b763a6493c78b82a3b6e3fd
|
||||
Whoosh==2.4.1+gx1
|
||||
|
||||
# Flexible BAM index naming
|
||||
pysam==0.8.3+gx1 --hash:sha256=020aa9101579ac1e82a194fdb08f49f517c634911409e9a2cda4d0a1c72a8c7c \
|
||||
--hash:sha256=1a3d86849b9bd962979b65aaa9af236030dcc1db40296c88d2aa436a0c9df79b \
|
||||
--hash:sha256=0fc55fb252eb0e7914679e9e22672fdc6a1e09804cbcc62769f004ebbed9b4c1 \
|
||||
--hash:sha256=dde8f5037661d7be42e2c3f50c01566dcaedbf2f88133a3bb50c6ae3f75e6e13 \
|
||||
--hash:sha256=7809fd926a071519c0a2b220346e45c094577877e5b2adba2903e7b52490c736 \
|
||||
--hash:sha256=021070ed70a89e19eee6a989933d69d0bdb076c02342e2987bb5fab43f63ad17 \
|
||||
--hash:sha256=374ea868bf64daa4665e8743db1be2e88712953a923020225f57a589b790537c \
|
||||
--hash:sha256=9884b6904face1977649847261e7c984120adaa169a0d62e07820a44c71e18c5 \
|
||||
--hash:sha256=873b81951e9d572b53ab4c7a0d3ef915f7d0e1db5f75603d8861cf1d3810491e \
|
||||
--hash:sha256=37d0ba3880b5a517f354281159f6751f6f9f1c1074ea48bf5f4c424e6ec488dd \
|
||||
--hash:sha256=db99cb20cb5e07998b2acfd29e34c367ef408a184a7b3150586212175a0719bf \
|
||||
--hash:sha256=a1fcb2a6459b799bff7a046e190452b151c5985dea404eaee82bd645b1bfe34d \
|
||||
--hash:sha256=306e4d900dfb582cf87bc21904e2193ef81db76173e976b74152c95ddd93bdc6 \
|
||||
--hash:sha256=2341438d636b8e3cb51b219aab1cc909142d3af176042d12b128d4177682b1ab \
|
||||
--hash:sha256=0f33df9eba7b079b7489ac3dd908a6e44b0e98d094e633b29035d33bfc990b9e \
|
||||
--hash:sha256=faa8aae3f8f105c5c823a7d570dd3caba31ece69b8f3325106435b9f1fcb68d2 \
|
||||
--hash:sha256=2db995758d666c51fecf11cbee1afda357477e01077aacf68ae0c00304c7bc51 \
|
||||
--hash:sha256=2de7a2098f64672d0396ac727633285f3562f804e7845e105ee19da544d7da8a
|
||||
pysam==0.8.3+gx1
|
||||
|
||||
@@ -43,6 +43,9 @@ log = logging.getLogger( __name__ )
|
||||
# and should eventually become API'd
|
||||
TOOL_PROVIDED_JOB_METADATA_FILE = 'galaxy.json'
|
||||
|
||||
# Override with config.default_job_shell.
|
||||
DEFAULT_JOB_SHELL = '/bin/sh'
|
||||
|
||||
|
||||
class JobDestination( Bunch ):
|
||||
"""
|
||||
@@ -55,6 +58,7 @@ class JobDestination( Bunch ):
|
||||
self['runner'] = None
|
||||
self['legacy'] = False
|
||||
self['converted'] = False
|
||||
self['shell'] = None
|
||||
self['env'] = []
|
||||
self['resubmit'] = []
|
||||
# dict is appropriate (rather than a bunch) since keys may not be valid as attributes
|
||||
@@ -785,6 +789,10 @@ class JobWrapper( object ):
|
||||
def get_parallelism(self):
|
||||
return self.tool.parallelism
|
||||
|
||||
@property
|
||||
def shell(self):
|
||||
return self.job_destination.shell or getattr(self.app.config, 'default_job_shell', DEFAULT_JOB_SHELL)
|
||||
|
||||
@property
|
||||
def commands_in_new_shell(self):
|
||||
return self.app.config.commands_in_new_shell
|
||||
@@ -1195,8 +1203,8 @@ class JobWrapper( object ):
|
||||
# either use the metadata from originating output dataset, or call set_meta on the copies
|
||||
# it would be quicker to just copy the metadata from the originating output dataset,
|
||||
# but somewhat trickier (need to recurse up the copied_from tree), for now we'll call set_meta()
|
||||
if ( self.app.config.retry_metadata_internally
|
||||
and not self.external_output_metadata.external_metadata_set_successfully(dataset, self.sa_session ) ):
|
||||
if ( self.app.config.retry_metadata_internally and
|
||||
not self.external_output_metadata.external_metadata_set_successfully(dataset, self.sa_session ) ):
|
||||
# If Galaxy was expected to sniff type and didn't - do so.
|
||||
if dataset.ext == "_sniff_":
|
||||
extension = sniff.handle_uploaded_dataset_file( dataset.dataset.file_name, self.app.datatypes_registry )
|
||||
@@ -1204,8 +1212,8 @@ class JobWrapper( object ):
|
||||
|
||||
# call datatype.set_meta directly for the initial set_meta call during dataset creation
|
||||
dataset.datatype.set_meta( dataset, overwrite=False )
|
||||
elif ( job.states.ERROR != final_job_state
|
||||
and not self.external_output_metadata.external_metadata_set_successfully( dataset, self.sa_session ) ):
|
||||
elif ( job.states.ERROR != final_job_state and
|
||||
not self.external_output_metadata.external_metadata_set_successfully( dataset, self.sa_session ) ):
|
||||
dataset._state = model.Dataset.states.FAILED_METADATA
|
||||
else:
|
||||
# load metadata from file
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
from os import getcwd
|
||||
from os import chmod
|
||||
from os.path import join
|
||||
from os.path import abspath
|
||||
|
||||
from galaxy import util
|
||||
from galaxy.jobs.runners.util.job_script import (
|
||||
INTEGRITY_INJECTION,
|
||||
write_script,
|
||||
check_script_integrity,
|
||||
)
|
||||
|
||||
from logging import getLogger
|
||||
log = getLogger( __name__ )
|
||||
|
||||
CAPTURE_RETURN_CODE = "return_code=$?"
|
||||
YIELD_CAPTURED_CODE = 'sh -c "exit $return_code"'
|
||||
DEFAULT_SHELL = "/bin/sh"
|
||||
|
||||
|
||||
def build_command(
|
||||
@@ -19,7 +22,7 @@ def build_command(
|
||||
container=None,
|
||||
include_metadata=False,
|
||||
include_work_dir_outputs=True,
|
||||
remote_command_params={}
|
||||
remote_command_params={},
|
||||
):
|
||||
"""
|
||||
Compose the sequence of commands necessary to execute a job. This will
|
||||
@@ -30,6 +33,7 @@ def build_command(
|
||||
- command line taken from job wrapper
|
||||
- commands to set metadata (if include_metadata is True)
|
||||
"""
|
||||
shell = job_wrapper.shell
|
||||
base_command_line = job_wrapper.get_command_line()
|
||||
# job_id = job_wrapper.job_id
|
||||
# log.debug( 'Tool evaluation for job (%s) produced command-line: %s' % ( job_id, base_command_line ) )
|
||||
@@ -52,7 +56,7 @@ def build_command(
|
||||
__handle_dependency_resolution(commands_builder, job_wrapper, remote_command_params)
|
||||
|
||||
if container or job_wrapper.commands_in_new_shell:
|
||||
externalized_commands = __externalize_commands(job_wrapper, commands_builder, remote_command_params)
|
||||
externalized_commands = __externalize_commands(job_wrapper, shell, commands_builder, remote_command_params)
|
||||
if container:
|
||||
# Stop now and build command before handling metadata and copying
|
||||
# working directory files back. These should always happen outside
|
||||
@@ -76,17 +80,18 @@ def build_command(
|
||||
return commands_builder.build()
|
||||
|
||||
|
||||
def __externalize_commands(job_wrapper, commands_builder, remote_command_params, script_name="tool_script.sh"):
|
||||
def __externalize_commands(job_wrapper, shell, commands_builder, remote_command_params, script_name="tool_script.sh"):
|
||||
local_container_script = join( job_wrapper.working_directory, script_name )
|
||||
tool_commands = commands_builder.build()
|
||||
with open( local_container_script, "w" ) as f:
|
||||
script_contents = u"#!%s\n%s" % (DEFAULT_SHELL, tool_commands)
|
||||
f.write(script_contents.encode(util.DEFAULT_ENCODING))
|
||||
chmod( local_container_script, 0755 )
|
||||
|
||||
config = job_wrapper.app.config
|
||||
integrity_injection = ""
|
||||
if check_script_integrity(config):
|
||||
integrity_injection = INTEGRITY_INJECTION
|
||||
script_contents = u"#!%s\n%s%s" % (shell, integrity_injection, tool_commands)
|
||||
write_script(local_container_script, script_contents, config)
|
||||
commands = local_container_script
|
||||
if 'working_directory' in remote_command_params:
|
||||
commands = "%s %s" % (DEFAULT_SHELL, join(remote_command_params['working_directory'], script_name))
|
||||
commands = "%s %s" % (shell, join(remote_command_params['working_directory'], script_name))
|
||||
log.info("Built script [%s] for tool command[%s]" % (local_container_script, tool_commands))
|
||||
return commands
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ from galaxy.util import in_directory
|
||||
from galaxy.util import ParamsWithSpecs
|
||||
from galaxy.util import ExecutionTimer
|
||||
from galaxy.util.bunch import Bunch
|
||||
from galaxy.jobs.runners.util.job_script import write_script
|
||||
from galaxy.jobs.runners.util.job_script import job_script
|
||||
from galaxy.jobs.runners.util.env import env_to_statement
|
||||
|
||||
@@ -166,7 +167,7 @@ class BaseJobRunner( object ):
|
||||
job_wrapper.runner_command_line = self.build_command_line(
|
||||
job_wrapper,
|
||||
include_metadata=include_metadata,
|
||||
include_work_dir_outputs=include_work_dir_outputs
|
||||
include_work_dir_outputs=include_work_dir_outputs,
|
||||
)
|
||||
except:
|
||||
log.exception("(%s) Failure preparing job" % job_id)
|
||||
@@ -297,6 +298,7 @@ class BaseJobRunner( object ):
|
||||
env_setup_commands=env_setup_commands,
|
||||
working_directory=os.path.abspath( job_wrapper.working_directory ),
|
||||
command=command_line,
|
||||
shell=job_wrapper.shell,
|
||||
)
|
||||
# Additional logging to enable if debugging from_work_dir handling, metadata
|
||||
# commands, etc... (or just peak in the job script.)
|
||||
@@ -306,41 +308,7 @@ class BaseJobRunner( object ):
|
||||
return job_script(**options)
|
||||
|
||||
def write_executable_script( self, path, contents, mode=0o755 ):
|
||||
with open( path, 'w' ) as f:
|
||||
if isinstance(contents, unicode):
|
||||
contents = contents.encode("UTF-8")
|
||||
f.write( contents )
|
||||
os.chmod( path, mode )
|
||||
self._handle_script_integrity( path )
|
||||
|
||||
def _handle_script_integrity( self, path ):
|
||||
if not getattr( self.app.config, "check_job_script_integrity", True ):
|
||||
return
|
||||
|
||||
script_integrity_verified = False
|
||||
for i in range(10):
|
||||
try:
|
||||
proc = subprocess.Popen( [path], shell=True, env={"ABC_TEST_JOB_SCRIPT_INTEGRITY_XYZ": "1"} )
|
||||
proc.wait()
|
||||
if proc.returncode == 42:
|
||||
script_integrity_verified = True
|
||||
break
|
||||
|
||||
# Else we will sync and wait to see if the script becomes
|
||||
# executable.
|
||||
try:
|
||||
# sync file system to avoid "Text file busy" problems.
|
||||
# These have occurred both in Docker containers and on EC2 clusters
|
||||
# under high load.
|
||||
subprocess.check_call(["/bin/sync"])
|
||||
except Exception:
|
||||
pass
|
||||
time.sleep( .25 )
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if not script_integrity_verified:
|
||||
raise Exception("Failed to write job script, could not verify job script integrity.")
|
||||
write_script( path, contents, self.app.config, mode=mode )
|
||||
|
||||
def _complete_terminal_job( self, ajs, **kwargs ):
|
||||
if ajs.job_wrapper.get_state() != model.Job.states.DELETED:
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
# The following block can be used by the job creation system
|
||||
# to ensure this script is runnable before running it directly
|
||||
# or submitting it to a cluster manager.
|
||||
if [ -n "$ABC_TEST_JOB_SCRIPT_INTEGRITY_XYZ" ]; then
|
||||
exit 42
|
||||
fi
|
||||
#!$shell
|
||||
|
||||
$integrity_injection
|
||||
$headers
|
||||
$slots_statement
|
||||
export GALAXY_SLOTS
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
import os
|
||||
from string import Template
|
||||
import subprocess
|
||||
import time
|
||||
from pkg_resources import resource_string
|
||||
|
||||
from six import text_type
|
||||
from galaxy.util import unicodify
|
||||
|
||||
DEFAULT_SHELL = '/bin/sh'
|
||||
|
||||
DEFAULT_JOB_FILE_TEMPLATE = Template(
|
||||
resource_string(__name__, 'DEFAULT_JOB_FILE_TEMPLATE.sh').decode('UTF-8')
|
||||
)
|
||||
@@ -13,6 +20,19 @@ SLOTS_STATEMENT_SINGLE = """
|
||||
GALAXY_SLOTS="1"
|
||||
"""
|
||||
|
||||
INTEGRITY_INJECTION = """
|
||||
# The following block can be used by the job system
|
||||
# to ensure this script is runnable before actually attempting
|
||||
# to run it.
|
||||
if [ -n "$ABC_TEST_JOB_SCRIPT_INTEGRITY_XYZ" ]; then
|
||||
exit 42
|
||||
fi
|
||||
"""
|
||||
|
||||
INTEGRITY_SYNC_COMMAND = "/bin/sync"
|
||||
DEFAULT_INTEGRITY_CHECK = True
|
||||
DEFAULT_INTEGRITY_COUNT = 35
|
||||
DEFAULT_INTEGRITY_SLEEP = .25
|
||||
REQUIRED_TEMPLATE_PARAMS = ['working_directory', 'command', 'exit_code_path']
|
||||
OPTIONAL_TEMPLATE_PARAMS = {
|
||||
'galaxy_lib': None,
|
||||
@@ -22,6 +42,8 @@ OPTIONAL_TEMPLATE_PARAMS = {
|
||||
'slots_statement': SLOTS_STATEMENT_CLUSTER_DEFAULT,
|
||||
'instrument_pre_commands': '',
|
||||
'instrument_post_commands': '',
|
||||
'integrity_injection': INTEGRITY_INJECTION,
|
||||
'shell': DEFAULT_SHELL,
|
||||
}
|
||||
|
||||
|
||||
@@ -67,3 +89,56 @@ def job_script(template=DEFAULT_JOB_FILE_TEMPLATE, **kwds):
|
||||
if not isinstance(template, Template):
|
||||
template = Template(template)
|
||||
return template.safe_substitute(template_params)
|
||||
|
||||
|
||||
def check_script_integrity(config):
|
||||
return getattr(config, "check_job_script_integrity", DEFAULT_INTEGRITY_CHECK)
|
||||
|
||||
|
||||
def write_script(path, contents, config, mode=0o755):
|
||||
with open(path, 'w') as f:
|
||||
if isinstance(contents, text_type):
|
||||
contents = contents.encode("UTF-8")
|
||||
f.write(contents)
|
||||
os.chmod(path, mode)
|
||||
_handle_script_integrity(path, config)
|
||||
|
||||
|
||||
def _handle_script_integrity(path, config):
|
||||
if not check_script_integrity(config):
|
||||
return
|
||||
|
||||
script_integrity_verified = False
|
||||
count = getattr(config, "check_job_script_integrity_count", DEFAULT_INTEGRITY_COUNT)
|
||||
sleep_amt = getattr(config, "check_job_script_integrity_sleep", DEFAULT_INTEGRITY_SLEEP)
|
||||
for i in range(count):
|
||||
try:
|
||||
proc = subprocess.Popen([path], shell=True, env={"ABC_TEST_JOB_SCRIPT_INTEGRITY_XYZ": "1"})
|
||||
proc.wait()
|
||||
if proc.returncode == 42:
|
||||
script_integrity_verified = True
|
||||
break
|
||||
|
||||
# Else we will sync and wait to see if the script becomes
|
||||
# executable.
|
||||
try:
|
||||
# sync file system to avoid "Text file busy" problems.
|
||||
# These have occurred both in Docker containers and on EC2 clusters
|
||||
# under high load.
|
||||
subprocess.check_call(INTEGRITY_SYNC_COMMAND)
|
||||
except Exception:
|
||||
pass
|
||||
time.sleep(sleep_amt)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if not script_integrity_verified:
|
||||
raise Exception("Failed to write job script, could not verify job script integrity.")
|
||||
|
||||
|
||||
__all__ = [
|
||||
'check_script_integrity',
|
||||
'job_script',
|
||||
'write_script',
|
||||
'INTEGRITY_INJECTION',
|
||||
]
|
||||
|
||||
@@ -259,6 +259,6 @@ class AccessDatasetRBACPermission( DatasetRBACPermission ):
|
||||
|
||||
def _role_is_permitted( self, dataset, role ):
|
||||
current_roles = self._roles( dataset )
|
||||
return ( self._is_public_from_roles( current_roles )
|
||||
# if there's only one role and this is it, let em in
|
||||
or ( ( len( current_roles ) == 1 ) and ( role == current_roles[0] ) ) )
|
||||
return ( self._is_public_from_roles( current_roles ) or
|
||||
# if there's only one role and this is it, let em in
|
||||
( ( len( current_roles ) == 1 ) and ( role == current_roles[0] ) ) )
|
||||
|
||||
@@ -1398,7 +1398,6 @@ class History( object, Dictifiable, UsesAnnotations, HasName ):
|
||||
assert db_session is not None
|
||||
query = db_session.query( content_class ).filter( content_class.table.c.history_id == self.id )
|
||||
query = query.order_by( content_class.table.c.hid.asc() )
|
||||
python_filter = None
|
||||
deleted = galaxy.util.string_as_bool_or_none( kwds.get( 'deleted', None ) )
|
||||
if deleted is not None:
|
||||
query = query.filter( content_class.deleted == deleted )
|
||||
@@ -1411,11 +1410,8 @@ class History( object, Dictifiable, UsesAnnotations, HasName ):
|
||||
if len(ids) < max_in_filter_length:
|
||||
query = query.filter( content_class.id.in_(ids) )
|
||||
else:
|
||||
python_filter = lambda content: content.id in ids
|
||||
if python_filter:
|
||||
return ifilter(python_filter, query)
|
||||
else:
|
||||
return query
|
||||
query = ifilter(lambda content: content.id in ids, query)
|
||||
return query
|
||||
|
||||
def __collection_contents_iter( self, **kwds ):
|
||||
return self.__filter_contents( HistoryDatasetCollectionAssociation, **kwds )
|
||||
|
||||
@@ -232,7 +232,8 @@ def total_size(o, handlers={}, verbose=False):
|
||||
|
||||
Recipe from: https://code.activestate.com/recipes/577504-compute-memory-footprint-of-an-object-and-its-cont/
|
||||
"""
|
||||
dict_handler = lambda d: chain.from_iterable(d.items())
|
||||
def dict_handler(d):
|
||||
return chain.from_iterable(d.items())
|
||||
all_handlers = { tuple: iter,
|
||||
list: iter,
|
||||
deque: iter,
|
||||
|
||||
@@ -61,7 +61,7 @@ def upgrade(migrate_engine):
|
||||
if r[1]:
|
||||
dataset_files = loads(r[1])
|
||||
for df in dataset_files:
|
||||
if type(df) == type(dict()):
|
||||
if isinstance(df, dict):
|
||||
cmd = "INSERT INTO sample_dataset VALUES (%s, %s, %s, %s, '%s', '%s', '%s', '%s', '%s')"
|
||||
cmd = cmd % ( nextval(migrate_engine, 'sample_dataset'),
|
||||
localtimestamp(migrate_engine),
|
||||
|
||||
@@ -77,7 +77,7 @@ def upgrade(migrate_engine):
|
||||
if not str( row[2] ).strip():
|
||||
continue
|
||||
fields_list = loads( str( row[2] ).strip() )
|
||||
if fields_list and type(values_list) == type(list()):
|
||||
if fields_list and isinstance(values_list, list):
|
||||
values_dict = {}
|
||||
for field_index, field in enumerate( fields_list ):
|
||||
field_name = field[ 'name' ]
|
||||
|
||||
@@ -136,7 +136,7 @@ def get_sequencer_id( migrate_engine, sequencer_info ):
|
||||
continue
|
||||
values = loads( values )
|
||||
# proceed only if sequencer_info is a valid list
|
||||
if values and type( values ) == type( dict() ):
|
||||
if values and isinstance(values, dict):
|
||||
if sequencer_info.get( 'host', '' ) == values.get( 'field_0', '' ) \
|
||||
and sequencer_info.get( 'username', '' ) == values.get( 'field_1', '' ) \
|
||||
and sequencer_info.get( 'password', '' ) == values.get( 'field_2', '' ) \
|
||||
@@ -236,7 +236,7 @@ def upgrade(migrate_engine):
|
||||
continue
|
||||
sequencer_info = loads( sequencer_info.strip() )
|
||||
# proceed only if sequencer_info is a valid dict
|
||||
if sequencer_info and type( sequencer_info ) == type( dict() ):
|
||||
if sequencer_info and isinstance(sequencer_info, dict):
|
||||
# check if this sequencer has already been added to the sequencer table
|
||||
sequencer_id = get_sequencer_id( migrate_engine, sequencer_info )
|
||||
if not sequencer_id:
|
||||
|
||||
@@ -18,7 +18,6 @@ from cgi import FieldStorage
|
||||
from xml.etree import ElementTree
|
||||
from mako.template import Template
|
||||
from paste import httpexceptions
|
||||
from sqlalchemy import and_
|
||||
|
||||
from galaxy import model
|
||||
from galaxy.managers import histories
|
||||
@@ -194,14 +193,13 @@ class ToolBox( BaseGalaxyToolBox ):
|
||||
# Abstract toolbox doesn't have a dependency on the the database, so
|
||||
# override _get_tool_shed_repository here to provide this information.
|
||||
|
||||
# We store only the port, if one exists, in the database.
|
||||
tool_shed = common_util.remove_protocol_from_tool_shed_url( tool_shed )
|
||||
return self.app.install_model.context.query( self.app.install_model.ToolShedRepository ) \
|
||||
.filter( and_( self.app.install_model.ToolShedRepository.table.c.tool_shed == tool_shed,
|
||||
self.app.install_model.ToolShedRepository.table.c.name == name,
|
||||
self.app.install_model.ToolShedRepository.table.c.owner == owner,
|
||||
self.app.install_model.ToolShedRepository.table.c.installed_changeset_revision == installed_changeset_revision ) ) \
|
||||
.first()
|
||||
return suc.get_installed_repository(
|
||||
self.app,
|
||||
tool_shed=tool_shed,
|
||||
name=name,
|
||||
owner=owner,
|
||||
installed_changeset_revision=installed_changeset_revision
|
||||
)
|
||||
|
||||
def __build_tool_version_select_field( self, tools, tool_id, set_selected ):
|
||||
"""Build a SelectField whose options are the ids for the received list of tools."""
|
||||
@@ -1675,7 +1673,7 @@ class Tool( object, Dictifiable ):
|
||||
if isinstance( input, Conditional ):
|
||||
cond_messages = {}
|
||||
if not input.is_job_resource_conditional:
|
||||
cond_messages = { input.test_param.name: "No value found for '%s%s', using default" % ( prefix, input.label ) }
|
||||
cond_messages = { input.test_param.name: "No value found for '%s%s', using default" % ( prefix, input.test_param.label ) }
|
||||
messages[ input.name ] = cond_messages
|
||||
test_value = input.test_param.get_initial_value( trans, context )
|
||||
current_case = input.get_current_case( test_value, trans )
|
||||
@@ -1689,6 +1687,7 @@ class Tool( object, Dictifiable ):
|
||||
messages[ input.name ].append( rep_dict )
|
||||
self.check_and_update_param_values_helper( input.inputs, {}, trans, rep_dict, context, rep_prefix, allow_workflow_parameters=allow_workflow_parameters )
|
||||
elif isinstance( input, Section ):
|
||||
messages[ input.name ] = {}
|
||||
self.check_and_update_param_values_helper( input.inputs, {}, trans, messages[ input.name ], context, prefix, allow_workflow_parameters=allow_workflow_parameters )
|
||||
else:
|
||||
messages[ input.name ] = "No value found for '%s%s', using default" % ( prefix, input.label )
|
||||
@@ -1718,7 +1717,8 @@ class Tool( object, Dictifiable ):
|
||||
current = group_values["__current_case__"]
|
||||
self.check_and_update_param_values_helper( input.cases[current].inputs, group_values, trans, messages, context, prefix, allow_workflow_parameters=allow_workflow_parameters )
|
||||
elif isinstance( input, Section ):
|
||||
self.check_and_update_param_values_helper( input.inputs, values[ input.name ], trans, messages, context, prefix, allow_workflow_parameters=allow_workflow_parameters )
|
||||
messages[ input.name ] = {}
|
||||
self.check_and_update_param_values_helper( input.inputs, values[ input.name ], trans, messages[ input.name ], context, prefix, allow_workflow_parameters=allow_workflow_parameters )
|
||||
else:
|
||||
# Regular tool parameter, no recursion needed
|
||||
try:
|
||||
|
||||
@@ -273,7 +273,7 @@ class DefaultToolAction( object ):
|
||||
child_dataset_names = set()
|
||||
object_store_populator = ObjectStorePopulator( app )
|
||||
|
||||
def handle_output( name, output ):
|
||||
def handle_output( name, output, hidden=None ):
|
||||
if output.parent:
|
||||
parent_to_child_pairs.append( ( output.parent, name ) )
|
||||
child_dataset_names.add( name )
|
||||
@@ -295,7 +295,9 @@ class DefaultToolAction( object ):
|
||||
input_ext
|
||||
)
|
||||
data = app.model.HistoryDatasetAssociation( extension=ext, create_dataset=True, flush=False )
|
||||
if output.hidden:
|
||||
if hidden is None:
|
||||
hidden = output.hidden
|
||||
if hidden:
|
||||
data.visible = False
|
||||
trans.sa_session.add( data )
|
||||
trans.app.security_agent.set_all_dataset_permissions( data.dataset, output_permissions, new=True )
|
||||
@@ -371,7 +373,10 @@ class DefaultToolAction( object ):
|
||||
current_element_identifiers = current_element_identifiers[ index ][ "element_identifiers" ]
|
||||
|
||||
effective_output_name = output_part_def.effective_output_name
|
||||
element = handle_output( effective_output_name, output_part_def.output_def )
|
||||
element = handle_output( effective_output_name, output_part_def.output_def, hidden=True )
|
||||
# TODO: this shouldn't exist in the top-level of the history at all
|
||||
# but for now we are still working around that by hiding the contents
|
||||
# there.
|
||||
# Following hack causes dataset to no be added to history...
|
||||
child_dataset_names.add( effective_output_name )
|
||||
|
||||
|
||||
@@ -350,7 +350,7 @@ def create_paramfile( trans, uploaded_datasets ):
|
||||
return json_file_path
|
||||
|
||||
|
||||
def create_job( trans, params, tool, json_file_path, data_list, folder=None, history=None ):
|
||||
def create_job( trans, params, tool, json_file_path, data_list, folder=None, history=None, job_params=None ):
|
||||
"""
|
||||
Create the upload job.
|
||||
"""
|
||||
@@ -395,7 +395,10 @@ def create_job( trans, params, tool, json_file_path, data_list, folder=None, his
|
||||
# open( dataset.file_name, "w" ).close()
|
||||
job.object_store_id = object_store_id
|
||||
job.set_state( job.states.NEW )
|
||||
job.set_handler(tool.get_job_handler(None))
|
||||
job.set_handler( tool.get_job_handler( None ) )
|
||||
if job_params:
|
||||
for name, value in job_params.iteritems():
|
||||
job.add_parameter( name, value )
|
||||
trans.sa_session.add( job )
|
||||
trans.sa_session.flush()
|
||||
|
||||
|
||||
@@ -23,10 +23,9 @@ try:
|
||||
except ImportError:
|
||||
shellescape = None
|
||||
|
||||
if job is not None:
|
||||
needs_shell_quoting = job.needs_shell_quoting
|
||||
else:
|
||||
needs_shell_quoting = None
|
||||
import re
|
||||
|
||||
needs_shell_quoting = re.compile(r"""(^$|[\s|&;()<>\'"$@])""").search
|
||||
|
||||
|
||||
def ensure_cwltool_available():
|
||||
|
||||
@@ -27,11 +27,11 @@ class DependencyResolver(Dictifiable, object):
|
||||
version for instance if the request version is 'default'.)
|
||||
"""
|
||||
|
||||
def _get_config_option(self, key, dependency_resolver, default=None, prefix=None, **kwds):
|
||||
def _get_config_option(self, key, dependency_resolver, default=None, config_prefix=None, **kwds):
|
||||
""" Look in resolver-specific settings for option and then fallback to
|
||||
global settings.
|
||||
"""
|
||||
global_key = "%s_%s" % (prefix, key)
|
||||
global_key = "%s_%s" % (config_prefix, key)
|
||||
if key in kwds:
|
||||
return kwds.get(key)
|
||||
elif global_key in dependency_resolver.extra_config:
|
||||
|
||||
@@ -42,7 +42,7 @@ class CondaDependencyResolver(DependencyResolver, ListableDependencyResolver, In
|
||||
self.versionless = _string_as_bool(kwds.get('versionless', 'false'))
|
||||
|
||||
def get_option(name):
|
||||
return self._get_config_option(name, dependency_manager, prefix="conda", **kwds)
|
||||
return self._get_config_option(name, dependency_manager, config_prefix="conda", **kwds)
|
||||
|
||||
# Conda context options (these define the environment)
|
||||
conda_prefix = get_option("prefix")
|
||||
@@ -177,7 +177,7 @@ class CondaDepenency(Dependency):
|
||||
return self._exact
|
||||
|
||||
def shell_commands(self, requirement):
|
||||
return """[ "$CONDA_DEFAULT_ENV" = "%s" ] || source %s '%s'""" % (
|
||||
return """[ "$CONDA_DEFAULT_ENV" = "%s" ] || . %s '%s'""" % (
|
||||
self.environment_path,
|
||||
self.activate,
|
||||
self.environment_path
|
||||
|
||||
@@ -754,7 +754,8 @@ class BaseURLToolParameter( HiddenToolParameter ):
|
||||
return d
|
||||
|
||||
|
||||
DEFAULT_VALUE_MAP = lambda x: x
|
||||
def DEFAULT_VALUE_MAP(x):
|
||||
return x
|
||||
|
||||
|
||||
def parse_dynamic_options(param, input_source):
|
||||
@@ -1873,9 +1874,11 @@ class DataToolParameter( BaseDataToolParameter ):
|
||||
|
||||
def _get_select_dataset_collection_fields( self, history, dataset_matcher, multiple=False, suffix="|__collection_multirun__", reduction=False ):
|
||||
if not reduction:
|
||||
value_modifier = lambda x: x
|
||||
def value_modifier(x):
|
||||
return x
|
||||
else:
|
||||
value_modifier = lambda value: "__collection_reduce__|%s" % value
|
||||
def value_modifier(value):
|
||||
return "__collection_reduce__|%s" % value
|
||||
|
||||
value = dataset_matcher.value
|
||||
if value is not None:
|
||||
@@ -2212,14 +2215,15 @@ class DataToolParameter( BaseDataToolParameter ):
|
||||
return d
|
||||
|
||||
# add datasets
|
||||
visible_hda = other_values.get( self.name )
|
||||
for hda in history.active_datasets_children_and_roles:
|
||||
match = dataset_matcher.hda_match( hda )
|
||||
match = dataset_matcher.hda_match( hda, ensure_visible=visible_hda != hda )
|
||||
if match:
|
||||
m = match.hda
|
||||
d['options']['hda'].append({
|
||||
'id' : trans.security.encode_id( m.id ),
|
||||
'hid' : m.hid,
|
||||
'name' : m.name,
|
||||
'name' : m.name if m.visible else '(hidden) %s' % m.name,
|
||||
'src' : 'hda'
|
||||
})
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"""
|
||||
import os
|
||||
import re
|
||||
import operator
|
||||
import glob
|
||||
import json
|
||||
|
||||
@@ -220,7 +221,7 @@ def collect_primary_datasets( tool, output, job_working_directory, input_ext ):
|
||||
primary_output_assigned = True
|
||||
continue
|
||||
if name not in primary_datasets:
|
||||
primary_datasets[ name ] = {}
|
||||
primary_datasets[ name ] = odict.odict()
|
||||
visible = fields_match.visible
|
||||
ext = fields_match.ext
|
||||
if ext == "input":
|
||||
@@ -310,6 +311,7 @@ def collect_primary_datasets( tool, output, job_working_directory, input_ext ):
|
||||
|
||||
def walk_over_extra_files( extra_file_collectors, job_working_directory, matchable ):
|
||||
for extra_file_collector in extra_file_collectors:
|
||||
matches = []
|
||||
directory = job_working_directory
|
||||
if extra_file_collector.directory:
|
||||
directory = os.path.join( directory, extra_file_collector.directory )
|
||||
@@ -317,12 +319,16 @@ def walk_over_extra_files( extra_file_collectors, job_working_directory, matchab
|
||||
raise Exception( "Problem with tool configuration, attempting to pull in datasets from outside working directory." )
|
||||
if not os.path.isdir( directory ):
|
||||
continue
|
||||
for filename in sorted( os.listdir( directory ) ):
|
||||
for filename in os.listdir( directory ):
|
||||
path = os.path.join( directory, filename )
|
||||
if not os.path.isfile( path ):
|
||||
continue
|
||||
if extra_file_collector.match( matchable, filename ):
|
||||
yield path, extra_file_collector
|
||||
match = extra_file_collector.match( matchable, filename, path=path )
|
||||
if match:
|
||||
matches.append(match)
|
||||
|
||||
for match in extra_file_collector.sort(matches):
|
||||
yield match.path, extra_file_collector
|
||||
|
||||
|
||||
def dataset_collector( dataset_collection_description ):
|
||||
@@ -339,6 +345,9 @@ class DatasetCollector( object ):
|
||||
def __init__( self, dataset_collection_description ):
|
||||
# dataset_collection_description is an abstract description
|
||||
# built from the tool parsing module - see galaxy.tools.parser.output_colleciton_def
|
||||
self.sort_key = dataset_collection_description.sort_key
|
||||
self.sort_reverse = dataset_collection_description.sort_reverse
|
||||
self.sort_comp = dataset_collection_description.sort_comp
|
||||
self.pattern = dataset_collection_description.pattern
|
||||
self.default_dbkey = dataset_collection_description.default_dbkey
|
||||
self.default_ext = dataset_collection_description.default_ext
|
||||
@@ -352,20 +361,38 @@ class DatasetCollector( object ):
|
||||
token_replacement = str( dataset_instance.id )
|
||||
return self.pattern.replace( DATASET_ID_TOKEN, token_replacement )
|
||||
|
||||
def match( self, dataset_instance, filename ):
|
||||
def match( self, dataset_instance, filename, path=None ):
|
||||
pattern = self.pattern_for_dataset( dataset_instance )
|
||||
re_match = re.match( pattern, filename )
|
||||
match_object = None
|
||||
if re_match:
|
||||
match_object = CollectedDatasetMatch( re_match, self )
|
||||
match_object = CollectedDatasetMatch( re_match, self, filename, path=path )
|
||||
return match_object
|
||||
|
||||
def sort( self, matches ):
|
||||
reverse = self.sort_reverse
|
||||
sort_key = self.sort_key
|
||||
sort_comp = self.sort_comp
|
||||
assert sort_key in ["filename", "dbkey", "name", "designation"]
|
||||
assert sort_comp in ["lexical", "numeric"]
|
||||
key = operator.attrgetter(sort_key)
|
||||
if sort_comp == "numeric":
|
||||
key = _compose(int, key)
|
||||
|
||||
return sorted(matches, key=key, reverse=reverse)
|
||||
|
||||
|
||||
def _compose(f, g):
|
||||
return lambda x: f(g(x))
|
||||
|
||||
|
||||
class CollectedDatasetMatch( object ):
|
||||
|
||||
def __init__( self, re_match, collector ):
|
||||
def __init__( self, re_match, collector, filename, path=None ):
|
||||
self.re_match = re_match
|
||||
self.collector = collector
|
||||
self.filename = filename
|
||||
self.path = path
|
||||
|
||||
@property
|
||||
def designation( self ):
|
||||
|
||||
@@ -593,7 +593,9 @@ def parse_cast_attribute( cast ):
|
||||
elif cast == 'str':
|
||||
cast = str
|
||||
else:
|
||||
cast = lambda x: x # return value as-is
|
||||
# return value as-is
|
||||
def cast(x):
|
||||
return x
|
||||
return cast
|
||||
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@ dataset collection after jobs are finished.
|
||||
from galaxy.util import asbool
|
||||
|
||||
DEFAULT_EXTRA_FILENAME_PATTERN = r"primary_DATASET_ID_(?P<designation>[^_]+)_(?P<visible>[^_]+)_(?P<ext>[^_]+)(_(?P<dbkey>[^_]+))?"
|
||||
DEFAULT_SORT_BY = "filename"
|
||||
DEFAULT_SORT_COMP = "lexical"
|
||||
|
||||
|
||||
# XML can describe custom patterns, but these literals describe named
|
||||
@@ -44,5 +46,24 @@ class DatasetCollectionDescription(object):
|
||||
self.default_visible = asbool( kwargs.get( "visible", None ) )
|
||||
self.directory = kwargs.get( "directory", None )
|
||||
self.assign_primary_output = asbool( kwargs.get( 'assign_primary_output', False ) )
|
||||
sort_by = kwargs.get( "sort_by", DEFAULT_SORT_BY )
|
||||
if sort_by.startswith("reverse_"):
|
||||
self.sort_reverse = True
|
||||
sort_by = sort_by[len("reverse_"):]
|
||||
else:
|
||||
self.sort_reverse = False
|
||||
if "_" in sort_by:
|
||||
sort_comp, sort_by = sort_by.split("_", 1)
|
||||
assert sort_comp in ["lexical", "numeric"]
|
||||
else:
|
||||
sort_comp = DEFAULT_SORT_COMP
|
||||
assert sort_by in [
|
||||
"filename",
|
||||
"name",
|
||||
"designation",
|
||||
"dbkey"
|
||||
]
|
||||
self.sort_key = sort_by
|
||||
self.sort_comp = sort_comp
|
||||
|
||||
DEFAULT_DATASET_COLLECTOR_DESCRIPTION = DatasetCollectionDescription()
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
import logging
|
||||
import os
|
||||
import os.path
|
||||
import galaxy.tools.parameters.basic
|
||||
import galaxy.tools.parameters.grouping
|
||||
from galaxy.util import string_as_bool
|
||||
|
||||
try:
|
||||
from nose.tools import nottest
|
||||
except ImportError:
|
||||
nottest = lambda x: x
|
||||
import logging
|
||||
def nottest(x):
|
||||
return x
|
||||
|
||||
log = logging.getLogger( __name__ )
|
||||
|
||||
@@ -74,11 +76,15 @@ class ToolTestBuilder( object ):
|
||||
query_value = test_param.checked
|
||||
else:
|
||||
query_value = _process_bool_param_value( test_param, declared_value )
|
||||
matches_declared_value = lambda case_value: _process_bool_param_value( test_param, case_value ) == query_value
|
||||
|
||||
def matches_declared_value(case_value):
|
||||
return _process_bool_param_value( test_param, case_value ) == query_value
|
||||
elif isinstance(test_param, galaxy.tools.parameters.basic.SelectToolParameter):
|
||||
if declared_value is not None:
|
||||
# Test case supplied explicit value to check against.
|
||||
matches_declared_value = lambda case_value: case_value == declared_value
|
||||
|
||||
def matches_declared_value(case_value):
|
||||
return case_value == declared_value
|
||||
elif test_param.static_options:
|
||||
# No explicit value in test case, not much to do if options are dynamic but
|
||||
# if static options are available can find the one specified as default or
|
||||
@@ -90,7 +96,9 @@ class ToolTestBuilder( object ):
|
||||
first_option = test_param.static_options[0]
|
||||
first_option_value = first_option[1]
|
||||
default_option = first_option_value
|
||||
matches_declared_value = lambda case_value: case_value == default_option
|
||||
|
||||
def matches_declared_value(case_value):
|
||||
return case_value == default_option
|
||||
else:
|
||||
# No explicit value for this param and cannot determine a
|
||||
# default - give up. Previously this would just result in a key
|
||||
|
||||
@@ -17,6 +17,7 @@ from galaxy.util import string_as_bool
|
||||
from galaxy.util.bunch import Bunch
|
||||
|
||||
from .parser import get_toolbox_parser, ensure_tool_conf_item
|
||||
|
||||
from .panel import ToolPanelElements
|
||||
from .panel import ToolSectionLabel
|
||||
from .panel import ToolSection
|
||||
@@ -556,11 +557,24 @@ class AbstractToolBox( Dictifiable, ManagesIntegratedToolPanelMixin, object ):
|
||||
# Backward compatibility issue - the tag used to be named 'changeset_revision'.
|
||||
installed_changeset_revision_elem = item.elem.find( "changeset_revision" )
|
||||
installed_changeset_revision = installed_changeset_revision_elem.text
|
||||
try:
|
||||
splitted_path = path.split('/')
|
||||
assert splitted_path[0] == tool_shed
|
||||
assert splitted_path[2] == repository_owner
|
||||
assert splitted_path[3] == repository_name
|
||||
if splitted_path[4] != installed_changeset_revision:
|
||||
# This can happen if the Tool Shed repository has been
|
||||
# updated to a new revision and the installed_changeset_revision
|
||||
# element in shed_tool_conf.xml file has been updated too
|
||||
log.debug("The installed_changeset_revision for tool %s is %s, using %s instead", path, installed_changeset_revision, splitted_path[4])
|
||||
installed_changeset_revision = splitted_path[4]
|
||||
except Exception as e:
|
||||
log.debug("Error while loading tool %s : %s", path, e)
|
||||
pass
|
||||
tool_shed_repository = self._get_tool_shed_repository( tool_shed,
|
||||
repository_name,
|
||||
repository_owner,
|
||||
installed_changeset_revision )
|
||||
|
||||
if tool_shed_repository:
|
||||
# Only load tools if the repository is not deactivated or uninstalled.
|
||||
can_load_into_panel_dict = not tool_shed_repository.deleted
|
||||
|
||||
@@ -53,10 +53,11 @@ class ToolSection( Dictifiable, HasPanelItems, object ):
|
||||
def __init__( self, item=None ):
|
||||
""" Build a ToolSection from an ElementTree element or a dictionary.
|
||||
"""
|
||||
f = lambda item, val: item is not None and item.get( val ) or ''
|
||||
self.name = f( item, 'name' )
|
||||
self.id = f( item, 'id' )
|
||||
self.version = f( item, 'version' )
|
||||
if item is None:
|
||||
item = dict()
|
||||
self.name = item.get('name') or ''
|
||||
self.id = item.get('id') or ''
|
||||
self.version = item.get('version') or ''
|
||||
self.elems = ToolPanelElements()
|
||||
|
||||
def copy( self ):
|
||||
|
||||
@@ -9,8 +9,9 @@ try:
|
||||
from watchdog.observers.polling import PollingObserver
|
||||
can_watch = True
|
||||
except ImportError:
|
||||
Observer = None
|
||||
FileSystemEventHandler = object
|
||||
PollingObserver = object
|
||||
PollingObserver = None
|
||||
can_watch = False
|
||||
|
||||
log = logging.getLogger( __name__ )
|
||||
|
||||
@@ -12,9 +12,12 @@ log = getLogger( __name__ )
|
||||
# remote ComputeEnvironments (such as one used by Pulsar) determine what values to
|
||||
# rewrite or transfer...
|
||||
PATH_ATTRIBUTES = [ "path" ]
|
||||
|
||||
|
||||
# ... by default though - don't rewrite anything (if no ComputeEnviornment
|
||||
# defined or ComputeEnvironment doesn't supply a rewriter).
|
||||
DEFAULT_PATH_REWRITER = lambda x: x
|
||||
def DEFAULT_PATH_REWRITER(x):
|
||||
return x
|
||||
|
||||
|
||||
class ToolParameterValueWrapper( object ):
|
||||
|
||||
@@ -94,7 +94,8 @@ INVALID_CHARACTER = "X"
|
||||
|
||||
if sys.version_info > (3, 0):
|
||||
# __coerce__ doesn't do anything under Python anyway.
|
||||
coerce = lambda x, y: x
|
||||
def coerce(x, y):
|
||||
return x
|
||||
|
||||
|
||||
def sanitize_lists_to_string( values, valid_characters=VALID_CHARACTERS, character_map=CHARACTER_MAP, invalid_character=INVALID_CHARACTER ):
|
||||
|
||||
@@ -7,12 +7,13 @@ from __future__ import with_statement
|
||||
|
||||
import inspect
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
import sys
|
||||
|
||||
from galaxy.util.properties import NicerConfigParser
|
||||
|
||||
import pkg_resources
|
||||
from six import iteritems
|
||||
|
||||
__all__ = ['loadapp', 'loadserver', 'loadfilter', 'appconfig']
|
||||
|
||||
@@ -31,15 +32,11 @@ def print_(template, *args, **kwargs):
|
||||
|
||||
if sys.version_info < (3, 0):
|
||||
from urllib import unquote
|
||||
iteritems = lambda d: d.iteritems()
|
||||
dictkeys = lambda d: d.keys()
|
||||
|
||||
def reraise(t, e, tb):
|
||||
exec('raise t, e, tb', dict(t=t, e=e, tb=tb))
|
||||
else:
|
||||
from urllib.parse import unquote
|
||||
iteritems = lambda d: d.items()
|
||||
dictkeys = lambda d: list(d.keys())
|
||||
|
||||
def reraise(t, e, tb):
|
||||
exec('raise e from tb', dict(e=e, tb=tb))
|
||||
@@ -63,9 +60,9 @@ def fix_type_error(exc_info, callable, varargs, kwargs):
|
||||
"""
|
||||
if exc_info is None:
|
||||
exc_info = sys.exc_info()
|
||||
if (exc_info[0] != TypeError
|
||||
or str(exc_info[1]).find('arguments') == -1
|
||||
or getattr(exc_info[1], '_type_error_fixed', False)):
|
||||
if (exc_info[0] != TypeError or
|
||||
str(exc_info[1]).find('arguments') == -1 or
|
||||
getattr(exc_info[1], '_type_error_fixed', False)):
|
||||
return exc_info
|
||||
exc_info[1]._type_error_fixed = True
|
||||
argspec = inspect.formatargspec(*inspect.getargspec(callable))
|
||||
@@ -703,7 +700,7 @@ class EggLoader(_Loader):
|
||||
dist.location,
|
||||
', '.join(_flatten(object_type.egg_protocols)),
|
||||
', '.join(_flatten([
|
||||
dictkeys(pkg_resources.get_entry_info(self.spec, prot, name) or {})
|
||||
list((pkg_resources.get_entry_info(self.spec, prot, name) or {}).keys())
|
||||
for prot in protocol_options] or '(no entry points)'))))
|
||||
if len(possible) > 1:
|
||||
raise LookupError(
|
||||
|
||||
@@ -260,9 +260,12 @@ class Genomes( object ):
|
||||
# Add app keys to dbkeys.
|
||||
|
||||
# If chrom_info is True, only include keys with len files (which contain chromosome info).
|
||||
filter_fn = lambda b: True
|
||||
if chrom_info:
|
||||
filter_fn = lambda b: b.len_file is not None
|
||||
def filter_fn(b):
|
||||
return b.len_file is not None
|
||||
else:
|
||||
def filter_fn(b):
|
||||
return True
|
||||
|
||||
dbkeys.extend( [ ( genome.description, genome.key ) for key, genome in self.genomes.items() if filter_fn( genome ) ] )
|
||||
|
||||
|
||||
@@ -15,7 +15,8 @@ except ImportError:
|
||||
oidutil = None
|
||||
|
||||
class FakeConsumer( object ):
|
||||
__getattr__ = lambda x, y: None
|
||||
def __getattr__(x, y):
|
||||
return None
|
||||
consumer = FakeConsumer()
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user