Merge branch 'dev' into remove_toolshed_grids

This commit is contained in:
guerler
2017-10-13 14:53:14 -04:00
233 changed files with 2750 additions and 2439 deletions
+3
View File
@@ -57,6 +57,7 @@ lib/galaxy/managers/taggable.py
lib/galaxy/model/
lib/galaxy/objectstore/pulsar.py
lib/galaxy/objectstore/s3_multipart_upload.py
lib/galaxy/objectstore/s3.py
lib/galaxy/openid/__init__.py
lib/galaxy/quota/
lib/galaxy/sample_tracking/data_transfer.py
@@ -81,6 +82,7 @@ lib/galaxy/visualization/tracks/
lib/galaxy/web/base/
lib/galaxy/web/buildapp.py
lib/galaxy/web/formatting.py
lib/galaxy/web/form_builder.py
lib/galaxy/web/framework/base.py
lib/galaxy/web/framework/decorators.py
lib/galaxy/web/framework/helpers/grids.py
@@ -126,6 +128,7 @@ lib/galaxy/webapps/__init__.py
lib/galaxy/webapps/reports/config.py
lib/galaxy/webapps/reports/controllers/__init__.py
lib/galaxy/webapps/reports/controllers/query.py
lib/galaxy/webapps/reports/controllers/tools.py
lib/galaxy/webapps/reports/__init__.py
lib/galaxy/webapps/tool_shed/api/__init__.py
lib/galaxy/webapps/tool_shed/controllers/groups.py
+2 -2
View File
@@ -2,11 +2,11 @@ FROM toolshed/requirements
MAINTAINER John Chilton, jmchilton@gmail.com
RUN apt-get -qq update && \
apt-get install --no-install-recommends -y postgresql-client python-pip && \
apt-get install --no-install-recommends -y postgresql-client python-pip libffi-dev python-cffi && \
apt-get autoremove -y && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
ENV GALAXY_ROOT=/galaxy \
GALAXY_CONFIG_OVERRIDE_ADMIN_USERS=admin@galaxy.org \
GALAXY_CONFIG_OVERRIDE_ADMIN_USERS=admin@galaxy.org,test@bx.psu.edu \
GALAXY_CONFIG_OVERRIDE_ALLOW_USER_DATASET_PURGE=true \
GALAXY_CONFIG_OVERRIDE_ALLOW_LIBRARY_PATH_PASTE=true \
GALAXY_CONFIG_OVERRIDE_ENABLE_BETA_WORKFLOW_MODULES=true \
+2
View File
@@ -11,6 +11,8 @@ services:
- postgres
ports:
- "${GALAXY_PORT}:8080"
environment:
GALAXY_TEST_UID: "${MY_UID}"
selenium:
image: selenium/standalone-chrome:3.5.2
ports:
+6
View File
@@ -6,6 +6,12 @@ host = 0.0.0.0
use_threadpool = True
threadpool_kill_thread_limit = 10800
[filter:proxy-prefix]
use = egg:PasteDeploy#prefix
prefix = /galaxypf
[app:main]
paste.app_factory = galaxy.web.buildapp:app_factory
filter-with = proxy-prefix
+22 -1
View File
@@ -2,6 +2,27 @@
set -e
# Same hacks to setup a Galaxy user as used in test/docker/base/run_test_wrapper.sh
# We want to make sure Galaxy runs as the same user as the external user so the files have the correct permission.
echo "Deleting galaxy user - it may not exist and this is fine."
deluser galaxy | true
: ${GALAXY_TEST_UID:-"1"}
echo "Creating galaxy group with gid $GALAXY_TEST_UID - it may already exist and this is fine."
groupadd -r galaxy -g "$GALAXY_TEST_UID" | true
echo "Creating galaxy user with uid $GALAXY_TEST_UID - it may already exist and this is fine."
useradd -u $GALAXY_TEST_UID -r -g galaxy -d /home/galaxy -c "Galaxy User" galaxy -s /bin/bash | true
echo "Setting galaxy user password - the operation may fail."
echo "galaxy:galaxy" | chpasswd | true
virtualenv "$GALAXY_VIRTUAL_ENV"
chown -R "$GALAXY_TEST_UID:$GALAXY_TEST_UID" "$GALAXY_VIRTUAL_ENV"
cd /galaxy
HOME=/galaxy
sudo -E -u "#${GALAXY_TEST_UID}" ./scripts/common_startup.sh || { echo "common_startup.sh failed"; exit 1; }
echo "Waiting for postgres to become available"
while ! nc -z postgres 5432;
do
@@ -13,7 +34,7 @@ echo "Creating postgres database for Galaxy"
createdb -w -U postgres -h postgres galaxy
echo "Starting and waiting for Galaxy daemon(s)"
GALAXY_RUN_ALL=1 bash "$GALAXY_ROOT/run.sh" --daemon --wait
sudo -E -u "#${GALAXY_TEST_UID}" GALAXY_RUN_ALL=1 bash "$GALAXY_ROOT/run.sh" --daemon --wait
echo "Galaxy daemon ready, monitoring Galaxy logs"
tail -f "$GALAXY_ROOT/main.log"
+6 -1
View File
@@ -28,6 +28,7 @@ export SELENIUM_PORT=`python -c 'import socket; s=socket.socket(); s.bind(("", 0
export TARGET_ROOT=`pwd`
export TARGET_PATH=/galaxy
export MY_UID=$(id -u)
cd $TEST_DIRECTORY
@@ -107,7 +108,11 @@ export GALAXY_TEST_SELENIUM_RETRIES=1
export GALAXY_TEST_PORT="${GALAXY_PORT}"
# Have Selenium access Galaxy at this URL
export GALAXY_TEST_EXTERNAL_FROM_SELENIUM="http://galaxy:8080"
export GALAXY_TEST_EXTERNAL_FROM_SELENIUM="http://galaxy:8080/galaxypf"
export GALAXY_TEST_EXTERNAL="http://localhost:${GALAXY_TEST_PORT}/galaxypf"
# Point tests at the Master API Key configured in the Dockerfile.
export GALAXY_CONFIG_MASTER_API_KEY=94a548bea347a35e457a804bf75bec53
cd ../../..
+1
View File
@@ -70,6 +70,7 @@ scripts/communication/
scripts/data_libraries/build_whoosh_index.py
scripts/db_shell.py
scripts/drmaa_external_runner.py
scripts/metagenomics/
scripts/secret_decoder_ring.py
test/
tool_list.py
+1 -1
View File
@@ -19,7 +19,7 @@ var Router = Backbone.Router.extend({
url += url.indexOf( '?' ) == -1 ? '?' : '&';
url += $.param( data , true );
}
Galaxy.params = {};
Galaxy.params = data;
this.navigate( url, { 'trigger': true } );
},
@@ -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();
}
@@ -49,20 +49,26 @@ var DatasetListItemEdit = _super.extend(
/** Render icon-button to edit the attributes (format, permissions, etc.) this dataset. */
_renderEditButton : function(){
var self = this;
// don't show edit while uploading, in-accessible
// DO show if in error (ala previous history panel)
if( ( this.model.get( 'state' ) === STATES.DISCARDED )
|| ( !this.model.get( 'accessible' ) ) ){
return null;
}
var purged = this.model.get( 'purged' ),
deleted = this.model.get( 'deleted' ),
editBtnData = {
title : _l( 'Edit attributes' ),
href : Galaxy.root + 'datasets/edit?dataset_id=' + this.model.attributes.id,
faIcon : 'fa-pencil',
classes : 'edit-btn'
classes : 'edit-btn',
onclick : function( ev ) {
if ( Galaxy.router ) {
ev.preventDefault();
Galaxy.router.push( 'datasets/edit', { dataset_id : self.model.attributes.id } );
}
}
};
// disable if purged or deleted and explain why in the tooltip
if( deleted || purged ){
@@ -195,11 +201,18 @@ var DatasetListItemEdit = _super.extend(
/** Render icon-button to report an error on this dataset to the galaxy admin. */
_renderErrButton : function(){
var self = this;
return faIconButton({
title : _l( 'View or report this error' ),
href : Galaxy.root + 'datasets/error?dataset_id=' + this.model.attributes.id,
classes : 'report-error-btn',
faIcon : 'fa-bug'
faIcon : 'fa-bug',
onclick : function( ev ) {
if ( Galaxy.router ) {
ev.preventDefault();
Galaxy.router.push( 'datasets/error', { dataset_id : self.model.attributes.id } );
}
}
});
},
@@ -214,8 +227,10 @@ var DatasetListItemEdit = _super.extend(
target : this.linkTarget,
faIcon : 'fa-refresh',
onclick : function( ev ) {
ev.preventDefault();
Galaxy.router.push( '/', { job_id : creating_job } );
if ( Galaxy.router ) {
ev.preventDefault();
Galaxy.router.push( '/', { job_id : creating_job } );
}
}
});
}
@@ -307,7 +322,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 +374,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,
@@ -0,0 +1,62 @@
/** Contains helpers to limit/lazy load views for backbone views */
define([], function() {
return Backbone.View.extend({
initialize: function( options ) {
var self = this;
this.$container = options.$container;
this.collection = options.collection;
this.new_content = options.new_content;
this.max = options.max || 50;
this.content_list = {}
this.$message = $( '<div/>' ).addClass( 'ui-limitloader' ).append( '...only the first ' + this.max + ' entries are visible.' );
this.$container.append( this.$message );
this.listenTo( this.collection, 'reset', this._reset, this );
this.listenTo( this.collection, 'add', this._refresh, this );
this.listenTo( this.collection, 'remove', this._remove, this );
},
/** Checks if the limit has been reached */
_done: function() {
var done = _.size( this.content_list ) > this.max;
this.$message[ done ? 'show' : 'hide' ]();
return done;
},
/** Remove all content */
_reset: function() {
_.each( this.content_list, function( content ) {
content.remove();
});
this.content_list = {};
this.$message.hide();
},
/** Remove content */
_remove: function( model ) {
var model_id = model.id;
var content = this.content_list[ model_id ];
if ( content ) {
content.remove();
delete this.content_list[ model_id ];
}
this._refresh();
},
/** Refreshes container content by adding new views if visible */
_refresh: function() {
if ( !this._done() ) {
for ( var i in this.collection.models ) {
var model = this.collection.models[ i ];
var view = this.content_list[ model.id ];
if ( !this.content_list[ model.id ] ) {
var content = this.new_content( model );
this.content_list[ model.id ] = content;
if ( this._done() ) {
break;
}
}
}
}
}
});
});
@@ -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();
},
@@ -1,6 +1,6 @@
/** Renders contents of the collection uploader */
define([ 'utils/utils', 'mvc/upload/upload-model', 'mvc/upload/collection/collection-row', 'mvc/upload/upload-ftp', 'mvc/ui/ui-popover', 'mvc/ui/ui-select', 'mvc/ui/ui-misc', 'mvc/collection/list-collection-creator', 'utils/uploadbox' ],
function( Utils, UploadModel, UploadRow, UploadFtp, Popover, Select, Ui, LIST_COLLECTION_CREATOR ) {
define([ 'utils/utils', 'mvc/upload/upload-model', 'mvc/upload/collection/collection-row', 'mvc/upload/upload-ftp', 'mvc/upload/upload-extension','mvc/ui/ui-popover', 'mvc/ui/ui-select', 'mvc/ui/ui-misc', 'mvc/collection/list-collection-creator', 'utils/uploadbox' ],
function( Utils, UploadModel, UploadRow, UploadFtp, UploadExtension, Popover, Select, Ui, LIST_COLLECTION_CREATOR ) {
return Backbone.View.extend({
// current upload size in bytes
upload_size: 0,
@@ -53,8 +53,6 @@ function( Utils, UploadModel, UploadRow, UploadFtp, Popover, Select, Ui, LIST_CO
ondragleave : function() { self.$( '.upload-box' ).removeClass( 'highlight' ) }
});
console.log(this.list_extensions);
// add ftp file viewer
this.ftp = new Popover.View( { title: 'FTP files', container: this.btnFtp.$el } );
@@ -78,10 +76,11 @@ function( Utils, UploadModel, UploadRow, UploadFtp, Popover, Select, Ui, LIST_CO
// handle extension info popover
this.$( '.upload-footer-extension-info' ).on( 'click', function( e ) {
self.showExtensionInfo({
new UploadExtension({
$el : $( e.target ),
title : self.select_extension.text(),
extension : self.select_extension.value(),
list : self.list_extensions,
placement : 'top'
});
}).on( 'mousedown', function( e ) { e.preventDefault() } );
@@ -191,21 +190,6 @@ function( Utils, UploadModel, UploadRow, UploadFtp, Popover, Select, Ui, LIST_CO
// events triggered by this view
//
/** [public] display extension info popup */
showExtensionInfo: function( options ) {
var self = this;
var $el = options.$el;
var extension = options.extension;
var title = options.title;
var description = _.findWhere( self.list_extensions, { 'id': extension } );
this.extension_popup && this.extension_popup.remove();
this.extension_popup = new Popover.View({ placement: options.placement || 'bottom', container: $el } );
this.extension_popup.title( title );
this.extension_popup.empty();
this.extension_popup.append( this._templateDescription( description ) );
this.extension_popup.show();
},
/** Show/hide ftp popup */
_eventFtp: function() {
if ( !this.ftp.visible ) {
@@ -215,7 +199,7 @@ function( Utils, UploadModel, UploadRow, UploadFtp, Popover, Select, Ui, LIST_CO
collection : this.collection,
ftp_upload_site : this.ftp_upload_site,
onadd : function( ftp_file ) {
self.uploadbox.add([{
return self.uploadbox.add([{
mode: 'ftp',
name: ftp_file.path,
size: ftp_file.size,
@@ -347,19 +331,6 @@ function( Utils, UploadModel, UploadRow, UploadFtp, Popover, Select, Ui, LIST_CO
return ( this.upload_completed + ( percentage * size ) ) / this.upload_size;
},
/** Template for extensions description */
_templateDescription: function( options ) {
if ( options.description ) {
var tmpl = options.description;
if ( options.description_url ) {
tmpl += '&nbsp;(<a href="' + options.description_url + '" target="_blank">read more</a>)';
}
return tmpl;
} else {
return 'There is no description available for this file extension.';
}
},
/** Template */
_template: function() {
return '<div class="upload-view-default">' +
@@ -1,6 +1,6 @@
/** Renders contents of the composite uploader */
define([ 'utils/utils', 'mvc/upload/upload-model', 'mvc/upload/composite/composite-row', 'mvc/ui/ui-popover', 'mvc/ui/ui-select', 'mvc/ui/ui-misc'],
function( Utils, UploadModel, UploadRow, Popover, Select, Ui ) {
define([ 'utils/utils', 'mvc/upload/upload-model', 'mvc/upload/composite/composite-row', 'mvc/upload/upload-extension', 'mvc/ui/ui-popover', 'mvc/ui/ui-select', 'mvc/ui/ui-misc'],
function( Utils, UploadModel, UploadRow, UploadExtension, Popover, Select, Ui ) {
return Backbone.View.extend({
collection: new UploadModel.Collection(),
initialize: function(app) {
@@ -40,10 +40,11 @@ function( Utils, UploadModel, UploadRow, Popover, Select, Ui ) {
// handle extension info popover
this.$( '.upload-footer-extension-info' ).on( 'click', function( e ) {
self._showExtensionInfo({
new UploadExtension({
$el : $( e.target ),
title : self.select_extension.text(),
extension : self.select_extension.value(),
list : self.list_extensions,
placement : 'top'
});
}).on( 'mousedown', function( e ) { e.preventDefault() } );
@@ -126,47 +127,11 @@ function( Utils, UploadModel, UploadRow, Popover, Select, Ui ) {
this.collection.each( function( it ) { it.set( { 'status': 'error', 'info': message } ) } );
},
/** Display extension info popup */
_showExtensionInfo: function(options) {
var self = this;
var $el = options.$el;
var extension = options.extension;
var title = options.title;
var description = _.findWhere(this.list_extensions, { id : extension });
this.extension_popup && this.extension_popup.remove();
this.extension_popup = new Popover.View({
placement: options.placement || 'bottom',
container: $el,
destroy: true
});
this.extension_popup.title( title );
this.extension_popup.empty();
this.extension_popup.append( this._templateDescription( description ) );
this.extension_popup.show();
},
/* Template for extensions description */
_templateDescription: function( options ) {
if ( options.description ) {
var tmpl = options.description;
if ( options.description_url ) {
tmpl += '&nbsp;(<a href="' + options.description_url + '" target="_blank">read more</a>)';
}
return tmpl;
} else {
return 'There is no description available for this file extension.';
}
},
/** Load html template */
_template: function() {
return '<div class="upload-view-composite">' +
'<div class="upload-footer">' +
'<span class="upload-footer-title">Composite Type:</span>' +
'<span class="upload-footer-extension"/>' +
'<span class="upload-footer-extension-info upload-icon-button fa fa-search"/> ' +
'<span class="upload-footer-title">Genome/Build:</span>' +
'<span class="upload-footer-genome"/>' +
'<div class="upload-top">' +
'<h6 class="upload-top-info"/>' +
'</div>' +
'<div class="upload-box">' +
'<table class="upload-table ui-table-striped" style="display: none;">' +
@@ -184,6 +149,13 @@ function( Utils, UploadModel, UploadRow, Popover, Select, Ui ) {
'<tbody/>' +
'</table>' +
'</div>' +
'<div class="upload-footer">' +
'<span class="upload-footer-title">Composite Type:</span>' +
'<span class="upload-footer-extension"/>' +
'<span class="upload-footer-extension-info upload-icon-button fa fa-search"/> ' +
'<span class="upload-footer-title">Genome/Build:</span>' +
'<span class="upload-footer-genome"/>' +
'</div>' +
'<div class="upload-buttons"/>' +
'</div>';
}
@@ -89,11 +89,27 @@ function( Utils, UploadModel, UploadSettings, Popover, Select ) {
this.listenTo( this.model, 'change:genome', function() { self._refreshGenome() } );
this.listenTo( this.model, 'change:extension', function() { self._refreshExtension() } );
this.listenTo( this.model, 'change:file_size', function() { self._refreshFileSize() } );
this.listenTo( this.model, 'remove', function() { self.remove() } );
this.app.collection.on('reset', function() { self.remove() } );
},
render: function() {
this._refreshType();
this._refreshPercentage();
this._refreshStatus();
this._refreshInfo()
this._refreshGenome();
this._refreshExtension();
this._refreshFileSize()
},
/** Remove view */
remove: function() {
this.select_genome.remove();
this.select_extension.remove();
Backbone.View.prototype.remove.apply( this );
},
/** Render type */
_refreshType: function() {
var options = this.model.attributes;
this.$title.html( _.escape( options.file_name ) );
this.$size.html( Utils.bytesToString ( options.file_size ) );
@@ -109,13 +125,6 @@ function( Utils, UploadModel, UploadSettings, Popover, Select ) {
}
},
/** Remove view */
remove: function() {
this.select_genome.remove();
this.select_extension.remove();
Backbone.View.prototype.remove.apply( this );
},
/** Update extension */
_refreshExtension: function() {
this.select_extension.value( this.model.get( 'extension' ) );
@@ -1,6 +1,7 @@
/** Renders contents of the default uploader */
define([ 'utils/utils', 'mvc/upload/upload-model', 'mvc/upload/default/default-row', 'mvc/upload/upload-ftp', 'mvc/ui/ui-popover', 'mvc/ui/ui-select', 'mvc/ui/ui-misc', 'utils/uploadbox'],
function( Utils, UploadModel, UploadRow, UploadFtp, Popover, Select, Ui ) {
define([ 'utils/utils', 'mvc/upload/upload-model', 'mvc/upload/default/default-row', 'mvc/upload/upload-ftp', 'mvc/upload/upload-extension', 'mvc/ui/ui-popover', 'mvc/ui/ui-select', 'mvc/ui/ui-misc', 'mvc/lazy/lazy-limited', 'utils/uploadbox'],
function( Utils, UploadModel, UploadRow, UploadFtp, UploadExtension, Popover, Select, Ui, LazyLimited ) {
return Backbone.View.extend({
// current upload size in bytes
upload_size: 0,
@@ -14,7 +15,7 @@ function( Utils, UploadModel, UploadRow, UploadFtp, Popover, Select, Ui ) {
success : 0,
error : 0,
running : 0,
reset : function() { this.announce = this.success = this.error = this.running = 0 }
reset : function() { this.announce = this.success = this.error = this.running = 0 }
},
initialize : function( app ) {
@@ -25,7 +26,11 @@ function( Utils, UploadModel, UploadRow, UploadFtp, Popover, Select, Ui ) {
this.list_genomes = app.list_genomes;
this.ui_button = app.ui_button;
this.ftp_upload_site = app.currentFtp();
// build template
this.setElement( this._template() );
this.$uploadbox = this.$( '.upload-box' );
this.$uploadtable = this.$( '.upload-table' );
// append buttons to dom
this.btnLocal = new Ui.Button( { id: 'btn-local', title: 'Choose local file', onclick: function() { self.uploadbox.select() }, icon: 'fa fa-laptop' } );
@@ -40,7 +45,7 @@ function( Utils, UploadModel, UploadRow, UploadFtp, Popover, Select, Ui ) {
});
// file upload
this.uploadbox = this.$( '.upload-box' ).uploadbox({
this.uploadbox = this.$uploadbox.uploadbox({
url : this.app.options.nginx_upload_path,
announce : function( index, file ) { self._eventAnnounce( index, file ) },
initialize : function( index ) { return self.app.toData( [ self.collection.get( index ) ], self.history_id ) },
@@ -48,8 +53,8 @@ function( Utils, UploadModel, UploadRow, UploadFtp, Popover, Select, Ui ) {
success : function( index, message ) { self._eventSuccess( index, message ) },
error : function( index, message ) { self._eventError( index, message ) },
complete : function() { self._eventComplete() },
ondragover : function() { self.$( '.upload-box' ).addClass( 'highlight' ) },
ondragleave : function() { self.$( '.upload-box' ).removeClass( 'highlight' ) }
ondragover : function() { self.$uploadbox.addClass( 'highlight' ) },
ondragleave : function() { self.$uploadbox.removeClass( 'highlight' ) }
});
// add ftp file viewer
@@ -61,15 +66,16 @@ function( Utils, UploadModel, UploadRow, UploadFtp, Popover, Select, Ui ) {
container : this.$( '.upload-footer-extension' ),
data : _.filter( this.list_extensions, function( ext ) { return !ext.composite_files } ),
value : this.options.default_extension,
onchange : function( extension ) { self.updateExtension( extension ) }
onchange : function( extension ) { self._changeExtension( extension ) }
});
// handle extension info popover
this.$( '.upload-footer-extension-info' ).on( 'click', function( e ) {
self.showExtensionInfo({
new UploadExtension({
$el : $( e.target ),
title : self.select_extension.text(),
extension : self.select_extension.value(),
list : self.list_extensions,
placement : 'top'
});
}).on( 'mousedown', function( e ) { e.preventDefault() } );
@@ -80,198 +86,27 @@ function( Utils, UploadModel, UploadRow, UploadFtp, Popover, Select, Ui ) {
container : this.$( '.upload-footer-genome' ),
data : this.list_genomes,
value : this.options.default_genome,
onchange : function( genome ) { self.updateGenome(genome) }
onchange : function( genome ) { self._changeGenome(genome) }
});
// Lazy load helper
this.loader = new LazyLimited({
$container : this.$uploadbox,
collection : this.collection,
new_content : function( model ) {
var upload_row = new UploadRow( self, { model: model } )
self.$uploadtable.find( '> tbody:first' ).append( upload_row.$el );
upload_row.render();
return upload_row;
}
});
// events
this.collection.on( 'remove', function( model ) { self._eventRemove( model ) } );
this._updateScreen();
this.render();
},
/** A new file has been dropped/selected through the uploadbox plugin */
_eventAnnounce: function( index, file ) {
this.counter.announce++;
var new_model = new UploadModel.Model({
id : index,
file_name : file.name,
file_size : file.size,
file_mode : file.mode || 'local',
file_path : file.path,
file_data : file
});
this.collection.add( new_model );
var upload_row = new UploadRow( this, { model: new_model } );
this.$( '.upload-table > tbody:first' ).append( upload_row.$el );
this._updateScreen();
upload_row.render();
},
/** Progress */
_eventProgress: function( index, percentage ) {
var it = this.collection.get( index );
it.set( 'percentage', percentage );
this.ui_button.model.set( 'percentage', this._uploadPercentage( percentage, it.get( 'file_size' ) ) );
},
/** Success */
_eventSuccess: function( index, message ) {
var it = this.collection.get( index );
it.set( { 'percentage': 100, 'status': 'success' } );
this.ui_button.model.set( 'percentage', this._uploadPercentage( 100, it.get( 'file_size' ) ) );
this.upload_completed += it.get( 'file_size' ) * 100;
this.counter.announce--;
this.counter.success++;
this._updateScreen();
Galaxy.currHistoryPanel.refreshContents();
},
/** Error */
_eventError: function( index, message ) {
var it = this.collection.get( index );
it.set( { 'percentage': 100, 'status': 'error', 'info': message } );
this.ui_button.model.set( { 'percentage': this._uploadPercentage( 100, it.get( 'file_size' ) ), 'status': 'danger' } );
this.upload_completed += it.get( 'file_size' ) * 100;
this.counter.announce--;
this.counter.error++;
this._updateScreen();
},
/** Queue is done */
_eventComplete: function() {
this.collection.each( function( model ) { model.get( 'status' ) == 'queued' && model.set( 'status', 'init' ) } );
this.counter.running = 0;
this._updateScreen();
},
/** Remove model from upload list */
_eventRemove: function( model ) {
var status = model.get( 'status' );
if ( status == 'success' ) {
this.counter.success--;
} else if ( status == 'error' ) {
this.counter.error--;
} else {
this.counter.announce--;
}
this.uploadbox.remove( model.id );
this._updateScreen();
},
//
// events triggered by this view
//
/** [public] display extension info popup */
showExtensionInfo: function( options ) {
var self = this;
var $el = options.$el;
var extension = options.extension;
var title = options.title;
var description = _.findWhere( self.list_extensions, { 'id': extension } );
this.extension_popup && this.extension_popup.remove();
this.extension_popup = new Popover.View({ placement: options.placement || 'bottom', container: $el } );
this.extension_popup.title( title );
this.extension_popup.empty();
this.extension_popup.append( this._templateDescription( description ) );
this.extension_popup.show();
},
/** Show/hide ftp popup */
_eventFtp: function() {
if ( !this.ftp.visible ) {
this.ftp.empty();
var self = this;
this.ftp.append( ( new UploadFtp({
collection : this.collection,
ftp_upload_site : this.ftp_upload_site,
onadd : function( ftp_file ) {
self.uploadbox.add([{
mode: 'ftp',
name: ftp_file.path,
size: ftp_file.size,
path: ftp_file.path
}]);
},
onremove: function( model_index ) {
self.collection.remove( model_index );
}
} ) ).$el );
this.ftp.show();
} else {
this.ftp.hide();
}
},
/** Create a new file */
_eventCreate: function (){
this.uploadbox.add( [ { name: 'New File', size: 0, mode: 'new' } ] );
},
/** Start upload process */
_eventStart: function() {
if ( this.counter.announce == 0 || this.counter.running > 0 ) {
return;
}
var self = this;
this.upload_size = 0;
this.upload_completed = 0;
this.collection.each( function( model ) {
if( model.get( 'status' ) == 'init' ) {
model.set( 'status', 'queued' );
self.upload_size += model.get( 'file_size' );
}
});
this.ui_button.model.set( { 'percentage': 0, 'status': 'success' } );
this.counter.running = this.counter.announce;
this.history_id = this.app.currentHistory();
this.uploadbox.start();
this._updateScreen();
},
/** Pause upload process */
_eventStop: function() {
if ( this.counter.running > 0 ) {
this.ui_button.model.set( 'status', 'info' );
$( '.upload-top-info' ).html( 'Queue will pause after completing the current file...' );
this.uploadbox.stop();
}
},
/** Remove all */
_eventReset: function() {
if ( this.counter.running == 0 ){
this.collection.reset();
this.counter.reset();
this.uploadbox.reset();
this.select_extension.value( this.options.default_extension );
this.select_genome.value( this.options.default_genome );
this.ui_button.model.set( 'percentage', 0 );
this._updateScreen();
}
},
/** Update extension for all models */
updateExtension: function( extension, defaults_only ) {
var self = this;
this.collection.each( function( model ) {
if ( model.get( 'status' ) == 'init' && ( model.get( 'extension' ) == self.options.default_extension || !defaults_only ) ) {
model.set( 'extension', extension );
}
});
},
/** Update genome for all models */
updateGenome: function( genome, defaults_only ) {
var self = this;
this.collection.each( function( model ) {
if ( model.get( 'status' ) == 'init' && ( model.get( 'genome' ) == self.options.default_genome || !defaults_only ) ) {
model.set( 'genome', genome );
}
});
},
/** Set screen */
_updateScreen: function () {
render: function () {
var message = '';
if( this.counter.announce == 0 ) {
if (this.uploadbox.compatible()) {
@@ -303,24 +138,201 @@ function( Utils, UploadModel, UploadRow, UploadFtp, Popover, Select, Ui ) {
this.$( '.upload-helper' )[ show_table ? 'hide' : 'show' ]();
},
/** A new file has been dropped/selected through the uploadbox plugin */
_eventAnnounce: function( index, file ) {
this.counter.announce++;
var new_model = new UploadModel.Model({
id : index,
file_name : file.name,
file_size : file.size,
file_mode : file.mode || 'local',
file_path : file.path,
file_data : file
});
this.render();
this.collection.add( new_model );
},
/** Progress */
_eventProgress: function( index, percentage ) {
var it = this.collection.get( index );
it.set( 'percentage', percentage );
this.ui_button.model.set( 'percentage', this._uploadPercentage( percentage, it.get( 'file_size' ) ) );
},
/** Success */
_eventSuccess: function( index, message ) {
var it = this.collection.get( index );
it.set( { 'percentage': 100, 'status': 'success' } );
this.ui_button.model.set( 'percentage', this._uploadPercentage( 100, it.get( 'file_size' ) ) );
this.upload_completed += it.get( 'file_size' ) * 100;
this.counter.announce--;
this.counter.success++;
this.render();
Galaxy.currHistoryPanel.refreshContents();
},
/** Error */
_eventError: function( index, message ) {
var it = this.collection.get( index );
it.set( { 'percentage': 100, 'status': 'error', 'info': message } );
this.ui_button.model.set( { 'percentage': this._uploadPercentage( 100, it.get( 'file_size' ) ), 'status': 'danger' } );
this.upload_completed += it.get( 'file_size' ) * 100;
this.counter.announce--;
this.counter.error++;
this.render();
},
/** Queue is done */
_eventComplete: function() {
this.collection.each( function( model ) { model.get( 'status' ) == 'queued' && model.set( 'status', 'init' ) } );
this.counter.running = 0;
this.render();
},
/** Remove model from upload list */
_eventRemove: function( model ) {
var status = model.get( 'status' );
if ( status == 'success' ) {
this.counter.success--;
} else if ( status == 'error' ) {
this.counter.error--;
} else {
this.counter.announce--;
}
this.uploadbox.remove( model.id );
this.render();
},
//
// events triggered by this view
//
/** Show/hide ftp popup */
_eventFtp: function() {
if ( !this.ftp.visible ) {
this.ftp.empty();
var self = this;
this.ftp.append( ( new UploadFtp({
collection : this.collection,
ftp_upload_site : this.ftp_upload_site,
onadd : function( ftp_file ) {
return self.uploadbox.add([{
mode: 'ftp',
name: ftp_file.path,
size: ftp_file.size,
path: ftp_file.path
}]);
},
onremove: function( model_index ) {
self.collection.remove( model_index );
}
} ) ).$el );
this.ftp.show();
} else {
this.ftp.hide();
}
},
/** Create a new file */
_eventCreate: function (){
this.uploadbox.add( [ { name: 'New File', size: 0, mode: 'new' } ] );
},
/** Start upload process */
_eventStart: function() {
if ( this.counter.announce != 0 && this.counter.running == 0 ) {
// prepare upload process
var self = this;
this.upload_size = 0;
this.upload_completed = 0;
this.collection.each( function( model ) {
if( model.get( 'status' ) == 'init' ) {
model.set( 'status', 'queued' );
self.upload_size += model.get( 'file_size' );
}
});
this.ui_button.model.set( { 'percentage': 0, 'status': 'success' } );
this.counter.running = this.counter.announce;
this.history_id = this.app.currentHistory();
// package ftp files separately, and remove them from queue
this._uploadFtp();
// queue remaining files
this.uploadbox.start();
this.render();
}
},
/** Pause upload process */
_eventStop: function() {
if ( this.counter.running > 0 ) {
this.ui_button.model.set( 'status', 'info' );
$( '.upload-top-info' ).html( 'Queue will pause after completing the current file...' );
this.uploadbox.stop();
}
},
/** Remove all */
_eventReset: function() {
if ( this.counter.running == 0 ){
var self = this;
this.collection.reset();
this.counter.reset();
this.uploadbox.reset();
this.select_extension.value( this.options.default_extension );
this.select_genome.value( this.options.default_genome );
this.ui_button.model.set( 'percentage', 0 );
this.render();
}
},
/** Update extension for all models */
_changeExtension: function( extension, defaults_only ) {
var self = this;
this.collection.each( function( model ) {
if ( model.get( 'status' ) == 'init' && ( model.get( 'extension' ) == self.options.default_extension || !defaults_only ) ) {
model.set( 'extension', extension );
}
});
},
/** Update genome for all models */
_changeGenome: function( genome, defaults_only ) {
var self = this;
this.collection.each( function( model ) {
if ( model.get( 'status' ) == 'init' && ( model.get( 'genome' ) == self.options.default_genome || !defaults_only ) ) {
model.set( 'genome', genome );
}
});
},
/** Package and upload ftp files in a single request */
_uploadFtp: function() {
var self = this;
var list = [];
this.collection.each( function( model ) {
if( model.get( 'status' ) == 'queued' && model.get( 'file_mode' ) == 'ftp' ) {
self.uploadbox.remove( model.id );
list.push( model );
}
});
if(list.length > 0) {
$.uploadpost({
data : this.app.toData( list ),
url : this.app.options.nginx_upload_path,
success : function( message ) { _.each( list, function( model ) { self._eventSuccess( model.id ) } ) },
error : function( message ) { _.each( list, function( model ) { self._eventError( model.id, message ) } ) }
});
}
},
/** Calculate percentage of all queued uploads */
_uploadPercentage: function( percentage, size ) {
return ( this.upload_completed + ( percentage * size ) ) / this.upload_size;
},
/** Template for extensions description */
_templateDescription: function( options ) {
if ( options.description ) {
var tmpl = options.description;
if ( options.description_url ) {
tmpl += '&nbsp;(<a href="' + options.description_url + '" target="_blank">read more</a>)';
}
return tmpl;
} else {
return 'There is no description available for this file extension.';
}
},
/** Template */
_template: function() {
return '<div class="upload-view-default">' +
@@ -0,0 +1,35 @@
/** This renders a popover with extension details **/
define( [ 'utils/utils', 'mvc/ui/ui-popover' ], function( Utils, Popover ) {
return Backbone.View.extend({
initialize: function( options ) {
this.model = new Backbone.Model( options );
this.setElement( '<div/>' );
this.render();
},
render: function() {
var self = this;
var options = this.model.attributes;
var description = _.findWhere( options.list, { 'id': options.extension } );
this.extension_popup && this.extension_popup.remove();
this.extension_popup = new Popover.View({ placement: options.placement || 'bottom', container: options.$el } );
this.extension_popup.title( options.title );
this.extension_popup.empty();
this.extension_popup.append( this._templateDescription( description ) );
this.extension_popup.show();
},
/** Template for extensions description */
_templateDescription: function( options ) {
if ( options.description ) {
var tmpl = options.description;
if ( options.description_url ) {
tmpl += '&nbsp;(<a href="' + options.description_url + '" target="_blank">read more</a>)';
}
return tmpl;
} else {
return 'There is no description available for this file extension.';
}
}
});
});
+132 -91
View File
@@ -3,105 +3,153 @@ define( [ 'utils/utils' ], function( Utils ) {
return Backbone.View.extend({
initialize: function( options ) {
var self = this;
this.options = Utils.merge( options, {
this.model = new Backbone.Model( {
cls : 'upload-ftp',
class_add : 'upload-icon-button fa fa-square-o',
class_remove : 'upload-icon-button fa fa-check-square-o',
class_partial : 'upload-icon-button fa fa-minus-square-o',
help_enabled : true,
help_text : 'This Galaxy server allows you to upload files via FTP. To upload some files, log in to the FTP server at <strong>' + options.ftp_upload_site + '</strong> using your Galaxy credentials.',
collection : null,
onchange : function() {},
onadd : function() {},
onremove : function() {}
} );
this.collection = this.options.collection;
} ).set( options );
this.collection = this.model.get( 'collection' );
this.setElement( this._template() );
this.rows = [];
Utils.get({
this.$content = this.$( '.upload-ftp-content' );
this.$wait = this.$( '.upload-ftp-wait' );
this.$help = this.$( '.upload-ftp-help' );
this.$number = this.$( '.upload-ftp-number' );
this.$disk = this.$( '.upload-ftp-disk' );
this.$body = this.$( '.upload-ftp-body' );
this.$warning = this.$( '.upload-ftp-warning' );
this.$select = this.$( '.upload-ftp-select-all' );
this.render();
},
render: function() {
var self = this;
this.$wait.show();
this.$content.hide();
this.$warning.hide();
this.$help.hide();
$.ajax({
url : Galaxy.root + 'api/remote_files',
success : function( ftp_files ) { self._fill( ftp_files ) },
error : function() { self._fill(); }
method : 'GET',
success : function( ftp_files ) {
self.model.set( 'ftp_files', ftp_files );
self._index();
self._renderTable();
},
error : function() { self._renderTable() }
});
},
/** Fill table with ftp entries */
_fill: function( ftp_files ) {
_renderTable: function() {
var self = this;
var ftp_files = this.model.get( 'ftp_files' );
this.rows = [];
if ( ftp_files && ftp_files.length > 0 ) {
this.$( '.upload-ftp-content' ).html( $( this._templateTable() ) );
this.$body.empty();
var size = 0;
for (var index in ftp_files ) {
this.rows.push( this._add( ftp_files[ index ] ) );
size += ftp_files[ index ].size;
}
this.$( '.upload-ftp-number' ).html( ftp_files.length + ' files' );
this.$( '.upload-ftp-disk' ).html( Utils.bytesToString ( size, true ) );
_.each( ftp_files, function( ftp_file ) {
self.rows.push( self._renderRow( ftp_file ) );
size += ftp_file.size;
} );
this.$number.html( ftp_files.length + ' files' );
this.$disk.html( Utils.bytesToString ( size, true ) );
if ( this.collection ) {
var self = this;
this.$( '._has_collection' ).show();
this.$select_all = this.$( '.upload-selectall' ).addClass( this.options.class_add );
this.$select_all.on( 'click', function() {
var add = self.$select_all.hasClass( self.options.class_add );
for (var index in ftp_files ) {
var ftp_file = ftp_files[ index ];
var model_index = self._find( ftp_file );
if( !model_index && add || model_index && !add ) {
self.rows[ index ].trigger( 'click' );
}
}
});
this.$select.addClass( this.model.get( 'class_add' ) )
.off().on( 'click', function() { self._all() } );
this._refresh();
}
this.$content.show();
} else {
this.$( '.upload-ftp-content' ).html( $( this._templateInfo() ) );
this.$warning.show();
}
this.$( '.upload-ftp-wait' ).hide();
this.model.get( 'help_enabled' ) && this.$help.show();
this.$wait.hide();
},
/** Add file to table */
_add: function( ftp_file ) {
/** Add row */
_renderRow: function( ftp_file ) {
var self = this;
var options = this.model.attributes;
var $it = $( this._templateRow( ftp_file ) );
var $icon = $it.find( '.icon' );
this.$( 'tbody' ).append( $it );
this.$body.append( $it );
if ( this.collection ) {
$icon.addClass( this._find( ftp_file ) ? this.options.class_remove : this.options.class_add );
var model_index = this.ftp_index[ ftp_file.path ];
$icon.addClass( model_index === undefined ? options.class_add : options.class_remove );
$it.on('click', function() {
var model_index = self._find( ftp_file );
$icon.removeClass();
if ( !model_index ) {
self.options.onadd( ftp_file );
$icon.addClass( self.options.class_remove );
} else {
self.options.onremove( model_index );
$icon.addClass( self.options.class_add );
}
self._switch( $icon, ftp_file );
self._refresh();
});
} else {
$it.on('click', function() { self.options.onchange( ftp_file ) } );
$it.on('click', function() { options.onchange( ftp_file ) } );
}
return $icon;
},
/** Create ftp index */
_index: function() {
var self = this;
this.ftp_index = {};
this.collection && this.collection.each( function( model ) {
if ( model.get( 'file_mode' ) == 'ftp' ) {
self.ftp_index[ model.get( 'file_path' ) ] = model.id;
}
} );
},
/** Select all event handler */
_all: function() {
var options = this.model.attributes;
var ftp_files = this.model.get( 'ftp_files' );
var add = this.$select.hasClass( options.class_add );
for (var index in ftp_files ) {
var ftp_file = ftp_files[ index ];
var model_index = this.ftp_index[ ftp_file.path ];
if( model_index === undefined && add || model_index !== undefined && !add ) {
this._switch( this.rows[ index ], ftp_file );
}
}
this._refresh();
},
/** Handle collection changes */
_switch: function( $icon, ftp_file ) {
$icon.removeClass();
var options = this.model.attributes;
var model_index = this.ftp_index[ ftp_file.path ];
if ( model_index === undefined ) {
var new_index = options.onadd( ftp_file );
$icon.addClass( options.class_remove );
this.ftp_index[ ftp_file.path ] = new_index;
} else {
options.onremove( model_index );
$icon.addClass( options.class_add );
this.ftp_index[ ftp_file.path ] = undefined;
}
return $it;
},
/** Refresh select all button state */
_refresh: function() {
var filtered = this.collection.where( { file_mode: 'ftp', enabled: true } );
this.$select_all.removeClass();
if ( filtered.length == 0 ) {
this.$select_all.addClass( this.options.class_add );
var counts = _.reduce( this.ftp_index, function( memo, element ) {
( element !== undefined ) && memo++;
return memo;
}, 0 );
this.$select.removeClass();
if ( counts == 0 ) {
this.$select.addClass( this.model.get( 'class_add' ) );
} else {
this.$select_all.addClass( filtered.length == this.rows.length ? this.options.class_remove : this.options.class_partial );
this.$select.addClass( counts == this.rows.length ? this.model.get( 'class_remove' ) : this.model.get( 'class_partial' ) );
}
},
/** Get model index */
_find: function( ftp_file ) {
var item = this.collection.findWhere({
file_path : ftp_file.path,
file_mode : 'ftp',
enabled : true
});
return item && item.get('id');
},
/** Template of row */
_templateRow: function( options ) {
return '<tr class="upload-ftp-row">' +
@@ -112,41 +160,34 @@ define( [ 'utils/utils' ], function( Utils ) {
'</tr>';
},
/** Template of table */
_templateTable: function() {
return '<span style="whitespace: nowrap; float: left;">Available files: </span>' +
'<span style="whitespace: nowrap; float: right;">' +
'<span class="upload-icon fa fa-file-text-o"/>' +
'<span class="upload-ftp-number"/>&nbsp;&nbsp;' +
'<span class="upload-icon fa fa-hdd-o"/>' +
'<span class="upload-ftp-disk"/>' +
'</span>' +
'<table class="grid" style="float: left;">' +
'<thead>' +
'<tr>' +
'<th class="_has_collection" style="display: none;"><div class="upload-selectall"></th>' +
'<th>Name</th>' +
'<th>Size</th>' +
'<th>Created</th>' +
'</tr>' +
'</thead>' +
'<tbody/>' +
'</table>';
},
/** Template of info message */
_templateInfo: function() {
return '<div class="upload-ftp-warning warningmessage">' +
'Your FTP directory does not contain any files.' +
'</div>';
},
/** Template of main view */
_template: function() {
return '<div class="upload-ftp">' +
return '<div class="' + this.model.get( 'cls' ) + '">' +
'<div class="upload-ftp-wait fa fa-spinner fa-spin"/>' +
'<div class="upload-ftp-help">This Galaxy server allows you to upload files via FTP. To upload some files, log in to the FTP server at <strong>' + this.options.ftp_upload_site + '</strong> using your Galaxy credentials (email address and password).</div>' +
'<div class="upload-ftp-content"/>' +
'<div class="upload-ftp-help">' + this.model.get( 'help_text' ) + '</div>' +
'<div class="upload-ftp-content">' +
'<span style="whitespace: nowrap; float: left;">Available files: </span>' +
'<span style="whitespace: nowrap; float: right;">' +
'<span class="upload-icon fa fa-file-text-o"/>' +
'<span class="upload-ftp-number"/>&nbsp;&nbsp;' +
'<span class="upload-icon fa fa-hdd-o"/>' +
'<span class="upload-ftp-disk"/>' +
'</span>' +
'<table class="grid" style="float: left;">' +
'<thead>' +
'<tr>' +
'<th class="_has_collection" style="display: none;"><div class="upload-ftp-select-all"></th>' +
'<th>Name</th>' +
'<th>Size</th>' +
'<th>Created</th>' +
'</tr>' +
'</thead>' +
'<tbody class="upload-ftp-body"/>' +
'</table>' +
'</div>' +
'<div class="upload-ftp-warning warningmessage">' +
'Your FTP directory does not contain any files.' +
'</div>'
'<div>';
}
});
@@ -1,5 +1,5 @@
/** Upload app contains the upload progress button and upload modal, compiles model data for API request **/
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'],
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( Utils, Modal, Tabs, UploadButton, UploadViewDefault, UploadViewComposite, UploadViewCollection ) {
return Backbone.View.extend({
options : {
@@ -114,7 +114,7 @@ function( Utils, Modal, Tabs, UploadButton, UploadViewDefault, UploadViewComposi
id : 'collection',
title : 'Collection',
$el : this.collection_view.$el
})
});
this.modal = new Modal.View({
title : 'Download from web or upload from disk',
body : this.tabs.$el,
@@ -154,9 +154,11 @@ function( Utils, Modal, Tabs, UploadButton, UploadViewDefault, UploadViewComposi
}
// add upload tools input data
if ( items && items.length > 0 ) {
var inputs = {};
inputs[ 'dbkey' ] = items[0].get( 'genome', null );
inputs[ 'file_type' ] = items[0].get( 'extension', null );
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' );
@@ -165,6 +167,8 @@ function( Utils, Modal, Tabs, UploadButton, UploadViewDefault, UploadViewComposi
inputs[ prefix + 'type' ] = 'upload_dataset';
inputs[ prefix + 'space_to_tab' ] = it.get( 'space_to_tab' ) && 'Yes' || null;
inputs[ prefix + 'to_posix_lines' ] = it.get( 'to_posix_lines' ) && 'Yes' || null;
inputs[ prefix + 'dbkey' ] = it.get( 'genome', null );
inputs[ prefix + 'file_type' ] = it.get( 'extension', null );
switch ( it.get( 'file_mode' ) ) {
case 'new':
inputs[ prefix + 'url_paste' ] = it.get( 'url_paste' );
+3 -3
View File
@@ -187,7 +187,7 @@
// add new files to upload queue
function add(files) {
if (files && files.length && !queue_running) {
var current_index = queue_index;
var index = undefined;
_.each(files, function(file, key) {
if (file.mode !== 'new' && _.filter(queue, function(f) {
return f.name === file.name && f.size === file.size;
@@ -197,13 +197,13 @@
});
_.each(files, function(file) {
if (!file.duplicate) {
var index = String(queue_index++);
index = String(queue_index++);
queue[index] = file;
opts.announce(index, queue[index]);
queue_length++;
}
});
return current_index;
return index;
}
}
+10
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 {
@@ -994,6 +997,13 @@
background: lighten(@state-success-bg, 10%) !important;
}
.ui-limitloader {
padding: 10px;
float: left;
font-weight: bold;
display: none;
}
// global select2 adjustments
.select2-container .select2-choice,
.select2-container .select2-choices {
+36 -14
View File
@@ -160,6 +160,9 @@
}
}
}
.upload-box-solid {
border: 1px solid @btn-default-border;
}
.upload-buttons {
padding-top: 30px;
button {
@@ -179,8 +182,6 @@
.upload-view-composite {
&:extend(.upload-view-default all);
.upload-box {
margin-top: 10px;
background: lighten(@btn-default-border, 30%);
.upload-row {
.upload-title {
width: 175px;
@@ -192,16 +193,10 @@
}
}
}
.upload-footer {
margin-top: 35px;
}
}
.upload-ftp {
height: 250px;
width: 500px;
overflow-y: auto;
overflow-x: hidden;
.upload-ftp-base {
position: relative;
.upload-ftp-wait {
font-size: 1.2em;
position: absolute;
@@ -213,21 +208,18 @@
}
.upload-ftp-warning {
text-align: center;
margin-top: 20px;
margin-top: 50px;
}
.upload-ftp-row {
cursor: pointer;
.ftp-name {
position: relative;
width: 240px;
word-wrap: break-word;
}
.ftp-size {
width: 60px;
white-space: nowrap;
}
.ftp-time {
width: 165px;
white-space: nowrap;
}
}
@@ -242,6 +234,36 @@
}
}
.upload-ftp {
&:extend(.upload-ftp-base all);
height: 250px;
width: 500px;
overflow-y: auto;
overflow-x: hidden;
.upload-ftp-row {
cursor: pointer;
.ftp-name {
width: 240px;
}
.ftp-size {
width: 60px;
}
.ftp-time {
width: 165px;
}
}
}
.upload-ftp-full {
&:extend(.upload-ftp-base all);
.upload-ftp-content {
line-height: 2.0em !important;
}
th {
text-align: center !important;
}
}
.upload-settings {
position: relative;
.upload-settings-cover {
+7 -7
View File
@@ -1175,13 +1175,6 @@
}
}
},
"string_decoder": {
"version": "1.0.1",
"bundled": true,
"requires": {
"safe-buffer": "5.0.1"
}
},
"string-width": {
"version": "1.0.2",
"bundled": true,
@@ -1191,6 +1184,13 @@
"strip-ansi": "3.0.1"
}
},
"string_decoder": {
"version": "1.0.1",
"bundled": true,
"requires": {
"safe-buffer": "5.0.1"
}
},
"stringstream": {
"version": "0.0.5",
"bundled": true,
+12
View File
@@ -51,3 +51,15 @@
# influxdb_port: 8086
# influxdb_database: galaxy
# influxdb_timeout: 2
# Github error reporting backend. You will need to `pip install pygithub` in
# the galaxy virtualenv. This will create a new issue if none exists, and
# comment on existing, open issues. The issues are labelled based on tool ID /
# version and include all of the information the normal emailed bug reports
# include. If you use a private Github Enterprise deployment, you can set
# github_base_url='https://...'
# - type: github
# user_submission: true
# github_oauth_token: 00000000000
# github_repo_owner: galaxyproject
# github_repo_name: galaxy
-3
View File
@@ -80,9 +80,6 @@ def main():
config_sample.write(outputfile)
outputfile.close()
else:
# print "----------"
# config_sample.write(sys.stdout)
# print "----------"
logging.info("use -o OUTPUT to write the merged configuration into a file.")
logging.info("read Galaxy galaxy.ini.sample for detailed information.")
+4
View File
@@ -1039,6 +1039,10 @@ class ConfiguresGalaxyMixin:
combined_install_database = not(install_db_url and install_db_url != db_url)
install_db_url = install_db_url or db_url
if getattr(self.config, "max_metadata_value_size", None):
from galaxy.model import custom_types
custom_types.MAX_METADATA_VALUE_SIZE = self.config.max_metadata_value_size
if check_migrate_databases:
# Initialize database / check for appropriate schema version. # If this
# is a new installation, we'll restrict the tool migration messaging.
@@ -15,28 +15,28 @@ class CollectionTypeDescription(object):
""" Abstraction over dataset collection type that ties together string
reprentation in database/model with type registry.
>>> factory = CollectionTypeDescriptionFactory( None )
>>> nested_type_description = factory.for_collection_type( "list:paired" )
>>> paired_type_description = factory.for_collection_type( "paired" )
>>> nested_type_description.has_subcollections_of_type( "list" )
>>> factory = CollectionTypeDescriptionFactory(None)
>>> nested_type_description = factory.for_collection_type("list:paired")
>>> paired_type_description = factory.for_collection_type("paired")
>>> nested_type_description.has_subcollections_of_type("list")
False
>>> nested_type_description.has_subcollections_of_type( "list:paired" )
>>> nested_type_description.has_subcollections_of_type("list:paired")
False
>>> nested_type_description.has_subcollections_of_type( "paired" )
>>> nested_type_description.has_subcollections_of_type("paired")
True
>>> nested_type_description.has_subcollections_of_type( paired_type_description )
>>> nested_type_description.has_subcollections_of_type(paired_type_description)
True
>>> nested_type_description.has_subcollections( )
>>> nested_type_description.has_subcollections()
True
>>> paired_type_description.has_subcollections( )
>>> paired_type_description.has_subcollections()
False
>>> paired_type_description.rank_collection_type()
'paired'
>>> nested_type_description.rank_collection_type()
'list'
>>> nested_type_description.effective_collection_type( paired_type_description )
>>> nested_type_description.effective_collection_type(paired_type_description)
'list'
>>> nested_type_description.effective_collection_type_description( paired_type_description ).collection_type
>>> nested_type_description.effective_collection_type_description(paired_type_description).collection_type
'list'
"""
@@ -4,7 +4,7 @@ from __future__ import print_function
import sys
assert sys.version_info[:2] >= (2, 4)
assert sys.version_info[:2] >= (2, 6)
def __main__():
@@ -3,7 +3,7 @@ from __future__ import print_function
import sys
assert sys.version_info[:2] >= (2, 4)
assert sys.version_info[:2] >= (2, 6)
def __main__():
@@ -6,7 +6,7 @@ import sys
import bx.intervals.io
assert sys.version_info[:2] >= (2, 4)
assert sys.version_info[:2] >= (2, 6)
def stop_err(msg):
@@ -6,7 +6,7 @@ import sys
import bx.intervals.io
assert sys.version_info[:2] >= (2, 4)
assert sys.version_info[:2] >= (2, 6)
def stop_err(msg):
@@ -8,7 +8,7 @@ import bx.align.maf
from galaxy.tools.util import maf_utilities
assert sys.version_info[:2] >= (2, 4)
assert sys.version_info[:2] >= (2, 6)
def __main__():
@@ -8,7 +8,7 @@ import bx.align.maf
from galaxy.tools.util import maf_utilities
assert sys.version_info[:2] >= (2, 4)
assert sys.version_info[:2] >= (2, 6)
def __main__():
@@ -4,7 +4,7 @@ from __future__ import print_function
import sys
assert sys.version_info[:2] >= (2, 5)
assert sys.version_info[:2] >= (2, 6)
HEADER_STARTS_WITH = ('@')
@@ -260,8 +260,6 @@ class LimitedOffsetDataProvider(FilteredDataProvider):
parent_gen = super(LimitedOffsetDataProvider, self).__iter__()
for datum in parent_gen:
self.num_data_returned -= 1
# print 'self.num_data_returned:', self.num_data_returned
# print 'self.num_valid_data_read:', self.num_valid_data_read
if self.num_valid_data_read > self.offset:
self.num_data_returned += 1
+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 -1
View File
@@ -351,8 +351,8 @@ class Arff(Text):
5.1,3.5,1.4,0.2,Iris-setosa
4.9,3.0,1.4,0.2,Iris-setosa
"""
comment_lines = column_count = 0
if dataset.has_data():
comment_lines = 0
first_real_line = False
data_block = False
with open(dataset.file_name) as handle:
-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 -41
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
@@ -4273,7 +4242,6 @@ class MetadataFile(StorableObject):
return path
except AttributeError:
# In case we're not working with the history_dataset
# print "Caught AttributeError"
path = os.path.join(Dataset.file_path, '_metadata_files', *directory_hash_id(self.id))
# Create directory if it does not exist
try:
+5 -3
View File
@@ -16,7 +16,6 @@ from sqlalchemy.types import (
TypeDecorator
)
from galaxy import app
from galaxy.util.aliaspickler import AliasPickleModule
log = logging.getLogger(__name__)
@@ -25,6 +24,9 @@ log = logging.getLogger(__name__)
json_encoder = json.JSONEncoder(sort_keys=True)
json_decoder = json.JSONDecoder()
# Galaxy app will set this if configured to avoid circular dependency
MAX_METADATA_VALUE_SIZE = None
def _sniffnfix_pg9_hex(value):
"""
@@ -272,10 +274,10 @@ class MetadataType(JSONType):
def process_bind_param(self, value, dialect):
if value is not None:
if app.app and app.app.config.max_metadata_value_size:
if MAX_METADATA_VALUE_SIZE is not None:
for k, v in list(value.items()):
sz = total_size(v)
if sz > app.app.config.max_metadata_value_size:
if sz > MAX_METADATA_VALUE_SIZE:
del value[k]
log.warning('Refusing to bind metadata key %s due to size (%s)' % (k, sz))
value = json_encoder.encode(value)
-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'),
-3
View File
@@ -122,7 +122,6 @@ class ViewQueryBaseClass(object):
clazz, attribute = field.sqlalchemy_field
sqlalchemy_field_value = getattr(clazz, attribute)
if operator == "=":
# print field.sqlalchemy_field == right, field.sqlalchemy_field, right
self.query = self.query.filter(sqlalchemy_field_value == right)
elif operator == "!=":
self.query = self.query.filter(sqlalchemy_field_value != right)
@@ -166,7 +165,6 @@ def library_extended_metadata_filter(view, left, operator, right):
view.state['extended_metadata_joined'] = True
alias = aliased(ExtendedMetadataIndex)
field = "/%s" % ("/".join(left.split(".")[1:]))
# print "FIELD", field
view.query = view.query.filter(
and_(
ExtendedMetadata.id == alias.extended_metadata_id,
@@ -313,7 +311,6 @@ def history_dataset_extended_metadata_filter(view, left, operator, right):
view.state['extended_metadata_joined'] = True
alias = aliased(ExtendedMetadataIndex)
field = "/%s" % ("/".join(left.split(".")[1:]))
# print "FIELD", field
view.query = view.query.filter(
and_(
ExtendedMetadata.id == alias.extended_metadata_id,
+15 -18
View File
@@ -1,7 +1,6 @@
"""
Object Store plugin for the Amazon Simple Storage Service (S3)
"""
import logging
import multiprocessing
import os
@@ -9,9 +8,17 @@ import shutil
import subprocess
import threading
import time
from datetime import datetime
try:
# Imports are done this way to allow objectstore code to be used outside of Galaxy.
import boto
from boto.exception import S3ResponseError
from boto.s3.connection import S3Connection
from boto.s3.key import Key
except ImportError:
boto = None
from galaxy.exceptions import ObjectInvalid, ObjectNotFound
from galaxy.util import (
directory_hash_id,
@@ -25,16 +32,6 @@ from galaxy.util.sleeper import Sleeper
from .s3_multipart_upload import multipart_upload
from ..objectstore import convert_bytes, ObjectStore
try:
# Imports are done this way to allow objectstore code to be used outside of Galaxy.
import boto
from boto.exception import S3ResponseError
from boto.s3.key import Key
from boto.s3.connection import S3Connection
except ImportError:
boto = None
NO_BOTO_ERROR_MESSAGE = ("S3/Swift object store configured, but no boto dependency available."
"Please install and properly configure boto or modify object store configuration.")
@@ -296,21 +293,21 @@ class S3ObjectStore(ObjectStore):
# creates, this check sould be implemented- in the mean time, it's not
# looking likely to be implementable reliably.
# if os.path.exists(cache_path):
# # print "***1 %s exists" % cache_path
# # print("***1 %s exists" % cache_path)
# if self._key_exists(rel_path):
# # print "***2 %s exists in S3" % rel_path
# # print("***2 %s exists in S3" % rel_path)
# # Make sure the size in cache is available in its entirety
# # print "File '%s' cache size: %s, S3 size: %s" % (cache_path, os.path.getsize(cache_path), self._get_size_in_s3(rel_path))
# # print("File '%s' cache size: %s, S3 size: %s" % (cache_path, os.path.getsize(cache_path), self._get_size_in_s3(rel_path)))
# if os.path.getsize(cache_path) == self._get_size_in_s3(rel_path):
# # print "***2.1 %s exists in S3 and the size is the same as in cache (in_cache=True)" % rel_path
# # print("***2.1 %s exists in S3 and the size is the same as in cache (in_cache=True)" % rel_path)
# exists = True
# else:
# # print "***2.2 %s exists but differs in size from cache (in_cache=False)" % cache_path
# # print("***2.2 %s exists but differs in size from cache (in_cache=False)" % cache_path)
# exists = False
# else:
# # Although not perfect decision making, this most likely means
# # that the file is currently being uploaded
# # print "***3 %s found in cache but not in S3 (in_cache=True)" % cache_path
# # print("***3 %s found in cache but not in S3 (in_cache=True)" % cache_path)
# exists = True
# else:
# return False
+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
+8 -2
View File
@@ -35,7 +35,13 @@ ALL_CONTAINER_TYPES = [DOCKER_CONTAINER_TYPE, SINGULARITY_CONTAINER_TYPE]
LOAD_CACHED_IMAGE_COMMAND_TEMPLATE = '''
python << EOF
import re, tarfile, json, subprocess
from __future__ import print_function
import json
import re
import subprocess
import tarfile
t = tarfile.TarFile("${cached_image_file}")
meta_str = t.extractfile('repositories').read()
meta = json.loads(meta_str)
@@ -50,7 +56,7 @@ for line in stdo.split("\\n"):
if tmp[0] == tag and tmp[1] == rev and tmp[2] == rev_value:
found = True
if not found:
print "Loading image"
print("Loading image")
cmd = "cat ${cached_image_file} | ${load_cmd}"
subprocess.check_call(cmd, shell=True)
EOF
@@ -0,0 +1,93 @@
"""The module describes the ``github`` error plugin plugin."""
from __future__ import absolute_import
import logging
from galaxy.tools.errors import EmailErrorReporter
from galaxy.util import string_as_bool, unicodify
from ..plugins import ErrorPlugin
log = logging.getLogger(__name__)
class GithubPlugin(ErrorPlugin):
"""Send error report to Github.
"""
plugin_type = "github"
def __init__(self, **kwargs):
self.app = kwargs['app']
self.verbose = string_as_bool(kwargs.get('verbose', False))
self.user_submission = string_as_bool(kwargs.get('user_submission', False))
try:
import github
self.github = github.Github(
kwargs['github_oauth_token'],
# Allow running against GH enterprise deployments.
base_url=kwargs.get('github_base_url', 'https://api.github.com')
)
self.repo = self.github.get_repo('{github_repo_owner}/{github_repo_name}'.format(**kwargs))
log.info(self.repo)
# We want to ensure that we don't generate a thousand issues when
# multiple users report a bug. So, we need to de-dupe issues. In
# order to de-dupe, we need to know which are open. So, we'll keep
# a cache of open issues and just add to it whenever we create a
# new one.
self.issue_cache = {}
for issue in self.repo.get_issues(state='open'):
log.info(issue)
self.issue_cache[issue.title] = issue
log.info(self.issue_cache)
# We'll also cache labels which we'll use for tagging issues.
self.label_cache = {}
for label in self.repo.get_labels():
log.info(label)
self.label_cache[label.name] = label
log.info(self.label_cache)
except ImportError:
log.error("Please install pygithub to submit bug reports to github")
self.github = None
def get_label(self, label):
# If we don't have this label, then create it + cache it.
if label not in self.label_cache:
self.label_cache[label] = self.repo.create_label(name=label, color='ffffff')
return self.label_cache[label]
def submit_report(self, dataset, job, tool, **kwargs):
"""Submit the error report to sentry
"""
log.info(self.github)
if self.github:
tool_kw = {'tool_id': unicodify(job.tool_id), 'tool_version': unicodify(job.tool_version)}
label = self.get_label('{tool_id}/{tool_version}'.format(**tool_kw))
error_title = u"""Galaxy Job Error: {tool_id} v{tool_version}""".format(**tool_kw)
# We'll re-use the email error reporter's template since github supports HTML
error_reporter = EmailErrorReporter(dataset.id, self.app)
error_reporter.create_report(job.get_user(), email=kwargs.get('email', None), message=kwargs.get('message', None))
# The HTML report
error_message = error_reporter.html_report
log.info(error_title in self.issue_cache)
if error_title not in self.issue_cache:
# Create a new issue.
self.issue_cache[error_title] = self.repo.create_issue(
title=error_title,
body=error_message,
# Label it with a tag: tool_id/tool_version
labels=[label]
)
else:
self.issue_cache[error_title].create_comment(error_message)
return ('Submitted bug report to Github. Your issue number is %s' % self.issue_cache[error_title].number, 'success')
__all__ = ('GithubPlugin', )
-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 -4
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
@@ -271,14 +271,12 @@ class JobImportHistoryArchiveWrapper(object, UsesAnnotations):
input_hda = self.sa_session.query(model.HistoryDatasetAssociation) \
.filter_by(history=new_history, hid=value.hid).first()
value = input_hda.id
# print "added parameter %s-->%s to job %i" % ( name, value, imported_job.id )
imported_job.add_parameter(name, dumps(value, cls=HistoryDatasetAssociationIDEncoder))
# TODO: Connect jobs to input datasets.
# Connect jobs to output datasets.
for output_hid in job_attrs['output_datasets']:
# print "%s job has output dataset %i" % (imported_job.id, output_hid)
output_hda = self.sa_session.query(model.HistoryDatasetAssociation) \
.filter_by(history=new_history, hid=output_hid).first()
if output_hda:
@@ -322,7 +320,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)
+32 -30
View File
@@ -1,6 +1,8 @@
"""
Classes encapsulating Galaxy tool parameters.
"""
from __future__ import print_function
import re
from json import dumps
@@ -31,34 +33,34 @@ def visit_input_values(inputs, input_values, callback, name_prefix='', label_pre
>>> from galaxy.util.odict import odict
>>> from galaxy.tools.parameters.basic import TextToolParameter, BooleanToolParameter
>>> from galaxy.tools.parameters.grouping import Repeat
>>> a = TextToolParameter( None, XML( '<param name="a"/>' ) )
>>> a = TextToolParameter(None, XML('<param name="a"/>'))
>>> b = Repeat()
>>> c = TextToolParameter( None, XML( '<param name="c"/>' ) )
>>> c = TextToolParameter(None, XML('<param name="c"/>'))
>>> d = Repeat()
>>> e = TextToolParameter( None, XML( '<param name="e"/>' ) )
>>> e = TextToolParameter(None, XML('<param name="e"/>'))
>>> f = Conditional()
>>> g = BooleanToolParameter( None, XML( '<param name="g"/>' ) )
>>> h = TextToolParameter( None, XML( '<param name="h"/>' ) )
>>> i = TextToolParameter( None, XML( '<param name="i"/>' ) )
>>> g = BooleanToolParameter(None, XML('<param name="g"/>'))
>>> h = TextToolParameter(None, XML('<param name="h"/>'))
>>> i = TextToolParameter(None, XML('<param name="i"/>'))
>>> b.name = 'b'
>>> b.inputs = odict([ ('c', c), ('d', d) ])
>>> b.inputs = odict([('c', c), ('d', d)])
>>> d.name = 'd'
>>> d.inputs = odict([ ('e', e), ('f', f) ])
>>> d.inputs = odict([('e', e), ('f', f)])
>>> f.test_param = g
>>> f.name = 'f'
>>> f.cases = [ Bunch( value='true', inputs= { 'h': h } ), Bunch( value='false', inputs= { 'i': i } ) ]
>>> f.cases = [Bunch(value='true', inputs= { 'h': h }), Bunch(value='false', inputs= { 'i': i })]
>>>
>>> def visitor( input, value, prefix, prefixed_name, **kwargs ):
... print 'name=%s, prefix=%s, prefixed_name=%s, value=%s' % ( input.name, prefix, prefixed_name, value )
>>> def visitor(input, value, prefix, prefixed_name, **kwargs):
... print('name=%s, prefix=%s, prefixed_name=%s, value=%s' % (input.name, prefix, prefixed_name, value))
>>> inputs = odict([('a',a),('b',b)])
>>> nested = odict([ ('a', 1), ('b', [ odict([('c', 3), ( 'd', [odict([ ('e', 5), ('f', odict([ ('g', True), ('h', 7) ])) ]) ])]) ]) ])
>>> visit_input_values( inputs, nested, visitor )
>>> nested = odict([('a', 1), ('b', [odict([('c', 3), ('d', [odict([('e', 5), ('f', odict([('g', True), ('h', 7)]))])])])])])
>>> visit_input_values(inputs, nested, visitor)
name=a, prefix=, prefixed_name=a, value=1
name=c, prefix=b_0|, prefixed_name=b_0|c, value=3
name=e, prefix=b_0|d_0|, prefixed_name=b_0|d_0|e, value=5
name=g, prefix=b_0|d_0|, prefixed_name=b_0|d_0|f|g, value=True
name=h, prefix=b_0|d_0|, prefixed_name=b_0|d_0|f|h, value=7
>>> params_from_strings( inputs, params_to_strings( inputs, nested, None ), None )[ 'b' ][ 0 ][ 'd' ][ 0 ][ 'f' ][ 'g' ] is True
>>> params_from_strings(inputs, params_to_strings(inputs, nested, None), None)['b'][0]['d'][0]['f']['g'] is True
True
"""
def callback_helper(input, input_values, name_prefix, label_prefix, parent_prefix, context=None, error=None):
@@ -224,38 +226,38 @@ def populate_state(request_context, inputs, incoming, state, errors={}, prefix='
>>> from galaxy.util.odict import odict
>>> from galaxy.tools.parameters.basic import TextToolParameter, BooleanToolParameter
>>> from galaxy.tools.parameters.grouping import Repeat
>>> trans = Bunch( workflow_building_mode=False )
>>> a = TextToolParameter( None, XML( '<param name="a"/>' ) )
>>> trans = Bunch(workflow_building_mode=False)
>>> a = TextToolParameter(None, XML('<param name="a"/>'))
>>> b = Repeat()
>>> b.min = 0
>>> b.max = 1
>>> c = TextToolParameter( None, XML( '<param name="c"/>' ) )
>>> c = TextToolParameter(None, XML('<param name="c"/>'))
>>> d = Repeat()
>>> d.min = 0
>>> d.max = 1
>>> e = TextToolParameter( None, XML( '<param name="e"/>' ) )
>>> e = TextToolParameter(None, XML('<param name="e"/>'))
>>> f = Conditional()
>>> g = BooleanToolParameter( None, XML( '<param name="g"/>' ) )
>>> h = TextToolParameter( None, XML( '<param name="h"/>' ) )
>>> i = TextToolParameter( None, XML( '<param name="i"/>' ) )
>>> g = BooleanToolParameter(None, XML('<param name="g"/>'))
>>> h = TextToolParameter(None, XML('<param name="h"/>'))
>>> i = TextToolParameter(None, XML('<param name="i"/>'))
>>> b.name = 'b'
>>> b.inputs = odict([ ('c', c), ('d', d) ])
>>> b.inputs = odict([('c', c), ('d', d)])
>>> d.name = 'd'
>>> d.inputs = odict([ ('e', e), ('f', f) ])
>>> d.inputs = odict([('e', e), ('f', f)])
>>> f.test_param = g
>>> f.name = 'f'
>>> f.cases = [ Bunch( value='true', inputs= { 'h': h } ), Bunch( value='false', inputs= { 'i': i } ) ]
>>> f.cases = [Bunch(value='true', inputs= { 'h': h }), Bunch(value='false', inputs= { 'i': i })]
>>> inputs = odict([('a',a),('b',b)])
>>> flat = odict([ ('a', 1 ), ( 'b_0|c', 2 ), ( 'b_0|d_0|e', 3 ), ( 'b_0|d_0|f|h', 4 ), ( 'b_0|d_0|f|g', True ) ])
>>> flat = odict([('a', 1), ('b_0|c', 2), ('b_0|d_0|e', 3), ('b_0|d_0|f|h', 4), ('b_0|d_0|f|g', True)])
>>> state = odict()
>>> populate_state( trans, inputs, flat, state, check=False )
>>> print state[ 'a' ]
>>> populate_state(trans, inputs, flat, state, check=False)
>>> print(state['a'])
1
>>> print state[ 'b' ][ 0 ][ 'c' ]
>>> print(state['b'][0]['c'])
2
>>> print state[ 'b' ][ 0 ][ 'd' ][ 0 ][ 'e' ]
>>> print(state['b'][0]['d'][0]['e'])
3
>>> print state[ 'b' ][ 0 ][ 'd' ][ 0 ][ 'f' ][ 'h' ]
>>> print(state['b'][0]['d'][0]['f']['h'])
4
"""
context = ExpressionContext(state, context)
+104 -102
View File
@@ -1,6 +1,8 @@
"""
Basic tool parameters.
"""
from __future__ import print_function
import logging
import os
import os.path
@@ -165,18 +167,18 @@ class ToolParameter(object, Dictifiable):
"""
Convert a value to a text representation suitable for displaying to
the user
>>> p = ToolParameter( None, XML( '<param name="_name" />' ) )
>>> print p.to_text( None )
>>> p = ToolParameter(None, XML('<param name="_name" />'))
>>> print(p.to_text(None))
Not available.
>>> print p.to_text( '' )
>>> print(p.to_text(''))
Empty.
>>> print p.to_text( 'text' )
>>> print(p.to_text('text'))
text
>>> print p.to_text( True )
>>> print(p.to_text(True))
True
>>> print p.to_text( False )
>>> print(p.to_text(False))
False
>>> print p.to_text( 0 )
>>> print(p.to_text(0))
0
"""
if value is not None:
@@ -244,11 +246,11 @@ class TextToolParameter(ToolParameter):
Parameter that can take on any text value.
>>> from galaxy.util.bunch import Bunch
>>> trans = Bunch( app=None )
>>> p = TextToolParameter( None, XML( '<param name="_name" type="text" value="default" />' ) )
>>> print p.name
>>> trans = Bunch(app=None)
>>> p = TextToolParameter(None, XML('<param name="_name" type="text" value="default" />'))
>>> print(p.name)
_name
>>> sorted( p.to_dict( trans ).items() )
>>> sorted(p.to_dict(trans).items())
[('area', False), ('argument', None), ('datalist', []), ('help', ''), ('hidden', False), ('is_dynamic', False), ('label', ''), ('model_class', 'TextToolParameter'), ('name', '_name'), ('optional', False), ('refresh_on_change', False), ('type', 'text'), ('value', 'default')]
"""
@@ -289,15 +291,15 @@ class IntegerToolParameter(TextToolParameter):
Parameter that takes an integer value.
>>> from galaxy.util.bunch import Bunch
>>> trans = Bunch( app=None, history=Bunch(), workflow_building_mode=True )
>>> p = IntegerToolParameter( None, XML( '<param name="_name" type="integer" value="10" />' ) )
>>> print p.name
>>> trans = Bunch(app=None, history=Bunch(), workflow_building_mode=True)
>>> p = IntegerToolParameter(None, XML('<param name="_name" type="integer" value="10" />'))
>>> print(p.name)
_name
>>> sorted( p.to_dict( trans ).items() )
>>> sorted(p.to_dict(trans).items())
[('area', False), ('argument', None), ('datalist', []), ('help', ''), ('hidden', False), ('is_dynamic', False), ('label', ''), ('max', None), ('min', None), ('model_class', 'IntegerToolParameter'), ('name', '_name'), ('optional', False), ('refresh_on_change', False), ('type', 'integer'), ('value', '10')]
>>> type( p.from_json( "10", trans ) )
>>> type(p.from_json("10", trans))
<type 'int'>
>>> type( p.from_json( "_string", trans ) )
>>> type(p.from_json("_string", trans))
Traceback (most recent call last):
...
ValueError: An integer or workflow parameter e.g. ${name} is required
@@ -365,15 +367,15 @@ class FloatToolParameter(TextToolParameter):
Parameter that takes a real number value.
>>> from galaxy.util.bunch import Bunch
>>> trans = Bunch( app=None, history=Bunch(), workflow_building_mode=True )
>>> p = FloatToolParameter( None, XML( '<param name="_name" type="float" value="3.141592" />' ) )
>>> print p.name
>>> trans = Bunch(app=None, history=Bunch(), workflow_building_mode=True)
>>> p = FloatToolParameter(None, XML('<param name="_name" type="float" value="3.141592" />'))
>>> print(p.name)
_name
>>> sorted( p.to_dict( trans ).items() )
>>> sorted(p.to_dict(trans).items())
[('area', False), ('argument', None), ('datalist', []), ('help', ''), ('hidden', False), ('is_dynamic', False), ('label', ''), ('max', None), ('min', None), ('model_class', 'FloatToolParameter'), ('name', '_name'), ('optional', False), ('refresh_on_change', False), ('type', 'float'), ('value', '3.141592')]
>>> type( p.from_json( "36.1", trans ) )
>>> type(p.from_json("36.1", trans))
<type 'float'>
>>> type( p.from_json( "_string", trans ) )
>>> type(p.from_json("_string", trans))
Traceback (most recent call last):
...
ValueError: A real number or workflow parameter e.g. ${name} is required
@@ -441,19 +443,19 @@ class BooleanToolParameter(ToolParameter):
Parameter that takes one of two values.
>>> from galaxy.util.bunch import Bunch
>>> trans = Bunch( app=None, history=Bunch() )
>>> p = BooleanToolParameter( None, XML( '<param name="_name" type="boolean" checked="yes" truevalue="_truevalue" falsevalue="_falsevalue" />' ) )
>>> print p.name
>>> trans = Bunch(app=None, history=Bunch())
>>> p = BooleanToolParameter(None, XML('<param name="_name" type="boolean" checked="yes" truevalue="_truevalue" falsevalue="_falsevalue" />'))
>>> print(p.name)
_name
>>> sorted( p.to_dict( trans ).items() )
>>> sorted(p.to_dict(trans).items())
[('argument', None), ('falsevalue', '_falsevalue'), ('help', ''), ('hidden', False), ('is_dynamic', False), ('label', ''), ('model_class', 'BooleanToolParameter'), ('name', '_name'), ('optional', False), ('refresh_on_change', False), ('truevalue', '_truevalue'), ('type', 'boolean'), ('value', 'true')]
>>> print p.from_json( 'true' )
>>> print(p.from_json('true'))
True
>>> print p.to_param_dict_string( True )
>>> print(p.to_param_dict_string(True))
_truevalue
>>> print p.from_json( 'false' )
>>> print(p.from_json('false'))
False
>>> print p.to_param_dict_string( False )
>>> print(p.to_param_dict_string(False))
_falsevalue
"""
@@ -501,11 +503,11 @@ class FileToolParameter(ToolParameter):
Parameter that takes an uploaded file as a value.
>>> from galaxy.util.bunch import Bunch
>>> trans = Bunch( app=None, history=Bunch() )
>>> p = FileToolParameter( None, XML( '<param name="_name" type="file"/>' ) )
>>> print p.name
>>> trans = Bunch(app=None, history=Bunch())
>>> p = FileToolParameter(None, XML('<param name="_name" type="file"/>'))
>>> print(p.name)
_name
>>> sorted( p.to_dict( trans ).items() )
>>> sorted(p.to_dict(trans).items())
[('argument', None), ('help', ''), ('hidden', False), ('is_dynamic', False), ('label', ''), ('model_class', 'FileToolParameter'), ('name', '_name'), ('optional', False), ('refresh_on_change', False), ('type', 'file'), ('value', None)]
"""
@@ -558,11 +560,11 @@ class FTPFileToolParameter(ToolParameter):
Parameter that takes a file uploaded via FTP as a value.
>>> from galaxy.util.bunch import Bunch
>>> trans = Bunch( app=None, history=Bunch(), user=None )
>>> p = FTPFileToolParameter( None, XML( '<param name="_name" type="ftpfile"/>' ) )
>>> print p.name
>>> trans = Bunch(app=None, history=Bunch(), user=None)
>>> p = FTPFileToolParameter(None, XML('<param name="_name" type="ftpfile"/>'))
>>> print(p.name)
_name
>>> sorted( p.to_dict( trans ).items() )
>>> sorted(p.to_dict(trans).items())
[('argument', None), ('help', ''), ('hidden', False), ('is_dynamic', False), ('label', ''), ('model_class', 'FTPFileToolParameter'), ('multiple', True), ('name', '_name'), ('optional', True), ('refresh_on_change', False), ('type', 'ftpfile'), ('value', None)]
"""
@@ -645,11 +647,11 @@ class HiddenToolParameter(ToolParameter):
Parameter that takes one of two values.
>>> from galaxy.util.bunch import Bunch
>>> trans = Bunch( app=None, history=Bunch() )
>>> p = HiddenToolParameter( None, XML( '<param name="_name" type="hidden" value="_value"/>' ) )
>>> print p.name
>>> trans = Bunch(app=None, history=Bunch())
>>> p = HiddenToolParameter(None, XML('<param name="_name" type="hidden" value="_value"/>'))
>>> print(p.name)
_name
>>> sorted( p.to_dict( trans ).items() )
>>> sorted(p.to_dict(trans).items())
[('argument', None), ('help', ''), ('hidden', True), ('is_dynamic', False), ('label', ''), ('model_class', 'HiddenToolParameter'), ('name', '_name'), ('optional', False), ('refresh_on_change', False), ('type', 'hidden'), ('value', u'_value')]
"""
@@ -671,18 +673,18 @@ class ColorToolParameter(ToolParameter):
Parameter that stores a color.
>>> from galaxy.util.bunch import Bunch
>>> trans = Bunch( app=None, history=Bunch() )
>>> p = ColorToolParameter( None, XML( '<param name="_name" type="color" value="#ffffff"/>' ) )
>>> print p.name
>>> trans = Bunch(app=None, history=Bunch())
>>> p = ColorToolParameter(None, XML('<param name="_name" type="color" value="#ffffff"/>'))
>>> print(p.name)
_name
>>> print p.to_param_dict_string( "#fdeada" )
>>> print(p.to_param_dict_string("#fdeada"))
#fdeada
>>> sorted( p.to_dict( trans ).items() )
>>> sorted(p.to_dict(trans).items())
[('argument', None), ('help', ''), ('hidden', False), ('is_dynamic', False), ('label', ''), ('model_class', 'ColorToolParameter'), ('name', '_name'), ('optional', False), ('refresh_on_change', False), ('type', 'color'), ('value', u'#ffffff')]
>>> p = ColorToolParameter( None, XML( '<param name="_name" type="color" value="#ffffff" rgb="True"/>' ) )
>>> print p.to_param_dict_string( "#fdeada" )
>>> p = ColorToolParameter(None, XML('<param name="_name" type="color" value="#ffffff" rgb="True"/>'))
>>> print(p.to_param_dict_string("#fdeada"))
(253, 234, 218)
>>> print p.to_param_dict_string( None )
>>> print(p.to_param_dict_string(None))
Traceback (most recent call last):
...
ValueError: Failed to convert 'None' to RGB.
@@ -712,11 +714,11 @@ class BaseURLToolParameter(HiddenToolParameter):
current server base url. Used in all redirects.
>>> from galaxy.util.bunch import Bunch
>>> trans = Bunch( app=None, history=Bunch() )
>>> p = BaseURLToolParameter( None, XML( '<param name="_name" type="base_url" value="_value"/>' ) )
>>> print p.name
>>> trans = Bunch(app=None, history=Bunch())
>>> p = BaseURLToolParameter(None, XML('<param name="_name" type="base_url" value="_value"/>'))
>>> print(p.name)
_name
>>> sorted( p.to_dict( trans ).items() )
>>> sorted(p.to_dict(trans).items())
[('argument', None), ('help', ''), ('hidden', True), ('is_dynamic', False), ('label', ''), ('model_class', 'BaseURLToolParameter'), ('name', '_name'), ('optional', False), ('refresh_on_change', False), ('type', 'base_url'), ('value', u'_value')]
"""
@@ -748,32 +750,32 @@ class SelectToolParameter(ToolParameter):
Parameter that takes on one (or many) or a specific set of values.
>>> from galaxy.util.bunch import Bunch
>>> trans = Bunch( app=None, history=Bunch() )
>>> p = SelectToolParameter( None, XML(
>>> trans = Bunch(app=None, history=Bunch())
>>> p = SelectToolParameter(None, XML(
... '''
... <param name="_name" type="select">
... <option value="x">x_label</option>
... <option value="y" selected="true">y_label</option>
... <option value="z">z_label</option>
... </param>
... ''' ) )
>>> print p.name
... '''))
>>> print(p.name)
_name
>>> sorted( p.to_dict( trans ).items() )
>>> sorted(p.to_dict(trans).items())
[('argument', None), ('display', None), ('help', ''), ('hidden', False), ('is_dynamic', False), ('label', ''), ('model_class', 'SelectToolParameter'), ('multiple', False), ('name', '_name'), ('optional', False), ('options', [('x_label', 'x', False), ('y_label', 'y', True), ('z_label', 'z', False)]), ('refresh_on_change', False), ('type', 'select'), ('value', 'y')]
>>> p = SelectToolParameter( None, XML(
>>> p = SelectToolParameter(None, XML(
... '''
... <param name="_name" type="select" multiple="true">
... <option value="x">x_label</option>
... <option value="y" selected="true">y_label</option>
... <option value="z" selected="true">z_label</option>
... </param>
... ''' ) )
>>> print p.name
... '''))
>>> print(p.name)
_name
>>> sorted( p.to_dict( trans ).items() )
>>> sorted(p.to_dict(trans).items())
[('argument', None), ('display', None), ('help', ''), ('hidden', False), ('is_dynamic', False), ('label', ''), ('model_class', 'SelectToolParameter'), ('multiple', True), ('name', '_name'), ('optional', True), ('options', [('x_label', 'x', False), ('y_label', 'y', True), ('z_label', 'z', True)]), ('refresh_on_change', False), ('type', 'select'), ('value', ['y', 'z'])]
>>> print p.to_param_dict_string( ["y", "z"] )
>>> print(p.to_param_dict_string(["y", "z"]))
y,z
"""
@@ -957,15 +959,15 @@ class GenomeBuildParameter(SelectToolParameter):
>>> # Create a mock transaction with 'hg17' as the current build
>>> from galaxy.util.bunch import Bunch
>>> trans = Bunch( app=None, history=Bunch( genome_build='hg17' ), db_builds=util.read_dbnames( None ) )
>>> p = GenomeBuildParameter( None, XML( '<param name="_name" type="genomebuild" value="hg17" />' ) )
>>> print p.name
>>> trans = Bunch(app=None, history=Bunch(genome_build='hg17'), db_builds=util.read_dbnames(None))
>>> p = GenomeBuildParameter(None, XML('<param name="_name" type="genomebuild" value="hg17" />'))
>>> print(p.name)
_name
>>> d = p.to_dict( trans )
>>> o = d[ 'options' ]
>>> [ i for i in o if i[ 2 ] == True ]
>>> d = p.to_dict(trans)
>>> o = d['options']
>>> [i for i in o if i[2] == True]
[('Human May 2004 (NCBI35/hg17) (hg17)', 'hg17', True)]
>>> [ i for i in o if i[ 1 ] == 'hg18' ]
>>> [i for i in o if i[1] == 'hg18']
[('Human Mar. 2006 (NCBI36/hg18) (hg18)', 'hg18', False)]
"""
@@ -1024,16 +1026,16 @@ class ColumnListParameter(SelectToolParameter):
>>> from galaxy.model import History, HistoryDatasetAssociation
>>> from galaxy.util.bunch import Bunch
>>> from galaxy.model.mapping import init
>>> sa_session = init( "/tmp", "sqlite:///:memory:", create_tables=True ).session
>>> sa_session = init("/tmp", "sqlite:///:memory:", create_tables=True).session
>>> hist = History()
>>> sa_session.add( hist )
>>> sa_session.add(hist)
>>> sa_session.flush()
>>> hda = hist.add_dataset( HistoryDatasetAssociation( id=1, extension='interval', create_dataset=True, sa_session=sa_session ) )
>>> dtp = DataToolParameter( None, XML( '<param name="blah" type="data" format="interval"/>' ) )
>>> print dtp.name
>>> hda = hist.add_dataset(HistoryDatasetAssociation(id=1, extension='interval', create_dataset=True, sa_session=sa_session))
>>> dtp = DataToolParameter(None, XML('<param name="blah" type="data" format="interval"/>'))
>>> print(dtp.name)
blah
>>> clp = ColumnListParameter ( None, XML( '<param name="numerical_column" type="data_column" data_ref="blah" numerical="true"/>' ) )
>>> print clp.name
>>> clp = ColumnListParameter(None, XML('<param name="numerical_column" type="data_column" data_ref="blah" numerical="true"/>'))
>>> print(clp.name)
numerical_column
"""
@@ -1182,8 +1184,8 @@ class DrillDownSelectToolParameter(SelectToolParameter):
Creating a hierarchical select menu, which allows users to 'drill down' a tree-like set of options.
>>> from galaxy.util.bunch import Bunch
>>> trans = Bunch( app=None, history=Bunch( genome_build='hg17' ), db_builds=util.read_dbnames( None ) )
>>> p = DrillDownSelectToolParameter( None, XML(
>>> trans = Bunch(app=None, history=Bunch(genome_build='hg17'), db_builds=util.read_dbnames(None))
>>> p = DrillDownSelectToolParameter(None, XML(
... '''
... <param name="_name" type="drill_down" display="checkbox" hierarchy="recurse" multiple="true">
... <options>
@@ -1198,26 +1200,26 @@ class DrillDownSelectToolParameter(SelectToolParameter):
... <option name="Option 5" value="option5"/>
... </options>
... </param>
... ''' ) )
>>> print p.name
... '''))
>>> print(p.name)
_name
>>> d = p.to_dict( trans )
>>> assert d[ 'multiple' ] == True
>>> assert d[ 'display' ] == 'checkbox'
>>> assert d[ 'options' ][ 0 ][ 'name' ] == 'Heading 1'
>>> assert d[ 'options' ][ 0 ][ 'value' ] == 'heading1'
>>> assert d[ 'options' ][ 0 ][ 'options' ][ 0 ][ 'name' ] == 'Option 1'
>>> assert d[ 'options' ][ 0 ][ 'options' ][ 0 ][ 'value' ] == 'option1'
>>> assert d[ 'options' ][ 0 ][ 'options' ][ 1 ][ 'name' ] == 'Option 2'
>>> assert d[ 'options' ][ 0 ][ 'options' ][ 1 ][ 'value' ] == 'option2'
>>> assert d[ 'options' ][ 0 ][ 'options' ][ 2 ][ 'name' ] == 'Heading 2'
>>> assert d[ 'options' ][ 0 ][ 'options' ][ 2 ][ 'value' ] == 'heading2'
>>> assert d[ 'options' ][ 0 ][ 'options' ][ 2 ][ 'options' ][ 0 ][ 'name' ] == 'Option 3'
>>> assert d[ 'options' ][ 0 ][ 'options' ][ 2 ][ 'options' ][ 0 ][ 'value' ] == 'option3'
>>> assert d[ 'options' ][ 0 ][ 'options' ][ 2 ][ 'options' ][ 1 ][ 'name' ] == 'Option 4'
>>> assert d[ 'options' ][ 0 ][ 'options' ][ 2 ][ 'options' ][ 1 ][ 'value' ] == 'option4'
>>> assert d[ 'options' ][ 1 ][ 'name' ] == 'Option 5'
>>> assert d[ 'options' ][ 1 ][ 'value' ] == 'option5'
>>> d = p.to_dict(trans)
>>> assert d['multiple'] == True
>>> assert d['display'] == 'checkbox'
>>> assert d['options'][0]['name'] == 'Heading 1'
>>> assert d['options'][0]['value'] == 'heading1'
>>> assert d['options'][0]['options'][0]['name'] == 'Option 1'
>>> assert d['options'][0]['options'][0]['value'] == 'option1'
>>> assert d['options'][0]['options'][1]['name'] == 'Option 2'
>>> assert d['options'][0]['options'][1]['value'] == 'option2'
>>> assert d['options'][0]['options'][2]['name'] == 'Heading 2'
>>> assert d['options'][0]['options'][2]['value'] == 'heading2'
>>> assert d['options'][0]['options'][2]['options'][0]['name'] == 'Option 3'
>>> assert d['options'][0]['options'][2]['options'][0]['value'] == 'option3'
>>> assert d['options'][0]['options'][2]['options'][1]['name'] == 'Option 4'
>>> assert d['options'][0]['options'][2]['options'][1]['value'] == 'option4'
>>> assert d['options'][1]['name'] == 'Option 5'
>>> assert d['options'][1]['value'] == 'option5'
"""
def __init__(self, tool, input_source, context=None):
@@ -1280,7 +1282,7 @@ class DrillDownSelectToolParameter(SelectToolParameter):
options = []
for filter_key, filter_value in self.filtered.items():
dataset = other_values.get(filter_key)
if dataset.__class__.__name__.endswith("DatasetFilenameWrapper"): # this is a bad way to check for this, but problems importing class ( due to circular imports? )
if dataset.__class__.__name__.endswith("DatasetFilenameWrapper"): # this is a bad way to check for this, but problems importing class (due to circular imports?)
dataset = dataset.dataset
if dataset:
for meta_key, meta_dict in filter_value.items():
@@ -1563,7 +1565,7 @@ class DataToolParameter(BaseDataToolParameter):
displayed as radio buttons and multiple selects as a set of checkboxes
TODO: The following must be fixed to test correctly for the new security_check tag in
the DataToolParameter ( the last test below is broken ) Nate's next pass at the dataset
the DataToolParameter (the last test below is broken) Nate's next pass at the dataset
security stuff will dramatically alter this anyway.
"""
@@ -1,6 +1,8 @@
"""
Tool Input Translation.
"""
from __future__ import print_function
import logging
from galaxy.util.bunch import Bunch
@@ -15,7 +17,7 @@ class ToolInputTranslator(object):
>>> from galaxy.util import Params
>>> from xml.etree.ElementTree import XML
>>> translator = ToolInputTranslator.from_element( XML(
>>> translator = ToolInputTranslator.from_element(XML(
... '''
... <request_param_translation>
... <request_param galaxy_name="URL_method" remote_name="URL_method" missing="post" />
@@ -40,10 +42,10 @@ class ToolInputTranslator(object):
... </value_translation>
... </request_param>
... </request_param_translation>
... ''' ) )
>>> params = Params( { 'db':'hg17', 'URL':'URL_value', 'org':'Human', 'hgta_outputType':'primaryTable' } )
>>> translator.translate( params )
>>> print sorted(list(params.__dict__.keys()))
... '''))
>>> params = Params({'db':'hg17', 'URL':'URL_value', 'org':'Human', 'hgta_outputType':'primaryTable'})
>>> translator.translate(params)
>>> print(sorted(params.__dict__.keys()))
['URL', 'URL_method', 'data_type', 'db', 'dbkey', 'description', 'hgta_outputType', 'org', 'organism', 'table']
>>> params.get('URL', None) in ['URL_value?GALAXY_URL=0&_export=1', 'URL_value?_export=1&GALAXY_URL=0']
True
+12 -10
View File
@@ -1,3 +1,5 @@
from __future__ import print_function
import copy
import itertools
import logging
@@ -15,20 +17,20 @@ log = logging.getLogger(__name__)
def expand_workflow_inputs(inputs):
"""
Expands incoming encoded multiple payloads, into the set of all individual payload combinations
>>> params, param_keys = expand_workflow_inputs( {'1': {'input': {'batch': True, 'product': True, 'values': [{'hid': '1'}, {'hid': '2'}] }}} )
>>> print [ "%s" % ( p[ '1' ][ 'input' ][ 'hid' ] ) for p in params ]
>>> params, param_keys = expand_workflow_inputs({'1': {'input': {'batch': True, 'product': True, 'values': [{'hid': '1'}, {'hid': '2'}] }}})
>>> print(["%s" % (p['1']['input']['hid']) for p in params])
['1', '2']
>>> params, param_keys = expand_workflow_inputs( {'1': {'input': {'batch': True, 'values': [{'hid': '1'}, {'hid': '2'}] }}} )
>>> print [ "%s" % ( p[ '1' ][ 'input' ][ 'hid' ] ) for p in params ]
>>> params, param_keys = expand_workflow_inputs({'1': {'input': {'batch': True, 'values': [{'hid': '1'}, {'hid': '2'}] }}})
>>> print(["%s" % (p['1']['input']['hid']) for p in params])
['1', '2']
>>> params, param_keys = expand_workflow_inputs( {'1': {'input': {'batch': True, 'values': [{'hid': '1'}, {'hid': '2'}] }}, '2': {'input': {'batch': True, 'values': [{'hid': '3'}, {'hid': '4'}] }}} )
>>> print [ "%s%s" % ( p[ '1' ][ 'input' ][ 'hid' ], p[ '2' ][ 'input' ][ 'hid' ] ) for p in params ]
>>> params, param_keys = expand_workflow_inputs({'1': {'input': {'batch': True, 'values': [{'hid': '1'}, {'hid': '2'}] }}, '2': {'input': {'batch': True, 'values': [{'hid': '3'}, {'hid': '4'}] }}})
>>> print(["%s%s" % (p['1']['input']['hid'], p['2']['input']['hid']) for p in params])
['13', '24']
>>> params, param_keys = expand_workflow_inputs( {'1': {'input': {'batch': True, 'product': True, 'values': [{'hid': '1'}, {'hid': '2'}] }}, '2': {'input': {'batch': True, 'values': [{'hid': '3'}, {'hid': '4'}, {'hid': '5'}] }}} )
>>> print [ "%s%s" % ( p[ '1' ][ 'input' ][ 'hid' ], p[ '2' ][ 'input' ][ 'hid' ] ) for p in params ]
>>> params, param_keys = expand_workflow_inputs({'1': {'input': {'batch': True, 'product': True, 'values': [{'hid': '1'}, {'hid': '2'}] }}, '2': {'input': {'batch': True, 'values': [{'hid': '3'}, {'hid': '4'}, {'hid': '5'}] }}})
>>> print(["%s%s" % (p['1']['input']['hid'], p['2']['input']['hid']) for p in params])
['13', '23', '14', '24', '15', '25']
>>> params, param_keys = expand_workflow_inputs( {'1': {'input': {'batch': True, 'product': True, 'values': [{'hid': '1'}, {'hid': '2'}] }}, '2': {'input': {'batch': True, 'product': True, 'values': [{'hid': '3'}, {'hid': '4'}, {'hid': '5'}] }}, '3': {'input': {'batch': True, 'product': True, 'values': [{'hid': '6'}, {'hid': '7'}, {'hid': '8'}] }}} )
>>> print [ "%s%s%s" % ( p[ '1' ][ 'input' ][ 'hid' ], p[ '2' ][ 'input' ][ 'hid' ], p[ '3' ][ 'input' ][ 'hid' ] ) for p in params ]
>>> params, param_keys = expand_workflow_inputs({'1': {'input': {'batch': True, 'product': True, 'values': [{'hid': '1'}, {'hid': '2'}] }}, '2': {'input': {'batch': True, 'product': True, 'values': [{'hid': '3'}, {'hid': '4'}, {'hid': '5'}] }}, '3': {'input': {'batch': True, 'product': True, 'values': [{'hid': '6'}, {'hid': '7'}, {'hid': '8'}] }}})
>>> print(["%s%s%s" % (p['1']['input']['hid'], p['2']['input']['hid'], p['3']['input']['hid']) for p in params])
['136', '137', '138', '146', '147', '148', '156', '157', '158', '236', '237', '238', '246', '247', '248', '256', '257', '258']
"""
linked_n = None
+7 -7
View File
@@ -16,16 +16,16 @@ class ToolParameterSanitizer(object):
Handles tool parameter specific sanitizing.
>>> from xml.etree.ElementTree import XML
>>> sanitizer = ToolParameterSanitizer.from_element( XML(
>>> sanitizer = ToolParameterSanitizer.from_element(XML(
... '''
... <sanitizer invalid_char="">
... <valid initial="string.letters"/>
... </sanitizer>
... ''' ) )
>>> sanitizer.sanitize_param( ''.join( sorted( [ c for c in string.printable ] ) ) ) == ''.join( sorted( [ c for c in string.letters ] ) )
... '''))
>>> sanitizer.sanitize_param(''.join(sorted([c for c in string.printable]))) == ''.join(sorted([c for c in string.letters]))
True
>>> slash = chr( 92 )
>>> sanitizer = ToolParameterSanitizer.from_element( XML(
>>> slash = chr(92)
>>> sanitizer = ToolParameterSanitizer.from_element(XML(
... '''
... <sanitizer>
... <valid initial="none">
@@ -38,9 +38,9 @@ class ToolParameterSanitizer(object):
... <add source="%s" target="%s%s"/>
... </mapping>
... </sanitizer>
... ''' % ( slash, slash, slash, slash, slash ) ) )
... ''' % (slash, slash, slash, slash, slash)))
>>> text = '%s"$rm&#!' % slash
>>> [ c for c in sanitizer.sanitize_param( text ) ] == [ slash, slash, slash, '"', '$', 'r', 'm', '&', '#', '!' ]
>>> [c for c in sanitizer.sanitize_param(text)] == [slash, slash, slash, '"', '$', 'r', 'm', '&', '#', '!']
True
"""
+24 -24
View File
@@ -36,14 +36,14 @@ class RegexValidator(Validator):
>>> from xml.etree.ElementTree import XML
>>> from galaxy.tools.parameters.basic import ToolParameter
>>> p = ToolParameter.build( None, XML( '''
>>> p = ToolParameter.build(None, XML('''
... <param name="blah" type="text" size="10" value="10">
... <validator type="regex" message="Not gonna happen">[Ff]oo</validator>
... </param>
... ''' ) )
>>> t = p.validate( "Foo" )
>>> t = p.validate( "foo" )
>>> t = p.validate( "Fop" )
... '''))
>>> t = p.validate("Foo")
>>> t = p.validate("foo")
>>> t = p.validate("Fop")
Traceback (most recent call last):
...
ValueError: Not gonna happen
@@ -70,14 +70,14 @@ class ExpressionValidator(Validator):
>>> from xml.etree.ElementTree import XML
>>> from galaxy.tools.parameters.basic import ToolParameter
>>> p = ToolParameter.build( None, XML( '''
>>> p = ToolParameter.build(None, XML('''
... <param name="blah" type="text" size="10" value="10">
... <validator type="expression" message="Not gonna happen">value.lower() == "foo"</validator>
... </param>
... ''' ) )
>>> t = p.validate( "Foo" )
>>> t = p.validate( "foo" )
>>> t = p.validate( "Fop" )
... '''))
>>> t = p.validate("Foo")
>>> t = p.validate("foo")
>>> t = p.validate("Fop")
Traceback (most recent call last):
...
ValueError: Not gonna happen
@@ -107,18 +107,18 @@ class InRangeValidator(Validator):
>>> from xml.etree.ElementTree import XML
>>> from galaxy.tools.parameters.basic import ToolParameter
>>> p = ToolParameter.build( None, XML( '''
>>> p = ToolParameter.build(None, XML('''
... <param name="blah" type="integer" size="10" value="10">
... <validator type="in_range" message="Not gonna happen" min="10" exclude_min="true" max="20"/>
... </param>
... ''' ) )
>>> t = p.validate( 10 )
... '''))
>>> t = p.validate(10)
Traceback (most recent call last):
...
ValueError: Not gonna happen
>>> t = p.validate( 15 )
>>> t = p.validate( 20 )
>>> t = p.validate( 21 )
>>> t = p.validate(15)
>>> t = p.validate(20)
>>> t = p.validate(21)
Traceback (most recent call last):
...
ValueError: Not gonna happen
@@ -134,7 +134,7 @@ class InRangeValidator(Validator):
"""
When the optional exclude_min and exclude_max attributes are set
to true, the range excludes the end points (i.e., min < value < max),
while if set to False ( the default), then range includes the end points
while if set to False (the default), then range includes the end points
(1.e., min <= value <= max). Combinations of exclude_min and exclude_max
values are allowed.
"""
@@ -175,18 +175,18 @@ class LengthValidator(Validator):
>>> from xml.etree.ElementTree import XML
>>> from galaxy.tools.parameters.basic import ToolParameter
>>> p = ToolParameter.build( None, XML( '''
>>> p = ToolParameter.build(None, XML('''
... <param name="blah" type="text" size="10" value="foobar">
... <validator type="length" min="2" max="8"/>
... </param>
... ''' ) )
>>> t = p.validate( "foo" )
>>> t = p.validate( "bar" )
>>> t = p.validate( "f" )
... '''))
>>> t = p.validate("foo")
>>> t = p.validate("bar")
>>> t = p.validate("f")
Traceback (most recent call last):
...
ValueError: Must have length of at least 2
>>> t = p.validate( "foobarbaz" )
>>> t = p.validate("foobarbaz")
Traceback (most recent call last):
...
ValueError: Must have length no more than 8
@@ -460,7 +460,7 @@ validator_types = dict(expression=ExpressionValidator,
empty_extra_files_path=DatasetExtraFilesPathEmptyValidator,
dataset_metadata_in_file=MetadataInFileColumnValidator,
dataset_metadata_in_data_table=MetadataInDataTableColumnValidator,
dataset_ok_validator=DatasetOkValidator, )
dataset_ok_validator=DatasetOkValidator,)
def get_suite():
+2 -2
View File
@@ -201,7 +201,7 @@ class XmlToolSource(ToolSource):
def parse_provided_metadata_style(self):
style = None
out_elem = self.root.find("outputs")
if out_elem and "provided_metadata_style" in out_elem.attrib:
if out_elem is not None and "provided_metadata_style" in out_elem.attrib:
style = out_elem.attrib["provided_metadata_style"]
if style is None:
@@ -213,7 +213,7 @@ class XmlToolSource(ToolSource):
def parse_provided_metadata_file(self):
provided_metadata_file = "galaxy.json"
out_elem = self.root.find("outputs")
if out_elem and "provided_metadata_file" in out_elem.attrib:
if out_elem is not None and "provided_metadata_file" in out_elem.attrib:
provided_metadata_file = out_elem.attrib["provided_metadata_file"]
return provided_metadata_file
+1 -1
View File
@@ -19,7 +19,7 @@ import bx.interval_index_file
import bx.intervals
from six.moves import xrange
assert sys.version_info[:2] >= (2, 4)
assert sys.version_info[:2] >= (2, 6)
log = logging.getLogger(__name__)
+26 -26
View File
@@ -376,10 +376,10 @@ associated with a tool's single input dataset. The 2 metadata elements we're
using look like this.
```python
MetadataElement( name="field_names", default=[], desc="Field names", readonly=True, optional=True, visible=True, no_value=[] )
MetadataElement(name="field_names", default=[], desc="Field names", readonly=True, optional=True, visible=True, no_value=[])
# The keys in the field_components map to the list of field_names in the above element
# which ensures order for select list options that are built from it.
MetadataElement( name="field_components", default={}, desc="Field names and components", readonly=True, optional=True, visible=True, no_value={} )
MetadataElement(name="field_components", default={}, desc="Field names and components", readonly=True, optional=True, visible=True, no_value={})
```
Our tool config includes a code file tag like this.
@@ -427,11 +427,11 @@ list, which is the behavior we want.
The ``get_field_components_options()`` method looks like this.
```python
def get_field_components_options( dataset, field_name ):
def get_field_components_options(dataset, field_name):
options = []
if dataset.metadata is None:
return options
if not hasattr( dataset.metadata, 'field_names' ):
if not hasattr(dataset.metadata, 'field_names'):
return options
if dataset.metadata.field_names is None:
return options
@@ -439,12 +439,12 @@ def get_field_components_options( dataset, field_name ):
# The expression validator that helps populate the select list of input
# datsets in the icqsol_color_surface_field tool does not filter out
# datasets with no field field_names, so we need this check.
if len( dataset.metadata.field_names ) == 0:
if len(dataset.metadata.field_names) == 0:
return options
field_name = dataset.metadata.field_names[0]
field_components = dataset.metadata.field_components.get( field_name, [] )
for i, field_component in enumerate( field_components ):
options.append( ( field_component, field_component, i == 0 ) )
field_components = dataset.metadata.field_components.get(field_name, [])
for i, field_component in enumerate(field_components):
options.append((field_component, field_component, i == 0))
return options
```
@@ -1716,7 +1716,7 @@ shown above:
```
biom convert -i "${input_type.input_table}" -o "${output_table}"
#if str( $input_type.input_type_selector ) == "tsv":
#if str($input_type.input_type_selector) == "tsv":
#if $input_type.process_obs_metadata:
--process-obs-metadata "${input_type.process_obs_metadata}"
#end if
@@ -1854,7 +1854,7 @@ This Cheetah code can be used in the ``<command>`` tag set or the
``<configfile>`` tag set.
```xml
#for $i, $s in enumerate( $series )
#for $i, $s in enumerate($series)
rank_of_series=$i
input_path='${s.input}'
x_colom=${s.xcol}
@@ -2541,9 +2541,9 @@ bedtools annotate
'${bed.inputName}'
#end for
#else:
#set files = '" "'.join( [ str( $file ) for $file in $names.beds ] )
#set files = '" "'.join([str($file) for $file in $names.beds])
-files '${files}'
#set names = '" "'.join( [ str( $name.display_name ) for $name in $names.beds ] )
#set names = '" "'.join([str($name.display_name) for $name in $names.beds])
-names '${names}'
#end if
$strand
@@ -4039,7 +4039,7 @@ based on inputs, as shown below:
```xml
<data format="fastqsanger" name="output_unaligned_reads_r" label="${tool.name} on ${on_string}: unaligned reads (R)">
<filter>( library['type'] == "paired" or library['type'] == "paired_collection" ) and library['unaligned_file'] is True</filter>
<filter>(library['type'] == "paired" or library['type'] == "paired_collection") and library['unaligned_file'] is True</filter>
<actions>
<conditional name="library.type">
<when value="paired">
@@ -4100,7 +4100,7 @@ Or in case of multiple files:
<outputs>
<data format="tabular" name="output_short">
<actions>
<action name="column_names" type="metadata" default="Geneid,${','.join([ a.name for a in $input_files ])}" />
<action name="column_names" type="metadata" default="Geneid,${','.join([a.name for a in $input_files])}" />
</actions>
</data>
</outputs>
@@ -4445,27 +4445,27 @@ tool config.
<configfiles>
<configfile name="script_file">
## Setup R error handling to go to stderr
options( show.error.messages=F, error = function () { cat( geterrmessage(), file=stderr() ); q( "no", 1, F ) } )
options(show.error.messages=F, error = function () { cat(geterrmessage(), file=stderr()); q("no", 1, F) })
## Determine range of all series in the plot
xrange = c( NULL, NULL )
yrange = c( NULL, NULL )
#for $i, $s in enumerate( $series )
s${i} = read.table( "${s.input.file_name}" )
xrange = c(NULL, NULL)
yrange = c(NULL, NULL)
#for $i, $s in enumerate($series)
s${i} = read.table("${s.input.file_name}")
x${i} = s${i}[,${s.xcol}]
y${i} = s${i}[,${s.ycol}]
xrange = range( x${i}, xrange )
yrange = range( y${i}, yrange )
xrange = range(x${i}, xrange)
yrange = range(y${i}, yrange)
#end for
## Open output PDF file
pdf( "${out_file1}" )
pdf("${out_file1}")
## Dummy plot for axis / labels
plot( NULL, type="n", xlim=xrange, ylim=yrange, main="${main}", xlab="${xlab}", ylab="${ylab}" )
plot(NULL, type="n", xlim=xrange, ylim=yrange, main="${main}", xlab="${xlab}", ylab="${ylab}")
## Plot each series
#for $i, $s in enumerate( $series )
#for $i, $s in enumerate($series)
#if $s.series_type['type'] == "line"
lines( x${i}, y${i}, lty=${s.series_type.lty}, lwd=${s.series_type.lwd}, col=${s.series_type.col} )
lines(x${i}, y${i}, lty=${s.series_type.lty}, lwd=${s.series_type.lwd}, col=${s.series_type.col})
#elif $s.series_type.type == "points"
points( x${i}, y${i}, pch=${s.series_type.pch}, cex=${s.series_type.cex}, col=${s.series_type.col} )
points(x${i}, y${i}, pch=${s.series_type.pch}, cex=${s.series_type.cex}, col=${s.series_type.col})
#end if
#end for
## Close the PDF file
+11 -8
View File
@@ -1,8 +1,11 @@
import os
from __future__ import print_function
import copy
import dictobj
import os
from collections import namedtuple
import dictobj
Path = namedtuple('Path', ('path', 'id', 'options'))
@@ -46,23 +49,23 @@ class Node(dictobj.DictionaryObject):
Example:
>>> import jstree
>>> node = jstree.Node('a', None)
>>> print node
>>> print(node)
Node({'text': 'a', 'children': MutableDictionaryObject({})})
>>> print node.jsonData()
>>> print(node.jsonData())
{'text': 'a'}
>>> import jstree
>>> node = jstree.Node('a', 1)
>>> print node
>>> print(node)
Node({'text': 'a', 'children': MutableDictionaryObject({}), 'li_attr': DictionaryObject({'id': 1}), 'id': 1})
>>> print node.jsonData()
>>> print(node.jsonData())
{'text': 'a', 'id': 1, 'li_attr': {'id': 1}}
>>> import jstree
>>> node = jstree.Node('a', 5, icon="folder", state = {'opened': True})
>>> print node
>>> print(node)
Node({'text': 'a', 'id': 5, 'state': DictionaryObject({'opened': True}), 'children': MutableDictionaryObject({}), 'li_attr': DictionaryObject({'id': 5}), 'icon': 'folder'})
>>> print node.jsonData()
>>> print(node.jsonData())
{'text': 'a', 'state': {'opened': True}, 'id': 5, 'li_attr': {'id': 5}, 'icon': 'folder'}
"""
super(Node, self).__init__()
@@ -104,7 +104,6 @@ class ColumnDataProvider(BaseDataProvider):
(column >= 0)), (
"column index (%d) must be positive and less" % (column) +
" than the number of columns: %d" % (self.original_dataset.metadata.columns))
# print columns, start_val, max_vals, skip_comments, kwargs
# set up the response, column lists
response = {}
@@ -3,6 +3,7 @@ import logging
import os
import random
import stat
import string
import tempfile
import uuid
from subprocess import PIPE, Popen
@@ -20,8 +21,14 @@ from galaxy.util.bunch import Bunch
IS_OS_X = _platform == "darwin"
CONTAINER_NAME_PREFIX = 'gie_'
ENV_OVERRIDE_CAPITALIZE = frozenset([
'notebook_username',
'notebook_password',
'dataset_hid',
'dataset_filename',
'additional_ids',
])
log = logging.getLogger(__name__)
@@ -252,7 +259,10 @@ class InteractiveEnvironmentRequest(object):
env_override = {}
conf = self.get_conf_dict()
conf = dict([(key.upper(), item) for key, item in conf.items()])
conf.update(env_override)
for key, item in env_override.items():
if key in ENV_OVERRIDE_CAPITALIZE:
key = key.upper()
conf[key] = item
return conf
def _get_import_volume_for_run(self):
@@ -307,15 +317,35 @@ class InteractiveEnvironmentRequest(object):
else:
return True
def _get_command_inject_env(self):
"""For the containers interface, parse any -e/--env flags from `command_inject`.
"""
# using a list ensures that later vars override earlier ones with the
# same name, which is how `docker run` works on the command line
envsets = []
command_inject = self.attr.viz_config.get("docker", "command_inject").strip().split()
for i, item in enumerate(command_inject):
if item.startswith('-e=') or item.startswith('--env='):
envsets.append(item.split('=', 1)[1])
elif item == ('-e') or item == ('--env'):
envsets.append(command_inject[i + 1])
elif item.startswith('-e'):
envsets.append(item[2:])
elif item.startswith('--env'):
envsets.append(item[5:])
return dict(map(lambda s: string.split(s, '=', 1), envsets))
def container_run_args(self, image, env_override=None, volumes=None):
if volumes is None:
volumes = []
import_volume_def = self._get_import_volume_for_run()
if import_volume_def:
volumes.append(import_volume_def)
env = self._get_command_inject_env()
env.update(self._get_env_for_run(env_override))
args = {
'image': image,
'environment': self._get_env_for_run(env_override),
'environment': env,
'volumes': volumes,
'name': self._get_name_for_run(),
'detach': True,
+19 -16
View File
@@ -1,10 +1,13 @@
"""
Classes for generating HTML forms
"""
from __future__ import print_function
import logging
from six import string_types
from cgi import escape
from six import string_types
from galaxy.util import restore_text, unicodify
log = logging.getLogger(__name__)
@@ -44,9 +47,9 @@ class TextField(BaseField):
"""
A standard text input box.
>>> print TextField( "foo" ).get_html()
>>> print(TextField( "foo" ).get_html())
<input type="text" name="foo" size="10" value="">
>>> print TextField( "bins", size=4, value="default" ).get_html()
>>> print(TextField( "bins", size=4, value="default" ).get_html())
<input type="text" name="bins" size="4" value="default">
"""
@@ -72,9 +75,9 @@ class PasswordField(BaseField):
"""
A password input box. text appears as "******"
>>> print PasswordField( "foo" ).get_html()
>>> print(PasswordField( "foo" ).get_html())
<input type="password" name="foo" size="10" value="">
>>> print PasswordField( "bins", size=4, value="default" ).get_html()
>>> print(PasswordField( "bins", size=4, value="default" ).get_html())
<input type="password" name="bins" size="4" value="default">
"""
@@ -101,9 +104,9 @@ class TextArea(BaseField):
"""
A standard text area box.
>>> print TextArea( "foo" ).get_html()
>>> print(TextArea( "foo" ).get_html())
<textarea name="foo" rows="5" cols="25"></textarea>
>>> print TextArea( "bins", size="4x5", value="default" ).get_html()
>>> print(TextArea( "bins", size="4x5", value="default" ).get_html())
<textarea name="bins" rows="4" cols="5">default</textarea>
"""
_DEFAULT_SIZE = "5x25"
@@ -136,9 +139,9 @@ class CheckboxField(BaseField):
"""
A checkbox (boolean input)
>>> print CheckboxField( "foo" ).get_html()
>>> print(CheckboxField( "foo" ).get_html())
<input type="checkbox" id="foo" name="foo" value="__CHECKED__"><input type="hidden" name="foo" value="__NOTHING__">
>>> print CheckboxField( "bar", checked="yes" ).get_html()
>>> print(CheckboxField( "bar", checked="yes" ).get_html())
<input type="checkbox" id="bar" name="bar" value="__CHECKED__" checked="checked"><input type="hidden" name="bar" value="__NOTHING__">
"""
@@ -186,9 +189,9 @@ class FileField(BaseField):
"""
A file upload input.
>>> print FileField( "foo" ).get_html()
>>> print(FileField( "foo" ).get_html())
<input type="file" name="foo">
>>> print FileField( "foo", ajax = True ).get_html()
>>> print(FileField( "foo", ajax = True ).get_html())
<input type="file" name="foo" galaxy-ajax-upload="true">
"""
@@ -233,7 +236,7 @@ class HiddenField(BaseField):
"""
A hidden field.
>>> print HiddenField( "foo", 100 ).get_html()
>>> print(HiddenField( "foo", 100 ).get_html())
<input type="hidden" name="foo" value="100">
"""
@@ -259,7 +262,7 @@ class SelectField(BaseField):
>>> t = SelectField( "foo", multiple=True )
>>> t.add_option( "tuti", 1 )
>>> t.add_option( "fruity", "x" )
>>> print t.get_html()
>>> print(t.get_html())
<select name="foo" multiple>
<option value="1">tuti</option>
<option value="x">fruity</option>
@@ -268,7 +271,7 @@ class SelectField(BaseField):
>>> t = SelectField( "bar" )
>>> t.add_option( "automatic", 3 )
>>> t.add_option( "bazooty", 4, selected=True )
>>> print t.get_html()
>>> print(t.get_html())
<select name="bar" last_selected_value="4">
<option value="3">automatic</option>
<option value="4" selected>bazooty</option>
@@ -277,14 +280,14 @@ class SelectField(BaseField):
>>> t = SelectField( "foo", display="radio" )
>>> t.add_option( "tuti", 1 )
>>> t.add_option( "fruity", "x" )
>>> print t.get_html()
>>> print(t.get_html())
<div><input type="radio" name="foo" value="1" id="foo|1"><label class="inline" for="foo|1">tuti</label></div>
<div><input type="radio" name="foo" value="x" id="foo|x"><label class="inline" for="foo|x">fruity</label></div>
>>> t = SelectField( "bar", multiple=True, display="checkboxes" )
>>> t.add_option( "automatic", 3 )
>>> t.add_option( "bazooty", 4, selected=True )
>>> print t.get_html()
>>> print(t.get_html())
<div class="checkUncheckAllPlaceholder" checkbox_name="bar"></div>
<div><input type="checkbox" name="bar" value="3" id="bar|3"><label class="inline" for="bar|3">automatic</label></div>
<div><input type="checkbox" name="bar" value="4" id="bar|4" checked='checked'><label class="inline" for="bar|4">bazooty</label></div>
+18 -4
View File
@@ -121,6 +121,10 @@ class UserListGrid(grids.Grid):
grids.GridAction("Create new user", url_args=dict(webapp="galaxy", action="create_new_user"))
]
operations = [
grids.GridOperation("Manage Information",
condition=(lambda item: not item.deleted),
allow_multiple=False,
url_args=dict(controller="user", action="information", webapp="galaxy")),
grids.GridOperation("Manage Roles and Groups",
condition=(lambda item: not item.deleted),
allow_multiple=False,
@@ -208,7 +212,8 @@ class RoleListGrid(grids.Grid):
UsersColumn("Users", attach_popup=False),
StatusColumn("Status", attach_popup=False),
# Columns that are valid for filtering but are not visible.
grids.DeletedColumn("Deleted", key="deleted", visible=False, filterable="advanced")
grids.DeletedColumn("Deleted", key="deleted", visible=False, filterable="advanced"),
grids.GridColumn("Last Updated", key="update_time", format=time_ago)
]
columns.append(grids.MulticolFilterColumn("Search",
cols_to_filter=[columns[0], columns[1], columns[2]],
@@ -218,10 +223,14 @@ class RoleListGrid(grids.Grid):
global_actions = [
grids.GridAction("Add new role", url_args=dict(action="form/create_role"))
]
operations = [grids.GridOperation("Edit",
operations = [grids.GridOperation("Edit Name/Description",
condition=(lambda item: not item.deleted),
allow_multiple=False,
url_args=dict(action="form/rename_role")),
grids.GridOperation("Edit Permissions",
condition=(lambda item: not item.deleted),
allow_multiple=False,
url_args=dict(action="form/manage_users_and_groups_for_role", webapp="galaxy")),
grids.GridOperation("Delete",
condition=(lambda item: not item.deleted),
allow_multiple=True),
@@ -283,7 +292,8 @@ class GroupListGrid(grids.Grid):
RolesColumn("Roles", attach_popup=False),
StatusColumn("Status", attach_popup=False),
# Columns that are valid for filtering but are not visible.
grids.DeletedColumn("Deleted", key="deleted", visible=False, filterable="advanced")
grids.DeletedColumn("Deleted", key="deleted", visible=False, filterable="advanced"),
grids.GridColumn("Last Updated", key="update_time", format=time_ago)
]
columns.append(grids.MulticolFilterColumn("Search",
cols_to_filter=[columns[0]],
@@ -293,10 +303,14 @@ class GroupListGrid(grids.Grid):
global_actions = [
grids.GridAction("Add new group", url_args=dict(action="form/create_group"))
]
operations = [grids.GridOperation("Rename",
operations = [grids.GridOperation("Edit Name",
condition=(lambda item: not item.deleted),
allow_multiple=False,
url_args=dict(action="form/rename_group")),
grids.GridOperation("Edit Permissions",
condition=(lambda item: not item.deleted),
allow_multiple=False,
url_args=dict(action="form/manage_users_and_roles_for_group", webapp="galaxy")),
grids.GridOperation("Delete",
condition=(lambda item: not item.deleted),
allow_multiple=True),
+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,15 +1,15 @@
import collections
import logging
import galaxy.model
import sqlalchemy as sa
from datetime import timedelta
import sqlalchemy as sa
from markupsafe import escape
from sqlalchemy import and_
import galaxy.model
from galaxy import util
from galaxy.web.base.controller import BaseUIController, web
from sqlalchemy import and_
from datetime import timedelta
from markupsafe import escape
log = logging.getLogger(__name__)
@@ -344,7 +344,6 @@ class Tools(BaseUIController):
if word in to_replace:
continue
if words.count(word) > 1:
print word
to_replace.append(word)
for word in to_replace:
sentence = ("</br>" + word) * 2
@@ -352,7 +351,6 @@ class Tools(BaseUIController):
while sentence + "</br>" + word in new_key:
sentence += "</br>" + word
count += 1
print sentence, count
if sentence in new_key:
new_key = new_key.replace(sentence, '</br>' + word + " [this line in %d times]" % (count))
data[new_key] = counter[key]
@@ -1,6 +1,8 @@
"""
Migration script to create initial tables.
"""
from __future__ import print_function
import datetime
import logging
import sys
@@ -145,7 +147,7 @@ ToolAnnotationAssociation_table = Table("tool_annotation_association", metadata,
def upgrade(migrate_engine):
print __doc__
print(__doc__)
metadata.bind = migrate_engine
metadata.create_all()
Index('ix_tool_annotation_association_annotation', ToolAnnotationAssociation_table.c.annotation, mysql_length=767).create()
@@ -1,6 +1,8 @@
"""
Migration script to add the suite column to the tool table.
"""
from __future__ import print_function
import logging
import sys
@@ -19,7 +21,7 @@ metadata = MetaData()
def upgrade(migrate_engine):
metadata.bind = migrate_engine
print __doc__
print(__doc__)
metadata.reflect()
# Create and initialize imported column in job table.
Tool_table = Table("tool", metadata, autoload=True)
@@ -34,9 +36,8 @@ def upgrade(migrate_engine):
elif migrate_engine.name in ['postgresql', 'postgres']:
default_false = "false"
migrate_engine.execute("UPDATE tool SET suite=%s" % default_false)
except Exception as e:
print "Adding suite column to the tool table failed: %s" % str(e)
log.debug("Adding suite column to the tool table failed: %s" % str(e))
except Exception:
log.exception("Adding suite column to the tool table failed.")
def downgrade(migrate_engine):
@@ -46,6 +47,5 @@ def downgrade(migrate_engine):
Tool_table = Table("tool", metadata, autoload=True)
try:
Tool_table.c.suite.drop()
except Exception as e:
print "Dropping column suite from the tool table failed: %s" % str(e)
log.debug("Dropping column suite from the tool table failed: %s" % str(e))
except Exception:
log.exception("Dropping column suite from the tool table failed.")
@@ -1,6 +1,8 @@
"""
Adds the tool_rating_association table, enabling tools to be rated along with review comments.
"""
from __future__ import print_function
import datetime
import logging
import sys
@@ -29,14 +31,14 @@ ToolRatingAssociation_table = Table("tool_rating_association", metadata,
def upgrade(migrate_engine):
print __doc__
print(__doc__)
metadata.bind = migrate_engine
# Load existing tables
metadata.reflect()
try:
ToolRatingAssociation_table.create()
except Exception as e:
log.debug("Creating tool_rating_association table failed: %s" % str(e))
except Exception:
log.exception("Creating tool_rating_association table failed.")
def downgrade(migrate_engine):
@@ -45,5 +47,5 @@ def downgrade(migrate_engine):
metadata.reflect()
try:
ToolRatingAssociation_table.drop()
except Exception as e:
log.debug("Dropping tool_rating_association table failed: %s" % str(e))
except Exception:
log.exception("Dropping tool_rating_association table failed.")
@@ -1,6 +1,8 @@
"""
Adds the repository, repository_rating_association and repository_category_association tables.
"""
from __future__ import print_function
import datetime
import logging
import sys
@@ -47,22 +49,22 @@ RepositoryCategoryAssociation_table = Table("repository_category_association", m
def upgrade(migrate_engine):
print __doc__
print(__doc__)
# Load existing tables
metadata.bind = migrate_engine
metadata.reflect()
try:
Repository_table.create()
except Exception as e:
log.debug("Creating repository table failed: %s" % str(e))
except Exception:
log.exception("Creating repository table failed.")
try:
RepositoryRatingAssociation_table.create()
except Exception as e:
log.debug("Creating repository_rating_association table failed: %s" % str(e))
except Exception:
log.exception("Creating repository_rating_association table failed.")
try:
RepositoryCategoryAssociation_table.create()
except Exception as e:
log.debug("Creating repository_category_association table failed: %s" % str(e))
except Exception:
log.exception("Creating repository_category_association table failed.")
def downgrade(migrate_engine):
@@ -71,13 +73,13 @@ def downgrade(migrate_engine):
metadata.reflect()
try:
Repository_table.drop()
except Exception as e:
log.debug("Dropping repository table failed: %s" % str(e))
except Exception:
log.exception("Dropping repository table failed.")
try:
RepositoryRatingAssociation_table.drop()
except Exception as e:
log.debug("Dropping repository_rating_association table failed: %s" % str(e))
except Exception:
log.exception("Dropping repository_rating_association table failed.")
try:
RepositoryCategoryAssociation_table.drop()
except Exception as e:
log.debug("Dropping repository_category_association table failed: %s" % str(e))
except Exception:
log.exception("Dropping repository_category_association table failed.")
@@ -3,6 +3,8 @@ Drops the tool, tool_category_association, event, tool_event_association, tool_r
tool_tag_association and tool_annotation_association tables since they are no longer used in the
next-gen tool shed.
"""
from __future__ import print_function
import datetime
import logging
import sys
@@ -26,7 +28,7 @@ metadata = MetaData()
def upgrade(migrate_engine):
print __doc__
print(__doc__)
# Load existing tables
metadata.bind = migrate_engine
metadata.reflect()
@@ -37,8 +39,8 @@ def upgrade(migrate_engine):
log.debug("Failed loading table tool_category_association")
try:
ToolCategoryAssociation_table.drop()
except Exception as e:
log.debug("Dropping tool_category_association table failed: %s" % str(e))
except Exception:
log.exception("Dropping tool_category_association table failed.")
# Load and then drop the tool_event_association table
try:
ToolEventAssociation_table = Table("tool_event_association", metadata, autoload=True)
@@ -46,8 +48,8 @@ def upgrade(migrate_engine):
log.debug("Failed loading table tool_event_association")
try:
ToolEventAssociation_table.drop()
except Exception as e:
log.debug("Dropping tool_event_association table failed: %s" % str(e))
except Exception:
log.exception("Dropping tool_event_association table failed.")
# Load and then drop the tool_rating_association table
try:
ToolRatingAssociation_table = Table("tool_rating_association", metadata, autoload=True)
@@ -55,8 +57,8 @@ def upgrade(migrate_engine):
log.debug("Failed loading table tool_rating_association")
try:
ToolRatingAssociation_table.drop()
except Exception as e:
log.debug("Dropping tool_rating_association table failed: %s" % str(e))
except Exception:
log.exception("Dropping tool_rating_association table failed.")
# Load and then drop the tool_tag_association table
try:
ToolTagAssociation_table = Table("tool_tag_association", metadata, autoload=True)
@@ -64,8 +66,8 @@ def upgrade(migrate_engine):
log.debug("Failed loading table tool_tag_association")
try:
ToolTagAssociation_table.drop()
except Exception as e:
log.debug("Dropping tool_tag_association table failed: %s" % str(e))
except Exception:
log.exception("Dropping tool_tag_association table failed.")
# Load and then drop the tool_annotation_association table
try:
ToolAnnotationAssociation_table = Table("tool_annotation_association", metadata, autoload=True)
@@ -73,8 +75,8 @@ def upgrade(migrate_engine):
log.debug("Failed loading table tool_annotation_association")
try:
ToolAnnotationAssociation_table.drop()
except Exception as e:
log.debug("Dropping tool_annotation_association table failed: %s" % str(e))
except Exception:
log.exception("Dropping tool_annotation_association table failed.")
# Load and then drop the event table
try:
Event_table = Table("event", metadata, autoload=True)
@@ -82,8 +84,8 @@ def upgrade(migrate_engine):
log.debug("Failed loading table event")
try:
Event_table.drop()
except Exception as e:
log.debug("Dropping event table failed: %s" % str(e))
except Exception:
log.exception("Dropping event table failed.")
# Load and then drop the tool table
try:
Tool_table = Table("tool", metadata, autoload=True)
@@ -91,8 +93,8 @@ def upgrade(migrate_engine):
log.debug("Failed loading table tool")
try:
Tool_table.drop()
except Exception as e:
log.debug("Dropping tool table failed: %s" % str(e))
except Exception:
log.exception("Dropping tool table failed.")
def downgrade(migrate_engine):
@@ -161,35 +163,35 @@ def downgrade(migrate_engine):
# Create the event table
try:
Event_table.create()
except Exception as e:
log.debug("Creating event table failed: %s" % str(e))
except Exception:
log.exception("Creating event table failed.")
# Create the tool table
try:
Tool_table.create()
except Exception as e:
log.debug("Creating tool table failed: %s" % str(e))
except Exception:
log.exception("Creating tool table failed.")
# Create the tool_category_association table
try:
ToolCategoryAssociation_table.create()
except Exception as e:
log.debug("Creating tool_category_association table failed: %s" % str(e))
except Exception:
log.exception("Creating tool_category_association table failed.")
# Create the tool_event_association table
try:
ToolEventAssociation_table.create()
except Exception as e:
log.debug("Creating tool_event_association table failed: %s" % str(e))
except Exception:
log.exception("Creating tool_event_association table failed.")
# Create the tool_rating_association table
try:
ToolRatingAssociation_table.create()
except Exception as e:
log.debug("Creating tool_rating_association table failed: %s" % str(e))
except Exception:
log.exception("Creating tool_rating_association table failed.")
# Create the tool_tag_association table
try:
ToolTagAssociation_table.create()
except Exception as e:
log.debug("Creating tool_tag_association table failed: %s" % str(e))
except Exception:
log.exception("Creating tool_tag_association table failed.")
# Create the tool_annotation_association table
try:
ToolAnnotationAssociation_table.create()
except Exception as e:
log.debug("Creating tool_annotation_association table failed: %s" % str(e))
except Exception:
log.exception("Creating tool_annotation_association table failed.")
@@ -1,6 +1,8 @@
"""
Migration script to add the email_alerts column to the repository table.
"""
from __future__ import print_function
import logging
import sys
@@ -21,7 +23,7 @@ metadata = MetaData()
def upgrade(migrate_engine):
print __doc__
print(__doc__)
metadata.bind = migrate_engine
metadata.reflect()
# Create and initialize imported column in job table.
@@ -31,9 +33,8 @@ def upgrade(migrate_engine):
# Create
c.create(Repository_table)
assert c is Repository_table.c.email_alerts
except Exception as e:
print "Adding email_alerts column to the repository table failed: %s" % str(e)
log.debug("Adding email_alerts column to the repository table failed: %s" % str(e))
except Exception:
log.exception("Adding email_alerts column to the repository table failed.")
def downgrade(migrate_engine):
@@ -43,6 +44,5 @@ def downgrade(migrate_engine):
Repository_table = Table("repository", metadata, autoload=True)
try:
Repository_table.c.email_alerts.drop()
except Exception as e:
print "Dropping column email_alerts from the repository table failed: %s" % str(e)
log.debug("Dropping column email_alerts from the repository table failed: %s" % str(e))
except Exception:
log.exception("Dropping column email_alerts from the repository table failed.")
@@ -1,6 +1,8 @@
"""
Migration script to add the long_description and times_downloaded columns to the repository table.
"""
from __future__ import print_function
import logging
import sys
@@ -18,7 +20,7 @@ metadata = MetaData()
def upgrade(migrate_engine):
print __doc__
print(__doc__)
metadata.bind = migrate_engine
metadata.reflect()
# Create and initialize imported column in job table.
@@ -28,18 +30,16 @@ def upgrade(migrate_engine):
# Create
c.create(Repository_table)
assert c is Repository_table.c.long_description
except Exception as e:
print "Adding long_description column to the repository table failed: %s" % str(e)
log.debug("Adding long_description column to the repository table failed: %s" % str(e))
except Exception:
log.exception("Adding long_description column to the repository table failed.")
c = Column("times_downloaded", Integer)
try:
# Create
c.create(Repository_table)
assert c is Repository_table.c.times_downloaded
except Exception as e:
print "Adding times_downloaded column to the repository table failed: %s" % str(e)
log.debug("Adding times_downloaded column to the repository table failed: %s" % str(e))
except Exception:
log.exception("Adding times_downloaded column to the repository table failed.")
cmd = "UPDATE repository SET long_description = ''"
migrate_engine.execute(cmd)
@@ -54,11 +54,9 @@ def downgrade(migrate_engine):
Repository_table = Table("repository", metadata, autoload=True)
try:
Repository_table.c.long_description.drop()
except Exception as e:
print "Dropping column long_description from the repository table failed: %s" % str(e)
log.debug("Dropping column long_description from the repository table failed: %s" % str(e))
except Exception:
log.exception("Dropping column long_description from the repository table failed.")
try:
Repository_table.c.times_downloaded.drop()
except Exception as e:
print "Dropping column times_downloaded from the repository table failed: %s" % str(e)
log.debug("Dropping column times_downloaded from the repository table failed: %s" % str(e))
except Exception:
log.exception("Dropping column times_downloaded from the repository table failed.")
@@ -1,6 +1,8 @@
"""
Migration script to add the repository_metadata table.
"""
from __future__ import print_function
import datetime
import logging
import sys
@@ -31,15 +33,14 @@ RepositoryMetadata_table = Table("repository_metadata", metadata,
def upgrade(migrate_engine):
print __doc__
print(__doc__)
metadata.bind = migrate_engine
metadata.reflect()
# Create repository_metadata table.
try:
RepositoryMetadata_table.create()
except Exception as e:
print str(e)
log.debug("Creating repository_metadata table failed: %s" % str(e))
except Exception:
log.exception("Creating repository_metadata table failed.")
def downgrade(migrate_engine):
@@ -48,6 +49,5 @@ def downgrade(migrate_engine):
# Drop repository_metadata table.
try:
RepositoryMetadata_table.drop()
except Exception as e:
print str(e)
log.debug("Dropping repository_metadata table failed: %s" % str(e))
except Exception:
log.exception("Dropping repository_metadata table failed.")
@@ -1,6 +1,8 @@
"""
Migration script to add the malicious column to the repository_metadata table.
"""
from __future__ import print_function
import logging
import sys
@@ -18,7 +20,7 @@ metadata = MetaData()
def upgrade(migrate_engine):
print __doc__
print(__doc__)
metadata.bind = migrate_engine
metadata.reflect()
# Create and initialize imported column in job table.
@@ -34,9 +36,8 @@ def upgrade(migrate_engine):
elif migrate_engine.name in ['postgresql', 'postgres']:
default_false = "false"
migrate_engine.execute("UPDATE repository_metadata SET malicious=%s" % default_false)
except Exception as e:
print "Adding malicious column to the repository_metadata table failed: %s" % str(e)
log.debug("Adding malicious column to the repository_metadata table failed: %s" % str(e))
except Exception:
log.exception("Adding malicious column to the repository_metadata table failed.")
def downgrade(migrate_engine):
@@ -46,6 +47,5 @@ def downgrade(migrate_engine):
Repository_metadata_table = Table("repository_metadata", metadata, autoload=True)
try:
Repository_metadata_table.c.malicious.drop()
except Exception as e:
print "Dropping column malicious from the repository_metadata table failed: %s" % str(e)
log.debug("Dropping column malicious from the repository_metadata table failed: %s" % str(e))
except Exception:
log.exception("Dropping column malicious from the repository_metadata table failed.")
@@ -1,6 +1,8 @@
"""
Migration script to add the new_repo_alert column to the galaxy_user table.
"""
from __future__ import print_function
import logging
import sys
@@ -18,7 +20,7 @@ metadata = MetaData()
def upgrade(migrate_engine):
print __doc__
print(__doc__)
metadata.bind = migrate_engine
metadata.reflect()
# Create and initialize imported column in job table.
@@ -36,9 +38,8 @@ def upgrade(migrate_engine):
else:
log.debug("unknown migrate_engine dialect")
migrate_engine.execute("UPDATE galaxy_user SET new_repo_alert=%s" % default_false)
except Exception as e:
print "Adding new_repo_alert column to the galaxy_user table failed: %s" % str(e)
log.debug("Adding new_repo_alert column to the galaxy_user table failed: %s" % str(e))
except Exception:
log.exception("Adding new_repo_alert column to the galaxy_user table failed.")
def downgrade(migrate_engine):
@@ -48,6 +49,5 @@ def downgrade(migrate_engine):
User_table = Table("galaxy_user", metadata, autoload=True)
try:
User_table.c.new_repo_alert.drop()
except Exception as e:
print "Dropping column new_repo_alert from the galaxy_user table failed: %s" % str(e)
log.debug("Dropping column new_repo_alert from the galaxy_user table failed: %s" % str(e))
except Exception:
log.exception("Dropping column new_repo_alert from the galaxy_user table failed.")
@@ -1,6 +1,8 @@
"""
Migration script to add the tool_versions column to the repository_metadata table.
"""
from __future__ import print_function
import datetime
import logging
import sys
@@ -23,7 +25,7 @@ metadata = MetaData()
def upgrade(migrate_engine):
print __doc__
print(__doc__)
metadata.bind = migrate_engine
metadata.reflect()
RepositoryMetadata_table = Table("repository_metadata", metadata, autoload=True)
@@ -32,8 +34,8 @@ def upgrade(migrate_engine):
# Create
c.create(RepositoryMetadata_table)
assert c is RepositoryMetadata_table.c.tool_versions
except Exception as e:
print "Adding tool_versions column to the repository_metadata table failed: %s" % str(e)
except Exception:
log.exception("Adding tool_versions column to the repository_metadata table failed.")
def downgrade(migrate_engine):
@@ -43,5 +45,5 @@ def downgrade(migrate_engine):
RepositoryMetadata_table = Table("repository_metadata", metadata, autoload=True)
try:
RepositoryMetadata_table.c.tool_versions.drop()
except Exception as e:
print "Dropping column tool_versions from the repository_metadata table failed: %s" % str(e)
except Exception:
log.exception("Dropping column tool_versions from the repository_metadata table failed.")
@@ -1,6 +1,8 @@
"""
Migration script to add the downloadable column to the repository_metadata table.
"""
from __future__ import print_function
import logging
import sys
@@ -18,7 +20,7 @@ metadata = MetaData()
def upgrade(migrate_engine):
print __doc__
print(__doc__)
metadata.bind = migrate_engine
metadata.reflect()
# Create and initialize imported column in job table.
@@ -34,8 +36,8 @@ def upgrade(migrate_engine):
elif migrate_engine.name in ['postgresql', 'postgres']:
default_true = "true"
migrate_engine.execute("UPDATE repository_metadata SET downloadable=%s" % default_true)
except Exception as e:
print "Adding downloadable column to the repository_metadata table failed: %s" % str(e)
except Exception:
log.exception("Adding downloadable column to the repository_metadata table failed.")
def downgrade(migrate_engine):
@@ -45,5 +47,5 @@ def downgrade(migrate_engine):
RepositoryMetadata_table = Table("repository_metadata", metadata, autoload=True)
try:
RepositoryMetadata_table.c.downloadable.drop()
except Exception as e:
print "Dropping column downloadable from the repository_metadata table failed: %s" % str(e)
except Exception:
log.exception("Dropping column downloadable from the repository_metadata table failed.")
@@ -1,6 +1,8 @@
"""
Migration script to add the repository_review, component_review and component tables and the Repository Reviewer group and role.
"""
from __future__ import print_function
import datetime
import logging
import sys
@@ -83,25 +85,22 @@ Component_table = Table("component", metadata,
def upgrade(migrate_engine):
print __doc__
print(__doc__)
metadata.bind = migrate_engine
metadata.reflect()
# Create new review tables.
try:
Component_table.create()
except Exception as e:
print str(e)
log.debug("Creating component table failed: %s" % str(e))
except Exception:
log.exception("Creating component table failed.")
try:
RepositoryReview_table.create()
except Exception as e:
print str(e)
log.debug("Creating repository_review table failed: %s" % str(e))
except Exception:
log.exception("Creating repository_review table failed.")
try:
ComponentReview_table.create()
except Exception as e:
print str(e)
log.debug("Creating component_review table failed: %s" % str(e))
except Exception:
log.exception("Creating component_review table failed.")
# Insert default Component values.
names = ['Data types', 'Functional tests', 'README', 'Tool dependencies', 'Tools', 'Workflows']
descriptions = ['Proprietary datatypes defined in a file named datatypes_conf.xml included in the repository',
@@ -170,19 +169,16 @@ def downgrade(migrate_engine):
# Drop review tables.
try:
ComponentReview_table.drop()
except Exception as e:
print str(e)
log.debug("Dropping component_review table failed: %s" % str(e))
except Exception:
log.exception("Dropping component_review table failed.")
try:
RepositoryReview_table.drop()
except Exception as e:
print str(e)
log.debug("Dropping repository_review table failed: %s" % str(e))
except Exception:
log.exception("Dropping repository_review table failed.")
try:
Component_table.drop()
except Exception as e:
print str(e)
log.debug("Dropping component table failed: %s" % str(e))
except Exception:
log.exception("Dropping component table failed.")
# Get the id of the REVIEWER group.
cmd = "SELECT id FROM galaxy_group WHERE name = '%s';" % (IUC)
row = migrate_engine.execute(cmd).fetchone()
@@ -1,6 +1,8 @@
"""
Migration script to add the deprecated column to the repository table.
"""
from __future__ import print_function
import logging
import sys
@@ -18,7 +20,7 @@ metadata = MetaData()
def upgrade(migrate_engine):
print __doc__
print(__doc__)
metadata.bind = migrate_engine
metadata.reflect()
# Create and initialize imported column in job table.
@@ -34,9 +36,8 @@ def upgrade(migrate_engine):
elif migrate_engine.name in ['postgresql', 'postgres']:
default_false = "false"
migrate_engine.execute("UPDATE repository SET deprecated=%s" % default_false)
except Exception as e:
print "Adding deprecated column to the repository table failed: %s" % str(e)
log.debug("Adding deprecated column to the repository table failed: %s" % str(e))
except Exception:
log.exception("Adding deprecated column to the repository table failed.")
def downgrade(migrate_engine):
@@ -46,6 +47,5 @@ def downgrade(migrate_engine):
Repository_table = Table("repository", metadata, autoload=True)
try:
Repository_table.c.deprecated.drop()
except Exception as e:
print "Dropping column deprecated from the repository table failed: %s" % str(e)
log.debug("Dropping column deprecated from the repository table failed: %s" % str(e))
except Exception:
log.exception("Dropping column deprecated from the repository table failed.")
@@ -1,6 +1,8 @@
"""
Migration script to add the api_keys table.
"""
from __future__ import print_function
import datetime
import logging
import sys
@@ -30,13 +32,13 @@ APIKeys_table = Table("api_keys", metadata,
def upgrade(migrate_engine):
print __doc__
print(__doc__)
metadata.bind = migrate_engine
metadata.reflect()
try:
APIKeys_table.create()
except Exception as e:
log.debug("Creating api_keys table failed: %s" % str(e))
except Exception:
log.exception("Creating api_keys table failed.")
def downgrade(migrate_engine):
@@ -45,5 +47,5 @@ def downgrade(migrate_engine):
metadata.reflect()
try:
APIKeys_table.drop()
except Exception as e:
log.debug("Dropping api_keys table failed: %s" % str(e))
except Exception:
log.exception("Dropping api_keys table failed.")
@@ -1,6 +1,8 @@
"""
Migration script to add the tool_test_errors, do_not_test, tools_functionally_correct, and time_last_tested columns to the repository_metadata table.
"""
from __future__ import print_function
import logging
import sys
@@ -21,7 +23,7 @@ metadata = MetaData()
def upgrade(migrate_engine):
print __doc__
print(__doc__)
metadata.bind = migrate_engine
metadata.reflect()
# Create and initialize tools_functionally_correct, do_not_test, time_last_tested, and tool_test_errors columns in repository_metadata table.
@@ -37,9 +39,8 @@ def upgrade(migrate_engine):
elif migrate_engine.name in ['postgresql', 'postgres']:
default_false = "false"
migrate_engine.execute("UPDATE repository_metadata SET tools_functionally_correct=%s" % default_false)
except Exception as e:
print "Adding tools_functionally_correct column to the repository_metadata table failed: %s" % str(e)
log.debug("Adding tools_functionally_correct column to the repository_metadata table failed: %s" % str(e))
except Exception:
log.exception("Adding tools_functionally_correct column to the repository_metadata table failed.")
c = Column("do_not_test", Boolean, default=False, index=True)
try:
# Create do_not_test column
@@ -51,25 +52,22 @@ def upgrade(migrate_engine):
elif migrate_engine.name in ['postgresql', 'postgres']:
default_false = "false"
migrate_engine.execute("UPDATE repository_metadata SET do_not_test=%s" % default_false)
except Exception as e:
print "Adding do_not_test column to the repository_metadata table failed: %s" % str(e)
log.debug("Adding do_not_test column to the repository_metadata table failed: %s" % str(e))
except Exception:
log.exception("Adding do_not_test column to the repository_metadata table failed.")
c = Column("time_last_tested", DateTime, default=None, nullable=True)
try:
# Create time_last_tested column
c.create(RepositoryMetadata_table, index_name="ix_repository_metadata_tlt")
assert c is RepositoryMetadata_table.c.time_last_tested
except Exception as e:
print "Adding time_last_tested column to the repository_metadata table failed: %s" % str(e)
log.debug("Adding time_last_tested column to the repository_metadata table failed: %s" % str(e))
except Exception:
log.exception("Adding time_last_tested column to the repository_metadata table failed.")
c = Column("tool_test_errors", JSONType, nullable=True)
try:
# Create tool_test_errors column
c.create(RepositoryMetadata_table, index_name="ix_repository_metadata_tte")
assert c is RepositoryMetadata_table.c.tool_test_errors
except Exception as e:
print "Adding tool_test_errors column to the repository_metadata table failed: %s" % str(e)
log.debug("Adding tool_test_errors column to the repository_metadata table failed: %s" % str(e))
except Exception:
log.exception("Adding tool_test_errors column to the repository_metadata table failed.")
def downgrade(migrate_engine):
@@ -79,21 +77,17 @@ def downgrade(migrate_engine):
RepositoryMetadata_table = Table("repository_metadata", metadata, autoload=True)
try:
RepositoryMetadata_table.c.tool_test_errors.drop()
except Exception as e:
print "Dropping column tool_test_errors from the repository_metadata table failed: %s" % str(e)
log.debug("Dropping column tool_test_errors from the repository_metadata table failed: %s" % str(e))
except Exception:
log.exception("Dropping column tool_test_errors from the repository_metadata table failed.")
try:
RepositoryMetadata_table.c.time_last_tested.drop()
except Exception as e:
print "Dropping column time_last_tested from the repository_metadata table failed: %s" % str(e)
log.debug("Dropping column time_last_tested from the repository_metadata table failed: %s" % str(e))
except Exception:
log.exception("Dropping column time_last_tested from the repository_metadata table failed.")
try:
RepositoryMetadata_table.c.do_not_test.drop()
except Exception as e:
print "Dropping column do_not_test from the repository_metadata table failed: %s" % str(e)
log.debug("Dropping column do_not_test from the repository_metadata table failed: %s" % str(e))
except Exception:
log.exception("Dropping column do_not_test from the repository_metadata table failed.")
try:
RepositoryMetadata_table.c.tools_functionally_correct.drop()
except Exception as e:
print "Dropping column tools_functionally_correct from the repository_metadata table failed: %s" % str(e)
log.debug("Dropping column tools_functionally_correct from the repository_metadata table failed: %s" % str(e))
except Exception:
log.exception("Dropping column tools_functionally_correct from the repository_metadata table failed.")
@@ -2,6 +2,8 @@
Migration script to add the includes_datatypes, has_repository_dependencies, includes_tools, includes_tool_dependencies and includes_workflows
columns to the repository_metadata table.
"""
from __future__ import print_function
import logging
import sys
@@ -19,7 +21,7 @@ metadata = MetaData()
def upgrade(migrate_engine):
print __doc__
print(__doc__)
metadata.bind = migrate_engine
metadata.reflect()
# Initialize.
@@ -36,8 +38,8 @@ def upgrade(migrate_engine):
c.create(RepositoryMetadata_table, index_name="ix_repository_metadata_inc_datatypes")
assert c is RepositoryMetadata_table.c.includes_datatypes
migrate_engine.execute("UPDATE repository_metadata SET includes_datatypes=%s" % default_false)
except Exception as e:
print "Adding includes_datatypes column to the repository_metadata table failed: %s" % str(e)
except Exception:
log.exception("Adding includes_datatypes column to the repository_metadata table failed.")
# Create includes_datatypes column
c = Column("has_repository_dependencies", Boolean, default=False, index=True)
@@ -45,8 +47,8 @@ def upgrade(migrate_engine):
c.create(RepositoryMetadata_table, index_name="ix_repository_metadata_has_repo_deps")
assert c is RepositoryMetadata_table.c.has_repository_dependencies
migrate_engine.execute("UPDATE repository_metadata SET has_repository_dependencies=%s" % default_false)
except Exception as e:
print "Adding has_repository_dependencies column to the repository_metadata table failed: %s" % str(e)
except Exception:
log.exception("Adding has_repository_dependencies column to the repository_metadata table failed.")
# Create includes_tools column
c = Column("includes_tools", Boolean, default=False, index=True)
@@ -54,8 +56,8 @@ def upgrade(migrate_engine):
c.create(RepositoryMetadata_table, index_name="ix_repository_metadata_inc_tools")
assert c is RepositoryMetadata_table.c.includes_tools
migrate_engine.execute("UPDATE repository_metadata SET includes_tools=%s" % default_false)
except Exception as e:
print "Adding includes_tools column to the repository_metadata table failed: %s" % str(e)
except Exception:
log.exception("Adding includes_tools column to the repository_metadata table failed.")
# Create includes_tool_dependencies column
c = Column("includes_tool_dependencies", Boolean, default=False, index=True)
@@ -63,8 +65,8 @@ def upgrade(migrate_engine):
c.create(RepositoryMetadata_table, index_name="ix_repository_metadata_inc_tool_deps")
assert c is RepositoryMetadata_table.c.includes_tool_dependencies
migrate_engine.execute("UPDATE repository_metadata SET includes_tool_dependencies=%s" % default_false)
except Exception as e:
print "Adding includes_tool_dependencies column to the repository_metadata table failed: %s" % str(e)
except Exception:
log.exception("Adding includes_tool_dependencies column to the repository_metadata table failed.")
# Create includes_workflows column
c = Column("includes_workflows", Boolean, default=False, index=True)
@@ -72,8 +74,8 @@ def upgrade(migrate_engine):
c.create(RepositoryMetadata_table, index_name="ix_repository_metadata_inc_workflows")
assert c is RepositoryMetadata_table.c.includes_workflows
migrate_engine.execute("UPDATE repository_metadata SET includes_workflows=%s" % default_false)
except Exception as e:
print "Adding includes_workflows column to the repository_metadata table failed: %s" % str(e)
except Exception:
log.exception("Adding includes_workflows column to the repository_metadata table failed.")
def downgrade(migrate_engine):
@@ -85,29 +87,29 @@ def downgrade(migrate_engine):
# Drop the includes_workflows column.
try:
RepositoryMetadata_table.c.includes_workflows.drop()
except Exception as e:
print "Dropping column includes_workflows from the repository_metadata table failed: %s" % str(e)
except Exception:
log.exception("Dropping column includes_workflows from the repository_metadata table failed.")
# Drop the includes_tool_dependencies column.
try:
RepositoryMetadata_table.c.includes_tool_dependencies.drop()
except Exception as e:
print "Dropping column includes_tool_dependencies from the repository_metadata table failed: %s" % str(e)
except Exception:
log.exception("Dropping column includes_tool_dependencies from the repository_metadata table failed.")
# Drop the includes_tools column.
try:
RepositoryMetadata_table.c.includes_tools.drop()
except Exception as e:
print "Dropping column includes_tools from the repository_metadata table failed: %s" % str(e)
except Exception:
log.exception("Dropping column includes_tools from the repository_metadata table failed.")
# Drop the has_repository_dependencies column.
try:
RepositoryMetadata_table.c.has_repository_dependencies.drop()
except Exception as e:
print "Dropping column has_repository_dependencies from the repository_metadata table failed: %s" % str(e)
except Exception:
log.exception("Dropping column has_repository_dependencies from the repository_metadata table failed.")
# Drop the includes_datatypes column.
try:
RepositoryMetadata_table.c.includes_datatypes.drop()
except Exception as e:
print "Dropping column includes_datatypes from the repository_metadata table failed: %s" % str(e)
except Exception:
log.exception("Dropping column includes_datatypes from the repository_metadata table failed.")
@@ -2,6 +2,8 @@
Migration script to alter the repository_metadata table by dropping the tool_test_errors column and adding columns
tool_test_results, missing_test_components.
"""
from __future__ import print_function
import logging
import sys
@@ -23,7 +25,7 @@ metadata = MetaData()
def upgrade(migrate_engine):
print __doc__
print(__doc__)
metadata.bind = migrate_engine
metadata.reflect()
# Initialize.
@@ -44,16 +46,16 @@ def upgrade(migrate_engine):
try:
col = RepositoryMetadata_table.c.tool_test_errors
col.drop()
except Exception as e:
log.debug("Dropping column 'tool_test_errors' from repository_metadata table failed: %s" % (str(e)))
except Exception:
log.exception("Dropping column 'tool_test_errors' from repository_metadata table failed.")
# Create the tool_test_results column to replace the ill-named tool_test_errors column just dropped above.
c = Column("tool_test_results", JSONType, nullable=True)
try:
c.create(RepositoryMetadata_table)
assert c is RepositoryMetadata_table.c.tool_test_results
except Exception as e:
print "Adding tool_test_results column to the repository_metadata table failed: %s" % str(e)
except Exception:
log.exception("Adding tool_test_results column to the repository_metadata table failed.")
# Create the missing_test_components column.
c = Column("missing_test_components", Boolean, default=False, index=True)
@@ -61,8 +63,8 @@ def upgrade(migrate_engine):
c.create(RepositoryMetadata_table, index_name="ix_repository_metadata_mtc")
assert c is RepositoryMetadata_table.c.missing_test_components
migrate_engine.execute("UPDATE repository_metadata SET missing_test_components=%s" % default_false)
except Exception as e:
print "Adding missing_test_components column to the repository_metadata table failed: %s" % str(e)
except Exception:
log.exception("Adding missing_test_components column to the repository_metadata table failed.")
def downgrade(migrate_engine):
@@ -74,19 +76,19 @@ def downgrade(migrate_engine):
# Drop the missing_test_components column.
try:
RepositoryMetadata_table.c.missing_test_components.drop()
except Exception as e:
print "Dropping column missing_test_components from the repository_metadata table failed: %s" % str(e)
except Exception:
log.exception("Dropping column missing_test_components from the repository_metadata table failed.")
# Drop the tool_test_results column.
try:
RepositoryMetadata_table.c.tool_test_results.drop()
except Exception as e:
print "Dropping column tool_test_results from the repository_metadata table failed: %s" % str(e)
except Exception:
log.exception("Dropping column tool_test_results from the repository_metadata table failed.")
# Create the tool_test_errors column.
c = Column("tool_test_errors", JSONType, nullable=True)
try:
c.create(RepositoryMetadata_table)
assert c is RepositoryMetadata_table.c.tool_test_errors
except Exception as e:
print "Adding tool_test_errors column to the repository_metadata table failed: %s" % str(e)
except Exception:
log.exception("Adding tool_test_errors column to the repository_metadata table failed.")
@@ -1,6 +1,8 @@
"""
Migration script to add the skip_tool_test table and add the test_install_error column to the repository_metadata table.
"""
from __future__ import print_function
import datetime
import logging
import sys
@@ -33,7 +35,7 @@ SkipToolTest_table = Table("skip_tool_test", metadata,
def upgrade(migrate_engine):
print __doc__
print(__doc__)
metadata.bind = migrate_engine
metadata.reflect()
# Initialize.
@@ -55,14 +57,14 @@ def upgrade(migrate_engine):
c.create(RepositoryMetadata_table, index_name="ix_repository_metadata_ttie")
assert c is RepositoryMetadata_table.c.test_install_error
migrate_engine.execute("UPDATE repository_metadata SET test_install_error=%s" % default_false)
except Exception as e:
print "Adding test_install_error column to the repository_metadata table failed: %s" % str(e)
except Exception:
log.exception("Adding test_install_error column to the repository_metadata table failed.")
# Create skip_tool_test table.
try:
SkipToolTest_table.create()
except Exception as e:
print "Creating the skip_tool_test table failed: %s" % str(e)
except Exception:
log.exception("Creating the skip_tool_test table failed.")
def downgrade(migrate_engine):
@@ -72,12 +74,12 @@ def downgrade(migrate_engine):
# Drop the skip_tool_test table.
try:
SkipToolTest_table.drop()
except Exception as e:
print "Dropping the skip_tool_test table failed: %s" % str(e)
except Exception:
log.exception("Dropping the skip_tool_test table failed.")
# Drop test_install_error column from the repository_metadata table.
RepositoryMetadata_table = Table("repository_metadata", metadata, autoload=True)
try:
RepositoryMetadata_table.c.test_install_error.drop()
except Exception as e:
print "Dropping column test_install_error from the repository_metadata table failed: %s" % str(e)
except Exception:
log.exception("Dropping column test_install_error from the repository_metadata table failed.")
@@ -1,4 +1,6 @@
"""Migration script to add the type column to the repository table."""
from __future__ import print_function
import logging
import sys
@@ -19,7 +21,7 @@ metadata = MetaData()
def upgrade(migrate_engine):
print __doc__
print(__doc__)
metadata.bind = migrate_engine
metadata.reflect()
Repository_table = Table("repository", metadata, autoload=True)
@@ -28,8 +30,8 @@ def upgrade(migrate_engine):
# Create
c.create(Repository_table, index_name="ix_repository_type")
assert c is Repository_table.c.type
except Exception as e:
print "Adding type column to the repository table failed: %s" % str(e)
except Exception:
log.exception("Adding type column to the repository table failed.")
# Update the type column to have the default unrestricted value.
cmd = "UPDATE repository SET type = 'unrestricted'"
migrate_engine.execute(cmd)
@@ -42,5 +44,5 @@ def downgrade(migrate_engine):
Repository_table = Table("repository", metadata, autoload=True)
try:
Repository_table.c.type.drop()
except Exception as e:
print "Dropping column type from the repository table failed: %s" % str(e)
except Exception:
log.exception("Dropping column type from the repository table failed.")
@@ -1,4 +1,6 @@
"""Migration script to change repository.type column value from generic to unrestricted."""
from __future__ import print_function
import logging
import sys
@@ -16,7 +18,7 @@ metadata = MetaData()
def upgrade(migrate_engine):
print __doc__
print(__doc__)
metadata.bind = migrate_engine
metadata.reflect()
# Update the type column to have the default unrestricted value.
@@ -3,6 +3,8 @@ Migration script to create the repository_role_association table, insert name-sp
repository administrative roles into the role table and associate each repository and
owner with the appropriate name-spaced role.
"""
from __future__ import print_function
import datetime
import logging
import sys
@@ -59,15 +61,14 @@ def boolean_false(migrate_engine):
def upgrade(migrate_engine):
print __doc__
print(__doc__)
metadata.bind = migrate_engine
metadata.reflect()
# Create the new repository_role_association table.
try:
RepositoryRoleAssociation_table.create()
except Exception as e:
print str(e)
log.debug("Creating repository_role_association table failed: %s" % str(e))
except Exception:
log.exception("Creating repository_role_association table failed.")
# Select the list of repositories and associated public user names for their owners.
user_ids = []
repository_ids = []
@@ -159,5 +160,5 @@ def downgrade(migrate_engine):
log.debug("Failed loading table repository_role_association")
try:
RepositoryRoleAssociation_table.drop()
except Exception as e:
log.debug("Dropping repository_role_association table failed: %s" % str(e))
except Exception:
log.exception("Dropping repository_role_association table failed.")
@@ -2,6 +2,8 @@
Migration script to add the remote_repository_url and homepage_url
columns to the repository table.
"""
from __future__ import print_function
import logging
import sys
@@ -21,7 +23,7 @@ metadata = MetaData()
def upgrade(migrate_engine):
print __doc__
print(__doc__)
metadata.bind = migrate_engine
metadata.reflect()
Repository_table = Table("repository", metadata, autoload=True)
@@ -33,8 +35,8 @@ def upgrade(migrate_engine):
c_homepage.create(Repository_table)
assert c_remote is Repository_table.c.remote_repository_url
assert c_homepage is Repository_table.c.homepage_url
except Exception as e:
print "Adding remote_repository_url and homepage_url columns to the repository table failed: %s" % str(e)
except Exception:
log.exception("Adding remote_repository_url and homepage_url columns to the repository table failed.")
def downgrade(migrate_engine):
@@ -45,5 +47,5 @@ def downgrade(migrate_engine):
try:
Repository_table.c.remote_repository_url.drop()
Repository_table.c.homepage_url.drop()
except Exception as e:
print "Dropping columns remote_repository_url and homepage_url from the repository table failed: %s" % str(e)
except Exception:
log.exception("Dropping columns remote_repository_url and homepage_url from the repository table failed.")
@@ -1,6 +1,8 @@
"""
Migration script for the password reset table
"""
from __future__ import print_function
import datetime
import logging
@@ -18,12 +20,11 @@ PasswordResetToken_table = Table("password_reset_token", metadata,
def upgrade(migrate_engine):
metadata.bind = migrate_engine
print __doc__
print(__doc__)
metadata.reflect()
try:
PasswordResetToken_table.create()
except Exception as e:
print str(e)
except Exception:
log.exception("Creating %s table failed", PasswordResetToken_table.name)
@@ -32,6 +33,5 @@ def downgrade(migrate_engine):
metadata.reflect()
try:
PasswordResetToken_table.drop()
except Exception as e:
print str(e)
except Exception:
log.exception("Dropping %s table failed", PasswordResetToken_table.name)
@@ -1,6 +1,8 @@
"""
Migration script to add session update time (used for timeouts)
"""
from __future__ import print_function
import datetime
import logging
@@ -13,7 +15,7 @@ metadata = MetaData()
def upgrade(migrate_engine):
metadata.bind = migrate_engine
print __doc__
print(__doc__)
metadata.reflect()
lastaction_column = Column("last_action", DateTime)
@@ -31,8 +33,7 @@ def __add_column(column, table_name, metadata, **kwds):
try:
table = Table(table_name, metadata, autoload=True)
column.create(table, **kwds)
except Exception as e:
print str(e)
except Exception:
log.exception("Adding column %s failed.", column)
@@ -40,6 +41,5 @@ def __drop_column(column_name, table_name, metadata):
try:
table = Table(table_name, metadata, autoload=True)
getattr(table.c, column_name).drop()
except Exception as e:
print str(e)
except Exception:
log.exception("Dropping column %s failed.", column_name)
+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":
+3 -1
View File
@@ -66,7 +66,8 @@ def set_meta_with_tool_provided(dataset_instance, file_dict, set_meta_kwds, data
def set_metadata():
# locate galaxy_root for loading datatypes
galaxy_root = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, os.pardir))
galaxy.datatypes.metadata.MetadataTempFile.tmp_dir = tool_job_working_directory = os.path.abspath(os.getcwd())
import galaxy.model
galaxy.model.metadata.MetadataTempFile.tmp_dir = tool_job_working_directory = os.path.abspath(os.getcwd())
# This is ugly, but to transition from existing jobs without this parameter
# to ones with, smoothly, it has to be the last optional parameter and we
@@ -80,6 +81,7 @@ def set_metadata():
# Set up datatypes registry
datatypes_config = sys.argv.pop(1)
import galaxy.datatypes.registry
datatypes_registry = galaxy.datatypes.registry.Registry()
datatypes_registry.load_datatypes(root_dir=galaxy_root, config=datatypes_config)
galaxy.model.set_datatypes_registry(datatypes_registry)
@@ -1807,7 +1807,7 @@ class SetupVirtualEnv(Download, RecipeStep):
# to subprocess.Popen.
for site_packages_command in [r"""%s -c 'import site; site.getsitepackages()[0]'""" %
os.path.join(venv_directory, "bin", "python"),
r"""%s -c 'import os, sys; print os.path.join( sys.prefix, "lib", "python" + sys.version[:3], "site-packages" )'""" %
r"""%s -c 'from __future__ import print_function; import os, sys; print(os.path.join(sys.prefix, "lib", "python" + sys.version[:3], "site-packages"))'""" %
os.path.join(venv_directory, "bin", "python")]:
output = install_environment.handle_command(tool_dependency=tool_dependency,
cmd=site_packages_command,

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