Merge remote-tracking branch 'upstream/dev' into managers.ratable

This commit is contained in:
carlfeberhard
2016-02-08 11:47:42 -05:00
137 changed files with 2849 additions and 1020 deletions
+6
View File
@@ -0,0 +1,6 @@
echo "Testing for correct startup:"
bash run.sh --daemon && sleep 30s && curl -I localhost:8080
EXIT_CODE=$?
echo "exit code:$EXIT_CODE, showing startup log:"
cat paster.log
exit $EXIT_CODE
+17
View File
@@ -1,5 +1,7 @@
language: python
python: 2.7
os:
- linux
env:
- TOX_ENV=py34-lint
- TOX_ENV=py27-lint
@@ -7,10 +9,25 @@ env:
- TOX_ENV=py27-unit
- TOX_ENV=py26-unit
- TOX_ENV=qunit
- TOX_ENV=first_startup
matrix:
include:
- os: osx
env: TOX_ENV=first_startup
language: generic
- os: osx
env: TOX_ENV=py27-unit
language: generic
before_install:
- if [ `uname` == "Darwin" ]; then bash -c "brew update && brew install python"; fi
install:
- pip install tox
- if [ "$TOX_ENV" == "qunit" ]; then bash -c 'cd test/qunit && npm install'; fi
- if [ "$TOX_ENV" == "first_startup" ]; then bash -c "bash scripts/common_startup.sh && wget -q https://github.com/jmchilton/galaxy-downloads/raw/master/db_gx_rev_0127.sqlite && mv db_gx_rev_0127.sqlite database/universe.sqlite && bash manage_db.sh -c ./config/galaxy.ini.sample upgrade"; fi
script: tox -e $TOX_ENV
notifications:
email: false
+12 -1
View File
@@ -7,7 +7,8 @@ var jQuery = require( 'jquery' ),
ToolPanel = require( './tool-panel' ),
HistoryPanel = require( './history-panel' ),
PAGE = require( 'layout/page' ),
ToolForm = require( 'mvc/tool/tool-form' );
ToolForm = require( 'mvc/tool/tool-form' ),
Tours = require( 'mvc/tours' );
/** define the 'Analyze Data'/analysis/main/home page for Galaxy
* * has a masthead
@@ -99,6 +100,16 @@ window.app = function app( options, bootstrapped ){
'(/)' : 'home',
// TODO: remove annoying 'root' from root urls
'(/)root*' : 'home',
'(/)tours(/:tour_id)' : 'show_tours',
},
show_tours : function( tour_id ){
if (tour_id){
Tours.giveTour(tour_id);
}
else{
centerPanel.display( new Tours.ToursView() );
}
},
/** */
+7 -2
View File
@@ -144,8 +144,13 @@ var Collection = Backbone.Collection.extend({
target : '_blank'
},{
title : 'Interactive Tours',
onclick : function(c){
Galaxy.app.display(new Tours.ToursView());
onclick : function(){
if (Galaxy.app){
Galaxy.app.display(new Tours.ToursView());
} else {
// Redirect and use clientside routing to go to tour index
window.location = Galaxy.root + "#/tours";
}
},
target : 'galaxy_main'
}]
+1 -1
View File
@@ -94,7 +94,7 @@ var PageLayoutView = Backbone.View.extend( BaseMVC.LoggableMixin ).extend({
page[ panelId ].setElement( '#' + panelId );
page[ panelId ].render();
} else if ( panelId !== 'center' ) {
page.center.$el( panelId, 0 );
page.center.$el.css( panelId, 0 );
}
});
return this;
+3 -3
View File
@@ -109,9 +109,9 @@ define([], function() {
tmp += '<div class="ui-form-info">';
if (options.help) {
tmp += options.help;
if (options.argument && options.help.indexOf('(' + options.argument + ')') == -1) {
tmp += ' (' + options.argument + ')';
}
}
if (options.argument && options.help.indexOf('(' + options.argument + ')') == -1) {
tmp += ' (' + options.argument + ')';
}
tmp += '</div>' +
'<div class="ui-form-backdrop"/>' +
+3 -10
View File
@@ -147,16 +147,9 @@ define(['utils/utils',
//
// add parsed/minimum number of repeat blocks
//
var n_min = input_def.min;
var n_cache = _.size(input_def.cache);
for (var i = 0; i < Math.max(n_cache, n_min); i++) {
var inputs = null;
if (i < n_cache) {
inputs = input_def.cache[i];
} else {
inputs = input_def.inputs;
}
create(inputs);
var n_cache = _.size( input_def.cache );
for ( var i = 0; i < Math.max( Math.max( n_cache, input_def.min ), input_def.default ); i++ ) {
create( i < n_cache ? input_def.cache[ i ] : input_def.inputs );
}
// hide options
@@ -195,6 +195,7 @@ var View = Backbone.View.extend({
for (var i in options) {
var item = options[i];
select_options.push({
hid : item.hid,
label: item.hid + ': ' + item.name,
value: item.id
});
@@ -202,7 +203,7 @@ var View = Backbone.View.extend({
self.history[item.id + '_' + item.src] = item;
}
// update field
field.update(select_options);
field.add( select_options, function( a, b ) { return b.hid - a.hid } );
}
}
@@ -178,11 +178,6 @@ var FolderListView = Backbone.View.extend({
var fetched_metadata = this.folderContainer.attributes.metadata;
fetched_metadata.contains_file_or_folder = typeof this.collection.findWhere({type: 'file'}) !== 'undefined' || typeof this.collection.findWhere({type: 'folder'}) !== 'undefined';
Galaxy.libraries.folderToolbarView.configureElements(fetched_metadata);
$('.library-row').hover(function() {
$(this).find('.show_on_hover').show();
}, function () {
$(this).find('.show_on_hover').hide();
});
},
/**
@@ -207,18 +202,12 @@ var FolderListView = Backbone.View.extend({
// model.set('readable_size', this.size_to_string(model.get('file_size')));
//}
model.set('folder_id', this.id);
var rowView = new mod_library_folderrow_view.FolderRowView(model);
var rowView = new mod_library_folderrow_view.FolderRowView({model: model});
// save new rowView to cache
this.rowViews[model.get('id')] = rowView;
this.$el.find('#first_folder_item').after(rowView.el);
$('.library-row').hover(function() {
$(this).find('.show_on_hover').show();
}, function () {
$(this).find('.show_on_hover').hide();
});
},
/**
@@ -226,7 +215,9 @@ var FolderListView = Backbone.View.extend({
* @param {Item or FolderAsModel} model of the view that will be removed
*/
removeOne: function( model ){
this.$el.find( '#' + model.id ).remove();
this.$el.find('tr').filter(function(){
return $(this).data('id') && $(this).data('id') === model.id;
}).remove();
},
/**
@@ -310,8 +301,8 @@ var FolderListView = Backbone.View.extend({
$row = $(event.target.parentElement.parentElement);
source = 'input';
} else if (event.target.localName === 'td') {
checkbox = $("#" + event.target.parentElement.id).find(':checkbox')[0];
$row = $(event.target.parentElement);
checkbox = $row.find(':checkbox')[0];
source = 'td';
}
if (checkbox.checked){
@@ -374,6 +365,7 @@ var FolderListView = Backbone.View.extend({
tmpl_array.push(' <th class="button_heading"></th>');
tmpl_array.push(' <th style="text-align: center; width: 20px; " title="Check to select all datasets"><input id="select-all-checkboxes" style="margin: 0;" type="checkbox"></th>');
tmpl_array.push(' <th><a class="sort-folder-link" title="Click to reverse order" href="#">name</a> <span title="Sorted alphabetically" class="sort-icon fa fa-sort-alpha-<%- order %>"></span></th>');
tmpl_array.push(' <th style="width:25%;">description</th>');
tmpl_array.push(' <th style="width:5%;">data type</th>');
tmpl_array.push(' <th style="width:10%;">size</th>');
tmpl_array.push(' <th style="width:160px;">time updated (UTC)</th>');
@@ -388,6 +380,7 @@ var FolderListView = Backbone.View.extend({
tmpl_array.push(' <td></td>');
tmpl_array.push(' <td></td>');
tmpl_array.push(' <td></td>');
tmpl_array.push(' <td></td>');
tmpl_array.push(' </tr>');
tmpl_array.push(' </tbody>');
@@ -1,43 +1,51 @@
define([
"layout/masthead",
"utils/utils",
"libs/toastr",
"mvc/library/library-model",
"mvc/library/library-dataset-view"],
function(mod_masthead,
mod_utils,
mod_toastr,
function(mod_toastr,
mod_library_model,
mod_library_dataset_view) {
var FolderRowView = Backbone.View.extend({
lastSelectedHistory: '',
events: {
'click .undelete_dataset_btn' : 'undeleteDataset',
'click .undelete_folder_btn' : 'undeleteFolder'
'click .undelete_folder_btn' : 'undeleteFolder',
'click .edit_folder_btn' : 'startModifications',
'click .cancel_folder_btn' : 'cancelModifications',
'click .save_folder_btn' : 'saveModifications',
},
options: {
type: null
defaults: {
type: null,
visibility_config: {
edit_folder_btn: true,
save_folder_btn: false,
cancel_folder_btn: false,
permission_folder_btn: true
},
edit_mode: false
},
initialize : function(folder_item){
this.model = folder_item;
this.render(folder_item);
initialize : function(options){
this.options = _.defaults( options || {}, this.defaults );
this.render(this.options);
},
render: function(folder_item){
render: function(options){
this.options = _.extend( this.options, options );
var folder_item = this.options.model;
var template = null;
if (folder_item.get('type') === 'folder' || folder_item.get('model_class') === 'LibraryFolder'){
this.options.type = 'folder';
this.prepareButtons(folder_item);
if (folder_item.get('deleted')){
template = this.templateRowDeletedFolder();
} else{
} else {
template = this.templateRowFolder();
}
} else if (folder_item.get('type') === 'file' || folder_item.get('model_class') === 'LibraryDatasetDatasetAssociation'){
} else if (folder_item.get('type') === 'file' || folder_item.get('model_class') === 'LibraryDatasetDatasetAssociation' || folder_item.get('model_class') === 'LibraryDataset'){
this.options.type = 'file';
if (folder_item.get('deleted')){
template = this.templateRowDeletedFile();
@@ -48,22 +56,52 @@ var FolderRowView = Backbone.View.extend({
console.error('Unknown library item type found.');
console.error(folder_item.get('type') || folder_item.get('model_class'));
}
this.setElement(template({content_item:folder_item}));
this.setElement(template({content_item: folder_item, edit_mode: this.options.edit_mode, button_config: this.options.visibility_config}));
this.$el.show();
return this;
},
/**
* Modify the visibility of buttons for
* the filling of the row template of a given folder.
*/
prepareButtons: function(folder){
vis_config = this.options.visibility_config;
if (this.options.edit_mode === false){
vis_config.save_folder_btn = false;
vis_config.cancel_folder_btn = false;
if (folder.get('deleted') === true ){
vis_config.edit_folder_btn = false;
vis_config.permission_folder_btn = false;
} else if (folder.get('deleted') === false ) {
vis_config.save_folder_btn = false;
vis_config.cancel_folder_btn = false;
if (folder.get('can_modify') === true){
vis_config.edit_folder_btn = true;
}
if (folder.get('can_manage') === true){
vis_config.permission_folder_btn = true;
}
}
} else if (this.options.edit_mode === true){
vis_config.edit_folder_btn = false;
vis_config.permission_folder_btn = false;
vis_config.save_folder_btn = true;
vis_config.cancel_folder_btn = true;
}
this.options.visibility_config = vis_config;
},
/* Show the page with dataset details. */
showDatasetDetails : function(){
Galaxy.libraries.datasetView = new mod_library_dataset_view.LibraryDatasetView({id: this.id});
},
/**
* Undeletes the dataset on server and renders the row again.
*/
/* Undelete the dataset on server and render the row again. */
undeleteDataset : function(event){
$(".tooltip").hide();
var that = this;
var dataset_id = $(event.target).closest('tr')[0].id;
var dataset_id = $(event.target).closest('tr').data('id');
var dataset = Galaxy.libraries.folderListView.collection.get(dataset_id);
dataset.url = dataset.urlRoot + dataset.id + '?undelete=true';
dataset.destroy({
@@ -87,13 +125,11 @@ var FolderRowView = Backbone.View.extend({
});
},
/**
* Undeletes the folder on server and renders the row again.
*/
/* Undelete the folder on server and render the row again. */
undeleteFolder : function(event){
$(".tooltip").hide();
var that = this;
var folder_id = $(event.target).closest('tr')[0].id;
var folder_id = $(event.target).closest('tr').data('id');
var folder = Galaxy.libraries.folderListView.collection.get(folder_id);
folder.url = folder.urlRoot + folder.id + '?undelete=true';
folder.destroy({
@@ -114,37 +150,128 @@ var FolderRowView = Backbone.View.extend({
});
},
/* User clicked the 'edit' button on row so render the row as editable. */
startModifications: function(){
this.options.edit_mode = true;
this.repaint();
},
/* User clicked the 'cancel' button so render normal row */
cancelModifications: function(){
this.options.edit_mode = false;
this.repaint();
},
saveModifications: function(){
var folder = Galaxy.libraries.folderListView.collection.get(this.$el.data('id'));
var is_changed = false;
var new_name = this.$el.find('.input_folder_name').val();
if (typeof new_name !== 'undefined' && new_name !== folder.get('name') ){
if (new_name.length > 2){
folder.set("name", new_name);
is_changed = true;
} else{
mod_toastr.warning('Folder name has to be at least 3 characters long.');
return;
}
}
var new_description = this.$el.find('.input_folder_description').val();
if (typeof new_description !== 'undefined' && new_description !== folder.get('description') ){
folder.set("description", new_description);
is_changed = true;
}
if (is_changed){
var row_view = this;
folder.save(null, {
patch: true,
success: function(folder) {
row_view.options.edit_mode = false;
row_view.repaint(folder);
mod_toastr.success('Changes to folder saved.');
},
error: function(model, response){
if (typeof response.responseJSON !== "undefined"){
mod_toastr.error(response.responseJSON.err_msg);
} else {
mod_toastr.error('An error occured while attempting to update the folder.');
}
}
});
} else {
this.options.edit_mode = false;
this.repaint(folder);
mod_toastr.info('Nothing has changed.');
}
},
repaint: function(){
/* need to hide manually because of the element removal in setElement
invoked in render() */
$(".tooltip").hide();
/* we need to store the old element to be able to replace it with
new one */
var old_element = this.$el;
/* if user canceled the folder param is undefined,
if user saved and succeeded the updated folder is rendered */
this.render();
old_element.replaceWith(this.$el);
/* now we attach new tooltips to the newly created row element */
this.$el.find("[data-toggle]").tooltip();
},
templateRowFolder: function() {
tmpl_array = [];
tmpl_array.push('<tr class="folder_row light library-row" id="<%- content_item.id %>">');
tmpl_array.push(' <td>');
tmpl_array.push(' <span title="Folder" class="fa fa-folder-o"></span>');
tmpl_array.push(' </td>');
tmpl_array.push(' <td style="text-align: center; "><input style="margin: 0;" type="checkbox"></td>');
tmpl_array.push(' <td>');
tmpl_array.push(' <a href="#folders/<%- content_item.id %>"><%- content_item.get("name") %></a>');
tmpl_array.push(' </td>');
tmpl_array.push(' <td>folder</td>');
tmpl_array.push(' <td></td>');
tmpl_array.push(' <td><%= _.escape(content_item.get("update_time")) %></td>'); // time updated
tmpl_array.push(' <td>');
tmpl_array.push(' <% if (content_item.get("can_manage")) { %><a href="#/folders/<%- content_item.id %>/permissions"><button data-toggle="tooltip" data-placement="top" class="primary-button btn-xs permissions-folder-btn show_on_hover" title="Manage permissions" style="display:none;"><span class="fa fa-group"></span></button></a><% } %>');
tmpl_array.push(' </td>');
tmpl_array.push('</tr>');
return _.template(tmpl_array.join(''));
return _.template([
'<tr class="folder_row light library-row" data-id="<%- content_item.id %>">',
'<td>',
'<span title="Folder" class="fa fa-folder-o"></span>',
'</td>',
'<td style="text-align: center; "><input style="margin: 0;" type="checkbox"></td>',
'<% if(!edit_mode) { %>',
'<td>',
'<a href="#folders/<%- content_item.id %>"><%- content_item.get("name") %></a>',
'</td>',
'<td>',
'<%- content_item.get("description") %>',
'</td>',
'<% } else if(edit_mode){ %>',
'<td><textarea rows="4" class="form-control input_folder_name" placeholder="name" ><%- content_item.get("name") %></textarea></td>',
'<td><textarea rows="4" class="form-control input_folder_description" placeholder="description" ><%- content_item.get("description") %></textarea></td>',
'<% } %>',
'<td>folder</td>',
'<td></td>',
'<td>',
'<%= _.escape(content_item.get("update_time")) %>',
'</td>',
'<td>',
'<% if(edit_mode) { %>', // start edit mode
'<button data-toggle="tooltip" data-placement="top" title="Save changes" class="primary-button btn-xs save_folder_btn" type="button" style="<% if(button_config.save_folder_btn === false) { print("display:none;") } %>"><span class="fa fa-floppy-o"> Save</span></button>',
'<button data-toggle="tooltip" data-placement="top" title="Discard changes" class="primary-button btn-xs cancel_folder_btn" type="button" style="<% if(button_config.cancel_folder_btn === false) { print("display:none;") } %>"><span class="fa fa-times"> Cancel</span></button>',
'<% } else if (!edit_mode){%>', // start no edit mode
'<button data-toggle="tooltip" data-placement="top" title="Modify \'<%- content_item.get("name") %>\'" class="primary-button btn-xs edit_folder_btn" type="button" style="<% if(button_config.edit_folder_btn === false) { print("display:none;") } %>">',
'<span class="fa fa-pencil"></span>',
'</button>',
'<a href="#/folders/<%- content_item.id %>/permissions">',
'<button data-toggle="tooltip" data-placement="top" class="primary-button btn-xs permission_folder_btn" title="Manage \'<%- content_item.get("name") %>\'" style="<% if(button_config.permission_folder_btn === false) { print("display:none;") } %>">',
'<span class="fa fa-group"></span>',
'</button>',
'</a>',
'<% } %>', //end no edit mode
'</td>',
'</tr>'
].join(''));
},
templateRowFile: function(){
tmpl_array = [];
tmpl_array.push('<tr class="dataset_row light library-row" id="<%- content_item.id %>">');
tmpl_array.push('<tr class="dataset_row light library-row" data-id="<%- content_item.id %>">');
tmpl_array.push(' <td>');
tmpl_array.push(' <span title="Dataset" class="fa fa-file-o"></span>');
tmpl_array.push(' </td>');
tmpl_array.push(' <td style="text-align: center; "><input style="margin: 0;" type="checkbox"></td>');
tmpl_array.push(' <td><a href="#folders/<%- content_item.get("folder_id") %>/datasets/<%- content_item.id %>" class="library-dataset"><%- content_item.get("name") %><a></td>'); // dataset
tmpl_array.push(' <td><%- content_item.get("message") %></td>');
tmpl_array.push(' <td><%= _.escape(content_item.get("file_ext")) %></td>'); // data type
tmpl_array.push(' <td><%= _.escape(content_item.get("file_size")) %></td>'); // size
tmpl_array.push(' <td><%= _.escape(content_item.get("update_time")) %></td>'); // time updated
@@ -152,7 +279,7 @@ var FolderRowView = Backbone.View.extend({
tmpl_array.push(' <% if (content_item.get("is_unrestricted")) { %><span data-toggle="tooltip" data-placement="top" title="Unrestricted dataset" style="color:grey;" class="fa fa-globe fa-lg"></span><% } %>');
tmpl_array.push(' <% if (content_item.get("is_private")) { %><span data-toggle="tooltip" data-placement="top" title="Private dataset" style="color:grey;" class="fa fa-key fa-lg"></span><% } %>');
tmpl_array.push(' <% if ((content_item.get("is_unrestricted") === false) && (content_item.get("is_private") === false)) { %><span data-toggle="tooltip" data-placement="top" title="Restricted dataset" style="color:grey;" class="fa fa-shield fa-lg"></span><% } %>');
tmpl_array.push(' <% if (content_item.get("can_manage")) { %><a href="#folders/<%- content_item.get("folder_id") %>/datasets/<%- content_item.id %>/permissions"><button data-toggle="tooltip" data-placement="top" class="primary-button btn-xs permissions-dataset-btn show_on_hover" title="Manage permissions" style="display:none;"><span class="fa fa-group"></span></button></a><% } %>');
tmpl_array.push(' <% if (content_item.get("can_manage")) { %><a href="#folders/<%- content_item.get("folder_id") %>/datasets/<%- content_item.id %>/permissions"><button data-toggle="tooltip" data-placement="top" class="primary-button btn-xs permissions-dataset-btn" title="Manage permissions"><span class="fa fa-group"></span></button></a><% } %>');
tmpl_array.push(' </td>');
tmpl_array.push('</tr>');
@@ -162,16 +289,17 @@ var FolderRowView = Backbone.View.extend({
templateRowDeletedFile: function(){
tmpl_array = [];
tmpl_array.push('<tr class="active deleted_dataset library-row" id="<%- content_item.id %>">');
tmpl_array.push('<tr class="active deleted_dataset library-row" data-id="<%- content_item.id %>">');
tmpl_array.push(' <td>');
tmpl_array.push(' <span title="Dataset" class="fa fa-file-o"></span>');
tmpl_array.push(' </td>');
tmpl_array.push(' <td></td>');
tmpl_array.push(' <td style="color:grey;"><%- content_item.get("name") %></td>'); // dataset
tmpl_array.push(' <td><%- content_item.get("message") %></td>');
tmpl_array.push(' <td><%= _.escape(content_item.get("file_ext")) %></td>'); // data type
tmpl_array.push(' <td><%= _.escape(content_item.get("file_size")) %></td>'); // size
tmpl_array.push(' <td><%= _.escape(content_item.get("update_time")) %></td>'); // time updated
tmpl_array.push(' <td><span data-toggle="tooltip" data-placement="top" title="Marked deleted" style="color:grey;" class="fa fa-ban fa-lg"> </span><button data-toggle="tooltip" data-placement="top" title="Undelete <%- content_item.get("name") %>" class="primary-button btn-xs undelete_dataset_btn show_on_hover" type="button" style="display:none; margin-left:1em;"><span class="fa fa-unlock"> Undelete</span></button></td>');
tmpl_array.push(' <td><span data-toggle="tooltip" data-placement="top" title="Marked deleted" style="color:grey;" class="fa fa-ban fa-lg"> </span><button data-toggle="tooltip" data-placement="top" title="Undelete <%- content_item.get("name") %>" class="primary-button btn-xs undelete_dataset_btn" type="button" style="margin-left:1em;"><span class="fa fa-unlock"> Undelete</span></button></td>');
tmpl_array.push('</tr>');
return _.template(tmpl_array.join(''));
@@ -180,7 +308,7 @@ var FolderRowView = Backbone.View.extend({
templateRowDeletedFolder: function(){
tmpl_array = [];
tmpl_array.push('<tr class="active deleted_folder light library-row" id="<%- content_item.id %>">');
tmpl_array.push('<tr class="active deleted_folder light library-row" data-id="<%- content_item.id %>">');
tmpl_array.push(' <td>');
tmpl_array.push(' <span title="Folder" class="fa fa-folder-o"></span>');
tmpl_array.push(' </td>');
@@ -188,10 +316,11 @@ var FolderRowView = Backbone.View.extend({
tmpl_array.push(' <td style="color:grey;">');
tmpl_array.push(' <%- content_item.get("name") %>');
tmpl_array.push(' </td>');
tmpl_array.push(' <td><%- content_item.get("description") %></td>');
tmpl_array.push(' <td>folder</td>');
tmpl_array.push(' <td></td>');
tmpl_array.push(' <td><%= _.escape(content_item.get("update_time")) %></td>'); // time updated
tmpl_array.push(' <td><span data-toggle="tooltip" data-placement="top" title="Marked deleted" style="color:grey;" class="fa fa-ban fa-lg"> </span><button data-toggle="tooltip" data-placement="top" title="Undelete <%- content_item.get("name") %>" class="primary-button btn-xs undelete_folder_btn show_on_hover" type="button" style="display:none; margin-left:1em;"><span class="fa fa-unlock"> Undelete</span></button></td>');
tmpl_array.push(' <td><span data-toggle="tooltip" data-placement="top" title="Marked deleted" style="color:grey;" class="fa fa-ban fa-lg"> </span><button data-toggle="tooltip" data-placement="top" title="Undelete <%- content_item.get("name") %>" class="primary-button btn-xs undelete_folder_btn" type="button" style="margin-left:1em;"><span class="fa fa-unlock"> Undelete</span></button></td>');
tmpl_array.push('</tr>');
return _.template(tmpl_array.join(''));
@@ -20,7 +20,7 @@ var FolderToolbarView = Backbone.View.extend({
'click #toolbtn_bulk_import' : 'modalBulkImport',
'click #include_deleted_datasets_chk' : 'checkIncludeDeleted',
'click #toolbtn_show_libinfo' : 'showLibInfo',
'click #toolbtn_bulk_delete' : 'deleteSelectedDatasets',
'click #toolbtn_bulk_delete' : 'deleteSelectedItems',
'click #page_size_prompt' : 'showPageSizePrompt'
},
@@ -252,10 +252,10 @@ var FolderToolbarView = Backbone.View.extend({
var dataset_ids = [];
var folder_ids = [];
$('#folder_table').find(':checked').each(function(){
if (this.parentElement.parentElement.id !== '' && this.parentElement.parentElement.classList.contains('dataset_row') ) {
dataset_ids.push(this.parentElement.parentElement.id);
} else if (this.parentElement.parentElement.id !== '' && this.parentElement.parentElement.classList.contains('folder_row') ) {
folder_ids.push(this.parentElement.parentElement.id);
if ($(this.parentElement.parentElement).data('id') !== '' && this.parentElement.parentElement.classList.contains('dataset_row') ) {
dataset_ids.push($(this.parentElement.parentElement).data('id'));
} else if ($(this.parentElement.parentElement).data('id') !== '' && this.parentElement.parentElement.classList.contains('folder_row') ) {
folder_ids.push($(this.parentElement.parentElement).data('id'));
}
});
// prepare the dataset objects to be imported
@@ -306,10 +306,10 @@ var FolderToolbarView = Backbone.View.extend({
var dataset_ids = [];
var folder_ids = [];
$( '#folder_table' ).find( ':checked' ).each( function(){
if ( this.parentElement.parentElement.id !== '' && this.parentElement.parentElement.classList.contains('dataset_row') ) {
dataset_ids.push( this.parentElement.parentElement.id );
} else if ( this.parentElement.parentElement.id !== '' && this.parentElement.parentElement.classList.contains('folder_row') ) {
folder_ids.push( this.parentElement.parentElement.id );
if ( $(this.parentElement.parentElement).data('id') !== '' && this.parentElement.parentElement.classList.contains('dataset_row') ) {
dataset_ids.push( $(this.parentElement.parentElement).data('id') );
} else if ( $(this.parentElement.parentElement).data('id') !== '' && this.parentElement.parentElement.classList.contains('folder_row') ) {
folder_ids.push( $(this.parentElement.parentElement).data('id') );
}
} );
var url = Galaxy.root + 'api/libraries/datasets/download/' + format;
@@ -868,6 +868,8 @@ var FolderToolbarView = Backbone.View.extend({
* @param {array} lddas_set array of lddas to delete
*/
chainCallDeletingItems: function( items_to_delete ){
console.log('chaincall');
console.log(items_to_delete);
var self = this;
this.deleted_items = new mod_library_model.Folder();
var popped_item = items_to_delete.pop();
@@ -898,6 +900,8 @@ var FolderToolbarView = Backbone.View.extend({
console.error('Unknown library item type found.');
console.error(item.type || item.model_class);
}
console.log('updated item')
console.log(updated_item);
Galaxy.libraries.folderListView.collection.add( updated_item );
}
self.chainCallDeletingItems( items_to_delete );
@@ -921,9 +925,9 @@ var FolderToolbarView = Backbone.View.extend({
},
/**
* Deletes the selected datasets. Atomic. One by one.
* Delete the selected items. Atomic. One by one.
*/
deleteSelectedDatasets: function(){
deleteSelectedItems: function(){
var checkedValues = $('#folder_table').find(':checked');
if(checkedValues.length === 0){
mod_toastr.info('You must select at least one dataset for deletion.');
@@ -945,11 +949,11 @@ var FolderToolbarView = Backbone.View.extend({
var dataset_ids = [];
var folder_ids = [];
checkedValues.each(function(){
if (this.parentElement.parentElement.id !== '') {
if (this.parentElement.parentElement.id.substring(0,1) == 'F'){
folder_ids.push(this.parentElement.parentElement.id);
if ($(this.parentElement.parentElement).data('id') !== '') {
if ($(this.parentElement.parentElement).data('id').substring(0,1) == 'F'){
folder_ids.push($(this.parentElement.parentElement).data('id'));
} else {
dataset_ids.push(this.parentElement.parentElement.id);
dataset_ids.push($(this.parentElement.parentElement).data('id'));
}
}
});
@@ -968,6 +972,7 @@ var FolderToolbarView = Backbone.View.extend({
var folder = new mod_library_model.FolderAsModel({id:folder_ids[i]});
items_to_delete.push(folder);
}
console.log(items_to_delete);
this.options.chain_call_control.total_number = items_total.length;
// call the recursive function to call ajax one after each other (request FIFO queue)
@@ -1104,7 +1109,7 @@ var FolderToolbarView = Backbone.View.extend({
tmpl_array.push(' <li><a href="#/folders/<%= id %>/download/zip">.zip</a></li>');
tmpl_array.push(' </ul>');
tmpl_array.push(' </div>');
tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Mark selected datasets deleted" id="toolbtn_bulk_delete" class="primary-button logged-dataset-manipulation" style="margin-left: 0.5em; display:none; " type="button"><span class="fa fa-times"></span> Delete</button>');
tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Mark selected items deleted" id="toolbtn_bulk_delete" class="primary-button logged-dataset-manipulation" style="margin-left: 0.5em; display:none; " type="button"><span class="fa fa-times"></span> Delete</button>');
tmpl_array.push(' <button data-id="<%- id %>" data-toggle="tooltip" data-placement="top" title="Show library information" id="toolbtn_show_libinfo" class="primary-button" style="margin-left: 0.5em;" type="button"><span class="fa fa-info-circle"></span> Library Info</button>');
tmpl_array.push(' <span class="help-button" data-toggle="tooltip" data-placement="top" title="Visit Libraries Wiki"><a href="https://wiki.galaxyproject.org/DataLibraries/screen/FolderContents" target="_blank"><button class="primary-button" type="button"><span class="fa fa-question-circle"></span> Help</button></a></span>');
tmpl_array.push(' </div>');
@@ -53,7 +53,7 @@ var LibraryRowView = Backbone.View.extend({
var old_element = this.$el;
/* if user canceled the library param is undefined,
if user saved and succeeded the updated library is rendered */
this.render(library);
this.render();
old_element.replaceWith(this.$el);
/* now we attach new tooltips to the newly created row element */
this.$el.find("[data-toggle]").tooltip();
@@ -223,55 +223,50 @@ var LibraryRowView = Backbone.View.extend({
},
templateRow: function() {
tmpl_array = [];
tmpl_array.push(' <tr class="<% if(library.get("deleted") === true) { print("active") } %>" style="display:none;" data-id="<%- library.get("id") %>">');
tmpl_array.push(' <% if(!edit_mode) { %>');
tmpl_array.push(' <% if(library.get("deleted")) { %>');
tmpl_array.push(' <td style="color:grey;"><span data-toggle="tooltip" data-placement="top" title="Marked deleted" style="color:grey;" class="fa fa-ban fa-lg deleted_lib_ico"> </span> <%- library.get("name") %></td>');
tmpl_array.push(' <% } else { %>');
tmpl_array.push(' <td><a href="#folders/<%- library.get("root_folder_id") %>"><%- library.get("name") %></a></td>');
tmpl_array.push(' <% } %>');
tmpl_array.push(' <% if(library.get("description")) { %>');
tmpl_array.push(' <% if( (library.get("description")).length> 80 ) { %>');
tmpl_array.push(' <td data-toggle="tooltip" data-placement="bottom" title="<%= _.escape(library.get("description")) %>"><%= _.escape(library.get("description")).substring(0, 80) + "..." %></td>');
tmpl_array.push(' <% } else { %>');
tmpl_array.push(' <td><%= _.escape(library.get("description"))%></td>');
tmpl_array.push(' <% } %>');
tmpl_array.push(' <% } else { %>');
tmpl_array.push(' <td></td>');
tmpl_array.push(' <% } %>');
tmpl_array.push(' <% if(library.get("synopsis")) { %>');
tmpl_array.push(' <% if( (library.get("synopsis")).length> 120 ) { %>');
tmpl_array.push(' <td data-toggle="tooltip" data-placement="bottom" title="<%= _.escape(library.get("synopsis")) %>"><%= _.escape(library.get("synopsis")).substring(0, 120) + "..." %></td>');
tmpl_array.push(' <% } else { %>');
tmpl_array.push(' <td><%= _.escape(library.get("synopsis"))%></td>');
tmpl_array.push(' <% } %>');
tmpl_array.push(' <% } else { %>');
tmpl_array.push(' <td></td>');
tmpl_array.push(' <% } %>');
tmpl_array.push(' <% } else if(edit_mode){ %>');
tmpl_array.push(' <td><textarea rows="4" class="form-control input_library_name" placeholder="name" ><%- library.get("name") %></textarea></td>');
tmpl_array.push(' <td><textarea rows="4" class="form-control input_library_description" placeholder="description" ><%- library.get("description") %></textarea></td>');
tmpl_array.push(' <td><textarea rows="4" class="form-control input_library_synopsis" placeholder="synopsis" ><%- library.get("synopsis") %></textarea></td>');
tmpl_array.push(' <% } %>');
tmpl_array.push(' <td class="right-center">');
tmpl_array.push(' <% if( (library.get("public")) && (library.get("deleted") === false) ) { %>');
tmpl_array.push(' <span data-toggle="tooltip" data-placement="top" title="Unrestricted library" style="color:grey;" class="fa fa-globe fa-lg public_lib_ico"> </span>');
tmpl_array.push(' <% }%>');
tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Modify <%- library.get("name") %>" class="primary-button btn-xs edit_library_btn" type="button" style="<% if(button_config.edit_library_btn === false) { print("display:none;") } %>"><span class="fa fa-pencil"></span></button>');
tmpl_array.push(' <a href="#library/<%- library.get("id") %>/permissions"> <button data-toggle="tooltip" data-placement="top" title="Modify permissions" class="primary-button btn-xs permission_library_btn" type="button" style="<% if(button_config.permission_library_btn === false) { print("display:none;") } %>"><span class="fa fa-group"></span></button></a>');
tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Save changes" class="primary-button btn-xs save_library_btn" type="button" style="<% if(button_config.save_library_btn === false) { print("display:none;") } %>"><span class="fa fa-floppy-o"> Save</span></button>');
tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Discard changes" class="primary-button btn-xs cancel_library_btn" type="button" style="<% if(button_config.cancel_library_btn === false) { print("display:none;") } %>"><span class="fa fa-times"> Cancel</span></button>');
tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Delete <%- library.get("name") %>" class="primary-button btn-xs delete_library_btn" type="button" style="<% if(button_config.delete_library_btn === false) { print("display:none;") } %>"><span class="fa fa-trash-o"> Delete</span></button>');
tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Undelete <%- library.get("name") %> " class="primary-button btn-xs undelete_library_btn" type="button" style="<% if(button_config.undelete_library_btn === false) { print("display:none;") } %>"><span class="fa fa-unlock"> Undelete</span></button>');
tmpl_array.push(' </td>');
tmpl_array.push(' </tr>');
return _.template(tmpl_array.join(''));
return _.template([
'<tr class="<% if(library.get("deleted") === true) { print("active") } %>" style="display:none;" data-id="<%- library.get("id") %>">',
'<% if(!edit_mode) { %>',
'<% if(library.get("deleted")) { %>',
'<td style="color:grey;"><span data-toggle="tooltip" data-placement="top" title="Marked deleted" style="color:grey;" class="fa fa-ban fa-lg deleted_lib_ico"> </span> <%- library.get("name") %></td>',
'<% } else { %>',
'<td><a href="#folders/<%- library.get("root_folder_id") %>"><%- library.get("name") %></a></td>',
'<% } %>',
'<% if(library.get("description")) { %>',
'<% if( (library.get("description")).length> 80 ) { %>',
'<td data-toggle="tooltip" data-placement="bottom" title="<%= _.escape(library.get("description")) %>"><%= _.escape(library.get("description")).substring(0, 80) + "..." %></td>',
'<% } else { %>',
'<td><%= _.escape(library.get("description"))%></td>',
'<% } %>',
'<% } else { %>',
'<td></td>',
'<% } %>',
'<% if(library.get("synopsis")) { %>',
'<% if( (library.get("synopsis")).length> 120 ) { %>',
'<td data-toggle="tooltip" data-placement="bottom" title="<%= _.escape(library.get("synopsis")) %>"><%= _.escape(library.get("synopsis")).substring(0, 120) + "..." %></td>',
'<% } else { %>',
'<td><%= _.escape(library.get("synopsis"))%></td>',
'<% } %>',
'<% } else { %>',
'<td></td>',
'<% } %>',
'<% } else if(edit_mode){ %>',
'<td><textarea rows="4" class="form-control input_library_name" placeholder="name" ><%- library.get("name") %></textarea></td>',
'<td><textarea rows="4" class="form-control input_library_description" placeholder="description" ><%- library.get("description") %></textarea></td>',
'<td><textarea rows="4" class="form-control input_library_synopsis" placeholder="synopsis" ><%- library.get("synopsis") %></textarea></td>',
'<% } %>',
'<td class="right-center">',
'<% if( (library.get("public")) && (library.get("deleted") === false) ) { %>',
'<span data-toggle="tooltip" data-placement="top" title="Unrestricted library" style="color:grey;" class="fa fa-globe fa-lg public_lib_ico"> </span>',
'<% }%>',
'<button data-toggle="tooltip" data-placement="top" title="Modify \'<%- library.get("name") %>\'" class="primary-button btn-xs edit_library_btn" type="button" style="<% if(button_config.edit_library_btn === false) { print("display:none;") } %>"><span class="fa fa-pencil"></span></button>',
'<a href="#library/<%- library.get("id") %>/permissions"><button data-toggle="tooltip" data-placement="top" title="Manage \'<%- library.get("name") %>\'" class="primary-button btn-xs permission_library_btn" type="button" style="<% if(button_config.permission_library_btn === false) { print("display:none;") } %>"><span class="fa fa-group"></span></button></a>',
'<button data-toggle="tooltip" data-placement="top" title="Save changes" class="primary-button btn-xs save_library_btn" type="button" style="<% if(button_config.save_library_btn === false) { print("display:none;") } %>"><span class="fa fa-floppy-o"> Save</span></button>',
'<button data-toggle="tooltip" data-placement="top" title="Discard changes" class="primary-button btn-xs cancel_library_btn" type="button" style="<% if(button_config.cancel_library_btn === false) { print("display:none;") } %>"><span class="fa fa-times"> Cancel</span></button>',
'<button data-toggle="tooltip" data-placement="top" title="Delete <%- library.get("name") %>" class="primary-button btn-xs delete_library_btn" type="button" style="<% if(button_config.delete_library_btn === false) { print("display:none;") } %>"><span class="fa fa-trash-o"> Delete</span></button>',
'<button data-toggle="tooltip" data-placement="top" title="Undelete <%- library.get("name") %> " class="primary-button btn-xs undelete_library_btn" type="button" style="<% if(button_config.undelete_library_btn === false) { print("display:none;") } %>"><span class="fa fa-unlock"> Undelete</span></button>',
'</td>',
'</tr>'
].join(''));
}
});
+14 -23
View File
@@ -10,13 +10,15 @@
define(['libs/bootstrap-tour'],function(BootstrapTour) {
var gxy_root = typeof Galaxy === "undefined" ? '/' : Galaxy.root;
var tour_opts = { storage: window.sessionStorage,
onEnd: function(){
sessionStorage.removeItem('activeGalaxyTour');
},
delay: 150, // Attempts to make it look natural
orphan:true
}
};
var hooked_tour_from_data = function(data){
_.each(data.steps, function(step) {
@@ -41,20 +43,12 @@ define(['libs/bootstrap-tour'],function(BootstrapTour) {
// elements which have additional logic, like the
// upload input box
step.onShown= function(){
$(step.element).val(step.textinsert).trigger("change")
$(step.element).val(step.textinsert).trigger("change");
};
}
});
return data;
}
// DBTODO: there's probably a better way to do this for pages which don't
// have Galaxy objects.
if (typeof Galaxy != "undefined") {
var gxy_root = Galaxy.root;
}else{
var gxy_root = '/';
}
};
var TourItem = Backbone.Model.extend({
urlRoot: gxy_root + 'api/tours',
@@ -70,8 +64,7 @@ define(['libs/bootstrap-tour'],function(BootstrapTour) {
var url = gxy_root + 'api/tours/' + tour_id;
$.getJSON( url, function( data ) {
// Set hooks for additional click and data entry actions.
tourdata = hooked_tour_from_data(data);
console.log(tourdata);
var tourdata = hooked_tour_from_data(data);
sessionStorage.setItem('activeGalaxyTour', JSON.stringify(data));
// Store tour steps in sessionStorage to easily persist w/o hackery.
var tour = new Tour(_.extend({
@@ -82,19 +75,18 @@ define(['libs/bootstrap-tour'],function(BootstrapTour) {
tour.goTo(0);
tour.restart();
});
}
};
var ToursView = Backbone.View.extend({
// initialize
initialize: function(options) {
initialize: function() {
var self = this;
this.setElement('<div/>');
this.model = new Tours()
this.model = new Tours();
this.model.fetch({
success: function( model ){
success: function(){
self.render();
},
error: function( model, response ){
error: function(){
// Do something.
console.error("Failed to fetch tours.");
}
@@ -102,7 +94,6 @@ define(['libs/bootstrap-tour'],function(BootstrapTour) {
},
render: function(){
var self = this;
var tpl = _.template([
"<h2>Galaxy Tours</h2>",
"<p>This page presents a list of interactive tours available on this Galaxy server. ",
@@ -110,14 +101,14 @@ define(['libs/bootstrap-tour'],function(BootstrapTour) {
"<ul>",
'<% _.each(tours, function(tour) { %>',
'<li>',
'<a href="#" class="tourItem" data-tour.id=<%- tour.id %>>',
'<a href="#/tours/<%- tour.id %>" class="tourItem" data-tour.id=<%- tour.id %>>',
'<%- tour.attributes.name || tour.id %>',
'</a>',
' - <%- tour.attributes.description || "No description given." %>',
'</li>',
'<% }); %>',
"</ul>"].join(''));
this.$el.html(tpl({tours: this.model.models})).on("click", ".tourItem", function(e){
this.$el.html(tpl({tours: this.model.models})).on("click", ".tourItem", function(){
giveTour($(this).data("tour.id"));
});
}
@@ -126,5 +117,5 @@ define(['libs/bootstrap-tour'],function(BootstrapTour) {
return {ToursView: ToursView,
hooked_tour_from_data: hooked_tour_from_data,
tour_opts: tour_opts,
giveTour: giveTour}
giveTour: giveTour};
});
@@ -20,6 +20,7 @@ var View = Backbone.View.extend({
initialize: function(options) {
// link this
var self = this;
this.model = new Backbone.Model();
// configure options
this.options = Utils.merge(options, this.optionsDefault);
@@ -186,6 +187,13 @@ var View = Backbone.View.extend({
/** Update all available options at once
*/
add: function( options, sorter ) {
_.each( this.model.get( 'options' ), function( v ) {
!_.findWhere( options, v ) && options.push( v );
});
sorter && options.sort( sorter );
this.update( options );
},
update: function(options) {
// backup current value
var current = this._getValue();
@@ -199,6 +207,7 @@ var View = Backbone.View.extend({
}
// add new options
this.model.set( 'options', options );
for (var key in options) {
this.$select.append(this._templateOption(options[key]));
}
@@ -61,7 +61,6 @@ return Backbone.View.extend({
css: 'upload-genome',
onchange : function(genome) {
self.model.set('genome', genome);
self.app.updateGenome(genome, true);
},
data: self.app.list_genomes,
container: this.$('#genome'),
@@ -79,7 +78,6 @@ return Backbone.View.extend({
css: 'upload-extension',
onchange : function(extension) {
self.model.set('extension', extension);
self.app.updateExtension(extension, true);
},
data: self.app.list_extensions,
container: this.$('#extension'),
@@ -21,7 +21,7 @@ var Visualization = Backbone.Model.extend(
/** override urlRoot to handle prefix */
urlRoot : function(){
var apiUrl = '/api/visualizations';
var apiUrl = 'api/visualizations';
return Galaxy.root + apiUrl;
},
@@ -361,12 +361,16 @@ EditorFormView = Backbone.View.extend({
self.canvas_manager.draw_overview();
// Determine if any parameters were 'upgraded' and provide message
upgrade_message = "";
$.each( data.upgrade_messages, function( k, v ) {
upgrade_message += ( "<li>Step " + ( parseInt(k, 10) + 1 ) + ": " + self.workflow.nodes[k].name + "<ul>");
$.each( v, function( i, vv ) {
upgrade_message += "<li>" + vv +"</li>";
$.each( data.upgrade_messages, function( step_id, messages ) {
var details = "";
Utils.deepeach( [ messages ], function( d ) {
$.each( d, function( i, v ) {
details += typeof v === "string" ? "<li>" + v + "</li>" : "";
});
});
upgrade_message += "</ul></li>";
if ( details ) {
upgrade_message += "<li>Step " + ( parseInt( step_id, 10 ) + 1 ) + ": " + self.workflow.nodes[ step_id ].name + "<ul>" + details + "</ul></li>";
}
});
if ( upgrade_message ) {
window.show_modal( "Workflow loaded with changes",
+10 -33
View File
@@ -20,6 +20,7 @@ window.make_popupmenu = POPUPMENU.make_popupmenu;
window.make_popup_menus = POPUPMENU.make_popup_menus;
window.init_tag_click_function = require( 'ui/autocom_tagging' );
var TOURS = require( 'mvc/tours' );
var QUERY_STRING = require( 'utils/query-string-parsing' );
// console.debug( 'galaxy globals loaded' );
// ============================================================================
@@ -165,39 +166,15 @@ $(document).ready( function() {
return anchor;
});
try{
// So, depending on what elements your tour is hooked to, this may not
// work on some pages with some rendered content because of view
// rendering delays.
// Another option is to present an icon for 'continue-tour' somewhere?
urlparms = _.object(_.compact(_.map(location.search.slice(1).split('&'), function(item) { if (item) return item.split('='); })));
if (urlparms.tour_id){
var tour_id = urlparms.tour_id;
delete urlparms.tour_id;
var url = $(location).attr('href');
var repacked_url_args = _.map(Object.getOwnPropertyNames(urlparms), function(k) { return "?" + [k, urlparms[k]].join('=') }).join('&');
url = window.location.href.split('?')[0];
if (repacked_url_args !== "?"){
url = url + repacked_url_args;
}
history.pushState(null, null, url);
TOURS.giveTour(tour_id);
var et = JSON.parse(sessionStorage.getItem('activeGalaxyTour'));
if (et){
et = TOURS.hooked_tour_from_data(et);
if (et && et.steps){
var tour = new Tour(_.extend({
steps: et.steps,
}, TOURS.tour_opts));
tour.init();
tour.restart();
}
else{
et = JSON.parse(sessionStorage.getItem('activeGalaxyTour'));
if (et){
et = TOURS.hooked_tour_from_data(et);
if (et && et.steps){
var tour = new Tour(_.extend({
steps: et.steps,
}, TOURS.tour_opts));
tour.init();
tour.restart();
}
}
}
}
catch(ex){
console.log("Tour loading failure, you'll need to restart the tour manually." + ex);
}
});
+4 -2
View File
@@ -573,10 +573,12 @@ div.toolHelpBody {
.toolForm.toolFormInCanvas {
border: solid @form-border 1px;
.border-radius(2px);
background: @white;
margin: 0px;
&.toolForm-active {
border: solid @brand-primary 3px;
margin: 4px;
box-shadow: 0 0 0 3px @brand-primary;
.border-radius(1px);
}
.toolFormTitle {
font-size: @font-size-base;
+12 -6
View File
@@ -30,7 +30,7 @@ li.datasetRow:hover
}
td.right-center {
vertical-align: middle !important;
vertical-align: middle !important;
text-align: right;
}
@@ -44,7 +44,7 @@ td.right-center {
.library_table {
td {
border-top:1px solid #5f6990 !important;
}
}
th {
border-bottom: 2px solid #5f6990 !important;
}
@@ -56,10 +56,10 @@ td.right-center {
}
}
.library_style_container {
width: 95%;
margin: auto;
margin-top:2em;
overflow: auto !important;
width: 95%;
margin: auto;
margin-top:2em;
overflow: auto !important;
tr {
height: 32px;
}
@@ -128,6 +128,12 @@ th.button_heading{
}
}
#libraries_element, #folder_items_element{
button{
margin-left: 0.5em;
}
}
img.expanderIcon {
padding-right: 4px;
}
+1 -1
View File
@@ -1,4 +1,4 @@
.popover-title{
.tour-tour > .popover-title{
background-color: @base-color-1;
color: @white;
}
+10 -1
View File
@@ -714,6 +714,15 @@ use_interactive = True
# lot of CPU.
#use_heartbeat = False
# Control the period (in seconds) between dumps. Use -1 to disable. Regardless
# of this setting, if use_heartbeat is enabled, you can send a Galaxy process
# (unless running with uWSGI) SIGUSR1 (`kill -USR1`) to force a dump.
#heartbeat_interval = 20
# Heartbeat log filename. Can accept the template variables {server_name} and
# {pid}
#heartbeat_log = heartbeat_{server_name}.log
# Log to Sentry
# Sentry is an open source logging and error aggregation platform. Setting
# sentry_dsn will enable the Sentry middleware and errors will be sent to the
@@ -771,7 +780,7 @@ use_interactive = True
# Search data libraries with lucene
#enable_lucene_library_search = False
# maxiumum file size to index for searching, in MB
# maximum file size to index for searching, in MB
#fulltext_max_size = 500
#fulltext_noindex_filetypes = bam,sam,wig,bigwig,fasta,fastq,fastqsolexa,fastqillumina,fastqsanger
# base URL of server providing search functionality using lucene
@@ -11,7 +11,7 @@ module.exports = function(grunt) {
},
shim : {
"libs/underscore": { exports: "_" },
"libs/backbone/backbone": { exports: "Backbone" }
"libs/backbone": { exports: "Backbone" }
},
name : "plugin/app",
out : "static/build-app.js",
@@ -15,7 +15,7 @@
'libs/jquery/select2',
'libs/bootstrap',
'libs/underscore',
'libs/backbone/backbone',
'libs/backbone',
'libs/d3',
'libs/require')}
@@ -39,7 +39,7 @@
## load merged/minified code
${h.javascript_link( app_root + "build-app.js" )}
## install default css
${h.stylesheet_link( app_root + "app.css" )}
</head>
@@ -79,7 +79,7 @@
},
shim: {
"libs/underscore": { exports: "_" },
"libs/backbone/backbone": { exports: "Backbone" },
"libs/backbone": { exports: "Backbone" },
"d3": { exports: "d3"}
}
@@ -89,7 +89,7 @@
};
// application
var app = null;
$(function() {
$(function() {
// request application script
require(['plugin/app'], function(App) {
// load options
@@ -97,10 +97,10 @@
id : ${h.dumps( visualization_id )} || undefined,
config : ${h.dumps( config )}
}
// create application
app = new App(options);
// add to body
$('body').append(app.$el);
});
@@ -23,12 +23,16 @@ ${h.css( 'base', 'jquery-ui/smoothness/jquery-ui')}
${h.stylesheet_link( root + 'plugins/visualizations/scatterplot/static/scatterplot.css' )}
## ----------------------------------------------------------------------------
<script type="text/javascript">
// TODO: blah
window.Galaxy = { root: '${ root }' };
</script>
${h.js( 'libs/jquery/jquery',
'libs/jquery/jquery.migrate',
'libs/jquery/jquery-ui',
'libs/bootstrap',
'libs/underscore',
'libs/backbone/backbone',
'libs/backbone',
'libs/d3',
'ui/peek-column-selector',
'ui/pagination',
@@ -40,7 +44,7 @@ ${h.javascript_link( root + 'plugins/visualizations/scatterplot/static/scatterpl
function getModel(){
return new ScatterplotModel({
id : ${h.dumps( visualization_id )} || undefined,
title : "${title}",
title : "${title or default_title}",
config : ${h.dumps( config, indent=2 )}
});
}
@@ -87,7 +91,7 @@ function getHDAJSON(){
hdaJSON = getHDAJSON(),
editor = new ScatterplotConfigEditor({
el : $( '.scatterplot-editor' ).attr( 'id', 'scatterplot-editor-hda-' + hdaJSON.id ),
model : getModel(),
model : model,
dataset : hdaJSON
}).render();
window.editor = editor;
+614
View File
@@ -0,0 +1,614 @@
.. _framework-dependencies:
Galaxy Framework Dependencies
=============================
Galaxy is a large Python application with a long list of `Python module
dependencies`_. As a result, the Galaxy developers have made significant effort
to provide these dependencies in as simple a method as possible. Prior to the
16.01 release, this was done by distributing dependencies in Python's old
standard packaging format (Egg) in a non-standard way. As of the 16.01 release,
Galaxy now distributes dependencies in Python's new standard packaging format
(Wheel), albeit still in a non-standard way. Thankfully, the new distribution
method is far more compatible with the standard package distribution tooling
(i.e. `pip`_) than the old method.
.. _Python module dependencies: https://github.com/galaxyproject/galaxy/blob/dev/lib/galaxy/dependencies/requirements.txt
.. _pip: https://pip.pypa.io/
.. _wheel: https://wheel.readthedocs.org/
How it works
------------
Upon startup (with ``run.sh``), the startup scripts will:
1. Create a Python `virtualenv`_ in the directory ``.venv``.
2. Unset the ``$PYTHONPATH`` environment variable (if set) as this can
interfere with installing `Galaxy pip`_ and dependencies.
3. Replace that virtualenv's pip with `Galaxy pip`_.
4. Download and install wheels from the Galaxy project wheel server,
`wheels.galaxyproject.org`_, using pip.
5. Start Galaxy using ``.venv/bin/python``.
.. _virtualenv: https://virtualenv.readthedocs.org/
.. _wheels.galaxyproject.org: https://wheels.galaxyproject.org/
Options
-------
A variety of options to ``run.sh`` are available to control the above behavior:
- ``--skip-venv``: Do not create or use a virtualenv, and do not replace pip
with Galaxy pip.
- ``--skip-wheels``: Do not install wheels.
- ``--no-create-venv``: Do not create a virtualenv, but use one if it exists at
``.venv`` or if ``$VIRTUAL_ENV`` is set (this variable is set by virtualenv's
``activate``)
- ``--replace-pip/--no-replace-pip``: Do/do not replace pip with Galaxy pip.
Managing dependencies manually
------------------------------
Create a virtualenv
^^^^^^^^^^^^^^^^^^^
Using a `virtualenv`_ in ``.venv`` under the Galaxy source tree is not
required. More complicated Galaxy setups may choose to use a virtualenv
external to the Galaxy source tree, which can be done either by not using
``run.sh`` directly (an example of this can be found under the `Supervisor`_
section) or using the ``--no-create-venv`` option, explained in the `Options`_
section. It is also possible to force Galaxy to start without a virtualenv at
all, but you should not do this unless you know what you're doing.
To manually create a virtualenv, you will first need to obtain virtualenv.
There are a variety of ways to do this:
- ``pip install virtualenv``
- ``brew install virtualenv``
- Install your Linux distribution's virtualenv package from the system package
manager (e.g. ``apt-get install python-virtualenv``).
- Download the `virtualenv source from PyPI
<https://pypi.python.org/pypi/virtualenv>`_, untar, and run the
``virtualenv.py`` script contained within as ``python virtualenv.py
/path/to/galaxy/virtualenv``
Once this is done, create a virtualenv. In our example, the virtualenv will
live in ``/srv/galaxy/venv`` and the Galaxy source code has been cloned to
``/srv/galaxy/server``.
.. code-block:: console
$ virtualenv /srv/galaxy/venv
New python executable in /srv/galaxy/venv/bin/python
Installing setuptools, pip, wheel...done.
$ . /srv/galaxy/venv/bin/activate
(venv)$
Install dependencies
^^^^^^^^^^^^^^^^^^^^
Normally, ``run.sh`` calls `common_startup.sh`_, which creates the virtualenv,
installs Galaxy pip, and installs dependencies. You can call this script
yourself to set up Galaxy pip and the dependencies without creating a
virtualenv using the ``--no-create-venv`` option:
.. code-block:: console
(venv)$ PYTHONPATH= sh /srv/galaxy/server/scripts/common_startup.sh --no-create-venv
Ignoring indexes: https://pypi.python.org/simple
Collecting pip
Downloading https://wheels.galaxyproject.org/packages/pip-8.0.0+gx1-py2.py3-none-any.whl (1.2MB)
100% |████████████████████████████████| 1.2MB 37.8MB/s
Installing collected packages: pip
Found existing installation: pip 7.1.2
Uninstalling pip-7.1.2:
Successfully uninstalled pip-7.1.2
Successfully installed pip-8.0.0+gx1
Collecting bx-python==0.7.3 (from -r requirements.txt (line 2))
Downloading https://wheels.galaxyproject.org/packages/bx_python-0.7.3-cp27-cp27mu-linux_x86_64.whl (1.7MB)
100% |████████████████████████████████| 1.7MB 25.4MB/s
...
Collecting pysam==0.8.3+gx1 (from -r requirements.txt (line 69))
Downloading https://wheels.galaxyproject.org/packages/pysam-0.8.3+gx1-cp27-cp27mu-linux_x86_64.whl (7.4MB)
100% |████████████████████████████████| 7.4MB 15.1MB/s
Installing collected packages: bx-python, MarkupSafe, PyYAML, SQLAlchemy,
mercurial, numpy, pycrypto, six, Paste, PasteDeploy, docutils, wchartype,
repoze.lru, Routes, WebOb, WebHelpers, Mako, pytz, Babel, Beaker,
Markdown, Cheetah, requests, requests-toolbelt, boto, bioblend, amqp,
anyjson, kombu, pbr, sqlparse, decorator, Tempita, sqlalchemy-migrate,
Parsley, nose, SVGFig, ecdsa, paramiko, Fabric, Whoosh, pysam
Successfully installed Babel-2.0 Beaker-1.7.0 Cheetah-2.4.4 Fabric-1.10.2
Mako-1.0.2 Markdown-2.6.3 MarkupSafe-0.23 Parsley-1.3 Paste-2.0.2
PasteDeploy-1.5.2 PyYAML-3.11 Routes-2.2 SQLAlchemy-1.0.8 SVGFig-1.1.6
Tempita-0.5.3.dev0 WebHelpers-1.3 WebOb-1.4.1 Whoosh-2.4.1+gx1 amqp-1.4.8
anyjson-0.3.3 bioblend-0.6.1 boto-2.38.0 bx-python-0.7.3 decorator-4.0.2
docutils-0.12 ecdsa-0.13 kombu-3.0.30 mercurial-3.4.2 nose-1.3.7
numpy-1.9.2 paramiko-1.15.2 pbr-1.8.0 pycrypto-2.6.1 pysam-0.8.3+gx1
pytz-2015.4 repoze.lru-0.6 requests-2.8.1 requests-toolbelt-0.4.0
six-1.9.0 sqlalchemy-migrate-0.10.0 sqlparse-0.1.16 wchartype-0.1
**Warning:** If your ``$PYTHONPATH`` is set, it may interfere with the
dependency installation process (this will almost certainly be the case if you
use `virtualenv-burrito`_). Without ``--no-create-venv`` the ``$PYTHONPATH``
variable will be automatically unset, but we assume you know what you're doing
and may want it left intact if you are using ``--no-create-venv``. If you
encounter problems, try unsetting ``$PYTHONPATH`` as shown in the example
above.
.. _common_startup.sh: https://github.com/galaxyproject/galaxy/blob/dev/scripts/common_startup.sh
.. _virtualenv-burrito: https://github.com/brainsik/virtualenv-burrito
Installing unpinned dependencies
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Galaxy's dependencies can be installed either "pinned" (they will be installed
at exact versions specified for your Galaxy release) or "unpinned" (the latest
versions of all dependencies will be installed unless there are known
incompatibilities with new versions). By default, the release branch(es) of
Galaxy use pinned versions for three reasons:
1. Using pinned versions insures that the prebuilt wheels on
`wheels.galaxyproject.org`_ will be installed, and no compilation will be
necesseary.
2. Galaxy releases are tested with the pinned versions and this allows us to
give as much assurance as possible that the pinned versions will work with
the given Galaxy release (especially as time progresses and newer dependency
versions are released while the Galaxy release receives fewer updates.
3. Pinning furthers Galaxy's goal of reproducibility as differing dependency
versions could result in non-reproducible behavior.
Install dependencies using the `unpinned requirements file`_, and then instruct
Galaxy to start without attempting to fetch wheels:
.. code-block:: console
(venv)$ pip install --index-url=https://wheels.galaxyproject.org/simple/ -r lib/galaxy/dependencies/requirements.txt
(venv)$ deactivate
$ sh run.sh --no-create-venv --skip-wheels
Including ``--index-url=https://wheels.galaxyproject.org/simple/`` is important
- at least one current Galaxy dependency (SVGFig) is not available in PyPI but
is available (in both source and wheel form) on `wheels.galaxyproject.org`_,
and two (pysam, Whoosh) include modifications specific to Galaxy which are only
available on `wheels.galaxyproject.org`_.
.. _unpinned requirements file: https://github.com/galaxyproject/galaxy/blob/dev/lib/galaxy/dependencies/requirements.txt
Wheel interaction with other software
-------------------------------------
Galaxy job handlers
^^^^^^^^^^^^^^^^^^^
All Galaxy jobs run a metadata detection step on the job outputs upon
completion of the tool. The metadata detection step requires many of Galaxy's
dependencies. Because of this, it's necessary to make sure the metadata
detection step runs in Galaxy's virtualenv. If you run a relatively simple
Galaxy setup (e.g. single process, or multiple Python Paste processes started
using ``run.sh``) then this is assured for you automatically. In more
complicated setups (using a cluster, supervisor, and/or the "headless" Galaxy
handler) it may be necessary to make sure the handlers know where the
virtualenv (or a virtualenv containing Galaxy's dependencies) can be found.
If your jobs are failing due to Python ``ImportError`` exceptions, this is most
likely the problem. If your jobs run on a cluster, you can use the ``<env>``
tag in ``job_conf.xml`` to source the virtualenv. For example:
.. code-block:: xml
<job_conf>
<plugins>
...
</plugins>
<destinations default="cluster">
<destination id="cluster" runner="drmaa">
<param id="nativeSpecification"> ...cluster options... </param>
<env file="/galaxy/server/.venv/bin/activate" />
</destination>
</destinations>
</job_conf>
If your Galaxy server's virtualenv isn't available on the cluster you can
create one manually using the instructions under `Managing dependencies
manually`_.
Pulsar
^^^^^^
If using `Pulsar`_'s option to set metadata on the remote server, the same
conditions as with `Galaxy job handlers`_ apply. You should create a virtualenv
on the remote resource, install Galaxy's dependencies in to it, and set an
``<env>`` tag pointing to the virtualenv's ``activate`` as in the `Galaxy job
handlers`_ section. Instructions on how to create a virtualenv can be found
under the `Managing dependencies manually`_ section.
.. _Pulsar: http://pulsar.readthedocs.org/
Conda
^^^^^
`Conda`_ and `virtualenv`_ are incompatible. However, Conda provides its own
environment separation functionality in the form of `Conda environments`_.
Starting Galaxy with Conda Python will cause ``--skip-venv`` to be implicitly
set, and the currently active Conda environment will be used to install Galaxy
framework dependencies instaead. Be sure to create and activate a Conda
environment for Galaxy prior to installing packages and/or starting Galaxy.
You may choose to install Galaxy's dependencies either at their `pinned`_
versions using pip or `unpinned`_ using a combination of conda and pip. When
running under Conda, pip is not replaced with Galaxy pip, so installing pinned
dependencies will require compilation, will be slower and requires having those
dependencies' build-time dependencies installed, but has benefits as explained
under the `Installing unpinned dependencies`_ section. Installing unpinned
dependencies allows you to use Conda's binary packages for quick and easy
installation.
Pinned dependencies will be installed by default when running ``run.sh``. To
install unpinned dependencies, the process is similar as to installing unpinned
versions without Conda, with the extra step of installing as much as possible
from Conda/Bioconda before installing from pip. Begin by adding the `Bioconda`_
channel as explained in the `Bioconda instructions`_ and then creating a new
Conda environment using the provided Conda environment file. Then, install
remaining dependencies using pip and start Galaxy, instructing it to skip the
automatic fetching of pinned dependencies.
.. code-block:: console
$ conda config --add channels r
$ conda config --add channels bioconda
$ conda create --name galaxy --file lib/galaxy/dependencies/conda-environment.txt
Fetching package metadata: ........
Solving package specifications: ............................................
Package plan for installation in environment /home/nate/conda/envs/galaxy:
The following packages will be downloaded:
package | build
---------------------------|-----------------
boto-2.38.0 | py27_0 1.3 MB
cheetah-2.4.4 | py27_0 267 KB
decorator-4.0.6 | py27_0 11 KB
docutils-0.12 | py27_0 636 KB
ecdsa-0.11 | py27_0 73 KB
markupsafe-0.23 | py27_0 30 KB
mercurial-3.4.2 | py27_0 2.9 MB
nose-1.3.7 | py27_0 194 KB
paste-1.7.5.1 | py27_0 490 KB
pytz-2015.7 | py27_0 174 KB
repoze.lru-0.6 | py27_0 15 KB
requests-2.9.1 | py27_0 605 KB
six-1.10.0 | py27_0 16 KB
sqlalchemy-1.0.11 | py27_0 1.3 MB
sqlparse-0.1.18 | py27_0 51 KB
webob-1.4.1 | py27_0 108 KB
babel-2.1.1 | py27_0 2.3 MB
bx-python-0.7.3 | np110py27_1 2.1 MB
mako-1.0.3 | py27_0 105 KB
paramiko-1.15.2 | py27_0 197 KB
pastedeploy-1.5.2 | py27_1 23 KB
requests-toolbelt-0.5.0 | py27_0 83 KB
routes-2.2 | py27_0 48 KB
bioblend-0.7.0 | py27_0 181 KB
fabric-1.10.2 | py27_0 108 KB
------------------------------------------------------------
Total: 13.2 MB
The following NEW packages will be INSTALLED:
babel: 2.1.1-py27_0
bioblend: 0.7.0-py27_0
boto: 2.38.0-py27_0
bx-python: 0.7.3-np110py27_1
cheetah: 2.4.4-py27_0
decorator: 4.0.6-py27_0
docutils: 0.12-py27_0
ecdsa: 0.11-py27_0
fabric: 1.10.2-py27_0
libgfortran: 1.0-0
mako: 1.0.3-py27_0
markupsafe: 0.23-py27_0
mercurial: 3.4.2-py27_0
nose: 1.3.7-py27_0
numpy: 1.10.2-py27_0
openblas: 0.2.14-3
openssl: 1.0.2e-0
paramiko: 1.15.2-py27_0
paste: 1.7.5.1-py27_0
pastedeploy: 1.5.2-py27_1
pip: 7.1.2-py27_0
pycrypto: 2.6.1-py27_0
python: 2.7.11-0
pytz: 2015.7-py27_0
pyyaml: 3.11-py27_1
readline: 6.2-2
repoze.lru: 0.6-py27_0
requests: 2.9.1-py27_0
requests-toolbelt: 0.5.0-py27_0
routes: 2.2-py27_0
setuptools: 19.2-py27_0
six: 1.10.0-py27_0
sqlalchemy: 1.0.11-py27_0
sqlite: 3.9.2-0
sqlparse: 0.1.18-py27_0
tk: 8.5.18-0
webob: 1.4.1-py27_0
wheel: 0.26.0-py27_1
yaml: 0.1.6-0
zlib: 1.2.8-0
Proceed ([y]/n)?
Fetching packages ...
boto-2.38.0-py 100% |############################################| Time: 0:00:00 3.27 MB/s
cheetah-2.4.4- 100% |############################################| Time: 0:00:00 1.65 MB/s
decorator-4.0. 100% |############################################| Time: 0:00:00 20.38 MB/s
docutils-0.12- 100% |############################################| Time: 0:00:00 2.21 MB/s
ecdsa-0.11-py2 100% |############################################| Time: 0:00:00 762.58 kB/s
markupsafe-0.2 100% |############################################| Time: 0:00:00 931.23 kB/s
mercurial-3.4. 100% |############################################| Time: 0:00:00 5.36 MB/s
nose-1.3.7-py2 100% |############################################| Time: 0:00:00 1.12 MB/s
paste-1.7.5.1- 100% |############################################| Time: 0:00:00 1.91 MB/s
pytz-2015.7-py 100% |############################################| Time: 0:00:00 1.08 MB/s
repoze.lru-0.6 100% |############################################| Time: 0:00:00 465.26 kB/s
requests-2.9.1 100% |############################################| Time: 0:00:00 2.28 MB/s
six-1.10.0-py2 100% |############################################| Time: 0:00:00 477.04 kB/s
sqlalchemy-1.0 100% |############################################| Time: 0:00:00 4.25 MB/s
sqlparse-0.1.1 100% |############################################| Time: 0:00:00 774.57 kB/s
webob-1.4.1-py 100% |############################################| Time: 0:00:00 819.13 kB/s
babel-2.1.1-py 100% |############################################| Time: 0:00:00 5.53 MB/s
bx-python-0.7. 100% |############################################| Time: 0:00:00 5.11 MB/s
mako-1.0.3-py2 100% |############################################| Time: 0:00:00 813.04 kB/s
paramiko-1.15. 100% |############################################| Time: 0:00:00 1.23 MB/s
pastedeploy-1. 100% |############################################| Time: 0:00:00 721.20 kB/s
requests-toolb 100% |############################################| Time: 0:00:00 856.06 kB/s
routes-2.2-py2 100% |############################################| Time: 0:00:00 666.70 kB/s
bioblend-0.7.0 100% |############################################| Time: 0:00:00 1.15 MB/s
fabric-1.10.2- 100% |############################################| Time: 0:00:00 843.81 kB/s
Extracting packages ...
[ COMPLETE ]|###############################################################| 100%
Linking packages ...
[ COMPLETE ]|###############################################################| 100%
#
# To activate this environment, use:
# $ source activate galaxy
#
# To deactivate this environment, use:
# $ source deactivate
#
$ source activate galaxy
discarding /home/nate/conda/bin from PATH
prepending /home/nate/conda/envs/galaxy/bin to PATH
$ pip install --index-url=https://wheels.galaxyproject.org/simple/ -r lib/galaxy/dependencies/requirements.txt
Requirement already satisfied (use --upgrade to upgrade): numpy in /home/nate/conda/envs/galaxy/lib/python2.7/site-packages (from -r lib/galaxy/dependencies/requirements.txt (line 1))
...
Collecting WebHelpers (from -r lib/galaxy/dependencies/requirements.txt (line 15))
Downloading https://wheels.galaxyproject.org/packages/WebHelpers-1.3-py2-none-any.whl (149kB)
100% |████████████████████████████████| 151kB 55.7MB/s
...
Building wheels for collected packages: pysam
Running setup.py bdist_wheel for pysam
$ sh run.sh --skip-wheels
.. _Conda: http://conda.pydata.org/
.. _Conda environments: http://conda.pydata.org/docs/using/envs.html
.. _Bioconda: https://bioconda.github.io/
.. _Bioconda instructions: Bioconda_
.. _pinned: `Installing unpinned dependencies`_
.. _unpinned: pinned_
uWSGI
^^^^^
The simplest scenario to using uWSGI with the wheel-based dependencies is to
install uWSGI into Galaxy virtualenv (by default, ``.venv``) using pip, e.g.:
.. code-block:: console
$ . ./.venv/bin/activate
(.venv)$ pip install uwsgi
Collecting uwsgi
Downloading uwsgi-2.0.12.tar.gz (784kB)
100% |████████████████████████████████| 786kB 981kB/s
Building wheels for collected packages: uwsgi
Running setup.py bdist_wheel for uwsgi
Stored in directory: /home/nate/.cache/pip/wheels/a4/7b/7c/8cbe2fe2c2b963173361cc18aa726f165dc4803effbb8195fc
Successfully built uwsgi
Installing collected packages: uwsgi
Successfully installed uwsgi-2.0.12
Because uWSGI is installed in the virtualenv, Galaxy's dependencies will be
found upon startup.
If uWSGI is installed outside of the virtualenv (e.g. from apt) you will need
to pass the ``-H`` option (or one of `its many aliases
<http://uwsgi-docs.readthedocs.org/en/latest/Options.html#home>`_) on the uWSGI
command line:
.. code-block:: console
$ uwsgi --ini /srv/galaxy/config/uwsgi.ini -H /srv/galaxy/venv
Or in the uWSGI config file:
.. code-block:: ini
[uwsgi]
processes = 8
threads = 4
socket = /srv/galaxy/var/uwgi.sock
logto = /srv/galaxy/var/uwsgi.log
master = True
pythonpath = /srv/galaxy/server/lib
pythonhome = /srv/galaxy/venv
module = galaxy.webapps.galaxy.buildapp:uwsgi_app_factory()
set = galaxy_config_file=/srv/galaxy/config/galaxy.ini
set = galaxy_root=/srv/galaxy/server
Supervisor
^^^^^^^^^^
Many production sites use `supervisord`_ to manage their Galaxy processes
rather than relying on ``run.sh`` or other means. There's no simple way to
activate a virtualenv when using supervisor, but you can simulate the effects
by setting ``$PATH`` and ``$VIRTUAL_ENV`` in your supervisor config:
.. code-block:: ini
[program:galaxy_uwsgi]
command = /srv/galaxy/venv/bin/uwsgi --ini /srv/galaxy/config/uwsgi.ini
directory = /srv/galaxy/server
environment = VIRTUAL_ENV="/srv/galaxy/venv",PATH="/srv/galaxy/venv/bin:%(ENV_PATH)s"
numprocs = 1
[program:galaxy_handler]
command = /srv/galaxy/venv/bin/python ./scripts/galaxy-main -c /srv/galaxy/config/galaxy.ini --server-name=handler%(process_num)s
directory = /srv/galaxy/server
process_name = handler%(process_num)s
numprocs = 4
environment = VIRTUAL_ENV="/srv/galaxy/venv",PATH="/srv/galaxy/venv/bin:%(ENV_PATH)s"
With supervisor < 3.0 you cannot use the ``%(ENV_PATH)s`` template variable and
must instead specify the full desired ``$PATH``.
.. _supervisord: http://supervisord.org/
Custom pip/wheel rationale
--------------------------
We chose to use a modified version of the `pip`_ and `wheel`_ packages in order
to make Galaxy easy to use. People wishing to run Galaxy (especially only for
tool development) may not be systems or command line experts. Unfortunately,
Python modules with C extensions may not always compile out of the box
(typically due to missing compilers, headers, or other system packages) and the
failure messages generated are typically only decipherable to people
experienced with software compilation and almost never indicate how to fix the
problem. In addition, the process of compiling all of Galaxy's C extension
dependencies can be very long if it does succeed. As a result, we want to
precompile Galaxy's dependencies. However, the egg format was never prepared
for doing this on any platform and wheels could not do it on Linux because
there is no ABI compatibility between Linux distributions or versions.
As a benefit of using the standard tooling (pip), if you choose not to use
Galaxy pip, all of Galaxy's dependencies should still be installable using
standard pip. You will still need to point pip at `wheels.galaxyproject.org`_
in order to fetch some modified packages and ones that aren't available on
PyPI, but this can be done with the unmodified version of pip.
A good early discussion of these problems can be found in Armin Ronacher's
`blog post on wheels <http://lucumr.pocoo.org/2014/1/27/python-on-wheels/>`_.
One of the problems Armin discusses, Python interpreter ABI incompatibilites
depending on build-time options (UCS2 vs. UCS4), has been fixed by us and
accepted into pip >= 8.0 in `pip pull request #3075`_. The other major problem
(the non-portability of wheels between Linux distributions) remains. `Galaxy
pip`_ provides one solution to this problem.
More recently, the proposed `PEP 513`_ proposes a different solution to the
cross-distro problem. PEP 513 also contains a very detailed technical
explanation of the problem.
.. _PEP 513: https://www.python.org/dev/peps/pep-0513/
.. _pip pull request #3075: https://github.com/pypa/pip/pull/3075
.. _binary-compatibility.cfg: https://mail.python.org/pipermail/distutils-sig/2015-July/026617.html
Galaxy pip and wheel
--------------------
.. _Galaxy pip:
.. _Galaxy wheel: `Galaxy pip and wheel`_
`Galaxy pip is a fork <https://github.com/natefoo/pip/tree/linux-wheels>`_ of
`pip`_ in which we have added support for installing wheels containing C
extensions (wheels that have compiled binary code) on Linux. `Galaxy wheel is
a fork <https://bitbucket.org/natefoo/wheel>`_ of `wheel`_ in which we have
added support for building wheels installable with Galaxy pip.
Two different types of wheels can be created:
1. "Simple" wheels with very few dependencies outside of libc and libm built on
a "suitably old" platform (currently Debian Squeeze) such that they should
work on all newer systems (e.g. RHEL 6+, Ubuntu 12.04+). These wheels carry
the unmodified ``linux_{arch}`` platform tag (e.g. ``linux_x86_64``) as
specified in `PEP 425`_ and that you will find on wheels built with an
unmodified `wheel`_.
2. Wheels with specific external dependencies (for example, ``libpq.so``, the
PostgreSQL library, used by `psycopg2`_) can be built on each supported
Linux distribution and tagged more specifically for each distribution. These
wheels carry a ``linux_{arch}_{distro}_{version}`` platform tag (e.g.
``linux_x86_ubuntu_14_04``) and can be created using `Galaxy wheel`_.
Galaxy pip and Galaxy wheel also include support for the proposed
`binary-compatibility.cfg`_ file. This file allows distributions that are
binary compatibile (e.g. Red Hat Enterprise Linux 6 and CentOS 6) to use the
same wheels.
The `manylinux`_ project implements the "Simple" wheels in a more clearly
defined way and allows for the inclusion of "non-standard" external
dependencies directly into the wheel. Galaxy will officially support any
standard which allows for Linux wheels in PyPI once such a standard is
complete.
.. _PEP 425: https://www.python.org/dev/peps/pep-0425/
.. _manylinux: https://github.com/manylinux/manylinux/
.. _psycopg2: http://initd.org/psycopg/
Adding additional wheels as Galaxy dependencies
-----------------------------------------------
New wheels can be added to Galaxy, or the versions of existing wheels can be
updated, using `Galaxy Starforge`_, Galaxy's Docker-based build system.
The process is still under development and will be streamlined and automated
over time. For the time being, please use the following process to add new
wheels:
1. Install `Starforge`_ (e.g. with ``pip install starforge`` or ``python
setup.py install`` from the source). You will also need to have Docker
installed on your system.
2. Obtain `wheels.yml`_ (this file will most likely be moved in to Galaxy in
the future) and add/modify the wheel definition.
3. Use ``starforge wheel --wheels-config=wheels.yml <wheel-name>`` to build the
wheel. If the wheel includes C extensions, you will probably want to also
use the ``--no-qemu`` flag to prevent Starforge from attempting to build on
Mac OS X using QEMU/KVM.
4. If the wheel build is successful, submit a pull request to `Starforge`_ with
your changes to `wheels.yml`_.
5. A `Galaxy Committers group`_ member will need to trigger an automated build
of the wheel changes in your pull request. Galaxy's Jenkins_ service will
build these changes using Starforge.
6. If the pull request is merged, submit a pull request to Galaxy modifying the
files in `lib/galaxy/dependencies`_ as appropriate.
You may attempt to skip directly to step 4 and let the Starforge wheel PR
builder build your wheels for you. This is especially useful if you are simply
updating an existing wheel's version. However, if you are adding a new C
extension wheel that is not simple to build, you may need to go through many
iterations of updating the PR and having a `Galaxy Committers group`_ member
triggering builds before wheels are successfully built. You can avoid this
cycle by performing steps 1-3 locally.
.. _Starforge:
.. _Galaxy Starforge: https://github.com/galaxyproject/starforge/
.. _wheels.yml: https://github.com/galaxyproject/starforge/blob/master/wheels/build/wheels.yml
.. _Galaxy Committers group: https://github.com/galaxyproject/galaxy/blob/dev/doc/source/project/organization.rst#committers
.. _Jenkins: https://jenkins.galaxyproject.org/
.. _lib/galaxy/dependencies: https://github.com/galaxyproject/galaxy/tree/dev/lib/galaxy/dependencies
+2
View File
@@ -12,4 +12,6 @@ documentation. These resources should be used together.
dependency_resolvers.rst
framework_dependencies.rst
useful_scripts.rst
+20 -6
View File
@@ -105,19 +105,33 @@ Area Labels
The 'area' label is used for tagging issues and pull requests to a
particular focus area. This allows for easy searching within that
particular domain, as well as more organized release notes. Some
examples, not-exhaustive, are here:
particular domain, as well as more organized release notes.
- ``area/admin`` - Changes to admin functionality of the Galaxy webapp.
- ``area/API``
- ``area/cleanup``
- ``area/jobs``
- ``area/cleanup`` - General code cleanup.
- ``area/database`` - Change requires a modification to Galaxy's database.
- ``area/dataset-collections``
- ``area/datatypes`` - Changes to Galaxy's datatypes
- ``area/datatype-framework`` - Changes to Galaxy's datatype and metadata framework
- ``area/documentation``
- ``area/framework``
- ``area/GIEs``
- ``area/toolshed``
- ``area/histories``
- ``area/jobs``
- ``area/performance``
- ``area/reports``
- ``area/system`` - Changes to scripts used to run or manage Galaxy.
- ``area/tools`` - Changes to specific tools in Galaxy.
- ``area/tool-framework``
- ``area/toolshed``- Changes to the tool shed client or server.
- ``area/UI-UX``
- ``area/util``
- ``area/visualizations``
- ``area/workflows``
This list will definitely grow over time.
New labels should be proposed by opening a pull request against this document
in the dev branch of Galaxy.
Other Useful Labels
-------------------
+744
View File
@@ -0,0 +1,744 @@
.. to_doc
-------------------------------
16.01
-------------------------------
.. announce_start
Enhancements
-------------------------------
.. major_feature
* Interactive tours (with significant help from
`@bgruening <https://github.com/bgruening>`__.)
`Pull Request 1422`_, `Pull Request 1464`_
* Replace Galaxy eggs dependency management with wheels.
`Pull Request 428`_, `Pull Request 989`_, `Pull Request 988`_,
`Pull Request 1389`_, `Pull Request 1485`_, `Pull Request 995`_,
`Pull Request 996`_, `Pull Request 1006`_, `Pull Request 1017`_,
`Pull Request 1037`_
* Implement nested workflows.
`Pull Request 1306`_
.. feature
* Use Webpack to greatly optimize JavaScript and other assets served by Galaxy.
`Pull Request 1144`_
* Overhaul Galaxy analysis view toward a more modular JavaScript architecture.
`Pull Request 706`_, `Pull Request 1184`_
* Add BAM iobio_ visualization as a Galaxy Interactive Environment
(thanks to `@bgruening <https://github.com/bgruening>`__.)
`Pull Request 1131`_
* Add Jupyter Interactive Environment
(thanks to `@bgruening <https://github.com/bgruening>`__.)
`Pull Request 1400`_
* Procedures for bug and issue handling as well as roadmap management.
`Pull Request 902`_, `Pull Request 1020`_
* Implement a conda dependency resolver (with significant help from
`@bgruening <https://github.com/bgruening>`__.)
`Pull Request 1345`_, `Pull Request 1527`_, `Pull Request 1421`_,
`Pull Request 1409`_
* Many ToolBox improvements including allowing specifying labels on individual
tools, monitoring and automatic reloading of ``tool_conf.xml`` files, and
allowing specification of such files in JSON/YAML.
`Pull Request 1012`_, `Pull Request 1398`_
* Configurable client side logging.
`Pull Request 1011`_
* Allow input collections to specify multiple ``collection_type``\ s.
`Pull Request 1308`_
* Allow multiple collections to be supplied to a multiple data parameter.
`Pull Request 805`_
* Implement ``type_source`` on output collections.
`Pull Request 1153`_
* Allow tools to request a special configuration file containing tool parameters
dumped to json.
`Pull Request 1405`_
* Add search on username/any for API calls to user and use Select2 for sharing
workflows/pages/histories
(thanks to `@erasche <https://github.com/erasche>`__.)
`Pull Request 1111`_
* Improve masthead and scratchbook UI and architecture.
`Pull Request 1407`_, `Pull Request 1424`_
* Add support for constructive solid geometry datatypes ``ply`` and ``vtk``.
(Thanks to `@gregvonkuster <https://github.com/gregvonkuster>`__.)
`Pull Request 905`_, `Pull Request 1211`_
* Add searchgui datatype
(thanks to `@jj-umn <https://github.com/jj-umn>`__.)
`Pull Request 914`_
* Add BIOM v1 datatype
(thanks to `@fescudie <https://github.com/fescudie>`__.)
`Pull Request 950`_, `Pull Request 1198`_
* Add CRAM datatype
(thanks to `@yhoogstrate <https://github.com/yhoogstrate>`__.)
`Pull Request 1108`_, `Pull Request 1182`_
* Add UniProtXML datatype
(thanks to `@jj-umn <https://github.com/jj-umn>`__.)
`Pull Request 1004`_
* Avoid confusion by adding the PDF datatype to the list of uploadable file
types.
`Pull Request 901`_
* Add idpDB and HDF5 sniffers and fix MzSQlite sniffer
(thanks to `@chambm <https://github.com/chambm>`__.)
`Pull Request 1209`_
* Improve tool shed installation API for installation of repositories if they
are already installed
(thanks to `@bgruening <https://github.com/bgruening>`__.)
`Pull Request 1095`_
* Prevent GIEs from being closed without user confirmation
(thanks to `@bgruening <https://github.com/bgruening>`__.)
`Pull Request 1178`_
* Add the constructive solid geometery (CSG) viewer visualization plugin
(thanks to `@gregvonkuster <https://github.com/gregvonkuster>`__.)
`Pull Request 1254`_
* Add Google analytics tracking to new data libraries.
`Pull Request 959`_
* Extend users API with delete action
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__.)
`Pull Request 1063`_
* Finish swapping unencoded ids with order_index in workflows API.
`Pull Request 1137`_
.. enhancement
* Add documentation and extra options to Environment Modules resolver
(thanks to `@pvanheus <https://github.com/pvanheus>`__.)
`Pull Request 1221`_
* Documentation for dependency resolvers
(thanks to `@pvanheus <https://github.com/pvanheus>`__.)
`Pull Request 1296`_
* Populate env.sh files created via tool shed installations with ``X_ROOT_DIR``
environment variables.
`Pull Request 564`_, `Pull Request 889`_
* Reorganize history menu
(thanks to `@erasche <https://github.com/erasche>`__.)
`Pull Request 985`_
* Look up installed tools from different toolshed(s)
(thanks to `@mvdbeek <https://github.com/mvdbeek>`__.)
`Pull Request 818`_, `Pull Request 1286`_
* Documentation updates for ObjectStore
(thanks to `@mr-c <https://github.com/mr-c>`__.)
`Pull Request 853`_
* Update JavaScript dependency Dynatree.
`Pull Request 856`_
* Eliminate LWR from Galaxy (you will need to upgrade to Pulsar).
`Pull Request 857`_
* Isolate tool commands by default.
`Pull Request 1412`_, `Pull Request 1494`_
* Allow override of job shell (for conda resolver).
`Pull Request 1473`_
* Slight tweak to sidebar section naming from 'security' to 'user management'.
`Pull Request 877`_
* Fix the issue where too many datasets are linked to a certain role
(thanks to `@scholtalbers <https://github.com/scholtalbers>`__.)
`Pull Request 881`_
* Fix R dependency installation to be more portable
(thanks to `@bgruening <https://github.com/bgruening>`__.)
`Pull Request 893`_
* Reorder workflow inputs to top
(thanks to `@scholtalbers <https://github.com/scholtalbers>`__.)
`Pull Request 912`_
* Add an API script to upload directory as a data library
(thanks to `@erasche <https://github.com/erasche>`__.)
`Pull Request 918`_
* Enable dockerized toolshed tests.
`Pull Request 942`_
* Improvements and fixes for abstract tool interface.
`Pull Request 955`_
* Remove remaining references to galaxy.eggs and flake8 some tools
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__.)
`Pull Request 990`_
* Apply stricter flake8 rules for the directories shared with Pulsar
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__.)
`Pull Request 1010`_
* Updates to default welcome page.
`Pull Request 1013`_
* Revise deferred queue, use jQuery promises.
`Pull Request 1018`_
* Keep select field open in tool form multi select fields to ease selecting many
options quickly.
`Pull Request 1019`_
* Allow resizing of regular multi-select boxes.
`Pull Request 1025`_
* Add error message for wrongly formatted data in wig_to_bigwig
(thanks to `@scholtalbers <https://github.com/scholtalbers>`__.)
`Pull Request 1033`_
* Verify len files during download from UCSC
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__.)
`Pull Request 1066`_
* Add biocrusoe to contributors
`Pull Request 1067`_
* Outline "Format 2" workflow definitions.
`Pull Request 1096`_
* Improve the API attributes display on parameters page.
`Pull Request 1098`_
* Update run_tests.sh help for recent changes
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__.)
`Pull Request 1101`_
* Show welcome page with required login.
`Pull Request 1105`_
* Allow accessing collection elements in format_source.
(with significant help from `@nsoranzo <https://github.com/nsoranzo>`__.)
`Pull Request 1113`_, `Pull Request 1155`_
* Add nginx config for GIE proxy to documentation.
`Pull Request 1123`_
* Enforce client build deps are up-to-date.
`Pull Request 1130`_
* Menu onclick addition.
`Pull Request 1142`_
* Ensure confirmation when leaving GIE windows.
`Pull Request 1157`_
* Add local grunt-cli dependency for qunit tests.
`Pull Request 1159`_
* Tighten up GG sniffing
`Pull Request 864`_
* Use common exceptions in tools.
`Pull Request 874`_
* Refactor the remote user middleware for complexity
(thanks to `@erasche <https://github.com/erasche>`__.)
`Pull Request 875`_
* Allowed for capitalized package names such as R in unlinked tool shed
dependency resolver
(thanks to `@Christian-B <https://github.com/Christian-B>`__.)
`Pull Request 1160`_
* A slew of tool execution performance optimizations including a huge
fix from `@ericenns <https://github.com/ericenns>`__.
`Pull Request 1166`_, `Pull Request 1163`_, `Pull Request 1199`_,
`Pull Request 1212`_
* Do not check for tool migrations when running tests.
`Pull Request 1176`_
* Lazy load HDA/LDDA metadata to speed up history loading
(thanks to `@abretaud <https://github.com/abretaud>`__.)
`Pull Request 1179`_
* Add debug statement in output checker for why job is failing.
`Pull Request 1213`_
* Small enhancements in workflow inputs and outputs.
`Pull Request 1214`_
* More small workflow tweaks.
`Pull Request 1216`_
* Add Workflow editor UI for step labels.
`Pull Request 1251`_
* Ease the grunt uglify process
(Thanks to `@erasche <https://github.com/erasche>`__.)
`Pull Request 1238`_
* Add beta run workflow form based on the newer tool form code.
`Pull Request 1249`_
* During tool migrations, do not mess with galaxy_config_file if provided
(thanks to `@openlangrid <https://github.com/openlangrid>`__ and `@nsoranzo <https://github.com/nsoranzo>`__.)
`Pull Request 1230`_, `Pull Request 1253`_
* In the users API, properly return a boolean from has_requests
`Pull Request 1262`_
* Extend the logging of tool dependency status changes
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__.)
`Pull Request 1263`_
* Remove history_options and options.mako (history options as a page).
`Pull Request 1271`_
* Minor mail config cleanup
`Pull Request 1299`_
* Replace uses of history.imp and history.copy web methods for API create
`Pull Request 1303`_
* More tightening up of parameter validation during workflow stuff.
`Pull Request 1319`_
* Show a more user-friendly error when the webserver port is blocked
(thanks to `@shano <https://github.com/shano>`__.)
`Pull Request 1320`_
* Upgrade Paste to 2.0.2.
`Pull Request 1344`_
* A series of small refactoring enabling use of certain Galaxy modules
a stand-alone Python library with minimal dependencies and Python 3
compatibility.
`Pull Request 1350`_, `Pull Request 1351`_, `Pull Request 1352`_,
`Pull Request 1359`_, `Pull Request 1362`_, `Pull Request 1376`_,
`Pull Request 1413`_, `Pull Request 1427`_, `Pull Request 1363`_,
`Pull Request 1367`_, `Pull Request 1377`_, `Pull Request 1388`_,
`Pull Request 1448`_
* Adding UUID support to directory_hash_id
(thanks to `@kellrott <https://github.com/kellrott>`__.)
`Pull Request 1397`_
* Unify and abstract code for checking if file looks like a tool definition.
`Pull Request 1368`_
* Added hashes to pip requirements file
(thanks to `@erasche <https://github.com/erasche>`__.)
`Pull Request 1393`_
* Interactive environment updates
(thanks to `@bgruening <https://github.com/bgruening>`__.)
`Pull Request 1399`_
* Change scratchbook close icon.
`Pull Request 1425`_
* Rename reports_wsgi.ini to reports.ini
(thanks to `@souravsingh <https://github.com/souravsingh>`__.)
`Pull Request 1181`_
.. small_enhancement
* Attempt to fix more transiently failing API tests.
`Pull Request 859`_, `Pull Request 865`_
* Fix data library test case.
`Pull Request 898`_
* Remove ``test_map_over_two_collections_legacy`` test case as it is obsolete.
`Pull Request 924`_
* Version the testing-base docker image.
`Pull Request 938`_
* Update casperjs functional tests.
`Pull Request 944`_
* Fix the docker db client_encoding to not be ascii (default).
`Pull Request 952`_
* Use the database temp directory to store the Mako template cache when
running framework tests.
`Pull Request 956`_
* Rename ``lib/galaxy/main.py`` to scripts/galaxy-main
`Pull Request 994`_
* Fix deferred dom removal.
`Pull Request 997`_
* Options to more easily test esoteric tooling options.
`Pull Request 1014`_
* Fix log statements and link to logger.
`Pull Request 1040`_
* Add more data libraries API tests.
`Pull Request 1074`_
* Remove upload unused function parameter
(thanks to `@einon <https://github.com/einon>`__.)
`Pull Request 1078`_
* Update testing docker image.
`Pull Request 1083`_
* Small tool and workflow refactorings.
`Pull Request 1097`_
* Revise and fix waiting for tool tests.
`Pull Request 1119`_
* Small Tool and Workflow Refactoring and Fixes
`Pull Request 1202`_
* Wait on jobs and history in certain API test cases.
`Pull Request 1226`_
* Fix qunit shim to match base_panels.mako shim.
`Pull Request 1233`_
* Improved logging related tool test timeouts.
`Pull Request 1243`_
* Refactor generic side workflow editor panel toward backbone.
`Pull Request 1247`_
* Attempt to fix transiently failing tool test on Jenkins.
`Pull Request 1248`_
* Set client_encoding for TS dockerized test db
`Pull Request 1276`_
* Check for sessionStorage using a more cross-browser way.
`Pull Request 1279`_
* Small API test improvements.
`Pull Request 1285`_
* Enforce metrics related to moving toward modern client infrastructure.
`Pull Request 1292`_
* Refactor tool stuff for generic model actions.
`Pull Request 1307`_
* Remove workflow casperjs API test duplicating test coverage of API tests.
`Pull Request 1316`_
* Refactor tool parsing handling toward reuse outside Galaxy.
`Pull Request 1349`_, `Pull Request 1353`_
* Lint with Python 3 several modules.
`Pull Request 1354`_
* Fix and potential fix for transiently failing tests.
`Pull Request 1401`_
* Fix CasperJS tests.
`Pull Request 1438`_, `Pull Request 1439`_
* Add a log.warn() if extracted file does not exist when changing permissions.
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__.)
`Pull Request 939`_
Fixes
-------------------------------
.. major_bug
.. bug
* Add check for ``HTTP_GX_SECRET``
(thanks to `@golharam <https://github.com/golharam>`__.)
`Pull Request 827`_
* Test if parameter present in value to avoid index error in
tool state handling
(thanks to `@mvdbeek <https://github.com/mvdbeek>`__.)
`Pull Request 863`_
* Bump version of sqlite3 in nodejs proxy
(thanks to `@erasche <https://github.com/erasche>`__.)
`Pull Request 866`_
* Expose API keys to admins under ``REMOTE_USER``
(thanks to `@erasche <https://github.com/erasche>`__.)
`Pull Request 872`_
* Bug fix for tool shed repository API
(thanks to `@mvdbeek <https://github.com/mvdbeek>`__.)
`Pull Request 891`_
* Add a workaround to return a proper error code during R
package installation
(thanks to `@bgruening <https://github.com/bgruening>`__.)
`Pull Request 892`_
* Various Quota bug fixes.
`Pull Request 907`_
* Always set 'tests' for a visualization plugin to avoid an attribute
error.
`Pull Request 908`_
* Bug fix for condor runner changes made this release cycle
(thanks to `@erasche <https://github.com/erasche>`__.)
`Pull Request 909`_
* Change user preference datatype to text.
`Pull Request 916`_
* Fix syntax of error parameter of ``tryCatch`` in ``setup_r_environment action``
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__.)
`Pull Request 929`_
* Revise tool URL building.
`Pull Request 947`_
* Fix for code checking if a file seems to a tool definition file
(thanks to `@erasche <https://github.com/erasche>`__.)
`Pull Request 949`_
* Fix base panels to include scripts as the last element of the body.
`Pull Request 969`_
* Grid batch operation fixes.
`Pull Request 971`_
* Fix extra files path URL problem.
(thanks to `@erasche <https://github.com/erasche>`__.)
`Pull Request 991`_
* Fixes broken env-var declarations for tools with weird chars in their names
(thanks to `@yhoogstrate <https://github.com/yhoogstrate>`__.)
`Pull Request 1028`_
* Added gitignore rules to ignore custom tool-data
(thanks to `@yhoogstrate <https://github.com/yhoogstrate>`__.)
`Pull Request 1048`_
* Fix import of history datasets into library.
(thanks to `@mvdbeek <https://github.com/mvdbeek>`__.)
`Pull Request 1049`_
* Fix for reloading tools that have non-standard tool_ids/versions.
`Pull Request 1050`_
* Improved encoding handling for Jobs.
`Pull Request 1052`_
* Fix lped report output from converter.
`Pull Request 1069`_, `Pull Request 1070`_, `Pull Request 1072`_
* Trivial: Replace unnecessary duplicated var check with 'else if'
(thanks to `@einon <https://github.com/einon>`__.)
`Pull Request 1073`_
* Fix a bug in IEs when proxying the proxy.
`Pull Request 1076`_
* Fix 500 error when attempting to update installed repository.
`Pull Request 1082`_
* Resolve conflicting label CSS class for trackster.
`Pull Request 1086`_
* Fix bug with referrer attribute type change in WebOb.
`Pull Request 1091`_
* Fix API TS installation
(thanks to `@bgruening <https://github.com/bgruening>`__.)
`Pull Request 1094`_
* Better error when tool shed repository directory is missing
(thanks to `@lparsons <https://github.com/lparsons>`__.)
`Pull Request 1107`_
* Don't let ``$input`` hang cheetah evaluation.
`Pull Request 1117`_
* Fix for re-installing an uninstalled TS repository with a dependency
(Thanks to `@gregvonkuster <https://github.com/gregvonkuster>`__.)
`Pull Request 1154`_
* Fix interface and usage of ``WorkflowModule.get_runtime_inputs``.
`Pull Request 1174`_
* Add enhancements to the Galaxy repository install process
(thanks to `@mvdbeek <https://github.com/mvdbeek>`__.)
`Pull Request 1193`_
* Tool shed fixes
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__.)
`Pull Request 1200`_
* Fix for updating tool parameter dicts when a new parameter has been added to
a section.
`Pull Request 1215`_
* Replace the defunct readthedocs badge.
`Pull Request 1229`_
* Export ``GALAXY_TEST_DBURI`` as ``GALAXY_CONFIG_OVERRIDE_DATABASE_CONNECTION``
before installing wheels.
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__.)
`Pull Request 1231`_
* Fix passing of nginx_upload_path and ftp_upload_site.
`Pull Request 1250`_
* Fixed indentation errors for reports app
(thanks to `@markiskander <https://github.com/markiskander>`__.)
`Pull Request 1259`_
* Open select2 drop down on caret click.
`Pull Request 1298`_
* Improved validation of tools during workflow execution.
`Pull Request 1302`_
* Properly remove datasets from the filtered lists when pairing datasets
for the paired dataset list creator.
`Pull Request 1310`_
* Update Kombu and AMQP wheels to fix problems with El Capitan's System
Integrity Protection.
`Pull Request 1327`_
* Fix for creating workflow outputs on initial workflow upload.
`Pull Request 1330`_
* Don't query on unencoded IDs for error form
(thanks to `@erasche <https://github.com/erasche>`__.)
`Pull Request 1340`_
* If ``GALAXY_SLOTS`` is defined in the environment, use it for the local runner.
`Pull Request 1346`_
* Use both ``SLURM_NTASKS`` and ``SLURM_CPUS_PER_TASK`` to set ``GALAXY_SLOTS``
(thanks to `@lparsons <https://github.com/lparsons>`__.)
`Pull Request 1347`_
* Fix for loading workflows that have tool version / step upgrade messages.
`Pull Request 1348`_
* Allow installation of different repositories with the same name in a single
request
(thanks to `@mvdbeek <https://github.com/mvdbeek>`__.)
`Pull Request 1366`_
* Copy workflow objects when importing them.
`Pull Request 1474`_
* Fix mime type when previewing certain tabular data.
`Pull Request 1498`_
* Fix disabled CSS.
`Pull Request 1501`_
* catch Exception and properly log errors
`Pull Request 1511`_
* Fix for workflow validation problem introduced in 15.10.
`Pull Request 1536`_,
`Issue #1514 <https://github.com/galaxyproject/galaxy/issues/1514>`__
* Keep track of hidden datasets.
`Pull Request 1551`_
* Force ``--skip-venv`` if we can detect that Python is Conda Python.
`Pull Request 1554`_
.. _iobio: http://iobio.io/
.. github_links
.. _Pull Request 428: https://github.com/galaxyproject/galaxy/pull/428
.. _Pull Request 564: https://github.com/galaxyproject/galaxy/pull/564
.. _Pull Request 706: https://github.com/galaxyproject/galaxy/pull/706
.. _Pull Request 805: https://github.com/galaxyproject/galaxy/pull/805
.. _Pull Request 818: https://github.com/galaxyproject/galaxy/pull/818
.. _Pull Request 827: https://github.com/galaxyproject/galaxy/pull/827
.. _Pull Request 853: https://github.com/galaxyproject/galaxy/pull/853
.. _Pull Request 856: https://github.com/galaxyproject/galaxy/pull/856
.. _Pull Request 857: https://github.com/galaxyproject/galaxy/pull/857
.. _Pull Request 859: https://github.com/galaxyproject/galaxy/pull/859
.. _Pull Request 863: https://github.com/galaxyproject/galaxy/pull/863
.. _Pull Request 864: https://github.com/galaxyproject/galaxy/pull/864
.. _Pull Request 865: https://github.com/galaxyproject/galaxy/pull/865
.. _Pull Request 866: https://github.com/galaxyproject/galaxy/pull/866
.. _Pull Request 872: https://github.com/galaxyproject/galaxy/pull/872
.. _Pull Request 874: https://github.com/galaxyproject/galaxy/pull/874
.. _Pull Request 875: https://github.com/galaxyproject/galaxy/pull/875
.. _Pull Request 876: https://github.com/galaxyproject/galaxy/pull/876
.. _Pull Request 877: https://github.com/galaxyproject/galaxy/pull/877
.. _Pull Request 881: https://github.com/galaxyproject/galaxy/pull/881
.. _Pull Request 889: https://github.com/galaxyproject/galaxy/pull/889
.. _Pull Request 891: https://github.com/galaxyproject/galaxy/pull/891
.. _Pull Request 892: https://github.com/galaxyproject/galaxy/pull/892
.. _Pull Request 893: https://github.com/galaxyproject/galaxy/pull/893
.. _Pull Request 898: https://github.com/galaxyproject/galaxy/pull/898
.. _Pull Request 901: https://github.com/galaxyproject/galaxy/pull/901
.. _Pull Request 902: https://github.com/galaxyproject/galaxy/pull/902
.. _Pull Request 905: https://github.com/galaxyproject/galaxy/pull/905
.. _Pull Request 907: https://github.com/galaxyproject/galaxy/pull/907
.. _Pull Request 908: https://github.com/galaxyproject/galaxy/pull/908
.. _Pull Request 909: https://github.com/galaxyproject/galaxy/pull/909
.. _Pull Request 912: https://github.com/galaxyproject/galaxy/pull/912
.. _Pull Request 914: https://github.com/galaxyproject/galaxy/pull/914
.. _Pull Request 916: https://github.com/galaxyproject/galaxy/pull/916
.. _Pull Request 918: https://github.com/galaxyproject/galaxy/pull/918
.. _Pull Request 924: https://github.com/galaxyproject/galaxy/pull/924
.. _Pull Request 929: https://github.com/galaxyproject/galaxy/pull/929
.. _Pull Request 938: https://github.com/galaxyproject/galaxy/pull/938
.. _Pull Request 939: https://github.com/galaxyproject/galaxy/pull/939
.. _Pull Request 942: https://github.com/galaxyproject/galaxy/pull/942
.. _Pull Request 944: https://github.com/galaxyproject/galaxy/pull/944
.. _Pull Request 947: https://github.com/galaxyproject/galaxy/pull/947
.. _Pull Request 949: https://github.com/galaxyproject/galaxy/pull/949
.. _Pull Request 950: https://github.com/galaxyproject/galaxy/pull/950
.. _Pull Request 952: https://github.com/galaxyproject/galaxy/pull/952
.. _Pull Request 955: https://github.com/galaxyproject/galaxy/pull/955
.. _Pull Request 956: https://github.com/galaxyproject/galaxy/pull/956
.. _Pull Request 959: https://github.com/galaxyproject/galaxy/pull/959
.. _Pull Request 960: https://github.com/galaxyproject/galaxy/pull/960
.. _Pull Request 969: https://github.com/galaxyproject/galaxy/pull/969
.. _Pull Request 971: https://github.com/galaxyproject/galaxy/pull/971
.. _Pull Request 985: https://github.com/galaxyproject/galaxy/pull/985
.. _Pull Request 988: https://github.com/galaxyproject/galaxy/pull/988
.. _Pull Request 989: https://github.com/galaxyproject/galaxy/pull/989
.. _Pull Request 990: https://github.com/galaxyproject/galaxy/pull/990
.. _Pull Request 991: https://github.com/galaxyproject/galaxy/pull/991
.. _Pull Request 994: https://github.com/galaxyproject/galaxy/pull/994
.. _Pull Request 995: https://github.com/galaxyproject/galaxy/pull/995
.. _Pull Request 996: https://github.com/galaxyproject/galaxy/pull/996
.. _Pull Request 997: https://github.com/galaxyproject/galaxy/pull/997
.. _Pull Request 1004: https://github.com/galaxyproject/galaxy/pull/1004
.. _Pull Request 1006: https://github.com/galaxyproject/galaxy/pull/1006
.. _Pull Request 1010: https://github.com/galaxyproject/galaxy/pull/1010
.. _Pull Request 1011: https://github.com/galaxyproject/galaxy/pull/1011
.. _Pull Request 1012: https://github.com/galaxyproject/galaxy/pull/1012
.. _Pull Request 1013: https://github.com/galaxyproject/galaxy/pull/1013
.. _Pull Request 1014: https://github.com/galaxyproject/galaxy/pull/1014
.. _Pull Request 1017: https://github.com/galaxyproject/galaxy/pull/1017
.. _Pull Request 1018: https://github.com/galaxyproject/galaxy/pull/1018
.. _Pull Request 1019: https://github.com/galaxyproject/galaxy/pull/1019
.. _Pull Request 1020: https://github.com/galaxyproject/galaxy/pull/1020
.. _Pull Request 1025: https://github.com/galaxyproject/galaxy/pull/1025
.. _Pull Request 1028: https://github.com/galaxyproject/galaxy/pull/1028
.. _Pull Request 1033: https://github.com/galaxyproject/galaxy/pull/1033
.. _Pull Request 1037: https://github.com/galaxyproject/galaxy/pull/1037
.. _Pull Request 1040: https://github.com/galaxyproject/galaxy/pull/1040
.. _Pull Request 1048: https://github.com/galaxyproject/galaxy/pull/1048
.. _Pull Request 1049: https://github.com/galaxyproject/galaxy/pull/1049
.. _Pull Request 1050: https://github.com/galaxyproject/galaxy/pull/1050
.. _Pull Request 1052: https://github.com/galaxyproject/galaxy/pull/1052
.. _Pull Request 1063: https://github.com/galaxyproject/galaxy/pull/1063
.. _Pull Request 1066: https://github.com/galaxyproject/galaxy/pull/1066
.. _Pull Request 1067: https://github.com/galaxyproject/galaxy/pull/1067
.. _Pull Request 1069: https://github.com/galaxyproject/galaxy/pull/1069
.. _Pull Request 1070: https://github.com/galaxyproject/galaxy/pull/1070
.. _Pull Request 1072: https://github.com/galaxyproject/galaxy/pull/1072
.. _Pull Request 1073: https://github.com/galaxyproject/galaxy/pull/1073
.. _Pull Request 1074: https://github.com/galaxyproject/galaxy/pull/1074
.. _Pull Request 1076: https://github.com/galaxyproject/galaxy/pull/1076
.. _Pull Request 1078: https://github.com/galaxyproject/galaxy/pull/1078
.. _Pull Request 1082: https://github.com/galaxyproject/galaxy/pull/1082
.. _Pull Request 1083: https://github.com/galaxyproject/galaxy/pull/1083
.. _Pull Request 1086: https://github.com/galaxyproject/galaxy/pull/1086
.. _Pull Request 1091: https://github.com/galaxyproject/galaxy/pull/1091
.. _Pull Request 1094: https://github.com/galaxyproject/galaxy/pull/1094
.. _Pull Request 1095: https://github.com/galaxyproject/galaxy/pull/1095
.. _Pull Request 1096: https://github.com/galaxyproject/galaxy/pull/1096
.. _Pull Request 1097: https://github.com/galaxyproject/galaxy/pull/1097
.. _Pull Request 1098: https://github.com/galaxyproject/galaxy/pull/1098
.. _Pull Request 1101: https://github.com/galaxyproject/galaxy/pull/1101
.. _Pull Request 1105: https://github.com/galaxyproject/galaxy/pull/1105
.. _Pull Request 1107: https://github.com/galaxyproject/galaxy/pull/1107
.. _Pull Request 1108: https://github.com/galaxyproject/galaxy/pull/1108
.. _Pull Request 1111: https://github.com/galaxyproject/galaxy/pull/1111
.. _Pull Request 1113: https://github.com/galaxyproject/galaxy/pull/1113
.. _Pull Request 1117: https://github.com/galaxyproject/galaxy/pull/1117
.. _Pull Request 1119: https://github.com/galaxyproject/galaxy/pull/1119
.. _Pull Request 1123: https://github.com/galaxyproject/galaxy/pull/1123
.. _Pull Request 1126: https://github.com/galaxyproject/galaxy/pull/1126
.. _Pull Request 1130: https://github.com/galaxyproject/galaxy/pull/1130
.. _Pull Request 1131: https://github.com/galaxyproject/galaxy/pull/1131
.. _Pull Request 1137: https://github.com/galaxyproject/galaxy/pull/1137
.. _Pull Request 1142: https://github.com/galaxyproject/galaxy/pull/1142
.. _Pull Request 1144: https://github.com/galaxyproject/galaxy/pull/1144
.. _Pull Request 1153: https://github.com/galaxyproject/galaxy/pull/1153
.. _Pull Request 1154: https://github.com/galaxyproject/galaxy/pull/1154
.. _Pull Request 1155: https://github.com/galaxyproject/galaxy/pull/1155
.. _Pull Request 1157: https://github.com/galaxyproject/galaxy/pull/1157
.. _Pull Request 1159: https://github.com/galaxyproject/galaxy/pull/1159
.. _Pull Request 1160: https://github.com/galaxyproject/galaxy/pull/1160
.. _Pull Request 1163: https://github.com/galaxyproject/galaxy/pull/1163
.. _Pull Request 1166: https://github.com/galaxyproject/galaxy/pull/1166
.. _Pull Request 1174: https://github.com/galaxyproject/galaxy/pull/1174
.. _Pull Request 1176: https://github.com/galaxyproject/galaxy/pull/1176
.. _Pull Request 1178: https://github.com/galaxyproject/galaxy/pull/1178
.. _Pull Request 1179: https://github.com/galaxyproject/galaxy/pull/1179
.. _Pull Request 1181: https://github.com/galaxyproject/galaxy/pull/1181
.. _Pull Request 1182: https://github.com/galaxyproject/galaxy/pull/1182
.. _Pull Request 1184: https://github.com/galaxyproject/galaxy/pull/1184
.. _Pull Request 1193: https://github.com/galaxyproject/galaxy/pull/1193
.. _Pull Request 1198: https://github.com/galaxyproject/galaxy/pull/1198
.. _Pull Request 1199: https://github.com/galaxyproject/galaxy/pull/1199
.. _Pull Request 1200: https://github.com/galaxyproject/galaxy/pull/1200
.. _Pull Request 1202: https://github.com/galaxyproject/galaxy/pull/1202
.. _Pull Request 1209: https://github.com/galaxyproject/galaxy/pull/1209
.. _Pull Request 1211: https://github.com/galaxyproject/galaxy/pull/1211
.. _Pull Request 1212: https://github.com/galaxyproject/galaxy/pull/1212
.. _Pull Request 1213: https://github.com/galaxyproject/galaxy/pull/1213
.. _Pull Request 1214: https://github.com/galaxyproject/galaxy/pull/1214
.. _Pull Request 1215: https://github.com/galaxyproject/galaxy/pull/1215
.. _Pull Request 1216: https://github.com/galaxyproject/galaxy/pull/1216
.. _Pull Request 1217: https://github.com/galaxyproject/galaxy/pull/1217
.. _Pull Request 1221: https://github.com/galaxyproject/galaxy/pull/1221
.. _Pull Request 1226: https://github.com/galaxyproject/galaxy/pull/1226
.. _Pull Request 1229: https://github.com/galaxyproject/galaxy/pull/1229
.. _Pull Request 1230: https://github.com/galaxyproject/galaxy/pull/1230
.. _Pull Request 1231: https://github.com/galaxyproject/galaxy/pull/1231
.. _Pull Request 1233: https://github.com/galaxyproject/galaxy/pull/1233
.. _Pull Request 1238: https://github.com/galaxyproject/galaxy/pull/1238
.. _Pull Request 1243: https://github.com/galaxyproject/galaxy/pull/1243
.. _Pull Request 1247: https://github.com/galaxyproject/galaxy/pull/1247
.. _Pull Request 1248: https://github.com/galaxyproject/galaxy/pull/1248
.. _Pull Request 1249: https://github.com/galaxyproject/galaxy/pull/1249
.. _Pull Request 1250: https://github.com/galaxyproject/galaxy/pull/1250
.. _Pull Request 1251: https://github.com/galaxyproject/galaxy/pull/1251
.. _Pull Request 1253: https://github.com/galaxyproject/galaxy/pull/1253
.. _Pull Request 1254: https://github.com/galaxyproject/galaxy/pull/1254
.. _Pull Request 1259: https://github.com/galaxyproject/galaxy/pull/1259
.. _Pull Request 1261: https://github.com/galaxyproject/galaxy/pull/1261
.. _Pull Request 1262: https://github.com/galaxyproject/galaxy/pull/1262
.. _Pull Request 1263: https://github.com/galaxyproject/galaxy/pull/1263
.. _Pull Request 1271: https://github.com/galaxyproject/galaxy/pull/1271
.. _Pull Request 1276: https://github.com/galaxyproject/galaxy/pull/1276
.. _Pull Request 1277: https://github.com/galaxyproject/galaxy/pull/1277
.. _Pull Request 1279: https://github.com/galaxyproject/galaxy/pull/1279
.. _Pull Request 1285: https://github.com/galaxyproject/galaxy/pull/1285
.. _Pull Request 1286: https://github.com/galaxyproject/galaxy/pull/1286
.. _Pull Request 1292: https://github.com/galaxyproject/galaxy/pull/1292
.. _Pull Request 1296: https://github.com/galaxyproject/galaxy/pull/1296
.. _Pull Request 1298: https://github.com/galaxyproject/galaxy/pull/1298
.. _Pull Request 1299: https://github.com/galaxyproject/galaxy/pull/1299
.. _Pull Request 1302: https://github.com/galaxyproject/galaxy/pull/1302
.. _Pull Request 1303: https://github.com/galaxyproject/galaxy/pull/1303
.. _Pull Request 1306: https://github.com/galaxyproject/galaxy/pull/1306
.. _Pull Request 1307: https://github.com/galaxyproject/galaxy/pull/1307
.. _Pull Request 1308: https://github.com/galaxyproject/galaxy/pull/1308
.. _Pull Request 1310: https://github.com/galaxyproject/galaxy/pull/1310
.. _Pull Request 1316: https://github.com/galaxyproject/galaxy/pull/1316
.. _Pull Request 1319: https://github.com/galaxyproject/galaxy/pull/1319
.. _Pull Request 1320: https://github.com/galaxyproject/galaxy/pull/1320
.. _Pull Request 1327: https://github.com/galaxyproject/galaxy/pull/1327
.. _Pull Request 1330: https://github.com/galaxyproject/galaxy/pull/1330
.. _Pull Request 1340: https://github.com/galaxyproject/galaxy/pull/1340
.. _Pull Request 1343: https://github.com/galaxyproject/galaxy/pull/1343
.. _Pull Request 1344: https://github.com/galaxyproject/galaxy/pull/1344
.. _Pull Request 1345: https://github.com/galaxyproject/galaxy/pull/1345
.. _Pull Request 1346: https://github.com/galaxyproject/galaxy/pull/1346
.. _Pull Request 1347: https://github.com/galaxyproject/galaxy/pull/1347
.. _Pull Request 1348: https://github.com/galaxyproject/galaxy/pull/1348
.. _Pull Request 1349: https://github.com/galaxyproject/galaxy/pull/1349
.. _Pull Request 1350: https://github.com/galaxyproject/galaxy/pull/1350
.. _Pull Request 1351: https://github.com/galaxyproject/galaxy/pull/1351
.. _Pull Request 1352: https://github.com/galaxyproject/galaxy/pull/1352
.. _Pull Request 1353: https://github.com/galaxyproject/galaxy/pull/1353
.. _Pull Request 1354: https://github.com/galaxyproject/galaxy/pull/1354
.. _Pull Request 1359: https://github.com/galaxyproject/galaxy/pull/1359
.. _Pull Request 1362: https://github.com/galaxyproject/galaxy/pull/1362
.. _Pull Request 1363: https://github.com/galaxyproject/galaxy/pull/1363
.. _Pull Request 1366: https://github.com/galaxyproject/galaxy/pull/1366
.. _Pull Request 1367: https://github.com/galaxyproject/galaxy/pull/1367
.. _Pull Request 1368: https://github.com/galaxyproject/galaxy/pull/1368
.. _Pull Request 1376: https://github.com/galaxyproject/galaxy/pull/1376
.. _Pull Request 1377: https://github.com/galaxyproject/galaxy/pull/1377
.. _Pull Request 1385: https://github.com/galaxyproject/galaxy/pull/1385
.. _Pull Request 1388: https://github.com/galaxyproject/galaxy/pull/1388
.. _Pull Request 1389: https://github.com/galaxyproject/galaxy/pull/1389
.. _Pull Request 1393: https://github.com/galaxyproject/galaxy/pull/1393
.. _Pull Request 1397: https://github.com/galaxyproject/galaxy/pull/1397
.. _Pull Request 1398: https://github.com/galaxyproject/galaxy/pull/1398
.. _Pull Request 1399: https://github.com/galaxyproject/galaxy/pull/1399
.. _Pull Request 1400: https://github.com/galaxyproject/galaxy/pull/1400
.. _Pull Request 1401: https://github.com/galaxyproject/galaxy/pull/1401
.. _Pull Request 1405: https://github.com/galaxyproject/galaxy/pull/1405
.. _Pull Request 1407: https://github.com/galaxyproject/galaxy/pull/1407
.. _Pull Request 1409: https://github.com/galaxyproject/galaxy/pull/1409
.. _Pull Request 1412: https://github.com/galaxyproject/galaxy/pull/1412
.. _Pull Request 1413: https://github.com/galaxyproject/galaxy/pull/1413
.. _Pull Request 1414: https://github.com/galaxyproject/galaxy/pull/1414
.. _Pull Request 1415: https://github.com/galaxyproject/galaxy/pull/1415
.. _Pull Request 1421: https://github.com/galaxyproject/galaxy/pull/1421
.. _Pull Request 1422: https://github.com/galaxyproject/galaxy/pull/1422
.. _Pull Request 1424: https://github.com/galaxyproject/galaxy/pull/1424
.. _Pull Request 1425: https://github.com/galaxyproject/galaxy/pull/1425
.. _Pull Request 1427: https://github.com/galaxyproject/galaxy/pull/1427
.. _Pull Request 1430: https://github.com/galaxyproject/galaxy/pull/1430
.. _Pull Request 1438: https://github.com/galaxyproject/galaxy/pull/1438
.. _Pull Request 1439: https://github.com/galaxyproject/galaxy/pull/1439
.. _Pull Request 1448: https://github.com/galaxyproject/galaxy/pull/1448
.. _Pull Request 1464: https://github.com/galaxyproject/galaxy/pull/1464
.. _Pull Request 1473: https://github.com/galaxyproject/galaxy/pull/1473
.. _Pull Request 1474: https://github.com/galaxyproject/galaxy/pull/1474
.. _Pull Request 1485: https://github.com/galaxyproject/galaxy/pull/1485
.. _Pull Request 1487: https://github.com/galaxyproject/galaxy/pull/1487
.. _Pull Request 1494: https://github.com/galaxyproject/galaxy/pull/1494
.. _Pull Request 1498: https://github.com/galaxyproject/galaxy/pull/1498
.. _Pull Request 1501: https://github.com/galaxyproject/galaxy/pull/1501
.. _Pull Request 1511: https://github.com/galaxyproject/galaxy/pull/1511
.. _Pull Request 1527: https://github.com/galaxyproject/galaxy/pull/1527
.. _Pull Request 1536: https://github.com/galaxyproject/galaxy/pull/1536
.. _Pull Request 1551: https://github.com/galaxyproject/galaxy/pull/1551
.. _Pull Request 1554: https://github.com/galaxyproject/galaxy/pull/1554
.. _Pull Request 1558: https://github.com/galaxyproject/galaxy/pull/1558
+71 -3
View File
@@ -3,8 +3,76 @@
January 2016 Galaxy Release (v 16.01)
===========================================================
.. include:: _header.rst
Schedule
Highlights
===========================================================
* Planned Freeze Date: 2016-01-04
* Planned Release Date: 2016-01-25
**Interactive Tours**
The interactive tours framework allows developers and deployers to build
interactive tutorials for users superimposed on the actual Galaxy web front
end. Unlike video tutorials, these will not become stale and are truly
interactive (allowing users to actually navigate and interact with Galaxy).
Galaxy 16.01 ships with two example tours and new ones can easily be added by
creating a small YAML file describing the tour. Try the `Galaxy UI tour
<https://usegalaxy.org/?tour_id=core.galaxy_ui>`__ on Main.
**Wheels**
Galaxy's Python dependencies have traditionally been distributed as eggs_ using
custom dependency management code to enable Galaxy to distribute binary
dependencies (enabling quick downloads and minimal system requirements). With
this release all of that infrastructure has been replaced with a modern Python
infrastructure based on pip_ and wheels_.
Work done as part of this to enable binary dependencies on Linux has been
included with the recently released pip_ 8.
Detailed documentation on these changes and their impact under a variety of
Galaxy deployment scenarios can be found in the :ref:`framework-dependencies`
section of the Admin documentation.
**Nested Workflows**
Workflows may now run other workflows as a single abstract step in the parent
workflow. This allows for reusing or subworkflows in your analyses.
`Github <https://github.com/galaxyproject/galaxy>`__
===========================================================
New
.. code-block:: shell
% git clone -b master https://github.com/galaxyproject/galaxy.git
Update to latest stable release
.. code-block:: shell
% git checkout master && pull --ff-only origin master
Update to exact version
.. code-block:: shell
% git checkout v16.01
`BitBucket <https://bitbucket.org/galaxy/galaxy-dist>`__
===========================================================
Upgrade
.. code-block:: shell
% hg pull
% hg update latest_16.01
See `our wiki <https://wiki.galaxyproject.org/Develop/SourceCode>`__ for additional details regarding the source code locations.
.. _eggs: https://pythonhosted.org/setuptools/formats.html
.. _wheels: http://pythonwheels.com/
.. _pip: https://pip.pypa.io/en/stable/
Release Notes
===========================================================
.. include:: 16.01.rst
:start-after: announce_start
.. include:: _thanks.rst
+10
View File
@@ -0,0 +1,10 @@
===========================================================
April 2016 Galaxy Release (v 16.04)
===========================================================
Schedule
===========================================================
* Planned Freeze Date: 2016-04-04
* Planned Release Date: 2016-04-25
+1
View File
@@ -4,6 +4,7 @@ Releases
.. toctree::
:maxdepth: 1
16.01_announce
15.10_announce
15.07_announce
15.05_announce
+31 -6
View File
@@ -1,8 +1,17 @@
from __future__ import absolute_import
import logging
import signal
import sys
import time
import os
import time
try:
from uwsgidecorators import postfork
except:
def pf_dec(func):
return func
postfork = pf_dec
from galaxy import config, jobs
import galaxy.model
import galaxy.security
@@ -21,9 +30,10 @@ from galaxy.tools.data_manager.manager import DataManagers
from galaxy.jobs import metrics as job_metrics
from galaxy.web.proxy import ProxyManager
from galaxy.queue_worker import GalaxyQueueWorker
from galaxy.util import heartbeat
from tool_shed.galaxy_install import update_repository_manager
import logging
log = logging.getLogger( __name__ )
app = None
@@ -127,15 +137,24 @@ class UniverseApplication( object, config.ConfiguresGalaxyMixin ):
self.openid_providers = OpenIDProviders.from_file( self.config.openid_config_file )
else:
self.openid_providers = OpenIDProviders()
# Start the heartbeat process if configured and available
from galaxy import auth
self.auth_manager = auth.AuthManager( self )
# Start the heartbeat process if configured and available (wait until
# postfork if using uWSGI)
if self.config.use_heartbeat:
from galaxy.util import heartbeat
if heartbeat.Heartbeat:
self.heartbeat = heartbeat.Heartbeat( fname=self.config.heartbeat_log )
self.heartbeat = heartbeat.Heartbeat(
self.config,
period=self.config.heartbeat_interval,
fname=self.config.heartbeat_log
)
self.heartbeat.daemon = True
self.heartbeat.start()
@postfork
def _start():
self.heartbeat.start()
if not config.process_is_uwsgi:
_start()
# Transfer manager client
if self.config.get_bool( 'enable_beta_job_managers', False ):
from galaxy.jobs import transfer_manager
@@ -157,6 +176,12 @@ class UniverseApplication( object, config.ConfiguresGalaxyMixin ):
# Must be initialized after job_config.
self.workflow_scheduling_manager = scheduling_manager.WorkflowSchedulingManager( self )
# Configure handling of signals
handlers = {}
if self.heartbeat:
handlers[signal.SIGUSR1] = self.heartbeat.dump_signal_handler
self._configure_signal_handlers( handlers )
self.model.engine.dispose()
self.server_starttime = int(time.time()) # used for cachebusting
+12 -3
View File
@@ -9,6 +9,7 @@ import logging
import logging.config
import os
import re
import signal
import socket
import string
import sys
@@ -255,6 +256,8 @@ class Configuration( object ):
self.external_chown_script = kwargs.get('external_chown_script', None)
self.environment_setup_file = kwargs.get( 'environment_setup_file', None )
self.use_heartbeat = string_as_bool( kwargs.get( 'use_heartbeat', 'False' ) )
self.heartbeat_interval = int( kwargs.get( 'heartbeat_interval', 20 ) )
self.heartbeat_log = kwargs.get( 'heartbeat_log', None )
self.log_actions = string_as_bool( kwargs.get( 'log_actions', 'False' ) )
self.log_events = string_as_bool( kwargs.get( 'log_events', 'False' ) )
self.sanitize_all_html = string_as_bool( kwargs.get( 'sanitize_all_html', True ) )
@@ -306,7 +309,7 @@ class Configuration( object ):
self.use_tool_dependencies = True
else:
self.tool_dependency_dir = None
self.use_tool_dependencies = False
self.use_tool_dependencies = os.path.exists(self.dependency_resolvers_config_file)
# Configuration options for taking advantage of nginx features
self.upstream_gzip = string_as_bool( kwargs.get( 'upstream_gzip', False ) )
self.apache_xsendfile = string_as_bool( kwargs.get( 'apache_xsendfile', False ) )
@@ -351,8 +354,10 @@ class Configuration( object ):
self.config_file = global_conf['__file__']
global_conf_parser.read(global_conf['__file__'])
# Heartbeat log file name override
if global_conf is not None:
self.heartbeat_log = global_conf.get( 'heartbeat_log', 'heartbeat.log' )
if global_conf is not None and 'heartbeat_log' in global_conf:
self.heartbeat_log = global_conf['heartbeat_log']
if self.heartbeat_log is None:
self.heartbeat_log = 'heartbeat_{server_name}.log'
# Determine which 'server:' this is
self.server_name = 'main'
for arg in sys.argv:
@@ -912,3 +917,7 @@ class ConfiguresGalaxyMixin:
install_db_engine_options = self.config.install_database_engine_options
self.install_model = install_mapping.init( install_db_url,
install_db_engine_options )
def _configure_signal_handlers( self, handlers ):
for sig, handler in handlers.items():
signal.signal( sig, handler )
+1 -1
View File
@@ -339,7 +339,7 @@ class Bam( Binary ):
os.unlink( stderr_name )
# Now use pysam with BAI index to determine additional metadata
try:
bam_file = pysam.AlignmentFile( filename=dataset.file_name, mode='rb', index_filename=index_file.file_name )
bam_file = pysam.AlignmentFile( dataset.file_name, mode='rb', index_filename=index_file.file_name )
dataset.metadata.reference_names = list( bam_file.references )
dataset.metadata.reference_lengths = list( bam_file.lengths )
dataset.metadata.bam_header = bam_file.header
+16 -4
View File
@@ -742,13 +742,13 @@ class Text( Data ):
data_lines += 1
return data_lines
def set_peek( self, dataset, line_count=None, is_multi_byte=False, WIDTH=256, skipchars=None ):
def set_peek( self, dataset, line_count=None, is_multi_byte=False, WIDTH=256, skipchars=None, line_wrap=True ):
"""
Set the peek. This method is used by various subclasses of Text.
"""
if not dataset.dataset.purged:
# The file must exist on disk for the get_file_peek() method
dataset.peek = get_file_peek( dataset.file_name, is_multi_byte=is_multi_byte, WIDTH=WIDTH, skipchars=skipchars )
dataset.peek = get_file_peek( dataset.file_name, is_multi_byte=is_multi_byte, WIDTH=WIDTH, skipchars=skipchars, line_wrap=line_wrap )
if line_count is None:
# See if line_count is stored in the metadata
if dataset.metadata.data_lines:
@@ -950,7 +950,7 @@ def get_test_fname( fname ):
return full_path
def get_file_peek( file_name, is_multi_byte=False, WIDTH=256, LINE_COUNT=5, skipchars=None ):
def get_file_peek( file_name, is_multi_byte=False, WIDTH=256, LINE_COUNT=5, skipchars=None, line_wrap=True ):
"""
Returns the first LINE_COUNT lines wrapped to WIDTH
@@ -971,8 +971,9 @@ def get_file_peek( file_name, is_multi_byte=False, WIDTH=256, LINE_COUNT=5, skip
file_type = None
data_checked = False
temp = open( file_name, "U" )
last_line = ''
while count <= LINE_COUNT:
line = temp.readline( WIDTH )
line = last_line + temp.readline( WIDTH - len( last_line ) )
if line and not is_multi_byte and not data_checked:
# See if we have a compressed or binary file
if line[0:2] == util.gzip_magic:
@@ -986,6 +987,17 @@ def get_file_peek( file_name, is_multi_byte=False, WIDTH=256, LINE_COUNT=5, skip
data_checked = True
if file_type in [ 'gzipped', 'binary' ]:
break
if not line_wrap:
if '\n' in line:
i = line.index( '\n' )
last_line = line[i:]
line = line[:i]
else:
last_line = ''
while True:
i = temp.read(1)
if not i or i == '\n':
break
skip_line = False
for skipchar in skipchars:
if line.startswith( skipchar ):
+6 -3
View File
@@ -1519,9 +1519,12 @@ class ScIdx(Tabular):
line = line.strip()
# The first line is always a comment like this:
# 2015-11-23 20:18:56.51;input.bam;READ1
if line.startswith('#'):
count += 1
continue
if count == 0:
if line.startswith('#'):
count += 1
continue
else:
return False
if not line:
# EOF
if count > 1:
+4 -1
View File
@@ -39,7 +39,7 @@ class TabularData( data.Text ):
MetadataElement( name="delimiter", default='\t', desc="Data delimiter", readonly=True, visible=False, optional=True, no_value=[] )
def set_peek( self, dataset, line_count=None, is_multi_byte=False, WIDTH=256, skipchars=None ):
super(TabularData, self).set_peek( dataset, line_count=line_count, is_multi_byte=is_multi_byte, WIDTH=WIDTH, skipchars=skipchars)
super(TabularData, self).set_peek( dataset, line_count=line_count, is_multi_byte=is_multi_byte, WIDTH=WIDTH, skipchars=skipchars, line_wrap=False )
if dataset.metadata.comment_lines:
dataset.blurb = "%s, %s comments" % ( dataset.blurb, util.commaify( str( dataset.metadata.comment_lines ) ) )
@@ -180,6 +180,9 @@ class TabularData( data.Text ):
out.append( '<tr><td colspan="100%%">%s</td></tr>' % escape( line ) )
elif line:
elems = line.split( dataset.metadata.delimiter )
# pad shortened elems, since lines could have been truncated by width
if len( elems ) < columns:
elems.extend( [''] * ( columns - len( elems ) ) )
# we may have an invalid comment line or invalid data
if len( elems ) != columns:
out.append( '<tr><td colspan="100%%">%s</td></tr>' % escape( line ) )
@@ -0,0 +1,81 @@
# This file can be used with conda's `--file` option to install as many of
# Galaxy's dependencies as possible using Conda. The file
# conda-requirements.txt in this directory can be used to install the remaining
# missing dependencies using pip:
#
# $ conda create --name galaxy --file lib/galaxy/dependencies/conda-environment.txt
# $ source activate galaxy
# $ pip install --index-url=https://wheels.galaxyproject.org/simple/ -r lib/galaxy/dependencies/requirements.txt
#
# or if you already have an environment:
#
# $ source activate galaxy
# $ conda install --file lib/galaxy/dependencies/conda-environment.txt
# $ pip install --index-url=https://wheels.galaxyproject.org/simple/ -r lib/galaxy/dependencies/requirements.txt
#
# More details are available in the administration section of the Galaxy
# documentation at https://galaxy.readthedocs.org/
# packages with C extensions
# numpy should be installed before bx to enable extra features in bx
numpy
bx-python
MarkupSafe
PyYAML
SQLAlchemy
# Mercurial >= 3.5 changed the bundle format, which breaks hg push of TS repositories
mercurial<3.5
pycrypto
# Install python_lzo if you want to support indexed access to lzo-compressed
# locally cached maf files via bx-python
#python_lzo
# pure Python packages
Paste
PasteDeploy
docutils
#wchartype
repoze.lru
Routes
WebOb
#WebHelpers
Mako
pytz
Babel
#Beaker
# Cheetah and dependencies
Cheetah
# BioBlend and dependencies
bioblend
boto
requests
# kombu and dependencies
#kombu
# sqlalchemy-migrate and dependencies
#sqlalchemy-migrate
decorator
#Tempita
sqlparse
six
#Parsley
nose
#SVGFig
# Fabric and dependencies
Fabric
# We still pin these dependencies because of modifications to the upstream packages
# 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
# Flexible BAM index naming
#pysam==0.8.4+gx1
@@ -112,7 +112,8 @@ Cheetah==2.4.4 --hash:sha256=24cf67789b7a9f1e0a55cba266b6aad16e97aaf25810fd6f2f
Markdown==2.6.3 --hash:sha256=59417f5eb3dace08309d81e48fc903217d12d66677f367674b22c317b0f04284
# BioBlend and dependencies
bioblend==0.6.1 --hash:sha256=f5eea1f6c31264ef7bfab8c70deac2b9229a10e5c56508a6542f5643ad9e2a5b
bioblend==0.7.0 --hash:sha256=cb1068c0b05ca069a550ecbbf19014631bb6570b565387de15876c44478ee07d \
--hash:sha256=db7dc929199837b6d9a502fcf9d537a57fdee605ca45cd1548583a5eccc648a6
boto==2.38.0 --hash:sha256=1760584368da0c3861dbed448dcb439334ce831044262a5ca5188167f8bba585
requests==2.8.1 --hash:sha256=70e285122c97b1d104824482cb929246b2b8a2b9858897c4fab3acec83f1e03c
requests-toolbelt==0.4.0 --hash:sha256=94694e32845b84ed2186fdf56219b949582ebd08dc3abc55c0549958f2029643
@@ -149,22 +150,23 @@ ecdsa==0.13 --hash:sha256=89f149066e4a1e419892cef830fd0db85c227d5d427f7075422ace
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
# Flexible BAM/tabix index naming
pysam==0.8.4+gx1 --hash:sha256=9a548c88dbc928b64292ffa4a7697a4ee8c6653f998ef75c717c6dd37c8f67d3 \
--hash:sha256=bc2ba93bdf9228aaf479eae953a2d9012c9f69ee753446eec3edbdd5c55e8bd4 \
--hash:sha256=55e06fa6ce2df2e2bdb0705a14eefc6ad433effc79ab53d30642d8d0b33a98ff \
--hash:sha256=dd8600bee61cca3005c0e95b29aefa3611c452d980055799c3999e1c3cc044bb \
--hash:sha256=e4cc2b4b24d84b71c82f3194815b986e4f450ab62b96d7f28a453f5a47afdc24 \
--hash:sha256=f4eb92138ac871fe4db2e5a70ddbc2d6ffcf0c77314b4866b013b7a4d3a52aa6 \
--hash:sha256=c388728ec37d979c84980f662e9329452f90acf5e2e34c3afb1f66403e063b3f \
--hash:sha256=001620b7ea051fd2c868ef4f83a07838177a28c42839d76a86f653e124f9830b \
--hash:sha256=c27e705259d74dba190a2d729c326384ee9949e73478d7dca8e9e2aa593b54c1 \
--hash:sha256=4c3dae36124646a3bed6bc7e6fd2c979a4430aa290b61da1a611d3cf7e9b38e5 \
--hash:sha256=73124bec6d2699a30396c6eb63584230c8fdc0dce563391c217b9b57777d0d14 \
--hash:sha256=8db6bde296f6a34b584dddaeac1dc53f5819d0f63b0cded014a143366c64307f \
--hash:sha256=a40617160ba503ba31c297de24007e189cbb54325ea11265fa1b96e7d3f32625 \
--hash:sha256=2045ceb8f733dc787b5fa23293330d8f669a42952be14014d91b2d1d4db99c9e \
--hash:sha256=f140cd6c2c7b78be20f207e86be79772496a770c0d132604db0f632d54564ff8 \
--hash:sha256=d35cb62c382bda70552878069d7cc0321b41ec6095838332a15c44a14736b8aa \
--hash:sha256=2fae280fecfa6547b7c8291bc3966a940ce80400d79cdbc612cefb2bc399f5fd \
--hash:sha256=a85c470c3ae9d77f13b9fd57fcfdddf26b176d69840eb6654112fd711c86c243 \
--hash:sha256=9028099e40c45a3959add2c091b8817454b41c8aaa192e72d9c3ee9a5a1c5f8b
@@ -31,7 +31,7 @@ Cheetah==2.4.4
Markdown==2.6.3
# BioBlend and dependencies
bioblend==0.6.1
bioblend==0.7.0
boto==2.38.0
requests==2.8.1
requests-toolbelt==0.4.0
@@ -66,4 +66,4 @@ ecdsa==0.13
Whoosh==2.4.1+gx1
# Flexible BAM index naming
pysam==0.8.3+gx1
pysam==0.8.4+gx1
+1 -1
View File
@@ -60,4 +60,4 @@ Fabric
Whoosh==2.4.1+gx1
# Flexible BAM index naming
pysam==0.8.3+gx1
pysam==0.8.4+gx1
+14 -20
View File
@@ -965,9 +965,6 @@ class JobWrapper( object ):
# Get the exception and let the tool attempt to generate
# a better message
etype, evalue, tb = sys.exc_info()
m = self.tool.handle_job_failure_exception( evalue )
if m:
message = m
if self.app.config.outputs_to_working_directory:
for dataset_path in self.get_output_fnames():
try:
@@ -1301,9 +1298,7 @@ class JobWrapper( object ):
if not data:
continue
input_ext = data.ext
# why not re-use self.param_dict here? ##dunno...probably should, this causes
# tools.parameters.basic.UnvalidatedValue to be used in following methods
# instead of validated and transformed values during i.e. running workflows
# why not re-use self.param_dict here?
param_dict = dict( [ ( p.name, p.value ) for p in job.parameters ] )
param_dict = self.tool.params_from_strings( param_dict, self.app )
# Create generated output children and primary datasets and add to param_dict
@@ -1598,20 +1593,19 @@ class JobWrapper( object ):
config_file = self.app.config.config_file
if datatypes_config is None:
datatypes_config = self.app.datatypes_registry.integrated_datatypes_configs
base_command = self.external_output_metadata.setup_external_metadata( [ output_dataset_assoc.dataset for
output_dataset_assoc in
job.output_datasets + job.output_library_datasets ],
self.sa_session,
exec_dir=exec_dir,
tmp_dir=tmp_dir,
dataset_files_path=dataset_files_path,
config_root=config_root,
config_file=config_file,
datatypes_config=datatypes_config,
job_metadata=os.path.join( self.working_directory, TOOL_PROVIDED_JOB_METADATA_FILE ),
max_metadata_value_size=self.app.config.max_metadata_value_size,
**kwds )
command = base_command
command = self.external_output_metadata.setup_external_metadata( [ output_dataset_assoc.dataset for
output_dataset_assoc in
job.output_datasets + job.output_library_datasets ],
self.sa_session,
exec_dir=exec_dir,
tmp_dir=tmp_dir,
dataset_files_path=dataset_files_path,
config_root=config_root,
config_file=config_file,
datatypes_config=datatypes_config,
job_metadata=os.path.join( self.working_directory, TOOL_PROVIDED_JOB_METADATA_FILE ),
max_metadata_value_size=self.app.config.max_metadata_value_size,
**kwds )
if resolve_metadata_dependencies:
metadata_tool = self.app.toolbox.get_tool("__SET_METADATA__")
dependency_shell_commands = metadata_tool.build_dependency_shell_commands(job_directory=self.working_directory)
+18 -7
View File
@@ -402,23 +402,34 @@ class DeleteIntermediatesAction(DefaultJobAction):
# POTENTIAL ISSUES: When many outputs are being finish()ed
# concurrently, sometimes non-terminal steps won't be cleaned up
# because of the lag in job state updates.
sa_session.flush()
if not job.workflow_invocation_step:
log.debug("This job is not part of a workflow invocation, delete intermediates aborted.")
return
wfi = job.workflow_invocation_step.workflow_invocation
sa_session.refresh(wfi)
if wfi.active:
log.debug("Workflow still scheduling so new jobs may appear, skipping deletion of intermediate files.")
# Still evaluating workflow so we don't yet have all workflow invocation
# steps to start looking at.
return
if wfi.workflow.has_outputs_defined():
jobs_to_check = [wfistep.job for wfistep in wfi.steps if not wfistep.workflow_step.workflow_outputs]
outputs_defined = wfi.workflow.has_outputs_defined()
if outputs_defined:
wfi_steps = [wfistep for wfistep in wfi.steps if not wfistep.workflow_step.workflow_outputs and wfistep.workflow_step.type == "tool"]
jobs_to_check = []
for wfi_step in wfi_steps:
sa_session.refresh(wfi_step)
wfi_step_job = wfi_step.job
if wfi_step_job:
jobs_to_check.append(wfi_step_job)
else:
log.debug("No job found yet for wfi_step %s, (step %s)" % (wfi_step, wfi_step.workflow_step))
for j2c in jobs_to_check:
if j2c is None:
# Job not yet created, this will be re-evaluated after subsequent jobs in
# workflow.
return
for input_dataset in [x.dataset for x in j2c.input_datasets if x.dataset.creating_job.workflow_invocation_step and x.dataset.creating_job.workflow_invocation_step.workflow_invocation == wfi]:
creating_jobs = [(x, x.dataset.creating_job) for x in j2c.input_datasets if x.dataset.creating_job]
for (x, creating_job) in creating_jobs:
sa_session.refresh(creating_job)
sa_session.refresh(x)
for input_dataset in [x.dataset for (x, creating_job) in creating_jobs if creating_job.workflow_invocation_step and creating_job.workflow_invocation_step.workflow_invocation == wfi]:
safe_to_delete = True
for job_to_check in [d_j.job for d_j in input_dataset.dependent_jobs]:
if job_to_check != job and job_to_check.state not in [job.states.OK, job.states.DELETED]:
+2 -2
View File
@@ -169,9 +169,9 @@ class BaseJobRunner( object ):
include_metadata=include_metadata,
include_work_dir_outputs=include_work_dir_outputs,
)
except:
except Exception as e:
log.exception("(%s) Failure preparing job" % job_id)
job_wrapper.fail( "failure preparing job", exception=True )
job_wrapper.fail( e.message if hasattr( e, 'message' ) else "Job preparation failed", exception=True )
return False
if not job_wrapper.runner_command_line:
-13
View File
@@ -212,7 +212,6 @@ class CondorJobRunner( AsynchronousJobRunner ):
cjs.job_destination = job_wrapper.job_destination
cjs.user_log = os.path.join( self.app.config.cluster_files_directory, 'galaxy_%s.condor.log' % galaxy_id_tag )
cjs.register_cleanup_file_attribute( 'user_log' )
self.__old_state_paths( cjs )
if job.state == model.Job.states.RUNNING:
log.debug( "(%s/%s) is still in running state, adding to the DRM queue" % ( job.id, job.job_runner_external_id ) )
cjs.running = True
@@ -221,15 +220,3 @@ class CondorJobRunner( AsynchronousJobRunner ):
log.debug( "(%s/%s) is still in DRM queued state, adding to the DRM queue" % ( job.id, job.job_runner_external_id ) )
cjs.running = False
self.monitor_queue.put( cjs )
def __old_state_paths( self, cjs ):
"""For recovery of jobs started prior to standardizing the naming of
files in the AsychronousJobState object
"""
if cjs.job_wrapper is not None:
user_log = "%s/%s.condor.log" % (self.app.config.cluster_files_directory, cjs.job_wrapper.job_id)
if not os.path.exists( cjs.user_log ) and os.path.exists( user_log ):
cjs.output_file = "%s/%s.o" % (self.app.config.cluster_files_directory, cjs.job_wrapper.job_id)
cjs.error_file = "%s/%s.e" % (self.app.config.cluster_files_directory, cjs.job_wrapper.job_id)
cjs.job_file = "%s/galaxy_%s.sh" % (self.app.config.cluster_files_directory, cjs.job_wrapper.job_id)
cjs.user_log = user_log
-13
View File
@@ -332,7 +332,6 @@ class DRMAAJobRunner( AsynchronousJobRunner ):
ajs.command_line = job.get_command_line()
ajs.job_wrapper = job_wrapper
ajs.job_destination = job_wrapper.job_destination
self.__old_state_paths( ajs )
if job.state == model.Job.states.RUNNING:
log.debug( "(%s/%s) is still in running state, adding to the DRM queue" % ( job.get_id(), job.get_job_runner_external_id() ) )
ajs.old_state = drmaa.JobState.RUNNING
@@ -344,18 +343,6 @@ class DRMAAJobRunner( AsynchronousJobRunner ):
ajs.running = False
self.monitor_queue.put( ajs )
def __old_state_paths( self, ajs ):
"""For recovery of jobs started prior to standardizing the naming of
files in the AsychronousJobState object
"""
if ajs.job_wrapper is not None:
job_file = "%s/galaxy_%s.sh" % (self.app.config.cluster_files_directory, ajs.job_wrapper.job_id)
if not os.path.exists( ajs.job_file ) and os.path.exists( job_file ):
ajs.output_file = "%s.drmout" % os.path.join(os.getcwd(), ajs.job_wrapper.working_directory, ajs.job_wrapper.get_id_tag())
ajs.error_file = "%s.drmerr" % os.path.join(os.getcwd(), ajs.job_wrapper.working_directory, ajs.job_wrapper.get_id_tag())
ajs.exit_code_file = "%s.drmec" % os.path.join(os.getcwd(), ajs.job_wrapper.working_directory, ajs.job_wrapper.get_id_tag())
ajs.job_file = job_file
def store_jobtemplate(self, job_wrapper, jt):
""" Stores the content of a DRMAA JobTemplate object in a file as a JSON string.
Path is hard-coded, but it's no worse than other path in this module.
+9 -1
View File
@@ -535,8 +535,16 @@ class WorkflowContentsManager(UsesAnnotations):
# 'data_outputs': module.get_data_outputs(),
'annotation': annotation_str
}
# Add post-job actions to step dict.
# Add tool shed repository information and post-job actions to step dict.
if module.type == 'tool':
if module.tool.tool_shed_repository:
tsr = module.tool.tool_shed_repository
step_dict["tool_shed_repository"] = {
'name': tsr.name,
'owner': tsr.owner,
'changeset_revision': tsr.changeset_revision,
'tool_shed': tsr.tool_shed
}
pja_dict = {}
for pja in step.post_job_actions:
pja_dict[pja.action_type + pja.output_name] = dict(
+1 -1
View File
@@ -3177,7 +3177,7 @@ class DatasetCollectionInstance( object, HasName ):
return changed
class HistoryDatasetCollectionAssociation( DatasetCollectionInstance, Dictifiable ):
class HistoryDatasetCollectionAssociation( DatasetCollectionInstance, UsesAnnotations, Dictifiable ):
""" Associates a DatasetCollection with a History. """
editable_keys = ( 'name', 'deleted', 'visible' )
+2 -3
View File
@@ -12,7 +12,7 @@ import logging
import threading
from xml.etree import ElementTree
from galaxy.util import umask_fix_perms, force_symlink
from galaxy.util import umask_fix_perms, force_symlink, safe_makedirs
from galaxy.exceptions import ObjectInvalid, ObjectNotFound
from galaxy.util.sleeper import Sleeper
from galaxy.util.directory_hash import directory_hash_id
@@ -331,8 +331,7 @@ class DiskObjectStore(ObjectStore):
dir_only = kwargs.get('dir_only', False)
# Create directory if it does not exist
dir = path if dir_only else os.path.dirname(path)
if not os.path.exists(dir):
os.makedirs(dir)
safe_makedirs(dir)
# Create the file if it does not exist
if not dir_only:
open(path, 'w').close() # Should be rb?
+79 -186
View File
@@ -31,11 +31,10 @@ from galaxy.tools.parameters import params_to_incoming, check_param, params_from
from galaxy.tools.parameters import output_collect
from galaxy.tools.parameters.basic import (BaseURLToolParameter,
DataToolParameter, DataCollectionToolParameter, HiddenToolParameter,
SelectToolParameter, ToolParameter, UnvalidatedValue,
SelectToolParameter, ToolParameter,
contains_workflow_parameter)
from galaxy.tools.parameters.grouping import Conditional, ConditionalWhen, Repeat, Section, UploadDataset
from galaxy.tools.parameters.input_translation import ToolInputTranslator
from galaxy.tools.parameters.validation import LateValidationError
from galaxy.tools.test import parse_tests
from galaxy.tools.parser import get_tool_source
from galaxy.tools.parser.xml import XmlPageSource
@@ -53,6 +52,7 @@ from galaxy.util.template import fill_template
from galaxy.web import url_for
from galaxy.web.form_builder import SelectField
from galaxy.util.dictifiable import Dictifiable
from galaxy.work.context import WorkRequestContext
from tool_shed.util import common_util
from tool_shed.util import shed_util_common as suc
@@ -866,6 +866,9 @@ class Tool( object, Dictifiable ):
# Should have one child "input" which determines the case
test_param_input_source = input_source.parse_test_input_source()
group.test_param = self.parse_param_elem( test_param_input_source, enctypes, context )
if group.test_param.optional:
log.warning("Tool with id %s declares a conditional test parameter as optional, this is invalid and will be ignored." % self.id)
group.test_param.optional = False
possible_cases = list( group.test_param.legal_values ) # store possible cases, undefined whens will have no inputs
# Must refresh when test_param changes
group.test_param.refresh_on_change = True
@@ -1049,40 +1052,24 @@ class Tool( object, Dictifiable ):
# outputs?
return True
def new_state( self, trans, history=None ):
def new_state( self, trans ):
"""
Create a new `DefaultToolState` for this tool. It will be initialized
with default values for inputs.
"""
state = DefaultToolState()
state.inputs = {}
self.fill_in_new_state( trans, self.inputs, state.inputs, history=history )
self.fill_in_new_state( trans, self.inputs, state.inputs )
return state
def fill_in_new_state( self, trans, inputs, state, context=None, history=None ):
def fill_in_new_state( self, trans, inputs, state, context=None ):
"""
Fill in a tool state dictionary with default values for all parameters
in the dictionary `inputs`. Grouping elements are filled in recursively.
"""
context = ExpressionContext( state, context )
for input in inputs.itervalues():
state[ input.name ] = input.get_initial_value( trans, context, history=history )
def get_param_html_map( self, trans, page=0, other_values={} ):
"""
Return a dictionary containing the HTML representation of each
parameter. This is used for rendering display elements. It is
currently not compatible with grouping constructs.
NOTE: This should be considered deprecated, it is only used for tools
with `display` elements. These should be eliminated.
"""
rval = dict()
for key, param in self.inputs_by_page[page].iteritems():
if not isinstance( param, ToolParameter ):
raise Exception( "'get_param_html_map' only supported for simple paramters" )
rval[key] = param.get_html( trans, other_values=other_values )
return rval
state[ input.name ] = input.get_initial_value( trans, context )
def get_param( self, key ):
"""
@@ -1128,6 +1115,7 @@ class Tool( object, Dictifiable ):
to the form or execute the tool (only if 'execute' was clicked and
there were no errors).
"""
request_context = WorkRequestContext( app=trans.app, user=trans.user, history=history or trans.history )
rerun_remap_job_id = None
if 'rerun_remap_job_id' in incoming:
try:
@@ -1152,7 +1140,7 @@ class Tool( object, Dictifiable ):
all_params = []
validate_input = self.get_hook( 'validate_input' )
for expanded_incoming in expanded_incomings:
expanded_state = self.new_state( trans, history=history )
expanded_state = self.new_state( request_context )
# Process incoming data
if not self.check_values:
# If `self.check_values` is false we don't do any checking or
@@ -1163,7 +1151,7 @@ class Tool( object, Dictifiable ):
else:
# Update state for all inputs on the current page taking new
# values from `incoming`.
errors = self.populate_state( trans, self.inputs, expanded_state.inputs, expanded_incoming, history, source=source )
errors = self.populate_state( request_context, self.inputs, expanded_state.inputs, expanded_incoming, source=source )
# If the tool provides a `validate_input` hook, call it.
if validate_input:
validate_input( trans, errors, expanded_state.inputs, self.inputs )
@@ -1176,7 +1164,7 @@ class Tool( object, Dictifiable ):
if any( all_errors ):
raise exceptions.MessageException( err_data=all_errors[ 0 ] )
else:
execution_tracker = execute_job( trans, self, all_params, history=history, rerun_remap_job_id=rerun_remap_job_id, collection_info=collection_info )
execution_tracker = execute_job( trans, self, all_params, history=request_context.history, rerun_remap_job_id=rerun_remap_job_id, collection_info=collection_info )
if execution_tracker.successful_jobs:
return dict( out_data=execution_tracker.output_datasets,
num_jobs=len( execution_tracker.successful_jobs ),
@@ -1219,7 +1207,7 @@ class Tool( object, Dictifiable ):
elif isinstance(x, list):
[ self.find_fieldstorage( y ) for y in x ]
def populate_state( self, trans, inputs, state, incoming, history=None, source="html", prefix="", context=None ):
def populate_state( self, trans, inputs, state, incoming, source="html", prefix="", context=None ):
errors = dict()
# Push this level onto the context stack
context = ExpressionContext( state, context )
@@ -1239,14 +1227,13 @@ class Tool( object, Dictifiable ):
if rep_index < input.max:
new_state = {}
new_state['__index__'] = rep_index
self.fill_in_new_state( trans, input.inputs, new_state, context, history=history )
self.fill_in_new_state( trans, input.inputs, new_state, context )
group_state.append( new_state )
group_errors.append( {} )
rep_errors = self.populate_state( trans,
input.inputs,
new_state,
incoming,
history,
source,
prefix=rep_name + "|",
context=context )
@@ -1288,12 +1275,11 @@ class Tool( object, Dictifiable ):
# Current case has changed, throw away old state
group_state = state[input.name] = {}
# TODO: we should try to preserve values if we can
self.fill_in_new_state( trans, input.cases[current_case].inputs, group_state, context, history=history )
self.fill_in_new_state( trans, input.cases[current_case].inputs, group_state, context )
group_errors = self.populate_state( trans,
input.cases[current_case].inputs,
group_state,
incoming,
history,
source,
prefix=group_prefix,
context=context)
@@ -1306,12 +1292,11 @@ class Tool( object, Dictifiable ):
elif isinstance( input, Section ):
group_state = state[input.name]
group_prefix = "%s|" % ( key )
self.fill_in_new_state( trans, input.inputs, group_state, context, history=history )
self.fill_in_new_state( trans, input.inputs, group_state, context )
group_errors = self.populate_state( trans,
input.inputs,
group_state,
incoming,
history,
source,
prefix=group_prefix,
context=context )
@@ -1344,7 +1329,6 @@ class Tool( object, Dictifiable ):
input.inputs,
rep_state,
incoming,
history,
source,
prefix=rep_prefix,
context=context)
@@ -1485,11 +1469,7 @@ class Tool( object, Dictifiable ):
# load default initial value
if not test_param_error:
test_param_error = str( e )
if trans is not None:
history = trans.get_history()
else:
history = None
value = input.test_param.get_initial_value( trans, context, history=history )
value = input.test_param.get_initial_value( trans, context )
current_case = input.get_current_case( value, trans )
case_changed = current_case != old_current_case
if case_changed:
@@ -1652,17 +1632,18 @@ class Tool( object, Dictifiable ):
def params_from_strings( self, params, app, ignore_errors=False ):
return params_from_strings( self.inputs, params, app, ignore_errors )
def check_and_update_param_values( self, values, trans, update_values=True, allow_workflow_parameters=False ):
def check_and_update_param_values( self, values, trans, update_values=True, workflow_building_mode=False ):
"""
Check that all parameters have values, and fill in with default
values where necessary. This could be called after loading values
from a database in case new parameters have been added.
"""
messages = {}
self.check_and_update_param_values_helper( self.inputs, values, trans, messages, update_values=update_values, allow_workflow_parameters=allow_workflow_parameters )
request_context = WorkRequestContext( app=trans.app, user=trans.user, history=trans.history, workflow_building_mode=workflow_building_mode )
self.check_and_update_param_values_helper( self.inputs, values, request_context, messages, update_values=update_values )
return messages
def check_and_update_param_values_helper( self, inputs, values, trans, messages, context=None, prefix="", update_values=True, allow_workflow_parameters=False ):
def check_and_update_param_values_helper( self, inputs, values, trans, messages, context=None, prefix="", update_values=True ):
"""
Recursive helper for `check_and_update_param_values_helper`
"""
@@ -1677,7 +1658,7 @@ class Tool( object, Dictifiable ):
messages[ input.name ] = cond_messages
test_value = input.test_param.get_initial_value( trans, context )
current_case = input.get_current_case( test_value, trans )
self.check_and_update_param_values_helper( input.cases[ current_case ].inputs, {}, trans, cond_messages, context, prefix, allow_workflow_parameters=allow_workflow_parameters )
self.check_and_update_param_values_helper( input.cases[ current_case ].inputs, {}, trans, cond_messages, context, prefix, update_values=update_values )
elif isinstance( input, Repeat ):
if input.min:
messages[ input.name ] = []
@@ -1685,10 +1666,10 @@ class Tool( object, Dictifiable ):
rep_prefix = prefix + "%s %d > " % ( input.title, i + 1 )
rep_dict = dict()
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 )
self.check_and_update_param_values_helper( input.inputs, {}, trans, rep_dict, context, rep_prefix, update_values=update_values )
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 )
self.check_and_update_param_values_helper( input.inputs, {}, trans, messages[ input.name ], context, prefix, update_values=update_values )
else:
messages[ input.name ] = "No value found for '%s%s', using default" % ( prefix, input.label )
values[ input.name ] = input.get_initial_value( trans, context )
@@ -1697,7 +1678,7 @@ class Tool( object, Dictifiable ):
if isinstance( input, Repeat ):
for i, d in enumerate( values[ input.name ] ):
rep_prefix = prefix + "%s %d > " % ( input.title, i + 1 )
self.check_and_update_param_values_helper( input.inputs, d, trans, messages, context, rep_prefix, allow_workflow_parameters=allow_workflow_parameters )
self.check_and_update_param_values_helper( input.inputs, d, trans, messages, context, rep_prefix, update_values=update_values )
elif isinstance( input, Conditional ):
group_values = values[ input.name ]
use_initial_value = False
@@ -1715,96 +1696,32 @@ class Tool( object, Dictifiable ):
messages[ child_input.name ] = "Value no longer valid for '%s%s', replacing with default" % ( prefix, child_input.label )
else:
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 )
self.check_and_update_param_values_helper( input.cases[current].inputs, group_values, trans, messages, context, prefix, update_values=update_values )
elif isinstance( input, Section ):
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 )
self.check_and_update_param_values_helper( input.inputs, values[ input.name ], trans, messages[ input.name ], context, prefix, update_values=update_values )
else:
# Regular tool parameter, no recursion needed
try:
value = values[ input.name ]
if not allow_workflow_parameters:
if not trans.workflow_building_mode:
input.value_from_basic( input.value_to_basic( value, trans.app ), trans.app, ignore_errors=False )
input.validate( value, history=trans.history )
input.validate( value, trans )
else:
# skip check if is workflow parameters
ck_param = True
search = input.type in ["text"]
if allow_workflow_parameters and contains_workflow_parameter( values[ input.name ], search=search ):
if trans.workflow_building_mode and contains_workflow_parameter( values[ input.name ], search=search ):
ck_param = False
# this will fail when a parameter's type has changed to a non-compatible one: e.g. conditional group changed to dataset input
if ck_param:
input.value_from_basic( input.value_to_basic( value, trans.app ), trans.app, ignore_errors=False )
input.value_from_basic( input.value_to_basic( value, self.app ), self.app, ignore_errors=False )
except:
log.info("Parameter validation failed.", exc_info=True)
messages[ input.name ] = "Value no longer valid for '%s%s', replacing with default" % ( prefix, input.label )
if update_values:
values[ input.name ] = input.get_initial_value( trans, context )
def handle_unvalidated_param_values( self, input_values, app ):
"""
Find any instances of `UnvalidatedValue` within input_values and
validate them (by calling `ToolParameter.from_html` and
`ToolParameter.validate`).
"""
# No validation is done when check_values is False
if not self.check_values:
return
self.handle_unvalidated_param_values_helper( self.inputs, input_values, app )
def handle_unvalidated_param_values_helper( self, inputs, input_values, app, context=None, prefix="" ):
"""
Recursive helper for `handle_unvalidated_param_values`
"""
context = ExpressionContext( input_values, context )
for input in inputs.itervalues():
if isinstance( input, Repeat ):
for i, d in enumerate( input_values[ input.name ] ):
rep_prefix = prefix + "%s %d > " % ( input.title, i + 1 )
self.handle_unvalidated_param_values_helper( input.inputs, d, app, context, rep_prefix )
elif isinstance( input, Conditional ):
values = input_values[ input.name ]
current = values["__current_case__"]
# NOTE: The test param doesn't need to be checked since
# there would be no way to tell what case to use at
# workflow build time. However I'm not sure if we are
# actually preventing such a case explicately.
self.handle_unvalidated_param_values_helper( input.cases[current].inputs, values, app, context, prefix )
else:
# Regular tool parameter
value = input_values[ input.name ]
if isinstance( value, UnvalidatedValue ):
try:
# Convert from html representation
if value.value is None:
# If value.value is None, it could not have been
# submited via html form and therefore .from_html
# can't be guaranteed to work
value = None
else:
value = input.from_html( value.value, None, context )
# Do any further validation on the value
input.validate( value, None )
except Exception, e:
# Wrap an re-raise any generated error so we can
# generate a more informative message
message = "Failed runtime validation of %s%s (%s)" \
% ( prefix, input.label, e )
raise LateValidationError( message )
input_values[ input.name ] = value
def handle_job_failure_exception( self, e ):
"""
Called by job.fail when an exception is generated to allow generation
of a better error message (returning None yields the default behavior)
"""
message = None
# If the exception was generated by late validation, use its error
# message (contains the parameter name and value)
if isinstance( e, LateValidationError ):
message = e.message
return message
def build_dependency_shell_commands( self, job_directory=None ):
"""Return a list of commands to be run to populate the current environment to include this tools requirements."""
return self.app.toolbox.dependency_manager.dependency_shell_commands(
@@ -2110,7 +2027,7 @@ class Tool( object, Dictifiable ):
# Add input and output details.
if io_details:
tool_dict[ 'inputs' ] = [ input.to_dict( trans ) for input in self.inputs.values() ]
tool_dict[ 'outputs' ] = [ output.to_dict( app=trans.app ) for output in self.outputs.values() ]
tool_dict[ 'outputs' ] = [ output.to_dict( app=self.app ) for output in self.outputs.values() ]
tool_dict[ 'panel_section_id' ], tool_dict[ 'panel_section_name' ] = self.get_panel_section()
@@ -2132,18 +2049,18 @@ class Tool( object, Dictifiable ):
except Exception, e:
raise exceptions.MessageException( '[history_id=%s] Failed to retrieve history. %s.' % ( history_id, str( e ) ) )
# set workflow mode ( TODO: Should be revised/parsed without trans to tool parameters (basic.py) )
trans.workflow_building_mode = workflow_mode
# build request context
request_context = WorkRequestContext( app=trans.app, user=trans.user, history=history, workflow_building_mode=workflow_mode )
# load job parameters into incoming
tool_message = ''
if job:
try:
job_params = job.get_param_values( trans.app, ignore_errors=True )
self.check_and_update_param_values( job_params, trans, update_values=False )
self._map_source_to_history( trans, self.inputs, job_params, history )
tool_message = self._compare_tool_version(trans, job)
params_to_incoming( kwd, self.inputs, job_params, trans.app, to_html=False )
job_params = job.get_param_values( self.app, ignore_errors=True )
self.check_and_update_param_values( job_params, request_context, update_values=False )
self._map_source_to_history( request_context, self.inputs, job_params )
tool_message = self._compare_tool_version( job )
params_to_incoming( kwd, self.inputs, job_params, self.app )
except Exception, e:
raise exceptions.MessageException( str( e ) )
@@ -2152,12 +2069,6 @@ class Tool( object, Dictifiable ):
# convert value to jsonifiable value
def jsonify(v):
if isinstance(v, UnvalidatedValue):
v = v.value
while isinstance( v, UnvalidatedValue ):
v = v.value
return v
# check if value is numeric
isnumber = False
try:
@@ -2167,17 +2078,17 @@ class Tool( object, Dictifiable ):
pass
# fix hda parsing
if isinstance(v, trans.app.model.HistoryDatasetAssociation):
if isinstance(v, self.app.model.HistoryDatasetAssociation):
return {
'id' : trans.security.encode_id(v.id),
'src' : 'hda'
}
elif isinstance(v, trans.app.model.HistoryDatasetCollectionAssociation):
elif isinstance(v, self.app.model.HistoryDatasetCollectionAssociation):
return {
'id' : trans.security.encode_id(v.id),
'src' : 'hdca'
}
elif isinstance(v, trans.app.model.LibraryDatasetDatasetAssociation):
elif isinstance(v, self.app.model.LibraryDatasetDatasetAssociation):
return {
'id' : trans.security.encode_id(v.id),
'name': v.name,
@@ -2219,35 +2130,27 @@ class Tool( object, Dictifiable ):
dict[key] = value
# check the current state of a value and update it if necessary
def check_state(trans, input, value, context):
def check_state( input, value, context ):
error = 'State validation failed.'
# handle unvalidated values
if isinstance(value, galaxy.tools.parameters.basic.DummyDataset):
if isinstance( value, galaxy.tools.parameters.basic.DummyDataset ):
return [ None, None ]
elif isinstance(value, galaxy.tools.parameters.basic.RuntimeValue):
elif isinstance( value, galaxy.tools.parameters.basic.RuntimeValue ):
return [ { '__class__' : 'RuntimeValue' }, None ]
elif isinstance( value, dict ):
if value.get('__class__') == 'RuntimeValue':
if value.get( '__class__' ) == 'RuntimeValue':
return [ value, None ]
# validate value content
try:
# resolves the inconsistent definition of boolean parameters (see base.py) without modifying shared code
if input.type == 'boolean' and isinstance(value, basestring):
value, error = [string_as_bool(value), None]
else:
value, error = check_param(trans, input, value, context, history=history, workflow_building_mode=workflow_mode)
value, error = check_param( request_context, input, value, context, boolean_fix=True )
except Exception, err:
log.error('Checking parameter %s failed. %s', input.name, str(err))
log.error( 'Checking parameter %s failed. %s', input.name, str( err ) )
pass
return [value, error]
return [ value, error ]
# populates state with incoming url parameters
def populate_state(trans, inputs, state, errors, incoming, prefix="", context=None ):
def populate_state( inputs, state, errors, incoming, prefix="", context=None ):
context = ExpressionContext(state, context)
for input in inputs.itervalues():
state[input.name] = input.get_initial_value(trans, context, history=history)
state[input.name] = input.get_initial_value( request_context, context )
key = prefix + input.name
if input.type == 'repeat':
group_state = state[input.name]
@@ -2261,21 +2164,21 @@ class Tool( object, Dictifiable ):
new_state = {}
new_state['__index__'] = rep_index
group_state.append(new_state)
populate_state(trans, input.inputs, new_state, errors, incoming, prefix=rep_name + "|", context=context)
populate_state( input.inputs, new_state, errors, incoming, prefix=rep_name + "|", context=context )
rep_index += 1
elif input.type == 'conditional':
group_state = state[input.name]
group_prefix = "%s|" % ( key )
test_param_key = group_prefix + input.test_param.name
default_value = incoming.get(test_param_key, group_state.get(input.test_param.name, None))
value, error = check_state(trans, input.test_param, default_value, context)
value, error = check_state( input.test_param, default_value, context )
if error:
errors[test_param_key] = error
else:
try:
current_case = input.get_current_case(value, trans)
current_case = input.get_current_case( value, request_context )
group_state = state[input.name] = {}
populate_state( trans, input.cases[current_case].inputs, group_state, errors, incoming, prefix=group_prefix, context=context)
populate_state( input.cases[current_case].inputs, group_state, errors, incoming, prefix=group_prefix, context=context )
group_state['__current_case__'] = current_case
except Exception:
errors[test_param_key] = 'The selected case is unavailable/invalid.'
@@ -2284,53 +2187,53 @@ class Tool( object, Dictifiable ):
elif input.type == 'section':
group_state = state[input.name]
group_prefix = "%s|" % ( key )
populate_state(trans, input.inputs, group_state, errors, incoming, prefix=group_prefix, context=context)
populate_state( input.inputs, group_state, errors, incoming, prefix=group_prefix, context=context )
else:
default_value = incoming.get(key, state.get(input.name, None))
value, error = check_state(trans, input, default_value, context)
value, error = check_state( input, default_value, context )
if error:
errors[key] = error
state[input.name] = value
# builds tool model including all attributes
def iterate(group_inputs, inputs, state_inputs, other_values=None):
def iterate( group_inputs, inputs, state_inputs, other_values=None ):
other_values = ExpressionContext( state_inputs, other_values )
for input_index, input in enumerate( inputs.itervalues() ):
tool_dict = None
group_state = state_inputs.get(input.name, {})
if input.type == 'repeat':
tool_dict = input.to_dict(trans)
tool_dict = input.to_dict( request_context )
group_cache = tool_dict['cache'] = {}
for i in range( len( group_state ) ):
group_cache[i] = {}
iterate( group_cache[i], input.inputs, group_state[i], other_values )
elif input.type == 'conditional':
tool_dict = input.to_dict(trans)
tool_dict = input.to_dict( request_context )
if 'test_param' in tool_dict:
test_param = tool_dict['test_param']
test_param['default_value'] = jsonify(input.test_param.get_initial_value(trans, other_values, history=history))
test_param['default_value'] = jsonify( input.test_param.get_initial_value( request_context, other_values ) )
test_param['value'] = jsonify(group_state.get(test_param['name'], test_param['default_value']))
test_param['text_value'] = input.test_param.value_to_display_text(test_param['value'], trans.app)
test_param['text_value'] = input.test_param.value_to_display_text(test_param['value'], self.app)
for i in range(len( tool_dict['cases'] ) ):
current_state = {}
if i == group_state.get('__current_case__', None):
current_state = group_state
iterate(tool_dict['cases'][i]['inputs'], input.cases[i].inputs, current_state, other_values)
iterate( tool_dict['cases'][i]['inputs'], input.cases[i].inputs, current_state, other_values )
elif input.type == 'section':
tool_dict = input.to_dict(trans)
tool_dict = input.to_dict( request_context )
iterate( tool_dict['inputs'], input.inputs, group_state, other_values )
else:
# expand input dictionary, resolve dynamic parameters
try:
tool_dict = input.to_dict(trans, other_values=other_values)
tool_dict = input.to_dict( request_context, other_values=other_values )
except Exception:
tool_dict = input.to_dict(trans)
tool_dict = input.to_dict( request_context )
log.exception('tools::to_json() - Skipping parameter expansion for %s.' % input.name)
pass
# backup default value
try:
tool_dict['default_value'] = input.get_initial_value(trans, other_values, history=history)
tool_dict['default_value'] = input.get_initial_value( request_context, other_values )
except Exception:
tool_dict['default_value'] = None
log.exception('tools::to_json() - Getting initial value failed %s.' % input.name)
@@ -2340,7 +2243,7 @@ class Tool( object, Dictifiable ):
tool_dict['value'] = state_inputs.get(input.name, tool_dict['default_value'])
# add text value
tool_dict[ 'text_value' ] = input.value_to_display_text( tool_dict[ 'value' ], trans.app )
tool_dict[ 'text_value' ] = input.value_to_display_text( tool_dict[ 'value' ], self.app )
# sanitize values
sanitize(tool_dict, 'value')
@@ -2375,14 +2278,14 @@ class Tool( object, Dictifiable ):
# initialize and populate tool state
state_inputs = {}
state_errors = {}
populate_state(trans, self.inputs, state_inputs, state_errors, params.__dict__)
populate_state( self.inputs, state_inputs, state_errors, params.__dict__ )
# create basic tool model
tool_model = self.to_dict(trans)
tool_model = self.to_dict( request_context )
tool_model['inputs'] = {}
# build tool model and tool state
iterate(tool_model['inputs'], self.inputs, state_inputs, '')
iterate( tool_model['inputs'], self.inputs, state_inputs, '' )
# sanitize tool state
sanitize_state(state_inputs)
@@ -2419,14 +2322,14 @@ class Tool( object, Dictifiable ):
# add toolshed url
sharable_url = None
if self.tool_shed_repository:
sharable_url = self.tool_shed_repository.get_sharable_url( trans.app )
sharable_url = self.tool_shed_repository.get_sharable_url( self.app )
# add additional properties
tool_model.update({
'id' : self.id,
'help' : tool_help,
'citations' : tool_citations,
'biostar_url' : trans.app.config.biostar_url,
'biostar_url' : self.app.config.biostar_url,
'sharable_url' : sharable_url,
'message' : tool_message,
'versions' : tool_versions,
@@ -2452,10 +2355,11 @@ class Tool( object, Dictifiable ):
pass
return False
def _map_source_to_history(self, trans, tool_inputs, params, history):
def _map_source_to_history( self, trans, tool_inputs, params ):
# Need to remap dataset parameters. Job parameters point to original
# dataset used; parameter should be the analygous dataset in the
# current history.
history = trans.history
# Create index for hdas.
hda_source_dict = {}
@@ -2473,10 +2377,10 @@ class Tool( object, Dictifiable ):
def map_to_history(value):
id = None
source = None
if isinstance(value, trans.app.model.HistoryDatasetAssociation):
if isinstance(value, self.app.model.HistoryDatasetAssociation):
id = value.dataset.id
source = hda_source_dict
elif isinstance(value, trans.app.model.HistoryDatasetCollectionAssociation):
elif isinstance(value, self.app.model.HistoryDatasetCollectionAssociation):
id = value.collection.id
source = hdca_source_dict
else:
@@ -2489,18 +2393,7 @@ class Tool( object, Dictifiable ):
else:
return None
# Unpack unvalidated values to strings, they'll be validated when the
# form is submitted (this happens when re-running a job that was
# initially run by a workflow)
# This needs to be done recursively through grouping parameters
def mapping_callback( input, value, prefixed_name, prefixed_label ):
if isinstance( value, UnvalidatedValue ):
try:
return input.to_html_value( value.value, trans.app )
except Exception, e:
# Need to determine when (if ever) the to_html_value call could fail.
log.debug( "Failed to use input.to_html_value to determine value of unvalidated parameter, defaulting to string: %s" % ( e ) )
return str( value )
if isinstance( input, DataToolParameter ):
if isinstance(value, list):
values = []
@@ -2517,7 +2410,7 @@ class Tool( object, Dictifiable ):
return map_to_history( value )
visit_input_values( tool_inputs, params, mapping_callback )
def _compare_tool_version( self, trans, job ):
def _compare_tool_version( self, job ):
"""
Compares a tool version with the tool version from a job (from ToolRunner).
"""
+4 -2
View File
@@ -6,6 +6,7 @@ from galaxy.model import LibraryDatasetDatasetAssociation
from galaxy import model
from galaxy.tools.parameters.basic import DataCollectionToolParameter, DataToolParameter
from galaxy.tools.parameters.wrapped import WrappedParameters
from galaxy.tools.parameters import update_param
from galaxy.util import ExecutionTimer
from galaxy.util.json import dumps
from galaxy.util.none_like import NoneDataset
@@ -491,9 +492,10 @@ class DefaultToolAction( object ):
if hda.state == hda.states.PAUSED:
hda.state = hda.states.NEW
hda.info = None
input_values = dict( [ ( p.name, json.loads( p.value ) ) for p in job_to_remap.parameters ] )
update_param( jtid.name, input_values, str( out_data[ jtod.name ].id ) )
for p in job_to_remap.parameters:
if p.name == jtid.name and p.value == str(jtod.dataset.id):
p.value = str(out_data[jtod.name].id)
p.value = json.dumps( input_values[ p.name ] )
jtid.dataset = out_data[jtod.name]
jtid.dataset.hid = jtod.dataset.hid
log.info('Job %s input HDA %s remapped to new HDA %s' % (job_to_remap.id, jtod.dataset.id, jtid.dataset.id))
+18 -7
View File
@@ -21,11 +21,11 @@ from galaxy.tools.parameters.basic import (
DataCollectionToolParameter,
SelectToolParameter,
)
from galaxy.tools.parameters import wrapped_json
from galaxy.tools.parameters import wrapped_json, visit_input_values
from galaxy.tools.parameters.grouping import Conditional, Repeat, Section
from galaxy.tools import global_tool_errors
from galaxy.jobs.datasets import dataset_path_rewrites
from galaxy.work.context import WorkRequestContext
import logging
log = logging.getLogger( __name__ )
@@ -52,8 +52,15 @@ class ToolEvaluator( object ):
job = self.job
incoming = dict( [ ( p.name, p.value ) for p in job.parameters ] )
incoming = self.tool.params_from_strings( incoming, self.app )
# Do any validation that could not be done at job creation
self.tool.handle_unvalidated_param_values( incoming, self.app )
# Full parameter validation
request_context = WorkRequestContext( app=self.app, user=job.history and job.history.user, history=job.history )
def validate_inputs( input, value, prefixed_name, prefixed_label, context ):
value = input.from_html( value, request_context, context )
input.validate( value, request_context )
visit_input_values( self.tool.inputs, incoming, validate_inputs, details=True )
# Restore input / output data lists
inp_data = dict( [ ( da.name, da.dataset ) for da in job.input_datasets ] )
out_data = dict( [ ( da.name, da.dataset ) for da in job.output_datasets ] )
@@ -123,7 +130,7 @@ class ToolEvaluator( object ):
param_dict.update( incoming )
input_dataset_paths = dataset_path_rewrites( input_paths )
self.__populate_wrappers(param_dict, input_dataset_paths)
self.__populate_wrappers(param_dict, input_dataset_paths, job_working_directory)
self.__populate_input_dataset_wrappers(param_dict, input_datasets, input_dataset_paths)
self.__populate_output_dataset_wrappers(param_dict, output_datasets, output_paths, job_working_directory)
self.__populate_output_collection_wrappers(param_dict, output_collections, output_paths, job_working_directory)
@@ -158,18 +165,20 @@ class ToolEvaluator( object ):
do_walk( inputs, input_values )
def __populate_wrappers(self, param_dict, input_dataset_paths):
def __populate_wrappers(self, param_dict, input_dataset_paths, job_working_directory):
def wrap_input( input_values, input ):
if isinstance( input, DataToolParameter ) and input.multiple:
value = input_values[ input.name ]
dataset_instances = DatasetListWrapper.to_dataset_instances( value )
input_values[ input.name ] = \
DatasetListWrapper( dataset_instances,
DatasetListWrapper( job_working_directory,
dataset_instances,
dataset_paths=input_dataset_paths,
datatypes_registry=self.app.datatypes_registry,
tool=self.tool,
name=input.name )
elif isinstance( input, DataToolParameter ):
# FIXME: We're populating param_dict with conversions when
# wrapping values, this should happen as a separate
@@ -227,6 +236,7 @@ class ToolEvaluator( object ):
name=input.name
)
wrapper = DatasetCollectionWrapper(
job_working_directory,
dataset_collection,
**wrapper_kwds
)
@@ -299,6 +309,7 @@ class ToolEvaluator( object ):
name=name
)
wrapper = DatasetCollectionWrapper(
job_working_directory,
out_collection,
**wrapper_kwds
)
+1 -1
View File
@@ -39,7 +39,7 @@ def execute( trans, tool, param_combinations, history, rerun_remap_job_id=None,
# the state we about to execute one last time. Consider whether tool executions
# should run this as well.
if workflow_invocation_uuid:
messages = tool.check_and_update_param_values( params, trans, update_values=False, allow_workflow_parameters=False )
messages = tool.check_and_update_param_values( params, trans, update_values=False )
if messages:
execution_tracker.record_error( messages )
return
-3
View File
@@ -9,7 +9,6 @@ from sqlalchemy.orm import eagerload, eagerload_all
from galaxy import model
from galaxy.model.item_attrs import UsesAnnotations
from galaxy.tools.parameters.basic import UnvalidatedValue
from galaxy.util.json import dumps, loads
from galaxy.web.framework.helpers import to_unicode
@@ -382,8 +381,6 @@ class JobExportHistoryArchiveWrapper( object, UsesAnnotations ):
else:
rval['exported'] = True
return rval
if isinstance( obj, UnvalidatedValue ):
return obj.__str__()
return json.JSONEncoder.default( self, obj )
#
+6
View File
@@ -51,16 +51,22 @@ def lint_inputs(tool_xml, lint_ctx):
lint_ctx.warn("Conditional without <param type=\"select\" /> or <param type=\"boolean\" />")
continue
test_param_optional = False
for select in selects:
test_param_optional = test_param_optional or (select.attrib.get('optional', None) is not None)
select_options = _find_with_attribute(select, 'option', 'value')
select_option_ids = [option.attrib.get('value', None) for option in select_options]
for boolean in booleans:
test_param_optional = test_param_optional or (boolean.attrib.get('optional', None) is not None)
select_option_ids = [
boolean.attrib.get('truevalue', 'true'),
boolean.attrib.get('falsevalue', 'false')
]
if test_param_optional:
lint_ctx.warn("Conditional test parameter declares an invalid optional attribute.")
whens = conditional.findall('./when')
if any(['value' not in when.attrib for when in whens]):
lint_ctx.error("When without value")
+46 -25
View File
@@ -1,15 +1,17 @@
"""
Classes encapsulating Galaxy tool parameters.
"""
import re
from basic import DataCollectionToolParameter, DataToolParameter, SelectToolParameter
from grouping import Conditional, Repeat, Section, UploadDataset
from galaxy.util import string_as_bool
from galaxy.util.json import dumps, json_fix, loads
from galaxy.util.expressions import ExpressionContext
REPLACE_ON_TRUTHY = object()
def visit_input_values( inputs, input_values, callback, name_prefix="", label_prefix="", no_replacement_value=REPLACE_ON_TRUTHY ):
def visit_input_values( inputs, input_values, callback, name_prefix="", label_prefix="", no_replacement_value=REPLACE_ON_TRUTHY, context=None, details=False ):
"""
Given a tools parameter definition (`inputs`) and a specific set of
parameter `values`, call `callback` for each non-grouping parameter,
@@ -22,30 +24,33 @@ def visit_input_values( inputs, input_values, callback, name_prefix="", label_pr
Repeat and Group. This tracks labels and those do not. It would
be nice to unify all the places that recursively visit inputs.
"""
context = ExpressionContext( input_values, context )
for input in inputs.itervalues():
if isinstance( input, Repeat ) or isinstance( input, UploadDataset ):
for i, d in enumerate( input_values[ input.name ] ):
index = d['__index__']
new_name_prefix = name_prefix + "%s_%d|" % ( input.name, index )
new_label_prefix = label_prefix + "%s %d > " % ( input.title, i + 1 )
visit_input_values( input.inputs, d, callback, new_name_prefix, new_label_prefix, no_replacement_value=no_replacement_value )
visit_input_values( input.inputs, d, callback, new_name_prefix, new_label_prefix, no_replacement_value=no_replacement_value, context=context, details=details )
elif isinstance( input, Conditional ):
values = input_values[ input.name ]
current = values["__current_case__"]
label_prefix = label_prefix
new_name_prefix = name_prefix + input.name + "|"
visit_input_values( input.cases[current].inputs, values, callback, new_name_prefix, label_prefix, no_replacement_value=no_replacement_value )
visit_input_values( input.cases[current].inputs, values, callback, new_name_prefix, label_prefix, no_replacement_value=no_replacement_value, context=context, details=details )
elif isinstance( input, Section ):
values = input_values[ input.name ]
label_prefix = label_prefix
new_name_prefix = name_prefix + input.name + "|"
visit_input_values( input.inputs, values, callback, new_name_prefix, label_prefix, no_replacement_value=no_replacement_value )
visit_input_values( input.inputs, values, callback, new_name_prefix, label_prefix, no_replacement_value=no_replacement_value, context=context, details=details )
else:
new_value = callback( input,
input_values[input.name],
prefixed_name=name_prefix + input.name,
prefixed_label=label_prefix + input.label )
args = {
'input' : input,
'value' : input_values.get( input.name ),
'prefixed_name' : "%s%s" % ( name_prefix, input.name ),
'prefixed_label' : "%s%s" % ( label_prefix, input.label )
}
if details:
args[ 'context' ] = context
new_value = callback( **args )
if no_replacement_value is REPLACE_ON_TRUTHY:
replace = bool(new_value)
else:
@@ -54,7 +59,7 @@ def visit_input_values( inputs, input_values, callback, name_prefix="", label_pr
input_values[input.name] = new_value
def check_param( trans, param, incoming_value, param_values, source='html', history=None, workflow_building_mode=False ):
def check_param( trans, param, incoming_value, param_values, source='html', boolean_fix=False ):
"""
Check the value of a single parameter `param`. The value in
`incoming_value` is converted from its HTML encoding and validated.
@@ -65,21 +70,20 @@ def check_param( trans, param, incoming_value, param_values, source='html', hist
value = incoming_value
error = None
try:
if history is None:
history = trans.history
# resolves the inconsistent definition of boolean parameters (see base.py) without modifying shared code
if boolean_fix and param.type == 'boolean' and isinstance( value, basestring ):
return [ string_as_bool( value ), None ]
if value is not None or isinstance( param, DataToolParameter ) or isinstance( param, DataCollectionToolParameter ):
# Convert value from HTML representation
if source == 'html':
value = param.from_html( value, trans, param_values )
else:
value = param.from_json( value, trans, param_values )
# Allow the value to be converted if necessary
filtered_value = param.filter_value( value, trans, param_values )
# Then do any further validation on the value
param.validate( filtered_value, history, workflow_building_mode=workflow_building_mode )
param.validate( value, trans )
elif value is None and isinstance( param, SelectToolParameter ):
# An empty select list or column list
param.validate( value, history, workflow_building_mode=workflow_building_mode )
param.validate( value, trans )
except ValueError, e:
error = str( e )
return value, error
@@ -117,7 +121,7 @@ def params_from_strings( params, param_values, app, ignore_errors=False ):
return rval
def params_to_incoming( incoming, inputs, input_values, app, name_prefix="", to_html=True ):
def params_to_incoming( incoming, inputs, input_values, app, name_prefix="" ):
"""
Given a tool's parameter definition (`inputs`) and a specific set of
parameter `input_values` objects, populate `incoming` with the html values.
@@ -129,19 +133,36 @@ def params_to_incoming( incoming, inputs, input_values, app, name_prefix="", to_
for d in input_values[ input.name ]:
index = d['__index__']
new_name_prefix = name_prefix + "%s_%d|" % ( input.name, index )
params_to_incoming( incoming, input.inputs, d, app, new_name_prefix, to_html=to_html)
params_to_incoming( incoming, input.inputs, d, app, new_name_prefix )
elif isinstance( input, Conditional ):
values = input_values[ input.name ]
current = values["__current_case__"]
new_name_prefix = name_prefix + input.name + "|"
incoming[ new_name_prefix + input.test_param.name ] = values[ input.test_param.name ]
params_to_incoming( incoming, input.cases[current].inputs, values, app, new_name_prefix, to_html=to_html )
params_to_incoming( incoming, input.cases[current].inputs, values, app, new_name_prefix )
elif isinstance( input, Section ):
values = input_values[ input.name ]
new_name_prefix = name_prefix + input.name + "|"
params_to_incoming( incoming, input.inputs, values, app, new_name_prefix, to_html=to_html )
params_to_incoming( incoming, input.inputs, values, app, new_name_prefix )
else:
value = input_values.get( input.name )
if to_html:
value = input.to_html_value( value, app )
incoming[ name_prefix + input.name ] = value
def update_param( prefixed_name, input_values, new_value ):
"""
Given a prefixed parameter name, e.g. 'parameter_0|parameter_1', update
the corresponding input value in a nested input values dictionary.
"""
for key in input_values:
match = re.match( '^' + key + '_(\d+)\|(.+)', prefixed_name )
if match:
index = int( match.group( 1 ) )
if isinstance( input_values[ key ], list ) and len( input_values[ key ] ) > index:
update_param( match.group( 2 ), input_values[ key ][ index ], new_value )
else:
match = re.match( '^' + key + '\|(.+)', prefixed_name )
if isinstance( input_values[ key ], dict ) and match:
update_param( match.group( 1 ), input_values[ key ], new_value )
elif prefixed_name == key:
input_values[ key ] = new_value
+124 -238
View File
@@ -97,7 +97,7 @@ class ToolParameter( object, Dictifiable ):
def get_html_field( self, trans=None, value=None, other_values={} ):
raise TypeError( "Abstract Method" )
def get_html( self, trans=None, value=None, other_values={}):
def get_html( self, trans=None, value=None, other_values={} ):
"""
Returns the html widget corresponding to the parameter.
Optionally attempt to retain the current value specific by 'value'
@@ -114,13 +114,13 @@ class ToolParameter( object, Dictifiable ):
def from_json( self, value, trans=None, other_values={} ):
return self.from_html( value, trans, other_values )
def get_initial_value( self, trans, context, history=None ):
def get_initial_value( self, trans, other_values ):
"""
Return the starting value of the parameter
"""
return None
def get_initial_value_from_history_prevent_repeats( self, trans, context, already_used, history=None ):
def get_initial_value_from_history_prevent_repeats( self, trans, other_values, already_used ):
"""
Get the starting value for the parameter, but if fetching from the history, try
to find a value that has not yet been used. already_used is a list of objects that
@@ -128,7 +128,7 @@ class ToolParameter( object, Dictifiable ):
if a value has already been chosen from the history. This is to support the capability to
choose each dataset once
"""
return self.get_initial_value(trans, context, history=history)
return self.get_initial_value( trans, other_values )
def get_required_enctype( self ):
"""
@@ -144,17 +144,6 @@ class ToolParameter( object, Dictifiable ):
"""
return []
def filter_value( self, value, trans=None, other_values={} ):
"""
Parse the value returned by the view into a form usable by the tool OR
raise a ValueError.
"""
return value
def to_html_value( self, value, app ):
"""Convert an object value to the value expected from an html post"""
return self.to_string( value, app )
def to_string( self, value, app ):
"""Convert a value to a string representation suitable for persisting"""
if not isinstance( value, basestring ):
@@ -209,11 +198,11 @@ class ToolParameter( object, Dictifiable ):
value = sanitize_param( value )
return value
def validate( self, value, history=None, workflow_building_mode=False ):
def validate( self, value, trans=None ):
if value == "" and self.optional:
return
for validator in self.validators:
validator.validate( value, history )
validator.validate( value, trans )
def to_dict( self, trans, view='collection', value_mapper=None, other_values={} ):
""" to_dict tool parameter. This can be overridden by subclasses. """
@@ -285,18 +274,12 @@ class TextToolParameter( ToolParameter ):
rval = util.smart_str( value )
return rval
def to_html_value( self, value, app ):
if value is None:
return ''
else:
return self.to_string( value, app )
def validate( self, value, history=None, workflow_building_mode=False ):
def validate( self, value, trans=None ):
search = self.type == "text"
if not ( workflow_building_mode and contains_workflow_parameter(value, search=search) ):
return super( TextToolParameter, self ).validate( value, history )
if not ( trans and trans.workflow_building_mode and contains_workflow_parameter(value, search=search) ):
return super( TextToolParameter, self ).validate( value, trans )
def get_initial_value( self, trans, context, history=None ):
def get_initial_value( self, trans, other_values ):
return self.value
def to_dict( self, trans, view='collection', value_mapper=None, other_values={} ):
@@ -309,15 +292,16 @@ class TextToolParameter( ToolParameter ):
class IntegerToolParameter( TextToolParameter ):
"""
Parameter that takes an integer value.
>>> from galaxy.util.bunch import Bunch
>>> trans = Bunch( history=Bunch(), workflow_building_mode=True )
>>> p = IntegerToolParameter( None, XML( '<param name="blah" type="integer" size="4" value="10" />' ) )
>>> print p.name
blah
>>> print p.get_html()
<input type="text" name="blah" size="4" value="10">
>>> type( p.from_html( "10" ) )
>>> type( p.from_html( "10", trans ) )
<type 'int'>
>>> type( p.from_html( "bleh" ) )
>>> type( p.from_html( "bleh", trans ) )
Traceback (most recent call last):
...
ValueError: An integer or workflow parameter e.g. ${name} is required
@@ -355,15 +339,15 @@ class IntegerToolParameter( TextToolParameter ):
value = str( value )
return super( IntegerToolParameter, self ).get_html_field( trans=trans, value=value, other_values=other_values )
def from_html( self, value, trans=None, other_values={} ):
def from_html( self, value, trans, other_values={} ):
try:
return int( value )
except:
if contains_workflow_parameter(value) and _allow_workflow_parameters_in_context(trans):
if contains_workflow_parameter( value ) and trans.workflow_building_mode:
return value
if not value and self.optional:
return ""
if _allow_workflow_parameters_in_context(trans):
if trans.workflow_building_mode:
raise ValueError( "An integer or workflow parameter e.g. ${name} is required" )
else:
raise ValueError( "An integer is required" )
@@ -378,7 +362,7 @@ class IntegerToolParameter( TextToolParameter ):
return None
raise err
def get_initial_value( self, trans, context, history=None ):
def get_initial_value( self, trans, other_values ):
if self.value:
return int( self.value )
else:
@@ -388,15 +372,16 @@ class IntegerToolParameter( TextToolParameter ):
class FloatToolParameter( TextToolParameter ):
"""
Parameter that takes a real number value.
>>> from galaxy.util.bunch import Bunch
>>> trans = Bunch( history=Bunch(), workflow_building_mode=True )
>>> p = FloatToolParameter( None, XML( '<param name="blah" type="float" size="4" value="3.141592" />' ) )
>>> print p.name
blah
>>> print p.get_html()
<input type="text" name="blah" size="4" value="3.141592">
>>> type( p.from_html( "36.1" ) )
>>> type( p.from_html( "36.1", trans ) )
<type 'float'>
>>> type( p.from_html( "bleh" ) )
>>> type( p.from_html( "bleh", trans ) )
Traceback (most recent call last):
...
ValueError: A real number or workflow parameter e.g. ${name} is required
@@ -434,15 +419,15 @@ class FloatToolParameter( TextToolParameter ):
value = str( value )
return super( FloatToolParameter, self ).get_html_field( trans=trans, value=value, other_values=other_values )
def from_html( self, value, trans=None, other_values={} ):
def from_html( self, value, trans, other_values={} ):
try:
return float( value )
except:
if contains_workflow_parameter(value) and _allow_workflow_parameters_in_context(trans):
if contains_workflow_parameter( value ) and trans.workflow_building_mode:
return value
if not value and self.optional:
return ""
if _allow_workflow_parameters_in_context(trans):
if trans and trans.workflow_building_mode:
raise ValueError( "A real number or workflow parameter e.g. ${name} is required" )
else:
raise ValueError( "A real number is required" )
@@ -457,7 +442,7 @@ class FloatToolParameter( TextToolParameter ):
return None
raise err
def get_initial_value( self, trans, context, history=None ):
def get_initial_value( self, trans, other_values ):
try:
return float( self.value )
except:
@@ -501,16 +486,10 @@ class BooleanToolParameter( ToolParameter ):
def from_json( self, value, trans=None, other_values={} ):
return string_as_bool( value )
def to_html_value( self, value, app ):
if value:
return [ 'true', 'true' ]
else:
return [ 'true' ]
def to_python( self, value, app ):
return ( value in [ 'True', 'true' ])
def get_initial_value( self, trans, context, history=None ):
def get_initial_value( self, trans, other_values ):
return self.checked
def to_param_dict_string( self, value, other_values={} ):
@@ -559,7 +538,7 @@ class FileToolParameter( ToolParameter ):
# Middleware or proxies may encode files in special ways (TODO: this
# should be pluggable)
if type( value ) == dict:
upload_store = self.tool.app.config.nginx_upload_store
upload_store = trans.app.config.nginx_upload_store
assert upload_store, \
"Request appears to have been processed by nginx_upload_module \
but Galaxy is not configured to recognize it"
@@ -600,7 +579,7 @@ class FileToolParameter( ToolParameter ):
else:
raise Exception( "FileToolParameter cannot be persisted" )
def get_initial_value( self, trans, context, history=None ):
def get_initial_value( self, trans, other_values ):
return None
@@ -615,9 +594,10 @@ class FTPFileToolParameter( ToolParameter ):
input_source = ensure_input_source(input_source)
ToolParameter.__init__( self, tool, input_source )
self.multiple = input_source.get_bool( 'multiple', True )
self.optional = input_source.parse_optional( True )
self.user_ftp_dir = ''
def get_initial_value( self, trans, context, history=None ):
def get_initial_value( self, trans, other_values ):
if trans is not None:
if trans.user is not None:
self.user_ftp_dir = "%s/" % trans.user_ftp_dir
@@ -652,8 +632,6 @@ class FTPFileToolParameter( ToolParameter ):
return self.to_python( value, app )
def to_python( self, value, app, validate=False ):
if validate and self.tool.app.config.ftp_upload_dir is None:
raise ValueError( "The FTP directory is not configured." )
if not isinstance( value, list ):
value = [ value ]
lst = []
@@ -669,6 +647,8 @@ class FTPFileToolParameter( ToolParameter ):
if not self.optional and validate:
raise ValueError( "Please select a valid FTP file." )
return ''
if validate and self.tool.app.config.ftp_upload_dir is None:
raise ValueError( "The FTP directory is not configured." )
return lst
def to_dict( self, trans, view='collection', value_mapper=None, other_values=None ):
@@ -699,7 +679,7 @@ class HiddenToolParameter( ToolParameter ):
def get_html_field( self, trans=None, value=None, other_values={} ):
return form_builder.HiddenField( self.name, self.value )
def get_initial_value( self, trans, context, history=None ):
def get_initial_value( self, trans, other_values ):
return self.value
def get_label( self ):
@@ -722,7 +702,7 @@ class ColorToolParameter( ToolParameter ):
def get_html_field( self, trans=None, value=None, other_values={} ):
return form_builder.HiddenField( self.name, self.value )
def get_initial_value( self, trans, context, history=None ):
def get_initial_value( self, trans, other_values ):
return self.value.lower()
@@ -736,17 +716,21 @@ class BaseURLToolParameter( HiddenToolParameter ):
super( BaseURLToolParameter, self ).__init__( tool, input_source )
self.value = input_source.get( 'value', '' )
def get_initial_value( self, trans, context, history=None ):
def get_initial_value( self, trans, other_values ):
return self._get_value()
def get_html_field( self, trans=None, value=None, other_values={} ):
return form_builder.HiddenField( self.name, self._get_value() )
def from_html( self, value=None, trans=None, context={} ):
def from_html( self, value=None, trans=None, other_values={} ):
return self._get_value()
def _get_value( self ):
return url_for( self.value, qualified=True )
try:
return url_for( self.value, qualified=True )
except Exception as e:
log.debug( 'Url creation failed for "%s": %s', self.name, e )
return self.value
def to_dict( self, trans, view='collection', value_mapper=None, other_values={} ):
d = super( BaseURLToolParameter, self ).to_dict( trans )
@@ -793,8 +777,6 @@ class SelectToolParameter( ToolParameter ):
<option value="y">I am Y</option>
<option value="z" selected>I am Z</option>
</select>
>>> print p.filter_value( "y" )
y
>>> p = SelectToolParameter( None, XML(
... '''
@@ -885,12 +867,8 @@ class SelectToolParameter( ToolParameter ):
return self.static_options
def get_legal_values( self, trans, other_values ):
def _get_UnvalidatedValue_value( value ):
if isinstance( value, UnvalidatedValue ):
return value.value
return value
if self.options:
return map( _get_UnvalidatedValue_value, set( v for _, v, _ in self.options.get_options( trans, other_values ) ) )
return set( v for _, v, _ in self.options.get_options( trans, other_values ) )
elif self.dynamic_options:
try:
call_other_values = self._get_dynamic_options_call_other_values( trans, other_values )
@@ -901,13 +879,11 @@ class SelectToolParameter( ToolParameter ):
else:
return self.legal_values
def get_html_field( self, trans=None, value=None, context={} ):
def get_html_field( self, trans=None, value=None, other_values={} ):
# Dynamic options are not yet supported in workflow, allow
# specifying the value as text for now.
options = list(self.get_options( trans, context ))
if len(list(options)) == 0 and (trans is None or trans.workflow_building_mode):
if isinstance( value, UnvalidatedValue ):
value = value.value
options = list(self.get_options( trans, other_values ))
if len( list( options ) ) == 0 and trans.workflow_building_mode:
if self.multiple:
if value is None:
value = ""
@@ -919,21 +895,16 @@ class SelectToolParameter( ToolParameter ):
if value is not None:
if not isinstance( value, list ):
value = [ value ]
# We could have an unvalidated value here when e.g. running a workflow.
value = [ val.value if isinstance( val, UnvalidatedValue ) else val for val in value ]
field = form_builder.SelectField( self.name, self.multiple, self.display, self.refresh_on_change, refresh_on_change_values=self.refresh_on_change_values )
for text, optval, selected in options:
if isinstance( optval, UnvalidatedValue ):
optval = optval.value
text = "%s (unvalidated)" % text
if value:
selected = ( optval in value )
field.add_option( text, optval, selected )
return field
def from_html( self, value, trans=None, context={} ):
legal_values = self.get_legal_values( trans, context )
if len(list(legal_values)) == 0 and (trans is None or trans.workflow_building_mode):
def from_html( self, value, trans, other_values={} ):
legal_values = self.get_legal_values( trans, other_values )
if len(list(legal_values)) == 0 and trans.workflow_building_mode:
if self.multiple:
# While it is generally allowed that a select value can be '',
# we do not allow this to be the case in a dynamically
@@ -947,8 +918,8 @@ class SelectToolParameter( ToolParameter ):
# in interpreting values but also is needed because many browsers
# use \r\n to separate lines.
value = value.split()
return UnvalidatedValue( value )
if not legal_values and self.optional:
return value
if ( not legal_values or value is None ) and self.optional:
return None
if not legal_values:
raise ValueError( "Parameter %s requires a value, but has no legal values defined." % self.name )
@@ -973,12 +944,6 @@ class SelectToolParameter( ToolParameter ):
raise ValueError( "An invalid option was selected for %s, %r, please verify." % ( self.name, value ) )
return value
def to_html_value( self, value, app ):
if isinstance( value, list ):
return value
else:
return str( value )
def to_param_dict_string( self, value, other_values={}, value_map=DEFAULT_VALUE_MAP ):
if value is None:
return "None"
@@ -1000,9 +965,7 @@ class SelectToolParameter( ToolParameter ):
return value
def value_to_basic( self, value, app ):
if isinstance( value, UnvalidatedValue ):
return { "__class__": "UnvalidatedValue", "value": value.value }
elif isinstance( value, RuntimeValue ):
if isinstance( value, RuntimeValue ):
# Need to handle runtime value's ourself since delegating to the
# parent method causes the value to be turned into a string, which
# breaks multiple selection
@@ -1010,14 +973,15 @@ class SelectToolParameter( ToolParameter ):
return value
def value_from_basic( self, value, app, ignore_errors=False ):
# Backward compatibility for unvalidated values already stored in databases
if isinstance( value, dict ) and value.get( "__class__", None ) == "UnvalidatedValue":
return UnvalidatedValue( value["value"] )
return value[ "value" ]
return super( SelectToolParameter, self ).value_from_basic( value, app, ignore_errors=ignore_errors )
def get_initial_value( self, trans, context, history=None ):
options = list( self.get_options( trans, context ) )
if len(options) == 0 and (trans is None or trans.workflow_building_mode):
return UnvalidatedValue( None )
def get_initial_value( self, trans, other_values ):
options = list( self.get_options( trans, other_values ) )
if len(options) == 0 and trans.workflow_building_mode:
return None
value = [ optval for _, optval, selected in options if selected ]
if len( value ) == 0:
if not self.optional and not self.multiple and options:
@@ -1031,11 +995,6 @@ class SelectToolParameter( ToolParameter ):
return value
def value_to_display_text( self, value, app ):
if isinstance( value, UnvalidatedValue ):
suffix = "\n(value not yet validated)"
value = value.value
else:
suffix = ""
if not isinstance( value, list ):
value = [ value ]
# FIXME: Currently only translating values back to labels if they
@@ -1048,7 +1007,7 @@ class SelectToolParameter( ToolParameter ):
for t, v, s in options:
if v in value:
rval.append( t )
return "\n".join( rval ) + suffix
return "\n".join( rval )
def get_dependencies( self ):
"""
@@ -1123,9 +1082,6 @@ class GenomeBuildParameter( SelectToolParameter ):
<option value="hg17">Human May 2004 (NCBI35/hg17) (hg17)</option>
...
</select>
>>> print p.filter_value( "hg17" )
hg17
"""
def __init__( self, *args, **kwds ):
super( GenomeBuildParameter, self ).__init__( *args, **kwds )
@@ -1158,7 +1114,7 @@ class GenomeBuildParameter( SelectToolParameter ):
'options' : options,
'value' : value,
'display' : self.display,
'multiple' : self.multiple
'multiple' : self.multiple,
})
return d
@@ -1213,7 +1169,7 @@ class ColumnListParameter( SelectToolParameter ):
self.is_dynamic = True
self.usecolnames = input_source.get_bool( "use_header_names", False )
def from_html( self, value, trans=None, context={} ):
def from_html( self, value, trans, other_values={} ):
"""
Label convention prepends column number with a 'c', but tool uses the integer. This
removes the 'c' when entered into a workflow.
@@ -1237,7 +1193,7 @@ class ColumnListParameter( SelectToolParameter ):
value = ColumnListParameter._strip_c( value )
else:
value = None
return super( ColumnListParameter, self ).from_html( value, trans, context )
return super( ColumnListParameter, self ).from_html( value, trans, other_values )
@staticmethod
def _strip_c(column):
@@ -1327,10 +1283,10 @@ class ColumnListParameter( SelectToolParameter ):
options.append( ( 'Column: ' + col, col, False ) )
return options
def get_initial_value( self, trans, context, history=None ):
def get_initial_value( self, trans, other_values ):
if self.default_value is not None:
return self.default_value
return SelectToolParameter.get_initial_value( self, trans, context )
return SelectToolParameter.get_initial_value( self, trans, other_values )
def get_legal_values( self, trans, other_values ):
return set( self.get_column_list( trans, other_values ) )
@@ -1546,9 +1502,7 @@ class DrillDownSelectToolParameter( SelectToolParameter ):
# Dynamic options are not yet supported in workflow, allow
# specifying the value as text for now.
options = self.get_options( trans, value, other_values )
if len(list(options)) == 0 and (trans is None or trans.workflow_building_mode):
if isinstance( value, UnvalidatedValue ):
value = value.value
if len( list( options ) ) == 0 and trans.workflow_building_mode:
if self.multiple:
if value is None:
value = ""
@@ -1559,28 +1513,28 @@ class DrillDownSelectToolParameter( SelectToolParameter ):
return form_builder.TextField( self.name, value=(value or "") )
return form_builder.DrillDownField( self.name, self.multiple, self.display, self.refresh_on_change, options, value, refresh_on_change_values=self.refresh_on_change_values )
def from_html( self, value, trans=None, other_values={} ):
def from_html( self, value, trans, other_values={} ):
legal_values = self.get_legal_values( trans, other_values )
if len(list(legal_values)) == 0 and (trans is None or trans.workflow_building_mode):
if len( list( legal_values ) ) == 0 and trans.workflow_building_mode:
if self.multiple:
if value == '': # No option selected
value = None
else:
value = value.split( "\n" )
return UnvalidatedValue( value )
return value
if not value and not self.optional:
raise ValueError( "An invalid option was selected for %s, 'None', please verify" % (self.name) )
if not value:
return None
if not isinstance( value, list ):
value = [value]
value = [ value ]
if not( self.repeat ) and len( value ) > 1:
assert self.multiple, "Multiple values provided but parameter %s is not expecting multiple values" % self.name
rval = []
assert legal_values, "Parameter %s requires a value, but has no legal values defined" % self.name
for val in value:
if val not in legal_values:
raise ValueError( "An invalid option was selected for %s, %r, please verify" % (self.name, val))
raise ValueError( "An invalid option was selected for %s, %r, please verify" % ( self.name, val ) )
rval.append( val )
return rval
@@ -1625,16 +1579,16 @@ class DrillDownSelectToolParameter( SelectToolParameter ):
rval = sanitize_param( rval )
return rval
def get_initial_value( self, trans, context, history=None ):
def get_initial_value( self, trans, other_values ):
def recurse_options( initial_values, options ):
for option in options:
if option['selected']:
initial_values.append( option['value'] )
recurse_options( initial_values, option['options'] )
# More working around dynamic options for workflow
options = self.get_options( trans=trans, other_values=context )
if len(list(options)) == 0 and (trans is None or trans.workflow_building_mode):
return UnvalidatedValue( None )
options = self.get_options( trans=trans, other_values=other_values )
if len( list( options ) ) == 0 and trans.workflow_building_mode:
return None
initial_values = []
recurse_options( initial_values, options )
if len( initial_values ) == 0:
@@ -1650,12 +1604,6 @@ class DrillDownSelectToolParameter( SelectToolParameter ):
if rval:
return rval
return None # not found
if isinstance( value, UnvalidatedValue ):
suffix = "\n(value not yet validated)"
value = value.value
else:
suffix = ""
if not value:
value = []
elif not isinstance( value, list ):
@@ -1674,7 +1622,7 @@ class DrillDownSelectToolParameter( SelectToolParameter ):
rval = []
for val in value:
rval.append( get_option_display( val, self.options ) or val )
return "\n".join( map( str, rval ) ) + suffix
return "\n".join( map( str, rval ) )
def get_dependencies( self ):
"""
@@ -1707,13 +1655,11 @@ class BaseDataToolParameter( ToolParameter ):
def __init__( self, tool, input_source, trans ):
super(BaseDataToolParameter, self).__init__( tool, input_source )
def _get_history( self, trans, history=None ):
def _get_history( self, trans ):
class_name = self.__class__.__name__
assert trans is not None, "%s requires a trans" % class_name
if history is None:
history = trans.get_history()
assert history is not None, "%s requires a history" % class_name
return history
assert trans.history is not None, "%s requires a history" % class_name
return trans.history
def _ensure_selection( self, field ):
set_selected = field.get_selected( return_label=True, return_value=True, multi=False ) is not None
@@ -1822,7 +1768,7 @@ class DataToolParameter( BaseDataToolParameter ):
conv_types = [ tool.app.datatypes_registry.get_datatype_by_extension( conv_extensions.lower() ) ]
self.conversions.append( ( name, conv_extensions, conv_types ) )
def get_html_field( self, trans=None, value=None, other_values={} ):
def get_html_field( self, trans, value=None, other_values={} ):
if value is not None:
if type( value ) != list:
value = [ value ]
@@ -1838,7 +1784,7 @@ class DataToolParameter( BaseDataToolParameter ):
fields[ "multiselect_single" ] = multi_select
if self.__display_multirun_option():
collection_select = self._get_select_dataset_collection_fields( history, dataset_matcher, suffix="", reduction=True )
collection_select = self._get_select_dataset_collection_fields( trans, dataset_matcher, suffix="", reduction=True )
if collection_select.get_selected(return_value=True):
default_field = "multiselect_collection"
fields[ "multiselect_collection" ] = collection_select
@@ -1867,12 +1813,12 @@ class DataToolParameter( BaseDataToolParameter ):
multi_dataset_matcher = DatasetMatcher( trans, self, multirun_value, other_values )
multi_select = self._get_select_dataset_field( history, multi_dataset_matcher, multiple=True, suffix="|__multirun__" )
fields[ "select_multiple" ] = multi_select
collection_field = self._get_select_dataset_collection_fields( history, dataset_matcher, multiple=False, reduction=False )
collection_field = self._get_select_dataset_collection_fields( trans, dataset_matcher, multiple=False, reduction=False )
fields[ "select_collection" ] = collection_field
return self._switch_fields( fields, default_field=default_field )
def _get_select_dataset_collection_fields( self, history, dataset_matcher, multiple=False, suffix="|__collection_multirun__", reduction=False ):
def _get_select_dataset_collection_fields( self, trans, dataset_matcher, multiple=False, suffix="|__collection_multirun__", reduction=False ):
if not reduction:
def value_modifier(x):
return x
@@ -1888,11 +1834,11 @@ class DataToolParameter( BaseDataToolParameter ):
field_name = "%s%s" % ( self.name, suffix )
field = form_builder.SelectField( field_name, multiple, None, self.refresh_on_change, refresh_on_change_values=self.refresh_on_change_values )
for history_dataset_collection in self.match_collections( history, dataset_matcher, reduction=reduction ):
for history_dataset_collection in self.match_collections( trans.history, dataset_matcher, reduction=reduction ):
name = history_dataset_collection.name
hid = str( history_dataset_collection.hid )
hidden_text = "" # TODO
id = value_modifier( dataset_matcher.trans.security.encode_id( history_dataset_collection.id ) )
id = value_modifier( trans.security.encode_id( history_dataset_collection.id ) )
selected = value and history_dataset_collection in value
text = "%s:%s %s" % ( hid, hidden_text, name )
field.add_option( text, id, selected )
@@ -1949,19 +1895,19 @@ class DataToolParameter( BaseDataToolParameter ):
for item in dataset_collector( history.active_datasets_children_and_roles, None ):
yield item
def get_initial_value( self, trans, context, history=None ):
return self.get_initial_value_from_history_prevent_repeats(trans, context, None, history=history)
def get_initial_value( self, trans, other_values ):
return self.get_initial_value_from_history_prevent_repeats(trans, other_values, None )
def get_initial_value_from_history_prevent_repeats( self, trans, context, already_used, history=None ):
def get_initial_value_from_history_prevent_repeats( self, trans, other_values, already_used ):
"""
NOTE: This is wasteful since dynamic options and dataset collection
happens twice (here and when generating HTML).
"""
# Can't look at history in workflow mode. Tool shed has no histories.
if trans is None or trans.workflow_building_mode or trans.webapp.name == 'tool_shed':
if trans.workflow_building_mode or trans.app.name == 'tool_shed':
return DummyDataset()
history = self._get_history( trans, history )
dataset_matcher = DatasetMatcher( trans, self, None, context )
history = self._get_history( trans )
dataset_matcher = DatasetMatcher( trans, self, None, other_values )
if self.optional:
return None
most_recent_dataset = []
@@ -1994,7 +1940,7 @@ class DataToolParameter( BaseDataToolParameter ):
return None
if not value and not self.optional:
raise ValueError( "History does not include a dataset of the required format / build" )
if value in [None, "None", '']:
if value in [ None, "None", '' ]:
return None
if isinstance( value, str ) and value.find( "," ) > 0:
value = [ int( value_part ) for value_part in value.split( "," ) ]
@@ -2004,10 +1950,10 @@ class DataToolParameter( BaseDataToolParameter ):
for single_value in value:
if isinstance( single_value, dict ) and 'src' in single_value and 'id' in single_value:
if single_value['src'] == 'hda':
rval.append(trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( trans.app.security.decode_id(single_value['id']) ))
rval.append( trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( trans.security.decode_id(single_value['id']) ))
elif single_value['src'] == 'hdca':
found_hdca = True
decoded_id = trans.app.security.decode_id( single_value[ 'id' ] )
decoded_id = trans.security.decode_id( single_value[ 'id' ] )
rval.append( trans.sa_session.query( trans.app.model.HistoryDatasetCollectionAssociation ).get( decoded_id ) )
else:
raise ValueError("Unknown input source %s passed to job submission API." % single_value['src'])
@@ -2025,15 +1971,15 @@ class DataToolParameter( BaseDataToolParameter ):
rval = value
elif isinstance( value, dict ) and 'src' in value and 'id' in value:
if value['src'] == 'hda':
rval = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( trans.app.security.decode_id(value['id']) )
rval = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( trans.security.decode_id(value['id']) )
elif value['src'] == 'hdca':
decoded_id = trans.app.security.decode_id( value[ 'id' ] )
decoded_id = trans.security.decode_id( value[ 'id' ] )
rval = trans.sa_session.query( trans.app.model.HistoryDatasetCollectionAssociation ).get( decoded_id )
else:
raise ValueError("Unknown input source %s passed to job submission API." % value['src'])
elif str( value ).startswith( "__collection_reduce__|" ):
encoded_ids = [ v[ len( "__collection_reduce__|" ): ] for v in str( value ).split(",") ]
decoded_ids = map( trans.app.security.decode_id, encoded_ids )
decoded_ids = map( trans.security.decode_id, encoded_ids )
rval = []
for decoded_id in decoded_ids:
hdca = trans.sa_session.query( trans.app.model.HistoryDatasetCollectionAssociation ).get( decoded_id )
@@ -2114,9 +2060,15 @@ class DataToolParameter( BaseDataToolParameter ):
pass
return "No dataset"
def validate( self, value, history=None, workflow_building_mode=False ):
def validate( self, value, trans=None ):
dataset_count = 0
for validator in self.validators:
def do_validate( v ):
if validator.requires_dataset_metadata and v and v.dataset.state != galaxy.model.Dataset.states.OK:
return
else:
validator.validate( v, trans )
if value and self.multiple:
if not isinstance( value, list ):
value = [ value ]
@@ -2124,14 +2076,14 @@ class DataToolParameter( BaseDataToolParameter ):
if isinstance(v, galaxy.model.HistoryDatasetCollectionAssociation):
for dataset_instance in v.collection.dataset_instances:
dataset_count += 1
validator.validate( dataset_instance, history )
do_validate( dataset_instance )
else:
dataset_count += 1
validator.validate( v, history )
do_validate( v )
else:
if value:
dataset_count += 1
validator.validate( value, history )
do_validate( value )
if self.min is not None:
if self.min > dataset_count:
@@ -2214,29 +2166,27 @@ class DataToolParameter( BaseDataToolParameter ):
if history is None:
return d
# build and append a new select option
def append( list, id, hid, name, src ):
return list.append( { 'id' : trans.security.encode_id( id ), 'hid' : hid, 'name' : name, 'src' : src } )
# add datasets
visible_hda = other_values.get( self.name )
has_matched = False
for hda in history.active_datasets_children_and_roles:
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 if m.visible else '(hidden) %s' % m.name,
'src' : 'hda'
})
has_matched = has_matched or visible_hda == m
append( d[ 'options' ][ 'hda' ], m.id, m.hid, m.name if m.visible else '(hidden) %s' % m.name, 'hda' )
if not has_matched and isinstance( visible_hda, trans.app.model.HistoryDatasetAssociation ):
append( d[ 'options' ][ 'hda' ], visible_hda.id, visible_hda.hid, '(unavailable) %s' % visible_hda.name, 'hda' )
# add dataset collections
dataset_collection_matcher = DatasetCollectionMatcher( dataset_matcher )
for hdca in history.active_dataset_collections:
if dataset_collection_matcher.hdca_match( hdca, reduction=multiple ):
d['options']['hdca'].append({
'id' : trans.security.encode_id( hdca.id ),
'hid' : hdca.hid,
'name' : hdca.name,
'src' : 'hdca'
})
append( d[ 'options' ][ 'hdca' ], hdca.id, hdca.hid, hdca.name, 'hdca' )
# sort both lists
d['options']['hda'] = sorted(d['options']['hda'], key=lambda k: k['hid'], reverse=True)
@@ -2334,8 +2284,8 @@ class DataCollectionToolParameter( BaseDataToolParameter ):
name = history_dataset_collection.name
hid = str( history_dataset_collection.hid )
hidden_text = "" # TODO
subcollection_type = self._history_query( trans ).collection_type_description.collection_type
id = "%s|%s" % ( dataset_matcher.trans.security.encode_id( history_dataset_collection.id ), subcollection_type )
subcollection_type = self._history_query( trans ).can_map_over( history_dataset_collection ).collection_type
id = "%s|%s" % ( trans.security.encode_id( history_dataset_collection.id ), subcollection_type )
text = "%s:%s %s" % ( hid, hidden_text, name )
field.add_option( text, id, False )
@@ -2358,13 +2308,13 @@ class DataCollectionToolParameter( BaseDataToolParameter ):
rval = value
elif isinstance( value, dict ) and 'src' in value and 'id' in value:
if value['src'] == 'hdca':
rval = trans.sa_session.query( trans.app.model.HistoryDatasetCollectionAssociation ).get( trans.app.security.decode_id(value['id']) )
rval = trans.sa_session.query( trans.app.model.HistoryDatasetCollectionAssociation ).get( trans.security.decode_id(value['id']) )
elif isinstance( value, list ):
if len( value ) > 0:
value = value[0]
if isinstance( value, dict ) and 'src' in value and 'id' in value:
if value['src'] == 'hdca':
rval = trans.sa_session.query( trans.app.model.HistoryDatasetCollectionAssociation ).get( trans.app.security.decode_id(value['id']) )
rval = trans.sa_session.query( trans.app.model.HistoryDatasetCollectionAssociation ).get( trans.security.decode_id(value['id']) )
elif isinstance( value, basestring ):
if value.startswith( "dce:" ):
rval = trans.sa_session.query( trans.app.model.DatasetCollectionElement ).get( value[ len( "dce:"): ] )
@@ -2420,7 +2370,7 @@ class DataCollectionToolParameter( BaseDataToolParameter ):
display_text = "No dataset collection."
return display_text
def validate( self, value, history=None, workflow_building_mode=False ):
def validate( self, value, trans=None ):
return True # TODO
def to_dict( self, trans, view='collection', value_mapper=None, other_values=None ):
@@ -2449,7 +2399,7 @@ class DataCollectionToolParameter( BaseDataToolParameter ):
# append matching subcollections
for hdca in self.match_multirun_collections( trans, history, dataset_matcher ):
subcollection_type = self._history_query( trans ).collection_type_description.collection_type
subcollection_type = self._history_query( trans ).can_map_over( hdca ).collection_type
d['options']['hdca'].append({
'id': trans.security.encode_id( hdca.id ),
'hid': hdca.hid,
@@ -2476,7 +2426,7 @@ class HiddenDataToolParameter( HiddenToolParameter, DataToolParameter ):
self.type = "hidden_data"
self.hidden = True
def get_initial_value( self, trans, context, history=None ):
def get_initial_value( self, trans, other_values ):
return None
def get_html_field( self, trans=None, value=None, other_values={} ):
@@ -2496,7 +2446,7 @@ class LibraryDatasetToolParameter( ToolParameter ):
def get_html_field( self, trans=None, value=None, other_values={} ):
return form_builder.LibraryField( self.name, value=value, trans=trans )
def get_initial_value( self, trans, context, history=None ):
def get_initial_value( self, trans, other_values ):
return None
def from_html( self, value, trans, other_values={} ):
@@ -2577,59 +2527,6 @@ class LibraryDatasetToolParameter( ToolParameter ):
d['multiple'] = self.multiple
return d
def _allow_workflow_parameters_in_context(trans):
return trans is None or trans.workflow_building_mode
# class RawToolParameter( ToolParameter ):
# """
# Completely nondescript parameter, HTML representation is provided as text
# contents.
#
# >>> p = RawToolParameter( None, XML(
# ... '''
# ... <param name="blah" type="raw">
# ... <![CDATA[<span id="$name">Some random stuff</span>]]>
# ... </param>
# ... ''' ) )
# >>> print p.name
# blah
# >>> print p.get_html().strip()
# <span id="blah">Some random stuff</span>
# """
# def __init__( self, tool, elem ):
# ToolParameter.__init__( self, tool, elem )
# self.template = string.Template( elem.text )
# def get_html( self, prefix="" ):
# context = dict( self.__dict__ )
# context.update( dict( prefix=prefix ) )
# return self.template.substitute( context )
# class HistoryIDParameter( ToolParameter ):
# """
# Parameter that takes a name value, makes history.id available.
#
# FIXME: This is a hack (esp. if hidden params are a hack) but in order to
# have the history accessable at the job level, it is necessary
# I also probably wrote this docstring test thing wrong.
#
# >>> from galaxy.model import History
# >>> from galaxy.util.bunch import Bunch
# >>> hist = History( id=1 )
# >>> p = HistoryIDParameter( None, XML( '<param name="blah" type="history"/>' ) )
# >>> print p.name
# blah
# >>> html_string = '<input type="hidden" name="blah" value="%d">' % hist.id
# >>> assert p.get_html( trans=Bunch( history=hist ) ) == html_string
# """
# def __init__( self, tool, elem ):
# ToolParameter.__init__( self, tool, elem )
# def get_html( self, trans, value=None, other_values={} ):
# assert trans.history is not None, "HistoryIDParameter requires a history"
# self.html = form_builder.HiddenField( self.name, trans.history.id ).get_html()
# return self.html
parameter_types = dict(
text=TextToolParameter,
integer=IntegerToolParameter,
@@ -2651,17 +2548,6 @@ parameter_types = dict(
)
class UnvalidatedValue( object ):
"""
Wrapper to mark a value that has not been validated
"""
def __init__( self, value ):
self.value = value
def __str__( self ):
return str( self.value )
class RuntimeValue( object ):
"""
Wrapper to note a value that is not yet set, but will be required at
@@ -5,7 +5,6 @@ on the values of other parameters or other aspects of the current state)
import logging
import os
import basic
import validation
from galaxy.util import string_as_bool
from galaxy.model import User
@@ -148,7 +147,7 @@ class DataMetaFilter( Filter ):
meta_value = ref.metadata.get( self.key, None )
if meta_value is None: # assert meta_value is not None, "Required metadata value '%s' not found in referenced dataset" % self.key
return [ ( disp_name, basic.UnvalidatedValue( optval ), selected ) for disp_name, optval, selected in options ]
return [ ( disp_name, optval, selected ) for disp_name, optval, selected in options ]
if self.column is not None:
rval = []
+11 -15
View File
@@ -43,7 +43,7 @@ class Group( object, Dictifiable ):
"""
return value
def get_initial_value( self, trans, context, history=None ):
def get_initial_value( self, trans, context ):
"""
Return the initial state/value for this group
"""
@@ -120,12 +120,12 @@ class Repeat( Group ):
else:
input.visit_inputs( new_prefix, d[input.name], callback )
def get_initial_value( self, trans, context, history=None ):
def get_initial_value( self, trans, context ):
rval = []
for i in range( self.default ):
rval_dict = { '__index__': i}
for input in self.inputs.itervalues():
rval_dict[ input.name ] = input.get_initial_value( trans, context, history=history )
rval_dict[ input.name ] = input.get_initial_value( trans, context )
rval.append( rval_dict )
return rval
@@ -182,11 +182,11 @@ class Section( Group ):
else:
input.visit_inputs( prefix, value[input.name], callback )
def get_initial_value( self, trans, context, history=None ):
def get_initial_value( self, trans, context ):
rval = {}
child_context = ExpressionContext( rval, context )
for child_input in self.inputs.itervalues():
rval[ child_input.name ] = child_input.get_initial_value( trans, child_context, history=history )
rval[ child_input.name ] = child_input.get_initial_value( trans, child_context )
return rval
def to_dict( self, trans, view='collection', value_mapper=None ):
@@ -296,14 +296,14 @@ class UploadDataset( Group ):
else:
input.visit_inputs( new_prefix, d[input.name], callback )
def get_initial_value( self, trans, context, history=None ):
def get_initial_value( self, trans, context ):
d_type = self.get_datatype( trans, context )
rval = []
for i, ( composite_name, composite_file ) in enumerate( d_type.writable_files.iteritems() ):
rval_dict = {}
rval_dict['__index__'] = i # create __index__
for input in self.inputs.itervalues():
rval_dict[ input.name ] = input.get_initial_value( trans, context, history=history ) # input.value_to_basic( d[input.name], app )
rval_dict[ input.name ] = input.get_initial_value( trans, context )
rval.append( rval_dict )
return rval
@@ -323,11 +323,9 @@ class UploadDataset( Group ):
if not dataset_info:
dataset_info = 'uploaded file'
return Bunch( type='file', path=data_file['local_filename'], name=dataset_name )
# return 'file', data_file['local_filename'], get_file_name( data_file.filename ), dataset_name, dataset_info
except:
# The uploaded file should've been persisted by the upload tool action
return Bunch( type=None, path=None, name=None )
# return None, None, None, None, None
def get_url_paste_urls_or_filename( group_incoming, override_name=None, override_info=None ):
url_paste_file = group_incoming.get( 'url_paste', None )
@@ -347,7 +345,6 @@ class UploadDataset( Group ):
if not dataset_info:
dataset_info = 'uploaded url'
yield Bunch( type='url', path=line, name=dataset_name )
# yield ( 'url', line, precreated_name, dataset_name, dataset_info )
else:
dataset_name = dataset_info = precreated_name = 'Pasted Entry' # we need to differentiate between various url pastes here
if override_name:
@@ -355,7 +352,6 @@ class UploadDataset( Group ):
if override_info:
dataset_info = override_info
yield Bunch( type='file', path=url_paste_file, name=precreated_name )
# yield ( 'file', url_paste_file, precreated_name, dataset_name, dataset_info )
def get_one_filename( context ):
data_file = context['file_data']
@@ -561,7 +557,7 @@ class Conditional( Group ):
if isinstance( value, bool ):
str_value = self.test_param.to_param_dict_string( value )
else:
str_value = self.test_param.filter_value( value, trans )
str_value = value
# Find the matching case
for index, case in enumerate( self.cases ):
if str_value == case.value:
@@ -611,12 +607,12 @@ class Conditional( Group ):
else:
input.visit_inputs( prefix, value[input.name], callback )
def get_initial_value( self, trans, context, history=None ):
def get_initial_value( self, trans, context ):
# State for a conditional is a plain dictionary.
rval = {}
# Get the default value for the 'test element' and use it
# to determine the current case
test_value = self.test_param.get_initial_value( trans, context, history=history )
test_value = self.test_param.get_initial_value( trans, context )
current_case = self.get_current_case( test_value, trans )
# Store the current case in a special value
rval['__current_case__'] = current_case
@@ -625,7 +621,7 @@ class Conditional( Group ):
# Fill in state for selected case
child_context = ExpressionContext( rval, context )
for child_input in self.cases[current_case].inputs.itervalues():
rval[ child_input.name ] = child_input.get_initial_value( trans, child_context, history=history )
rval[ child_input.name ] = child_input.get_initial_value( trans, child_context )
return rval
def to_dict( self, trans, view='collection', value_mapper=None ):
+17 -18
View File
@@ -10,16 +10,11 @@ from galaxy import util
log = logging.getLogger( __name__ )
class LateValidationError( Exception ):
def __init__( self, message ):
self.message = message
class Validator( object ):
"""
A validator checks that a value meets some conditions OR raises ValueError
"""
requires_dataset_metadata = False
@classmethod
def from_element( cls, param, elem ):
@@ -27,7 +22,7 @@ class Validator( object ):
assert type is not None, "Required 'type' attribute missing from validator"
return validator_types[type].from_element( param, elem )
def validate( self, value, history=None ):
def validate( self, value, trans=None ):
raise TypeError( "Abstract Method" )
@@ -60,7 +55,7 @@ class RegexValidator( Validator ):
# the sre module.
self.expression = expression
def validate( self, value, history=None ):
def validate( self, value, trans=None ):
if re.match( self.expression, value ) is None:
raise ValueError( self.message )
@@ -94,7 +89,7 @@ class ExpressionValidator( Validator ):
# Save compiled expression, code objects are thread safe (right?)
self.expression = compile( expression, '<string>', 'eval' )
def validate( self, value, history=None ):
def validate( self, value, trans=None ):
if not( eval( self.expression, dict( value=value ) ) ):
message = self.message
if self.substitute_value_in_message:
@@ -155,7 +150,7 @@ class InRangeValidator( Validator ):
op2 = '<'
self.message = message or "Value must be %s %s and %s %s" % ( op1, self_min_str, op2, self_max_str )
def validate( self, value, history=None ):
def validate( self, value, trans=None ):
if self.exclude_min:
if not self.min < float( value ):
raise ValueError( self.message )
@@ -206,7 +201,7 @@ class LengthValidator( Validator ):
self.min = length_min
self.max = length_max
def validate( self, value, history=None ):
def validate( self, value, trans=None ):
if self.min is not None and len( value ) < self.min:
raise ValueError( self.message or ( "Must have length of at least %d" % self.min ) )
if self.max is not None and len( value ) > self.max:
@@ -225,7 +220,7 @@ class DatasetOkValidator( Validator ):
def from_element( cls, param, elem ):
return cls( elem.get( 'message', None ) )
def validate( self, value, history=None ):
def validate( self, value, trans=None ):
if value and value.state != model.Dataset.states.OK:
if self.message is None:
self.message = "The selected dataset is still being generated, select another dataset or wait until it is completed"
@@ -236,6 +231,7 @@ class MetadataValidator( Validator ):
"""
Validator that checks for missing metadata
"""
requires_dataset_metadata = True
def __init__( self, message=None, check="", skip="" ):
self.message = message
@@ -246,7 +242,7 @@ class MetadataValidator( Validator ):
def from_element( cls, param, elem ):
return cls( message=elem.get( 'message', None ), check=elem.get( 'check', "" ), skip=elem.get( 'skip', "" ) )
def validate( self, value, history=None ):
def validate( self, value, trans=None ):
if value:
if not isinstance( value, model.DatasetInstance ):
raise ValueError( 'A non-dataset value was provided.' )
@@ -260,6 +256,7 @@ class UnspecifiedBuildValidator( Validator ):
"""
Validator that checks for dbkey not equal to '?'
"""
requires_dataset_metadata = True
def __init__( self, message=None ):
if message is None:
@@ -271,7 +268,7 @@ class UnspecifiedBuildValidator( Validator ):
def from_element( cls, param, elem ):
return cls( elem.get( 'message', None ) )
def validate( self, value, history=None ):
def validate( self, value, trans=None ):
# if value is None, we cannot validate
if value:
dbkey = value.metadata.dbkey
@@ -291,7 +288,7 @@ class NoOptionsValidator( Validator ):
def from_element( cls, param, elem ):
return cls( elem.get( 'message', None ) )
def validate( self, value, history=None ):
def validate( self, value, trans=None ):
if value is None:
if self.message is None:
self.message = "No options available for selection"
@@ -308,7 +305,7 @@ class EmptyTextfieldValidator( Validator ):
def from_element( cls, param, elem ):
return cls( elem.get( 'message', None ) )
def validate( self, value, history=None ):
def validate( self, value, trans=None ):
if value == '':
if self.message is None:
self.message = "Field requires a value"
@@ -319,6 +316,7 @@ class MetadataInFileColumnValidator( Validator ):
"""
Validator that checks if the value for a dataset's metadata item exists in a file.
"""
requires_dataset_metadata = True
@classmethod
def from_element( cls, param, elem ):
@@ -345,7 +343,7 @@ class MetadataInFileColumnValidator( Validator ):
if metadata_column < len( fields ):
self.valid_values.append( fields[metadata_column].strip() )
def validate( self, value, history=None ):
def validate( self, value, trans=None ):
if not value:
return
if hasattr( value, "metadata" ):
@@ -358,6 +356,7 @@ class MetadataInDataTableColumnValidator( Validator ):
"""
Validator that checks if the value for a dataset's metadata item exists in a file.
"""
requires_dataset_metadata = True
@classmethod
def from_element( cls, param, elem ):
@@ -396,7 +395,7 @@ class MetadataInDataTableColumnValidator( Validator ):
if self._metadata_column < len( fields ):
self.valid_values.append( fields[ self._metadata_column ] )
def validate( self, value, history=None ):
def validate( self, value, trans=None ):
if not value:
return
if hasattr( value, "metadata" ):
+3 -1
View File
@@ -58,7 +58,8 @@ class WrappedParameters( object ):
value = input_values[ input.name ]
dataset_instances = DatasetListWrapper.to_dataset_instances( value )
input_values[ input.name ] = \
DatasetListWrapper( dataset_instances,
DatasetListWrapper( None,
dataset_instances,
datatypes_registry=trans.app.datatypes_registry,
tool=tool,
name=input.name )
@@ -72,6 +73,7 @@ class WrappedParameters( object ):
input_values[ input.name ] = SelectToolParameterWrapper( input, input_values[ input.name ], tool.app, other_values=incoming )
elif isinstance( input, DataCollectionToolParameter ):
input_values[ input.name ] = DatasetCollectionWrapper(
None,
input_values[ input.name ],
datatypes_registry=trans.app.datatypes_registry,
tool=tool,
+1 -1
View File
@@ -10,4 +10,4 @@ SPECIAL_TOOLS = {
def load_lib_tools( toolbox ):
for name, path in SPECIAL_TOOLS.items():
tool = toolbox.load_hidden_lib_tool( path )
log.debug( "Loaded %s tool: %s", ( name, tool.id ) )
log.debug( "Loaded %s tool: %s", name, tool.id )
+1
View File
@@ -220,6 +220,7 @@ class AbstractToolBox( Dictifiable, ManagesIntegratedToolPanelMixin, object ):
tool_section = ToolSection( section_dict )
self._tool_panel.append_section( tool_panel_section_key, tool_section )
log.debug( "Loading new tool panel section: %s" % str( tool_section.name ) )
self._save_integrated_tool_panel()
else:
tool_section = None
return tool_panel_section_key, tool_section
+14 -3
View File
@@ -1,4 +1,6 @@
import os
import pipes
import tempfile
from galaxy import exceptions
from galaxy.util.none_like import NoneDataset
from galaxy.util import odict
@@ -263,11 +265,18 @@ class HasDatasets:
wrapper_kwds[ "dataset_path" ] = dataset_paths[ real_path ]
return DatasetFilenameWrapper( dataset, **wrapper_kwds )
def paths_as_file(self, sep="\n"):
handle, filepath = tempfile.mkstemp(prefix="gx_file_list", dir=self.job_working_directory)
contents = sep.join(map(str, self))
os.write(handle, contents)
os.close(handle)
return filepath
class DatasetListWrapper( list, ToolParameterValueWrapper, HasDatasets ):
"""
"""
def __init__( self, datasets, dataset_paths=[], **kwargs ):
def __init__( self, job_working_directory, datasets, dataset_paths=[], **kwargs ):
if not isinstance(datasets, list):
datasets = [datasets]
@@ -279,6 +288,7 @@ class DatasetListWrapper( list, ToolParameterValueWrapper, HasDatasets ):
return self._dataset_wrapper( dataset, dataset_paths, **kwargs )
list.__init__( self, map( to_wrapper, datasets ) )
self.job_working_directory = job_working_directory
@staticmethod
def to_dataset_instances( dataset_instance_sources ):
@@ -300,8 +310,9 @@ class DatasetListWrapper( list, ToolParameterValueWrapper, HasDatasets ):
class DatasetCollectionWrapper( ToolParameterValueWrapper, HasDatasets ):
def __init__( self, has_collection, dataset_paths=[], **kwargs ):
def __init__( self, job_working_directory, has_collection, dataset_paths=[], **kwargs ):
super(DatasetCollectionWrapper, self).__init__()
self.job_working_directory = job_working_directory
if has_collection is None:
self.__input_supplied = False
@@ -330,7 +341,7 @@ class DatasetCollectionWrapper( ToolParameterValueWrapper, HasDatasets ):
element_identifier = dataset_collection_element.element_identifier
if dataset_collection_element.is_collection:
element_wrapper = DatasetCollectionWrapper( dataset_collection_element, dataset_paths, **kwargs )
element_wrapper = DatasetCollectionWrapper(job_working_directory, dataset_collection_element, dataset_paths, **kwargs )
else:
element_wrapper = self._dataset_wrapper( element_object, dataset_paths, **kwargs)
+15
View File
@@ -568,6 +568,21 @@ def which(file):
return None
def safe_makedirs(path):
""" Safely make a directory, do not fail if it already exist or
is created during execution.
"""
if not os.path.exists(path):
try:
os.makedirs(path)
except OSError as e:
# review source for Python 2.7 this would only ever happen
# for the last path anyway so need to recurse - this exception
# means the last part of the path was already in existence.
if e.errno != errno.EEXIST:
raise
def in_directory( file, directory, local_path_module=os.path ):
"""
Return true, if the common prefix of both is equal to directory
+64 -43
View File
@@ -33,59 +33,77 @@ class Heartbeat( threading.Thread ):
"""
Thread that periodically dumps the state of all threads to a file
"""
def __init__( self, name="Heartbeat Thread", period=20, fname="heartbeat.log" ):
def __init__( self, config, name="Heartbeat Thread", period=20, fname="heartbeat.log" ):
threading.Thread.__init__( self, name=name )
self.config = config
self.should_stop = False
self.period = period
self.fname = fname
self.file = None
self.fname_nonsleeping = fname + ".nonsleeping"
self.fname_nonsleeping = None
self.file_nonsleeping = None
self.pid = None
self.nonsleeping_heartbeats = { }
# Save process id
self.pid = os.getpid()
# Event to wait on when sleeping, allows us to interrupt for shutdown
self.wait_event = threading.Event()
def run( self ):
self.file = open( self.fname, "a" )
print >> self.file, "Heartbeat for pid %d thread started at %s" % ( self.pid, time.asctime() )
print >> self.file
self.file_nonsleeping = open( self.fname_nonsleeping, "a" )
print >> self.file_nonsleeping, "Non-Sleeping-threads for pid %d thread started at %s" % ( self.pid, time.asctime() )
print >> self.file_nonsleeping
try:
while not self.should_stop:
# Print separator with timestamp
print >> self.file, "Traceback dump for all threads at %s:" % time.asctime()
print >> self.file
# Print the thread states
threads = get_current_thread_object_dict()
for thread_id, frame in iteritems(sys._current_frames()):
if thread_id in threads:
object = repr( threads[thread_id] )
else:
object = "<No Thread object>"
print >> self.file, "Thread %s, %s:" % ( thread_id, object )
print >> self.file
traceback.print_stack( frame, file=self.file )
print >> self.file
print >> self.file, "End dump"
print >> self.file
self.file.flush()
self.print_nonsleeping(threads)
# Sleep for a bit
self.wait_event.wait( self.period )
finally:
print >> self.file, "Heartbeat for pid %d thread stopped at %s" % ( self.pid, time.asctime() )
print >> self.file
# Cleanup
self.pid = os.getpid()
self.fname = self.fname.format(
server_name=self.config.server_name,
pid=self.pid
)
fname, ext = os.path.splitext(self.fname)
self.fname_nonsleeping = fname + '.nonsleeping' + ext
wait = self.period
if self.period <= 0:
wait = 60
while not self.should_stop:
if self.period > 0:
self.dump()
self.wait_event.wait( wait )
def open_logs( self ):
if self.file is None or self.file.closed:
self.file = open( self.fname, "a" )
self.file_nonsleeping = open( self.fname_nonsleeping, "a" )
self.file.write( "Heartbeat for pid %d thread started at %s\n\n" % ( self.pid, time.asctime() ) )
self.file_nonsleeping.write( "Non-Sleeping-threads for pid %d thread started at %s\n\n" % ( self.pid, time.asctime() ) )
def close_logs( self ):
if self.file is not None and not self.file.closed:
self.file.write( "Heartbeat for pid %d thread stopped at %s\n\n" % ( self.pid, time.asctime() ) )
self.file_nonsleeping.write( "Non-Sleeping-threads for pid %d thread stopped at %s\n\n" % ( self.pid, time.asctime() ) )
self.file.close()
self.file_nonsleeping.close()
def dump( self ):
self.open_logs()
try:
# Print separator with timestamp
self.file.write( "Traceback dump for all threads at %s:\n\n" % time.asctime() )
# Print the thread states
threads = get_current_thread_object_dict()
for thread_id, frame in iteritems(sys._current_frames()):
if thread_id in threads:
object = repr( threads[thread_id] )
else:
object = "<No Thread object>"
self.file.write( "Thread %s, %s:\n\n" % ( thread_id, object ) )
traceback.print_stack( frame, file=self.file )
self.file.write( "\n" )
self.file.write( "End dump\n\n" )
self.file.flush()
self.print_nonsleeping(threads)
except:
self.file.write( "Caught exception attempting to dump thread states:" )
traceback.print_exc( None, self.file )
self.file.write( "\n" )
def shutdown( self ):
self.should_stop = True
self.wait_event.set()
self.close_logs()
self.join()
def thread_is_sleeping( self, last_stack_frame ):
@@ -107,7 +125,8 @@ class Heartbeat( threading.Thread ):
return True
if _funcname == "accept" and _text[-14:] == "_sock.accept()":
return True
if _funcname == "monitor" and _text.startswith("time.sleep( ") and _text.endswith(" )"):
if _funcname in ("monitor", "__monitor", "app_loop", "check") \
and _text.startswith("time.sleep(") and _text.endswith(")"):
return True
if _funcname == "drain_events" and _text == "sleep(polling_interval)":
return True
@@ -139,8 +158,7 @@ class Heartbeat( threading.Thread ):
return stack_frames[-1]
def print_nonsleeping( self, threads_object_dict ):
print >> self.file_nonsleeping, "Non-Sleeping threads at %s:" % time.asctime()
print >> self.file_nonsleeping
self.file_nonsleeping.write( "Non-Sleeping threads at %s:\n\n" % time.asctime() )
all_threads_are_sleeping = True
threads = get_current_thread_object_dict()
for thread_id, frame in iteritems(sys._current_frames()):
@@ -161,11 +179,14 @@ class Heartbeat( threading.Thread ):
self.nonsleeping_heartbeats[thread_id] = 1
good_frame = self.get_interesting_stack_frame(tb)
print >> self.file_nonsleeping, "Thread %s\t%s\tnon-sleeping for %d heartbeat(s)\n File %s:%d\n Function \"%s\"\n %s" % \
( thread_id, object, self.nonsleeping_heartbeats[thread_id], good_frame[0], good_frame[1], good_frame[2], good_frame[3] )
self.file_nonsleeping.write( "Thread %s\t%s\tnon-sleeping for %d heartbeat(s)\n File %s:%d\n Function \"%s\"\n %s\n" %
( thread_id, object, self.nonsleeping_heartbeats[thread_id], good_frame[0], good_frame[1], good_frame[2], good_frame[3] ) )
all_threads_are_sleeping = False
if all_threads_are_sleeping:
print >> self.file_nonsleeping, "All threads are sleeping."
print >> self.file_nonsleeping
self.file_nonsleeping.write( "All threads are sleeping.\n" )
self.file_nonsleeping.write( "\n" )
self.file_nonsleeping.flush()
def dump_signal_handler( self, signum, frame ):
self.dump()
@@ -847,11 +847,11 @@ class BamDataProvider( GenomeDataProvider, FilterableMixin ):
"""
# Open current BAM file using index.
bamfile = pysam.AlignmentFile( filename=self.original_dataset.file_name, mode='rb',
bamfile = pysam.AlignmentFile( self.original_dataset.file_name, mode='rb',
index_filename=self.converted_dataset.file_name )
# TODO: write headers as well?
new_bamfile = pysam.AlignmentFile( template=bamfile, filename=filename, mode='wb' )
new_bamfile = pysam.AlignmentFile( filename, template=bamfile, mode='wb' )
for region in regions:
# Write data from region.
@@ -879,7 +879,7 @@ class BamDataProvider( GenomeDataProvider, FilterableMixin ):
def open_data_file( self ):
# Attempt to open the BAM file with index
return pysam.AlignmentFile( filename=self.original_dataset.file_name, mode='rb',
return pysam.AlignmentFile( self.original_dataset.file_name, mode='rb',
index_filename=self.converted_dataset.file_name )
def get_iterator( self, data_file, chrom, start, end, **kwargs ):
@@ -84,6 +84,8 @@ class FolderContentsController( BaseAPIController, UsesLibraryMixin, UsesLibrary
can_modify = is_admin or ( trans.user and trans.app.security_agent.can_modify_library_item( current_user_roles, folder ) )
can_manage = is_admin or ( trans.user and trans.app.security_agent.can_manage_library_item( current_user_roles, folder ) )
return_item.update( dict( can_modify=can_modify, can_manage=can_manage ) )
if content_item.description:
return_item.update( dict( description=content_item.description ) )
if content_item.api_type == 'file':
# Is the dataset public or private?
@@ -107,7 +109,10 @@ class FolderContentsController( BaseAPIController, UsesLibraryMixin, UsesLibrary
is_unrestricted=is_unrestricted,
is_private=is_private,
can_manage=can_manage,
file_size=nice_size ) )
file_size=nice_size
) )
if content_item.library_dataset_dataset_association.message:
return_item.update( dict( message=content_item.library_dataset_dataset_association.message ) )
# For every item include the default metadata
return_item.update( dict( id=encoded_id,
@@ -392,6 +392,8 @@ class LibraryDatasetsController( BaseAPIController, UsesVisualizationMixin ):
trans.sa_session.flush()
rval = trans.security.encode_all_ids( dataset.to_dict() )
nice_size = util.nice_size( int( dataset.library_dataset_dataset_association.get_size() ) )
rval[ 'file_size' ] = nice_size
rval[ 'update_time' ] = dataset.update_time.strftime( "%Y-%m-%d %I:%M %p" )
rval[ 'deleted' ] = dataset.deleted
rval[ 'folder_id' ] = 'F' + rval[ 'folder_id' ]
@@ -488,16 +490,15 @@ class LibraryDatasetsController( BaseAPIController, UsesVisualizationMixin ):
kwd[ 'filesystem_paths' ] = path
if source in [ 'importdir_folder' ]:
kwd[ 'filesystem_paths' ] = os.path.join( import_base_dir, path )
params = util.Params( kwd )
# user wants to import one file only
if source in [ "userdir_file", "importdir_file" ]:
file = os.path.abspath( path )
abspath_datasets.append( trans.webapp.controllers[ 'library_common' ].make_library_uploaded_dataset(
trans, 'api', params, os.path.basename( file ), file, 'server_dir', library_bunch ) )
trans, 'api', kwd, os.path.basename( file ), file, 'server_dir', library_bunch ) )
# user wants to import whole folder
if source == "userdir_folder":
uploaded_datasets_bunch = trans.webapp.controllers[ 'library_common' ].get_path_paste_uploaded_datasets(
trans, 'api', params, library_bunch, 200, '' )
trans, 'api', kwd, library_bunch, 200, '' )
uploaded_datasets = uploaded_datasets_bunch[ 0 ]
if uploaded_datasets is None:
raise exceptions.ObjectNotFound( 'Given folder does not contain any datasets.' )
@@ -508,7 +509,7 @@ class LibraryDatasetsController( BaseAPIController, UsesVisualizationMixin ):
if source in [ "admin_path", "importdir_folder" ]:
# validate the path is within root
uploaded_datasets_bunch = trans.webapp.controllers[ 'library_common' ].get_path_paste_uploaded_datasets(
trans, 'api', params, library_bunch, 200, '' )
trans, 'api', kwd, library_bunch, 200, '' )
uploaded_datasets = uploaded_datasets_bunch[0]
if uploaded_datasets is None:
raise exceptions.ObjectNotFound( 'Given folder does not contain any datasets.' )
@@ -79,7 +79,7 @@ class User( BaseUIController, UsesFormDefinitionsMixin, CreatesUsersMixin, Creat
installed_len_files = None
@web.expose
def index( self, trans, cntrller, **kwd ):
def index( self, trans, cntrller='user', **kwd ):
return trans.fill_template( '/user/index.mako', cntrller=cntrller )
@web.expose
+2 -1
View File
@@ -18,12 +18,13 @@ class WorkRequestContext( ProvidesAppContext, ProvidesUserContext, ProvidesHisto
objects.
"""
def __init__( self, app, user=None, history=None ):
def __init__( self, app, user=None, history=None, workflow_building_mode=False ):
self.app = app
self.security = app.security
self.__user = user
self.__history = history
self.api_inherit_admin = False
self.workflow_building_mode = workflow_building_mode
def get_history( self, create=False ):
if create:
+1 -7
View File
@@ -6,10 +6,7 @@ from galaxy import exceptions
from galaxy import model
from galaxy.tools.parameters.basic import (
DataToolParameter,
DataCollectionToolParameter,
DrillDownSelectToolParameter,
SelectToolParameter,
UnvalidatedValue
DataCollectionToolParameter
)
from galaxy.tools.parser import ToolOutputCollectionPart
from galaxy.tools.parameters.grouping import (
@@ -317,9 +314,6 @@ def __cleanup_param_values( inputs, values ):
# Recursively clean data inputs and dynamic selects
def cleanup( prefix, inputs, values ):
for key, input in inputs.items():
if isinstance( input, ( SelectToolParameter, DrillDownSelectToolParameter ) ):
if input.is_dynamic and not isinstance( values[key], UnvalidatedValue ):
values[key] = UnvalidatedValue( values[key] )
if isinstance( input, DataToolParameter ) or isinstance( input, DataCollectionToolParameter ):
tmp = values[key]
values[key] = None
+1 -1
View File
@@ -1080,7 +1080,7 @@ class ToolModule( WorkflowModule ):
def check_and_update_state( self ):
inputs = self.state.inputs
return self.tool.check_and_update_param_values( inputs, self.trans, allow_workflow_parameters=True )
return self.tool.check_and_update_param_values( inputs, self.trans, workflow_building_mode=True )
def compute_runtime_state( self, trans, step_updates=None, source="html" ):
# Warning: This method destructively modifies existing step state.
+2 -1
View File
@@ -156,7 +156,8 @@ class WorkflowRequestMonitor( object ):
return
self.__schedule( workflow_scheduler_id, workflow_scheduler )
time.sleep(1) # TODO: wake if stopped
# TODO: wake if stopped
time.sleep(1)
def __schedule( self, workflow_scheduler_id, workflow_scheduler ):
invocation_ids = self.__active_invocation_ids( workflow_scheduler_id )
@@ -834,6 +834,7 @@ class InstallRepositoryManager( object ):
def install_tool_shed_repository( self, tool_shed_repository, repo_info_dict, tool_panel_section_key, shed_tool_conf, tool_path,
install_tool_dependencies, reinstalling=False ):
self.app.install_model.context.flush()
if tool_panel_section_key:
_, tool_section = self.app.toolbox.get_section( tool_panel_section_key )
if tool_section is None:
+67 -42
View File
@@ -35,7 +35,13 @@ RELEASES = [
]
# Uncredit pull requestors... kind of arbitrary at this point.
DEVTEAM = ["afgane", "dannon", "blankenberg", "davebx", "martenson", "jmchilton", "tnabtaf", "natefoo", "carlfeberhard", "jgoecks", "guerler", "jennaj", "nekrut", "jxtx", "nitesh1989"]
DEVTEAM = [
"afgane", "dannon", "blankenberg",
"davebx", "martenson", "jmchilton",
"tnabtaf", "natefoo", "carlfeberhard",
"jgoecks", "guerler", "jennaj",
"nekrut", "jxtx", "nitesh1989"
]
TEMPLATE = """
.. to_doc
@@ -44,23 +50,36 @@ TEMPLATE = """
%s
-------------------------------
.. announce_start
Enhancements
-------------------------------
.. enhancements
.. major_feature
.. feature
.. enhancement
.. small_enhancement
Fixes
-------------------------------
.. major_bug
.. fixes
.. bug
.. github_links
"""
# TODO: for 15.10 use this template...
ANNOUNCE_TEMPLATE = string.Template("""
===========================================================
${month_name} 20${year} Galaxy Release (v ${release})
@@ -115,7 +134,7 @@ Release Notes
===========================================================
.. include:: ${release}.rst
:start-after: enhancements
:start-after: announce_start
.. include:: _thanks.rst
""")
@@ -167,7 +186,7 @@ def do_release(argv):
else:
next_year = year
next_version = "%s.%02d" % (next_year, next_month)
first_of_next_month = datetime.date(next_year + 2000, next_month, 1)
first_of_next_month = datetime.date(int(next_year) + 2000, next_month, 1)
freeze_date = next_weekday(first_of_next_month, 0)
release_date = next_weekday(first_of_next_month, 0) + datetime.timedelta(21)
@@ -181,34 +200,11 @@ def do_release(argv):
)
open(next_release_file, "w").write(next_announce.encode("utf-8"))
release_commit_start = None
release_commit_end = None
for i, release_info in enumerate(RELEASES):
if release_name == release_info[0]:
release_commit_start = release_info[1]
release_commit_end = RELEASES[i + 1][1]
if release_commit_start is None:
raise Exception("Failed to find information for version %s" % release_name)
start_release_time = commit_time(release_commit_start)
end_release_time = commit_time(release_commit_end)
for page in _get_prs():
for pr in page:
base_label = pr.base['label']
if base_label == "galaxyproject:dev":
merged_at = pr.merged_at
if merged_at is None:
continue
before_branch = merged_at < start_release_time
after_branch = merged_at > end_release_time
print "%s %s %s" % (merged_at, start_release_time, end_release_time)
if before_branch or after_branch:
print "SKIPPING"
continue
elif base_label != "galaxyproject:release_%s" % release_name:
merged_at = pr.merged_at
milestone = pr.milestone
if not merged_at or not milestone or milestone['title'] != release_name:
continue
# 2015-06-29 18:32:13 2015-04-22 19:11:53 2015-08-12 21:15:45
as_dict = {
@@ -221,7 +217,11 @@ def do_release(argv):
def _get_prs():
github = _github_client()
pull_requests = github.pull_requests.list(state='closed', user=PROJECT_OWNER, repo=PROJECT_NAME)
pull_requests = github.pull_requests.list(
state='closed',
user=PROJECT_OWNER,
repo=PROJECT_NAME,
)
return pull_requests
@@ -305,22 +305,47 @@ def main(argv):
labels = github.issues.labels.list_by_issue(int(pull_request), user=PROJECT_OWNER, repo=PROJECT_NAME)
except Exception:
pass
is_bug = is_enhancement = is_minor = False
is_bug = is_enhancement = is_feature = is_minor = is_major = is_merge = is_small_enhancement = False
for label in labels:
if label.name.lower() == "minor":
label_name = label.name.lower()
if label_name == "minor":
is_minor = True
if label.name.lower() == "bug":
elif label_name == "major":
is_major = True
elif label_name == "merge":
is_merge = True
elif label_name == "kind/bug":
is_bug = True
if label.name.lower() == "enhancement":
elif label_name == "kind/feature":
is_feature = True
elif label_name == "kind/enhancement":
is_enhancement = True
if is_minor:
elif label_name in ["kind/testing", "kind/refactoring"]:
is_small_enhancement = True
is_some_kind_of_enhancement = is_enhancement or is_feature or is_small_enhancement
if not( is_bug or is_some_kind_of_enhancement or is_minor or is_merge ):
print "No kind/ or minor or merge label found for %s" % pull_request
text_target = None
if is_minor or is_merge:
return
if is_enhancement:
text_target = "enhancements"
if is_some_kind_of_enhancement and is_major:
text_target = "major_feature"
elif is_feature:
text_target = "feature"
elif is_enhancement:
text_target = "enhancement"
elif is_some_kind_of_enhancement:
text_target = "small_enhancement"
elif is_major:
text_target = "major_bug"
elif is_bug:
text_target = "fixes"
text_target = "bug"
else:
print "Problem not label for %s" % pull_request
print "Logic problem, cannot determine section for %s" % pull_request
text_target = None
elif ident.startswith("issue"):
issue = ident[len("issue"):]
+29 -2
View File
@@ -1,11 +1,18 @@
#!/bin/bash
set -e
GXPIP_VERSION='8.0.2+gx2'
SET_VENV=1
for arg in "$@"; do
[ "$arg" = "--skip-venv" ] && SET_VENV=0
done
# Conda Python is in use, do not use virtualenv
if python -V 2>&1 | grep -q 'Continuum Analytics'; then
SET_VENV=0
fi
DEV_WHEELS=0
FETCH_WHEELS=1
CREATE_VENV=1
@@ -132,8 +139,28 @@ fi
: ${GALAXY_WHEELS_INDEX_URL:="https://wheels.galaxyproject.org/simple"}
if [ $REPLACE_PIP -eq 1 ]; then
pip_version=`pip --version | awk '{print $2}'`
pre=`python -c "from pkg_resources import parse_version; from sys import stdout; stdout.write('--pre') if parse_version('$pip_version') >= parse_version('1.4') else stdout.write('')"`
pip install $pre --no-index --find-links ${GALAXY_WHEELS_INDEX_URL}/pip --upgrade pip
method=`python - << EOF
from pkg_resources import parse_version
from sys import stdout
if parse_version('$pip_version') >= parse_version('6.0'):
stdout.write('req')
elif parse_version('$pip_version') >= parse_version('1.5'):
stdout.write('wheel')
else:
stdout.write('sdist')
EOF`
case $method in
req)
pip install --no-index --find-links ${GALAXY_WHEELS_INDEX_URL}/pip --upgrade "pip==${GXPIP_VERSION}"
;;
wheel)
pip install --upgrade "https://wheels.galaxyproject.org/packages/pip-${GXPIP_VERSION}-py2.py3-none-any.whl"
;;
sdist)
pip install --upgrade "https://wheels.galaxyproject.org/packages/pip-${GXPIP_VERSION}.tar.gz"
;;
esac
# binary-compatibility.cfg may need to be created (e.g. on CentOS)
[ -n "$VIRTUAL_ENV" -a ! -f ${VIRTUAL_ENV}/binary-compatibility.cfg ] && python ./scripts/binary_compatibility.py -o ${VIRTUAL_ENV}/binary-compatibility.cfg
fi
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"page.js","sources":["../../src/layout/page.js"],"names":["define","Masthead","Panel","Modal","BaseMVC","PageLayoutView","Backbone","View","extend","LoggableMixin","_logNamespace","el","className","_panelIds","defaultOptions","message_box_visible","message_box_content","message_box_class","show_inactivity_warning","inactivity_box_content","initialize","options","this","log","_","pick","defaults","omit","Galaxy","modal","masthead","config","$el","attr","append","_template","$messagebox","$","$inactivebox","render","remove","renderMessageBox","renderInactivityBox","renderPanels","content","level","addClass","html","toggle","show","removeClass","hide","verificationLink","root","page","forEach","panelId","has","setElement","center","join","toString"],"mappings":"AAAAA,QACI,kBACA,eACA,kBACA,gBACD,SAAUC,EAAUC,EAAOC,EAAOC,GAGrC,GAAIC,GAAiBC,SAASC,KAAKC,OAAQJ,EAAQK,eAAgBD,QAC/DE,cAAgB,SAEhBC,GAAK,OACLC,UAAY,eAEZC,WACI,OAAQ,SAAU,SAGtBC,gBACIC,qBAA0B,EAC1BC,oBAA0B,GAC1BC,kBAA0B,OAC1BC,yBAA0B,EAC1BC,uBAA0B,IAG9BC,WAAa,SAAUC,GAEnBC,KAAKC,IAAKD,KAAO,eAAgBD,GACjCG,EAAEhB,OAAQc,KAAME,EAAEC,KAAMJ,EAASC,KAAKT,YACtCS,KAAKD,QAAUG,EAAEE,SAAUF,EAAEG,KAAMN,EAASC,KAAKT,WAAaS,KAAKR,gBACnEc,OAAOC,MAAQP,KAAKO,MAAQ,GAAI1B,GAAMI,KACtCe,KAAKQ,SAAW,GAAI7B,GAASM,KAAMe,KAAKD,QAAQU,QAChDT,KAAKU,IAAIC,KAAM,SAAU,MACzBX,KAAKU,IAAIE,OAAQZ,KAAKa,aACtBb,KAAKU,IAAIE,OAAQZ,KAAKQ,SAASE,KAC/BV,KAAKU,IAAIE,OAAQZ,KAAKO,MAAMG,KAC5BV,KAAKc,YAAcd,KAAKe,EAAG,eAC3Bf,KAAKgB,aAAehB,KAAKe,EAAG,iBAGhCE,OAAS,WAQL,MANAF,GAAG,8BAA+BG,SAClClB,KAAKC,IAAKD,KAAO,YACjBA,KAAKQ,SAASS,SACdjB,KAAKmB,mBACLnB,KAAKoB,sBACLpB,KAAKqB,eACErB,MAIXmB,iBAAmB,WACf,GAAKnB,KAAKD,QAAQN,oBAAqB,CACnC,GAAI6B,GAAUtB,KAAKD,QAAQL,qBAAuB,GAC9C6B,EAAQvB,KAAKD,QAAQJ,mBAAqB,MAC9CK,MAAKU,IAAIc,SAAU,mBACnBxB,KAAKc,YACAH,KAAM,QAAS,SAAWY,EAAQ,YAClCE,KAAMH,GACNI,SAAUJ,GACVK,WAEL3B,MAAKU,IAAIkB,YAAa,mBACtB5B,KAAKc,YAAYe,MAErB,OAAO7B,OAIXoB,oBAAsB,WAClB,GAAIpB,KAAKD,QAAQH,wBAAyB,CACtC,GAAI0B,GAAUtB,KAAKD,QAAQF,wBAA0B,GACjDiC,EAAmBf,EAAG,QAASJ,KAAM,OAAQL,OAAOyB,KAAO,4BAA6BN,KAAM,uBAClGzB,MAAKU,IAAIc,SAAU,sBACnBxB,KAAKgB,aACAS,KAAMH,GACNV,OAAQ,IAAMkB,GACdJ,SAAUJ,GACVK,WAEL3B,MAAKU,IAAIkB,YAAa,sBACtB5B,KAAKgB,aAAaa,MAEtB,OAAO7B,OAIXqB,aAAe,WACX,GAAIW,GAAOhC,IASX,OARAA,MAAKT,UAAU0C,QAAS,SAAUC,GAC1BhC,EAAEiC,IAAKH,EAAME,IACbF,EAAME,GAAUE,WAAY,IAAMF,GAClCF,EAAME,GAAUjB,UACI,WAAZiB,GACRF,EAAKK,OAAO3B,IAAKwB,EAAS,KAG3BlC,MAIXa,UAAW,WACP,OACI,wBACI,yBACA,yBACA,wDACA,mBACA,qCACA,oBACJ,SACA,wBACA,aACI,4DACI,QACI,wDACA,QACI,gFACA,iDACJ,SACJ,SACJ,SACJ,eACFyB,KAAK,KAGXC,SAAW,WAAa,MAAO,mBAI/B,QACIxD,eAAgBA"}
{"version":3,"file":"page.js","sources":["../../src/layout/page.js"],"names":["define","Masthead","Panel","Modal","BaseMVC","PageLayoutView","Backbone","View","extend","LoggableMixin","_logNamespace","el","className","_panelIds","defaultOptions","message_box_visible","message_box_content","message_box_class","show_inactivity_warning","inactivity_box_content","initialize","options","this","log","_","pick","defaults","omit","Galaxy","modal","masthead","config","$el","attr","append","_template","$messagebox","$","$inactivebox","render","remove","renderMessageBox","renderInactivityBox","renderPanels","content","level","addClass","html","toggle","show","removeClass","hide","verificationLink","root","page","forEach","panelId","has","setElement","center","css","join","toString"],"mappings":"AAAAA,QACI,kBACA,eACA,kBACA,gBACD,SAAUC,EAAUC,EAAOC,EAAOC,GAGrC,GAAIC,GAAiBC,SAASC,KAAKC,OAAQJ,EAAQK,eAAgBD,QAC/DE,cAAgB,SAEhBC,GAAK,OACLC,UAAY,eAEZC,WACI,OAAQ,SAAU,SAGtBC,gBACIC,qBAA0B,EAC1BC,oBAA0B,GAC1BC,kBAA0B,OAC1BC,yBAA0B,EAC1BC,uBAA0B,IAG9BC,WAAa,SAAUC,GAEnBC,KAAKC,IAAKD,KAAO,eAAgBD,GACjCG,EAAEhB,OAAQc,KAAME,EAAEC,KAAMJ,EAASC,KAAKT,YACtCS,KAAKD,QAAUG,EAAEE,SAAUF,EAAEG,KAAMN,EAASC,KAAKT,WAAaS,KAAKR,gBACnEc,OAAOC,MAAQP,KAAKO,MAAQ,GAAI1B,GAAMI,KACtCe,KAAKQ,SAAW,GAAI7B,GAASM,KAAMe,KAAKD,QAAQU,QAChDT,KAAKU,IAAIC,KAAM,SAAU,MACzBX,KAAKU,IAAIE,OAAQZ,KAAKa,aACtBb,KAAKU,IAAIE,OAAQZ,KAAKQ,SAASE,KAC/BV,KAAKU,IAAIE,OAAQZ,KAAKO,MAAMG,KAC5BV,KAAKc,YAAcd,KAAKe,EAAG,eAC3Bf,KAAKgB,aAAehB,KAAKe,EAAG,iBAGhCE,OAAS,WAQL,MANAF,GAAG,8BAA+BG,SAClClB,KAAKC,IAAKD,KAAO,YACjBA,KAAKQ,SAASS,SACdjB,KAAKmB,mBACLnB,KAAKoB,sBACLpB,KAAKqB,eACErB,MAIXmB,iBAAmB,WACf,GAAKnB,KAAKD,QAAQN,oBAAqB,CACnC,GAAI6B,GAAUtB,KAAKD,QAAQL,qBAAuB,GAC9C6B,EAAQvB,KAAKD,QAAQJ,mBAAqB,MAC9CK,MAAKU,IAAIc,SAAU,mBACnBxB,KAAKc,YACAH,KAAM,QAAS,SAAWY,EAAQ,YAClCE,KAAMH,GACNI,SAAUJ,GACVK,WAEL3B,MAAKU,IAAIkB,YAAa,mBACtB5B,KAAKc,YAAYe,MAErB,OAAO7B,OAIXoB,oBAAsB,WAClB,GAAIpB,KAAKD,QAAQH,wBAAyB,CACtC,GAAI0B,GAAUtB,KAAKD,QAAQF,wBAA0B,GACjDiC,EAAmBf,EAAG,QAASJ,KAAM,OAAQL,OAAOyB,KAAO,4BAA6BN,KAAM,uBAClGzB,MAAKU,IAAIc,SAAU,sBACnBxB,KAAKgB,aACAS,KAAMH,GACNV,OAAQ,IAAMkB,GACdJ,SAAUJ,GACVK,WAEL3B,MAAKU,IAAIkB,YAAa,sBACtB5B,KAAKgB,aAAaa,MAEtB,OAAO7B,OAIXqB,aAAe,WACX,GAAIW,GAAOhC,IASX,OARAA,MAAKT,UAAU0C,QAAS,SAAUC,GAC1BhC,EAAEiC,IAAKH,EAAME,IACbF,EAAME,GAAUE,WAAY,IAAMF,GAClCF,EAAME,GAAUjB,UACI,WAAZiB,GACRF,EAAKK,OAAO3B,IAAI4B,IAAKJ,EAAS,KAG/BlC,MAIXa,UAAW,WACP,OACI,wBACI,yBACA,yBACA,wDACA,mBACA,qCACA,oBACJ,SACA,wBACA,aACI,4DACI,QACI,wDACA,QACI,gFACA,iDACJ,SACJ,SACJ,SACJ,eACF0B,KAAK,KAGXC,SAAW,WAAa,MAAO,mBAI/B,QACIzD,eAAgBA"}
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"form-input.js","sources":["../../../src/mvc/form/form-input.js"],"names":["define","Backbone","View","extend","initialize","app","options","this","field","text_enable","text_disable","cls_enable","cls_disable","setElement","_template","$field","$","$preview","$collapsible","$collapsible_icon","find","$error_text","$error","$backdrop","prepend","$el","collapsed","undefined","collapsible_value","JSON","stringify","value","_refresh","self","on","disable","silent","show","css","opacity","cursor","error","text","html","addClass","reset","hide","removeClass","_tooltip","fadeIn","trigger","title","cls","tooltip","placement","attr","tmp","disabled","label","help","argument","indexOf","collapsible_preview","text_value"],"mappings":"AAGAA,UAAW,WACP,MAAOC,UAASC,KAAKC,QACjBC,WAAY,SAASC,EAAKC,GACtBC,KAAKF,IAAMA,EACXE,KAAKC,MAAQF,EAAQE,MAGrBD,KAAKE,YAAiBJ,EAAIC,QAAQG,aAAe,SACjDF,KAAKG,aAAiBL,EAAIC,QAAQI,cAAgB,UAClDH,KAAKI,WAAiBN,EAAIC,QAAQK,YAAc,4BAChDJ,KAAKK,YAAiBP,EAAIC,QAAQM,aAAe,0BAGjDL,KAAKM,WAAWN,KAAKO,UAAUR,IAG/BC,KAAKQ,OAASR,KAAKS,EAAE,kBACrBT,KAAKU,SAAWV,KAAKS,EAAE,oBACvBT,KAAKW,aAAeX,KAAKS,EAAE,wBAC3BT,KAAKY,kBAAoBZ,KAAKS,EAAE,wBAAwBI,KAAK,SAC7Db,KAAKc,YAAcd,KAAKS,EAAE,uBAC1BT,KAAKe,OAASf,KAAKS,EAAE,kBACrBT,KAAKgB,UAAYhB,KAAKS,EAAE,qBAGxBT,KAAKQ,OAAOS,QAAQjB,KAAKC,MAAMiB,KAG/BlB,KAAKC,MAAMkB,UAA0CC,SAA9BrB,EAAQsB,mBAAmCC,KAAKC,UAAWxB,EAAQyB,QAAWF,KAAKC,UAAWxB,EAAQsB,mBAG7HrB,KAAKyB,UAGL,IAAIC,GAAO1B,IACXA,MAAKW,aAAagB,GAAG,QAAS,WAC1BD,EAAKzB,MAAMkB,WAAaO,EAAKzB,MAAMkB,UACnCO,EAAKD,cAMbG,QAAS,SAAUC,GACf7B,KAAKgB,UAAUc,OACfD,GAAU7B,KAAKgB,UAAUe,KAAMC,QAAW,EAAGC,OAAU,aAK3DC,MAAO,SAASC,GACZnC,KAAKc,YAAYsB,KAAKD,GACtBnC,KAAKe,OAAOe,OACZ9B,KAAKkB,IAAImB,SAAS,aAKtBC,MAAO,WACHtC,KAAKe,OAAOwB,OACZvC,KAAKkB,IAAIsB,YAAY,aAKzBf,SAAU,WACNzB,KAAKY,kBAAkB4B,cAAcH,SAAS,QACzCrC,KAAKC,MAAMkB,WAKZnB,KAAKQ,OAAO+B,OACZvC,KAAKU,SAASoB,OACd9B,KAAKyC,SAASzC,KAAKE,YAAaF,KAAKI,cANrCJ,KAAKQ,OAAOkC,OAAO,QACnB1C,KAAKU,SAAS6B,OACdvC,KAAKyC,SAASzC,KAAKG,aAAcH,KAAKK,cAM1CL,KAAKF,IAAI6C,QAAQ,WAKrBF,SAAU,SAASG,EAAOC,GACtB7C,KAAKY,kBAAkByB,SAASQ,GACZC,SAAUC,UAAW,WACrBC,KAAK,sBAAuBJ,GAC5BE,QAAQ,YAAYA,QAAQ,SAKpDvC,UAAW,SAASR,GAChB,GAAIkD,GAAQ,sKA4BZ,OAlBIA,IALElD,EAAQmD,UAA0C9B,SAA9BrB,EAAQsB,kBAKvBtB,EAAQoD,MAJC,qDAC0BpD,EAAQoD,MAClC,SAIpBF,GAAgB,oCAEhBA,GAAoB,6BAChBlD,EAAQqD,OACRH,GAAoBlD,EAAQqD,KACxBrD,EAAQsD,UAAkE,IAAtDtD,EAAQqD,KAAKE,QAAQ,IAAMvD,EAAQsD,SAAW,OAClEJ,GAAO,KAAOlD,EAAQsD,SAAW,MAGzCJ,GAAoB,8CAGflD,EAAQwD,sBACTN,GAAY,gCAAkClD,EAAQyD,WAAa,UAEvEP,GAAO"}
{"version":3,"file":"form-input.js","sources":["../../../src/mvc/form/form-input.js"],"names":["define","Backbone","View","extend","initialize","app","options","this","field","text_enable","text_disable","cls_enable","cls_disable","setElement","_template","$field","$","$preview","$collapsible","$collapsible_icon","find","$error_text","$error","$backdrop","prepend","$el","collapsed","undefined","collapsible_value","JSON","stringify","value","_refresh","self","on","disable","silent","show","css","opacity","cursor","error","text","html","addClass","reset","hide","removeClass","_tooltip","fadeIn","trigger","title","cls","tooltip","placement","attr","tmp","disabled","label","help","argument","indexOf","collapsible_preview","text_value"],"mappings":"AAGAA,UAAW,WACP,MAAOC,UAASC,KAAKC,QACjBC,WAAY,SAASC,EAAKC,GACtBC,KAAKF,IAAMA,EACXE,KAAKC,MAAQF,EAAQE,MAGrBD,KAAKE,YAAiBJ,EAAIC,QAAQG,aAAe,SACjDF,KAAKG,aAAiBL,EAAIC,QAAQI,cAAgB,UAClDH,KAAKI,WAAiBN,EAAIC,QAAQK,YAAc,4BAChDJ,KAAKK,YAAiBP,EAAIC,QAAQM,aAAe,0BAGjDL,KAAKM,WAAWN,KAAKO,UAAUR,IAG/BC,KAAKQ,OAASR,KAAKS,EAAE,kBACrBT,KAAKU,SAAWV,KAAKS,EAAE,oBACvBT,KAAKW,aAAeX,KAAKS,EAAE,wBAC3BT,KAAKY,kBAAoBZ,KAAKS,EAAE,wBAAwBI,KAAK,SAC7Db,KAAKc,YAAcd,KAAKS,EAAE,uBAC1BT,KAAKe,OAASf,KAAKS,EAAE,kBACrBT,KAAKgB,UAAYhB,KAAKS,EAAE,qBAGxBT,KAAKQ,OAAOS,QAAQjB,KAAKC,MAAMiB,KAG/BlB,KAAKC,MAAMkB,UAA0CC,SAA9BrB,EAAQsB,mBAAmCC,KAAKC,UAAWxB,EAAQyB,QAAWF,KAAKC,UAAWxB,EAAQsB,mBAG7HrB,KAAKyB,UAGL,IAAIC,GAAO1B,IACXA,MAAKW,aAAagB,GAAG,QAAS,WAC1BD,EAAKzB,MAAMkB,WAAaO,EAAKzB,MAAMkB,UACnCO,EAAKD,cAMbG,QAAS,SAAUC,GACf7B,KAAKgB,UAAUc,OACfD,GAAU7B,KAAKgB,UAAUe,KAAMC,QAAW,EAAGC,OAAU,aAK3DC,MAAO,SAASC,GACZnC,KAAKc,YAAYsB,KAAKD,GACtBnC,KAAKe,OAAOe,OACZ9B,KAAKkB,IAAImB,SAAS,aAKtBC,MAAO,WACHtC,KAAKe,OAAOwB,OACZvC,KAAKkB,IAAIsB,YAAY,aAKzBf,SAAU,WACNzB,KAAKY,kBAAkB4B,cAAcH,SAAS,QACzCrC,KAAKC,MAAMkB,WAKZnB,KAAKQ,OAAO+B,OACZvC,KAAKU,SAASoB,OACd9B,KAAKyC,SAASzC,KAAKE,YAAaF,KAAKI,cANrCJ,KAAKQ,OAAOkC,OAAO,QACnB1C,KAAKU,SAAS6B,OACdvC,KAAKyC,SAASzC,KAAKG,aAAcH,KAAKK,cAM1CL,KAAKF,IAAI6C,QAAQ,WAKrBF,SAAU,SAASG,EAAOC,GACtB7C,KAAKY,kBAAkByB,SAASQ,GACZC,SAAUC,UAAW,WACrBC,KAAK,sBAAuBJ,GAC5BE,QAAQ,YAAYA,QAAQ,SAKpDvC,UAAW,SAASR,GAChB,GAAIkD,GAAQ,sKA4BZ,OAlBIA,IALElD,EAAQmD,UAA0C9B,SAA9BrB,EAAQsB,kBAKvBtB,EAAQoD,MAJC,qDAC0BpD,EAAQoD,MAClC,SAIpBF,GAAgB,oCAEhBA,GAAoB,6BAChBlD,EAAQqD,OACRH,GAAoBlD,EAAQqD,MAE5BrD,EAAQsD,UAAkE,IAAtDtD,EAAQqD,KAAKE,QAAQ,IAAMvD,EAAQsD,SAAW,OAClEJ,GAAoB,KAAOlD,EAAQsD,SAAW,KAElDJ,GAAoB,8CAGflD,EAAQwD,sBACTN,GAAY,gCAAkClD,EAAQyD,WAAa,UAEvEP,GAAO"}
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"form-section.js","sources":["../../../src/mvc/form/form-section.js"],"names":["define","Utils","Table","Ui","Portlet","Repeat","InputElement","Parameters","View","Backbone","extend","initialize","app","options","this","inputs","cls","cls_tr","table","parameters","setElement","$el","render","delAll","i","add","input","input_def","jQuery","id","uid","input_list","type","_addConditional","_addRepeat","_addSection","_addRow","self","test_param","sustain_conditionals","disabled","field","onchange","value","selectedCase","data","matchCase","cases","case_def","section_id","section_row","get","nonhidden","j","hidden","fadeIn","hide","trigger","sub_section_id","sub_section","addClass","append","create","block_index","repeat","ondel","del","title","title_new","min","max","onnew","n_min","n_cache","_","size","cache","Math","sustain_repeats","hideOptions","input_element","label","name","help","button_visible","ButtonIcon","icon","tooltip","portlet","collapsible","collapsed","operations","$","html","setOperation","expand","collapse","on","setIcon","input_id","length","expanded","field_list","default_value","text_value","collapsible_value","collapsible_preview","argument","element_list"],"mappings":"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"}
{"version":3,"file":"form-section.js","sources":["../../../src/mvc/form/form-section.js"],"names":["define","Utils","Table","Ui","Portlet","Repeat","InputElement","Parameters","View","Backbone","extend","initialize","app","options","this","inputs","cls","cls_tr","table","parameters","setElement","$el","render","delAll","i","add","input","input_def","jQuery","id","uid","input_list","type","_addConditional","_addRepeat","_addSection","_addRow","self","test_param","sustain_conditionals","disabled","field","onchange","value","selectedCase","data","matchCase","cases","case_def","section_id","section_row","get","nonhidden","j","hidden","fadeIn","hide","trigger","sub_section_id","sub_section","addClass","append","create","block_index","repeat","ondel","del","title","title_new","min","max","onnew","n_cache","_","size","cache","Math","default","sustain_repeats","hideOptions","input_element","label","name","help","button_visible","ButtonIcon","icon","tooltip","portlet","collapsible","collapsed","operations","$","html","setOperation","expand","collapse","on","setIcon","input_id","length","expanded","field_list","default_value","text_value","collapsible_value","collapsible_preview","argument","element_list"],"mappings":"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"}
@@ -1 +1 @@
{"version":3,"file":"form-select-content.js","sources":["../../../src/mvc/form/form-select-content.js"],"names":["define","Utils","Ui","View","Backbone","extend","initialize","app","options","this","history","self","setElement","list","radio_buttons","mode","type","multiple","current","extensions","textify","hda_error","hdca_error","push","icon","value","tooltip","select_single","Select","optional","error_text","onchange","trigger","field","select_multiple","searchable","select_collection","button_type","RadioButton","data","refresh","$batch","$","template_batch","n_buttons","_","size","button_width","$el","append","Math","max","i","css","margin-left","update","undefined","on","wait","unwait","_update","select_options","item","label","hid","name","id","src","hda","hdca","new_value","values","length","err","Galaxy","emit","debug","id_list","_select","Array","result","batch","_batch","details","sort","a","b","show","hide","map_over_type"],"mappings":"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"}
{"version":3,"file":"form-select-content.js","sources":["../../../src/mvc/form/form-select-content.js"],"names":["define","Utils","Ui","View","Backbone","extend","initialize","app","options","this","history","self","setElement","list","radio_buttons","mode","type","multiple","current","extensions","textify","hda_error","hdca_error","push","icon","value","tooltip","select_single","Select","optional","error_text","onchange","trigger","field","select_multiple","searchable","select_collection","button_type","RadioButton","data","refresh","$batch","$","template_batch","n_buttons","_","size","button_width","$el","append","Math","max","i","css","margin-left","update","undefined","on","wait","unwait","_update","select_options","item","hid","label","name","id","src","add","a","b","hda","hdca","new_value","values","length","err","Galaxy","emit","debug","id_list","_select","Array","result","batch","_batch","details","sort","show","hide","map_over_type"],"mappings":"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"}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"tours.js","sources":["../../src/mvc/tours.js"],"names":["define","tour_opts","storage","window","sessionStorage","onEnd","removeItem","delay","orphan","hooked_tour_from_data","data","_","each","steps","step","preclick","onShow","$","click","postclick","onHide","textinsert","onShown","element","val","trigger","Galaxy","gxy_root","root","TourItem","Backbone","Model","extend","urlRoot","Tours","Collection","url","model","giveTour","tour_id","getJSON","tourdata","console","log","setItem","JSON","stringify","tour","Tour","init","goTo","restart","ToursView","View","initialize","self","this","setElement","fetch","success","render","error","tpl","template","join","$el","html","tours","models","on"],"mappings":"AAUAA,QAAQ,uBAAuB,WAE3B,GAAIC,IAAcC,QAASC,OAAOC,eAChBC,MAAO,WACHD,eAAeE,WAAW,qBAE9BC,MAAO,IACPC,QAAO,GAGrBC,EAAwB,SAASC,GA2BjC,MA1BAC,GAAEC,KAAKF,EAAKG,MAAO,SAASC,GACpBA,EAAKC,WACLD,EAAKE,OAAQ,WACTL,EAAEC,KAAKE,EAAKC,SAAU,SAASA,GAE3BE,EAAEF,GAAUG,YAIpBJ,EAAKK,YACLL,EAAKM,OAAS,WACVT,EAAEC,KAAKE,EAAKK,UAAW,SAASA,GAE5BF,EAAEE,GAAWD,YAIrBJ,EAAKO,aAILP,EAAKQ,QAAS,WACVL,EAAEH,EAAKS,SAASC,IAAIV,EAAKO,YAAYI,QAAQ,cAIlDf,EAKX,IAAqB,mBAAVgB,QACP,GAAIC,GAAWD,OAAOE,SAEtB,IAAID,GAAW,GAGnB,IAAIE,GAAWC,SAASC,MAAMC,QAC5BC,QAASN,EAAW,cAGlBO,EAAQJ,SAASK,WAAWH,QAC9BI,IAAMT,EAAW,YACjBU,MAAOR,IAILS,EAAY,SAASC,GACrB,GAAIH,GAAMT,EAAW,aAAeY,CACpCtB,GAAEuB,QAASJ,EAAK,SAAU1B,GAEtB+B,SAAWhC,EAAsBC,GACjCgC,QAAQC,IAAIF,UACZrC,eAAewC,QAAQ,mBAAoBC,KAAKC,UAAUpC,GAE1D,IAAIqC,GAAO,GAAIC,MAAKrC,EAAEqB,QAClBnB,MAAO4B,SAAS5B,OACjBZ,GAEH8C,GAAKE,OACLF,EAAKG,KAAK,GACVH,EAAKI,aAITC,EAAYtB,SAASuB,KAAKrB,QAE1BsB,WAAY,WACR,GAAIC,GAAOC,IACXA,MAAKC,WAAW,UAChBD,KAAKnB,MAAQ,GAAIH,GACjBsB,KAAKnB,MAAMqB,OACTC,QAAS,WACPJ,EAAKK,UAEPC,MAAO,WAELnB,QAAQmB,MAAM,8BAKtBD,OAAQ,WACJ,GACIE,GAAMnD,EAAEoD,UACR,wBACA,uFACA,2FACA,OACA,uCACI,OACI,4DACI,yCACJ,OACA,mEACJ,QACJ,YACA,SAASC,KAAK,IAClBR,MAAKS,IAAIC,KAAKJ,GAAKK,MAAOX,KAAKnB,MAAM+B,UAAUC,GAAG,QAAS,YAAa,WACpE/B,EAASrB,EAAEuC,MAAM9C,KAAK,gBAKlC,QAAQ0C,UAAWA,EACX3C,sBAAuBA,EACvBR,UAAWA,EACXqC,SAAUA"}
{"version":3,"file":"tours.js","sources":["../../src/mvc/tours.js"],"names":["define","gxy_root","Galaxy","root","tour_opts","storage","window","sessionStorage","onEnd","removeItem","delay","orphan","hooked_tour_from_data","data","_","each","steps","step","preclick","onShow","$","click","postclick","onHide","textinsert","onShown","element","val","trigger","TourItem","Backbone","Model","extend","urlRoot","Tours","Collection","url","model","giveTour","tour_id","getJSON","tourdata","setItem","JSON","stringify","tour","Tour","init","goTo","restart","ToursView","View","initialize","self","this","setElement","fetch","success","render","error","console","tpl","template","join","$el","html","tours","models","on"],"mappings":"AAUAA,QAAQ,uBAAuB,WAE3B,GAAIC,GAA6B,mBAAXC,QAAyB,IAAMA,OAAOC,KAExDC,GAAcC,QAASC,OAAOC,eAChBC,MAAO,WACHD,eAAeE,WAAW,qBAE9BC,MAAO,IACPC,QAAO,GAGrBC,EAAwB,SAASC,GA2BjC,MA1BAC,GAAEC,KAAKF,EAAKG,MAAO,SAASC,GACpBA,EAAKC,WACLD,EAAKE,OAAQ,WACTL,EAAEC,KAAKE,EAAKC,SAAU,SAASA,GAE3BE,EAAEF,GAAUG,YAIpBJ,EAAKK,YACLL,EAAKM,OAAS,WACVT,EAAEC,KAAKE,EAAKK,UAAW,SAASA,GAE5BF,EAAEE,GAAWD,YAIrBJ,EAAKO,aAILP,EAAKQ,QAAS,WACVL,EAAEH,EAAKS,SAASC,IAAIV,EAAKO,YAAYI,QAAQ,cAIlDf,GAGPgB,EAAWC,SAASC,MAAMC,QAC5BC,QAAShC,EAAW,cAGlBiC,EAAQJ,SAASK,WAAWH,QAC9BI,IAAMnC,EAAW,YACjBoC,MAAOR,IAILS,EAAY,SAASC,GACrB,GAAIH,GAAMnC,EAAW,aAAesC,CACpCnB,GAAEoB,QAASJ,EAAK,SAAUvB,GAEtB,GAAI4B,GAAW7B,EAAsBC,EACrCN,gBAAemC,QAAQ,mBAAoBC,KAAKC,UAAU/B,GAE1D,IAAIgC,GAAO,GAAIC,MAAKhC,EAAEkB,QAClBhB,MAAOyB,EAASzB,OACjBZ,GAEHyC,GAAKE,OACLF,EAAKG,KAAK,GACVH,EAAKI,aAGTC,EAAYpB,SAASqB,KAAKnB,QAE1BoB,WAAY,WACR,GAAIC,GAAOC,IACXA,MAAKC,WAAW,UAChBD,KAAKjB,MAAQ,GAAIH,GACjBoB,KAAKjB,MAAMmB,OACTC,QAAS,WACPJ,EAAKK,UAEPC,MAAO,WAELC,QAAQD,MAAM,8BAKtBD,OAAQ,WACJ,GAAIG,GAAM/C,EAAEgD,UACR,wBACA,uFACA,2FACA,OACA,uCACI,OACI,iFACI,yCACJ,OACA,mEACJ,QACJ,YACA,SAASC,KAAK,IAClBT,MAAKU,IAAIC,KAAKJ,GAAKK,MAAOZ,KAAKjB,MAAM8B,UAAUC,GAAG,QAAS,YAAa,WACpE9B,EAASlB,EAAEkC,MAAMzC,KAAK,gBAKlC,QAAQqC,UAAWA,EACXtC,sBAAuBA,EACvBR,UAAWA,EACXkC,SAAUA"}
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"ui-select-default.js","sources":["../../../src/mvc/ui/ui-select-default.js"],"names":["define","Utils","Buttons","View","Backbone","extend","optionsDefault","id","uid","cls","error_text","empty_text","visible","wait","multiple","searchable","optional","initialize","options","self","this","merge","setElement","_template","$select","$el","find","$icon_dropdown","on","select2","minHeight","$","event","currentY","pageY","currentHeight","height","show","Math","max","hide","off","all_button","ButtonCheck","onclick","new_value","value","_availableOptions","trigger","prepend","addClass","prop","remove","update","data","undefined","onchange","exists","val","current","_getValue","isArray","length","_size","first","text","unwait","removeClass","disabled","is","enable","disable","append","_templateOption","label","key","closeOnSelect","setOnChange","callback","validate","available","each","i","e","push","attr","_","escape"],"mappings":"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"}
{"version":3,"file":"ui-select-default.js","sources":["../../../src/mvc/ui/ui-select-default.js"],"names":["define","Utils","Buttons","View","Backbone","extend","optionsDefault","id","uid","cls","error_text","empty_text","visible","wait","multiple","searchable","optional","initialize","options","self","this","model","Model","merge","setElement","_template","$select","$el","find","$icon_dropdown","on","select2","minHeight","$","event","currentY","pageY","currentHeight","height","show","Math","max","hide","off","all_button","ButtonCheck","onclick","new_value","value","_availableOptions","trigger","prepend","addClass","prop","remove","update","data","undefined","onchange","exists","val","current","_getValue","isArray","length","_size","first","text","unwait","removeClass","disabled","is","enable","disable","add","sorter","_","each","get","v","findWhere","push","sort","append","_templateOption","label","set","key","closeOnSelect","setOnChange","callback","validate","available","i","e","attr","escape"],"mappings":"AAGAA,QAAQ,cAAe,qBAAsB,SAASC,EAAOC,GAC7D,GAAIC,GAAOC,SAASD,KAAKE,QAErBC,gBACIC,GAAcN,EAAMO,MACpBC,IAAc,YACdC,WAAc,uBACdC,WAAc,mBACdC,SAAc,EACdC,MAAc,EACdC,UAAc,EACdC,YAAc,EACdC,UAAc,GAIlBC,WAAY,SAASC,GAEjB,GAAIC,GAAOC,IACXA,MAAKC,MAAQ,GAAIjB,UAASkB,MAG1BF,KAAKF,QAAUjB,EAAMsB,MAAML,EAASE,KAAKd,gBAGzCc,KAAKI,WAAWJ,KAAKK,UAAUL,KAAKF,UAGpCE,KAAKM,QAAUN,KAAKO,IAAIC,KAAK,WAC7BR,KAAKS,eAAiBT,KAAKO,IAAIC,KAAK,kBACpCR,KAAKS,eAAeC,GAAI,QAAS,WAAaX,EAAKO,QAAQK,SAAWZ,EAAKO,QAAQK,QAAS,SAG5F,IAAIC,GAAY,IAChBZ,MAAKa,EAAE,gBAAgBH,GAAG,YAAa,SAASI,GAC5C,GAAIC,GAAWD,EAAME,MACjBC,EAAgBlB,EAAKO,QAAQY,QACjCN,GAAYA,GAAaK,EACzBJ,EAAE,cAAcM,OAAOT,GAAG,YAAa,SAASI,GAC5Cf,EAAKO,QAAQY,OAAOE,KAAKC,IAAIJ,GAAiBH,EAAME,MAAQD,GAAWH,MACxEF,GAAG,qBAAsB,WACxBG,EAAE,cAAcS,OAAOC,UAK3BvB,KAAKF,QAAQJ,WAETM,KAAKF,QAAQH,YACbK,KAAKwB,WAAa,GAAI1C,GAAQ2C,aAC1BC,QAAS,WACL,GAAIC,KAC4B,KAA5B5B,EAAKyB,WAAWI,UAChBD,EAAY5B,EAAK8B,qBAErB9B,EAAK6B,MAAMD,GACX5B,EAAK+B,QAAQ,aAGrB9B,KAAKO,IAAIwB,QAAQ/B,KAAKwB,WAAWjB,MAEjCP,KAAKO,IAAIyB,SAAS,sBAEtBhC,KAAKM,QAAQ2B,KAAK,YAAY,GAC9BjC,KAAKS,eAAeyB,UAIxBlC,KAAKmC,OAAOnC,KAAKF,QAAQsC,MAGEC,SAAvBrC,KAAKF,QAAQ8B,OACb5B,KAAK4B,MAAM5B,KAAKF,QAAQ8B,OAIvB5B,KAAKF,QAAQN,SACdQ,KAAKsB,OAILtB,KAAKF,QAAQL,KACbO,KAAKP,OAELO,KAAKmB,OAITnB,KAAKM,QAAQI,GAAG,SAAU,WACtBX,EAAK+B,QAAQ,YAIjB9B,KAAKU,GAAG,SAAU,WACdX,EAAKD,QAAQwC,UAAYvC,EAAKD,QAAQwC,SAAStC,KAAK4B,YAM5DA,MAAO,SAAUD,GAEKU,SAAdV,IACkB,OAAdA,IACAA,EAAY,aAEZ3B,KAAKuC,OAAOZ,IAAc3B,KAAKF,QAAQJ,YACvCM,KAAKM,QAAQkC,IAAIb,GACb3B,KAAKM,QAAQK,SACbX,KAAKM,QAAQK,QAAQ,MAAOgB,IAKxC,IAAIc,GAAUzC,KAAK0C,WAInB,OAHI1C,MAAKwB,YACLxB,KAAKwB,WAAWI,MAAMf,EAAE8B,QAAQF,IAAYA,EAAQG,QAAU,EAAG5C,KAAK6C,SAEnEJ,GAKXK,MAAO,WACH,GAAIhD,GAAUE,KAAKM,QAAQE,KAAK,UAAUsC,OAC1C,OAAIhD,GAAQ8C,OAAS,EACV9C,EAAQ0C,MAER,MAMfO,KAAM,WACF,MAAO/C,MAAKM,QAAQE,KAAK,mBAAmBuC,QAKhD5B,KAAM,WACFnB,KAAKgD,SACLhD,KAAKM,QAAQa,OACbnB,KAAKO,IAAIY,QAKbG,KAAM,WACFtB,KAAKO,IAAIe,QAKb7B,KAAM,WACFO,KAAKS,eAAewC,cACpBjD,KAAKS,eAAeuB,SAAS,wCAKjCgB,OAAQ,WACJhD,KAAKS,eAAewC,cACpBjD,KAAKS,eAAeuB,SAAS,mCAKjCkB,SAAU,WACN,MAAOlD,MAAKM,QAAQ6C,GAAG,cAK3BC,OAAQ,WACJpD,KAAKM,QAAQ2B,KAAK,YAAY,IAKlCoB,QAAS,WACLrD,KAAKM,QAAQ2B,KAAK,YAAY,IAKlCqB,IAAK,SAAUxD,EAASyD,GACpBC,EAAEC,KAAMzD,KAAKC,MAAMyD,IAAK,WAAa,SAAUC,IAC1CH,EAAEI,UAAW9D,EAAS6D,IAAO7D,EAAQ+D,KAAMF,KAEhDJ,GAAUzD,EAAQgE,KAAMP,GACxBvD,KAAKmC,OAAQrC,IAEjBqC,OAAQ,SAASrC,GAEb,GAAI2C,GAAUzC,KAAK0C,WAGnB1C,MAAKM,QAAQE,KAAK,UAAU0B,UAGvBlC,KAAKF,QAAQJ,UAAYM,KAAKF,QAAQF,UACvCI,KAAKM,QAAQyD,OAAO/D,KAAKgE,iBAAiBpC,MAAQ,WAAYqC,MAAQjE,KAAKF,QAAQP,cAIvFS,KAAKC,MAAMiE,IAAK,UAAWpE,EAC3B,KAAK,GAAIqE,KAAOrE,GACZE,KAAKM,QAAQyD,OAAO/D,KAAKgE,gBAAgBlE,EAAQqE,IAIjC,IAAhBnE,KAAK6C,SAEL7C,KAAKqD,UAGLrD,KAAKM,QAAQyD,OAAO/D,KAAKgE,iBAAiBpC,MAAQ,WAAYqC,MAAQjE,KAAKF,QAAQR,eAGnFU,KAAKoD,SAILpD,KAAKF,QAAQH,aACbK,KAAKM,QAAQK,QAAQ,WACrBX,KAAKM,QAAQK,SAAUyD,eAAgBpE,KAAKF,QAAQJ,WACpDM,KAAKa,EAAG,4CAA6CU,IAAK,SAI9DvB,KAAK4B,MAAMa,GAGc,OAArBzC,KAAK0C,aAA0B1C,KAAKF,QAAQJ,UAAYM,KAAKF,QAAQF,UACrEI,KAAK4B,MAAM5B,KAAK8C,UAMxBuB,YAAa,SAASC,GAClBtE,KAAKF,QAAQwC,SAAWgC,GAK5B/B,OAAQ,SAASX,GACb,MAAO5B,MAAKM,QAAQE,KAAK,iBAAmBoB,EAAQ,MAAMgB,OAAS,GAKvEF,UAAW,WACP,GAAIF,GAAMxC,KAAKM,QAAQkC,KACvB,OAAK3D,GAAM0F,SAAS/B,GAGbA,EAFI,MAOfX,kBAAmB,WACf,GAAI2C,KAIJ,OAHAxE,MAAKM,QAAQE,KAAK,UAAUiD,KAAK,SAASgB,EAAGC,GACzCF,EAAUX,KAAKhD,EAAE6D,GAAGC,KAAK,YAEtBH,GAKX3B,MAAO,WACH,MAAO7C,MAAKM,QAAQE,KAAK,UAAUoC,QAKvCoB,gBAAiB,SAASlE,GACtB,MAAO,kBAAoBA,EAAQ8B,MAAQ,KAAO4B,EAAEoB,OAAO9E,EAAQmE,OAAS,aAKhF5D,UAAW,SAASP,GAChB,MAAQ,YAAcA,EAAQX,GAAK,YAAcW,EAAQT,IAAM,iBAClCS,EAAQX,GAAK,iJASlD,QACIJ,KAAMA"}
@@ -1 +1 @@
{"version":3,"file":"default-row.js","sources":["../../../../src/mvc/upload/default/default-row.js"],"names":["define","Utils","UploadModel","UploadSettings","Popover","Select","Backbone","View","extend","status_classes","init","queued","running","success","error","settings","select_genome","select_extension","initialize","app","options","this","self","model","setElement","_template","title","container","$","placement","default_genome","value","css","onchange","genome","set","updateGenome","data","list_genomes","default_extension","extension","updateExtension","list_extensions","on","_removeRow","e","showExtensionInfo","$el","target","text","preventDefault","_showSettings","val","length","_refreshPercentage","_refreshStatus","_refreshInfo","_refreshGenome","_refreshExtension","_refreshFileSize","remove","collection","render","file_name","get","file_size","file_mode","html","bytesToString","removeClass","addClass","width","top","height","show","prototype","apply","info","hide","percentage","parseInt","status","enabled","attr","enable","disable","count","visible","empty","append","id"],"mappings":"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"}
{"version":3,"file":"default-row.js","sources":["../../../../src/mvc/upload/default/default-row.js"],"names":["define","Utils","UploadModel","UploadSettings","Popover","Select","Backbone","View","extend","status_classes","init","queued","running","success","error","settings","select_genome","select_extension","initialize","app","options","this","self","model","setElement","_template","title","container","$","placement","default_genome","value","css","onchange","genome","set","data","list_genomes","default_extension","extension","list_extensions","on","_removeRow","e","showExtensionInfo","$el","target","text","preventDefault","_showSettings","val","length","_refreshPercentage","_refreshStatus","_refreshInfo","_refreshGenome","_refreshExtension","_refreshFileSize","remove","collection","render","file_name","get","file_size","file_mode","html","bytesToString","removeClass","addClass","width","top","height","show","prototype","apply","info","hide","percentage","parseInt","status","enabled","attr","enable","disable","count","visible","empty","append","id"],"mappings":"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"}
@@ -1 +1 @@
{"version":3,"file":"visualization-model.js","sources":["../../../src/mvc/visualization/visualization-model.js"],"names":["Visualization","Backbone","Model","extend","defaults","config","urlRoot","apiUrl","Galaxy","root","initialize","data","_","isObject","this","_setUpListeners","set","key","val","oldConfig","get","clone","prototype","call","toString","idAndTitle","VisualizationCollection","Collection","model","url","models","options","collection","map","existing","id","merged","toJSON","historyId","length","join"],"mappings":"AASA,GAAIA,eAAgBC,SAASC,MAAMC,QAQ/BC,UACIC,WAIJC,QAAU,WACN,GAAIC,GAAS,qBACb,OAAOC,QAAOC,KAAOF,GAMzBG,WAAa,SAAUC,GAIfC,EAAEC,SAAUF,EAAKN,SAAYO,EAAEC,SAAUC,KAAKV,SAASC,SACvDO,EAAER,SAAUO,EAAKN,OAAQS,KAAKV,SAASC,QAG3CS,KAAKC,mBAKTA,gBAAkB,aAQlBC,IAAK,SAAUC,EAAKC,GAEhB,GAAY,WAARD,EAAkB,CAClB,GAAIE,GAAYL,KAAKM,IAAK,SAGtBR,GAAEC,SAAUM,KACZD,EAAMN,EAAET,OAAQS,EAAES,MAAOF,GAAaD,IAI9C,MADAjB,UAASC,MAAMoB,UAAUN,IAAIO,KAAMT,KAAMG,EAAKC,GACvCJ,MAKXU,SAAW,WACP,GAAIC,GAAaX,KAAKM,IAAK,OAAU,EAIrC,OAHIN,MAAKM,IAAK,WACVK,GAAc,IAAMX,KAAKM,IAAK,UAE3B,iBAAmBK,EAAa,OAU3CC,wBAA0BzB,SAAS0B,WAAWxB,QAE9CyB,MAAkB5B,cAMlB6B,IAAM,WACF,MAAOrB,QAAOC,KAAO,sBAMzBC,WAAa,SAAUoB,EAAQC,GAC3BA,EAAUA,OAUdf,IAAM,SAAUc,EAAQC,GAMpB,GAAIC,GAAalB,IACjBgB,GAASlB,EAAEqB,IAAKH,EAAQ,SAAUF,GAC9B,GAAIM,GAAWF,EAAWZ,IAAKQ,EAAMO,GACrC,KAAKD,EAAY,MAAON,EAGxB,IAAIQ,GAASF,EAASG,QAEtB,OADAzB,GAAET,OAAQiC,EAAQR,GACXQ,IAGXnC,SAAS0B,WAAWL,UAAUN,IAAIO,KAAMT,KAAMgB,EAAQC,IAI1DP,SAAW,WACN,OAAU,4BAA8BV,KAAKwB,UAAWxB,KAAKyB,QAASC,OAAQ,KAAMA,KAAM"}
{"version":3,"file":"visualization-model.js","sources":["../../../src/mvc/visualization/visualization-model.js"],"names":["Visualization","Backbone","Model","extend","defaults","config","urlRoot","apiUrl","Galaxy","root","initialize","data","_","isObject","this","_setUpListeners","set","key","val","oldConfig","get","clone","prototype","call","toString","idAndTitle","VisualizationCollection","Collection","model","url","models","options","collection","map","existing","id","merged","toJSON","historyId","length","join"],"mappings":"AASA,GAAIA,eAAgBC,SAASC,MAAMC,QAQ/BC,UACIC,WAIJC,QAAU,WACN,GAAIC,GAAS,oBACb,OAAOC,QAAOC,KAAOF,GAMzBG,WAAa,SAAUC,GAIfC,EAAEC,SAAUF,EAAKN,SAAYO,EAAEC,SAAUC,KAAKV,SAASC,SACvDO,EAAER,SAAUO,EAAKN,OAAQS,KAAKV,SAASC,QAG3CS,KAAKC,mBAKTA,gBAAkB,aAQlBC,IAAK,SAAUC,EAAKC,GAEhB,GAAY,WAARD,EAAkB,CAClB,GAAIE,GAAYL,KAAKM,IAAK,SAGtBR,GAAEC,SAAUM,KACZD,EAAMN,EAAET,OAAQS,EAAES,MAAOF,GAAaD,IAI9C,MADAjB,UAASC,MAAMoB,UAAUN,IAAIO,KAAMT,KAAMG,EAAKC,GACvCJ,MAKXU,SAAW,WACP,GAAIC,GAAaX,KAAKM,IAAK,OAAU,EAIrC,OAHIN,MAAKM,IAAK,WACVK,GAAc,IAAMX,KAAKM,IAAK,UAE3B,iBAAmBK,EAAa,OAU3CC,wBAA0BzB,SAAS0B,WAAWxB,QAE9CyB,MAAkB5B,cAMlB6B,IAAM,WACF,MAAOrB,QAAOC,KAAO,sBAMzBC,WAAa,SAAUoB,EAAQC,GAC3BA,EAAUA,OAUdf,IAAM,SAAUc,EAAQC,GAMpB,GAAIC,GAAalB,IACjBgB,GAASlB,EAAEqB,IAAKH,EAAQ,SAAUF,GAC9B,GAAIM,GAAWF,EAAWZ,IAAKQ,EAAMO,GACrC,KAAKD,EAAY,MAAON,EAGxB,IAAIQ,GAASF,EAASG,QAEtB,OADAzB,GAAET,OAAQiC,EAAQR,GACXQ,IAGXnC,SAAS0B,WAAWL,UAAUN,IAAIO,KAAMT,KAAMgB,EAAQC,IAI1DP,SAAW,WACN,OAAU,4BAA8BV,KAAKwB,UAAWxB,KAAKyB,QAASC,OAAQ,KAAMA,KAAM"}
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"onload.js","sources":["../src/onload.js"],"names":["replace_big_select_inputs","min_length","max_length","select_elts","refresh_select2","element","select_elt","$","options","placeholder","closeOnSelect","is","dropdownAutoWidth","containerCssClass","select2","jQuery","fn","undefined","each","this","not","num_options","find","length","hasClass","init_refresh_on_change","off","change","select_field","select_val","val","ref_on_change_vals","attr","split","last_selected_value","inArray","window","trigger","document","get","form","submit","click","confirm","_","Backbone","panels","require","extend","async_save_text","POPUPMENU","make_popupmenu","make_popup_menus","init_tag_click_function","TOURS","ready","tooltip","placement","anchor","galaxy_main_exists","parent","frames","galaxy_main","href","indexOf","urlparms","object","compact","map","location","search","slice","item","tour_id","url","repacked_url_args","Object","getOwnPropertyNames","k","join","history","pushState","giveTour","et","JSON","parse","sessionStorage","getItem","hooked_tour_from_data","steps","tour","Tour","tour_opts","init","restart","ex","console","log"],"mappings":"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"}
{"version":3,"file":"onload.js","sources":["../src/onload.js"],"names":["replace_big_select_inputs","min_length","max_length","select_elts","refresh_select2","element","select_elt","$","options","placeholder","closeOnSelect","is","dropdownAutoWidth","containerCssClass","select2","jQuery","fn","undefined","each","this","not","num_options","find","length","hasClass","init_refresh_on_change","off","change","select_field","select_val","val","ref_on_change_vals","attr","split","last_selected_value","inArray","window","trigger","document","get","form","submit","click","confirm","_","Backbone","panels","require","extend","async_save_text","POPUPMENU","make_popupmenu","make_popup_menus","init_tag_click_function","TOURS","QUERY_STRING","ready","tooltip","placement","anchor","galaxy_main_exists","parent","frames","galaxy_main","href","indexOf","et","JSON","parse","sessionStorage","getItem","hooked_tour_from_data","steps","tour","Tour","tour_opts","init","restart"],"mappings":"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"}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,2 +1,2 @@
webpackJsonp([4],[function(e,r,n){(function(e){var r=n(1),a=r,i=n(59).GalaxyApp,o=n(10),t=n(5),l=n(61);window.app=function(n,c){window.Galaxy=new i(n,c),Galaxy.debug("login app");var d=encodeURI(n.redirect);if(!n.show_welcome_with_login){var w=r.param({use_panels:"True",redirect:d});return void(window.location.href=Galaxy.root+"user/login?"+w)}var p=new l.PageLayoutView(e.extend(n,{el:"body",center:new o.CenterPanel({el:"#center"}),right:new o.RightPanel({title:t("Login required"),el:"#right"})}));a(function(){var e=r.param({redirect:d}),a=Galaxy.root+"user/login?"+e;p.render(),p.center.$("#galaxy_main").prop("src",n.welcome_url),p.right.$(".unified-panel-body").css("overflow","hidden").html('<iframe src="'+a+'" frameborder="0" style="width: 100%; height: 100%;"/>')})}}).call(r,n(3))}]);
webpackJsonp([4],[function(e,r,n){(function(e){var r=n(1),a=r,i=n(60).GalaxyApp,o=n(10),t=n(5),l=n(62);window.app=function(n,c){window.Galaxy=new i(n,c),Galaxy.debug("login app");var d=encodeURI(n.redirect);if(!n.show_welcome_with_login){var w=r.param({use_panels:"True",redirect:d});return void(window.location.href=Galaxy.root+"user/login?"+w)}var p=new l.PageLayoutView(e.extend(n,{el:"body",center:new o.CenterPanel({el:"#center"}),right:new o.RightPanel({title:t("Login required"),el:"#right"})}));a(function(){var e=r.param({redirect:d}),a=Galaxy.root+"user/login?"+e;p.render(),p.center.$("#galaxy_main").prop("src",n.welcome_url),p.right.$(".unified-panel-body").css("overflow","hidden").html('<iframe src="'+a+'" frameborder="0" style="width: 100%; height: 100%;"/>')})}}).call(r,n(3))}]);
//# sourceMappingURL=login.bundled.js.map
File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More