Merge remote-tracking branch 'upstream/dev' into es6

This commit is contained in:
Dannon Baker
2017-10-12 11:14:17 -04:00
44 changed files with 440 additions and 692 deletions
@@ -1,251 +1,185 @@
/** Dataset edit attributes view */
define( [ 'utils/utils', 'mvc/ui/ui-tabs', 'mvc/ui/ui-misc', 'mvc/form/form-view' ], function( Utils, Tabs, Ui, Form ) {
/** Dataset edit attributes view */
var View = Backbone.View.extend({
initialize: function() {
this.setElement( '<div/>' );
this.model = new Backbone.Model( { 'dataset_id': Galaxy.params.dataset_id } );
this.message = new Ui.Message( { 'persistent': true } );
this.tabs = this._createTabs();
this.$el.append( $( '<h4/>' ).append( 'Edit dataset attributes' ) )
.append( this.message.$el )
.append( '<p/>' )
.append( this.tabs.$el )
.hide();
this.render();
},
// Fetch data for the selected dataset and
// build tabs for editing its attributes
/** fetch data for the selected dataset and build forms */
render: function() {
var url = Galaxy.root + 'dataset/edit',
self = this;
Utils.get({
url : url,
data : { 'dataset_id' : self.model.get( 'dataset_id' ) },
success : function( response ) {
self.render_attribute_page( self, response );
},
error : function( response ) {
var error_response = {
'status': 'error',
'message': 'Error occured while loading the dataset.',
'persistent': true,
'cls': 'errormessage'
};
self.display_message( error_response, self.$( '.response-message' ) );
}
});
},
/** Render all the tabs view */
render_attribute_page: function( self, response ) {
var message = {
'message' : response.message,
'status' : response.status,
'persistent' : true,
'cls' : response.status + 'message'
};
self.$el.empty().append( self._templateHeader() );
self.display_message( message, self.$( '.response-message' ) );
// Create all tabs
self.create_tabs( response, self.$( '.edit-attr' ) );
},
/** Perform AJAX post call */
call_ajax: function( self, data, tab_name ) {
var post_url = Galaxy.root + 'dataset/edit';
$.ajax({
type: "PUT",
url: post_url,
data: data,
success: function( response ) {
self.render_attribute_page( self, response );
self.reload_history();
},
error : function( response ) {
var error_response = {
'status': 'error',
'message': 'Error occured while saving. Please fill all the required fields and try again.',
'persistent': true,
'cls': 'errormessage'
};
self.display_message( error_response, self.$( '.response-message' ) );
}
});
},
/** Display actions messages */
display_message: function( response, $el ) {
$el.empty().html( new Ui.Message( response ).$el );
},
/** Create tabs for different attributes of dataset*/
create_tabs: function( response, $el_edit_attr ) {
var self = this;
self.tabs = new Tabs.View();
self.tabs.add({
id : 'attributes',
$.ajax({
url : Galaxy.root + 'dataset/get_edit?dataset_id=' + self.model.get( 'dataset_id' ),
success : function( response ) {
!self.initial_message && self.message.update( response );
self.initial_message = true;
_.each( self.forms, function( form, key ) {
form.model.set( 'inputs', response[ key + '_inputs' ] );
form.model.set( 'hide_operations', response[ key + '_disable' ] );
form.render();
});
self.$el.show();
},
error : function( response ) {
var err_msg = response.responseJSON && response.responseJSON.err_msg;
self.message.update({
'status' : 'danger',
'message' : err_msg || 'Error occured while loading the dataset.'
});
}
});
},
/** submit data to backend to update attributes */
_submit: function( operation, form ) {
var self = this;
var data = form.data.create();
data.dataset_id = this.model.get( 'dataset_id' );
data.operation = operation;
$.ajax({
type : 'PUT',
url : Galaxy.root + 'dataset/set_edit',
data : data,
success : function( response ) {
self.message.update( response );
self.render();
self._reloadHistory();
},
error : function( response ) {
var err_msg = response.responseJSON && response.responseJSON.err_msg;
self.message.update({
'status' : 'danger',
'message' : err_msg || 'Error occured while editing the dataset attributes.'
});
}
});
},
/** create tabs for different dataset attribute categories*/
_createTabs: function() {
this.forms = {
attribute : this._getAttribute(),
conversion : this._getConversion(),
datatype : this._getDatatype(),
permission : this._getPermission()
}
var tabs = new Tabs.View();
tabs.add({
id : 'attribute',
title : 'Attributes',
icon : 'fa fa-bars',
tooltip : 'Edit dataset attributes',
$el : self._getAttributesFormTemplate( response )
$el : this.forms.attribute.$el
});
self.tabs.add({
tabs.add({
id : 'convert',
title : 'Convert',
icon : 'fa-gear',
tooltip : 'Convert to new format',
$el : self._getConvertFormTemplate( response )
$el : this.forms.conversion.$el
});
self.tabs.add({
tabs.add({
id : 'datatype',
title : 'Datatypes',
icon : 'fa-database',
tooltip : 'Change data type',
$el : self._getChangeDataTypeFormTemplate( response )
$el : this.forms.datatype.$el
});
self.tabs.add({
tabs.add({
id : 'permissions',
title : 'Permissions',
icon : 'fa-user',
tooltip : 'Permissions',
$el : self._getPermissionsFormTemplate( response )
$el : this.forms.permission.$el
});
$el_edit_attr.append( self.tabs.$el );
self.tabs.showTab( 'attributes' );
return tabs;
},
/** Main template */
_templateHeader: function() {
return '<div class="page-container edit-attr">' +
'<div class="response-message"></div>' +
'<h3>Edit Dataset Attributes</h3>' +
'</div>';
},
/** Attributes tab template */
_getAttributesFormTemplate: function( response ) {
/** edit main attributes form */
_getAttribute: function() {
var self = this;
var form = new Form({
title : 'Edit attributes',
inputs : response.edit_attributes_inputs,
operations: {
'submit_editattr' : new Ui.ButtonIcon({
tooltip : 'Save attributes of the dataset.',
icon : 'fa-floppy-o ',
title : 'Save attributes',
onclick : function() { self._submit( self, form, response, "edit_attributes" ) }
title : 'Edit attributes',
operations : {
'submit_attributes' : new Ui.ButtonIcon({
tooltip : 'Save attributes of the dataset.',
icon : 'fa-floppy-o',
title : 'Save',
onclick : function() { self._submit( 'attributes', form ) }
}),
'submit_autocorrect' : new Ui.ButtonIcon({
tooltip : 'This will inspect the dataset and attempt to correct the values of fields if they are not accurate.',
icon : 'fa-undo ',
title : 'Auto-detect',
onclick : function() { self._submit( self, form, response, "auto-detect" ) }
'submit_autodetect' : new Ui.ButtonIcon({
tooltip : 'This will inspect the dataset and attempt to correct the values of fields if they are not accurate.',
icon : 'fa-undo',
title : 'Auto-detect',
onclick : function() { self._submit( 'autodetect', form ) }
})
}
});
return form.$el;
return form;
},
/** Convert tab template */
_getConvertFormTemplate: function( response ) {
/** datatype conversion form */
_getConversion: function() {
var self = this;
var form = new Form({
title : 'Convert to new format',
inputs : response.convert_inputs,
operations: {
'submit' : new Ui.ButtonIcon({
title : 'Convert to new format',
operations : {
'submit_conversion' : new Ui.ButtonIcon({
tooltip : 'Convert the datatype to a new format.',
title : 'Convert datatype',
icon : 'fa-exchange ',
onclick : function() { self._submit( self, form, response, "convert" ) }
icon : 'fa-exchange',
onclick : function() { self._submit( 'conversion', form ) }
})
}
});
return form.$el;
return form;
},
/** Change datatype template */
_getChangeDataTypeFormTemplate: function( response ) {
/** change datatype form */
_getDatatype: function() {
var self = this;
var form = new Form({
title : 'Change datatype',
inputs : response.convert_datatype_inputs,
operations: {
'submit' : new Ui.ButtonIcon({
title : 'Change datatype',
operations : {
'submit_datatype' : new Ui.ButtonIcon({
tooltip : 'Change the datatype to a new type.',
title : 'Change datatype',
icon : 'fa-exchange ',
onclick : function() { self._submit( self, form, response, "change" ) }
icon : 'fa-exchange',
onclick : function() { self._submit( 'datatype', form ) }
})
}
});
return form.$el;
return form;
},
/** Permissions template */
_getPermissionsFormTemplate: function( response ) {
var template = "",
self = this;
if( response.can_manage_dataset ) {
var form = new Form({
title : 'Manage dataset permissions on ' + response.display_name,
inputs : response.permission_inputs,
operations: {
'submit': new Ui.ButtonIcon({
tooltip : 'Save permissions.',
title : 'Save permissions',
icon : 'fa-floppy-o ',
onclick : function() { self._submit( self, form, response, "permissions" ) }
})
}
});
return form.$el;
}
else {
var form = new Form({
title : 'View permissions',
inputs : response.permission_inputs
});
return form.$el;
}
/** dataset permissions form */
_getPermission: function() {
var self = this;
var form = new Form({
title : 'Manage dataset permissions',
operations : {
'submit_permission': new Ui.ButtonIcon({
tooltip : 'Save permissions.',
title : 'Save permissions',
icon : 'fa-floppy-o ',
onclick : function() { self._submit( 'permission', form ) }
})
}
});
return form;
},
/** Submit action */
_submit: function( self, form, response, type ) {
var form_data = form.data.create();
form_data.dataset_id = response.dataset_id;
switch( type ) {
case "edit_attributes":
form_data.save = 'Save';
break;
case "auto-detect":
form_data.detect = 'Auto-detect';
break;
case "convert":
if ( form_data.target_type !== null && form_data.target_type ) {
form_data.dataset_id = response.dataset_id;
form_data.convert_data = 'Convert';
}
break;
case "change":
form_data.change = 'Save';
break;
case "permissions":
var post_data = {};
post_data.permissions = JSON.stringify( form_data );
post_data.update_roles_button = "Save";
post_data.dataset_id = response.dataset_id;
form_data = post_data;
break;
}
self.call_ajax( self, form_data );
},
/** Reload Galaxy's history after updating dataset's attributes */
reload_history: function() {
/** reload Galaxy's history after updating dataset's attributes */
_reloadHistory: function() {
if ( window.Galaxy ) {
window.Galaxy.currHistoryPanel.loadCurrentHistory();
}
@@ -307,7 +307,7 @@ var DatasetListItemEdit = _super.extend(
&& !this.model.isDeletedOrPurged() ){
var editableDbkey = $( '<a class="value">?</a>' )
.attr( 'href', this.model.urls.edit )
.attr( 'target', this.linkTarget );
.attr( 'target', 'top' );
$details.find( '.dbkey .value' ).replaceWith( editableDbkey );
}
},
@@ -359,7 +359,7 @@ DatasetListItemEdit.prototype.templates = (function(){
'<% if( dataset.state === "failed_metadata" ){ %>',
'<div class="failed_metadata-warning warningmessagesmall">',
_l( 'An error occurred setting the metadata for this dataset' ),
'<br /><a href="<%- dataset.urls.edit %>" target="<%- view.linkTarget %>">',
'<br /><a href="<%- dataset.urls.edit %>" target="top">',
_l( 'Set it manually or retry auto-detection' ),
'</a>',
'</div>',
@@ -63,7 +63,7 @@ var DatasetAssociation = Backbone.Model
var urls = {
'purge' : 'datasets/' + id + '/purge_async',
'display' : 'datasets/' + id + '/display/?preview=True',
'edit' : 'datasets/' + id + '/edit',
'edit' : 'datasets/edit?dataset_id=' + id,
'download' : 'datasets/' + id + '/display' + this._downloadQueryParameters(),
'report_error' : 'dataset/errors?id=' + id,
'rerun' : 'tool_runner/rerun?id=' + id,
@@ -102,6 +102,7 @@ define(['utils/utils',
id : 'field-' + input_def.id,
data : data,
error_text : input_def.error_text || 'No options available',
readonly : input_def.readonly,
multiple : input_def.multiple,
optional : input_def.optional,
onchange : input_def.onchange,
+2 -1
View File
@@ -11,6 +11,7 @@ function( Utils, Portlet, Ui, FormSection, FormData ) {
icon : null,
always_refresh : true,
status : 'warning',
hide_operations : false,
onchange : function(){}
}).set( options );
this.setElement( '<div/>' );
@@ -132,7 +133,7 @@ function( Utils, Portlet, Ui, FormSection, FormData ) {
icon : options.icon,
title : options.title,
cls : options.cls,
operations : options.operations,
operations : !options.hide_operations && options.operations,
buttons : options.buttons,
collapsible : options.collapsible,
collapsed : options.collapsed,
@@ -18,6 +18,7 @@ var View = Backbone.View.extend({
searchable : true,
optional : false,
disabled : false,
readonly : false,
onchange : function(){},
value : null,
individual : false,
@@ -94,7 +95,7 @@ var View = Backbone.View.extend({
});
}
this.all_button = null;
if ( this.model.get( 'multiple' ) && !this.model.get( 'individual' ) ) {
if ( this.model.get( 'multiple' ) && !this.model.get( 'individual' ) && !this.model.get( 'readonly' ) ) {
this.all_button = new Buttons.ButtonCheck({
onclick: function() {
var new_value = [];
@@ -177,7 +178,7 @@ var View = Backbone.View.extend({
self.$select.append( $( '<option/>' ).attr( 'value', option.value ).html( _.escape( option.label ) ) );
});
}
this.model.set( 'disabled', this.length() == 0 );
this.model.set( 'disabled', this.model.get( 'readonly' ) || this.length() == 0 );
this._changeValue();
},
@@ -154,7 +154,11 @@ function( Utils, Modal, Tabs, UploadButton, UploadViewDefault, UploadViewComposi
}
// add upload tools input data
if ( items && items.length > 0 ) {
var inputs = { 'file_count' : items.length };
var inputs = {
'file_count' : items.length,
'dbkey' : items[ 0 ].get( 'genome', '?' ),
'file_type' : items[ 0 ].get( 'extension', 'auto' )
};
for ( var index in items ) {
var it = items[ index ];
it.set( 'status', 'running' );
+3
View File
@@ -551,6 +551,9 @@
.portlet-buttons {
margin-top: @ui-margin-vertical;
margin-bottom: @ui-margin-vertical;
> .btn {
margin-right: 5px;
}
}
}
.portlet-content.nopadding, .portlet-body.nopadding {
+12 -2
View File
@@ -605,15 +605,21 @@ class Frequency(Tabular):
>>> fname = get_test_fname( 'mothur_datatypetest_false.mothur.freq' )
>>> Frequency().sniff( fname )
False
# Expression count matrix (EdgeR wrapper)
>>> fname = get_test_fname( 'mothur_datatypetest_false_2.mothur.freq' )
>>> Frequency().sniff( fname )
False
"""
headers = iter_headers(filename, sep='\t')
count = 0
for line in headers:
if not line[0].startswith('@'):
# first line should be #<version string>
if count == 0:
# first line should be #<version string>
if not line[0].startswith('#') and len(line) == 1:
if not line[0].startswith('#') or len(line) != 1:
return False
else:
# all other lines should be <int> <float>
if len(line) != 2:
@@ -621,9 +627,13 @@ class Frequency(Tabular):
try:
int(line[0])
float(line[1])
if line[1].find('.') == -1:
return False
except Exception:
return False
count += 1
if count > 1:
return True
@@ -0,0 +1,7 @@
GeneID Mut1
11287 1463
11298 1345
11302 5
11303 1574
11304 361
11305 1762
-1
View File
@@ -1388,7 +1388,6 @@ class JobWrapper(object, HasResourceParameters):
# Maybe this is a legacy job, use the job working directory instead
tool_working_directory = self.working_directory
collected_datasets = {
'children': self.tool.collect_child_datasets(out_data, tool_working_directory),
'primary': self.tool.collect_primary_datasets(out_data, self.get_tool_provided_job_metadata(), tool_working_directory, input_ext, input_dbkey)
}
self.tool.collect_dynamic_collections(
+9 -40
View File
@@ -1351,7 +1351,7 @@ class History(HasTags, Dictifiable, UsesAnnotations, HasName):
hdas = self.active_datasets
for hda in hdas:
# Copy HDA.
new_hda = hda.copy(copy_children=True)
new_hda = hda.copy()
new_history.add_dataset(new_hda, set_hid=False, quota=applies_to_quota)
db_session.add(new_hda)
db_session.flush()
@@ -1856,7 +1856,7 @@ class Dataset(StorableObject):
"""Detects whether there is any data"""
return self.get_size() > 0
def mark_deleted(self, include_children=True):
def mark_deleted(self):
self.deleted = True
def is_multi_byte(self):
@@ -2189,12 +2189,6 @@ class DatasetInstance(object):
def clear_associated_files(self, metadata_safe=False, purge=False):
raise Exception("Unimplemented")
def get_child_by_designation(self, designation):
for child in self.children:
if child.designation == designation:
return child
return None
def get_converter_types(self):
return self.datatype.get_converter_types(self, _get_datatypes_registry())
@@ -2211,23 +2205,14 @@ class DatasetInstance(object):
def extend_validation_errors(self, validation_errors):
self.validation_errors.extend(validation_errors)
def mark_deleted(self, include_children=True):
def mark_deleted(self):
self.deleted = True
if include_children:
for child in self.children:
child.mark_deleted()
def mark_undeleted(self, include_children=True):
def mark_undeleted(self):
self.deleted = False
if include_children:
for child in self.children:
child.mark_undeleted()
def mark_unhidden(self, include_children=True):
def mark_unhidden(self):
self.visible = True
if include_children:
for child in self.children:
child.mark_unhidden()
def undeletable(self):
if self.purged:
@@ -2390,7 +2375,7 @@ class HistoryDatasetAssociation(DatasetInstance, HasTags, Dictifiable, UsesAnnot
self.copied_from_history_dataset_association = copied_from_history_dataset_association
self.copied_from_library_dataset_dataset_association = copied_from_library_dataset_dataset_association
def copy(self, copy_children=False, parent_id=None):
def copy(self, parent_id=None):
"""
Create a copy of this HDA.
"""
@@ -2415,9 +2400,6 @@ class HistoryDatasetAssociation(DatasetInstance, HasTags, Dictifiable, UsesAnnot
hda.set_size()
# Need to set after flushed, as MetadataFiles require dataset.id
hda.metadata = self.metadata
if copy_children:
for child in self.children:
child.copy(copy_children=copy_children, parent_id=hda.id)
if not self.datatype.copy_safe_peek:
# In some instances peek relies on dataset_id, i.e. gmaj.zip for viewing MAFs
hda.set_peek()
@@ -2481,12 +2463,6 @@ class HistoryDatasetAssociation(DatasetInstance, HasTags, Dictifiable, UsesAnnot
library_dataset.library_dataset_dataset_association_id = ldda.id
object_session(self).add(library_dataset)
object_session(self).flush()
for child in self.children:
child.to_library_dataset_dataset_association(trans,
target_folder=target_folder,
replace_dataset=replace_dataset,
parent_id=ldda.id,
user=ldda.user)
if not self.datatype.copy_safe_peek:
# In some instances peek relies on dataset_id, i.e. gmaj.zip for viewing MAFs
ldda.set_peek()
@@ -2520,7 +2496,7 @@ class HistoryDatasetAssociation(DatasetInstance, HasTags, Dictifiable, UsesAnnot
# Anon users are handled just by their single history size.
if not user:
return rval
# Gets an HDA and its children's disk usage, if the user does not already
# Gets an HDA disk usage, if the user does not already
# have an association of the same dataset
if not self.dataset.library_associations and not self.purged and not self.dataset.purged:
for hda in self.dataset.history_associations:
@@ -2530,8 +2506,6 @@ class HistoryDatasetAssociation(DatasetInstance, HasTags, Dictifiable, UsesAnnot
break
else:
rval += self.get_total_size()
for child in self.children:
rval += child.get_disk_usage(user)
return rval
def to_dict(self, view='collection', expose_dataset_path=False):
@@ -2946,14 +2920,12 @@ class LibraryDatasetDatasetAssociation(DatasetInstance, HasName):
hda.metadata = self.metadata # need to set after flushed, as MetadataFiles require dataset.id
if add_to_history and target_history:
target_history.add_dataset(hda)
for child in self.children:
child.to_history_dataset_association(target_history=target_history, parent_id=hda.id, add_to_history=False)
if not self.datatype.copy_safe_peek:
hda.set_peek() # in some instances peek relies on dataset_id, i.e. gmaj.zip for viewing MAFs
sa_session.flush()
return hda
def copy(self, copy_children=False, parent_id=None, target_folder=None):
def copy(self, parent_id=None, target_folder=None):
sa_session = object_session(self)
ldda = LibraryDatasetDatasetAssociation(name=self.name,
info=self.info,
@@ -2977,9 +2949,6 @@ class LibraryDatasetDatasetAssociation(DatasetInstance, HasName):
sa_session.flush()
# Need to set after flushed, as MetadataFiles require dataset.id
ldda.metadata = self.metadata
if copy_children:
for child in self.children:
child.copy(copy_children=copy_children, parent_id=ldda.id)
if not self.datatype.copy_safe_peek:
# In some instances peek relies on dataset_id, i.e. gmaj.zip for viewing MAFs
ldda.set_peek()
@@ -3591,7 +3560,7 @@ class DatasetCollectionElement(object, Dictifiable):
element_destination=element_destination
)
else:
new_element_object = element_object.copy(copy_children=True)
new_element_object = element_object.copy()
if destination is not None and element_object.hidden_beneath_collection_instance:
new_element_object.hidden_beneath_collection_instance = destination
# Ideally we would not need to give the following
-25
View File
@@ -1605,18 +1605,6 @@ simple_mapping(model.HistoryDatasetAssociation,
implicitly_converted_parent_datasets=relation(model.ImplicitlyConvertedDatasetAssociation,
primaryjoin=(model.ImplicitlyConvertedDatasetAssociation.table.c.hda_id ==
model.HistoryDatasetAssociation.table.c.id)),
children=relation(model.HistoryDatasetAssociation,
primaryjoin=(model.HistoryDatasetAssociation.table.c.parent_id ==
model.HistoryDatasetAssociation.table.c.id),
backref=backref("parent",
primaryjoin=(model.HistoryDatasetAssociation.table.c.parent_id ==
model.HistoryDatasetAssociation.table.c.id),
remote_side=[model.HistoryDatasetAssociation.table.c.id], uselist=False)),
visible_children=relation(model.HistoryDatasetAssociation,
primaryjoin=(
(model.HistoryDatasetAssociation.table.c.parent_id == model.HistoryDatasetAssociation.table.c.id) &
(model.HistoryDatasetAssociation.table.c.visible == true())),
remote_side=[model.HistoryDatasetAssociation.table.c.id]),
tags=relation(model.HistoryDatasetAssociationTagAssociation,
order_by=model.HistoryDatasetAssociationTagAssociation.table.c.id,
backref='history_tag_associations'),
@@ -1987,19 +1975,6 @@ mapper(model.LibraryDatasetDatasetAssociation, model.LibraryDatasetDatasetAssoci
implicitly_converted_datasets=relation(model.ImplicitlyConvertedDatasetAssociation,
primaryjoin=(model.ImplicitlyConvertedDatasetAssociation.table.c.ldda_parent_id ==
model.LibraryDatasetDatasetAssociation.table.c.id)),
children=relation(model.LibraryDatasetDatasetAssociation,
primaryjoin=(model.LibraryDatasetDatasetAssociation.table.c.parent_id ==
model.LibraryDatasetDatasetAssociation.table.c.id),
backref=backref("parent",
primaryjoin=(model.LibraryDatasetDatasetAssociation.table.c.parent_id ==
model.LibraryDatasetDatasetAssociation.table.c.id),
remote_side=[model.LibraryDatasetDatasetAssociation.table.c.id])),
visible_children=relation(model.LibraryDatasetDatasetAssociation,
primaryjoin=(
(model.LibraryDatasetDatasetAssociation.table.c.parent_id == model.LibraryDatasetDatasetAssociation.table.c.id) &
(model.LibraryDatasetDatasetAssociation.table.c.visible == true())
),
remote_side=[model.LibraryDatasetDatasetAssociation.table.c.id]),
tags=relation(model.LibraryDatasetDatasetAssociationTagAssociation,
order_by=model.LibraryDatasetDatasetAssociationTagAssociation.table.c.id,
backref='history_tag_associations'),
+1 -1
View File
@@ -885,7 +885,7 @@ class GalaxyRBACAgent(RBACAgent):
has_dataset_manage_permissions = True
break
if not has_dataset_manage_permissions:
return "At least 1 role must be associated with the <b>manage permissions</b> permission on this dataset."
return "At least 1 role must be associated with manage permissions on this dataset."
flush_needed = False
# Delete all of the current permissions on the dataset
if not new:
-68
View File
@@ -1,7 +1,6 @@
"""
Classes encapsulating galaxy tools and tool configuration.
"""
import glob
import json
import logging
import os
@@ -1560,73 +1559,6 @@ class Tool(object, Dictifiable):
"""
pass
def collect_child_datasets(self, output, job_working_directory):
"""
Look for child dataset files, create HDA and attach to parent.
"""
children = {}
# Loop through output file names, looking for generated children in
# form of 'child_parentId_designation_visibility_extension'
for name, outdata in output.items():
filenames = []
if 'new_file_path' in self.app.config.collect_outputs_from:
filenames.extend(glob.glob(os.path.join(self.app.config.new_file_path, "child_%i_*" % outdata.id)))
if 'job_working_directory' in self.app.config.collect_outputs_from:
filenames.extend(glob.glob(os.path.join(job_working_directory, "child_%i_*" % outdata.id)))
for filename in filenames:
if name not in children:
children[name] = {}
fields = os.path.basename(filename).split("_")
designation = fields[2]
visible = fields[3].lower()
if visible == "visible":
visible = True
else:
visible = False
ext = fields[4].lower()
child_dataset = self.app.model.HistoryDatasetAssociation(extension=ext,
parent_id=outdata.id,
designation=designation,
visible=visible,
dbkey=outdata.dbkey,
create_dataset=True,
sa_session=self.sa_session)
self.app.security_agent.copy_dataset_permissions(outdata.dataset, child_dataset.dataset)
# Move data from temp location to dataset location
self.app.object_store.update_from_file(child_dataset.dataset, file_name=filename, create=True)
self.sa_session.add(child_dataset)
self.sa_session.flush()
child_dataset.set_size()
child_dataset.name = "Secondary Dataset (%s)" % (designation)
child_dataset.init_meta()
child_dataset.set_meta()
child_dataset.set_peek()
# Associate new dataset with job
job = None
for assoc in outdata.creating_job_associations:
job = assoc.job
break
if job:
assoc = self.app.model.JobToOutputDatasetAssociation('__new_child_file_%s|%s__' % (name, designation), child_dataset)
assoc.job = job
self.sa_session.add(assoc)
self.sa_session.flush()
child_dataset.state = outdata.state
self.sa_session.add(child_dataset)
self.sa_session.flush()
# Add child to return dict
children[name][designation] = child_dataset
# Need to update all associated output hdas, i.e. history was
# shared with job running
for dataset in outdata.dataset.history_associations:
if outdata == dataset:
continue
# Create new child dataset
child_data = child_dataset.copy(parent_id=dataset.id)
self.sa_session.add(child_data)
self.sa_session.flush()
return children
def collect_primary_datasets(self, output, tool_provided_metadata, job_working_directory, input_ext, input_dbkey="?"):
"""
Find any additional datasets generated by a tool and attach (for
-6
View File
@@ -91,7 +91,6 @@ class ToolEvaluator(object):
self.dataset = dataset
self.file_name = dataset.file_name
self.metadata = dict()
self.children = []
special = get_special()
if special:
@@ -303,9 +302,6 @@ class ToolEvaluator(object):
dataset_path = input_dataset_paths[real_path]
wrapper_kwds['dataset_path'] = dataset_path
param_dict[name] = DatasetFilenameWrapper(data, **wrapper_kwds)
if data:
for child in data.children:
param_dict["_CHILD___%s___%s" % (name, child.designation)] = DatasetFilenameWrapper(child)
def __populate_output_collection_wrappers(self, param_dict, output_collections, output_paths, job_working_directory):
output_dataset_paths = dataset_path_rewrites(output_paths)
@@ -355,8 +351,6 @@ class ToolEvaluator(object):
# Provide access to a path to store additional files
# TODO: path munging for cluster/dataset server relocatability
param_dict[name].files_path = os.path.abspath(os.path.join(job_working_directory, "dataset_%s_files" % (hda.dataset.id)))
for child in hda.children:
param_dict["_CHILD___%s___%s" % (name, child.designation)] = DatasetFilenameWrapper(child)
for out_name, output in self.tool.outputs.items():
if out_name not in param_dict and output.filters:
# Assume the reason we lack this output is because a filter
+3 -3
View File
@@ -9,9 +9,9 @@
<inputs>
<param type="data_collection" name="input" label="Input Collection" />
<param type="select" name="join_identifier" label="Join collection identifiers using" help="">
<option value="_">_</option>
<option value=":">:</option>
<option value="-">-</option>
<option value="_">underscore ( _ )</option>
<option value=":">colon ( : )</option>
<option value="-">dash ( - )</option>
</param>
</inputs>
<outputs>
+1 -2
View File
@@ -6,7 +6,7 @@ import shutil
import tempfile
from json import dumps, loads
from sqlalchemy.orm import eagerload, eagerload_all
from sqlalchemy.orm import eagerload_all
from sqlalchemy.sql import expression
from galaxy import model
@@ -322,7 +322,6 @@ class JobExportHistoryArchiveWrapper(object, UsesAnnotations):
"""
query = (trans.sa_session.query(trans.model.HistoryDatasetAssociation)
.filter(trans.model.HistoryDatasetAssociation.history == history)
.options(eagerload("children"))
.join("dataset")
.options(eagerload_all("dataset.actions"))
.order_by(trans.model.HistoryDatasetAssociation.hid)
+215 -306
View File
@@ -1,7 +1,6 @@
import logging
import os
import urllib
import json
from markupsafe import escape
import paste.httpexceptions
@@ -13,11 +12,11 @@ from galaxy import managers
from galaxy.datatypes.display_applications.util import decode_dataset_user, encode_dataset_user
from galaxy.exceptions import RequestParameterInvalidException
from galaxy.model.item_attrs import UsesAnnotations, UsesItemRatings
from galaxy.util import inflector, smart_str
from galaxy.util import inflector, smart_str, sanitize_text
from galaxy.util.sanitize_html import sanitize_html
from galaxy.web import form_builder
from galaxy.web.base.controller import BaseUIController, ERROR, SUCCESS, url_for, UsesExtendedMetadataMixin
from galaxy.web.framework.helpers import grids, iff, time_ago, to_unicode
from galaxy.web.framework.helpers import grids, iff, time_ago
log = logging.getLogger(__name__)
@@ -239,55 +238,23 @@ class DatasetInterface(BaseUIController, UsesAnnotations, UsesItemRatings, UsesE
ck_size = int(ck_size)
return data.datatype.display_data(trans, data, preview, filename, to_ext, offset=offset, ck_size=ck_size, **kwd)
@web.expose
@web.json
def edit(self, trans, dataset_id=None, filename=None, hid=None, **kwd):
"""Allows user to modify parameters of an HDA."""
@web.expose_api_anonymous
def get_edit(self, trans, dataset_id=None, **kwd):
"""Produces the input definitions available to modify dataset attributes"""
message = None
status = 'done'
error = False
def __ok_to_edit_metadata(dataset_id):
# prevent modifying metadata when dataset is queued or running as input/output
# This code could be more efficient, i.e. by using mappers, but to prevent slowing down loading a History panel, we'll leave the code here for now
for job_to_dataset_association in trans.sa_session.query(
self.app.model.JobToInputDatasetAssociation) \
.filter_by(dataset_id=dataset_id) \
.all() \
+ trans.sa_session.query(self.app.model.JobToOutputDatasetAssociation) \
.filter_by(dataset_id=dataset_id) \
.all():
if job_to_dataset_association.job.state not in [job_to_dataset_association.job.states.OK, job_to_dataset_association.job.states.ERROR, job_to_dataset_association.job.states.DELETED]:
return False
return True
if hid is not None:
history = trans.get_history()
# TODO: hid handling
data = history.datasets[int(hid) - 1]
id = None
elif dataset_id is not None:
status = None
if dataset_id is not None:
id = self.decode_id(dataset_id)
data = trans.sa_session.query(self.app.model.HistoryDatasetAssociation).get(id)
else:
trans.log_event("dataset_id and hid are both None, cannot load a dataset to edit")
return {
status: 'error',
message: 'You must provide a history dataset id to edit.'
}
trans.log_event("dataset_id is None, cannot load a dataset to edit.")
return self.message_exception(trans, 'You must provide a dataset id to edit attributes.')
if data is None:
trans.log_event("Problem retrieving dataset (encoded: %s, decoded: %s) with history id %s." % (str(dataset_id), str(id), str(hid)))
return {
status: 'error',
message: "History dataset id is invalid."
}
trans.log_event("Problem retrieving dataset id (%s)." % dataset_id)
return self.message_exception(trans, 'The dataset id is invalid.')
if dataset_id is not None and data.history.user is not None and data.history.user != trans.user:
trans.log_event("User attempted to edit an HDA they do not own (encoded: %s, decoded: %s)." % (dataset_id, id))
# Do not reveal the dataset's existence
return {
status: 'error',
message: "History dataset id is invalid."
}
current_user_roles = trans.get_current_user_roles()
trans.log_event("User attempted to edit a dataset they do not own (encoded: %s, decoded: %s)." % (dataset_id, id))
return self.message_exception(trans, 'The dataset id is invalid.')
if data.history.user and not data.dataset.has_manage_permissions_roles(trans):
# Permission setting related to DATASET_MANAGE_PERMISSIONS was broken for a period of time,
# so it is possible that some Datasets have no roles associated with the DATASET_MANAGE_PERMISSIONS
@@ -297,300 +264,242 @@ class DatasetInterface(BaseUIController, UsesAnnotations, UsesItemRatings, UsesE
trans.app.security_agent.set_dataset_permission(data.dataset, permissions)
if self._can_access_dataset(trans, data):
if data.state == trans.model.Dataset.states.UPLOAD:
return {
status: 'error',
message: "Please wait until this dataset finishes uploading before attempting to edit its metadata."
}
params = util.Params(kwd, sanitize=False)
if params.change:
# The user clicked the Save button on the 'Change data type' form
if data.datatype.allow_datatype_change and trans.app.datatypes_registry.get_datatype_by_extension(params.datatype).allow_datatype_change:
# prevent modifying datatype when dataset is queued or running as input/output
if not __ok_to_edit_metadata(data.id):
message = "This dataset is currently being used as input or output. You cannot change datatype until the jobs have completed or you have canceled them."
error = True
else:
trans.app.datatypes_registry.change_datatype(data, params.datatype)
trans.sa_session.flush()
trans.app.datatypes_registry.set_external_metadata_tool.tool_action.execute(trans.app.datatypes_registry.set_external_metadata_tool, trans, incoming={'input1': data}, overwrite=False) # overwrite is False as per existing behavior
message = "Changed the type of dataset %s to %s." % (to_unicode(data.name), params.datatype)
else:
message = "You are unable to change datatypes in this manner. Changing %s to %s is not allowed." % (data.extension, params.datatype)
error = True
elif params.save:
# The user clicked the Save button on the 'Edit Attributes' form
data.name = params.name if params.name else ''
data.info = params.info if params.info else ''
message = ''
if __ok_to_edit_metadata(data.id):
# The following for loop will save all metadata_spec items
for name, spec in data.datatype.metadata_spec.items():
if spec.get("readonly"):
continue
setattr(data.metadata, name, spec.unwrap(params.get(name, None)))
data.datatype.after_setting_metadata(data)
# Sanitize annotation before adding it.
if params.annotation:
annotation = sanitize_html(params.annotation, 'utf-8', 'text/html')
self.add_item_annotation(trans.sa_session, trans.get_user(), data, annotation)
# This block on controller code is inactive until the 'extended_metadata' edit box is added back into the UI
# Add or delete extended metadata
# if params.extended_metadata:
# em_string = params.extended_metadata
# if len(em_string):
# em_payload = None
# try:
# em_payload = loads(em_string)
# except Exception as e:
# message = 'Invalid JSON input'
# error = True
# if em_payload is not None:
# if data is not None:
# ex_obj = self.get_item_extended_metadata_obj(trans, data)
# if ex_obj is not None:
# self.unset_item_extended_metadata_obj(trans, data)
# self.delete_extended_metadata(trans, ex_obj)
# ex_obj = self.create_extended_metadata(trans, em_payload)
# self.set_item_extended_metadata_obj(trans, data, ex_obj)
# message = "Updated Extended metadata '%s'." % data.name
# status = 'done'
# else:
# message = "data not found"
# error = True
# else:
# if data is not None:
# ex_obj = self.get_item_extended_metadata_obj(trans, data)
# if ex_obj is not None:
# self.unset_item_extended_metadata_obj(trans, data)
# self.delete_extended_metadata(trans, ex_obj)
# message = "Deleted Extended metadata '%s'." % data.name
# status = 'done'
# If setting metadata previously failed and all required elements have now been set, clear the failed state.
if data._state == trans.model.Dataset.states.FAILED_METADATA and not data.missing_meta():
data._state = None
trans.sa_session.flush()
if message:
message = "Attributes updated. %s" % message
else:
message = "Attributes updated."
else:
trans.sa_session.flush()
message = "Attributes updated, but metadata could not be changed because this dataset is currently being used as input or output. You must cancel or wait for these jobs to complete before changing metadata."
status = "warning"
elif params.detect:
# The user clicked the Auto-detect button on the 'Edit Attributes' form
# prevent modifying metadata when dataset is queued or running as input/output
if not __ok_to_edit_metadata(data.id):
message = "This dataset is currently being used as input or output. You cannot change metadata until the jobs have completed or you have canceled them."
error = True
else:
for name, spec in data.metadata.spec.items():
# We need to be careful about the attributes we are resetting
if name not in ['name', 'info', 'dbkey', 'base_name']:
if spec.get('default'):
setattr(data.metadata, name, spec.unwrap(spec.get('default')))
message = 'Attributes have been queued to be updated.'
trans.app.datatypes_registry.set_external_metadata_tool.tool_action.execute(trans.app.datatypes_registry.set_external_metadata_tool, trans, incoming={'input1': data})
trans.sa_session.flush()
elif params.convert_data:
target_type = kwd.get("target_type", None)
if target_type:
message = data.datatype.convert_dataset(trans, data, target_type)
elif params.update_roles_button:
if not trans.user:
return {
status: 'error',
message: "You must be logged in if you want to change permissions."
}
if trans.app.security_agent.can_manage_dataset(current_user_roles, data.dataset):
permitted_actions = trans.app.model.Dataset.permitted_actions.items()
payload_permissions = json.loads(params.permissions)
# The user associated the DATASET_ACCESS permission on the dataset with 1 or more roles. We
# need to ensure that they did not associate roles that would cause accessibility problems.
permissions, in_roles, error, message = \
trans.app.security_agent.derive_roles_from_access(trans, data.dataset.id, 'root', **payload_permissions)
if error:
# Keep the original role associations for the DATASET_ACCESS permission on the dataset.
access_action = trans.app.security_agent.get_action(trans.app.security_agent.permitted_actions.DATASET_ACCESS.action)
permissions[access_action] = data.dataset.get_access_roles(trans)
status = 'error'
else:
error = trans.app.security_agent.set_all_dataset_permissions(data.dataset, permissions)
if error:
message += error
status = 'error'
else:
message = 'Your changes completed successfully.'
trans.sa_session.refresh(data.dataset)
else:
message = "You are not authorized to change this dataset's permissions."
error = True
else:
if "dbkey" in data.datatype.metadata_spec and not data.metadata.dbkey:
# Copy dbkey into metadata, for backwards compatability
# This looks like it does nothing, but getting the dbkey
# returns the metadata dbkey unless it is None, in which
# case it resorts to the old dbkey. Setting the dbkey
# sets it properly in the metadata
# This is likely no longer required, since the dbkey exists entirely within metadata (the old_dbkey field is gone): REMOVE ME?
data.metadata.dbkey = data.dbkey
return self.message_exception(trans, 'Please wait until this dataset finishes uploading before attempting to edit its metadata.')
# let's not overwrite the imported datatypes module with the variable datatypes?
# the built-in 'id' is overwritten in lots of places as well
ldatatypes = [(dtype_name, dtype_name) for dtype_name, dtype_value in trans.app.datatypes_registry.datatypes_by_extension.iteritems() if dtype_value.allow_datatype_change]
ldatatypes.sort()
all_roles = trans.app.security_agent.get_legitimate_roles(trans, data.dataset, 'root')
all_roles = [(r.name, trans.security.encode_id(r.id)) for r in trans.app.security_agent.get_legitimate_roles(trans, data.dataset, 'root')]
data_metadata = [(name, spec) for name, spec in data.metadata.spec.items()]
converters_collection = [(key, value.name) for key, value in data.get_converter_types().items()]
can_manage_dataset = trans.app.security_agent.can_manage_dataset(current_user_roles, data.dataset)
if error:
status = 'error'
edit_attributes_inputs = list()
convert_inputs = list()
convert_datatype_inputs = list()
permission_inputs = list()
edit_attributes_inputs.append({
can_manage_dataset = trans.app.security_agent.can_manage_dataset(trans.get_current_user_roles(), data.dataset)
# attribute editing
attribute_inputs = [{
'name' : 'name',
'type' : 'text',
'label': 'Name:',
'label': 'Name',
'value': data.get_display_name()
})
edit_attributes_inputs.append({
}, {
'name' : 'info',
'type' : 'text',
'label': 'Info:',
'area' : True,
'label': 'Info',
'value': data.info
})
edit_attributes_inputs.append({
}, {
'name' : 'annotation',
'type' : 'text',
'area' : True,
'label': 'Annotation',
'value': self.get_item_annotation_str(trans.sa_session, trans.user, data),
'help' : 'Add an annotation or notes to a dataset; annotations are available when a history is viewed.'
})
}]
for name, spec in data_metadata:
if spec.visible:
attributes = data.metadata.get_metadata_parameter(name, trans=trans)
if type(attributes) is form_builder.SelectField:
edit_attributes_inputs.append({
'type': 'select',
'multiple': attributes.multiple,
'optional': attributes.optional,
'name': name,
'label': spec.desc,
'options': attributes.options,
'value': attributes.value if attributes.multiple else [attributes.value]
attribute_inputs.append({
'type' : 'select',
'multiple' : attributes.multiple,
'optional' : attributes.optional,
'name' : name,
'label' : spec.desc,
'options' : attributes.options,
'value' : attributes.value if attributes.multiple else [attributes.value]
})
elif type(attributes) is form_builder.TextField:
edit_attributes_inputs.append({
'type': 'text',
'name': name,
'label': spec.desc,
'value': attributes.value,
'readonly': spec.get('readonly')
attribute_inputs.append({
'type' : 'text',
'name' : name,
'label' : spec.desc,
'value' : attributes.value,
'readonly' : spec.get('readonly')
})
if data.missing_meta():
edit_attributes_inputs.append({
'name' : 'errormsg',
'type' : 'text',
'label': 'Error Message',
'value': 'Required metadata values are missing. Some of these values may not be editable by the user. Selecting "Auto-detect" will attempt to fix these values.',
'class' : 'errormessagesmall',
'readonly' : True
})
convert_inputs.append({
'type': 'select',
'name': 'target_type',
'label': 'Name:',
'help': 'This will create a new dataset with the contents of this dataset converted to a new format.',
'options': [(convert_name, convert_id) for convert_id, convert_name in converters_collection]
})
convert_datatype_inputs.append({
'type': 'select',
'name': 'datatype',
'label': 'New Type:',
'help': 'This will change the datatype of the existing dataset but not modify its contents. Use this if Galaxy has incorrectly guessed the type of your dataset.',
'options': [(ext_name, ext_id) for ext_id, ext_name in ldatatypes],
'value': [ext_id for ext_id, ext_name in ldatatypes if ext_id == data.ext]
})
if can_manage_dataset:
permitted_actions = trans.app.model.Dataset.permitted_actions.items()
saved_role_ids = {}
for action, roles in trans.app.security_agent.get_permissions(data.dataset).items():
for role in roles:
saved_role_ids[action.action] = role.id
for index, action in permitted_actions:
if action == trans.app.security_agent.permitted_actions.DATASET_ACCESS:
help_text = action.description + '<br/>NOTE: Users must have every role associated with this dataset in order to access it.'
else:
help_text = action.description
permission_inputs.append({
'type': 'select',
'multiple': True,
'optional': True,
'name': index,
'label': action.action,
'help': help_text,
'options': [(r.name, r.id) for r in all_roles],
'value': saved_role_ids[action.action] if action.action in saved_role_ids else []
})
elif trans.user:
message = 'Required metadata values are missing. Some of these values may not be editable by the user. Selecting "Auto-detect" will attempt to fix these values.'
status = 'warning'
# datatype conversion
conversion_options = [(convert_name, convert_id) for convert_id, convert_name in converters_collection]
conversion_disable = len(conversion_options) == 0
conversion_inputs = [{
'type' : 'select',
'name' : 'target_type',
'label' : 'Name',
'help' : 'This will create a new dataset with the contents of this dataset converted to a new format.',
'options' : conversion_options
}]
# datatype changeing
datatype_options = [(ext_name, ext_id) for ext_id, ext_name in ldatatypes]
datatype_disable = len(datatype_options) == 0
datatype_inputs = [{
'type' : 'select',
'name' : 'datatype',
'label' : 'New Type',
'options' : datatype_options,
'value' : [ext_id for ext_id, ext_name in ldatatypes if ext_id == data.ext],
'help' : 'This will change the datatype of the existing dataset but not modify its contents. Use this if Galaxy has incorrectly guessed the type of your dataset.',
}]
# permissions
permission_disable = True
permission_inputs = list()
if trans.user:
if data.dataset.actions:
permitted_actions = trans.app.model.Dataset.permitted_actions.items()
in_roles = {}
for action, roles in trans.app.security_agent.get_permissions(data.dataset).items():
if roles:
role_inputs = list()
for role in roles:
role_inputs.append({
'name': role.name + action.action,
'type': 'text',
'label': action.description,
'value': role.name,
'readonly': True
})
view_permissions = {'name': action.action, 'label': action.action, 'type': 'section', 'inputs': role_inputs}
permission_inputs.append(view_permissions)
in_roles[action.action] = [trans.security.encode_id(role.id) for role in roles]
for index, action in permitted_actions:
if action == trans.app.security_agent.permitted_actions.DATASET_ACCESS:
help_text = action.description + '<br/>NOTE: Users must have every role associated with this dataset in order to access it.'
else:
help_text = action.description
permission_inputs.append({
'type' : 'select',
'multiple' : True,
'optional' : True,
'name' : index,
'label' : action.action,
'help' : help_text,
'options' : all_roles,
'value' : in_roles.get(action.action),
'readonly' : not can_manage_dataset
})
permission_disable = not can_manage_dataset
else:
permission_inputs.append({
'name': 'access_public',
'type': 'text',
'label': 'Public access',
'value': 'This dataset is accessible by everyone (it is public).',
'readonly': True
'name' : 'access_public',
'type' : 'hidden',
'label' : 'This dataset is accessible by everyone (it is public).',
'readonly' : True
})
else:
permission_inputs.append({
'name': 'no_access',
'type': 'text',
'label': 'No access',
'value': 'Permissions not available (not logged in).',
'readonly': True
'name' : 'no_access',
'type' : 'hidden',
'label' : 'Permissions not available (not logged in).',
'readonly' : True
})
return {
'display_name': data.get_display_name(),
'message': message,
'status': status,
'dataset_id': dataset_id,
'can_manage_dataset': can_manage_dataset,
'edit_attributes_inputs': edit_attributes_inputs,
'convert_inputs': convert_inputs,
'convert_datatype_inputs': convert_datatype_inputs,
'permission_inputs': permission_inputs
'display_name' : data.get_display_name(),
'message' : message,
'status' : status,
'dataset_id' : dataset_id,
'attribute_inputs' : attribute_inputs,
'conversion_inputs' : conversion_inputs,
'conversion_disable': conversion_disable,
'datatype_inputs' : datatype_inputs,
'datatype_disable' : datatype_disable,
'permission_inputs' : permission_inputs,
'permission_disable': permission_disable
}
else:
return {
status: 'error',
message: "You do not have permission to edit this dataset's ( id: %s ) information." % str(dataset_id)
}
return self.message_exception(trans, 'You do not have permission to edit this dataset\'s ( id: %s ) information.' % str(dataset_id))
@web.expose_api_anonymous
def set_edit(self, trans, payload=None, **kwd):
"""Allows user to modify parameters of an HDA."""
def __ok_to_edit_metadata(dataset_id):
# prevent modifying metadata when dataset is queued or running as input/output
# This code could be more efficient, i.e. by using mappers, but to prevent slowing down loading a History panel, we'll leave the code here for now
for job_to_dataset_association in trans.sa_session.query(
self.app.model.JobToInputDatasetAssociation).filter_by(dataset_id=dataset_id).all() \
+ trans.sa_session.query(self.app.model.JobToOutputDatasetAssociation).filter_by(dataset_id=dataset_id).all():
if job_to_dataset_association.job.state not in [job_to_dataset_association.job.states.OK, job_to_dataset_association.job.states.ERROR, job_to_dataset_association.job.states.DELETED]:
return False
return True
message = None
status = 'success'
dataset_id = payload.get('dataset_id')
operation = payload.get('operation')
if dataset_id is not None:
id = self.decode_id(dataset_id)
data = trans.sa_session.query(self.app.model.HistoryDatasetAssociation).get(id)
if operation == 'attributes':
# The user clicked the Save button on the 'Edit Attributes' form
data.name = payload.get('name')
data.info = payload.get('info')
if __ok_to_edit_metadata(data.id):
# The following for loop will save all metadata_spec items
for name, spec in data.datatype.metadata_spec.items():
if not spec.get('readonly'):
setattr(data.metadata, name, spec.unwrap(payload.get(name) or None))
data.datatype.after_setting_metadata(data)
# Sanitize annotation before adding it.
if payload.get('annotation'):
annotation = sanitize_html(payload.get('annotation'), 'utf-8', 'text/html')
self.add_item_annotation(trans.sa_session, trans.get_user(), data, annotation)
# if setting metadata previously failed and all required elements have now been set, clear the failed state.
if data._state == trans.model.Dataset.states.FAILED_METADATA and not data.missing_meta():
data._state = None
message = 'Attributes updated. %s' % message if message else 'Attributes updated.'
else:
message = 'Attributes updated, but metadata could not be changed because this dataset is currently being used as input or output. You must cancel or wait for these jobs to complete before changing metadata.'
status = 'warning'
trans.sa_session.flush()
elif operation == 'datatype':
# The user clicked the Save button on the 'Change data type' form
datatype = payload.get('datatype')
if data.datatype.allow_datatype_change and trans.app.datatypes_registry.get_datatype_by_extension(datatype).allow_datatype_change:
# prevent modifying datatype when dataset is queued or running as input/output
if not __ok_to_edit_metadata(data.id):
return self.message_exception(trans, 'This dataset is currently being used as input or output. You cannot change datatype until the jobs have completed or you have canceled them.')
else:
trans.app.datatypes_registry.change_datatype(data, datatype)
trans.sa_session.flush()
trans.app.datatypes_registry.set_external_metadata_tool.tool_action.execute(trans.app.datatypes_registry.set_external_metadata_tool, trans, incoming={'input1': data}, overwrite=False) # overwrite is False as per existing behavior
message = 'Changed the type to %s.' % datatype
else:
return self.message_exception(trans, 'You are unable to change datatypes in this manner. Changing %s to %s is not allowed.' % (data.extension, datatype))
elif operation == 'autodetect':
# The user clicked the Auto-detect button on the 'Edit Attributes' form
# prevent modifying metadata when dataset is queued or running as input/output
if not __ok_to_edit_metadata(data.id):
return self.message_exception(trans, 'This dataset is currently being used as input or output. You cannot change metadata until the jobs have completed or you have canceled them.')
else:
for name, spec in data.metadata.spec.items():
# We need to be careful about the attributes we are resetting
if name not in ['name', 'info', 'dbkey', 'base_name']:
if spec.get('default'):
setattr(data.metadata, name, spec.unwrap(spec.get('default')))
message = 'Attributes have been queued to be updated.'
trans.app.datatypes_registry.set_external_metadata_tool.tool_action.execute(trans.app.datatypes_registry.set_external_metadata_tool, trans, incoming={'input1': data})
trans.sa_session.flush()
elif operation == 'conversion':
target_type = payload.get('target_type')
if target_type:
try:
message = data.datatype.convert_dataset(trans, data, target_type)
except Exception as e:
return self.message_exception(trans, str(e))
elif operation == 'permission':
if not trans.user:
return self.message_exception(trans, 'You must be logged in if you want to change permissions.')
if trans.app.security_agent.can_manage_dataset(trans.get_current_user_roles(), data.dataset):
permitted_actions = trans.app.model.Dataset.permitted_actions.items()
payload_permissions = {}
for action, key in permitted_actions:
payload_permissions[action] = [trans.security.decode_id(role_id) for role_id in util.listify(payload.get(action))]
# The user associated the DATASET_ACCESS permission on the dataset with 1 or more roles. We
# need to ensure that they did not associate roles that would cause accessibility problems.
permissions, in_roles, error, message = \
trans.app.security_agent.derive_roles_from_access(trans, data.dataset.id, 'root', **payload_permissions)
if error:
# Keep the original role associations for the DATASET_ACCESS permission on the dataset.
access_action = trans.app.security_agent.get_action(trans.app.security_agent.permitted_actions.DATASET_ACCESS.action)
permissions[access_action] = data.dataset.get_access_roles(trans)
trans.sa_session.refresh(data.dataset)
return self.message_exception(trans, message)
else:
error = trans.app.security_agent.set_all_dataset_permissions(data.dataset, permissions)
trans.sa_session.refresh(data.dataset)
if error:
return self.message_exception(trans, error)
else:
message = 'Your changes completed successfully.'
else:
return self.message_exception(trans, 'You are not authorized to change this dataset\'s permissions.')
else:
return self.message_exception(trans, 'Invalid operation identifier (%s).' % operation)
return {'status': status, 'message': sanitize_text(message)}
@web.expose
@web.json
@@ -1238,7 +1147,7 @@ class DatasetInterface(BaseUIController, UsesAnnotations, UsesItemRatings, UsesE
else:
for hist in target_histories:
if content.history_content_type == "dataset":
hist.add_dataset(content.copy(copy_children=True))
hist.add_dataset(content.copy())
else:
copy_collected_datasets = True
copy_kwds = {}
@@ -1296,7 +1205,7 @@ class DatasetInterface(BaseUIController, UsesAnnotations, UsesItemRatings, UsesE
invalid_datasets += 1
else:
for hist in target_histories:
dataset_copy = data.copy(copy_children=True)
dataset_copy = data.copy()
if imported:
dataset_copy.name = "imported: " + dataset_copy.name
hist.add_dataset(dataset_copy)
@@ -495,7 +495,6 @@ class HistoryController(BaseUIController, SharableMixin, UsesAnnotations, UsesIt
trans.sa_session.expunge(trans.history)
history = trans.sa_session.query(model.History).options(
eagerload_all('active_datasets.creating_job_associations.job.workflow_invocation_step.workflow_invocation.workflow'),
eagerload_all('active_datasets.children')
).get(id)
assert history
# TODO: formalize to trans.show_error
@@ -221,25 +221,6 @@ class RootController(controller.JSAppLauncher, UsesAnnotations):
else:
return "No dataset with id '%s'" % str(id)
@web.expose
def display_child(self, trans, parent_id=None, designation=None, tofile=None, toext=".txt"):
"""Returns child data directly into the browser, based upon parent_id and designation.
"""
# TODO: unencoded id
try:
data = trans.sa_session.query(self.app.model.HistoryDatasetAssociation).get(parent_id)
if data:
child = data.get_child_by_designation(designation)
if child:
current_user_roles = trans.get_current_user_roles()
if trans.app.security_agent.can_access_dataset(current_user_roles, child):
return self.display(trans, id=child.id, tofile=tofile, toext=toext)
else:
return "You are not privileged to access this dataset."
except Exception:
pass
return "A child named %s could not be found for data %s" % (designation, parent_id)
@web.expose
def display_as(self, trans, id=None, display_app=None, **kwd):
"""Returns a file in a format that can successfully be displayed in display_app.
+1 -1
View File
@@ -362,7 +362,7 @@ class InputModule(WorkflowModule):
for input_dataset_hda in list(step_outputs.values()):
content_type = input_dataset_hda.history_content_type
if content_type == "dataset":
new_hda = input_dataset_hda.copy(copy_children=True)
new_hda = input_dataset_hda.copy()
invocation.history.add_dataset(new_hda)
step_outputs['input_ds_copy'] = new_hda
elif content_type == "dataset_collection":
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
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
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,2 +1,2 @@
"use strict";define(["utils/utils","mvc/ui/ui-tabs","mvc/ui/ui-misc","mvc/form/form-view"],function(t,e,a,s){return{View:Backbone.View.extend({initialize:function(){this.setElement("<div/>"),this.model=new Backbone.Model({dataset_id:Galaxy.params.dataset_id}),this.render()},render:function(){var e=Galaxy.root+"dataset/edit",a=this;t.get({url:e,data:{dataset_id:a.model.get("dataset_id")},success:function(t){a.render_attribute_page(a,t)},error:function(t){var e={status:"error",message:"Error occured while loading the dataset.",persistent:!0,cls:"errormessage"};a.display_message(e,a.$(".response-message"))}})},render_attribute_page:function(t,e){var a={message:e.message,status:e.status,persistent:!0,cls:e.status+"message"};t.$el.empty().append(t._templateHeader()),t.display_message(a,t.$(".response-message")),t.create_tabs(e,t.$(".edit-attr"))},call_ajax:function(t,e,a){var s=Galaxy.root+"dataset/edit";$.ajax({type:"PUT",url:s,data:e,success:function(e){t.render_attribute_page(t,e),t.reload_history()},error:function(e){var a={status:"error",message:"Error occured while saving. Please fill all the required fields and try again.",persistent:!0,cls:"errormessage"};t.display_message(a,t.$(".response-message"))}})},display_message:function(t,e){e.empty().html(new a.Message(t).$el)},create_tabs:function(t,a){var s=this;s.tabs=new e.View,s.tabs.add({id:"attributes",title:"Attributes",icon:"fa fa-bars",tooltip:"Edit dataset attributes",$el:s._getAttributesFormTemplate(t)}),s.tabs.add({id:"convert",title:"Convert",icon:"fa-gear",tooltip:"Convert to new format",$el:s._getConvertFormTemplate(t)}),s.tabs.add({id:"datatype",title:"Datatypes",icon:"fa-database",tooltip:"Change data type",$el:s._getChangeDataTypeFormTemplate(t)}),s.tabs.add({id:"permissions",title:"Permissions",icon:"fa-user",tooltip:"Permissions",$el:s._getPermissionsFormTemplate(t)}),a.append(s.tabs.$el),s.tabs.showTab("attributes")},_templateHeader:function(){return'<div class="page-container edit-attr"><div class="response-message"></div><h3>Edit Dataset Attributes</h3></div>'},_getAttributesFormTemplate:function(t){var e=this,i=new s({title:"Edit attributes",inputs:t.edit_attributes_inputs,operations:{submit_editattr:new a.ButtonIcon({tooltip:"Save attributes of the dataset.",icon:"fa-floppy-o ",title:"Save attributes",onclick:function(){e._submit(e,i,t,"edit_attributes")}}),submit_autocorrect:new a.ButtonIcon({tooltip:"This will inspect the dataset and attempt to correct the values of fields if they are not accurate.",icon:"fa-undo ",title:"Auto-detect",onclick:function(){e._submit(e,i,t,"auto-detect")}})}});return i.$el},_getConvertFormTemplate:function(t){var e=this,i=new s({title:"Convert to new format",inputs:t.convert_inputs,operations:{submit:new a.ButtonIcon({tooltip:"Convert the datatype to a new format.",title:"Convert datatype",icon:"fa-exchange ",onclick:function(){e._submit(e,i,t,"convert")}})}});return i.$el},_getChangeDataTypeFormTemplate:function(t){var e=this,i=new s({title:"Change datatype",inputs:t.convert_datatype_inputs,operations:{submit:new a.ButtonIcon({tooltip:"Change the datatype to a new type.",title:"Change datatype",icon:"fa-exchange ",onclick:function(){e._submit(e,i,t,"change")}})}});return i.$el},_getPermissionsFormTemplate:function(t){var e=this;if(t.can_manage_dataset)return(i=new s({title:"Manage dataset permissions on "+t.display_name,inputs:t.permission_inputs,operations:{submit:new a.ButtonIcon({tooltip:"Save permissions.",title:"Save permissions",icon:"fa-floppy-o ",onclick:function(){e._submit(e,i,t,"permissions")}})}})).$el;var i=new s({title:"View permissions",inputs:t.permission_inputs});return i.$el},_submit:function(t,e,a,s){var i=e.data.create();switch(i.dataset_id=a.dataset_id,s){case"edit_attributes":i.save="Save";break;case"auto-detect":i.detect="Auto-detect";break;case"convert":null!==i.target_type&&i.target_type&&(i.dataset_id=a.dataset_id,i.convert_data="Convert");break;case"change":i.change="Save";break;case"permissions":var n={};n.permissions=JSON.stringify(i),n.update_roles_button="Save",n.dataset_id=a.dataset_id,i=n}t.call_ajax(t,i)},reload_history:function(){window.Galaxy&&window.Galaxy.currHistoryPanel.loadCurrentHistory()}})}});
"use strict";define(["utils/utils","mvc/ui/ui-tabs","mvc/ui/ui-misc","mvc/form/form-view"],function(t,e,i,a){return{View:Backbone.View.extend({initialize:function(){this.setElement("<div/>"),this.model=new Backbone.Model({dataset_id:Galaxy.params.dataset_id}),this.message=new i.Message({persistent:!0}),this.tabs=this._createTabs(),this.$el.append($("<h4/>").append("Edit dataset attributes")).append(this.message.$el).append("<p/>").append(this.tabs.$el).hide(),this.render()},render:function(){var t=this;$.ajax({url:Galaxy.root+"dataset/get_edit?dataset_id="+t.model.get("dataset_id"),success:function(e){!t.initial_message&&t.message.update(e),t.initial_message=!0,_.each(t.forms,function(t,i){t.model.set("inputs",e[i+"_inputs"]),t.model.set("hide_operations",e[i+"_disable"]),t.render()}),t.$el.show()},error:function(e){var i=e.responseJSON&&e.responseJSON.err_msg;t.message.update({status:"danger",message:i||"Error occured while loading the dataset."})}})},_submit:function(t,e){var i=this,a=e.data.create();a.dataset_id=this.model.get("dataset_id"),a.operation=t,$.ajax({type:"PUT",url:Galaxy.root+"dataset/set_edit",data:a,success:function(t){i.message.update(t),i.render(),i._reloadHistory()},error:function(t){var e=t.responseJSON&&t.responseJSON.err_msg;i.message.update({status:"danger",message:e||"Error occured while editing the dataset attributes."})}})},_createTabs:function(){this.forms={attribute:this._getAttribute(),conversion:this._getConversion(),datatype:this._getDatatype(),permission:this._getPermission()};var t=new e.View;return t.add({id:"attribute",title:"Attributes",icon:"fa fa-bars",tooltip:"Edit dataset attributes",$el:this.forms.attribute.$el}),t.add({id:"convert",title:"Convert",icon:"fa-gear",tooltip:"Convert to new format",$el:this.forms.conversion.$el}),t.add({id:"datatype",title:"Datatypes",icon:"fa-database",tooltip:"Change data type",$el:this.forms.datatype.$el}),t.add({id:"permissions",title:"Permissions",icon:"fa-user",tooltip:"Permissions",$el:this.forms.permission.$el}),t},_getAttribute:function(){var t=this,e=new a({title:"Edit attributes",operations:{submit_attributes:new i.ButtonIcon({tooltip:"Save attributes of the dataset.",icon:"fa-floppy-o",title:"Save",onclick:function(){t._submit("attributes",e)}}),submit_autodetect:new i.ButtonIcon({tooltip:"This will inspect the dataset and attempt to correct the values of fields if they are not accurate.",icon:"fa-undo",title:"Auto-detect",onclick:function(){t._submit("autodetect",e)}})}});return e},_getConversion:function(){var t=this,e=new a({title:"Convert to new format",operations:{submit_conversion:new i.ButtonIcon({tooltip:"Convert the datatype to a new format.",title:"Convert datatype",icon:"fa-exchange",onclick:function(){t._submit("conversion",e)}})}});return e},_getDatatype:function(){var t=this,e=new a({title:"Change datatype",operations:{submit_datatype:new i.ButtonIcon({tooltip:"Change the datatype to a new type.",title:"Change datatype",icon:"fa-exchange",onclick:function(){t._submit("datatype",e)}})}});return e},_getPermission:function(){var t=this,e=new a({title:"Manage dataset permissions",operations:{submit_permission:new i.ButtonIcon({tooltip:"Save permissions.",title:"Save permissions",icon:"fa-floppy-o ",onclick:function(){t._submit("permission",e)}})}});return e},_reloadHistory:function(){window.Galaxy&&window.Galaxy.currHistoryPanel.loadCurrentHistory()}})}});
//# sourceMappingURL=../../../maps/mvc/dataset/dataset-edit-attributes.js.map
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,2 +1,2 @@
"use strict";define(["mvc/dataset/states","mvc/base-mvc","utils/localization"],function(e,t,a){var i=t.SearchableModelMixin,n=Backbone.Model.extend(t.LoggableMixin).extend(t.mixin(i,{_logNamespace:"dataset",defaults:{state:e.NEW,deleted:!1,purged:!1,name:"(unnamed dataset)",accessible:!0,data_type:"",file_ext:"",file_size:0,meta_files:[],misc_blurb:"",misc_info:"",tags:[]},initialize:function(t,a){this.debug(this+"(Dataset).initialize",t,a),this.get("accessible")||this.set("state",e.NOT_VIEWABLE),this.urls=this._generateUrls(),this._setUpListeners()},_generateUrls:function(){var e=this.get("id");if(!e)return{};var t={purge:"datasets/"+e+"/purge_async",display:"datasets/"+e+"/display/?preview=True",edit:"datasets/"+e+"/edit",download:"datasets/"+e+"/display"+this._downloadQueryParameters(),report_error:"dataset/errors?id="+e,rerun:"tool_runner/rerun?id="+e,show_params:"datasets/"+e+"/show_params",visualization:"visualization",meta_download:"dataset/get_metadata_file?hda_id="+e+"&metadata_name="};return _.each(t,function(e,a){t[a]=Galaxy.root+e}),this.urls=t,t},_downloadQueryParameters:function(){return"?to_ext="+this.get("file_ext")},_setUpListeners:function(){this.on("change:state",function(e,t){this.log(this+" has changed state:",e,t),this.inReadyState()&&this.trigger("state:ready",e,t,this.previous("state"))}),this.on("change:id change:file_ext",function(e){this._generateUrls()})},toJSON:function(){var e=Backbone.Model.prototype.toJSON.call(this);return _.extend(e,{urls:this.urls})},isDeletedOrPurged:function(){return this.get("deleted")||this.get("purged")},inReadyState:function(){var t=_.contains(e.READY_STATES,this.get("state"));return this.isDeletedOrPurged()||t},hasDetails:function(){return!this.get("accessible")||this.has("annotation")},hasData:function(){return this.get("file_size")>0},fetch:function(e){var t=this;return Backbone.Model.prototype.fetch.call(this,e).always(function(){t._generateUrls()})},parse:function(e,t){var a=Backbone.Model.prototype.parse.call(this,e,t);return a.create_time&&(a.create_time=new Date(a.create_time)),a.update_time&&(a.update_time=new Date(a.update_time)),a},save:function(e,t){return t=t||{},t.wait=!!_.isUndefined(t.wait)||t.wait,Backbone.Model.prototype.save.call(this,e,t)},delete:function(e){return this.get("deleted")?jQuery.when():this.save({deleted:!0},e)},undelete:function(e){return!this.get("deleted")||this.get("purged")?jQuery.when():this.save({deleted:!1},e)},purge:function(e){if(this.get("purged"))return jQuery.when();(e=e||{}).url=this.urls.purge;var t=this,i=jQuery.ajax(e);return i.done(function(e,a,i){t.set({deleted:!0,purged:!0})}),i.fail(function(i,n,s){var r=a("Unable to purge dataset");i.responseJSON&&i.responseJSON.error?r=i.responseJSON.error:-1!==i.responseText.indexOf("Removal of datasets by users is not allowed in this Galaxy instance")&&(r="Removal of datasets by users is not allowed in this Galaxy instance"),i.responseText=r,t.trigger("error",t,i,e,a(r),{error:r})}),i},searchAttributes:["name","file_ext","genome_build","misc_blurb","misc_info","annotation","tags"],searchAliases:{title:"name",format:"file_ext",database:"genome_build",blurb:"misc_blurb",description:"misc_blurb",info:"misc_info",tag:"tags"},toString:function(){var e=this.get("id")||"";return this.get("name")&&(e='"'+this.get("name")+'",'+e),"Dataset("+e+")"}}));return{DatasetAssociation:n,DatasetAssociationCollection:Backbone.Collection.extend(t.LoggableMixin).extend({_logNamespace:"dataset",model:n,urlRoot:Galaxy.root+"api/datasets",url:function(){return this.urlRoot},ids:function(){return this.map(function(e){return e.get("id")})},notReady:function(){return this.filter(function(e){return!e.inReadyState()})},haveDetails:function(){return this.all(function(e){return e.hasDetails()})},ajaxQueue:function(e,t){var a=jQuery.Deferred(),i=this.length,n=[];if(!i)return a.resolve([]),a;var s=this.chain().reverse().map(function(r,o){return function(){var u=e.call(r,t);u.done(function(e){a.notify({curr:o,total:i,response:e,model:r})}),u.always(function(e){n.push(e),s.length?s.shift()():a.resolve(n)})}}).value();return s.shift()(),a},matches:function(e){return this.filter(function(t){return t.matches(e)})},toString:function(){return["DatasetAssociationCollection(",this.length,")"].join("")}})}});
"use strict";define(["mvc/dataset/states","mvc/base-mvc","utils/localization"],function(e,t,a){var i=t.SearchableModelMixin,n=Backbone.Model.extend(t.LoggableMixin).extend(t.mixin(i,{_logNamespace:"dataset",defaults:{state:e.NEW,deleted:!1,purged:!1,name:"(unnamed dataset)",accessible:!0,data_type:"",file_ext:"",file_size:0,meta_files:[],misc_blurb:"",misc_info:"",tags:[]},initialize:function(t,a){this.debug(this+"(Dataset).initialize",t,a),this.get("accessible")||this.set("state",e.NOT_VIEWABLE),this.urls=this._generateUrls(),this._setUpListeners()},_generateUrls:function(){var e=this.get("id");if(!e)return{};var t={purge:"datasets/"+e+"/purge_async",display:"datasets/"+e+"/display/?preview=True",edit:"datasets/edit?dataset_id="+e,download:"datasets/"+e+"/display"+this._downloadQueryParameters(),report_error:"dataset/errors?id="+e,rerun:"tool_runner/rerun?id="+e,show_params:"datasets/"+e+"/show_params",visualization:"visualization",meta_download:"dataset/get_metadata_file?hda_id="+e+"&metadata_name="};return _.each(t,function(e,a){t[a]=Galaxy.root+e}),this.urls=t,t},_downloadQueryParameters:function(){return"?to_ext="+this.get("file_ext")},_setUpListeners:function(){this.on("change:state",function(e,t){this.log(this+" has changed state:",e,t),this.inReadyState()&&this.trigger("state:ready",e,t,this.previous("state"))}),this.on("change:id change:file_ext",function(e){this._generateUrls()})},toJSON:function(){var e=Backbone.Model.prototype.toJSON.call(this);return _.extend(e,{urls:this.urls})},isDeletedOrPurged:function(){return this.get("deleted")||this.get("purged")},inReadyState:function(){var t=_.contains(e.READY_STATES,this.get("state"));return this.isDeletedOrPurged()||t},hasDetails:function(){return!this.get("accessible")||this.has("annotation")},hasData:function(){return this.get("file_size")>0},fetch:function(e){var t=this;return Backbone.Model.prototype.fetch.call(this,e).always(function(){t._generateUrls()})},parse:function(e,t){var a=Backbone.Model.prototype.parse.call(this,e,t);return a.create_time&&(a.create_time=new Date(a.create_time)),a.update_time&&(a.update_time=new Date(a.update_time)),a},save:function(e,t){return t=t||{},t.wait=!!_.isUndefined(t.wait)||t.wait,Backbone.Model.prototype.save.call(this,e,t)},delete:function(e){return this.get("deleted")?jQuery.when():this.save({deleted:!0},e)},undelete:function(e){return!this.get("deleted")||this.get("purged")?jQuery.when():this.save({deleted:!1},e)},purge:function(e){if(this.get("purged"))return jQuery.when();(e=e||{}).url=this.urls.purge;var t=this,i=jQuery.ajax(e);return i.done(function(e,a,i){t.set({deleted:!0,purged:!0})}),i.fail(function(i,n,s){var r=a("Unable to purge dataset");i.responseJSON&&i.responseJSON.error?r=i.responseJSON.error:-1!==i.responseText.indexOf("Removal of datasets by users is not allowed in this Galaxy instance")&&(r="Removal of datasets by users is not allowed in this Galaxy instance"),i.responseText=r,t.trigger("error",t,i,e,a(r),{error:r})}),i},searchAttributes:["name","file_ext","genome_build","misc_blurb","misc_info","annotation","tags"],searchAliases:{title:"name",format:"file_ext",database:"genome_build",blurb:"misc_blurb",description:"misc_blurb",info:"misc_info",tag:"tags"},toString:function(){var e=this.get("id")||"";return this.get("name")&&(e='"'+this.get("name")+'",'+e),"Dataset("+e+")"}}));return{DatasetAssociation:n,DatasetAssociationCollection:Backbone.Collection.extend(t.LoggableMixin).extend({_logNamespace:"dataset",model:n,urlRoot:Galaxy.root+"api/datasets",url:function(){return this.urlRoot},ids:function(){return this.map(function(e){return e.get("id")})},notReady:function(){return this.filter(function(e){return!e.inReadyState()})},haveDetails:function(){return this.all(function(e){return e.hasDetails()})},ajaxQueue:function(e,t){var a=jQuery.Deferred(),i=this.length,n=[];if(!i)return a.resolve([]),a;var s=this.chain().reverse().map(function(r,o){return function(){var u=e.call(r,t);u.done(function(e){a.notify({curr:o,total:i,response:e,model:r})}),u.always(function(e){n.push(e),s.length?s.shift()():a.resolve(n)})}}).value();return s.shift()(),a},matches:function(e){return this.filter(function(t){return t.matches(e)})},toString:function(){return["DatasetAssociationCollection(",this.length,")"].join("")}})}});
//# sourceMappingURL=../../../maps/mvc/dataset/dataset-model.js.map
+1 -1
View File
@@ -1,2 +1,2 @@
"use strict";define(["utils/utils","mvc/ui/ui-misc","mvc/ui/ui-select-content","mvc/ui/ui-select-library","mvc/ui/ui-select-ftp","mvc/ui/ui-select-genomespace","mvc/ui/ui-color-picker"],function(e,i,l,n,t,a,o){return Backbone.Model.extend({types:{text:"_fieldText",password:"_fieldText",select:"_fieldSelect",data_column:"_fieldSelect",genomebuild:"_fieldSelect",data:"_fieldData",data_collection:"_fieldData",integer:"_fieldSlider",float:"_fieldSlider",boolean:"_fieldBoolean",drill_down:"_fieldDrilldown",color:"_fieldColor",hidden:"_fieldHidden",hidden_data:"_fieldHidden",baseurl:"_fieldHidden",library_data:"_fieldLibrary",ftpfile:"_fieldFtp",upload:"_fieldUpload",genomespacefile:"_fieldGenomeSpace"},create:function(e){var i=this.types[e.type],l="function"==typeof this[i]?this[i].call(this,e):null;return l||(l=e.options?this._fieldSelect(e):this._fieldText(e),Galaxy.emit.debug("form-parameters::_addRow()","Auto matched field type ("+e.type+").")),void 0===e.value&&(e.value=null),l.value(e.value),l},_fieldData:function(e){return new l.View({id:"field-"+e.id,extensions:e.extensions,optional:e.optional,multiple:e.multiple,type:e.type,flavor:e.flavor,data:e.options,onchange:e.onchange})},_fieldSelect:function(e){if(e.is_workflow)return this._fieldText(e);"data_column"==e.type&&(e.error_text="Missing columns in referenced dataset.");var l=e.data;l||(l=[],_.each(e.options,function(e){l.push({label:e[0],value:e[1]})}));var n=i.Select;switch(e.display){case"checkboxes":n=i.Checkbox;break;case"radio":n=i.Radio;break;case"radiobutton":n=i.RadioButton}return new n.View({id:"field-"+e.id,data:l,error_text:e.error_text||"No options available",multiple:e.multiple,optional:e.optional,onchange:e.onchange,individual:e.individual,searchable:"workflow"!==e.flavor})},_fieldDrilldown:function(e){return e.is_workflow?this._fieldText(e):new i.Drilldown.View({id:"field-"+e.id,data:e.options,display:e.display,optional:e.optional,onchange:e.onchange})},_fieldText:function(l){if(l.options&&l.data)if(l.area=l.multiple,e.isEmpty(l.value))l.value=null;else if($.isArray(l.value)){var n="";for(var t in l.value){if(n+=String(l.value[t]),!l.multiple)break;n+="\n"}l.value=n}return new i.Input({id:"field-"+l.id,type:l.type,area:l.area,readonly:l.readonly,placeholder:l.placeholder,datalist:l.datalist,onchange:l.onchange})},_fieldSlider:function(e){return new i.Slider.View({id:"field-"+e.id,precise:"float"==e.type,is_workflow:e.is_workflow,min:e.min,max:e.max,onchange:e.onchange})},_fieldHidden:function(e){return new i.Hidden({id:"field-"+e.id,info:e.info})},_fieldBoolean:function(e){return new i.RadioButton.View({id:"field-"+e.id,data:[{label:"Yes",value:"true"},{label:"No",value:"false"}],onchange:e.onchange})},_fieldColor:function(e){return new o({id:"field-"+e.id,onchange:e.onchange})},_fieldLibrary:function(e){return new n.View({id:"field-"+e.id,optional:e.optional,multiple:e.multiple,onchange:e.onchange})},_fieldFtp:function(e){return new t.View({id:"field-"+e.id,optional:e.optional,multiple:e.multiple,onchange:e.onchange})},_fieldGenomeSpace:function(e){var i=this;return new a.View({id:"field-"+e.id,onchange:function(){i.app.trigger("change")}})},_fieldUpload:function(e){return new i.Upload({id:"field-"+e.id,onchange:e.onchange})}})});
"use strict";define(["utils/utils","mvc/ui/ui-misc","mvc/ui/ui-select-content","mvc/ui/ui-select-library","mvc/ui/ui-select-ftp","mvc/ui/ui-select-genomespace","mvc/ui/ui-color-picker"],function(e,i,l,n,a,t,o){return Backbone.Model.extend({types:{text:"_fieldText",password:"_fieldText",select:"_fieldSelect",data_column:"_fieldSelect",genomebuild:"_fieldSelect",data:"_fieldData",data_collection:"_fieldData",integer:"_fieldSlider",float:"_fieldSlider",boolean:"_fieldBoolean",drill_down:"_fieldDrilldown",color:"_fieldColor",hidden:"_fieldHidden",hidden_data:"_fieldHidden",baseurl:"_fieldHidden",library_data:"_fieldLibrary",ftpfile:"_fieldFtp",upload:"_fieldUpload",genomespacefile:"_fieldGenomeSpace"},create:function(e){var i=this.types[e.type],l="function"==typeof this[i]?this[i].call(this,e):null;return l||(l=e.options?this._fieldSelect(e):this._fieldText(e),Galaxy.emit.debug("form-parameters::_addRow()","Auto matched field type ("+e.type+").")),void 0===e.value&&(e.value=null),l.value(e.value),l},_fieldData:function(e){return new l.View({id:"field-"+e.id,extensions:e.extensions,optional:e.optional,multiple:e.multiple,type:e.type,flavor:e.flavor,data:e.options,onchange:e.onchange})},_fieldSelect:function(e){if(e.is_workflow)return this._fieldText(e);"data_column"==e.type&&(e.error_text="Missing columns in referenced dataset.");var l=e.data;l||(l=[],_.each(e.options,function(e){l.push({label:e[0],value:e[1]})}));var n=i.Select;switch(e.display){case"checkboxes":n=i.Checkbox;break;case"radio":n=i.Radio;break;case"radiobutton":n=i.RadioButton}return new n.View({id:"field-"+e.id,data:l,error_text:e.error_text||"No options available",readonly:e.readonly,multiple:e.multiple,optional:e.optional,onchange:e.onchange,individual:e.individual,searchable:"workflow"!==e.flavor})},_fieldDrilldown:function(e){return e.is_workflow?this._fieldText(e):new i.Drilldown.View({id:"field-"+e.id,data:e.options,display:e.display,optional:e.optional,onchange:e.onchange})},_fieldText:function(l){if(l.options&&l.data)if(l.area=l.multiple,e.isEmpty(l.value))l.value=null;else if($.isArray(l.value)){var n="";for(var a in l.value){if(n+=String(l.value[a]),!l.multiple)break;n+="\n"}l.value=n}return new i.Input({id:"field-"+l.id,type:l.type,area:l.area,readonly:l.readonly,placeholder:l.placeholder,datalist:l.datalist,onchange:l.onchange})},_fieldSlider:function(e){return new i.Slider.View({id:"field-"+e.id,precise:"float"==e.type,is_workflow:e.is_workflow,min:e.min,max:e.max,onchange:e.onchange})},_fieldHidden:function(e){return new i.Hidden({id:"field-"+e.id,info:e.info})},_fieldBoolean:function(e){return new i.RadioButton.View({id:"field-"+e.id,data:[{label:"Yes",value:"true"},{label:"No",value:"false"}],onchange:e.onchange})},_fieldColor:function(e){return new o({id:"field-"+e.id,onchange:e.onchange})},_fieldLibrary:function(e){return new n.View({id:"field-"+e.id,optional:e.optional,multiple:e.multiple,onchange:e.onchange})},_fieldFtp:function(e){return new a.View({id:"field-"+e.id,optional:e.optional,multiple:e.multiple,onchange:e.onchange})},_fieldGenomeSpace:function(e){var i=this;return new t.View({id:"field-"+e.id,onchange:function(){i.app.trigger("change")}})},_fieldUpload:function(e){return new i.Upload({id:"field-"+e.id,onchange:e.onchange})}})});
//# sourceMappingURL=../../../maps/mvc/form/form-parameters.js.map
+1 -1
View File
@@ -1,2 +1,2 @@
"use strict";define(["utils/utils","mvc/ui/ui-portlet","mvc/ui/ui-misc","mvc/form/form-section","mvc/form/form-data"],function(t,e,i,s,n){return Backbone.View.extend({initialize:function(t){this.model=new Backbone.Model({initial_errors:!1,cls:"ui-portlet-limited",icon:null,always_refresh:!0,status:"warning",onchange:function(){}}).set(t),this.setElement("<div/>"),this.render()},update:function(t){var e=this;this.data.matchModel(t,function(t,i){var s=e.input_list[i];if(s&&s.options&&!_.isEqual(s.options,t.options)){s.options=t.options;var n=e.field_list[i];if(n.update){var o=[];if(-1!=["data","data_collection","drill_down"].indexOf(s.type))o=s.options;else for(var a in t.options){var r=t.options[a];r.length>2&&o.push({label:r[0],value:r[1]})}n.update(o),n.trigger("change"),Galaxy.emit.debug("form-view::update()","Updating options for "+i)}}})},wait:function(t){for(var e in this.input_list){var i=this.field_list[e];this.input_list[e].is_dynamic&&i.wait&&i.unwait&&i[t?"wait":"unwait"]()}},highlight:function(t,e,i){var s=this.element_list[t];if(s&&(s.error(e||"Please verify this parameter."),this.portlet.expand(),this.trigger("expand",t),!i)){var n=this.$el.parents().filter(function(){return-1!=["auto","scroll"].indexOf($(this).css("overflow"))}).first();n.animate({scrollTop:n.scrollTop()+s.$el.offset().top-120},500)}},errors:function(t){if(this.trigger("reset"),t&&t.errors){var e=this.data.matchResponse(t.errors);for(var i in this.element_list){this.element_list[i];e[i]&&this.highlight(i,e[i],!0)}}},render:function(){var t=this;this.off("change"),this.off("reset"),this.field_list={},this.input_list={},this.element_list={},this.data=new n.Manager(this),this._renderForm(),this.data.create(),this.model.get("initial_errors")&&this.errors(this.model.attributes);var e=this.data.checksum();return this.on("change",function(i){var s=t.input_list[i];if(!s||s.refresh_on_change||t.model.get("always_refresh")){var n=t.data.checksum();n!=e&&(e=n,t.model.get("onchange")())}}),this.on("reset",function(){_.each(t.element_list,function(t){t.reset()})}),this},_renderForm:function(){$(".tooltip").remove();var t=this.model.attributes;this.message=new i.UnescapedMessage,this.section=new s.View(this,{inputs:t.inputs}),this.portlet=new e.View({icon:t.icon,title:t.title,cls:t.cls,operations:t.operations,buttons:t.buttons,collapsible:t.collapsible,collapsed:t.collapsed,onchange_title:t.onchange_title}),this.portlet.append(this.message.$el),this.portlet.append(this.section.$el),this.$el.empty(),t.inputs&&this.$el.append(this.portlet.$el),t.message&&this.message.update({persistent:!0,status:t.status,message:t.message}),Galaxy.emit.debug("form-view::initialize()","Completed")}})});
"use strict";define(["utils/utils","mvc/ui/ui-portlet","mvc/ui/ui-misc","mvc/form/form-section","mvc/form/form-data"],function(t,e,i,s,n){return Backbone.View.extend({initialize:function(t){this.model=new Backbone.Model({initial_errors:!1,cls:"ui-portlet-limited",icon:null,always_refresh:!0,status:"warning",hide_operations:!1,onchange:function(){}}).set(t),this.setElement("<div/>"),this.render()},update:function(t){var e=this;this.data.matchModel(t,function(t,i){var s=e.input_list[i];if(s&&s.options&&!_.isEqual(s.options,t.options)){s.options=t.options;var n=e.field_list[i];if(n.update){var o=[];if(-1!=["data","data_collection","drill_down"].indexOf(s.type))o=s.options;else for(var a in t.options){var r=t.options[a];r.length>2&&o.push({label:r[0],value:r[1]})}n.update(o),n.trigger("change"),Galaxy.emit.debug("form-view::update()","Updating options for "+i)}}})},wait:function(t){for(var e in this.input_list){var i=this.field_list[e];this.input_list[e].is_dynamic&&i.wait&&i.unwait&&i[t?"wait":"unwait"]()}},highlight:function(t,e,i){var s=this.element_list[t];if(s&&(s.error(e||"Please verify this parameter."),this.portlet.expand(),this.trigger("expand",t),!i)){var n=this.$el.parents().filter(function(){return-1!=["auto","scroll"].indexOf($(this).css("overflow"))}).first();n.animate({scrollTop:n.scrollTop()+s.$el.offset().top-120},500)}},errors:function(t){if(this.trigger("reset"),t&&t.errors){var e=this.data.matchResponse(t.errors);for(var i in this.element_list){this.element_list[i];e[i]&&this.highlight(i,e[i],!0)}}},render:function(){var t=this;this.off("change"),this.off("reset"),this.field_list={},this.input_list={},this.element_list={},this.data=new n.Manager(this),this._renderForm(),this.data.create(),this.model.get("initial_errors")&&this.errors(this.model.attributes);var e=this.data.checksum();return this.on("change",function(i){var s=t.input_list[i];if(!s||s.refresh_on_change||t.model.get("always_refresh")){var n=t.data.checksum();n!=e&&(e=n,t.model.get("onchange")())}}),this.on("reset",function(){_.each(t.element_list,function(t){t.reset()})}),this},_renderForm:function(){$(".tooltip").remove();var t=this.model.attributes;this.message=new i.UnescapedMessage,this.section=new s.View(this,{inputs:t.inputs}),this.portlet=new e.View({icon:t.icon,title:t.title,cls:t.cls,operations:!t.hide_operations&&t.operations,buttons:t.buttons,collapsible:t.collapsible,collapsed:t.collapsed,onchange_title:t.onchange_title}),this.portlet.append(this.message.$el),this.portlet.append(this.section.$el),this.$el.empty(),t.inputs&&this.$el.append(this.portlet.$el),t.message&&this.message.update({persistent:!0,status:t.status,message:t.message}),Galaxy.emit.debug("form-view::initialize()","Completed")}})});
//# sourceMappingURL=../../../maps/mvc/form/form-view.js.map
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,2 +1,2 @@
"use strict";define(["utils/utils","mvc/ui/ui-modal","mvc/ui/ui-tabs","mvc/upload/upload-button","mvc/upload/default/default-view","mvc/upload/composite/composite-view","mvc/upload/collection/collection-view"],function(t,e,i,o,s,n,l){return Backbone.View.extend({options:{nginx_upload_path:"",ftp_upload_site:"n/a",default_genome:"?",default_extension:"auto",height:500,width:900,auto:{id:"auto",text:"Auto-detect",description:"This system will try to detect the file type automatically. If your file is not detected properly as one of the known formats, it most likely means that it has some format problems (e.g., different number of columns on different rows). You can still coerce the system to set your data to the format you think it should be. You can also upload compressed files, which will automatically be decompressed."}},list_extensions:[],list_genomes:[],initialize:function(e){i=this;this.options=t.merge(e,this.options),this.ui_button=new o.View({onclick:function(t){t.preventDefault(),i.show()},onunload:function(){var t=i.ui_button.model.get("percentage",0);if(t>0&&t<100)return"Several uploads are queued."}}),this.setElement(this.ui_button.$el);var i=this;t.get({url:Galaxy.root+"api/datatypes?extension_only=False",success:function(t){for(var e in t)i.list_extensions.push({id:t[e].extension,text:t[e].extension,description:t[e].description,description_url:t[e].description_url,composite_files:t[e].composite_files});i.list_extensions.sort(function(t,e){var i=t.text&&t.text.toLowerCase(),o=e.text&&e.text.toLowerCase();return i>o?1:i<o?-1:0}),i.options.datatypes_disable_auto||i.list_extensions.unshift(i.options.auto)}}),t.get({url:Galaxy.root+"api/genomes",success:function(t){for(var e in t)i.list_genomes.push({id:t[e][1],text:t[e][0]});i.list_genomes.sort(function(t,e){return t.id==i.options.default_genome?-1:e.id==i.options.default_genome?1:t.text>e.text?1:t.text<e.text?-1:0})}})},show:function(){var t=this;Galaxy.currHistoryPanel&&Galaxy.currHistoryPanel.model?(this.current_user=Galaxy.user.id,this.modal||(this.tabs=new i.View,this.default_view=new s(this),this.tabs.add({id:"regular",title:"Regular",$el:this.default_view.$el}),this.composite_view=new n(this),this.tabs.add({id:"composite",title:"Composite",$el:this.composite_view.$el}),this.collection_view=new l(this),this.tabs.add({id:"collection",title:"Collection",$el:this.collection_view.$el}),this.modal=new e.View({title:"Download from web or upload from disk",body:this.tabs.$el,height:this.options.height,width:this.options.width,closing_events:!0,title_separator:!1})),this.modal.show()):window.setTimeout(function(){t.show()},500)},currentHistory:function(){return this.current_user&&Galaxy.currHistoryPanel.model.get("id")},currentFtp:function(){return this.current_user&&this.options.ftp_upload_site},toData:function(t,e){var i={payload:{tool_id:"upload1",history_id:e||this.currentHistory(),inputs:{}},files:[],error_message:null};if(t&&t.length>0){var o={file_count:t.length};for(var s in t){var n=t[s];if(n.set("status","running"),!(n.get("file_size")>0)){i.error_message="Upload content incomplete.",n.set("status","error"),n.set("info",i.error_message);break}var l="files_"+s+"|";switch(o[l+"type"]="upload_dataset",o[l+"space_to_tab"]=n.get("space_to_tab")&&"Yes"||null,o[l+"to_posix_lines"]=n.get("to_posix_lines")&&"Yes"||null,o[l+"dbkey"]=n.get("genome",null),o[l+"file_type"]=n.get("extension",null),n.get("file_mode")){case"new":o[l+"url_paste"]=n.get("url_paste");break;case"ftp":o[l+"ftp_files"]=n.get("file_path");break;case"local":i.files.push({name:l+"file_data",file:n.get("file_data")})}}i.payload.inputs=JSON.stringify(o)}return i}})});
"use strict";define(["utils/utils","mvc/ui/ui-modal","mvc/ui/ui-tabs","mvc/upload/upload-button","mvc/upload/default/default-view","mvc/upload/composite/composite-view","mvc/upload/collection/collection-view"],function(t,e,i,o,s,n,l){return Backbone.View.extend({options:{nginx_upload_path:"",ftp_upload_site:"n/a",default_genome:"?",default_extension:"auto",height:500,width:900,auto:{id:"auto",text:"Auto-detect",description:"This system will try to detect the file type automatically. If your file is not detected properly as one of the known formats, it most likely means that it has some format problems (e.g., different number of columns on different rows). You can still coerce the system to set your data to the format you think it should be. You can also upload compressed files, which will automatically be decompressed."}},list_extensions:[],list_genomes:[],initialize:function(e){i=this;this.options=t.merge(e,this.options),this.ui_button=new o.View({onclick:function(t){t.preventDefault(),i.show()},onunload:function(){var t=i.ui_button.model.get("percentage",0);if(t>0&&t<100)return"Several uploads are queued."}}),this.setElement(this.ui_button.$el);var i=this;t.get({url:Galaxy.root+"api/datatypes?extension_only=False",success:function(t){for(var e in t)i.list_extensions.push({id:t[e].extension,text:t[e].extension,description:t[e].description,description_url:t[e].description_url,composite_files:t[e].composite_files});i.list_extensions.sort(function(t,e){var i=t.text&&t.text.toLowerCase(),o=e.text&&e.text.toLowerCase();return i>o?1:i<o?-1:0}),i.options.datatypes_disable_auto||i.list_extensions.unshift(i.options.auto)}}),t.get({url:Galaxy.root+"api/genomes",success:function(t){for(var e in t)i.list_genomes.push({id:t[e][1],text:t[e][0]});i.list_genomes.sort(function(t,e){return t.id==i.options.default_genome?-1:e.id==i.options.default_genome?1:t.text>e.text?1:t.text<e.text?-1:0})}})},show:function(){var t=this;Galaxy.currHistoryPanel&&Galaxy.currHistoryPanel.model?(this.current_user=Galaxy.user.id,this.modal||(this.tabs=new i.View,this.default_view=new s(this),this.tabs.add({id:"regular",title:"Regular",$el:this.default_view.$el}),this.composite_view=new n(this),this.tabs.add({id:"composite",title:"Composite",$el:this.composite_view.$el}),this.collection_view=new l(this),this.tabs.add({id:"collection",title:"Collection",$el:this.collection_view.$el}),this.modal=new e.View({title:"Download from web or upload from disk",body:this.tabs.$el,height:this.options.height,width:this.options.width,closing_events:!0,title_separator:!1})),this.modal.show()):window.setTimeout(function(){t.show()},500)},currentHistory:function(){return this.current_user&&Galaxy.currHistoryPanel.model.get("id")},currentFtp:function(){return this.current_user&&this.options.ftp_upload_site},toData:function(t,e){var i={payload:{tool_id:"upload1",history_id:e||this.currentHistory(),inputs:{}},files:[],error_message:null};if(t&&t.length>0){var o={file_count:t.length,dbkey:t[0].get("genome","?"),file_type:t[0].get("extension","auto")};for(var s in t){var n=t[s];if(n.set("status","running"),!(n.get("file_size")>0)){i.error_message="Upload content incomplete.",n.set("status","error"),n.set("info",i.error_message);break}var l="files_"+s+"|";switch(o[l+"type"]="upload_dataset",o[l+"space_to_tab"]=n.get("space_to_tab")&&"Yes"||null,o[l+"to_posix_lines"]=n.get("to_posix_lines")&&"Yes"||null,o[l+"dbkey"]=n.get("genome",null),o[l+"file_type"]=n.get("extension",null),n.get("file_mode")){case"new":o[l+"url_paste"]=n.get("url_paste");break;case"ftp":o[l+"ftp_files"]=n.get("file_path");break;case"local":i.files.push({name:l+"file_data",file:n.get("file_data")})}}i.payload.inputs=JSON.stringify(o)}return i}})});
//# sourceMappingURL=../../../maps/mvc/upload/upload-view.js.map
File diff suppressed because one or more lines are too long
+28
View File
@@ -189,6 +189,34 @@ class ToolsUploadTestCase(api.ApiTestCase):
assert datasets[1]["file_ext"] == "txt"
assert datasets[1]["genome_build"] == "hg18", datasets
def test_upload_multiple_files_no_dbkey(self):
with self.dataset_populator.test_history() as history_id:
payload = self.dataset_populator.upload_payload(history_id, "Test123",
file_type="tabular",
dbkey=None,
extra_inputs={
"files_0|file_type": "txt",
"files_1|url_paste": "SecondOutputContent",
"files_1|NAME": "SecondOutputName",
"files_1|file_type": "txt",
"file_count": "2",
}
)
run_response = self.dataset_populator.tools_post(payload)
self.dataset_populator.wait_for_tool_run(history_id, run_response)
datasets = run_response.json()["outputs"]
assert len(datasets) == 2, datasets
content = self.dataset_populator.get_history_dataset_content(history_id, dataset=datasets[0])
assert content.strip() == "Test123"
assert datasets[0]["file_ext"] == "txt", datasets
assert datasets[0]["genome_build"] == "?", datasets
content = self.dataset_populator.get_history_dataset_content(history_id, dataset=datasets[1])
assert content.strip() == "SecondOutputContent"
assert datasets[1]["file_ext"] == "txt"
assert datasets[1]["genome_build"] == "?", datasets
def test_upload_multiple_files_space_to_tab(self):
with self.dataset_populator.test_history() as history_id:
payload = self.dataset_populator.upload_payload(history_id,
+2
View File
@@ -168,6 +168,8 @@ class BaseDatasetPopulator(object):
'dbkey': dbkey,
'file_type': file_type,
}
if dbkey is None:
del upload_params["dbkey"]
if content is None:
upload_params["files_0|ftp_files"] = kwds.get("ftp_files")
elif hasattr(content, 'read'):