Merging with dev

This commit is contained in:
anuprulez
2017-03-07 21:46:26 +01:00
497 changed files with 7898 additions and 7487 deletions
+1
View File
@@ -5,3 +5,4 @@ database/
doc/source/conf.py
eggs/
lib/galaxy/util/jstree.py
lib/galaxy/web/proxy/js/node_modules/
+6 -149
View File
@@ -14,6 +14,7 @@ lib/galaxy/dataset_collections/__init__.py
lib/galaxy/dataset_collections/structure.py
lib/galaxy/dataset_collections/subcollections.py
lib/galaxy/dataset_collections/type_description.py
lib/galaxy/dataset_collections/types/__init__.py
lib/galaxy/datatypes/assembly.py
lib/galaxy/datatypes/binary.py
lib/galaxy/datatypes/checkers.py
@@ -53,8 +54,10 @@ lib/galaxy/datatypes/dataproviders/__init__.py
lib/galaxy/datatypes/data.py
lib/galaxy/datatypes/display_applications/__init__.py
lib/galaxy/datatypes/display_applications/util.py
lib/galaxy/datatypes/genetics.py
lib/galaxy/datatypes/images.py
lib/galaxy/datatypes/__init__.py
lib/galaxy/datatypes/interval.py
lib/galaxy/datatypes/metadata.py
lib/galaxy/datatypes/msa.py
lib/galaxy/datatypes/ngsindex.py
@@ -93,16 +96,7 @@ lib/galaxy/jobs/runners/pulsar.py
lib/galaxy/jobs/runners/slurm.py
lib/galaxy/jobs/runners/state_handlers/
lib/galaxy/jobs/runners/tasks.py
lib/galaxy/jobs/runners/util/cli/factory.py
lib/galaxy/jobs/runners/util/cli/job/__init__.py
lib/galaxy/jobs/runners/util/cli/job/slurm_torque.py
lib/galaxy/jobs/runners/util/cli/job/torque.py
lib/galaxy/jobs/runners/util/cli/shell/__init__.py
lib/galaxy/jobs/runners/util/drmaa/
lib/galaxy/jobs/runners/util/env.py
lib/galaxy/jobs/runners/util/external.py
lib/galaxy/jobs/runners/util/__init__.py
lib/galaxy/jobs/runners/util/job_script/
lib/galaxy/jobs/runners/util/
lib/galaxy/jobs/splitters/basic.py
lib/galaxy/jobs/splitters/__init__.py
lib/galaxy/jobs/stock_rules.py
@@ -123,134 +117,7 @@ lib/galaxy/model/__init__.py
lib/galaxy/model/item_attrs.py
lib/galaxy/model/mapping.py
lib/galaxy/model/metadata.py
lib/galaxy/model/migrate/__init__.py
lib/galaxy/model/migrate/versions/0001_initial_tables.py
lib/galaxy/model/migrate/versions/0002_metadata_file_table.py
lib/galaxy/model/migrate/versions/0003_security_and_libraries.py
lib/galaxy/model/migrate/versions/0004_indexes_and_defaults.py
lib/galaxy/model/migrate/versions/0006_change_qual_datatype.py
lib/galaxy/model/migrate/versions/0007_sharing_histories.py
lib/galaxy/model/migrate/versions/0008_galaxy_forms.py
lib/galaxy/model/migrate/versions/0009_request_table.py
lib/galaxy/model/migrate/versions/0010_hda_display_at_authz_table.py
lib/galaxy/model/migrate/versions/0011_v0010_mysql_index_fix.py
lib/galaxy/model/migrate/versions/0012_user_address.py
lib/galaxy/model/migrate/versions/0013_change_lib_item_templates_to_forms.py
lib/galaxy/model/migrate/versions/0014_pages.py
lib/galaxy/model/migrate/versions/0015_tagging.py
lib/galaxy/model/migrate/versions/0016_v0015_mysql_index_fix.py
lib/galaxy/model/migrate/versions/0017_library_item_indexes.py
lib/galaxy/model/migrate/versions/0018_ordered_tags_and_page_tags.py
lib/galaxy/model/migrate/versions/0019_request_library_folder.py
lib/galaxy/model/migrate/versions/0020_library_upload_job.py
lib/galaxy/model/migrate/versions/0021_user_prefs.py
lib/galaxy/model/migrate/versions/0022_visualization_tables.py
lib/galaxy/model/migrate/versions/0023_page_published_and_deleted_columns.py
lib/galaxy/model/migrate/versions/0024_page_slug_unique_constraint.py
lib/galaxy/model/migrate/versions/0025_user_info.py
lib/galaxy/model/migrate/versions/0026_cloud_tables.py
lib/galaxy/model/migrate/versions/0027_request_events.py
lib/galaxy/model/migrate/versions/0028_external_metadata_file_override.py
lib/galaxy/model/migrate/versions/0029_user_actions.py
lib/galaxy/model/migrate/versions/0030_history_slug_column.py
lib/galaxy/model/migrate/versions/0031_community_and_workflow_tags.py
lib/galaxy/model/migrate/versions/0032_stored_workflow_slug_column.py
lib/galaxy/model/migrate/versions/0033_published_cols_for_histories_and_workflows.py
lib/galaxy/model/migrate/versions/0034_page_user_share_association.py
lib/galaxy/model/migrate/versions/0035_item_annotations_and_workflow_step_tags.py
lib/galaxy/model/migrate/versions/0036_add_deleted_column_to_library_template_assoc_tables.py
lib/galaxy/model/migrate/versions/0037_samples_library.py
lib/galaxy/model/migrate/versions/0038_add_inheritable_column_to_library_template_assoc_tables.py
lib/galaxy/model/migrate/versions/0039_add_synopsis_column_to_library_table.py
lib/galaxy/model/migrate/versions/0040_page_annotations.py
lib/galaxy/model/migrate/versions/0041_workflow_invocation.py
lib/galaxy/model/migrate/versions/0042_workflow_invocation_fix.py
lib/galaxy/model/migrate/versions/0043_visualization_sharing_tagging_annotating.py
lib/galaxy/model/migrate/versions/0044_add_notify_column_to_request_table.py
lib/galaxy/model/migrate/versions/0045_request_type_permissions_table.py
lib/galaxy/model/migrate/versions/0046_post_job_actions.py
lib/galaxy/model/migrate/versions/0047_job_table_user_id_column.py
lib/galaxy/model/migrate/versions/0048_dataset_instance_state_column.py
lib/galaxy/model/migrate/versions/0049_api_keys_table.py
lib/galaxy/model/migrate/versions/0050_drop_cloud_tables.py
lib/galaxy/model/migrate/versions/0051_imported_col_for_jobs_table.py
lib/galaxy/model/migrate/versions/0052_sample_dataset_table.py
lib/galaxy/model/migrate/versions/0053_item_ratings.py
lib/galaxy/model/migrate/versions/0054_visualization_dbkey.py
lib/galaxy/model/migrate/versions/0055_add_pja_assoc_for_jobs.py
lib/galaxy/model/migrate/versions/0056_workflow_outputs.py
lib/galaxy/model/migrate/versions/0057_request_notify.py
lib/galaxy/model/migrate/versions/0058_history_import_export.py
lib/galaxy/model/migrate/versions/0059_sample_dataset_file_path.py
lib/galaxy/model/migrate/versions/0060_history_archive_import.py
lib/galaxy/model/migrate/versions/0061_tasks.py
lib/galaxy/model/migrate/versions/0062_user_openid_table.py
lib/galaxy/model/migrate/versions/0063_sequencer_table.py
lib/galaxy/model/migrate/versions/0064_add_run_and_sample_run_association_tables.py
lib/galaxy/model/migrate/versions/0066_deferred_job_and_transfer_job_tables.py
lib/galaxy/model/migrate/versions/0067_populate_sequencer_table.py
lib/galaxy/model/migrate/versions/0068_rename_sequencer_to_external_services.py
lib/galaxy/model/migrate/versions/0069_rename_sequencer_form_type.py
lib/galaxy/model/migrate/versions/0070_add_info_column_to_deferred_job_table.py
lib/galaxy/model/migrate/versions/0071_add_history_and_workflow_to_sample.py
lib/galaxy/model/migrate/versions/0072_add_pid_and_socket_columns_to_transfer_job_table.py
lib/galaxy/model/migrate/versions/0073_add_ldda_to_implicit_conversion_table.py
lib/galaxy/model/migrate/versions/0074_add_purged_column_to_library_dataset_table.py
lib/galaxy/model/migrate/versions/0075_add_subindex_column_to_run_table.py
lib/galaxy/model/migrate/versions/0076_fix_form_values_data_corruption.py
lib/galaxy/model/migrate/versions/0077_create_tool_tag_association_table.py
lib/galaxy/model/migrate/versions/0078_add_columns_for_disk_usage_accounting.py
lib/galaxy/model/migrate/versions/0079_input_library_to_job_table.py
lib/galaxy/model/migrate/versions/0080_quota_tables.py
lib/galaxy/model/migrate/versions/0081_add_tool_version_to_hda_ldda.py
lib/galaxy/model/migrate/versions/0082_add_tool_shed_repository_table.py
lib/galaxy/model/migrate/versions/0083_add_prepare_files_to_task.py
lib/galaxy/model/migrate/versions/0084_add_ldda_id_to_implicit_conversion_table.py
lib/galaxy/model/migrate/versions/0085_add_task_info.py
lib/galaxy/model/migrate/versions/0086_add_tool_shed_repository_table_columns.py
lib/galaxy/model/migrate/versions/0087_tool_id_guid_map_table.py
lib/galaxy/model/migrate/versions/0088_add_installed_changeset_revison_column.py
lib/galaxy/model/migrate/versions/0089_add_object_store_id_columns.py
lib/galaxy/model/migrate/versions/0090_add_tool_shed_repository_table_columns.py
lib/galaxy/model/migrate/versions/0091_add_tool_version_tables.py
lib/galaxy/model/migrate/versions/0092_add_migrate_tools_table.py
lib/galaxy/model/migrate/versions/0093_add_job_params_col.py
lib/galaxy/model/migrate/versions/0094_add_job_handler_col.py
lib/galaxy/model/migrate/versions/0095_hda_subsets.py
lib/galaxy/model/migrate/versions/0096_openid_provider.py
lib/galaxy/model/migrate/versions/0097_add_ctx_rev_column.py
lib/galaxy/model/migrate/versions/0098_genome_index_tool_data_table.py
lib/galaxy/model/migrate/versions/0099_add_tool_dependency_table.py
lib/galaxy/model/migrate/versions/0100_alter_tool_dependency_table_version_column.py
lib/galaxy/model/migrate/versions/0101_drop_installed_changeset_revision_column.py
lib/galaxy/model/migrate/versions/0102_add_tool_dependency_status_columns.py
lib/galaxy/model/migrate/versions/0103_add_tool_shed_repository_status_columns.py
lib/galaxy/model/migrate/versions/0104_update_genome_downloader_job_parameters.py
lib/galaxy/model/migrate/versions/0105_add_cleanup_event_table.py
lib/galaxy/model/migrate/versions/0106_add_missing_indexes.py
lib/galaxy/model/migrate/versions/0107_add_exit_code_to_job_and_task.py
lib/galaxy/model/migrate/versions/0108_add_extended_metadata.py
lib/galaxy/model/migrate/versions/0109_add_repository_dependency_tables.py
lib/galaxy/model/migrate/versions/0110_add_dataset_uuid.py
lib/galaxy/model/migrate/versions/0111_add_job_destinations.py
lib/galaxy/model/migrate/versions/0112_add_data_manager_history_association_and_data_manager_job_association_tables.py
lib/galaxy/model/migrate/versions/0113_update_migrate_tools_table.py
lib/galaxy/model/migrate/versions/0114_update_migrate_tools_table_again.py
lib/galaxy/model/migrate/versions/0115_longer_user_password_field.py
lib/galaxy/model/migrate/versions/0116_drop_update_available_col_add_tool_shed_status_col.py
lib/galaxy/model/migrate/versions/0117_add_user_activation.py
lib/galaxy/model/migrate/versions/0118_add_hda_extended_metadata.py
lib/galaxy/model/migrate/versions/0119_job_metrics.py
lib/galaxy/model/migrate/versions/0120_dataset_collections.py
lib/galaxy/model/migrate/versions/0121_workflow_uuids.py
lib/galaxy/model/migrate/versions/0123_add_workflow_request_tables.py
lib/galaxy/model/migrate/versions/0124_job_state_history.py
lib/galaxy/model/migrate/versions/0125_workflow_step_tracking.py
lib/galaxy/model/migrate/versions/0126_password_reset.py
lib/galaxy/model/migrate/versions/0127_output_collection_adjustments.py
lib/galaxy/model/migrate/versions/0128_session_timeout.py
lib/galaxy/model/migrate/versions/0129_job_external_output_metadata_validity.py
lib/galaxy/model/migrate/versions/0130_change_pref_datatype.py
lib/galaxy/model/migrate/
lib/galaxy/model/orm/
lib/galaxy/model/tool_shed_install/migrate/__init__.py
lib/galaxy/model/tool_shed_install/migrate/versions/
@@ -266,16 +133,6 @@ lib/galaxy/security/validate_user_input.py
lib/galaxy/tags/
lib/galaxy/tools/
lib/galaxy/util/
lib/galaxy_utils/__init__.py
lib/galaxy/util/sleeper.py
lib/galaxy/util/specs.py
lib/galaxy_utils/sequence/fasta.py
lib/galaxy_utils/sequence/fastq.py
lib/galaxy_utils/sequence/__init__.py
lib/galaxy_utils/sequence/transform.py
lib/galaxy_utils/sequence/vcf.py
lib/galaxy/util/template.py
lib/galaxy/util/ucsc.py
lib/galaxy/version.py
lib/galaxy/visualization/data_providers/basic.py
lib/galaxy/visualization/data_providers/cigar.py
@@ -306,6 +163,7 @@ lib/galaxy/web/framework/middleware/xforwardedhost.py
lib/galaxy/web/__init__.py
lib/galaxy/web/params.py
lib/galaxy/webapps/galaxy/api/genomes.py
lib/galaxy/webapps/galaxy/api/histories.py
lib/galaxy/webapps/galaxy/api/__init__.py
lib/galaxy/webapps/galaxy/api/jobs.py
lib/galaxy/webapps/galaxy/api/lda_datasets.py
@@ -444,7 +302,6 @@ scripts/tools/re_escape_output.py
test/api/__init__.py
test/api/test_dataset_collections.py
test/api/test_datasets.py
test/api/test_datatypes.py
test/api/test_framework.py
test/api/test_history_contents_provenance.py
test/api/test_jobs.py
+6 -3
View File
@@ -36,6 +36,12 @@ docker-compose down | true
docker-compose build galaxy
docker-compose up -d
function tear_down {
docker-compose down
}
trap tear_down EXIT
for service_name in postgres galaxy selenium
do
echo "Waiting on service ${service_name}"
@@ -79,7 +85,6 @@ do
docker logs "${container_id}"
echo "---"
done
docker-compose down | true
exit 1
fi
done
@@ -105,6 +110,4 @@ exit_code=$?
cd $TEST_DIRECTORY
docker-compose down
exit $exit_code
+4 -2
View File
@@ -13,7 +13,9 @@ lib/galaxy/datatypes/constructive_solid_geometry.py
lib/galaxy/datatypes/converters/
lib/galaxy/datatypes/dataproviders/
lib/galaxy/datatypes/data.py
lib/galaxy/datatypes/genetics.py
lib/galaxy/datatypes/images.py
lib/galaxy/datatypes/interval.py
lib/galaxy/datatypes/msa.py
lib/galaxy/datatypes/ngsindex.py
lib/galaxy/datatypes/proteomics.py
@@ -50,6 +52,7 @@ lib/galaxy/web/framework/middleware/error.py
lib/galaxy/web/framework/middleware/static.py
lib/galaxy/web/framework/middleware/statsd.py
lib/galaxy/web/__init__.py
lib/galaxy/webapps/galaxy/api/histories.py
lib/galaxy/webapps/galaxy/api/tours.py
lib/galaxy/webapps/galaxy/api/workflows.py
lib/galaxy/webapps/galaxy/controllers/external_services.py
@@ -65,10 +68,9 @@ lib/galaxy/webapps/tool_shed/util/ratings_util.py
lib/galaxy/work/
lib/galaxy/workflow/extract.py
lib/galaxy/workflow/run.py
lib/galaxy/workflow/schedulers/core.py
lib/galaxy/workflow/schedulers/
lib/galaxy/workflow/steps.py
lib/galaxy_ext/
lib/galaxy_utils/
lib/log_tempfile.py
lib/psyco_full.py
lib/tool_shed/
+3 -4
View File
@@ -17,11 +17,10 @@ deeper discussion of some of these points - please see the
If you have an idea for a feature to add or an approach for a bugfix,
it is best to communicate with Galaxy developers early. The most
common venues for this are
[GitHub issues](https://github.com/galaxyproject/galaxy/issues) and the
[Galaxy and Tool Shed Trello boards](https://wiki.galaxyproject.org/Issues).
[GitHub issues](https://github.com/galaxyproject/galaxy/issues).
Browse through existing GitHub issues and Trello cards and if one seems related,
comment on it. We also maintain a [card](https://trello.com/c/eFdPIdIB) with
links to smaller issues we believe would make the best entry points for new
comment on it. We also maintain a [tag](https://github.com/galaxyproject/galaxy/issues?q=is%3Aissue+is%3Aopen+label%3Afriendliness%2Ffriendly) on Github for
smaller issues we believe would make the best entry points for new
developers.
Galaxy developers are generally available via
[IRC](https://wiki.galaxyproject.org/GetInvolved#IRC_Channel) and on
+6 -2
View File
@@ -9,9 +9,13 @@ The latest information about Galaxy is available via `https://galaxyproject.org/
.. image:: https://img.shields.io/badge/chat-irc.freenode.net%23galaxyproject-blue.svg
:target: https://webchat.freenode.net/?channels=galaxyproject
:alt: Chat with us
:alt: Chat on irc
.. image:: https://img.shields.io/badge/chat-gitter-blue.svg
:target: https://gitter.im/galaxyproject/Lobby
:alt: Chat on gitter
.. image:: https://img.shields.io/badge/docs-release-green.svg
.. image:: https://img.shields.io/badge/release-documentation-blue.svg
:target: https://docs.galaxyproject.org/en/master/
:alt: Release Documentation
@@ -14,7 +14,7 @@
* @param {object|string} options
* @returns (object} jQuery object
*/
$.fn.autocomplete = function(options) {
$.fn.autocomplete_verheul = function(options) {
var url;
if (arguments.length > 1) {
url = options;
@@ -24,7 +24,7 @@
url = options;
options = { url: url };
}
var opts = $.extend({}, $.fn.autocomplete.defaults, options);
var opts = $.extend({}, $.fn.autocomplete_verheul.defaults, options);
return this.each(function() {
var $this = $(this);
$this.data('autocompleter', new $.Autocompleter(
@@ -38,7 +38,7 @@
* Store default options
* @type {object}
*/
$.fn.autocomplete.defaults = {
$.fn.autocomplete_verheul.defaults = {
inputClass: 'acInput',
loadingClass: 'acLoading',
resultsClass: 'acResults',
@@ -289,10 +289,10 @@
/**
* Sanitize options
*/
this.options.minChars = sanitizeInteger(this.options.minChars, $.fn.autocomplete.defaults.minChars, { min: 0 });
this.options.maxItemsToShow = sanitizeInteger(this.options.maxItemsToShow, $.fn.autocomplete.defaults.maxItemsToShow, { min: 0 });
this.options.maxCacheLength = sanitizeInteger(this.options.maxCacheLength, $.fn.autocomplete.defaults.maxCacheLength, { min: 1 });
this.options.delay = sanitizeInteger(this.options.delay, $.fn.autocomplete.defaults.delay, { min: 0 });
this.options.minChars = sanitizeInteger(this.options.minChars, $.fn.autocomplete_verheul.defaults.minChars, { min: 0 });
this.options.maxItemsToShow = sanitizeInteger(this.options.maxItemsToShow, $.fn.autocomplete_verheul.defaults.maxItemsToShow, { min: 0 });
this.options.maxCacheLength = sanitizeInteger(this.options.maxCacheLength, $.fn.autocomplete_verheul.defaults.maxCacheLength, { min: 1 });
this.options.delay = sanitizeInteger(this.options.delay, $.fn.autocomplete_verheul.defaults.delay, { min: 0 });
if (this.options.preventDefaultReturn != 2) {
this.options.preventDefaultReturn = this.options.preventDefaultReturn ? 1 : 0;
}
+5 -8
View File
@@ -5,7 +5,7 @@ define([], function() {
return Backbone.View.extend({
initialize: function( app, options ) {
this.app = app;
this.app_options = app.options || {};
this.app_options = app.model ? app.model.attributes : {};
this.field = options && options.field || new Backbone.View();
this.model = options && options.model || new Backbone.Model({
text_enable : this.app_options.text_enable || 'Enable',
@@ -46,22 +46,19 @@ define([], function() {
});
},
/** Set backdrop for input element
*/
/** Set backdrop for input element */
backdrop: function() {
this.model.set( 'backdrop', true );
},
/** Set error text
*/
/** Set error text */
error: function( text ) {
this.model.set( 'error_text', text );
},
/** Reset this view
*/
/** Reset this view */
reset: function() {
this.model.set( 'error_text', null );
!this.model.get( 'fixed' ) && this.model.set( 'error_text', null );
},
render: function() {
@@ -151,6 +151,7 @@ define(['utils/utils',
area : input_def.area,
readonly : input_def.readonly,
placeholder : input_def.placeholder,
datalist : input_def.datalist,
onchange : input_def.onchange
});
},
@@ -43,7 +43,7 @@ function( Utils, Ui, Portlet, Repeat, InputElement, Parameters ) {
_addConditional: function( input_def ) {
var self = this;
input_def.test_param.id = input_def.id;
this.app.options.sustain_conditionals && ( input_def.test_param.disabled = true );
this.app.model.get( 'sustain_conditionals' ) && ( input_def.test_param.disabled = true );
var field = this._addRow( input_def.test_param );
// set onchange event for test parameter
@@ -109,7 +109,7 @@ function( Utils, Ui, Portlet, Repeat, InputElement, Parameters ) {
}
// hide options
this.app.options.sustain_repeats && repeat.hideOptions();
this.app.model.get( 'sustain_repeats' ) && repeat.hideOptions();
// create input field wrapper
var input_element = new InputElement( this.app, {
@@ -156,6 +156,7 @@ function( Utils, Ui, Portlet, Repeat, InputElement, Parameters ) {
style : input_def.style,
backdrop : input_def.backdrop,
hidden : input_def.hidden,
fixed : input_def.fixed,
field : field
});
this.app.element_list[ id ] = input_element;
+20 -17
View File
@@ -5,12 +5,13 @@ define( [ 'utils/utils', 'mvc/ui/ui-portlet', 'mvc/ui/ui-misc', 'mvc/form/form-s
function( Utils, Portlet, Ui, FormSection, FormData ) {
return Backbone.View.extend({
initialize: function( options ) {
this.options = Utils.merge( options, {
this.model = new Backbone.Model({
initial_errors : false,
cls : 'ui-portlet-limited',
icon : null,
always_refresh : true
});
always_refresh : true,
message_status : 'warning'
}).set( options );
this.setElement( '<div/>' );
this.render();
},
@@ -101,16 +102,16 @@ function( Utils, Portlet, Ui, FormSection, FormData ) {
this.data = new FormData.Manager( this );
this._renderForm();
this.data.create();
this.options.initial_errors && this.errors( this.options );
this.model.get( 'initial_errors' ) && this.errors( this.model.attributes );
// add listener which triggers on checksum change, and reset the form input wrappers
var current_check = this.data.checksum();
this.on('change', function( input_id ) {
this.on( 'change', function( input_id ) {
var input = self.input_list[ input_id ];
if ( !input || input.refresh_on_change || self.options.always_refresh ) {
if ( !input || input.refresh_on_change || self.model.get( 'always_refresh' ) ) {
var new_check = self.data.checksum();
if ( new_check != current_check ) {
current_check = new_check;
self.options.onchange && self.options.onchange();
self.model.get( 'onchange' ) && self.model.get( 'onchange' )();
}
}
});
@@ -123,22 +124,24 @@ function( Utils, Portlet, Ui, FormSection, FormData ) {
/** Renders/appends dom elements of the form */
_renderForm: function() {
$( '.tooltip' ).remove();
var options = this.model.attributes;
this.message = new Ui.UnescapedMessage();
this.section = new FormSection.View( this, { inputs: this.options.inputs } );
this.section = new FormSection.View( this, { inputs: options.inputs } );
this.portlet = new Portlet.View({
icon : this.options.icon,
title : this.options.title,
cls : this.options.cls,
operations : this.options.operations,
buttons : this.options.buttons,
collapsible : this.options.collapsible,
collapsed : this.options.collapsed
icon : options.icon,
title : options.title,
cls : options.cls,
operations : options.operations,
buttons : options.buttons,
collapsible : options.collapsible,
collapsed : options.collapsed,
onchange_title : options.onchange_title
});
this.portlet.append( this.message.$el );
this.portlet.append( this.section.$el );
this.$el.empty();
this.options.inputs && this.$el.append( this.portlet.$el );
this.options.message && this.message.update( { persistent: true, status: 'warning', message: this.options.message } );
options.inputs && this.$el.append( this.portlet.$el );
options.message && this.message.update( { persistent: true, status: options.message_status, message: options.message } );
Galaxy.emit.debug( 'form-view::initialize()', 'Completed' );
}
});
@@ -155,18 +155,6 @@ return Backbone.View.extend({
});
});
// Initialize autocomplete for text inputs in search UI.
var t1 = this.$el.find('#input-tags-filter');
if (t1.length) {
t1.autocomplete(this.grid.history_tag_autocomplete_url,
{ selectFirst: false, autoFill: false, highlight: false, mustMatch: false });
}
var t2 = this.$el.find('#input-name-filter');
if (t2.length) {
t2.autocomplete(this.grid.history_name_autocomplete_url,
{ selectFirst: false, autoFill: false, highlight: false, mustMatch: false });
}
// Initialize standard, advanced search toggles.
this.$el.find('.advanced-search-toggle').each( function() {
$(this).off();
@@ -43,6 +43,12 @@ HDAListItemView.prototype.templates = (function(){
'<span class="hid"><%- dataset.hid %></span> ',
'<span class="name"><%- dataset.name %></span>',
'</div>',
'</br>',
'<span class="nametags">',
'<% _.each(dataset.nametags, function(tag){ %>',
'<span class="label label-info"><%- tag %></span>',
'<% }); %>',
'</span>',
'</div>'
], 'dataset' );
@@ -177,7 +177,7 @@ var History = Backbone.Model
// if we don't flip this, then a fully-fetched list will not be re-checked via fetch
this.contents.allFetched = false;
var fetchFn = self.contents.currentPage !== 0
? function(){ return self.contents.fetchPage( 0 ); }
? function(){ return self.contents.fetchPage( self.contents.currentPage ); }
: function(){ return self.contents.fetchUpdated( lastUpdateTime ); };
// note: if there was no previous update time, all summary contents will be fetched
return fetchFn()
@@ -369,14 +369,17 @@ var HistoryView = _super.extend(
}),
_clickPrevPage : function( ev ){
this.model.clearUpdateTimeout();
this.model.contents.fetchPrevPage();
},
_clickNextPage : function( ev ){
this.model.clearUpdateTimeout();
this.model.contents.fetchNextPage();
},
_changePageSelect : function( ev ){
this.model.clearUpdateTimeout();
var page = $( ev.currentTarget ).val();
this.model.contents.fetchPage( page );
},
@@ -110,17 +110,11 @@ var menu = [
html : _l( 'Unhide Hidden Datasets' ),
anon : true,
func : function() {
// TODO: Deprecate this functionality and replace with group dataset selector and action combination
if( Galaxy && Galaxy.currHistoryPanel && confirm( _l( 'Really unhide all hidden datasets?' ) ) ){
var filtered = Galaxy.currHistoryPanel.model.contents.hidden();
//TODO: batch
filtered.ajaxQueue( Backbone.Model.prototype.save, { visible : true })
.done( function(){
Galaxy.currHistoryPanel.renderItems();
})
.fail( function(){
alert( 'There was an error unhiding the datasets' );
console.error( arguments );
});
$.post(Galaxy.root + "history/adjust_hidden",
{ 'user_action' : 'unhide' },
function(){Galaxy.currHistoryPanel.loadCurrentHistory();});
}
},
},
@@ -128,18 +122,11 @@ var menu = [
html : _l( 'Delete Hidden Datasets' ),
anon : true,
func : function() {
// TODO: Deprecate this functionality and replace with group dataset selector and action combination
if( Galaxy && Galaxy.currHistoryPanel && confirm( _l( 'Really delete all hidden datasets?' ) ) ){
var filtered = Galaxy.currHistoryPanel.model.contents.hidden();
//TODO: batch
// both delete *and* unhide them
filtered.ajaxQueue( Backbone.Model.prototype.save, { deleted : true, visible: true })
.done( function(){
Galaxy.currHistoryPanel.renderItems();
})
.fail( function(){
alert( 'There was an error deleting the datasets' );
console.error( arguments );
});
$.post(Galaxy.root + "history/adjust_hidden",
{ 'user_action' : 'delete' },
function(){Galaxy.currHistoryPanel.loadCurrentHistory();});
}
},
},
+73 -141
View File
@@ -1,75 +1,67 @@
/**
This is the base class of the tool form plugin. This class is e.g. inherited by the regular and the workflow tool form.
*/
define(['utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view',
'mvc/citation/citation-model', 'mvc/citation/citation-view'],
function(Utils, Deferred, Ui, FormBase, CitationModel, CitationView) {
define( [ 'utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view', 'mvc/citation/citation-model', 'mvc/citation/citation-view' ],
function( Utils, Deferred, Ui, FormBase, CitationModel, CitationView ) {
return FormBase.extend({
initialize: function(options) {
initialize: function( options ) {
var self = this;
FormBase.prototype.initialize.call(this, options);
this.deferred = new Deferred();
if (options.inputs) {
this._buildForm(options);
FormBase.prototype.initialize.call( this, options );
if ( this.model.get( 'inputs' ) ) {
this._buildForm( this.model.attributes );
} else {
this.deferred.execute(function(process) {
self._buildModel(process, options, true);
this.deferred.execute( function( process ) {
self._buildModel( process, self.model.attributes, true );
});
}
// listen to history panel
if ( options.listen_to_history && parent.Galaxy && parent.Galaxy.currHistoryPanel ) {
if ( this.model.get( 'listen_to_history' ) && parent.Galaxy && parent.Galaxy.currHistoryPanel ) {
this.listenTo( parent.Galaxy.currHistoryPanel.collection, 'change', function() {
this.refresh();
self.model.get( 'onchange' )();
});
}
// destroy dom elements
this.$el.on( 'remove', function() { self.remove() } );
},
/** Listen to history panel changes and update the tool form */
refresh: function() {
var self = this;
self.deferred.reset();
this.deferred.execute( function (process){
self._updateModel( process)
});
},
/** Wait for deferred build processes before removal */
remove: function() {
var self = this;
this.$el.hide();
this.deferred.execute(function(){
FormBase.prototype.remove.call(self);
Galaxy.emit.debug('tool-form-base::remove()', 'Destroy view.');
this.deferred.execute( function() {
FormBase.prototype.remove.call( self );
Galaxy.emit.debug( 'tool-form-base::remove()', 'Destroy view.' );
});
},
/** Build form */
_buildForm: function(options) {
_buildForm: function( options ) {
var self = this;
this.options = Utils.merge(options, this.options);
this.options = Utils.merge({
icon : options.icon,
title : '<b>' + options.name + '</b> ' + options.description + ' (Galaxy Version ' + options.version + ')',
operations : !this.options.hide_operations && this._operations(),
onchange : function() {
self.refresh();
this.model.set( options );
this.model.set({
title : options.title || '<b>' + options.name + '</b> ' + options.description + ' (Galaxy Version ' + options.version + ')',
operations : !this.model.get( 'hide_operations' ) && this._operations(),
onchange : function() {
self.deferred.reset();
self.deferred.execute( function ( process ) {
self.model.get( 'postchange' )( process, self );
});
}
}, this.options);
this.options.customize && this.options.customize( this.options );
});
this.model.get( 'customize' ) && this.model.get( 'customize' )( this );
this.render();
if ( !this.options.collapsible ) {
if ( !this.model.get( 'collapsible' ) ) {
this.$el.append( $( '<div/>' ).addClass( 'ui-margin-top-large' ).append( this._footer() ) );
}
},
/** Builds a new model through api call and recreates the entire form
*/
_buildModel: function(process, options, hide_message) {
/** Builds a new model through api call and recreates the entire form */
_buildModel: function( process, new_options, hide_message ) {
var self = this;
this.options.id = options.id;
this.options.version = options.version;
var options = this.model.attributes;
options.version = new_options.version;
options.id = new_options.id;
// build request url
var build_url = '';
@@ -88,32 +80,31 @@ define(['utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view',
Utils.get({
url : build_url,
data : build_data,
success : function(new_model) {
new_model = new_model.tool_model || new_model;
if( !new_model.display ) {
success : function( data ) {
if( !data.display ) {
window.location = Galaxy.root;
return;
}
self._buildForm(new_model);
self._buildForm( data );
!hide_message && self.message.update({
status : 'success',
message : 'Now you are using \'' + self.options.name + '\' version ' + self.options.version + ', id \'' + self.options.id + '\'.',
message : 'Now you are using \'' + options.name + '\' version ' + options.version + ', id \'' + options.id + '\'.',
persistent : false
});
Galaxy.emit.debug('tool-form-base::initialize()', 'Initial tool model ready.', new_model);
Galaxy.emit.debug('tool-form-base::_buildModel()', 'Initial tool model ready.', data);
process.resolve();
},
error : function(response, status) {
error : function( response, status ) {
var error_message = ( response && response.err_msg ) || 'Uncaught error.';
if ( status == 401 ) {
window.location = Galaxy.root + 'user/login?' + $.param({ redirect : Galaxy.root + '?tool_id=' + self.options.id });
} else if ( self.$el.is(':empty') ) {
self.$el.prepend((new Ui.Message({
window.location = Galaxy.root + 'user/login?' + $.param({ redirect : Galaxy.root + '?tool_id=' + options.id });
} else if ( self.$el.is( ':empty' ) ) {
self.$el.prepend( ( new Ui.Message({
message : error_message,
status : 'danger',
persistent : true,
large : true
})).$el);
}) ).$el );
} else {
Galaxy.modal && Galaxy.modal.show({
title : 'Tool request failed',
@@ -125,75 +116,39 @@ define(['utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view',
}
});
}
Galaxy.emit.debug('tool-form::initialize()', 'Initial tool model request failed.', response);
Galaxy.emit.debug( 'tool-form-base::_buildModel()', 'Initial tool model request failed.', response );
process.reject();
}
});
},
/** Request a new model for an already created tool form and updates the form inputs
*/
_updateModel: function(process) {
// link this
var self = this;
var model_url = this.options.update_url || Galaxy.root + 'api/tools/' + this.options.id + '/build';
var current_state = {
tool_id : this.options.id,
tool_version : this.options.version,
inputs : $.extend(true, {}, self.data.create())
}
this.wait(true);
// log tool state
Galaxy.emit.debug('tool-form-base::_updateModel()', 'Sending current state.', current_state);
// post job
Utils.request({
type : 'POST',
url : model_url,
data : current_state,
success : function(new_model) {
self.update(new_model['tool_model'] || new_model);
self.options.update && self.options.update(new_model);
self.wait(false);
Galaxy.emit.debug('tool-form-base::_updateModel()', 'Received new model.', new_model);
process.resolve();
},
error : function(response) {
Galaxy.emit.debug('tool-form-base::_updateModel()', 'Refresh request failed.', response);
process.reject();
}
});
},
/** Create tool operation menu
*/
/** Create tool operation menu */
_operations: function() {
var self = this;
var options = this.options;
var options = this.model.attributes;
// button for version selection
var versions_button = new Ui.ButtonMenu({
icon : 'fa-cubes',
title : (!options.narrow && 'Versions') || null,
title : ( !options.narrow && 'Versions' ) || null,
tooltip : 'Select another tool version'
});
if (!options.sustain_version && options.versions && options.versions.length > 1) {
for (var i in options.versions) {
var version = options.versions[i];
if (version != options.version) {
if ( !options.sustain_version && options.versions && options.versions.length > 1 ) {
for ( var i in options.versions ) {
var version = options.versions[ i ];
if ( version != options.version ) {
versions_button.addMenu({
title : 'Switch to ' + version,
version : version,
icon : 'fa-cube',
onclick : function() {
// here we update the tool version (some tools encode the version also in the id)
var id = options.id.replace(options.version, this.version);
var id = options.id.replace( options.version, this.version );
var version = this.version;
// queue model request
self.deferred.reset();
self.deferred.execute(function(process) {
self._buildModel(process, {id: id, version: version})
self.deferred.execute( function( process ) {
self._buildModel( process, { id : id, version : version } )
});
}
});
@@ -206,84 +161,64 @@ define(['utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view',
// button for options e.g. search, help
var menu_button = new Ui.ButtonMenu({
icon : 'fa-caret-down',
title : (!options.narrow && 'Options') || null,
title : ( !options.narrow && 'Options' ) || null,
tooltip : 'View available options'
});
if(options.biostar_url) {
if ( options.biostar_url ) {
menu_button.addMenu({
icon : 'fa-question-circle',
title : 'Question?',
tooltip : 'Ask a question about this tool (Biostar)',
onclick : function() {
window.open(options.biostar_url + '/p/new/post/');
window.open( options.biostar_url + '/p/new/post/' );
}
});
menu_button.addMenu({
icon : 'fa-search',
title : 'Search',
tooltip : 'Search help for this tool (Biostar)',
onclick : function() {
window.open(options.biostar_url + '/local/search/page/?q=' + options.name);
window.open( options.biostar_url + '/local/search/page/?q=' + options.name );
}
});
};
menu_button.addMenu({
icon : 'fa-share',
title : 'Share',
tooltip : 'Share this tool',
onclick : function() {
prompt('Copy to clipboard: Ctrl+C, Enter', window.location.origin + Galaxy.root + 'root?tool_id=' + options.id);
prompt( 'Copy to clipboard: Ctrl+C, Enter', window.location.origin + Galaxy.root + 'root?tool_id=' + options.id );
}
});
// add admin operations
if (Galaxy.user && Galaxy.user.get('is_admin')) {
if ( Galaxy.user && Galaxy.user.get( 'is_admin' ) ) {
menu_button.addMenu({
icon : 'fa-download',
title : 'Download',
tooltip : 'Download this tool',
onclick : function() {
window.location.href = Galaxy.root + 'api/tools/' + options.id + '/download';
}
});
}
// add admin operations for tool XML reloading
if (Galaxy.user && Galaxy.user.get('is_admin')) {
menu_button.addMenu({
icon : 'fa-refresh',
title : 'Reload Tool XML',
tooltip : 'Reload tool XML file',
title : 'Reload XML',
onclick : function() {
var modalMessage = new Ui.Modal.View();
$.ajax({
url: '/api/tools/' + options.id + '/reload',
type: "GET",
}).done(function(data){
modalMessage.show({
title : data.done ? 'Tool XML Reload' : 'Tool XML Reload Error',
body : data.done ? data.done : data.error,
buttons : { 'Close' : function() { modalMessage.hide() } }
});
window.setTimeout(function(){modalMessage.hide();}, 2000);
}).fail(function(error){
modalMessage.show({
title: "Tool XML Reload AJAX Error",
body: options.id + " " + error,
buttons : { 'Close' : function() { modalMessage.hide() } }
});
Utils.get({
url : Galaxy.root + 'api/tools/' + options.id + '/reload',
success : function( response ) {
self.message.update( { persistent : false, message : 'Tool XML has been reloaded.', status : 'success' } );
},
error : function( response ) {
self.message.update( { persistent : false, message : response.err_msg, status : 'danger' } );
}
});
}
});
}
// button for version selection
if (options.requirements && options.requirements.length > 0) {
if ( options.requirements && options.requirements.length > 0 ) {
menu_button.addMenu({
icon : 'fa-info-circle',
title : 'Requirements',
tooltip : 'Display tool requirements',
onclick : function() {
if ( !this.requirements_visible || self.portlet.collapsed ) {
this.requirements_visible = true;
@@ -298,13 +233,12 @@ define(['utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view',
}
// add toolshed url
if (options.sharable_url) {
if ( options.sharable_url ) {
menu_button.addMenu({
icon : 'fa-external-link',
title : 'See in Tool Shed',
tooltip : 'Access the repository',
onclick : function() {
window.open(options.sharable_url);
window.open( options.sharable_url );
}
});
}
@@ -315,10 +249,9 @@ define(['utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view',
}
},
/** Create footer
*/
/** Create footer */
_footer: function() {
var options = this.options;
var options = this.model.attributes;
var $el = $( '<div/>' ).append( this._templateHelp( options ) );
if ( options.citations ) {
var $citations = $( '<div/>' );
@@ -332,8 +265,7 @@ define(['utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view',
return $el;
},
/** Templates
*/
/** Templates */
_templateHelp: function( options ) {
var $tmpl = $( '<div/>' ).addClass( 'ui-form-help' ).append( options.help );
$tmpl.find( 'a' ).attr( 'target', '_blank' );
@@ -38,13 +38,19 @@ define([ 'utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view'
this.parms = [];
_.each( this.model.get( 'steps' ), function( step, i ) {
Galaxy.emit.debug( 'tool-form-composite::initialize()', i + ' : Preparing workflow step.' );
var icon = WorkflowIcons[step.step_type];
var icon = WorkflowIcons[ step.step_type ];
var title = parseInt( i + 1 ) + ': ' + ( step.step_label || step.step_name );
if ( step.annotation ) {
title += ' - ' + step.annotation;
}
if ( step.step_version ) {
title += ' (Galaxy Version ' + step.step_version + ')';
}
step = Utils.merge( {
index : i,
name : step.name,
title : _.escape( title ),
icon : icon || '',
help : null,
description : step.annotation && ' - ' + step.annotation || step.description,
citations : null,
collapsible : true,
collapsed : i > 0 && !self._isDataStep( step ),
@@ -261,6 +267,31 @@ define([ 'utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view'
this.deferred.execute( function( promise ) {
self.$steps.addClass( 'ui-steps' );
if ( step.step_type == 'tool' ) {
step.postchange = function( process, form ) {
var self = this;
var current_state = {
tool_id : step.id,
tool_version : step.version,
inputs : $.extend( true, {}, form.data.create() )
}
form.wait( true );
Galaxy.emit.debug( 'tool-form-composite::postchange()', 'Sending current state.', current_state );
Utils.request({
type : 'POST',
url : Galaxy.root + 'api/tools/' + step.id + '/build',
data : current_state,
success : function( data ) {
form.update( data );
form.wait( false );
Galaxy.emit.debug( 'tool-form-composite::postchange()', 'Received new model.', data );
process.resolve();
},
error : function( response ) {
Galaxy.emit.debug( 'tool-form-composite::postchange()', 'Refresh request failed.', response );
process.reject();
}
});
};
form = new ToolFormBase( step );
if ( step.post_job_actions && step.post_job_actions.length ) {
form.portlet.append( $( '<div/>' ).addClass( 'ui-form-element-disabled' )
@@ -275,7 +306,7 @@ define([ 'utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view'
var is_simple_input = ([ 'data_input', 'data_collection_input' ]).indexOf( step.step_type ) != -1;
_.each( step.inputs, function( input ) { input.flavor = 'module'; input.hide_label = is_simple_input; } );
form = new Form( Utils.merge({
title : '<b>' + step.name + '</b>',
title : step.title,
onchange : function() { _.each( self.links[ step.index ], function( link ) { self._refreshStep( link ) } ) },
inputs : step.inputs && step.inputs.length > 0 ? step.inputs : [ { type: 'hidden', name: 'No options available.', ignore: null } ]
}, step ) );
@@ -420,7 +451,7 @@ define([ 'utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view'
Galaxy.emit.debug( 'tool-form-composite::submit', 'Submission successful.', response );
self.$el.children().hide();
self.$el.append( self._templateSuccess( response ) );
// Show Webhook if job is running
if ($.isArray( response ) && response.length > 0) {
self.$el.append( $( '<div/>', { id: 'webhook-view' } ) );
@@ -437,7 +468,7 @@ define([ 'utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view'
if ( response && response.err_data ) {
for ( var i in self.forms ) {
var form = self.forms[ i ];
var step_related_errors = response.err_data[ form.options.step_index ];
var step_related_errors = response.err_data[ form.model.get( 'step_index' ) ];
if ( step_related_errors ) {
var error_messages = form.data.matchResponse( step_related_errors );
for ( var input_id in error_messages ) {
+32 -6
View File
@@ -8,7 +8,8 @@ define([ 'utils/utils', 'mvc/ui/ui-misc', 'mvc/ui/ui-modal', 'mvc/tool/tool-form
this.form = new ToolFormBase( Utils.merge({
listen_to_history : true,
always_refresh : false,
customize : function( options ) {
customize : function( form ) {
var options = form.model.attributes;
// build execute button
options.buttons = {
execute: execute_btn = new Ui.Button({
@@ -19,17 +20,17 @@ define([ 'utils/utils', 'mvc/ui/ui-misc', 'mvc/ui/ui-modal', 'mvc/tool/tool-form
floating : 'clear',
onclick : function() {
execute_btn.wait();
self.form.portlet.disable();
form.portlet.disable();
self.submit( options, function() {
execute_btn.unwait();
self.form.portlet.enable();
form.portlet.enable();
} );
}
})
};
}
// remap feature
if ( options.job_id && options.job_remap ) {
options.inputs[ 'rerun_remap_job_id' ] = {
options.inputs.push({
label : 'Resume dependencies from this job',
name : 'rerun_remap_job_id',
type : 'select',
@@ -38,8 +39,33 @@ define([ 'utils/utils', 'mvc/ui/ui-misc', 'mvc/ui/ui-modal', 'mvc/tool/tool-form
value : '__ignore__',
options : [ [ 'Yes', options.job_id ], [ 'No', '__ignore__' ] ],
help : 'The previous run of this tool failed and other tools were waiting for it to finish successfully. Use this option to resume those tools using the new output(s) of this tool run.'
}
});
}
},
postchange : function( process, form ) {
var self = this;
var current_state = {
tool_id : form.model.get( 'id' ),
tool_version : form.model.get( 'version' ),
inputs : $.extend(true, {}, form.data.create())
}
form.wait( true );
Galaxy.emit.debug( 'tool-form::postchange()', 'Sending current state.', current_state );
Utils.request({
type : 'POST',
url : Galaxy.root + 'api/tools/' + form.model.get( 'id' ) + '/build',
data : current_state,
success : function( data ) {
form.update( data );
form.wait( false );
Galaxy.emit.debug( 'tool-form::postchange()', 'Received new model.', data );
process.resolve();
},
error : function( response ) {
Galaxy.emit.debug( 'tool-form::postchange()', 'Refresh request failed.', response );
process.reject();
}
});
}
}, options ) );
this.deferred = this.form.deferred;
+5
View File
@@ -124,6 +124,11 @@ define(['utils/utils',
.attr( 'placeholder', this.model.get( 'placeholder' ) )
.css( 'color', this.model.get( 'color' ) || '' )
.css( 'border-color', this.model.get( 'color' ) || '' );
var datalist = this.model.get( 'datalist' );
if ( $.isArray( datalist ) && datalist.length > 0 ) {
this.$el.autocomplete( { source : function( request, response ) { response( self.model.get( 'datalist' ) ) },
change : function() { self._onchange() } } );
}
if ( this.model.get( 'value' ) !== this.$el.val() ) {
this.$el.val( this.model.get( 'value' ) );
}
+10 -1
View File
@@ -15,7 +15,8 @@ var View = Backbone.View.extend({
operations : null,
collapsible : false,
collapsible_button : false,
collapsed : false
collapsed : false,
onchange_title : null
} ).set( options );
this.setElement( this._template() );
@@ -66,6 +67,14 @@ var View = Backbone.View.extend({
options.collapsed ? this.collapse() : this.expand();
}
// allow title editing
this.$title_text.prop( 'disabled', !options.onchange_title );
options.onchange_title && this.$title_text.make_text_editable({
on_finish: function( new_title ) {
options.onchange_title( new_title );
}
});
// render buttons
if ( options.buttons ) {
this.$buttons.empty().show();
@@ -221,7 +221,8 @@ var View = Backbone.View.extend({
hid : item.hid,
keep : item.keep,
label: item.hid + ': ' + item.name,
value: item.id
value: item.id,
tags : item.tags
});
self.history[ item.id + '_' + src ] = item;
});
@@ -109,6 +109,11 @@ var View = Backbone.View.extend({
}
},
/** Matches a search term with a given text */
_match: function( term, text ) {
return !term || term == '' || String( text ).toUpperCase().indexOf( term.toUpperCase() ) >= 0
},
/** Updates the selection options */
_changeData: function() {
var self = this;
@@ -125,22 +130,44 @@ var View = Backbone.View.extend({
if ( this.model.get( 'searchable' ) ) {
this.data2 = [];
_.each( this.data, function( option, index ) {
self.data2.push( { order: index, id: option.value, text: option.label } );
self.data2.push( { order: index, id: option.value, text: option.label, tags: option.tags } );
});
this.$select.data( 'select2' ) && this.$select.select2( 'destroy' );
this.matched_tags = {};
this.$select.select2({
data : self.data2,
closeOnSelect : !this.model.get( 'multiple' ),
multiple : this.model.get( 'multiple' ),
query : function( q ) {
self.matched_tags = {};
var pagesize = self.model.get( 'pagesize' );
var results = _.filter( self.data2, function ( e ) {
return !q.term || q.term == '' || e.text.toUpperCase().indexOf( q.term.toUpperCase() ) >= 0;
var found = false;
_.each( e.tags, function( tag ) {
if ( self._match( q.term, tag ) ) {
found = self.matched_tags[ tag ] = true;
}
});
return found || self._match( q.term, e.text );
});
q.callback({
results: results.slice( ( q.page - 1 ) * pagesize, q.page * pagesize ),
more : results.length >= q.page * pagesize
});
},
formatResult : function( result ) {
return _.escape( result.text ) +
'<div class="ui-tags">' +
_.reduce( result.tags, function( memo, tag ) {
if ( self.matched_tags[ tag ] ) {
return memo + '&nbsp;' +
'<div class="label label-info">' +
_.escape( tag ) +
'</div>'
}
return memo;
}, '' ) +
'</div>';
}
});
this.$( '.select2-container .select2-search input' ).off( 'blur' );
@@ -106,7 +106,7 @@ define( [ 'utils/utils' ], function( Utils ) {
_templateRow: function( options ) {
return '<tr class="upload-ftp-row">' +
'<td class="_has_collection" style="display: none;"><div class="icon"/></td>' +
'<td class="ftp-name">' + options.path + '</td>' +
'<td class="ftp-name">' + _.escape(options.path) + '</td>' +
'<td class="ftp-size">' + Utils.bytesToString( options.size ) + '</td>' +
'<td class="ftp-time">' + options.ctime + '</td>' +
'</tr>';
@@ -128,8 +128,8 @@ var UserQuotaMeter = Backbone.View.extend( baseMVC.LoggableMixin ).extend(
return [
'<div id="quota-meter" class="quota-meter progress">',
'<div class="progress-bar" style="width: ', data.quota_percent, '%"></div>',
'<div class="quota-meter-text" style="top: 6px"',
(( data.nice_total_disk_usage )?( ' title="Using ' + data.nice_total_disk_usage + '">' ):( '>' )),
'<div class="quota-meter-text" data-placement="left" style="top: 6px"',
(( data.nice_total_disk_usage )?( ' title="Using ' + data.nice_total_disk_usage + '. This value is recalculated when you log out.">' ):( '>' )),
_l( 'Using' ), ' ', data.quota_percent, '%',
'</div>',
'</div>'
@@ -139,7 +139,7 @@ var UserQuotaMeter = Backbone.View.extend( baseMVC.LoggableMixin ).extend(
_templateUsage : function( data ){
return [
'<div id="quota-meter" class="quota-meter" style="background-color: transparent">',
'<div class="quota-meter-text" style="top: 6px; color: white">',
'<div class="quota-meter-text" data-placement="left" data-original-title="This value is recalculated when you log out." style="top: 6px; color: white">',
(( data.nice_total_disk_usage )?( _l( 'Using ' ) + data.nice_total_disk_usage ):( '' )),
'</div>',
'</div>'
@@ -157,7 +157,7 @@ define([], function() {
y = position.top / in_h * o_h,
w = node_element.width() / in_w * o_w,
h = node_element.height() / in_h * o_h;
if (node.tool_errors){
if (node.errors){
c.fillStyle = "#FFCCCC";
c.strokeStyle = "#AA6666";
} else if (node.workflow_outputs !== undefined && node.workflow_outputs.length > 0){
@@ -1,12 +1,18 @@
/** This is the workflow tool form. */
define( [ 'utils/utils', 'mvc/tool/tool-form-base' ],
function( Utils, ToolFormBase ) {
var View = Backbone.View.extend({
define( [ 'utils/utils', 'mvc/form/form-view', 'mvc/tool/tool-form-base' ], function( Utils, Form, ToolFormBase ) {
/** Default form wrapper for non-tool modules in the workflow editor. */
var Default = Backbone.View.extend({
initialize: function( options ) {
this.form = new Form( options );
}
});
/** Tool form wrapper for the workflow editor. */
var Tool = Backbone.View.extend({
initialize: function( options ) {
var self = this;
this.workflow = options.workflow;
this.node = options.node;
this.setElement( '<div/>' );
if ( this.node ) {
this.post_job_actions = this.node.post_job_actions || {};
Utils.deepeach( options.inputs, function( input ) {
@@ -15,7 +21,7 @@ define( [ 'utils/utils', 'mvc/tool/tool-form-base' ],
input.type = 'hidden';
input.info = 'Data input \'' + input.name + '\' (' + Utils.textify( input.extensions ) + ')';
input.value = { '__class__': 'RuntimeValue' };
} else {
} else if ( !input.fixed ) {
input.collapsible_value = { '__class__': 'RuntimeValue' };
input.is_workflow = ( input.options && input.options.length == 0 ) ||
( [ 'integer', 'float' ].indexOf( input.type ) != -1 );
@@ -33,17 +39,37 @@ define( [ 'utils/utils', 'mvc/tool/tool-form-base' ],
initial_errors : true,
sustain_version : true,
cls : 'ui-portlet-narrow',
update_url : Galaxy.root + 'api/workflows/build_module',
update : function( data ) {
// This hasn't modified the workflow, just returned
// module information for the tool to update the workflow
// state stored on the client with. User needs to save
// for this to take effect.
self.node.update_field_data( data );
self.form.errors( data && data.tool_model );
}
postchange : function( process, form ) {
var options = form.model.attributes;
var current_state = {
tool_id : options.id,
tool_version : options.version,
type : 'tool',
inputs : $.extend( true, {}, form.data.create() )
}
Galaxy.emit.debug( 'tool-form-workflow::postchange()', 'Sending current state.', current_state );
Utils.request({
type : 'POST',
url : Galaxy.root + 'api/workflows/build_module',
data : current_state,
success : function( data ) {
form.update( data.config_form );
form.errors( data.config_form );
// This hasn't modified the workflow, just returned
// module information for the tool to update the workflow
// state stored on the client with. User needs to save
// for this to take effect.
self.node.update_field_data( data );
Galaxy.emit.debug( 'tool-form-workflow::postchange()', 'Received new model.', data );
process.resolve();
},
error : function( response ) {
Galaxy.emit.debug( 'tool-form-workflow::postchange()', 'Refresh request failed.', response );
process.reject();
}
});
},
}));
this.$el.append( this.form.$el );
} else {
Galaxy.emit.debug('tool-form-workflow::initialize()', 'Node not found in workflow.');
}
@@ -53,17 +79,9 @@ define( [ 'utils/utils', 'mvc/tool/tool-form-base' ],
_makeSections: function( options ){
var inputs = options.inputs;
var datatypes = options.datatypes;
inputs[ Utils.uid() ] = {
label : 'Annotation / Notes',
name : 'annotation',
type : 'text',
area : true,
help : 'Add an annotation or note for this step. It will be shown with the workflow.',
value : this.node.annotation
}
var output_id = this.node.output_terminals && Object.keys( this.node.output_terminals )[ 0 ];
if ( output_id ) {
inputs[ Utils.uid() ] = {
inputs.push({
name : 'pja__' + output_id + '__EmailAction',
label : 'Email notification',
type : 'boolean',
@@ -73,17 +91,17 @@ define( [ 'utils/utils', 'mvc/tool/tool-form-base' ],
payload : {
'host' : window.location.host
}
};
inputs[ Utils.uid() ] = {
});
inputs.push({
name : 'pja__' + output_id + '__DeleteIntermediatesAction',
label : 'Output cleanup',
type : 'boolean',
value : String( Boolean( this.post_job_actions[ 'DeleteIntermediatesAction' + output_id ] ) ),
ignore : 'false',
help : 'Upon completion of this step, delete non-starred outputs from completed workflow steps if they are no longer required as inputs.'
};
});
for ( var i in this.node.output_terminals ) {
inputs[ Utils.uid() ] = this._makeSection( i, datatypes );
inputs.push( this._makeSection( i, datatypes ) );
}
}
},
@@ -235,6 +253,7 @@ define( [ 'utils/utils', 'mvc/tool/tool-form-base' ],
});
return {
View: View
Default: Default,
Tool: Tool
};
});
@@ -11,47 +11,9 @@ function( Connector, Toastr ) {
this.name = null;
this.has_changes = false;
this.active_form_has_changes = false;
this.nodeLabels = {};
this.workflowOutputLabels = {};
}
$.extend( Workflow.prototype, {
canLabelNodeWith: function( label ) {
if( label ) {
return ! (label in this.nodeLabels);
} else {
// empty labels are non-exclusive, so allow this one.
return true;
}
},
registerNodeLabel: function( label ) {
if( label ) {
this.nodeLabels[label] = true;
}
},
unregisterNodeLabel: function( label ) {
if( label ) {
delete this.nodeLabels[label];
}
},
updateNodeLabel: function( fromLabel, toLabel ) {
if( fromLabel ) {
this.unregisterNodeLabel( fromLabel );
}
if( ! this.canLabelNodeWith( toLabel ) ) {
Toastr.warning("Workflow contains duplicate node labels " + toLabel + ". This must be fixed before it can be saved.");
}
if( toLabel ) {
this.registerNodeLabel( toLabel );
}
},
attemptUpdateNodeLabel: function( node, label ) {
if( this.canLabelNodeWith( label ) ) {
node.setLabel( label );
return true;
} else {
return false;
}
},
canLabelOutputWith: function( label ) {
if( label ) {
return ! (label in this.workflowOutputLabels);
@@ -189,13 +151,15 @@ function( Connector, Toastr ) {
// really a sneaky if statement
var cons = []
$.each( t.connectors, function ( i, c ) {
var con_dict = { id: c.handle1.node.id, output_name: c.handle1.name };
var input_subworkflow_step_id = t.attributes.input.input_subworkflow_step_id;
if( input_subworkflow_step_id !== undefined ) {
con_dict["input_subworkflow_step_id"] = input_subworkflow_step_id;
if ( c.handle1 ) {
var con_dict = { id: c.handle1.node.id, output_name: c.handle1.name };
var input_subworkflow_step_id = t.attributes.input.input_subworkflow_step_id;
if( input_subworkflow_step_id !== undefined ) {
con_dict["input_subworkflow_step_id"] = input_subworkflow_step_id;
}
cons[i] = con_dict;
input_connections[ t.name ] = cons;
}
cons[i] = con_dict;
input_connections[ t.name ] = cons;
});
});
var post_job_actions = {};
@@ -219,7 +183,7 @@ function( Connector, Toastr ) {
type : node.type,
content_id : node.content_id,
tool_state : node.tool_state,
tool_errors : node.tool_errors,
errors : node.errors,
input_connections : input_connections,
position : $(node.element).position(),
annotation: node.annotation,
@@ -328,13 +292,13 @@ function( Connector, Toastr ) {
this.active_node.make_inactive();
this.active_node = null;
}
this.app.showToolForm( "<div>No node selected</div>", {id: 'no-node'} );
this.app.showAttributes();
},
activate_node : function( node ) {
if ( this.active_node != node ) {
this.check_changes_in_active_form();
this.clear_active_node();
this.app.showToolForm( node.form_html, node );
this.app.showForm( node.config_form, node );
node.make_active();
this.active_node = node;
}
@@ -344,8 +308,9 @@ function( Connector, Toastr ) {
if ( this.active_node == node && force ) {
// Force changes to be saved even on new connection (previously dumped)
this.check_changes_in_active_form();
this.app.showToolForm( node.form_html, node );
this.app.showForm( node.config_form, node );
}
this.app.showWorkflowParameters();
},
layout : function () {
this.check_changes_in_active_form();
@@ -5,7 +5,7 @@ define(['mvc/workflow/workflow-view-node'], function( NodeView ) {
this.element = attr.element;
this.input_terminals = {};
this.output_terminals = {};
this.tool_errors = {};
this.errors = {};
this.workflow_outputs = [];
},
getWorkflowOutput: function(outputName) {
@@ -148,32 +148,26 @@ define(['mvc/workflow/workflow-view-node'], function( NodeView ) {
// Remove active class
$(element).removeClass( "toolForm-active" );
},
setLabel: function(label) {
this.app.workflow.updateNodeLabel(this.label, label);
this.label = label || null;
},
init_field_data : function ( data ) {
if ( data.type ) {
this.type = data.type;
}
this.name = data.name;
this.form_html = data.form_html;
this.config_form = data.config_form;
this.tool_state = data.tool_state;
this.tool_errors = data.tool_errors;
this.errors = data.errors;
this.tooltip = data.tooltip ? data.tooltip : "";
this.annotation = data.annotation;
this.post_job_actions = data.post_job_actions ? data.post_job_actions : {};
this.setLabel(data.label);
this.label = data.label;
this.uuid = data.uuid;
this.workflow_outputs = data.workflow_outputs ? data.workflow_outputs : [];
var node = this;
var nodeView = new NodeView({
el: this.element[ 0 ],
node: node,
});
node.nodeView = nodeView;
$.each( data.data_inputs, function( i, input ) {
nodeView.addDataInput( input );
});
@@ -188,16 +182,15 @@ define(['mvc/workflow/workflow-view-node'], function( NodeView ) {
},
update_field_data : function( data ) {
var node = this;
nodeView = node.nodeView;
var nodeView = node.nodeView;
this.tool_state = data.tool_state;
this.form_html = data.form_html;
this.tool_errors = data.tool_errors;
this.config_form = data.config_form;
this.errors = data.errors;
this.annotation = data['annotation'];
this.setLabel(data.label);
this.label = data.label;
if( "post_job_actions" in data ) {
// Won't be present in response for data inputs
var pja_in = $.parseJSON(data.post_job_actions);
var pja_in = data.post_job_actions;
this.post_job_actions = pja_in ? pja_in : {};
}
node.nodeView.renderToolErrors();
@@ -223,13 +216,11 @@ define(['mvc/workflow/workflow-view-node'], function( NodeView ) {
nodeView.updateDataOutput( data.data_outputs[ 0 ] );
}
old_body.replaceWith( new_body );
if( "workflow_outputs" in data ) {
// Won't be present in response for data inputs
this.workflow_outputs = workflow_outputs ? workflow_outputs : [];
}
// If active, reactivate with new form_html
// If active, reactivate with new config_form
this.markChanged();
this.redraw();
},
@@ -237,7 +228,7 @@ define(['mvc/workflow/workflow-view-node'], function( NodeView ) {
var b = $(this.element).find( ".toolFormBody" );
b.find( "div" ).remove();
var tmp = "<div style='color: red; text-style: italic;'>" + text + "</div>";
this.form_html = tmp;
this.config_form = tmp;
b.html( tmp );
this.app.workflow.node_changed( this );
},
@@ -21,7 +21,7 @@ define(['libs/underscore', 'mvc/workflow/workflow-view-terminals', 'mvc/workflow
},
renderToolErrors: function() {
this.node.tool_errors ? this.$el.addClass( 'tool-node-error' ) : this.$el.removeClass( 'tool-node-error' );
this.node.errors ? this.$el.addClass( 'tool-node-error' ) : this.$el.removeClass( 'tool-node-error' );
},
newInputsDiv: function() {
@@ -6,160 +6,54 @@ define([
'mvc/workflow/workflow-canvas',
'mvc/workflow/workflow-node',
'mvc/workflow/workflow-icons',
'mvc/tool/tool-form-workflow',
'mvc/workflow/workflow-forms',
'mvc/ui/ui-misc',
'utils/async-save-text',
'libs/toastr',
'ui/editable-text'
], function( Utils, Globals, Workflow, WorkflowCanvas, Node, WorkflowIcons, ToolForm, Ui, async_save_text, Toastr ){
], function( Utils, Globals, Workflow, WorkflowCanvas, Node, WorkflowIcons, FormWrappers, Ui, async_save_text, Toastr ){
// Reset tool search to start state.
function reset_tool_search( initValue ) {
// Function may be called in top frame or in tool_menu_frame;
// in either case, get the tool menu frame.
var tool_menu_frame = $("#galaxy_tools").contents();
if (tool_menu_frame.length === 0) {
tool_menu_frame = $(document);
}
// Reset tool search to start state.
function reset_tool_search( initValue ) {
// Function may be called in top frame or in tool_menu_frame;
// in either case, get the tool menu frame.
var tool_menu_frame = $("#galaxy_tools").contents();
if (tool_menu_frame.length === 0) {
tool_menu_frame = $(document);
// Remove classes that indicate searching is active.
$(this).removeClass("search_active");
tool_menu_frame.find(".toolTitle").removeClass("search_match");
// Remove classes that indicate searching is active.
$(this).removeClass("search_active");
tool_menu_frame.find(".toolTitle").removeClass("search_match");
// Reset visibility of tools and labels.
tool_menu_frame.find(".toolSectionBody").hide();
tool_menu_frame.find(".toolTitle").show();
tool_menu_frame.find(".toolPanelLabel").show();
tool_menu_frame.find(".toolSectionWrapper").each( function() {
if ($(this).attr('id') !== 'recently_used_wrapper') {
// Default action.
$(this).show();
} else if ($(this).hasClass("user_pref_visible")) {
$(this).show();
}
});
tool_menu_frame.find("#search-no-results").hide();
// Reset search input.
tool_menu_frame.find("#search-spinner").hide();
if (initValue) {
var search_input = tool_menu_frame.find("#tool-search-query");
search_input.val("search tools");
}
}
add_node_icon = function($to_el, nodeType) {
var iconStyle = WorkflowIcons[nodeType];
if(iconStyle) {
var $icon = $('<i class="icon fa">&nbsp;</i>').addClass(iconStyle);
$to_el.before($icon);
}
}
// Really a shell of a real backbone view, but refactoring in the right
// direction I think.
EditorFormView = Backbone.View.extend({
initialize: function(options) {
var self = this;
this.options = Utils.merge(options, {});
var $el = $('<div/>'),
workflowView = options.workflowView,
node = options.node;
if(options.html) {
$el.html(options.html);
}
this.setElement($el);
if (node && node.id != 'no-node') {
$el.find('table:first').after(this._genericStepAttributesTemplate( node ));
var nodeType = node.type;
add_node_icon($el.find('.portlet-title-text'), nodeType);
var $titleText = $el.find(".portlet-title-text");
$titleText.data('last-value', $titleText.text());
$titleText.make_text_editable({
on_finish: function( newLabel ){
var lastValue = $titleText.data("last-value");
if( newLabel == lastValue ) {
return;
}
var workflow = workflowView.workflow;
if( workflow.attemptUpdateNodeLabel( node, newLabel ) ) {
$el.find("input[name='label']").val(newLabel);
$titleText.data("last-value", newLabel);
$el.find('form').submit();
if(newLabel == "") {
// If label unset restore default name as title.
$titleText.text(node.name);
}
} else {
Toastr.warning("Step label " + newLabel + " already exists, cannot update label.");
$titleText.text(lastValue);
}
// Reset visibility of tools and labels.
tool_menu_frame.find(".toolSectionBody").hide();
tool_menu_frame.find(".toolTitle").show();
tool_menu_frame.find(".toolPanelLabel").show();
tool_menu_frame.find(".toolSectionWrapper").each( function() {
if ($(this).attr('id') !== 'recently_used_wrapper') {
// Default action.
$(this).show();
} else if ($(this).hasClass("user_pref_visible")) {
$(this).show();
}
});
($el.find( 'form' ).length > 0) && $el.find( 'form' ).ajaxForm( {
type: 'POST',
dataType: 'json',
success: function( data ) {
workflowView.workflow.active_form_has_changes = false;
node.update_field_data( data );
workflowView.showWorkflowParameters();
},
beforeSubmit: function( data ) {
data.push( { name: 'content_id', value: node.content_id } );
data.push( { name: 'tool_state', value: node.tool_state } );
data.push( { name: '_', value: 'true' } );
}
}).each( function() {
var form = this;
$(this).find('select[refresh_on_change="true"]').change( function() {
$(form).submit();
});
$(this).find('input[refresh_on_change="true"]').change( function() {
$(form).submit();
});
$(this).find('input, textarea, select').each( function() {
$(this).bind('focus click', function() {
workflowView.workflow.active_form_has_changes = true;
});
});
});
tool_menu_frame.find("#search-no-results").hide();
// Reset search input.
tool_menu_frame.find("#search-spinner").hide();
if (initValue) {
var search_input = tool_menu_frame.find("#tool-search-query");
search_input.val("search tools");
}
}
}
},
_genericStepAttributesTemplate: function( node ) {
return '<p>' +
'<div class="metadataForm">' +
'<div class="metadataFormTitle">' +
'Edit Step Attributes' +
'</div>' +
this._annotationTemplate(node) +
'</div>' +
'</p>';
},
_annotationTemplate: function( node ){
return '<div class="form-row">' +
'<label>Annotation / Notes:</label>' +
'<div style="margin-right: 10px;">' +
'<textarea name="annotation" rows="3" style="width: 100%">' +
node.annotation +
'</textarea>' +
'<div class="toolParamHelp">' +
'Add an annotation or notes to this step; annotations are available when a workflow is viewed.' +
'</div>' +
'</div>' +
'</div>';
},
});
add_node_icon = function($to_el, nodeType) {
var iconStyle = WorkflowIcons[nodeType];
if(iconStyle) {
var $icon = $('<i class="icon fa">&nbsp;</i>').addClass(iconStyle);
$to_el.before($icon);
}
}
// create form view
return Backbone.View.extend({
@@ -167,7 +61,6 @@ EditorFormView = Backbone.View.extend({
var self = Globals.app = this;
this.options = options;
this.urls = options && options.urls || {};
this.active_ajax_call = false;
var close_editor = function() {
self.workflow.check_changes_in_active_form();
if ( workflow && self.workflow.has_changes ) {
@@ -200,56 +93,37 @@ EditorFormView = Backbone.View.extend({
return;
}
self.workflow.rectify_workflow_outputs();
var savefn = function(callback) {
$.ajax( {
url: self.urls.save_workflow,
type: "POST",
data: {
id: self.options.id,
workflow_data: function() { return JSON.stringify( self.workflow.to_simple() ); },
"_": "true"
},
dataType: 'json',
success: function( data ) {
var body = $("<div></div>").text( data.message );
if ( data.errors ) {
body.addClass( "warningmark" );
var errlist = $( "<ul/>" );
$.each( data.errors, function( i, v ) {
$("<li></li>").text( v ).appendTo( errlist );
});
body.append( errlist );
} else {
body.addClass( "donemark" );
}
self.workflow.name = data.name;
self.workflow.has_changes = false;
self.workflow.stored = true;
self.showWorkflowParameters();
if ( data.errors ) {
window.show_modal( "Saving workflow", body, { "Ok" : hide_modal } );
} else {
if (callback) {
callback();
}
hide_modal();
}
Utils.request( {
url: Galaxy.root + 'api/workflows/' + self.options.id,
type: "PUT",
data: { workflow: self.workflow.to_simple() },
success: function( data ) {
var body = $( "<div/>" ).text( data.message );
if ( data.errors ) {
body.addClass( "warningmark" );
var errlist = $( "<ul/>" );
$.each( data.errors, function( i, v ) {
$( "<li/>" ).text( v ).appendTo( errlist );
});
body.append( errlist );
} else {
body.addClass( "donemark" );
}
});
};
// We bind to ajaxStop because of auto-saving, since the form submission ajax
// call needs to be completed so that the new data is saved
if (self.active_ajax_call) {
$(document).bind('ajaxStop.save_workflow', function() {
$(document).unbind('ajaxStop.save_workflow');
savefn();
$(document).unbind('ajaxStop.save_workflow'); // IE7 needs it here
self.active_ajax_call = false;
});
} else {
savefn(success_callback);
}
self.workflow.name = data.name;
self.workflow.has_changes = false;
self.workflow.stored = true;
self.showWorkflowParameters();
if ( data.errors ) {
window.show_modal( "Saving workflow", body, { "Ok" : hide_modal } );
} else {
success_callback && success_callback();
hide_modal();
}
},
error: function( response ) {
window.show_modal( "Saving workflow failed.", response.err_msg, { "Ok" : hide_modal } );
}
});
};
// Init searching.
@@ -354,9 +228,12 @@ EditorFormView = Backbone.View.extend({
self.canvas_manager.draw_overview();
// Determine if any parameters were 'upgraded' and provide message
upgrade_message = "";
_.each( data.upgrade_messages, function( messages, step_id ) {
_.each( data.steps, function( step, step_id ) {
var details = "";
_.each( messages, function( m ) {
if ( step.errors ) {
details += "<li>" + step.errors + "</li>";
}
_.each( data.upgrade_messages[ step_id ], function( m ) {
details += "<li>" + m + "</li>";
});
if ( details ) {
@@ -364,9 +241,7 @@ EditorFormView = Backbone.View.extend({
}
});
if ( upgrade_message ) {
window.show_modal( "Workflow loaded with changes",
"Problems were encountered loading this workflow (possibly a result of tool upgrades). Please review the following parameters and then save.<ul>" + upgrade_message + "</ul>",
{ "Continue" : hide_modal } );
window.show_modal( "Issues loading this workflow", "Please review the following issues, possibly resulting from tool upgrades or changes.<p><ul>" + upgrade_message + "</ul></p>", { "Continue" : hide_modal } );
} else {
hide_modal();
}
@@ -377,32 +252,14 @@ EditorFormView = Backbone.View.extend({
}
});
// For autosave purposes
$(document).ajaxStart( function() {
self.active_ajax_call = true;
$(document).bind( "ajaxStop.global", function() {
self.active_ajax_call = false;
});
});
$(document).ajaxError( function ( e, x ) {
// console.log( e, x );
var message = x.responseText || x.statusText || "Could not connect to server";
window.show_modal( "Server error", message, { "Ignore error" : hide_modal } );
return false;
});
window.make_popupmenu && make_popupmenu( $("#workflow-options-button"), {
"Save" : save_current_workflow,
"Save As": workflow_save_as,
"Run": function() {
window.location = self.urls.run_workflow;
},
//"Create New" : create_new_workflow_dialog,
"Edit Attributes" : edit_workflow_attributes,
//"Edit Workflow Outputs": edit_workflow_outputs,
"Edit Attributes" : function() { self.workflow.clear_active_node() },
"Auto Re-layout": layout_editor,
//"Load a Workflow" : load_workflow,
"Close": close_editor
});
@@ -424,7 +281,7 @@ EditorFormView = Backbone.View.extend({
}
}).done(function(id){
window.onbeforeunload = undefined;
window.location = "/workflow/editor?id=" + id;
window.location = Galaxy.root + "workflow/editor?id=" + id;
hide_modal();
}).fail(function(){
hide_modal();
@@ -445,7 +302,6 @@ EditorFormView = Backbone.View.extend({
new_content += "<div class='toolForm' style='margin-bottom:5px;'><div class='toolFormTitle'>Step " + node.id + " - " + node.name + "</div>";
for (var ot_key in node.output_terminals){
var output = node.output_terminals[ot_key];
// if (node.workflow_outputs[node.id + "|" + output.name]){
if (node.isWorkflowOutput(output.name)) {
new_content += "<p>"+output.name +"<input type='checkbox' name='"+ node.id + "|" + output.name +"' checked /></p>";
}
@@ -478,12 +334,6 @@ EditorFormView = Backbone.View.extend({
self.canvas_manager.draw_overview();
}
function edit_workflow_attributes() {
self.workflow.clear_active_node();
$('.right-content').hide();
$('#edit-attributes').show();
}
// On load, set the size to the pref stored in local storage if it exists
overview_size = $.jStorage.get("overview-size");
if (overview_size !== undefined) {
@@ -673,20 +523,15 @@ EditorFormView = Backbone.View.extend({
},
_moduleInitAjax: function(node, request_data) {
$.ajax( {
url: this.urls.get_new_module_info,
data: request_data,
global: false,
dataType: "json",
success: function( data ) {
var self = this;
Utils.request({
type : 'POST',
url : Galaxy.root + 'api/workflows/build_module',
data : request_data,
success : function( data ) {
node.init_field_data( data );
},
error: function( x, e ) {
var m = "error loading field data";
if ( x.status === 0 ) {
m += ", server unavailable";
}
node.error( m );
node.update_field_data( data );
self.workflow.activate_node( node );
}
});
},
@@ -694,7 +539,7 @@ EditorFormView = Backbone.View.extend({
// Add a new step to the workflow by tool id
add_node_for_tool: function ( id, title ) {
node = this.workflow.create_node( 'tool', title, id );
this._moduleInitAjax(node, { type: "tool", content_id: id, "_": "true" });
this._moduleInitAjax(node, { type: "tool", tool_id: id, "_": "true" });
},
// Add a new step to the workflow by tool id
@@ -756,14 +601,20 @@ EditorFormView = Backbone.View.extend({
showWorkflowParameters: function () {
var parameter_re = /\$\{.+?\}/g;
var workflow_parameters = [];
var wf_parm_container = $("#workflow-parameters-container");
var wf_parm_box = $("#workflow-parameters-box");
var new_parameter_content = "";
var wf_parm_container = $( '#workflow-parameters-container' );
var wf_parm_box = $( '#workflow-parameters-box' );
var new_parameter_content = '';
var matches = [];
$.each(this.workflow.nodes, function (k, node){
var form_matches = node.form_html.match(parameter_re);
if (form_matches){
matches = matches.concat(form_matches);
$.each(this.workflow.nodes, function ( k, node ){
if ( node.config_form && node.config_form.inputs ) {
Utils.deepeach( node.config_form.inputs, function( d ) {
if ( typeof d.value == 'string' ) {
var form_matches = d.value.match( parameter_re );
if ( form_matches ) {
matches = matches.concat( form_matches );
}
}
});
}
if (node.post_job_actions){
$.each(node.post_job_actions, function(k, pja){
@@ -776,13 +627,13 @@ EditorFormView = Backbone.View.extend({
});
}
});
if (matches){
$.each(matches, function(k, element){
if ($.inArray(element, workflow_parameters) === -1){
workflow_parameters.push(element);
}
});
}
}
if (matches){
$.each(matches, function(k, element){
if ($.inArray(element, workflow_parameters) === -1){
workflow_parameters.push(element);
}
});
}
});
if (workflow_parameters && workflow_parameters.length !== 0){
@@ -797,47 +648,80 @@ EditorFormView = Backbone.View.extend({
}
},
showToolForm: function ( text, node ) {
// initialize tags and identifiers
showAttributes: function() {
$( '.right-content' ).hide();
$( '#edit-attributes' ).show();
},
showForm: function ( content, node ) {
var self = this;
var cls = 'right-content';
var id = cls + '-' + node.id;
// grab panel container
var $container = $('#' + cls);
// remove previous notifications
var $current = $container.find('#' + id);
if ($current.length > 0 && $current.find('.section-row').length == 0) {
$current.remove();
}
// check if tool form already exists
if ($container.find('#' + id).length == 0) {
var $el = $('<div id="' + id + '" class="' + cls + '"/>');
var formView = null;
if (node.type == 'tool' && Utils.isJSON(text)) {
var options = JSON.parse(text);
options.node = node;
options.workflow = this.workflow;
options.datatypes = this.datatypes;
formView = new ToolForm.View(options);
var $container = $( '#' + cls );
if ( content && $container.find( '#' + id ).length == 0 ) {
var $el = $( '<div id="' + id + '" class="' + cls + '"/>' );
var form_wrapper = null;
content.node = node;
content.workflow = this.workflow;
content.datatypes = this.datatypes;
content.icon = WorkflowIcons[ node.type ];
content.cls = 'ui-portlet-narrow';
content.inputs.unshift({
type : 'text',
name : '__annotation',
label : 'Annotation',
fixed : true,
value : node.annotation,
area : true,
help : 'Add an annotation or notes to this step. Annotations are available when a workflow is viewed.'
});
content.inputs.unshift({
type : 'text',
name : '__label',
label : 'Label',
value : node.label,
help : 'Add a step label.',
fixed : true,
onchange: function( new_label ) {
var duplicate = false;
for ( var i in self.workflow.nodes ) {
var n = self.workflow.nodes[ i ];
if ( n.label && n.label == new_label && n.id != node.id ) {
duplicate = true;
break;
}
}
var input_id = form_wrapper.form.data.match( '__label' );
var input_element = form_wrapper.form.element_list[ input_id ];
input_element.model.set( 'error_text', duplicate && 'Duplicate label. Please fix this before saving the workflow.' );
form_wrapper.form.trigger( 'change' );
}
});
content.onchange = function() {
Utils.request({
type : 'POST',
url : Galaxy.root + 'api/workflows/build_module',
data : {
id : node.id,
type : node.type,
content_id : node.content_id,
inputs : form_wrapper.form.data.create()
},
success : function( data ) {
node.update_field_data( data );
}
});
};
if ( node.type == 'tool' ) {
form_wrapper = new FormWrappers.Tool( content );
} else {
var options = {
html: text,
node: node,
workflowView: this
};
formView = new EditorFormView(options);
form_wrapper = new FormWrappers.Default( content );
}
$el.append(formView.$el);
$container.append($el);
$el.append( form_wrapper.form.$el );
$container.append( $el );
}
// hide everything
$('.' + cls).hide();
// show current form
$container.find('#' + id).show();
$( '.' + cls ).hide();
$container.find( '#' + id ).show();
$container.show();
$container.scrollTop();
},
@@ -848,27 +732,20 @@ EditorFormView = Backbone.View.extend({
return ( this.type_to_type[child] ) && ( parent in this.type_to_type[child] );
},
$newNodeElement: function(type, title_text) {
var $f = $("<div class='toolForm toolFormInCanvas'></div>");
prebuildNode: function ( type, title_text, content_id ) {
var self = this;
var $f = $("<div class='toolForm toolFormInCanvas'/>");
var $title = $("<div class='toolFormTitle unselectable'><span class='nodeTitle'>" + title_text + "</div></div>" );
add_node_icon($title.find('.nodeTitle'), type);
$f.append( $title );
$f.css( "left", $(window).scrollLeft() + 20 );
$f.css( "top", $(window).scrollTop() + 20 );
var $b = $("<div class='toolFormBody'></div>");
$f.append($b);
return $f
},
prebuildNode: function ( type, title_text, content_id ) {
var self = this;
var $f = this.$newNodeElement( type, title_text );
$f.append($("<div class='toolFormBody'></div>"));
var node = new Node( this, { element: $f } );
node.type = type;
node.content_id = content_id;
var tmp = "<div><img height='16' align='middle' src='" + Galaxy.root + "static/images/loading_small_white_bg.gif'/> loading tool info...</div>";
$f.find(".toolFormBody").append(tmp);
node.form_html = tmp;
// Fix width to computed width
// Now add floats
var buttons = $("<div class='buttons' style='float: right;'></div>");
+1 -1
View File
@@ -194,7 +194,7 @@ jQuery.fn.autocomplete_tagging = function(options) {
};
var autocomplete_options = { selectFirst: false, formatItem: format_item_func,
autoFill: false, highlight: false };
tag_input_field.autocomplete(settings.ajax_autocomplete_tag_url, autocomplete_options);
tag_input_field.autocomplete_verheul(settings.ajax_autocomplete_tag_url, autocomplete_options);
// Initialize delete tag images for current tags.
+10 -5
View File
@@ -1222,18 +1222,23 @@ extend( TracksterView.prototype, DrawableCollection.prototype, {
view.reference_track = ref_track;
}
view.chrom_data = result.chrom_info;
var chrom_options = '<option value="">Select Chrom/Contig</option>';
view.chrom_select.html('');
view.chrom_select.append($('<option value="">Select Chrom/Contig</option>'));
for (var i = 0, len = view.chrom_data.length; i < len; i++) {
var chrom = view.chrom_data[i].chrom;
chrom_options += '<option value="' + chrom + '">' + chrom + '</option>';
var chrom_option = $("<option>");
chrom_option.text(chrom);
chrom_option.val(chrom);
view.chrom_select.append(chrom_option);
}
if (result.prev_chroms) {
chrom_options += '<option value="previous">Previous ' + MAX_CHROMS_SELECTABLE + '</option>';
view.chrom_select.append($('<option value="previous">Previous ' + MAX_CHROMS_SELECTABLE + '</option>'));
}
if (result.next_chroms) {
chrom_options += '<option value="next">Next ' + MAX_CHROMS_SELECTABLE + '</option>';
view.chrom_select.append($('<option value="next">Next ' + MAX_CHROMS_SELECTABLE + '</option>'));
}
view.chrom_select.html(chrom_options);
view.chrom_start_index = result.start_index;
chrom_data.resolve(result.chrom_info);
+1 -1
View File
@@ -592,7 +592,6 @@ div.toolHelpBody {
}
}
div.form, div.toolForm {
border: solid @form-border 1px;
.border-radius(@panel-border-radius);
@@ -604,6 +603,7 @@ div.form-title, div.toolFormTitle {
padding: 5px 10px;
background: @form-heading-bg;
border-bottom: solid @form-border 1px;
word-wrap:break-word;
}
div.form-body {
+7
View File
@@ -221,6 +221,13 @@
}
}
}
span.nametags {
span.label {
display: inline-block;
margin-right: 2px;
text-decoration: none;
}
}
}
}
+5
View File
@@ -68,6 +68,11 @@
font-weight: bold;
}
.ui-tags {
word-wrap: break-word;
padding-right: 25px;
}
.ui-message {
padding: 2px 10px 2px 10px;
margin-top: @ui-margin-vertical-large;
+22
View File
@@ -0,0 +1,22 @@
# Build sites define the builds (dbkeys) available at sites used by display
# applications and the URL to those sites.
# The `display` attributes on the `ucsc` and `gbrowse` sites replace the
# `ucsc_display_sites` and `gbrowse_display_sites` options in galaxy.ini.
# Because these are used by "old-style" display applications, their types
# cannot change if you want the old-style display links for these sites to
# work.
- type: ucsc
file: tool-data/shared/ucsc/ucsc_build_sites.txt
display: [main,test,archaea,ucla]
- type: gbrowse
file: tool-data/shared/gbrowse/gbrowse_build_sites.txt
display: [modencode,sgd_yeast,tair,wormbase,wormbase_ws120,wormbase_ws140,wormbase_ws170,wormbase_ws180,wormbase_ws190,wormbase_ws200,wormbase_ws204,wormbase_ws210,wormbase_ws220,wormbase_ws225]
- type: ensembl
file: tool-data/shared/ensembl/ensembl_sites.txt
- type: ensembl_data_url
file: tool-data/shared/ensembl/ensembl_sites_data_URL.txt
- type: igv
file: tool-data/shared/igv/igv_build_sites.txt
- type: rviewer
file: tool-data/shared/rviewer/rviewer_build_sites.txt
+9 -21
View File
@@ -61,6 +61,7 @@
<datatype extension="bowtie_base_index" type="galaxy.datatypes.ngsindex:BowtieBaseIndex" mimetype="text/html" display_in_upload="false"/>
<datatype extension="csfasta" type="galaxy.datatypes.sequence:csFasta" display_in_upload="true"/>
<datatype extension="data" type="galaxy.datatypes.data:Data" mimetype="application/octet-stream" max_optional_metadata_filesize="1048576" />
<datatype extension="d3_hierarchy" type="galaxy.datatypes.text:Json" mimetype="application/json" subclass="true" display_in_upload="false"/>
<datatype extension="data_manager_json" type="galaxy.datatypes.text:Json" mimetype="application/json" subclass="true" display_in_upload="false"/>
<datatype extension="dbn" type="galaxy.datatypes.sequence:DotBracket" display_in_upload="true" description="Dot-Bracket format is a text-based format for storing both an RNA sequence and its corresponding 2D structure." description_url="https://wiki.galaxyproject.org/Learn/Datatypes#Dbn"/>
<datatype extension="fai" type="galaxy.datatypes.tabular:Tabular" display_in_upload="true" subclass="true" description="A Fasta Index File is a text file consisting of lines each with five TAB-delimited columns : Name, Length, offset, linebases, Linewidth" description_url="http://www.htslib.org/doc/faidx.html" />
@@ -217,6 +218,7 @@
<datatype extension="mgf" type="galaxy.datatypes.proteomics:Mgf" display_in_upload="true" />
<datatype extension="wiff" type="galaxy.datatypes.proteomics:Wiff" display_in_upload="true" />
<datatype extension="mzxml" type="galaxy.datatypes.proteomics:MzXML" mimetype="application/xml" display_in_upload="true" />
<datatype extension="mzdata" type="galaxy.datatypes.proteomics:MzData" mimetype="application/xml" display_in_upload="true" />
<datatype extension="ms2" type="galaxy.datatypes.proteomics:Ms2" display_in_upload="true" />
<datatype extension="mzq" type="galaxy.datatypes.proteomics:MzQuantML" mimetype="application/xml" display_in_upload="true" />
<datatype extension="mz.sqlite" type="galaxy.datatypes.binary:MzSQlite" mimetype="application/octet-stream" display_in_upload="true" />
@@ -447,7 +449,7 @@
<datatype extension="embl" type="galaxy.datatypes.data:Text" subclass="true"/>
<datatype extension="fitch" type="galaxy.datatypes.data:Text" subclass="true"/>
<datatype extension="gcg" type="galaxy.datatypes.data:Text" subclass="true"/>
<datatype extension="genbank" type="galaxy.datatypes.sequence:Genbank" edam_format="format_1936"/>
<datatype extension="genbank" type="galaxy.datatypes.sequence:Genbank" display_in_upload="True"/>
<datatype extension="hennig86" type="galaxy.datatypes.data:Text" subclass="true"/>
<datatype extension="ig" type="galaxy.datatypes.data:Text" subclass="true"/>
<datatype extension="jackknifer" type="galaxy.datatypes.data:Text" subclass="true"/>
@@ -596,7 +598,11 @@
<datatype extension="maskinfo-asn1-binary" type="galaxy.datatypes.binary:GenericAsn1Binary" mimetype="application/octet-stream" subclass="true" display_in_upload="true" />
<datatype extension="pssm-asn1" type="galaxy.datatypes.data:GenericAsn1" mimetype="text/plain" subclass="true" display_in_upload="true" />
<!-- PlantTribes datatypes -->
<datatype extension="smat" type="galaxy.datatypes.estscan:Smat" display_in_upload="true" />
<datatype extension="ptalign" type="galaxy.datatypes.text:PlantTribesMultipleSequenceAlignment" />
<datatype extension="ptortho" type="galaxy.datatypes.text:PlantTribesOrtho" />
<datatype extension="ptorthocs" type="galaxy.datatypes.text:PlantTribesOrthoCodingSequence" />
<datatype extension="pttree" type="galaxy.datatypes.text:PlantTribesPhylogeneticTree" />
<datatype extension="smat" type="galaxy.datatypes.text:Smat" display_in_upload="true" />
</registration>
<sniffers>
<!--
@@ -606,7 +612,7 @@
defined format first, followed by next-most rigidly defined,
and so on.
-->
<sniffer type="galaxy.datatypes.estscan:Smat"/>
<sniffer type="galaxy.datatypes.text:Smat"/>
<sniffer type="galaxy.datatypes.mothur:Sabund"/>
<sniffer type="galaxy.datatypes.mothur:Otu"/>
<sniffer type="galaxy.datatypes.mothur:GroupAbund"/>
@@ -736,22 +742,4 @@
<sniffer type="galaxy.datatypes.binary:OxliSubset"/>
<sniffer type="galaxy.datatypes.binary:OxliGraphLabels"/>
</sniffers>
<build_sites>
<!--
Build sites define the builds (dbkeys) available at sites used by display
applications and the URL to those sites.
The `display` attributes on the `ucsc` and `gbrowse` sites replace the
`ucsc_display_sites` and `gbrowse_display_sites` options in galaxy.ini.
Because these are used by "old-style" display applications, their types
cannot change if you want the old-style display links for these sites to
work.
-->
<site type="ucsc" file="tool-data/shared/ucsc/ucsc_build_sites.txt" display="main,test,archaea,ucla"/>
<site type="gbrowse" file="tool-data/shared/gbrowse/gbrowse_build_sites.txt" display="modencode,sgd_yeast,tair,wormbase,wormbase_ws120,wormbase_ws140,wormbase_ws170,wormbase_ws180,wormbase_ws190,wormbase_ws200,wormbase_ws204,wormbase_ws210,wormbase_ws220,wormbase_ws225"/>
<site type="ensembl" file="tool-data/shared/ensembl/ensembl_sites.txt"/>
<site type="ensembl_data_url" file="tool-data/shared/ensembl/ensembl_sites_data_URL.txt"/>
<site type="igv" file="tool-data/shared/igv/igv_build_sites.txt"/>
<site type="rviewer" file="tool-data/shared/rviewer/rviewer_build_sites.txt"/>
</build_sites>
</datatypes>
+51 -7
View File
@@ -117,6 +117,11 @@ paste.app_factory = galaxy.web.buildapp:app_factory
# 'galaxy.model.orm.logging_connection_proxy'
#database_query_profiling_proxy = False
# Slow query logging. Queries slower than the threshold indicated below will
# be logged to debug. A value of '0' is disabled. For example, you would set
# this to .005 to log all queries taking longer than 5 milliseconds
# slow_query_log_threshold = 0
# By default, Galaxy will use the same database to track user data and
# tool shed install data. There are many situations in which it is
# valuable to separate these - for instance bootstrapping fresh Galaxy
@@ -210,7 +215,7 @@ paste.app_factory = galaxy.web.buildapp:app_factory
#conda_auto_install = False
# Set to True to instruct Galaxy to install Conda from the web automatically
# if it cannot find a local copy and conda_exec is not configured.
#conda_auto_init = False
#conda_auto_init = True
# You must set this to True if conda_prefix and job_working_directory are not on the same
# volume, or some conda dependencies will fail to execute at job runtime.
# Conda will copy packages content instead of creating hardlinks or symlinks.
@@ -309,6 +314,17 @@ paste.app_factory = galaxy.web.buildapp:app_factory
# when installed from a ToolShed. Defaults to tool_data_path.
#shed_tool_data_path = tool-data
# Set to True to enable monitoring of the tool_data and shed_tool_data_path
# directories. If changes in tool data table files are found, the tool data
# tables for that data manager are automatically reloaded.
# Watchdog ( https://pypi.python.org/pypi/watchdog ) must be installed and
# available to Galaxy to use this option. Other options include 'auto'
# which will attempt to use the watchdog library if it is available but won't
# fail to load Galaxy if it is not and 'polling' which will use a less
# efficient monitoring scheme that may work in wider range of scenarios
# than the watchdog default.
#watch_tool_data_dir = False
# File containing old-style genome builds
#builds_file_path = tool-data/shared/ucsc/builds.txt
@@ -339,6 +355,16 @@ paste.app_factory = galaxy.web.buildapp:app_factory
# separated list.
#interactive_environment_plugins_directory =
# To run interactive environment containers in Docker Swarm mode (on an
# existing swarm), set this option to True and set `docker_connect_port` in the
# IE plugin config (ini) file(s) of any IE plugins you have enabled and ensure
# that you are not using any `docker run`-specific options in your plugins'
# `command_inject` options (swarm mode services run using `docker service
# create`, which has a different and more limited set of options). This option
# can be overridden on a per-plugin basis by using the `swarm_mode` option in
# the plugin's ini config file.
#interactive_environment_swarm_mode = False
# Interactive tour directory: where to store interactive tour definition files.
# Galaxy ships with several basic interface tours enabled, though a different
# directory with custom tours can be specified here. The path is relative to the
@@ -349,8 +375,9 @@ paste.app_factory = galaxy.web.buildapp:app_factory
# Webhooks directory: where to store webhooks - plugins to extend the Galaxy UI.
# By default none will be loaded. Set to config/plugins/webhooks/demo to load Galaxy's
# demo webhooks. To use an absolute path begin the path with '/'. This is a comma
# separated list.
# webhooks_dir = config/plugins/webhooks
# separated list. Add test/functional/webhooks to this list to include the demo webhooks
# used to test the webhook framework.
#webhooks_dir = config/plugins/webhooks
# Each job is given a unique empty directory as its current working directory.
# This option defines in what parent directory those directories will be
@@ -909,6 +936,16 @@ use_interactive = True
# results will appear.
# tool_search_limit = 20
# Enable/ disable Ngram-search for tools. It makes tool
# search results tolerant for spelling mistakes in the query
# by dividing the query into multiple ngrams and search for
# each ngram
#tool_enable_ngram_search = False
# Set minimum and maximum sizes of ngrams
#tool_ngram_minsize = 3
#tool_ngram_maxsize = 4
# -- Users and Security
# Galaxy encodes various internal values when these values will be output in
@@ -1044,9 +1081,13 @@ use_interactive = True
# the Galaxy's beta workflow scheduling.
#force_beta_workflow_scheduled_min_steps=250
# Switch to using Galaxy's beta workflow scheduling for all workflows involving
# ccollections.
# collections.
#force_beta_workflow_scheduled_for_collections=False
# Force serial scheduling of workflows within the context of a particular history
#history_local_serial_workflow_scheduling=False
# Enable authentication via OpenID. Allows users to log in to their Galaxy
# account by authenticating with an OpenID provider.
#enable_openid = False
@@ -1216,7 +1257,7 @@ use_interactive = True
# tools). Set this to legacy_and_local to preserve the environment for legacy
# tools and locally managed tools (this might be useful for instance if you are
# installing software into Galaxy's virtualenv for tool development).
#python_environment_problem = legacy_only
#preserve_python_environment = legacy_only
# Clean up various bits of jobs left on the filesystem after completion. These
# bits include the job working directory, external metadata temporary files,
@@ -1286,8 +1327,11 @@ use_interactive = True
# -- Galaxy Application Internal Message Queue
# Galaxy uses AMQP internally TODO more documentation on what for.
# For examples, see http://ask.github.io/kombu/userguide/connections.html
# Galaxy uses AMQP internally for communicating between processes. For
# example, when reloading the toolbox or locking job execution, the process
# that handled that particular request will tell all others to also reload,
# lock jobs, etc.
# For connection examples, see http://docs.celeryproject.org/projects/kombu/en/latest/userguide/connections.html
#
# Without specifying anything here, galaxy will first attempt to use your
# specified database_connection above. If that's not specified either, Galaxy
+2
View File
@@ -0,0 +1,2 @@
# See $GALAXY_ROOT/lib/galaxy/tools/deps/default_conda_mapping.yml for example mapping -
# additional site-specific mappings can be added to config/conda_mapping.yml.
@@ -41,3 +41,15 @@ image = qiaoy/iobio-bundle.bam-iobio:1.0-ondemand
# share data between the IE and Galaxy.
#docker_galaxy_temp_dir = None
# If your Docker container exposes more then one port, Galaxy needs to know to
# which ports it needs to connect. With this option you can specify the port number
# inside your container to which Galaxy should connect the UI.
#docker_connect_port = None
# To run containers in Docker Swarm mode on (an existing swarm), set the
# following option to True *and*:
# - set docker_connect_port above. For qiaoy/iobio-bundle.bam-iobio the port
# should most likely be 8000.
# - If command_inject is uncommented and includes `--sig-proxy`, that option should
# be removed.
#swarm_mode = False
@@ -6,7 +6,7 @@
# appropriate `apt-get/pip install` statements.
---
-
image: bgruening/docker-jupyter-notebook:16.01
image: bgruening/docker-jupyter-notebook:16.01.1
description: |
The Jupyter notebook is the next iteration of IPython, allowing
analysis in many different languages. This image features the Python,
@@ -18,7 +18,7 @@
# The image argument was moved to "allowed_images.yml.sample"
# Additional arguments that are passed to the `docker run` command.
command_inject = --sig-proxy=true -e DEBUG=false -e DEFAULT_CONTAINER_RUNTIME=120
#command_inject = --sig-proxy=true -e DEBUG=false -e DEFAULT_CONTAINER_RUNTIME=120
# URL to access the Galaxy API with from the spawn Docker containter, if empty
# this falls back to galaxy.ini's galaxy_infrastructure_url and finally to the
@@ -43,4 +43,12 @@ command_inject = --sig-proxy=true -e DEBUG=false -e DEFAULT_CONTAINER_RUNTIME=12
# If your Docker container exposes more then one port, Galaxy needs to know to
# which ports it needs to connect. With this option you can specify the port number
# inside your container to which Galaxy should connect the UI.
# docker_connect_port = None
#docker_connect_port = None
# To run containers in Docker Swarm mode on (an existing swarm), set the
# following option to True *and*:
# - set docker_connect_port above. For Jupyter the # port should most likely be
# 8888.
# - If command_inject is uncommented and includes `--sig-proxy`, that option should
# be removed.
#swarm_mode = False
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE interactive_environment SYSTEM "../../interactive_environments.dtd">
<interactive_environment name="Jupyter (Programming Environment)">
<interactive_environment name="Jupyter">
<data_sources>
<data_source>
<model_class>HistoryDatasetAssociation</model_class>
@@ -40,3 +40,16 @@ command_inject = --sig-proxy=true -e DEBUG=false -e DEFAULT_CONTAINER_RUNTIME=12
# you can have a shared sshfs share which you can use as temporary directory to
# share data between the IE and Galaxy.
#docker_galaxy_temp_dir = None
# If your Docker container exposes more then one port, Galaxy needs to know to
# which ports it needs to connect. With this option you can specify the port number
# inside your container to which Galaxy should connect the UI.
#docker_connect_port = None
# To run containers in Docker Swarm mode on (an existing swarm), set the
# following option to True *and*:
# - set docker_connect_port above. For thoba/neo4j_galaxy_ie the port
# should most likely be 7474.
# - If command_inject is uncommented and includes `--sig-proxy`, that option should
# be removed.
#swarm_mode = False
@@ -19,3 +19,16 @@ image = shiltemann/docker-phinch-galaxy:16.04
# The Docker hostname. It can be useful to run the Docker daemon on a different
# host than Galaxy.
#docker_hostname = localhost
# If your Docker container exposes more then one port, Galaxy needs to know to
# which ports it needs to connect. With this option you can specify the port number
# inside your container to which Galaxy should connect the UI.
#docker_connect_port = None
# To run containers in Docker Swarm mode on (an existing swarm), set the
# following option to True *and*:
# - set docker_connect_port above. For shiltemann/docker-phinch-galaxy the port
# should most likely be 80.
# - If command_inject is uncommented and includes `--sig-proxy`, that option should
# be removed.
#swarm_mode = False
@@ -41,3 +41,16 @@ password_auth = True
# you can have a shared sshfs share which you can use as temporary directory to
# share data between the IE and Galaxy.
#docker_galaxy_temp_dir = None
# If your Docker container exposes more then one port, Galaxy needs to know to
# which ports it needs to connect. With this option you can specify the port number
# inside your container to which Galaxy should connect the UI.
#docker_connect_port = None
# To run containers in Docker Swarm mode on (an existing swarm), set the
# following option to True *and*:
# - set docker_connect_port above. For erasche/docker-rstudio-notebook the port
# should most likely be 80.
# - If command_inject is uncommented and includes `--sig-proxy`, that option should
# be removed.
#swarm_mode = False
+1 -5
View File
@@ -145,8 +145,6 @@ steps:
element: "#current-history-panel .fa-times:eq(0)"
intro: "Delete your dataset by clicking the x-button."
position: "left"
#postclick:
# - "#current-history-panel .fa-times:eq(0)"
- title: "Dataset information"
element: "div.title-bar.clear:eq(0)"
@@ -156,11 +154,9 @@ steps:
- "div.title-bar.clear:eq(0)"
- title: "Re-run tool"
element: ".fa-refresh:eq(1)"
element: "#current-history-panel .fa-refresh:first"
intro: "By clicking the reload button, you can re-run your tool again (e.g. with different parameters or on another dataset)."
position: "left"
preclick:
- ".fa-refresh:eq(1)"
- title: "Panel collapse"
-7
View File
@@ -107,13 +107,6 @@ steps:
postclick:
- "#current-history-panel > ul.list-items > div:nth-child(1) > div.warnings > div > a"
- element: "#current-history-panel > div.controls > .subtitle .toggle-deleted-link"
title: "Hiding all deleted datasets"
intro: "Hiding datasets that were previously deleted works in the same way."
position: "bottom"
preclick:
- "#current-history-panel > div.controls > .subtitle .toggle-deleted-link"
- element: "#current-history-panel > div.controls > div.title > div"
title: "Change your History name"
intro: "You can change the history name clicking on the title."
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
define( [], function() { return {nvd3_bar:require( "visualizations/nvd3/bar/config" ), nvd3_bar_horizontal:require( "visualizations/nvd3/bar_horizontal/config" ), nvd3_bar_horizontal_stacked:require( "visualizations/nvd3/bar_horizontal_stacked/config" ), nvd3_bar_stacked:require( "visualizations/nvd3/bar_stacked/config" ), nvd3_line:require( "visualizations/nvd3/line/config" ), nvd3_line_focus:require( "visualizations/nvd3/line_focus/config" ), nvd3_scatter:require( "visualizations/nvd3/scatter/config" ), nvd3_stackedarea:require( "visualizations/nvd3/stackedarea/config" ), nvd3_stackedarea_full:require( "visualizations/nvd3/stackedarea_full/config" ), nvd3_stackedarea_stream:require( "visualizations/nvd3/stackedarea_stream/config" ), nvd3_pie:require( "visualizations/nvd3/pie/config" ), nvd3_histogram:require( "visualizations/nvd3/histogram/config" ), nvd3_histogram_discrete:require( "visualizations/nvd3/histogram_discrete/config" ), jqplot_bar:require( "visualizations/jqplot/bar/config" ), jqplot_boxplot:require( "visualizations/jqplot/boxplot/config" ), jqplot_histogram_discrete:require( "visualizations/jqplot/histogram_discrete/config" ), jqplot_line:require( "visualizations/jqplot/line/config" ), jqplot_scatter:require( "visualizations/jqplot/scatter/config" ), biojs_msa:require( "visualizations/biojs/msa/config" ), biojs_drawrnajs:require( "visualizations/biojs/drawrnajs/config" ), others_example:require( "visualizations/others/example/config" ), others_heatmap:require( "visualizations/others/heatmap/config" ), others_heatmap_cluster:require( "visualizations/others/heatmap_cluster/config" ), cytoscape_basic:require( "visualizations/cytoscape/basic/config" ), pv_viewer:require( "visualizations/pv/viewer/config" ), benfred_venn:require( "visualizations/benfred/venn/config" ),} } );
define( [], function() { return {nvd3_bar:require( "visualizations/nvd3/bar/config" ), nvd3_bar_horizontal:require( "visualizations/nvd3/bar_horizontal/config" ), nvd3_bar_horizontal_stacked:require( "visualizations/nvd3/bar_horizontal_stacked/config" ), nvd3_bar_stacked:require( "visualizations/nvd3/bar_stacked/config" ), nvd3_line:require( "visualizations/nvd3/line/config" ), nvd3_line_focus:require( "visualizations/nvd3/line_focus/config" ), nvd3_scatter:require( "visualizations/nvd3/scatter/config" ), nvd3_stackedarea:require( "visualizations/nvd3/stackedarea/config" ), nvd3_stackedarea_full:require( "visualizations/nvd3/stackedarea_full/config" ), nvd3_stackedarea_stream:require( "visualizations/nvd3/stackedarea_stream/config" ), nvd3_pie:require( "visualizations/nvd3/pie/config" ), nvd3_histogram:require( "visualizations/nvd3/histogram/config" ), nvd3_histogram_discrete:require( "visualizations/nvd3/histogram_discrete/config" ), jqplot_bar:require( "visualizations/jqplot/bar/config" ), jqplot_boxplot:require( "visualizations/jqplot/boxplot/config" ), jqplot_histogram_discrete:require( "visualizations/jqplot/histogram_discrete/config" ), jqplot_line:require( "visualizations/jqplot/line/config" ), jqplot_scatter:require( "visualizations/jqplot/scatter/config" ), biojs_msa:require( "visualizations/biojs/msa/config" ), biojs_drawrnajs:require( "visualizations/biojs/drawrnajs/config" ), others_example:require( "visualizations/others/example/config" ), others_heatmap:require( "visualizations/others/heatmap/config" ), others_heatmap_cluster:require( "visualizations/others/heatmap_cluster/config" ), cytoscape_basic:require( "visualizations/cytoscape/basic/config" ), pv_viewer:require( "visualizations/pv/viewer/config" ), benfred_venn:require( "visualizations/benfred/venn/config" ), ngl_viewer:require( "visualizations/ngl/viewer/config" ),} } );
File diff suppressed because one or more lines are too long
@@ -5,5 +5,6 @@
"others" : [ "example", "heatmap", "heatmap_cluster" ],
"cytoscape" : [ "basic" ],
"pv" : [ "viewer" ],
"benfred" : [ "venn" ]
"benfred" : [ "venn" ],
"ngl" : [ "viewer" ]
}
@@ -0,0 +1,131 @@
define( [], function() {
return {
title : 'NGL Viewer',
library : 'NGL',
datatypes : [ 'pdb' ],
keywords : 'NGL protein viewer pdb',
description : 'NGL Viewer is a WebGL based molecular visualization hosted at http://arose.github.io/ngl/.',
settings : {
quality : {
label : 'Quality',
help : 'Select the rendering quality.',
type : 'select',
display : 'radio',
value : 'medium',
data : [ { label : 'High', value : 'high' }, { label : 'Medium', value : 'medium' }, { label : 'Low', value : 'low' } ]
},
viewer : {
type : 'conditional',
test_param : {
name : 'mode',
label : 'Display mode',
type : 'select',
display : 'radio',
value : 'cartoon',
help : '',
data : [ { label : 'Axes', value : 'axes' },
{ label : 'Base', value : 'base' },
{ label : 'Backbone', value : 'backbone' },
{ label : 'Ball+Stick', value : 'ball+stick' },
{ label : 'Cartoon', value : 'cartoon' },
{ label : 'Contact', value : 'contact' },
{ label : 'Helixorient', value : 'helixorient' },
{ label : 'Hyperball', value : 'hyperball' },
{ label : 'Label', value : 'label' },
{ label : 'Licorice', value : 'licorice' },
{ label : 'Line', value : 'line' },
{ label : 'Point', value : 'point' },
{ label : 'Ribbon', value : 'ribbon' },
{ label : 'Rocket', value : 'rocket' },
{ label : 'Rope', value : 'rope' },
{ label : 'Spacefill', value : 'spacefill' },
{ label : 'Surface', value : 'surface' },
{ label : 'Trace', value : 'trace' },
{ label : 'Tube', value : 'tube' },
{ label : 'Unitcell', value : 'unitcell' } ]
}
},
radius: {
name : 'radius',
label : 'Radius',
help : 'Select a number providing a fixed radius used for rendering the representation.',
type : 'float',
min : 0.001,
max : 10.0,
value : 0.05
},
scale: {
name : 'scale',
label : 'Scale',
help : 'Select a number that scales the value defined by the *radius* parameter.',
type : 'float',
min : 0.001,
max : 10.0,
value : 0.7
},
colorscheme : {
label : 'Color Scheme',
help : 'Select color scheme of the molecule scene.',
type : 'select',
display : 'radio',
value : 'atomindex',
data : [ { label : 'Element', value : 'element' },
{ label : 'Picking', value : 'picking' },
{ label : 'Random', value : 'random' },
{ label : 'Uniform', value : 'uniform' },
{ label : 'Atomindex', value : 'atomindex' },
{ label : 'Residue Index', value : 'residueindex' },
{ label : 'Chain Index', value : 'chainindex' },
{ label : 'Chain Name', value : 'chainname' },
{ label : 'Chain Id', value : 'chainid' },
{ label : 'Polymer', value : 'polymer' },
{ label : 'Model Index', value : 'modelindex' },
{ label : 'Entity Type', value : 'entitytype' },
{ label : 'Molecule Type', value : 'moleculetype' },
{ label : 'Secondary Structure', value : 'sstruc' },
{ label : 'Bfactor', value : 'bfactor' },
{ label : 'Resname', value : 'resname' },
{ label : 'Hydrophobicity', value : 'hydrophobicity' },
{ label : 'Value', value : 'value' },
{ label : 'Volume', value : 'volume' },
{ label : 'Occupancy', value : 'occupancy' } ]
},
backcolor : {
label : 'Background Color',
help : 'Select background color of the viewer.',
type : 'select',
display : 'radio',
value : 'white',
data : [ { label : 'Light', value : 'white' }, { label : 'Dark', value : 'black' } ]
},
spin : {
label : 'Spin',
help : 'Spin the molecule view.',
type : 'select',
display : 'radio',
value : false,
data : [ { label : 'On', value : true }, { label : 'Off', value : false } ]
},
assembly : {
label : 'Assembly',
help : 'Select a name of an assembly object.',
type : 'select',
display : 'radio',
value : 'default',
data : [ { label : 'Default', value : 'default' }, { label : 'AU', value : '' },
{ label : 'BU1', value : 'BU1' }, { label : 'UNITCELL', value : 'UNITCELL' },
{ label : 'SUPERCELL', value: 'SUPERCELL' } ]
},
opacity : {
name : 'opacity',
label : 'Opacity',
help : 'Select opacity for the molecule scene.',
type : 'float',
min : 0.0,
max : 1.0,
value : 1.0
}
}
}
});
Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

@@ -0,0 +1,42 @@
define( [ 'utilities/utils', "plugins/ngl/viewer" ], function( Utils, ngl ) {
return Backbone.Model.extend({
initialize: function( options ) {
var dataset = options.dataset,
settings = options.chart.settings,
stage = new ngl.Stage( options.targets[ 0 ], { backgroundColor: settings.get( 'backcolor' ) } ),
viewer_options = {},
representation_parameters = {},
stage_parameters = {};
_.each( settings.attributes, function( value, key ) {
if ( key.startsWith( 'viewer|' ) ) {
viewer_options[ key.replace( 'viewer|', '' ) ] = value;
}
} );
representation_parameters = {
radius: settings.get( 'radius' ),
scale: settings.get( 'scale' ),
assembly: settings.get( 'assembly' ),
color: settings.get( 'colorscheme' ),
opacity: settings.get( 'opacity' )
};
stage_parameters = { ext: dataset.extension, defaultRepresentation: true };
try {
stage.loadFile( dataset.download_url, stage_parameters ).then( function( component ) {
component.addRepresentation( viewer_options.mode, representation_parameters );
options.chart.state( 'ok', 'Chart drawn.' );
options.process.resolve();
} );
} catch( e ) {
options.chart.state( 'failed', 'Could not load PDB file.' );
options.process.resolve();
}
stage.setQuality( settings.get( 'quality' ) );
if( settings.get( 'spin' ) === true || settings.get( 'spin' ) === 'true' ) {
stage.setSpin( [ 0, 1, 0 ], 0.01 );
}
// Re-renders the molecule view when window is resized
$( window ).resize( function() { stage.viewer.handleResize() } );
}
});
});
+16 -9
View File
@@ -1,13 +1,20 @@
#!/bin/sh
if [ -z "$3" ]; then
echo "usage: check_galaxy <server> <username> <password>"
echo "usage: check_galaxy <server> <username> <password> <handler>"
exit 3
fi
here=`dirname $0`
var="$HOME/.check_galaxy/$1"
# not sure why this is necessary, but nagios' $HOME is /root, despite not running as root.
HOME=/var/lib/nagios
export HOME
here=`dirname $0`
host=`basename $1`
handler="$4"
var="$HOME/.check_galaxy/$host/$handler"
mkdir -p $var
touch $var/iterations
iterations=`cat $var/iterations`
if [ -z "$iterations" ]; then
@@ -15,7 +22,7 @@ if [ -z "$iterations" ]; then
fi
new_history=''
if [ $iterations -gt 96 ]; then
if [ $iterations -gt 64 ]; then
new_history='-n'
echo 0 > $var/iterations
else
@@ -23,17 +30,17 @@ else
fi
date >> $var/log
status=`python $here/check_galaxy.py $new_history $1 $2 $3 2>&1 | tee -a $var/log | tail -n 1`
status=`python $here/check_galaxy.py $new_history $1 $2 $3 $4 2>&1 | tee -a $var/log | tail -n 1`
echo "$status"
case "$status" in
"Exception: Tool never finished")
exit 1
;;
"OK")
"OK: "*)
exit 0
;;
"AssertionError: "*)
exit 1
;;
*)
exit 2
;;
+81 -161
View File
@@ -5,7 +5,6 @@ via the check_galaxy.sh script in Galaxy's cron/ directory.
"""
from __future__ import print_function
import filecmp
import formatter
import getopt
import htmllib
@@ -13,13 +12,13 @@ import json
import os
import socket
import sys
import tempfile
import time
import urllib2
import warnings
from user import home
with warnings.catch_warnings():
warnings.simplefilter('ignore')
import twill
import twill.commands as tc
# options
@@ -28,38 +27,10 @@ if "DEBUG" in os.environ:
else:
debug = False
test_data_dir = os.path.join( os.path.dirname( __file__ ), 'check_galaxy_data' )
# what tools to run - not so pretty
tools = {
"Extract+genomic+DNA+1":
[
{
"inputs":
(
{
"file_path": os.path.join( test_data_dir, "1.bed" ),
"dbkey": "hg17",
},
)
},
{ "check_file": os.path.join( test_data_dir, "extract_genomic_dna_out1.fasta" ) },
{
"tool_run_options":
{
"input": "1.bed",
"interpret_features": "yes",
"index_source": "cached",
"out_format": "fasta"
}
}
]
}
# handle arg(s)
def usage():
sys.exit("usage: check_galaxy.py <server> <username> <password>")
sys.exit("usage: check_galaxy.py <server> <username> <password> <handler>")
try:
@@ -72,6 +43,8 @@ if len( args ) < 1:
server = args[0]
username = args[1]
password = args[2]
handler = args[3]
warntime = 240
new_history = False
for o, a in opts:
@@ -83,69 +56,70 @@ for o, a in opts:
usage()
# state information
var_dir = os.path.join( os.path.expanduser('~'), ".check_galaxy", server )
var_dir = os.path.join( home, ".check_galaxy", server.replace('http://', '').replace('https://', ''), handler )
if not os.access( var_dir, os.F_OK ):
os.makedirs( var_dir, 0o700 )
# default timeout for twill browser is never
socket.setdefaulttimeout(300)
socket.setdefaulttimeout(60)
# user-agent
tc.agent("Mozilla/5.0 (compatible; check_galaxy/0.1)")
tc.agent("Mozilla/5.0 (compatible; check_galaxy/0.2)")
tc.config('use_tidy', 0)
class Browser:
def __init__(self):
self.server = server
self.tool = None
self.tool_opts = None
self.handler = handler
self.waited = -1
self.tool = 'echo_' + handler
self._hda_id = None
self._hda_state = None
self._history_id = None
self.check_file = None
if not self.server.startswith('http'):
self.server = 'http://' + self.server
self.cookie_jar = os.path.join( var_dir, "cookie_jar" )
dprint("cookie jar path: %s" % self.cookie_jar)
if not os.access(self.cookie_jar, os.R_OK):
dprint("no cookie jar at above path, creating")
tc.save_cookies(self.cookie_jar)
tc.load_cookies(self.cookie_jar)
self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(tc.get_browser().cj))
def get(self, path):
tc.go("http://%s%s" % (self.server, path))
tc.go("%s%s" % (self.server, path))
tc.code(200)
def req(self, path, data=None, method=None):
url = self.server + path
if data:
req = urllib2.Request(url, headers={'Content-Type': 'application/json'}, data=json.dumps(data))
else:
req = urllib2.Request(url, headers={'Content-Type': 'application/json'})
if method:
req.get_method = lambda: method
res = self.opener.open( req )
print('==> at %s (%s)' % (url, method or 'GET'))
assert res.getcode() == 200, url
return res
def reset(self):
self.tool = None
self.tool_opts = None
self._hda_id = None
self._hda_state = None
self._history_id = None
self.check_file = None
if new_history:
self.get("/history/delete_current")
tc.save_cookies(self.cookie_jar)
self.delete_history()
self.create_history()
self.delete_datasets()
def check_redir(self, url):
try:
tc.get_browser()._browser.set_handle_redirect(False)
tc.go(url)
tc.code(302)
tc.get_browser()._browser.set_handle_redirect(True)
dprint( "%s is returning redirect (302)" % url )
return(True)
except twill.errors.TwillAssertionError as e:
tc.get_browser()._browser.set_handle_redirect(True)
dprint( "%s is not returning redirect (302): %s" % (url, e) )
code = tc.browser.get_code()
if code == 502:
sys.exit("Galaxy is down (code 502)")
return False
def delete_history(self):
# note, this could cause a history to be created and then deleted. i don't care.
self.req( '/api/histories/%s' % self.history_id, method='DELETE' )
def login(self, user, pw):
self.get("/user/login")
tc.fv("1", "email", user)
tc.fv("1", "login", user)
tc.fv("1", "password", pw)
tc.submit("Login")
tc.code(200)
@@ -153,50 +127,37 @@ class Browser:
# uh ohs, fail
p = userParser()
p.feed(tc.browser.get_html())
if p.no_user:
dprint("user does not exist, will try creating")
self.create_user(user, pw)
elif p.bad_pw:
if p.bad_pw:
raise Exception("Password is incorrect")
else:
raise Exception("Unknown error logging in")
tc.save_cookies(self.cookie_jar)
def create_user(self, user, pw):
self.get("/user/create")
tc.fv("1", "email", user)
tc.fv("1", "password", pw)
tc.fv("1", "confirm", pw)
tc.submit("Submit")
tc.code(200)
if len(tc.get_browser().get_all_forms()) > 0:
p = userParser()
p.feed(tc.browser.get_html())
if p.already_exists:
raise Exception('The user you were trying to create already exists')
def upload(self, input):
self.get("/tool_runner/index?tool_id=upload1")
tc.fv("1", "file_type", "bed")
tc.fv("1", "dbkey", input.get('dbkey', '?'))
tc.formfile("1", "file_data", input['file_path'])
tc.submit("runtool_btn")
tc.code(200)
def runtool(self):
self.get("/tool_runner/index?tool_id=%s" % self.tool)
for k, v in self.tool_opts.items():
tc.fv("1", k, v)
tc.submit("runtool_btn")
tc.code(200)
path = '/api/tools'
data = { 'tool_id' : self.tool,
'history_id' : self.history_id,
'inputs' : { 'echo' : self.handler } }
res = self.req(path, data=data)
dprint(json.loads(res.read()))
@property
def history_id(self):
if self._history_id is None:
self.get('/api/histories')
self._history_id = json.loads(tc.browser.get_html())[0]['id']
for history in json.loads(tc.browser.get_html()):
# find an undeleted history named the same as the handler
if history['name'] == self.handler:
self._history_id = history['id']
break
else:
self.create_history()
return self._history_id
def create_history(self):
res = self.req('/api/histories', data={'name' : handler})
self._history_id = json.loads(res.read())['id']
@property
def history_contents(self):
self.get('/api/histories/%s/contents' % self.history_id)
@@ -244,7 +205,8 @@ class Browser:
def wait(self):
sleep_amount = 1
count = 0
maxiter = 16
maxiter = 20
start = time.time()
while count < maxiter:
count += 1
if not self.history_state_terminal:
@@ -252,8 +214,8 @@ class Browser:
sleep_amount += 1
else:
break
if count == maxiter:
raise Exception("Tool never finished")
self.waited = time.time() - start
assert count < maxiter, "Job timeout, waited %.2f seconds" % self.waited
def check_state(self):
if self.hda_state != "ok":
@@ -261,36 +223,31 @@ class Browser:
print(tc.browser.get_html())
raise Exception("HDA %s NOT OK: %s" % (self.hda_id, self.hda_state))
def diff(self):
self.get("/datasets/%s/display?to_ext=%s" % (self.hda_id, self.tool_opts.get('out_format', 'fasta')))
data = tc.browser.get_html()
tmp = tempfile.mkstemp()
dprint("tmp file: %s" % tmp[1])
tmpfh = os.fdopen(tmp[0], 'w')
tmpfh.write(data)
tmpfh.close()
if filecmp.cmp(tmp[1], self.check_file):
dprint("Tool output is as expected")
def check_hda_content(self):
self.get("/datasets/%s/display?to_ext=txt" % self.hda_id)
data = tc.browser.get_html().strip()
if data == self.handler:
dprint("Tool output is correct: %s" % data)
else:
if not debug:
os.remove(tmp[1])
dprint("EXPECTED: %s" % self.handler)
dprint("GOT: %s" % data)
raise Exception("Tool output differs from expected")
if not debug:
os.remove(tmp[1])
def delete_datasets(self):
for hda in self.undeleted_hdas:
self.get('/datasets/%s/delete' % hda['id'])
path = '/api/histories/%s/contents/%s' % (self.history_id, hda['id'])
self.req(path, method='DELETE')
hdas = [hda['id'] for hda in self.undeleted_hdas]
if hdas:
print("Remaining datasets ids:", " ".join(hdas))
raise Exception("History still contains datasets after attempting to delete them")
def check_if_logged_in(self):
self.get("/user?cntrller=user")
p = loggedinParser()
p.feed(tc.browser.get_html())
return p.logged_in
def check_if_logged_in(self, user):
try:
return json.loads(self.req('/api/users').read())[0]['email'] == user
except Exception as e:
print('Exception checking if logged in: %s' % str(e))
return False
class userParser(htmllib.HTMLParser):
@@ -324,26 +281,6 @@ class userParser(htmllib.HTMLParser):
self.already_exists = True
class loggedinParser(htmllib.HTMLParser):
def __init__(self):
htmllib.HTMLParser.__init__(self, formatter.NullFormatter())
self.in_p = False
self.logged_in = False
def start_p(self, attrs):
self.in_p = True
def end_p(self):
self.in_p = False
def handle_data(self, data):
if self.in_p:
if data == "You are currently not logged in.":
self.logged_in = False
elif data.startswith( "You are currently logged in as " ):
self.logged_in = True
def dprint(str):
if debug:
print(str)
@@ -356,39 +293,22 @@ if __name__ == "__main__":
b = Browser()
# login (or not)
if b.check_if_logged_in():
if b.check_if_logged_in(username):
dprint("we are already logged in (via cookies), hooray!")
else:
dprint("not logged in... logging in")
b.login(username, password)
for tool, params in tools.items():
# make sure history and state is clean
b.reset()
check_file = ""
b.runtool()
b.wait()
b.check_state()
b.check_hda_content()
b.delete_datasets()
# make sure history and state is clean
b.reset()
b.tool = tool
assert b.waited <= warntime, "Warning: Job runtime: %.2f" % b.waited
# get all the tool run conditions
for dict in params:
for k, v in dict.items():
if k == 'inputs':
for input in v:
b.upload(input)
b.wait()
elif k == 'check_file':
b.check_file = v
elif k == 'tool_run_options':
b.tool_opts = v
else:
raise Exception("Unknown key in tools dict: %s" % k)
b.runtool()
b.wait()
b.check_state()
b.diff()
b.delete_datasets()
print("OK")
print("OK: Job runtime: %.2f" % b.waited)
sys.exit(0)
+24
View File
@@ -0,0 +1,24 @@
#!/bin/bash
#
# When running Galaxy Interactive Environments on a swarm (using Docker Engine
# swarm mode), GIE sessions that have ended will leave behind "shut down"
# Docker services. These must be removed, which you can do with this script.
#
# Note that this is dependent on the specific ordering and output format of
# `docker service ls` and `docker service ps`. As of the time of writing
# (Docker version 1.13.1) these formats cannot be controlled as can be done
# with `docker ps` and the `--format` option, so be careful when upgrading
# Docker releases.
CONTAINER_NAME_PREFIX='galaxy_gie_'
LOG_PATH=${1:-'/tmp/galaxy_gie_service_clean.log'}
{
echo "Running cleanup at $(date)"
for service_name in $(docker service ls | awk "\$2 ~ /^$CONTAINER_NAME_PREFIX/ {print \$2}"); do
docker service ps --no-trunc $service_name | tail -1 | awk '{print $6}' | grep -q '^Shutdown$' && docker service rm $service_name;
done
echo "Done"
} >>$LOG_PATH
+162 -87
View File
@@ -1,22 +1,18 @@
.. _conda_faq:
===========================
Conda for Tool Dependencies
===========================
Galaxy tools (also called wrappers) traditionally use Tool Shed package
recipes to install their dependencies. At the tool's installation time
the recipe is downloaded and executed in order to provide the underlying
software executables. Introduction of these Galaxy-specific recipes was
a necessary step at the time, however nowadays there are other more
mature and stable options to install software in a similar manner. The
Galaxy tools (also called wrappers) have tradionally used Tool Shed package
recipes to install their dependencies. These were too tightly tied to Galaxy
and to the Tool Shed and so have been replaced with Conda as the package
management solution of choice for newer best practice tools. The
Galaxy community has taken steps to improve the tool dependency system
in order to enable new features and expand its reach. This document aims
to describe these and answer the FAQ.
Galaxy has adopted a new standard for tool dependencies: Conda packages!
Not only do Conda packages make tool dependencies more reliable and
stable, they are also easier to test and faster to develop than the
traditional Tool Shed package recipes.
in order to enable new features and expand its reach. Not only do Conda packages
make tool dependencies more reliable and stable, they are also easier to test
and faster to develop than the traditional Tool Shed package recipes. This
document aims to describe these and answer frequently asked questions.
Conda is a package manager like ``apt-get``, ``yum``, ``pip``, ``brew`` or
``guix``. We don't want to argue about the relative merits of various package
@@ -25,8 +21,8 @@ community contributions (such as implementing a Guix package manager or
enhancing the existing brew support to bring it on par with Conda).
As a community, we have decided that Conda is the one that best fulfills
community's needs. The following are some of the crucial Conda features that led
to this decision:
the community's current needs. The following are some of the crucial Conda
features that led to this decision:
- Installation of packages does not require *root* privileges
(installation at any location the Galaxy user has write access to)
@@ -45,17 +41,22 @@ to this decision:
Below we answer some common questions (collected by Lance Parsons):
1. How do I enable Conda dependency resolution for Galaxy jobs?
***************************************************************
1. How do I enable Conda dependency resolution for Galaxy tools?
****************************************************************
Galaxy's dependency job resolution is managed via
``dependency_resolvers_conf.xml`` configuration file. Most Galaxy administrators
should be using Galaxy's default dependency resolvers configuration file
( ``dependency_resolvers_conf.xml.sample`` ). With
The short answer is that as of 17.01, Galaxy should install Conda the first
time it starts up and be configured to use it by default.
The long answer is that Galaxy's tool dependency resolution is managed via
``dependency_resolvers_conf.xml`` configuration file. This configuration
file is discussed in detail in the :ref:`Dependency Resolvers <dependency_resolvers>`
documentation. Most Galaxy administrators will be using Galaxy's default dependency
resolvers configuration file (``config/dependency_resolvers_conf.xml.sample``). With
release 16.04, Galaxy has enabled Conda dependency resolution by default when
Conda was already installed on the system. Having Conda enabled in
``dependency_resolvers_conf.xml`` means that Galaxy can look for job
dependencies using the Conda system when it attempts to run tools.
Conda was already installed on the system. As of 17.01, Galaxy will also install
Conda as needed when starting up. Having Conda enabled in ``dependency_resolvers_conf.xml``
means that Galaxy can look for tool dependencies using the Conda system when it
attempts to run a job.
Note that the order of resolvers in the file matters and the ``<tool_shed_packages />``
entry should remain first. This means that tools that have specified Tool Shed packages
@@ -64,40 +65,27 @@ as their dependencies will work without a change.
The most common configuration settings related to Conda are listed in Table 1.
See `galaxy.ini.sample`_ for the complete list.
+--------------------------+--------------------------+---------------------------+
| Setting | Default setting | Meaning |
+--------------------------+--------------------------+---------------------------+
| ``conda_prefix`` | <tool\_dependency\_dir>/ | the location |
| | \_conda | on the |
| | | filesystem where Conda |
| | | packages and |
| | | environments are |
| | | installed |
| | | |
| | | IMPORTANT : Due to a |
| | | current limitation in |
| | | Conda, the total length |
| | | of the |
| | | |
| | | ``conda_prefix`` and the |
| | | ``job_working_directory`` |
| | | path should be less |
| | | than 50 characters! |
+--------------------------+--------------------------+---------------------------+
| ``conda_auto_init`` | False | Set to True to instruct |
| | | Galaxy to install Conda |
| | | (the package manager) |
| | | automatically if it |
| | | cannot find a local copy |
| | | already on the system. |
+--------------------------+--------------------------+---------------------------+
| ``conda_auto_install`` | False | Set to True to instruct |
| | | Galaxy to look for and |
| | | install Conda packages |
| | | for missing tool |
| | | dependencies before |
| | | running a job. |
+--------------------------+--------------------------+---------------------------+
+-------------------------+------------------------------------+---------------------------+
| Setting | Default setting | Meaning |
+-------------------------+------------------------------------+---------------------------+
| ``conda_auto_init`` | ``True`` | If ``True``, Galaxy will |
| | | try to install Conda |
| | | (the package manager) |
| | | automatically if it |
| | | cannot find a local copy |
| | | already on the system |
+-------------------------+------------------------------------+---------------------------+
| ``conda_auto_install`` | ``False`` | If ``True``, Galaxy will |
| | | look for and install |
| | | Conda packages for |
| | | missing tool dependencies |
| | | before running a job |
+-------------------------+------------------------------------+---------------------------+
| ``conda_prefix`` | ``<tool\_dependency\_dir>/_conda`` | The location on the |
| | | filesystem where Conda |
| | | packages and environments |
| | | are installed |
+-------------------------+------------------------------------+---------------------------+
*Table 1: Commonly used configuration options for Conda in Galaxy.*
@@ -125,6 +113,11 @@ To summarize, there are four ways to manage Conda dependencies for use
with Galaxy. For all of these options, Conda dependency management must
be configured in the ``dependency_resolvers_conf.xml`` and the ``galaxy.ini`` file.
#. Galaxy Admin Interface (>= 16.07) - Galaxy will install Conda tool
dependencies when tools are installed from the Tool Shed if the
option “When available, install externally managed dependencies (e.g.
Conda)? Beta” is checked. Admins may also view and manage Conda
dependencies via the Admin interface.
#. Manual Install - Conda dependencies may be installed by
administrators from the command line. Conda (and thus the Conda
environments) should be installed in the location specified by the
@@ -141,11 +134,6 @@ be configured in the ``dependency_resolvers_conf.xml`` and the ``galaxy.ini`` fi
Tools that require samtools version 0.1.19 will then be able to find
and use the installed Conda package.
#. Galaxy Admin Interface (>= 16.07) - Galaxy will install Conda tool
dependencies when tools are installed from the Tool Shed if the
option “When available, install externally managed dependencies (e.g.
Conda)? Beta” is checked. Admins may also view and manage Conda
dependencies via the Admin interface.
#. Automatically at tool run time - When a tool is run and a dependency
is not found, Galaxy will attempt to install the dependency using
Conda if ``conda_auto_install`` is activated in the configuration.
@@ -157,15 +145,13 @@ be configured in the ``dependency_resolvers_conf.xml`` and the ``galaxy.ini`` fi
**************************************************************************************************
The minimum required version of Galaxy to use Conda is 16.01, however
version 16.07 or greater is recommended. The 16.07 release of Galaxy has
version 17.01 or greater is recommended. The 16.07 release of Galaxy has
a graphical user interface to manage packages, but this is not
required to have Conda dependencies managed and used by Galaxy.
Conda packages should work on all compatible operating systems with
*glibc* version 2.5 or newer (this includes Centos 5). We will most
likely switch soon to *glibc* version 2.12 as a minimum requirement (this
includes CentOS 6). So all packages will run on all \*nix operating
systems newer than 2007.
*glibc* version 2.12 or newer (this includes Centos 6). So all packages
will run on all major \*nix operating systems newer than 2007.
4. If I have Conda enabled, what do I need to do to install tools using it? For example, how can I install the latest Trinity? And how will I know the dependencies are installed?
@@ -175,8 +161,8 @@ This depends on your ``galaxy.ini`` setting. Starting with release 16.07, Galaxy
can automatically install the Conda package manager for you if you have enabled
``conda_auto_init``. Galaxy can then install Trinity along with its dependencies
using one of the methods listed in question 2 above. In particular, if
``conda_auto_install`` is True and Trinity is not installed yet, Galaxy will try
to install it via Conda when a Trinity job is launched.
``conda_auto_install`` is ``True`` and Trinity is not installed yet, Galaxy will
try to install it via Conda when a Trinity job is launched.
With release 16.07 you can see which dependencies are being used
in the “Manage installed tools” section of the Admin panel and you can select
@@ -190,7 +176,7 @@ dependency resolvers configuration with regards to what will actually be used du
the tool execution.
To check if Galaxy has created a Trinity environment, have a look at folders under
``<tool_dependency_dir>/_conda/envs/``(or ``<conda_prefix>/envs`` if you have changed `conda_prefix` in your galaxy.ini file).
``<tool_dependency_dir>/_conda/envs/`` (or ``<conda_prefix>/envs`` if you have changed ``conda_prefix`` in your galaxy.ini file).
We recommend to use Conda on a tool-per-tool basis, by unchecking the checkbox
for TS dependencies during the tool installation, and for tools where there
@@ -214,6 +200,11 @@ The order in which resolvers are tried is listed in the
The first system that satisfies a requirement will be used. See
`resolver docs`_ for detailed documentation.
This however is not recommended, ideally tools will target and test
against Conda for all dependencies. Also resolving all requirements
with Conda gives Conda a chance to select compatible versions of
dependencies. Read more about selecting compatible versions on
`Issue #3299`_ and `Pull Request #3391`_.
6. How do I know what system is being used by a given tool?
***********************************************************
@@ -301,35 +292,112 @@ leave the old versions as they are – simply because of time.
Old tools will use the traditional installation system; this system will
stay and will be supported for installing old tools to guarantee sustainability
and reproducibility. New tools from the IUC, may be Conda only.
and reproducibility. New tools from the IUC and other best practices sources
are Conda only.
13. What can I do if Conda doesn't work for me?
***********************************************
13. What can I do about this placehold error?
*********************************************
There is currently a limitation in the way Conda packages are being
built. This limitation will be addressed shortly by the Conda community,
however this requires all packages to be rebuilt.
To work around this limitation, please make sure that the total length
of the ``conda_prefix`` and ``job_working_directory`` path is less than 50
characters long.
If this is your problem, you should see a warning similar to the
following in your galaxy log files:
If you see a warning similar to the following in your galaxy log files:
.. code-block:: bash
ERROR: placeholder '/home/ray/r_3_3_1-x64-3.5/envs/_build_placehold_placehold_placehold_placehold_pl' too short
This means you are very likely using an older version of Conda. This
bug has been fixed with the Conda release that is targeted by Galaxy
17.01 or newer.
In the past, the work around for this limitation, was to make sure that the total length
of the ``conda_prefix`` and ``job_working_directory`` path was less than 50
characters long.
14. What can I do about this LOCKERROR error?
***********************************************
This question addresses work arounds for Conda if something like the following
message appears in your logs:
.. code-block:: bash
Error: LOCKERROR: It looks like conda is already doing something.
The lock ['/galaxy/galaxy-app/tool-dependencies/_conda/pkgs/.conda_lock-119903'] was found. Wait for it to finish before continuing.
If you are sure that conda is not running, remove it and try again.
You can also use: $ conda clean --lock
First, you may wish to enable cached dependencies. This can be done by setting
``use_cached_dependency_manager`` to ``True`` in ``galaxy.ini``. Without this
option, many jobs will create a per-job Conda environment with just the
dependencies needed for that job installed.
This will be placed on the filesystem containg the job working directory. This
is an expensive operation and Conda doesn't always link environments correctly
across filesystems. Enabling this dependency caching will create a cache
directory for each required combination of requirements inside the directory
specified by ``tool_dependency_cache_dir`` in ``galaxy.ini`` (defaulting to
``<tool_dependency_dir>/_cache``).
The cached dependency manager was added to the 16.10 release of Galaxy (see
`Pull Request #3106`_). In 17.01 Galaxy was updated to build the cached dependencies
as needed if the caching is in fact enabled (see `Pull Request #3348`_) and reduced
the number of jobs that would require such caching (see `Pull Request #3391`_).
15. What can I do about linking errors?
***************************************
If Galaxy jobs run on filesystems that cannot hardlink Conda packages managed
by Galaxy, linking errors may occur when building environment to execute jobs.
There are a few ways to potentially work around this.
The most straight forward and efficient work around is probably just to enable the cached
dependency manager as described in the previous question. Notice the default location
of the cache is right next to the default Conda directory - so hardlinks should
lie on the same file system as the default Conda installation.
If this still doesn't work, perhaps the underlying file system does not support hard
linking at all. In this case it is best to add ``always_softlink: True`` to Galaxy's
YAML ``condarc`` file, this should be created by Galaxy and placed in
``<tool_dependency_dir/_condarc``. This requires Conda 4.3 or newer. Note this is a
newer version of Conda than shipped with Galaxy as of 17.01. See the question below
on upgrading Conda if you must use this trick.
Alternatively, copying can be used when creating environments instead of links (either
symbolic or hard). To enable this set ``conda_copy_dependencies`` to ``True`` in
``galaxy.ini``. This requires at least version 16.07 of Galaxy.
More reading on this can be found at `Conda Pull Request #3870`_, `Conda Issue #3308`,
and Galaxy `Issue #3193`_.
16. What can I do if Conda doesn't work for me?
***********************************************
Please review the common problems covered in the previous few questions, if your
problem is different more investigation will be needed.
In rare cases Conda may not have been properly installed by Galaxy.
A symptom for this is if there is no activate script in
``<conda_prefix>/bin`` folder. In that case you can delete the ``conda_prefix`` folder
and restart Galaxy, which will again attempt to install Conda.
If this does not solve your problem or you have any trouble following
the instructions, please ask on the Galaxy mailing list or the Galaxy
IRC channel.
the instructions, please ask on the Galaxy developing mailing list or the Galaxy
Gitter or IRC channel.
17. How can I upgrade Conda?
****************************
Many potential issues with Conda have been resolved with fixes in Conda itself. If
you let Galaxy install Conda prior to the release of 17.01 you probably have version
3.19.3. This can be updated to 4.2.13 with the following command:
.. code-block:: bash
$ <tool_dependency_dir/_conda/bin/conda update -y conda==4.2.13
The command can obviously be adapted to install any version of Conda.
.. _Conda documentation: http://conda.pydata.org/docs/building/build.html
.. _Conda quick-start: http://conda.pydata.org/docs/get-started.html
@@ -342,3 +410,10 @@ IRC channel.
.. _BioConda: https://bioconda.github.io
.. _contact with the IUC: https://gitter.im/galaxy-iuc/iuc
.. _galaxy.ini.sample: https://github.com/galaxyproject/galaxy/blob/dev/config/galaxy.ini.sample
.. _Pull Request #3106: https://github.com/galaxyproject/galaxy/pull/3106
.. _Pull Request #3348: https://github.com/galaxyproject/galaxy/pull/3348
.. _Pull Request #3391: https://github.com/galaxyproject/galaxy/pull/3391
.. _Issue #3193: https://github.com/galaxyproject/galaxy/issues/3193
.. _Conda Pull Request #3870: https://github.com/conda/conda/pull/3870
.. _Conda Issue #3308: https://github.com/conda/conda/issues/3308
.. _Issue #3299: https://github.com/galaxyproject/galaxy/issues/3299
+81 -38
View File
@@ -1,3 +1,6 @@
.. _dependency_resolvers:
Dependency Resolvers in Galaxy
==============================
@@ -8,7 +11,7 @@ job uses includes commands, such as changes to the ``PATH`` environment variable
resolvers*. There is a default dependency resolver configuration but administrators can provide their own configuration
using the ``dependency_resolvers_conf.xml`` configuration file in the Galaxy ``config/`` directory.
The binding between tool XML and the tools they need to run is specified in the tool XML using *requirements*
The binding between tool XML and the tools they need to run is specified in the tool XML using ``<requirement>``
tags, for example
.. code-block:: xml
@@ -21,9 +24,7 @@ In some cases these requirement tags can be specified without a version
<requirement type="package">bedtools</requirement>
The requirement turn into inputs to the dependency resolver. Each dependency resolver is thus given given one or
two inputs: the name of the dependency to resolve and, in most cases, the version string of the
dependency.
These declared requirements are passed as inputs to the dependency resolver.
Default Dependency Resolvers
----------------------------
@@ -33,32 +34,49 @@ The default configuration of dependency resolvers is equivalent to the following
.. code-block:: xml
<dependency_resolvers>
<!-- the default configuration, first look for dependencies installed from the toolshed -->
<!-- the default configuration, first look for legacy dependencies installed from the toolshed -->
<tool_shed_packages />
<!-- then look for env.sh files profile according to the "galaxy packages" schema -->
<!-- then look for env.sh files profile according to the "galaxy packages" schema -->
<galaxy_packages />
<galaxy_packages versionless="true" />
<!-- finally look for Conda dependencies. -->
<conda />
<conda versionless="true" />
</dependency_resolvers>
This default dependency resolver configuration contains three items. First, the *tool shed dependency resolver* is used,
then the *Galaxy packages dependency resolver* is used, first looking for packages by name and version string and then
finally looking for the package just by name. The default configuration thus prefers packages installed from the Galaxy
Tool Shed, before trying to find a "Galaxy package" satisfying the specific version the dependency requires before
finally falling back to looking for a Galaxy package with merely the correct name. If any of the dependency
This default dependency resolver configuration contains five items. First, the *tool shed dependency resolver* is used,
then the *Galaxy packages dependency resolver* is used (initially looking for packages by name and version string and then looking for the package just by name), and finally it checks *Conda* for a versioned or unversioned match.
The default configuration thus prefers packages installed from the Galaxy Tool Shed using legacy ``tool_dependencies.xml``
files, before trying to find a "Galaxy package" satisfying the specific version the dependency requires before
falling back to looking for a Galaxy package with merely the correct name, and then looking for Conda recipes with
matching name and version, and finally just for a Conda package with the correct name. If any of the dependency
resolvers succeeds a dependency resolution object is returned and no more resolvers are called. This dependency
resolution object provides shell commands to prepend to the shell script that runs the tool.
This order can be thought of as a descending order of deliberation. Tool Shed dependencies must be declared next to the
tool by the tool author and must be selected for installation at tool installation time - this requires specific actions
by both the tool author and the deployer who installed the tools. The dependency is therefore expected to highly craft
to the individual tool. If Galaxy packages have been setup, the deployer of a Galaxy tool has purposely crafted tool
dependency statements for a specific installation - this is slightly less deliberate than tool shed packages but
such requirements are less likely to be incidentally resolved than Conda packages. Conda recipes are neither tied to
tools or a specific installation and are maintained in Conda channels such as Bioconda.
So while tool shed packages are first - they are also somewhat deprecated. Maintaining Conda recipes makes it easier
to describe software dependencies both inside of Galaxy and outside.
Tool Shed Dependency Resolver
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The ``tool_shed_packages`` dependency resolver works with packages installed from the Galaxy Tool Shed. When a package
is installed from the Tool Shed it creates a directory structure under the directory that is specified as the
``tool_dependency_dir`` in Galaxy's configuration. This directory structure contains references to the tool's name,
owner (in the Tool Shed) and version string (amongst other things) and ultimately contains a file named ``env.sh``
that contains commands to make the dependency runnable. This is installed, along with the packaged tool, by the tool
package and doesn't require any configuration by the Galaxy administrator.
The ``tool_shed_packages`` dependency resolver works with explicit software packages installed from the Galaxy Tool
Shed as described by legacy ``tool_dependencies.xml`` files. When such a package is installed from the Tool Shed it
creates a directory structure under the directory that is specified as the ``tool_dependency_dir`` in Galaxy's
configuration. This directory structure contains references to the tool's ID, owner (in the Tool Shed) and version
string (amongst other things) and ultimately contains a file named ``env.sh`` that contains commands to make the
dependency runnable. This is installed, along with the packaged tool, by the tool package and doesn't require any
configuration by the Galaxy administrator.
Tools installed from the Tool Shed may also install Conda recipes and most new best practice tools do this
by default now.
The Tool Shed dependency resolver is not able to resolve package requirements that do not have a version string,
like the `bedtools` example above.
@@ -80,7 +98,20 @@ needs ``bedtools`` version 2.20.1, the dependency resolver will look for a direc
If the Galaxy Package dependency resolver finds a ``bin`` directory in this directory, it adds it to the ``PATH``
used by the scripts Galaxy uses to run tools. If, however, it finds an ``env.sh`` script, it sources this
script before running the tool that requires this dependency. This can be used to set up the environment
needed for the tool to run. For example, this ``env.sh`` uses `Environment Modules <http://modules.sourceforge.net/>`_
needed for the tool to run.
A simple example might be to assume that a collection of bioinformatics software is manually installed in various
directories under ``/opt/biosoftware``. In this case a ``<tool_dependency_dir>/bedtools/2.20.1/env.sh`` could be
setup to add the corresponding bedtools installation to the Galaxy tool execution's ``PATH``.
.. code-block:: bash
#!/bin/sh
export PATH=$PATH:/opt/biosoftware/bedtools/2.20.1/bin
As another example, this ``env.sh`` uses `Environment Modules <http://modules.sourceforge.net/>`_
to setup the environment for ``bedtools``
.. code-block:: bash
@@ -94,10 +125,10 @@ to setup the environment for ``bedtools``
module add bedtools/bedtools-2.20.1
The Galaxy Package dependency resolver operates quite similarly when used in versionless module. Instead of looking
for a directory named after a version, it looks for a directory ending in ``default``. For example
``bedtools/default``. It then looks for a `bin` subdirectory or ``envh.sh`` and incorporates these in the tool
script that finally gets run. This versionless (i.e. default) lookup is also used if the package requirement
does not specify a version string.
for a directory named after a version, it looks for a directory symbolic link named ``default`` that links to a
concrete version such as the ``2.20.1`` example above. For example if ``bedtools/default`` links to ``bedtools/2.20.1``.
It then looks for a `bin` subdirectory or ``envh.sh`` and incorporates these in the tool script that finally gets run.
This versionless (i.e. default) lookup is also used if the package requirement does not specify a version string.
Environment Modules Dependency Resolver
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -113,17 +144,17 @@ modulepath
value used for MODULEPATH environment variable, used to locate modules
versionless
whether to resolve tools using a version string or not (default: *false*)
whether to resolve tools using a version string or not (default: ``false``)
find_by
whether to use the ``DirectoryModuleChecker`` or ``AvailModuleChecker`` (permissable values are "directory" or "avail",
default is "avail")
whether to use the ``DirectoryModuleChecker`` or ``AvailModuleChecker`` (permissable values are ``directory`` or ``avail``,
default is ``avail``)
prefetch
in the AvailModuleChecker prefetch module info with ``module avail`` (default: true)
in the AvailModuleChecker prefetch module info with ``module avail`` (default: ``true``)
default_indicator
what indicate to the AvailModuleChecker that a module is the default version (default: "(default)"). Note
what indicate to the AvailModuleChecker that a module is the default version (default: ``(default)``). Note
that the first module found is considered the default when no version is used by the resolver, so
the sort order of modules matters.
@@ -132,7 +163,7 @@ of the ``module avail`` command for the name of the dependency. If it is configu
or is looking for a package with no version specified, it accepts any module whose name matches and is a bare word
or the first module whose name matched. For this reason, the default version of the module should be the first one
listed, something that can be achieved by tagging it with a word that appears first in sort order, for example the
string "(default)" (yielding a module name like ``bedtools/(default)``). So when looking for ``bedtools`` in
string ``(default)`` (yielding a module name like ``bedtools/(default)``). So when looking for ``bedtools`` in
versionless mode the search would match the first module called ``bedtools``, and in versioned mode the search would
only match if a module named ``bedtools/2.20.1`` was present (assuming you're looking for ``bedtools/2.20.1``).
@@ -149,7 +180,8 @@ used, they'll be used in the ``load`` command e.g. ``modulecmd sh load bwa/0.7.1
Homebrew Dependency Resolver
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This dependency resolver uses homebrew packages to resolve requirements.
This dependency resolver uses homebrew packages to resolve requirements. It is highly experimental
and undocumented.
Brew Tool Shed Package Resolver
@@ -163,9 +195,12 @@ and will almost certainy be removed from the code base.
Conda Dependency Resolver
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The conda XML tag can be used to configure a conda dependency resolver.
The ``conda`` directive can be used to configure a conda dependency resolver.
This resolver can be configured with the following options.
For a very detailed discussion of Conda dependency resolution, check out the
:ref:`Conda FAQ <conda_faq>`.
prefix
The conda_prefix used to locate dependencies in (default: ``<tool_dependency_dir>/_conda``).
@@ -174,21 +209,29 @@ exec
PATH (if available) and then to ``<conda_prefix>/bin/conda``.
versionless
whether to resolve tools using a version string or not (default: *false*)
whether to resolve tools using a version string or not (default: ``False``).
debug
Pass debug flag to conda commands (default: false).
Pass debug flag to conda commands (default: ``False``).
ensure_channels
conda channels to enable by default. See
http://conda.pydata.org/docs/custom-channels.html for more
information about channels. (default: iuc,bioconda,r,defaults,conda-forge).
information about channels. This defaults to ``iuc,bioconda,r,defaults,conda-forge``.
This order should be consistent with `Bioconda prescribed order <https://github.com/bioconda/bioconda-recipes/blob/master/config.yml#L8>`__
if it includes ``bioconda``.
auto_install
Set to True to instruct Galaxy to look for and install missing tool
dependencies before each job runs. (default: False)
If ``True``, Galaxy will look for and install missing tool
dependencies before running a job (default: ``False``).
auto_init
Set to True to instruct Galaxy to install conda from the web
automatically if it cannot find a local copy and conda_exec is not
configured.
If ``True``, Galaxy will try to install Conda from the web
automatically if it cannot find a local copy and ``conda_exec`` is not
configured. This defaults to ``True`` as of Galaxy 17.01.
copy_dependencies
If ``True``, Galaxy will copy dependencies over instead of symbolically
linking them when creating per job environments. This should be considered somewhat
deprecated because Conda will do this as needed for newer versions of Conda - such
as the version targeted with Galaxy 17.01+.
+76 -10
View File
@@ -201,7 +201,8 @@ You might want to run your IEs on a host different to the one that hosts your
Galaxy webserver, since IEs on the same host as the webserver compete for
resources with that webserver and introduce some security considerations which
could be mitigated by moving containers to a separate host. This feature has
been available since 15.07 and is used in production at the University of Freiburg.
been available since 15.07 and is used in production at the University of
Freiburg and on usegalaxy.org.
First you need to configure a second host to be Docker enabled. In the
following we call this host ``gx-docker`` You need to start the Docker daemon
@@ -213,9 +214,9 @@ you can start the daemon with
$ docker -H 0.0.0.0:4243 -d
On your client, the Galaxy webserver, you can now install a Docker client. This
can also be done on older Systems like Scientific-Linux, CentOS 6, which does
not have Docker support by default. The client just talks to the Docker daemon
on host ``gx-docker``, and does not run anything itself, locally. You can test
can also be done on older systems like Scientific-Linux, CentOS 6, which do not
have Docker support by default. The client just talks to the Docker daemon on
host ``gx-docker``, and does not run anything itself, locally. You can test
your configuration for example by starting busybox from your client on the
Docker host with
@@ -223,7 +224,13 @@ Docker host with
$ docker -H tcp://gx-docker:4243 run -it busybox sh
So far so good! Now we need to configure Galaxy to use our new Docker host
So far so good! Note, however, that unless restricted by a firewall, this mode
of operation is insecure, as any client could connect and run containers on
``gx-docker``. If this is a concern at your site, follow the instructions in
the Docker documentation to `Protect the Docker daemon socket
<https://docs.docker.com/engine/security/https/>`__.
Now we need to configure Galaxy to use our new Docker host
to start the Interactive Environments. For that we need to edit the Jupyter GIE
configuration, ``jupyter.ini`` to use our custom docker host
@@ -233,14 +240,18 @@ configuration, ``jupyter.ini`` to use our custom docker host
[docker]
command = docker -H tcp://gx-docker:4243 {docker_args}
image = bgruening/docker-ipython-notebook:dev
docker_hostname = gx-docker
Please adapt your ``command`` and the ``image`` as needed.
Please adapt your ``command`` as needed.
As next step we need to configure a share mount point between the Docker host
and Galaxy. Unfortunately, this can not be a NFS mount. Docker does not like
NFS yet. You could for example use a sshfs mount with the following script
The Jupyter GIE supports getting and fetching Galaxy history datasets entirely
through the Galaxy API so it is not necessary to share a filesystem with
``gx-docker``. However, other GIE plugins may still require this.
For those GIE plugins, we need to configure a share mount point between the
Docker host and Galaxy. Unfortunately, this can not be a NFS mount. Docker does
not like NFS yet. You could for example use a sshfs mount with the following
script
.. code-block:: bash
@@ -252,3 +263,58 @@ NFS yet. You could for example use a sshfs mount with the following script
fi
This will let Galaxy and the Docker host share temporary files.
Docker Engine Swarm Mode
^^^^^^^^^^^^^^^^^^^^^^^^
As of Docker Engine version 1.12, Docker Engine can be configured to provide a
cluster of Docker Engines in a configuration known as *Docker Engine swarm
mode*. This replaces the previous and similarly named *Docker Swarm*
clustering solution, which is not compatible with swarm mode.
`The Docker Engine swarm mode documentation
<https://docs.docker.com/engine/swarm/>`__ fully explains the differences, but
the major difference is that whereas under Docker Swarm one could run commands
on the swarm with ``docker run``, Docker Engine swarm mode requires one to
create persistent services with ``docker service create`` and to remove those
services once no longer in use with ``docker service rm``.
Galaxy supports both Docker Engine swarm mode and the legacy Docker Swarm
system. Legacy Docker Swarm is supported without any special configuration,
because the containers are still run with ``docker run`` as before. To support
Docker Engine swarm mode, additional configuration is required. Begin by
editing your GIE config plugin's ini configuration file (e.g. ``jupyter.ini``)
and set the ``docker_connect_port`` and ``swarm_mode options`` in addition to
any other relevant options. Unless you are using a non-standard Docker image,
the correct value for ``docker_connect_port`` should be suggested to you in the
sample configuration file:
.. code-block:: ini
[docker]
docker_connect_port = 8888
swarm_mode = True
Note that your Galaxy server does not need to be a member of the swarm itself.
It can use the method outlined above in the `Docker on Another Host`_ section
to connect as a client to a Docker daemon acting as a swarm mode manager.
Once configured, you should see that your GIE containers are started and run as
services, which you can inspect using the ``docker service ls`` command and
other ``docker service`` subcommands.
**Docker services are not cleaned up by Galaxy**. To clean them up, we have
provided a script that can be run from cron which will locate "shut down"
services (GIE containers which have stopped themselves) at
`cron/clean_docker_swarm_mode_services.sh
<https://github.com/galaxyproject/galaxy/blob/dev/cron/clean_docker_swarm_mode_services.sh>`__
in the Galaxy source. This script can be run from cron with a crontab entry
like this example which runs every 15 minutes:
.. code-block:: bash
*/15 * * * * bash /path/to/clean_docker_swarm_mode_services.sh /path/to/galaxy/log/dir/clean_docker_swarm_mode_services.log
This entry would be suitable to be run as ``root`` on a swarm mode manager. You
could also run it as the Galaxy user on the Galaxy server (with modifications
to set the correct daemon socket, if running remotely).
-15
View File
@@ -1,15 +0,0 @@
galaxy_utils package
====================
.. automodule:: galaxy_utils
:members:
:undoc-members:
:show-inheritance:
Subpackages
-----------
.. toctree::
galaxy_utils.sequence
-52
View File
@@ -1,52 +0,0 @@
galaxy_utils.sequence package
=============================
.. automodule:: galaxy_utils.sequence
:members:
:undoc-members:
:show-inheritance:
Submodules
----------
galaxy_utils.sequence.fasta module
----------------------------------
.. automodule:: galaxy_utils.sequence.fasta
:members:
:undoc-members:
:show-inheritance:
galaxy_utils.sequence.fastq module
----------------------------------
.. automodule:: galaxy_utils.sequence.fastq
:members:
:undoc-members:
:show-inheritance:
galaxy_utils.sequence.sequence module
-------------------------------------
.. automodule:: galaxy_utils.sequence.sequence
:members:
:undoc-members:
:show-inheritance:
galaxy_utils.sequence.transform module
--------------------------------------
.. automodule:: galaxy_utils.sequence.transform
:members:
:undoc-members:
:show-inheritance:
galaxy_utils.sequence.vcf module
--------------------------------
.. automodule:: galaxy_utils.sequence.vcf
:members:
:undoc-members:
:show-inheritance:
-1
View File
@@ -6,7 +6,6 @@ lib
galaxy
galaxy_ext
galaxy_utils
log_tempfile
mimeparse
psyco_full
-1
View File
@@ -56,7 +56,6 @@ Members
- Eric Rasche (@erasche)
- Nicola Soranzo (@nsoranzo)
- James Taylor (@jxtx)
- Nitesh Turaga (@nturaga)
- Marius van den Beek (@mvdbeek)
Membership
+332
View File
@@ -0,0 +1,332 @@
.. to_doc
17.01
===============================
.. announce_start
Enhancements
-------------------------------
* Fuzzy search for tools search
(thanks to `@anuprulez <https://github.com/anuprulez>`__).
`Pull Request 3356`_
* Add cached dependency manager (was back-ported to 16.10 as well)
(thanks to `@mvdbeek <https://github.com/mvdbeek>`__).
`Pull Request 3106`_
* Cache dependencies on the fly when first used
(thanks to `@abretaud <https://github.com/abretaud>`__).
`Pull Request 3348`_
* Fix Conda channel order
(thanks to `@bgruening <https://github.com/bgruening>`__).
`Pull Request 3237`_
* Target Miniconda3 for new Conda installs - existing Conda
installs will be unaffected but new Conda installs will not be
subject to Conda bugs in Miniconda2 such as
`conda/conda#4492 <https://github.com/conda/conda/issues/4492>`__.
`Pull Request 3419`_
* Use a newer conda version by default
(thanks to `@bgruening <https://github.com/bgruening>`__).
`Pull Request 3378`_
* Resolve Conda dependencies all at once to allow Conda to select compatible
builds.
`Pull Request 3391`_
* Implement dependency resolver mapping files.
`Pull Request 3444`_
* Add API to install resolver tool dependencies
(thanks to `@mvdbeek <https://github.com/mvdbeek>`__).
`Pull Request 3222`_
* Various other dependency resolver fixes and improvements.
(thanks to `@mvdbeek <https://github.com/mvdbeek>`__)
`Pull Request 3454`_, `Pull Request 3461`_, `Pull Request 3483`_,
`Pull Request 3482`_, `Pull Request 3427`_
* Enhanced support for failed job re-submission - allow specifying
conditions for re-submission as well as improved support, documentation,
and testing.
`Pull Request 3319`_, `Pull Request 3291`_
* Allow specification of a per user total walltime limit.
(thanks to `@maxf130 <https://github.com/maxf130>`__).
`Pull Request 3217`_
* Many improvements to the job information page - including
exposing certain job metrics to non-admin users
(thanks to `@erasche <https://github.com/erasche>`__).
`Pull Request 3344`_, `Pull Request 3256`_,
`Pull Request 3340`_
* Formalize decision to increase time between releases to four months. The next release
will be 17.05.
`Pull Request 3271`_
* Add API endpoint to determine who the current user is
(thanks to `@erasche <https://github.com/erasche>`__).
`Pull Request 3423`_
* Extend API version information for Docker-based Galaxy instances
(thanks to `@manabuishii <https://github.com/manabuishii>`__).
`Pull Request 3411`_
* Implement a more complete Genbank datatype with sniffer
(thanks to `@erasche <https://github.com/erasche>`__).
`Pull Request 3339`_
* Add additional image datatypes
(thanks to `@ThomasWollmann <https://github.com/ThomasWollmann>`__).
`Pull Request 2679`_, `Pull Request 3380`_
* Add a DIAMOND database datatype
(thanks to `@bgruening <https://github.com/bgruening>`__ and `@bebatut <https://github.com/bebatut>`__).
`Pull Request 3379`_
* Add ESTScan scores matrices (smat) datatype
(thanks to `@gregvonkuster <https://github.com/gregvonkuster>`__
with bug fix from `@nsoranzo <https://github.com/nsoranzo>`__).
`Pull Request 3258`_, `Pull Request 3475`_
* Improve GG datatype sniffer to sniff fewer texts files as GG
`Pull Request 3233`_
* Allow rename dataset post job actions to work on input parameters inside of ``repeat`` blocks
(thanks to `@scholtalbers <https://github.com/scholtalbers>`__).
`Pull Request 3197`_
* Improve Tour URL routing in the client.
`Pull Request 3214`_
* Assorted enhancements for the SLURM job runner
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__).
`Pull Request 3218`_
* Various Galaxy tool schema definition fixes (including adding
EDAM topic(s) and operation(s) thanks to `@hmenager <https://github.com/hmenager>`__).
`Pull Request 3221`_, `Pull Request 3216`_
* Numerous improvements to the test framework including replacing broken CasperJS UI tests
with newer Selenium based ones and expanded test coverage with a particular
focus on web and integration testing.
`Pull Request 3285`_, `Pull Request 3286`_, `Pull Request 3291`_,
`Pull Request 3342`_, `Pull Request 3367`_, `Pull Request 3381`_,
`Pull Request 3239`_, `Pull Request 3371`_, `Pull Request 3190`_,
`Pull Request 3264`_, `Pull Request 3288`_, `Pull Request 3387`_,
`Pull Request 3400`_, `Pull Request 3401`_, `Pull Request 3228`_,
`Pull Request 3365`_, `Pull Request 3368`_, `Pull Request 3370`_,
`Pull Request 3482`_, `Pull Request 3185`_
* Bring in fix from galaxy-lib related to Biocontainers and mulled
<https://github.com/galaxyproject/galaxy-lib/pull/36>`__ from @bgruening.
`Pull Request 3304`_
* Large cleanup of datatype converter tools
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__).
`Pull Request 3305`_
* Adds a ``make charts`` Makefile target to make it more obvious how to build
these.
`Pull Request 3306`_
* Implement IGV display for FASTA datatypes
(thanks to `@Delphine-L <https://github.com/Delphine-L>`__).
`Pull Request 3327`_
* Add an option to specify the port when connecting clients to IEs.
(thanks to `@bgruening <https://github.com/bgruening>`__).
`Pull Request 3328`_
* Allow admins to see API keys under when using remote user authentication from proxies.
(thanks to `@erasche <https://github.com/erasche>`__).
`Pull Request 3338`_
* Limit adjusting Galaxy's Python environment to legacy tools
(discussed in Deprecation Notices section of release notes).
`Pull Request 3364`_
* Workflow run display improvements in particular for data inputs.
`Pull Request 3369`_
* Adjust menu tooltips to be one line each.
`Pull Request 3230`_
Fixes
-------------------------------
* Various fixes to escape variables in the client to prevent certain XSS attacks
(thanks in large part to `@yhoogstrate <https://github.com/yhoogstrate>`__).
`Pull Request 3403`_, `Pull Request 3416`_, `Pull Request 3448`_
* Fix import order and Python3 compatibility for lib/galaxy/tools/
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__).
`Pull Request 3431`_
* Fix SLURM job re-submission.
`Pull Request 3290`_
* Dependency resolver documentation fixes
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__).
`Pull Request 3490`_
* Fix directory existence checks in dependency resolver code
(thanks to `@bgruening <https://github.com/bgruening>`__).
`Pull Request 3301`_
* Fix for mapping tools with paired collection input and a ``structured_like`` tag
over ``list:paired`` collections
(thanks to `@mvdbeek <https://github.com/mvdbeek>`__).
`Pull Request 3209`_
* Fix ``I201`` errors from flake8-import-order
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__).
`Pull Request 3215`_
* Fix user table header in admin view
(thanks to `@erasche <https://github.com/erasche>`__).
`Pull Request 3200`_
* Fix to adjust masthead and tool search.
`Pull Request 3055`_
* Don't load tools from paths that start with ``.`` or ``_``
(thanks to `@mvdbeek <https://github.com/mvdbeek>`__).
`Pull Request 3201`_
* Fixes for ``core.galaxy_ui.yaml`` tour.
`Pull Request 3206`_
* Small fixes to release management script ``bootstrap_history.py``
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__).
`Pull Request 3223`_
* Fix tour URLs in welcome sample.
`Pull Request 3274`_
* Fix logo image when serving Galaxy from a subdirectory.
`Pull Request 3283`_
* Various fixes for transition from IPython to Jupyter
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__
and `@annefou <https://github.com/annefou>`__).
`Pull Request 3333`_, `Pull Request 3294`_
* Fix linting of ``gff_filter_by_attribute`` wrapper Python code.
`Pull Request 3324`_
* Fix typo in assertion based testing
(thanks to `@pvanheus <https://github.com/pvanheus>`__).
`Pull Request 3384`_
* Update ``UCSC_SERVERS`` list to include new(ish?) soe subdomain.
`Pull Request 3345`_
* Fix explicit Docker container resolution (this was backported to 16.10).
`Pull Request 3346`_
* Fix for connecting webhooks to masthead.
(thanks to `@anuprulez <https://github.com/anuprulez>`__).
`Pull Request 3349`_
* Remove seemingly unused file ``sort_gtf.py``.
`Pull Request 3362`_
* Fix upload to respect explicit name override on pasted uploads.
`Pull Request 3377`_
* Do not allow recursive replacements in PJA renames.
`Pull Request 3395`_
* Fix logout link when using remote user authentication from proxies.
`Pull Request 3405`_
* Fix typo in webhooks documentation
(thanks to `@manabuishii <https://github.com/manabuishii>`__).
`Pull Request 3409`_
* Fix login functionality for RStudio IEs
(thanks to `@erasche <https://github.com/erasche>`__).
`Pull Request 3414`_
* Fix accidental email exposure during history sharing
(thanks to `@erasche <https://github.com/erasche>`__).
`Pull Request 3417`_
* Fix UX problem when sharing objects with users.
`Pull Request 3373`_
* Do not wrap ``__class__`` attribute of ``SafeStringWrapper``
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__).
`Pull Request 3429`_
* Fix for determining Condor container id
(thanks to `@bgruening <https://github.com/bgruening>`__).
`Pull Request 3462`_
* Fix linting of ``<conditional>`` tags
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__).
`Pull Request 3464`_
* Upgrade Python dependency six to 1.10.0.
`Pull Request 3471`_
.. github_links
.. _Pull Request 2679: https://github.com/galaxyproject/galaxy/pull/2679
.. _Pull Request 3055: https://github.com/galaxyproject/galaxy/pull/3055
.. _Pull Request 3106: https://github.com/galaxyproject/galaxy/pull/3106
.. _Pull Request 3118: https://github.com/galaxyproject/galaxy/pull/3118
.. _Pull Request 3145: https://github.com/galaxyproject/galaxy/pull/3145
.. _Pull Request 3185: https://github.com/galaxyproject/galaxy/pull/3185
.. _Pull Request 3189: https://github.com/galaxyproject/galaxy/pull/3189
.. _Pull Request 3190: https://github.com/galaxyproject/galaxy/pull/3190
.. _Pull Request 3192: https://github.com/galaxyproject/galaxy/pull/3192
.. _Pull Request 3197: https://github.com/galaxyproject/galaxy/pull/3197
.. _Pull Request 3200: https://github.com/galaxyproject/galaxy/pull/3200
.. _Pull Request 3201: https://github.com/galaxyproject/galaxy/pull/3201
.. _Pull Request 3206: https://github.com/galaxyproject/galaxy/pull/3206
.. _Pull Request 3209: https://github.com/galaxyproject/galaxy/pull/3209
.. _Pull Request 3214: https://github.com/galaxyproject/galaxy/pull/3214
.. _Pull Request 3215: https://github.com/galaxyproject/galaxy/pull/3215
.. _Pull Request 3216: https://github.com/galaxyproject/galaxy/pull/3216
.. _Pull Request 3217: https://github.com/galaxyproject/galaxy/pull/3217
.. _Pull Request 3218: https://github.com/galaxyproject/galaxy/pull/3218
.. _Pull Request 3221: https://github.com/galaxyproject/galaxy/pull/3221
.. _Pull Request 3222: https://github.com/galaxyproject/galaxy/pull/3222
.. _Pull Request 3223: https://github.com/galaxyproject/galaxy/pull/3223
.. _Pull Request 3228: https://github.com/galaxyproject/galaxy/pull/3228
.. _Pull Request 3230: https://github.com/galaxyproject/galaxy/pull/3230
.. _Pull Request 3233: https://github.com/galaxyproject/galaxy/pull/3233
.. _Pull Request 3237: https://github.com/galaxyproject/galaxy/pull/3237
.. _Pull Request 3239: https://github.com/galaxyproject/galaxy/pull/3239
.. _Pull Request 3240: https://github.com/galaxyproject/galaxy/pull/3240
.. _Pull Request 3253: https://github.com/galaxyproject/galaxy/pull/3253
.. _Pull Request 3256: https://github.com/galaxyproject/galaxy/pull/3256
.. _Pull Request 3258: https://github.com/galaxyproject/galaxy/pull/3258
.. _Pull Request 3264: https://github.com/galaxyproject/galaxy/pull/3264
.. _Pull Request 3271: https://github.com/galaxyproject/galaxy/pull/3271
.. _Pull Request 3274: https://github.com/galaxyproject/galaxy/pull/3274
.. _Pull Request 3283: https://github.com/galaxyproject/galaxy/pull/3283
.. _Pull Request 3285: https://github.com/galaxyproject/galaxy/pull/3285
.. _Pull Request 3286: https://github.com/galaxyproject/galaxy/pull/3286
.. _Pull Request 3288: https://github.com/galaxyproject/galaxy/pull/3288
.. _Pull Request 3290: https://github.com/galaxyproject/galaxy/pull/3290
.. _Pull Request 3291: https://github.com/galaxyproject/galaxy/pull/3291
.. _Pull Request 3294: https://github.com/galaxyproject/galaxy/pull/3294
.. _Pull Request 3301: https://github.com/galaxyproject/galaxy/pull/3301
.. _Pull Request 3304: https://github.com/galaxyproject/galaxy/pull/3304
.. _Pull Request 3305: https://github.com/galaxyproject/galaxy/pull/3305
.. _Pull Request 3306: https://github.com/galaxyproject/galaxy/pull/3306
.. _Pull Request 3313: https://github.com/galaxyproject/galaxy/pull/3313
.. _Pull Request 3319: https://github.com/galaxyproject/galaxy/pull/3319
.. _Pull Request 3324: https://github.com/galaxyproject/galaxy/pull/3324
.. _Pull Request 3325: https://github.com/galaxyproject/galaxy/pull/3325
.. _Pull Request 3327: https://github.com/galaxyproject/galaxy/pull/3327
.. _Pull Request 3328: https://github.com/galaxyproject/galaxy/pull/3328
.. _Pull Request 3333: https://github.com/galaxyproject/galaxy/pull/3333
.. _Pull Request 3338: https://github.com/galaxyproject/galaxy/pull/3338
.. _Pull Request 3339: https://github.com/galaxyproject/galaxy/pull/3339
.. _Pull Request 3340: https://github.com/galaxyproject/galaxy/pull/3340
.. _Pull Request 3342: https://github.com/galaxyproject/galaxy/pull/3342
.. _Pull Request 3344: https://github.com/galaxyproject/galaxy/pull/3344
.. _Pull Request 3345: https://github.com/galaxyproject/galaxy/pull/3345
.. _Pull Request 3346: https://github.com/galaxyproject/galaxy/pull/3346
.. _Pull Request 3348: https://github.com/galaxyproject/galaxy/pull/3348
.. _Pull Request 3349: https://github.com/galaxyproject/galaxy/pull/3349
.. _Pull Request 3356: https://github.com/galaxyproject/galaxy/pull/3356
.. _Pull Request 3358: https://github.com/galaxyproject/galaxy/pull/3358
.. _Pull Request 3362: https://github.com/galaxyproject/galaxy/pull/3362
.. _Pull Request 3364: https://github.com/galaxyproject/galaxy/pull/3364
.. _Pull Request 3365: https://github.com/galaxyproject/galaxy/pull/3365
.. _Pull Request 3367: https://github.com/galaxyproject/galaxy/pull/3367
.. _Pull Request 3368: https://github.com/galaxyproject/galaxy/pull/3368
.. _Pull Request 3369: https://github.com/galaxyproject/galaxy/pull/3369
.. _Pull Request 3370: https://github.com/galaxyproject/galaxy/pull/3370
.. _Pull Request 3371: https://github.com/galaxyproject/galaxy/pull/3371
.. _Pull Request 3373: https://github.com/galaxyproject/galaxy/pull/3373
.. _Pull Request 3377: https://github.com/galaxyproject/galaxy/pull/3377
.. _Pull Request 3378: https://github.com/galaxyproject/galaxy/pull/3378
.. _Pull Request 3379: https://github.com/galaxyproject/galaxy/pull/3379
.. _Pull Request 3380: https://github.com/galaxyproject/galaxy/pull/3380
.. _Pull Request 3381: https://github.com/galaxyproject/galaxy/pull/3381
.. _Pull Request 3384: https://github.com/galaxyproject/galaxy/pull/3384
.. _Pull Request 3387: https://github.com/galaxyproject/galaxy/pull/3387
.. _Pull Request 3391: https://github.com/galaxyproject/galaxy/pull/3391
.. _Pull Request 3395: https://github.com/galaxyproject/galaxy/pull/3395
.. _Pull Request 3397: https://github.com/galaxyproject/galaxy/pull/3397
.. _Pull Request 3400: https://github.com/galaxyproject/galaxy/pull/3400
.. _Pull Request 3401: https://github.com/galaxyproject/galaxy/pull/3401
.. _Pull Request 3403: https://github.com/galaxyproject/galaxy/pull/3403
.. _Pull Request 3404: https://github.com/galaxyproject/galaxy/pull/3404
.. _Pull Request 3405: https://github.com/galaxyproject/galaxy/pull/3405
.. _Pull Request 3406: https://github.com/galaxyproject/galaxy/pull/3406
.. _Pull Request 3409: https://github.com/galaxyproject/galaxy/pull/3409
.. _Pull Request 3411: https://github.com/galaxyproject/galaxy/pull/3411
.. _Pull Request 3412: https://github.com/galaxyproject/galaxy/pull/3412
.. _Pull Request 3414: https://github.com/galaxyproject/galaxy/pull/3414
.. _Pull Request 3416: https://github.com/galaxyproject/galaxy/pull/3416
.. _Pull Request 3417: https://github.com/galaxyproject/galaxy/pull/3417
.. _Pull Request 3419: https://github.com/galaxyproject/galaxy/pull/3419
.. _Pull Request 3423: https://github.com/galaxyproject/galaxy/pull/3423
.. _Pull Request 3427: https://github.com/galaxyproject/galaxy/pull/3427
.. _Pull Request 3429: https://github.com/galaxyproject/galaxy/pull/3429
.. _Pull Request 3431: https://github.com/galaxyproject/galaxy/pull/3431
.. _Pull Request 3439: https://github.com/galaxyproject/galaxy/pull/3439
.. _Pull Request 3444: https://github.com/galaxyproject/galaxy/pull/3444
.. _Pull Request 3447: https://github.com/galaxyproject/galaxy/pull/3447
.. _Pull Request 3448: https://github.com/galaxyproject/galaxy/pull/3448
.. _Pull Request 3454: https://github.com/galaxyproject/galaxy/pull/3454
.. _Pull Request 3461: https://github.com/galaxyproject/galaxy/pull/3461
.. _Pull Request 3462: https://github.com/galaxyproject/galaxy/pull/3462
.. _Pull Request 3464: https://github.com/galaxyproject/galaxy/pull/3464
.. _Pull Request 3470: https://github.com/galaxyproject/galaxy/pull/3470
.. _Pull Request 3471: https://github.com/galaxyproject/galaxy/pull/3471
.. _Pull Request 3475: https://github.com/galaxyproject/galaxy/pull/3475
.. _Pull Request 3476: https://github.com/galaxyproject/galaxy/pull/3476
.. _Pull Request 3482: https://github.com/galaxyproject/galaxy/pull/3482
.. _Pull Request 3483: https://github.com/galaxyproject/galaxy/pull/3483
.. _Pull Request 3490: https://github.com/galaxyproject/galaxy/pull/3490
.. _Pull Request 3510: https://github.com/galaxyproject/galaxy/pull/3510
.. _Pull Request 3514: https://github.com/galaxyproject/galaxy/pull/3514
+68 -3
View File
@@ -3,8 +3,73 @@
January 2017 Galaxy Release (v 17.01)
===========================================================
.. include:: _header.rst
Schedule
Highlights
===========================================================
* Planned Freeze Date: 2017-01-02
* Planned Release Date: 2017-01-23
**Conda auto initialization is enabled by default**
After updating to 17.01 and upon starting Galaxy the Conda package manager will be installed automatically
within the Galaxy's workspace. This will enable your Galaxy to install tool dependencies from Conda channels
such as `BioConda <https://bioconda.github.io/>`__. Such channels are already being used for new and updated tools by IUC
and we suggest adopting this tool dependency resolution method to all tool developers instead of Tool Shed package
recipes - which are now considered deprecated.
Please see the details at the admin `documentation <https://docs.galaxyproject.org/en/master/admin/conda_faq.html>`__
**New interface for user preferences**
User preferences menu has been reworked for clarity and consistency.
Thanks to `@anuprulez <https://github.com/anuprulez>`__ and `@bgruening <https://github.com/bgruening>`__.
Implemented in `Pull Request 3118`_.
**Support for compressed FASTQ formats**
You can now upload compressed (with gzip or bzip2) FASTQ files without them being unpacked automatically (as it was until now).
For this to work you have to select the proper type when uploading (e.g. instead of ``fastqsanger`` you select ``fastqsanger.gz``
or ``fastqsanger.bz2`` for compressed files).
Existing tools will work as before and future tools will be able to consume archives and save space in your quota.
Thanks to `@abretaud <https://github.com/abretaud>`__, `@ashvark <https://github.com/ashvark>`__, `@jvolkening <https://github.com/jvolkening>`__, and `@mvdbeek <https://github.com/mvdbeek>`__.
Implemented in `Pull Request 3145`_, `PullRequest 3510`_ and `PullRequest 3514`_.
Get Galaxy
==========
The code lives at `Github <https://github.com/galaxyproject/galaxy>`__ and you should have `Git <https://git-scm.com/>`__ to obtain it.
To get a new Galaxy repository run:
.. code-block:: shell
$ git clone -b release_17.01 https://github.com/galaxyproject/galaxy.git
To update an existing Galaxy repository run:
.. code-block:: shell
$ git checkout release_17.01 && git pull --ff-only origin release_17.01
See `our wiki <https://wiki.galaxyproject.org/Develop/SourceCode>`__ for additional details regarding the source code locations.
Deprecation Notices
===================
* Galaxy tools no longer have access to Galaxy's core framework Python code during tool execution - see
`Pull Request 3364`_ for implementation details.
Previously, Galaxy's ``lib`` directory would be placed on a tool's PYTHONPATH - but this can cause different sorts of
conflicts with resolved dependencies and should never really have been part of the interface exposed to tools since
it makes both reproducibility and distribution of jobs difficult.
Unfortunately, there is a large number of Galaxy tools - both in the core distribution and in the Tool Shed - that depend on Galaxy internals. The ones we know about have been added to a whitelist as part of `Pull Request 3364`_
and we will continue to add there if we find more. If you discover a tool that has problems importing e.g. ``galaxy`` or
``galaxy_utils`` as a result of this release please let us know by `creating an issue
<https://github.com/galaxyproject/galaxy/issues/new>`__ with a link to the Tool Shed page of the tool.
If you have local tools that depend on these modules and you do not wish to use a formal dependency resolution mechanism
such as Conda, you can change the option ``preserve_python_environment`` in galaxy.ini from ``legacy`` to ``legacy_and_local``.
* Galaxy's 'repair repository' feature for installed repositories is deprecated and will be removed/replaced in the next release - `details <https://github.com/galaxyproject/galaxy/issues/2929>`__.
Release Notes
===========================================================
.. include:: 17.01.rst
:start-after: announce_start
.. include:: _thanks.rst
+10
View File
@@ -0,0 +1,10 @@
===========================================================
May 2017 Galaxy Release (v 17.05)
===========================================================
Schedule
===========================================================
* Planned Freeze Date: 2017-05-08
* Planned Release Date: 2017-05-29
+3 -1
View File
@@ -1,7 +1,9 @@
To stay up to date with Galaxy's progress watch our `screencasts <https://vimeo.com/galaxyproject>`__,
To stay up to date with Galaxy's progress watch our `screencasts <https://vimeo.com/galaxyproject>`__,
read our `wiki <https://wiki.galaxyproject.org/>`__, and follow
`@galaxyproject <https://twitter.com/galaxyproject>`__ on Twitter.
You can always reach us on `Gitter <https://gitter.im/galaxyproject/Lobby>`__ or `IRC <https://wiki.galaxyproject.org/Support/IRC>`__.
*Thanks for using Galaxy!*
`The Galaxy Team <https://wiki.galaxyproject.org/GalaxyTeam>`__
+1
View File
@@ -4,6 +4,7 @@ Releases
.. toctree::
:maxdepth: 1
17.01_announce
16.10_announce
16.07_announce
16.04_announce
@@ -1,18 +1,21 @@
layout: true
class: inverse, middle, large
name: left-aligned
class: left, middle
---
class: special
layout: true
class: center, middle
---
layout: introduction_slides
topic_name: Galaxy Architecture
# Galaxy Architecture
Nate, James, John, Rémi
.footnote[\#usegalaxy / @galaxyproject]
---
class: larger
### Please Interrupt!
We're here to answer your questions about Galaxy architecture!
@@ -23,13 +26,13 @@ We're here to answer your questions about Galaxy architecture!
---
class: larger
**Gitter:** [galaxyproject/Lobby](https://gitter.im/galaxyproject/Lobby)
**IRC:** irc.freenode.net#galaxyproject
**IRC:** [irc.freenode.net#galaxyproject](https://webchat.freenode.net/?channels=galaxyproject)
**GitHub:** github.com/galaxyproject
**GitHub:** [github.com/galaxyproject](https://github.com/galaxyproject)
**Twitter:**: #usegalaxy, @galaxyproject
**Twitter:** #usegalaxy, @galaxyproject
---
@@ -45,33 +48,37 @@ Contribution guidelines: http://bit.ly/gx-CONTRIBUTING-md
---
github.com/galaxyproject/**galaxy**
[github.com/galaxyproject/**galaxy**](https://github.com/galaxyproject/galaxy)
The main Galaxy application. Web interface, database model, job running, etc. Also includes other web applications including the **ToolShed** and **Reports**
The main Galaxy application.
Web interface, database model, job running, etc...
Also includes other web applications including the **ToolShed** and **Reports**
---
github.com/galaxyproject/**cloudman**
[github.com/galaxyproject/**cloudman**](https://github.com/galaxyproject/cloudman)
Galaxy CloudMan - a web application which manages a Galaxy cluster in
the cloud.
github.com/galaxyproject/**cloudlaunch**
[github.com/galaxyproject/**cloudlaunch**](https://github.com/galaxyproject/cloudlaunch)
CloudLaunch web application to make it wasy to launch images on a cloud, drives *https://launch.usegalaxy.org*
---
github.com/galaxyproject/**tools-iuc**
[github.com/galaxyproject/**tools-iuc**](https://github.com/galaxyproject/tools-iuc)
Galaxy tools maintained by *iuc* (the "Intergalactic Utilities Commission").
Galaxy tools maintained by the *IUC* ("Intergalactic Utilities Commission").
A variety of tools, generally of high quality including many of the core tools for Galaxy main.
Demonstrates *current tool development best practices* - development on
github and then deployed to test/main ToolSheds
github.com/galaxyproject/**tools-devteam**
[github.com/galaxyproject/**tools-devteam**](https://github.com/galaxyproject/tools-devteam)
Many older tools appearing on usegalaxy.org.
@@ -99,7 +106,7 @@ Other repositories with high quality tools:
---
github.com/galaxyproject/**starforge**
[github.com/galaxyproject/**starforge**](https://github.com/galaxyproject/starforge)
Build Galaxy Tool dependencies for the ToolShed in Docker containers
@@ -107,11 +114,12 @@ Build Galaxy framework dependencies as Python wheels
---
github.com/galaxyproject/**planemo**
[github.com/galaxyproject/**planemo**](https://github.com/galaxyproject/planemo)
Commande line utilities to assist in the development of Galaxy tools.
Linting, testing, deploying to ToolSheds... *The best practice approach
for Galaxy tool development!*
Linting, testing, deploying to ToolSheds...
*The best practice approach for Galaxy tool development!*
github.com/galaxyproject/**planemo-machine**
@@ -122,15 +130,15 @@ container, virtual machines, Google compute images
github.com/galaxyproject/**{ansible-\*, \*-playbook}**
Ansible components to automate almost every aspect of Galaxy installation and maintenance.
[Ansible](https://www.ansible.com/) components to automate almost every aspect of Galaxy installation and maintenance.
Ansible is an advanced configuration management system
These playbooks are used to maintain Galaxy main, cloud images, virtual machines, ...
These playbooks are used to maintain Galaxy main, cloud and Docker images, virtual machines, ...
---
github.com/galaxyproject/**pulsar**
[github.com/galaxyproject/**pulsar**](https://github.com/galaxyproject/pulsar)
Distributed job execution engine for Galaxy.
@@ -142,7 +150,7 @@ Can act as its own queuing system or access an existing cluster DRM.
---
github.com/galaxyproject/**bioblend**
[github.com/galaxyproject/**bioblend**](https://github.com/galaxyproject/bioblend)
Official Python client for the Galaxy, ToolShed, and CloudMan APIs.
@@ -150,15 +158,15 @@ Best documented path to scripting the Galaxy API.
---
- github.com/galaxyproject/**blend4php**
- github.com/**jmchilton/blend4j**
- github.com/**chapmanb/clj-blend**
- [github.com/galaxyproject/**blend4php**](https://github.com/galaxyproject/blend4php)
- [github.com/**jmchilton/blend4j**](https://github.com/jmchilton/blend4j)
- [github.com/**chapmanb/clj-blend**](https://github.com/chapmanb/clj-blend)
Galaxy API bindings for other languages.
---
github.com/**bgruening/docker-galaxy-stable**
[github.com/**bgruening/docker-galaxy-stable**](https://github.com/bgruening/docker-galaxy-stable)
High quality Docker containers for stable Galaxy environments.
@@ -235,7 +243,7 @@ the `run.sh` should "just work" and should work quickly.
So by default Galaxy does not require:
- Compilation - it fetches *binary wheels*.
- Compilation - it fetches *binary wheels* for your platform.
- A job manager - Galaxy can act as one.
- An external database server - Galaxy can use an sqlite database.
- A web proxy or external Python web server.
@@ -251,7 +259,7 @@ So by default Galaxy does not require:
???
Workflow, Data Libraries, Visualization, History, Tool Menu,
Many Grids
Many Grids, User and preference management.
---
@@ -267,8 +275,7 @@ class: white
???
User management and admin things, Reports and Tool Shed
Webapp
Admin things, Reports and Tool Shed Webapp
---
@@ -291,6 +298,8 @@ Webapp
---
template: left-aligned
### Galaxy WSGI Middleware
A WSGI function:
@@ -303,7 +312,7 @@ A WSGI function:
---
class: normal
template: left-aligned
### Galaxy's WSGI Middleware
@@ -320,11 +329,11 @@ Middleware configured in `galaxy.webapps.galaxy.buildapp#wrap_in_middleware`.
---
background-image: url(images/webapp.plantuml.svg)
![webapp](images/webapp.plantuml.svg)
---
class: normal
template: left-aligned
### Routes
@@ -348,7 +357,7 @@ Uses popular Routes library (https://pypi.python.org/pypi/Routes).
---
class: normal
template: left-aligned
Simplified `handle_request` from `lib/galaxy/web/framework/base.py`.
@@ -413,8 +422,6 @@ def handle_request(self, environ, start_response):
---
class: white, widen_image
![SQLAlchemy Architecture](images/sqla_arch_small.png)
---
@@ -432,7 +439,6 @@ class: white, widen_image
---
class: white, narrow_image
![Galaxy Schema](images/galaxy_schema.png)
### Database Diagram
@@ -494,8 +500,6 @@ Slides for datatypes, example of meta data definitions...
---
class: normal
### Object Store
.strike[```
@@ -514,10 +518,12 @@ class: normal
---
background-image: url(images/objectstore.plantuml.svg)
![Object Store](images/objectstore.plantuml.svg)
---
template: left-aligned
### Visualization Plugins
Adding new visualizations to a Galaxy instance
@@ -528,7 +534,7 @@ Adding new visualizations to a Galaxy instance
---
class: smaller
class: reduce70
```xml
<?xml version="1.0" encoding="UTF-8"?>
@@ -551,6 +557,8 @@ class: smaller
---
template: left-aligned
### Visualization Examples
All in `config/plugins/visualizations`:
@@ -586,6 +594,8 @@ Build a UI that accesses that process through a proxy
---
template: left-aligned
### Interactive Environments - Examples
All in `config/plugins/interactive_environments`:
@@ -612,6 +622,8 @@ in a manager instead of in the model.
---
template: left-aligned
### Client Directories
- Source stylesheets and JavaScript in `client/galaxy/{style|scripts}`
@@ -642,11 +654,13 @@ npm-deps: ## Install NodeJS dependencies.
---
template: left-aligned
### grunt
Build tool for node/JavaScript, tasks in `client/Gruntfile.js`. Default task is
.smaller[```grunt.registerTask( 'default', [ 'check-modules', 'uglify', 'webpack' ] );```]
.center[`grunt.registerTask( 'default', [ 'check-modules', 'uglify', 'webpack' ] );`]
- `check-modules` Verifies node dependencies are correct and exact.
- [`uglify`](https://github.com/mishoo/UglifyJS) Compresses JavaScript modules in `client` and move to `static` and creates source maps.
@@ -656,6 +670,8 @@ Build tool for node/JavaScript, tasks in `client/Gruntfile.js`. Default task is
---
template: left-aligned
### JavaScript Modules - The Problem
From http://requirejs.org/docs/why.html:
@@ -668,6 +684,8 @@ From http://requirejs.org/docs/why.html:
---
template: left-aligned
### JavaScript Modules - The Solution
From http://requirejs.org/docs/why.html:
@@ -681,8 +699,6 @@ RequireJS an implementation of AMD.
---
class: normal
### JavaScript Modules - Galaxy AMD Example
```javascript
@@ -737,6 +753,8 @@ class: white
---
template: left-aligned
### Dependencies - Python
`script/common_startup.sh` sets up a `virtualenv` with required dependencies in `$GALAXY_ROOT/.venv` (or `$GALAXY_VIRTUAL_ENV` if set).
@@ -750,6 +768,8 @@ class: white
---
template: left-aligned
### Dependencies - JavaScript
These come bundled with Galaxy, so do not need to be fetched at runtime.
@@ -764,8 +784,6 @@ These come bundled with Galaxy, so do not need to be fetched at runtime.
---
class: normal
### Cloning Galaxy
```
@@ -785,7 +803,7 @@ $ sh run.sh
---
class: normal
class: reduce90
### Copying Configs
@@ -823,7 +841,7 @@ Successfully installed pip-8.1.2
---
class: normal
class: reduce70
### Installing Dependencies
@@ -851,7 +869,7 @@ Successfully installed Babel-2.0 Beaker-1.7.0 Cheetah-2.4.4 Fabric-1.10.2 Mako-1
---
class: smaller
class: reduce70
### Initial Debugging as App Starts
@@ -871,7 +889,7 @@ galaxy.app DEBUG 2016-06-23 19:11:51,956 Using "galaxy.ini" config file:
---
class: normal
class: reduce70
### Database Migrations
@@ -905,7 +923,7 @@ Everything after here happens every time
---
class: smaller
class: reduce70
.code[```
migrate.versioning.repository DEBUG 2016-06-23 19:13:35,635 Loading repository lib/tool_shed/galaxy_install/migrate...
@@ -928,7 +946,7 @@ galaxy.config INFO 2016-06-23 19:13:35,679 Install database targetting Galaxy's
---
class: smaller
class: reduce70
.code[```
galaxy.datatypes.registry DEBUG 2016-06-23 19:13:35,748 Loading datatypes from ./config/datatypes_conf.xml.sample
@@ -956,7 +974,7 @@ galaxy.datatypes.registry DEBUG 2016-06-23 19:13:35,824 Retrieved datatype modul
---
class: smaller
class: reduce70
.code[```
galaxy.datatypes.registry DEBUG 2016-06-23 19:13:35,824 Loaded sniffer for datatype 'galaxy.datatypes.mothur:Sabund'
@@ -1001,7 +1019,7 @@ galaxy.datatypes.registry DEBUG 2016-06-23 19:13:35,833 Loaded sniffer for datat
---
class: smaller
class: reduce70
.code[```
galaxy.datatypes.registry DEBUG 2016-06-23 19:13:35,833 Loaded build site 'ucsc': tool-data/shared/ucsc/ucsc_build_sites.txt with display sites: main,test,archaea,ucla
@@ -1014,7 +1032,7 @@ galaxy.datatypes.registry DEBUG 2016-06-23 19:13:35,834 Loaded build site 'rview
---
class: smaller
class: reduce70
.code[```
galaxy.tools.data INFO 2016-06-23 19:13:35,871 Could not find tool data tool-data/all_fasta.loc, reading sample
@@ -1031,7 +1049,7 @@ galaxy.tools.data DEBUG 2016-06-23 19:13:36,211 Loaded tool data table 'biom_sim
---
class: normal
class: reduce70
### Job Configuration, Citation Cache
@@ -1043,7 +1061,7 @@ beaker.container DEBUG 2016-06-23 19:13:36,278 data file ./database/citations/da
---
class: smaller
class: reduce70
### Load Toolbox
@@ -1062,7 +1080,7 @@ galaxy.tools.toolbox.base INFO 2016-06-23 19:13:36,497 Parsing the tool configur
---
class: smaller
class: reduce90
### Tool Dependency Resolution and Indexing
@@ -1076,7 +1094,7 @@ galaxy.tools.search DEBUG 2016-06-23 19:13:37,789 Toolbox index finished. It too
---
class: smaller
class: reduce70
### Display Applications
@@ -1098,7 +1116,7 @@ galaxy.datatypes.registry DEBUG 2016-06-23 19:13:38,007 Adding inherited display
---
class: smaller
class: reduce70
### Datatype Converters
@@ -1117,7 +1135,7 @@ galaxy.datatypes.registry DEBUG 2016-06-23 19:13:38,099 Loaded converter: CONVER
---
class: normal
class: reduce90
### Special Tools
@@ -1129,7 +1147,7 @@ galaxy.tools.special_tools DEBUG 2016-06-23 19:13:38,108 Loaded history export t
---
class: normal
class: reduce70
### Vizualization Plugins
@@ -1148,8 +1166,6 @@ galaxy.web.base.pluginframework INFO 2016-06-23 19:13:38,114 VisualizationsRegis
---
class: normal
### Tours
.code[```
@@ -1160,7 +1176,7 @@ galaxy.tours INFO 2016-06-23 19:13:38,183 Loaded tour 'core.history'
---
class: normal
class: reduce90
### Job Handler and Runners
@@ -1178,7 +1194,7 @@ galaxy.jobs.handler INFO 2016-06-23 19:13:38,222 job handler queue started
---
class: normal
class: reduce70
### Ignore this...
@@ -1189,7 +1205,7 @@ galaxy.sample_tracking.external_service_types DEBUG 2016-06-23 19:13:38,230 Load
---
class: normal
class: reduce90
### Workflow Scheduler
@@ -1199,7 +1215,7 @@ galaxy.workflow.scheduling_manager DEBUG 2016-06-23 19:13:38,254 Starting workfl
---
class: normal
class: reduce90
### Controllers
@@ -1218,7 +1234,7 @@ galaxy.web.framework.base DEBUG 2016-06-23 19:13:38,728 Enabling 'workflow_tags'
---
class: normal
class: reduce90
### Middleware
@@ -1233,7 +1249,7 @@ galaxy.webapps.galaxy.buildapp DEBUG 2016-06-23 19:13:39,044 Enabling 'Request I
---
class: normal
class: reduce70
### Static Paths for Viz
@@ -1246,6 +1262,8 @@ galaxy.webapps.galaxy.buildapp DEBUG 2016-06-23 19:13:39,049 added url, path to
---
class: reduce90
### It is Up!
.code[```
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

@@ -2,14 +2,14 @@ skinparam handwritten true
' skinparam roundcorner 20
skinparam class {
ArrowFontColor #FFEFD5
ArrowFontColor DarkOrange
BackgroundColor #FFEFD5
ArrowColor Orange
BorderColor DarkOrange
}
skinparam object {
ArrowFontColor #FFEFD5
ArrowFontColor DarkOrange
BackgroundColor #FFEFD5
ArrowColor Orange
BorderColor DarkOrange
@@ -22,7 +22,7 @@ skinparam note {
skinparam sequence {
ArrowColor Orange
ArrowFontColor #FFEFD5
ArrowFontColor DarkOrange
ActorBorderColor DarkOrange
ActorBackgroundColor #FFEFD5
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

+131 -168
View File
@@ -1,99 +1,165 @@
@import url(https://fonts.googleapis.com/css?family=Oxygen);
@import url(https://fonts.googleapis.com/css?family=Consolas);
@import url(https://fonts.googleapis.com/css?family=Droid+Serif);
@import url(https://fonts.googleapis.com/css?family=Yanone+Kaffeesatz);
@import url(https://fonts.googleapis.com/css?family=Droid+Serif:400,700,400italic);
@import url(https://fonts.googleapis.com/css?family=Ubuntu+Mono:400,700,400italic);
body {
font-family: 'Oxygen', 'PT Sans', Serif;
}
body { font-family: 'Droid Serif'; }
h1, h2, h3 {
font-weight: bold;
}
h1 {
font-size: 3em;
color: #ff9300;
}
h2 { font-size: 2em; }
.title h1, h2 {
margin-bottom: 0px;
margin-top: 0px;
font-family: 'Yanone Kaffeesatz';
font-weight: normal;
text-align: center;
}
.title p {
margin-top: 50px;
text-align: center;
}
.centered {
text-align: center;
}
img {
max-width: 100%;
}
.widen_image img {
max-width: 100%;
h3{
position: absolute;
top: 30px;
left: 0px;
width: 100%;
}
.narrow_image img {
height: 500px;
.packed h3{
position: absolute;
top: 10px;
left: 0px;
width: 100%;
margin-top:0px;
}
h3 {
font-size: 1.8em;
position: absolute;
top: .5em;
.hljs-monokai .hljs {
display: block;
overflow-x: auto;
padding: .5em;
background: #272822;
color: #ddd;
}
.remark-code, .remark-inline-code {
font-family: 'Ubuntu Mono';
text-align: left;
}
.remark-code{
font-size: 18px;
}
.remark-code-line {
min-height: 1em;
}
ul, ol {
text-align: left;
}
img{
max-height: 400px;
max-width: 700px;
}
.image-10 img {
width: 10%;
}
.image-25 img {
width: 25%;
}
.image-50 img {
width: 50%;
}
.image-75 img {
width: 75%;
}
.footnote {
position: absolute;
bottom: 3em;
bottom: 60px;
left: 0px;
width: 100%;
font-size: 15px;
color: #444444;
}
.large {
font-size: 1.6em;
.my-footer {
position: absolute;
bottom: 0px;
left: 0px;
height: 50px;
width: 100%;
}
.larger {
font-size: 2em;
.my-footer span {
font-size: 10pt;
position: absolute;
left: 15px;
bottom: 2px;
}
li p { line-height: 1.25em; }
.normal {
font-size: 1em;
.remark-slide-number {
font-size: 12px;
}
.smaller {
font-size: .8em;
}
a, a > code {
color: #ff9300;
a{
text-decoration: none;
}
.code > pre, .code > code {
white-space: pre-wrap;
td, th {
text-align: left;
padding-left: 5px;
padding-right: 5px;
border-bottom: 1px solid #ddd;
}
.remark-code, .remark-inline-code {
font-family: 'Consolas';
color: #ff9300;
font-size: 1.1em;
.left-column5 {
width: 5%;
float: left;
}
.slightly-smaller {
font-size: .9em;
.right-column95 {
width: 93%;
float: right;
}
.remark-code-line-highlighted {
background-color: #373832;
.left-column95 {
width: 93%;
float: left;
}
.right-column5 {
width: 5%;
float: right;
}
.reduce90 {
font-size: 90%;
}
.reduce90 .remark-code{
font-size: 16px;
}
.reduce70 {
font-size: 70%;
}
.reduce70 .remark-code{
font-size: 12px;
}
.enlarge120 {
font-size: 120%;
}
.enlarge120 .remark-code{
font-size: 22px;
}
.strike {
text-decoration: line-through;
}
.pull-left {
float: left;
width: 47%;
@@ -105,106 +171,3 @@ a, a > code {
.pull-right ~ p {
clear: both;
}
#slideshow .slide .content code {
}
#slideshow .slide .content pre code {
}
.inverse {
background-color: #000;
background-repeat: no-repeat;
background-position: center;
background-size: contain;
color: #ffffff;
}
i, em, b, strong {
color: #ff9300;
}
.inverse h1, .inverse h2 {
color: #f3f3f3;
line-height: 0.8em;
}
.white {
background-color: #ffffff;
background-repeat: no-repeat;
background-position: center;
background-size: contain;
color: #000;
}
.strike {
text-decoration: line-through;
}
/* Slide-specific styling */
#slide-inverse .footnote {
bottom: 12px;
left: 20px;
}
#slide-how .slides {
font-size: 0.9em;
position: absolute;
top: 151px;
right: 140px;
}
#slide-how .slides h3 {
margin-top: 0.2em;
}
#slide-how .slides .first, #slide-how .slides .second {
padding: 1px 20px;
height: 90px;
width: 120px;
-moz-box-shadow: 0 0 10px #777;
-webkit-box-shadow: 0 0 10px #777;
box-shadow: 0 0 10px #777;
}
#slide-how .slides .first {
background: #fff;
position: absolute;
top: 20%;
left: 20%;
z-index: 1;
}
#slide-how .slides .second {
position: relative;
background: #fff;
z-index: 0;
}
/* Two-column layout */
.left-column {
color: #777;
width: 20%;
height: 92%;
float: left;
}
.left-column h2:last-of-type, .left-column h3:last-child {
color: #000;
}
.right-column {
width: 75%;
float: right;
padding-top: 1em;
}
/*First slide h1 orange, h2 white*/
.special h1 {
color: #ff8800;
}
.special p {
color: #cbcbcb;
}
.special {
color: #ff8800;
}
/* Emphasis 2 */
.special2 {
color: #00f900;
}
+3 -2
View File
@@ -3,13 +3,14 @@ Created on 15/07/2014
@author: Andrew Robinson
"""
import abc
import six
@six.add_metaclass(abc.ABCMeta)
class AuthProvider(object):
"""A base class for all Auth Providers."""
__metaclass__ = abc.ABCMeta
@abc.abstractproperty
def plugin_type(self):
+16 -20
View File
@@ -15,7 +15,7 @@ log = logging.getLogger(__name__)
def _get_subs(d, k, params):
if k not in d:
if k not in d or not d[k]:
raise ConfigurationError("Missing '%s' parameter in LDAP options" % k)
return str(d[k]).format(**params)
@@ -25,17 +25,17 @@ def _parse_ldap_options(ldap, options_unparsed):
if not options_unparsed:
return []
if "=" not in options_unparsed:
log.error("LDAP authenticate: Invalid syntax in <ldap-options>. Syntax should be option1=value1,option2=value2")
return []
ldap_options = []
# Valid options must start with this prefix. See help(ldap)
prefix = "OPT_"
for opt in options_unparsed.split(","):
key, value = opt.split("=")
try:
key, value = opt.split("=")
except ValueError:
log.warning("LDAP authenticate: Invalid syntax '%s' inside <ldap-options> element. Syntax should be option1=value1,option2=value2" % opt)
continue
try:
pair = []
@@ -109,14 +109,18 @@ class LDAP(AuthProvider):
else:
ldap_options = _parse_ldap_options(ldap, ldap_options_raw)
try:
# setup connection
ldap.set_option(ldap.OPT_REFERRALS, 0)
for opt in ldap_options:
ldap.set_option(*opt)
except Exception:
log.exception('LDAP authenticate: set_option exception')
return (failure_mode, '', '')
if 'search-fields' in options:
try:
# setup connection
ldap.set_option(ldap.OPT_REFERRALS, 0)
for opt in ldap_options:
ldap.set_option(*opt)
l = ldap.initialize(_get_subs(options, 'server', params))
l.protocol_version = 3
@@ -155,17 +159,9 @@ class LDAP(AuthProvider):
# bind as user to check their credentials
try:
# setup connection
ldap.set_option(ldap.OPT_REFERRALS, 0)
for opt in ldap_options:
ldap.set_option(*opt)
l = ldap.initialize(_get_subs(options, 'server', params))
l.protocol_version = 3
bind_password = _get_subs(options, 'bind-password', params)
if not bind_password:
raise RuntimeError('LDAP authenticate: empty password')
l.simple_bind_s(_get_subs(
options, 'bind-user', params), bind_password)
try:
+129 -71
View File
@@ -32,6 +32,47 @@ from .version import VERSION_MAJOR
log = logging.getLogger( __name__ )
PATH_DEFAULTS = dict(
auth_config_file=['config/auth_conf.xml', 'config/auth_conf.xml.sample'],
data_manager_config_file=['config/data_manager_conf.xml', 'data_manager_conf.xml', 'config/data_manager_conf.xml.sample'],
datatypes_config_file=['config/datatypes_conf.xml', 'datatypes_conf.xml', 'config/datatypes_conf.xml.sample'],
build_sites_config_file=['config/build_sites.yml', 'config/build_sites.yml.sample'],
external_service_type_config_file=['config/external_service_types_conf.xml', 'external_service_types_conf.xml', 'config/external_service_types_conf.xml.sample'],
job_config_file=['config/job_conf.xml', 'job_conf.xml'],
tool_destinations_config_file=['config/tool_destinations.yml', 'config/tool_destinations.yml.sample'],
job_metrics_config_file=['config/job_metrics_conf.xml', 'job_metrics_conf.xml', 'config/job_metrics_conf.xml.sample'],
dependency_resolvers_config_file=['config/dependency_resolvers_conf.xml', 'dependency_resolvers_conf.xml'],
job_resource_params_file=['config/job_resource_params_conf.xml', 'job_resource_params_conf.xml'],
migrated_tools_config=['migrated_tools_conf.xml', 'config/migrated_tools_conf.xml'],
object_store_config_file=['config/object_store_conf.xml', 'object_store_conf.xml'],
openid_config_file=['config/openid_conf.xml', 'openid_conf.xml', 'config/openid_conf.xml.sample'],
shed_data_manager_config_file=['shed_data_manager_conf.xml', 'config/shed_data_manager_conf.xml'],
shed_tool_data_table_config=['shed_tool_data_table_conf.xml', 'config/shed_tool_data_table_conf.xml'],
tool_sheds_config_file=['config/tool_sheds_conf.xml', 'tool_sheds_conf.xml', 'config/tool_sheds_conf.xml.sample'],
workflow_schedulers_config_file=['config/workflow_schedulers_conf.xml', 'config/workflow_schedulers_conf.xml.sample'],
modules_mapping_files=['config/environment_modules_mapping.yml', 'config/environment_modules_mapping.yml.sample'],
local_conda_mapping_file=['config/local_conda_mapping.yml', 'config/local_conda_mapping.yml.sample'],
)
PATH_LIST_DEFAULTS = dict(
tool_data_table_config_path=['config/tool_data_table_conf.xml', 'tool_data_table_conf.xml', 'config/tool_data_table_conf.xml.sample'],
# rationale:
# [0]: user has explicitly created config/tool_conf.xml but did not
# move their existing shed_tool_conf.xml, don't use
# config/shed_tool_conf.xml, which is probably the empty
# version copied from the sample, or else their shed tools
# will disappear
# [1]: user has created config/tool_conf.xml and, having passed
# [0], probably moved their shed_tool_conf.xml as well
# [2]: user has done nothing, use the old files
# [3]: fresh install
tool_config_file=['config/tool_conf.xml,shed_tool_conf.xml',
'config/tool_conf.xml,config/shed_tool_conf.xml',
'tool_conf.xml,shed_tool_conf.xml',
'config/tool_conf.xml.sample,config/shed_tool_conf.xml']
)
def resolve_path( path, root ):
"""If 'path' is relative make absolute by prepending 'root'"""
if not os.path.isabs( path ):
@@ -39,12 +80,34 @@ def resolve_path( path, root ):
return path
def find_path(kwargs, var, root):
"""Find a configuration path that may exist at different defaults."""
defaults = PATH_DEFAULTS[var]
if kwargs.get(var, None) is not None:
path = kwargs.get(var)
else:
for default in defaults:
if os.path.exists(resolve_path(default, root)):
path = default
break
else:
path = defaults[-1]
return resolve_path(path, root)
def find_root(kwargs):
root = kwargs.get('root_dir', '.')
return root
class Configuration( object ):
deprecated_options = ( 'database_file', )
def __init__( self, **kwargs ):
self.config_dict = kwargs
self.root = kwargs.get( 'root_dir', '.' )
self.root = find_root(kwargs)
# Resolve paths of other config files
self.__parse_config_file_options( kwargs )
@@ -61,6 +124,7 @@ class Configuration( object ):
self.database_engine_options = get_database_engine_options( kwargs )
self.database_create_tables = string_as_bool( kwargs.get( "database_create_tables", "True" ) )
self.database_query_profiling_proxy = string_as_bool( kwargs.get( "database_query_profiling_proxy", "False" ) )
self.slow_query_log_threshold = float( kwargs.get( "slow_query_log_threshold", 0) )
# Don't set this to true for production databases, but probably should
# default to True for sqlite databases.
@@ -261,6 +325,8 @@ class Configuration( object ):
self.force_beta_workflow_scheduled_min_steps = int( kwargs.get( 'force_beta_workflow_scheduled_min_steps', '250' ) )
self.force_beta_workflow_scheduled_for_collections = string_as_bool( kwargs.get( 'force_beta_workflow_scheduled_for_collections', 'False' ) )
self.history_local_serial_workflow_scheduling = string_as_bool( kwargs.get( 'history_local_serial_workflow_scheduling', 'False' ) )
# Per-user Job concurrency limitations
self.cache_user_job_count = string_as_bool( kwargs.get( 'cache_user_job_count', False ) )
self.user_job_limit = int( kwargs.get( 'user_job_limit', 0 ) )
@@ -315,6 +381,7 @@ class Configuration( object ):
self.allow_library_path_paste = kwargs.get( 'allow_library_path_paste', False )
self.disable_library_comptypes = kwargs.get( 'disable_library_comptypes', '' ).lower().split( ',' )
self.watch_tools = kwargs.get( 'watch_tools', 'false' )
self.watch_tool_data_dir = kwargs.get( 'watch_tool_data_dir', 'false' )
# On can mildly speed up Galaxy startup time by disabling index of help,
# not needed on production systems but useful if running many functional tests.
self.index_tool_help = string_as_bool( kwargs.get( "index_tool_help", True ) )
@@ -325,24 +392,26 @@ class Configuration( object ):
self.tool_stub_boost = kwargs.get( "tool_stub_boost", 5 )
self.tool_help_boost = kwargs.get( "tool_help_boost", 0.5 )
self.tool_search_limit = kwargs.get( "tool_search_limit", 20 )
self.tool_enable_ngram_search = kwargs.get( "tool_enable_ngram_search", False )
self.tool_ngram_minsize = kwargs.get( "tool_ngram_minsize", 3 )
self.tool_ngram_maxsize = kwargs.get( "tool_ngram_maxsize", 4 )
# Location for tool dependencies.
# Location for tool dependencies.
tool_dependency_dir = kwargs.get( "tool_dependency_dir", "database/dependencies" )
if tool_dependency_dir.lower() == "none":
tool_dependency_dir = None
if tool_dependency_dir is not None:
self.tool_dependency_dir = resolve_path( tool_dependency_dir, self.root )
# Setting the following flag to true will ultimately cause tool dependencies
# to be located in the shell environment and used by the job that is executing
# the tool.
self.use_tool_dependencies = True
use_tool_dependencies, tool_dependency_dir, use_cached_dependency_manager, tool_dependency_cache_dir, precache_dependencies = \
parse_dependency_options(kwargs, self.root, self.dependency_resolvers_config_file)
self.use_tool_dependencies = use_tool_dependencies
self.tool_dependency_dir = tool_dependency_dir
self.use_cached_dependency_manager = use_cached_dependency_manager
self.tool_dependency_cache_dir = tool_dependency_cache_dir
self.precache_dependencies = precache_dependencies
# Deployers may either specify a complete list of mapping files or get the default for free and just
# specify a local mapping file to adapt and extend the default one.
if "conda_mapping_files" in kwargs:
self.conda_mapping_files = kwargs["conda_mapping_files"]
else:
self.tool_dependency_dir = None
self.use_tool_dependencies = os.path.exists(self.dependency_resolvers_config_file)
self.use_cached_dependency_manager = string_as_bool(kwargs.get("use_cached_dependency_manager", 'False'))
self.tool_dependency_cache_dir = kwargs.get( 'tool_dependency_cache_dir', os.path.join(self.tool_dependency_dir, '_cache'))
self.precache_dependencies = string_as_bool(kwargs.get("precache_dependencies", 'True'))
self.conda_mapping_files = [
self.local_conda_mapping_file,
os.path.join(self.root, "lib", "galaxy", "tools", "deps", "resolvers", "default_conda_mapping.yml"),
]
self.enable_beta_mulled_containers = string_as_bool( kwargs.get( 'enable_beta_mulled_containers', 'False' ) )
containers_resolvers_config_file = kwargs.get( 'containers_resolvers_config_file', None )
@@ -508,6 +577,8 @@ class Configuration( object ):
elif ie_dirs:
self.visualization_plugins_directory += ",%s" % ie_dirs
self.gie_swarm_mode = string_as_bool( kwargs.get( 'interactive_environment_swarm_mode', False ) )
self.proxy_session_map = self.resolve_path( kwargs.get( "dynamic_proxy_session_map", "database/session_map.sqlite" ) )
self.manage_dynamic_proxy = string_as_bool( kwargs.get( "dynamic_proxy_manage", "True" ) ) # Set to false if being launched externally
self.dynamic_proxy_debug = string_as_bool( kwargs.get( "dynamic_proxy_debug", "False" ) )
@@ -555,56 +626,11 @@ class Configuration( object ):
"""
Backwards compatibility for config files moved to the config/ dir.
"""
defaults = dict(
auth_config_file=[ 'config/auth_conf.xml', 'config/auth_conf.xml.sample' ],
data_manager_config_file=[ 'config/data_manager_conf.xml', 'data_manager_conf.xml', 'config/data_manager_conf.xml.sample' ],
datatypes_config_file=[ 'config/datatypes_conf.xml', 'datatypes_conf.xml', 'config/datatypes_conf.xml.sample' ],
external_service_type_config_file=[ 'config/external_service_types_conf.xml', 'external_service_types_conf.xml', 'config/external_service_types_conf.xml.sample' ],
job_config_file=[ 'config/job_conf.xml', 'job_conf.xml' ],
tool_destinations_config_file=[ 'config/tool_destinations.yml', 'config/tool_destinations.yml.sample' ],
job_metrics_config_file=[ 'config/job_metrics_conf.xml', 'job_metrics_conf.xml', 'config/job_metrics_conf.xml.sample' ],
dependency_resolvers_config_file=[ 'config/dependency_resolvers_conf.xml', 'dependency_resolvers_conf.xml' ],
job_resource_params_file=[ 'config/job_resource_params_conf.xml', 'job_resource_params_conf.xml' ],
migrated_tools_config=[ 'migrated_tools_conf.xml', 'config/migrated_tools_conf.xml' ],
object_store_config_file=[ 'config/object_store_conf.xml', 'object_store_conf.xml' ],
openid_config_file=[ 'config/openid_conf.xml', 'openid_conf.xml', 'config/openid_conf.xml.sample' ],
shed_data_manager_config_file=[ 'shed_data_manager_conf.xml', 'config/shed_data_manager_conf.xml' ],
shed_tool_data_table_config=[ 'shed_tool_data_table_conf.xml', 'config/shed_tool_data_table_conf.xml' ],
tool_sheds_config_file=[ 'config/tool_sheds_conf.xml', 'tool_sheds_conf.xml', 'config/tool_sheds_conf.xml.sample' ],
workflow_schedulers_config_file=['config/workflow_schedulers_conf.xml', 'config/workflow_schedulers_conf.xml.sample'],
)
listify_defaults = dict(
tool_data_table_config_path=[ 'config/tool_data_table_conf.xml', 'tool_data_table_conf.xml', 'config/tool_data_table_conf.xml.sample' ],
# rationale:
# [0]: user has explicitly created config/tool_conf.xml but did not
# move their existing shed_tool_conf.xml, don't use
# config/shed_tool_conf.xml, which is probably the empty
# version copied from the sample, or else their shed tools
# will disappear
# [1]: user has created config/tool_conf.xml and, having passed
# [0], probably moved their shed_tool_conf.xml as well
# [2]: user has done nothing, use the old files
# [3]: fresh install
tool_config_file=[ 'config/tool_conf.xml,shed_tool_conf.xml',
'config/tool_conf.xml,config/shed_tool_conf.xml',
'tool_conf.xml,shed_tool_conf.xml',
'config/tool_conf.xml.sample,config/shed_tool_conf.xml' ]
)
for var in PATH_DEFAULTS:
setattr( self, var, find_path( kwargs, var, self.root ) )
for var, defaults in defaults.items():
if kwargs.get( var, None ) is not None:
path = kwargs.get( var )
else:
for default in defaults:
if os.path.exists( resolve_path( default, self.root ) ):
path = default
break
else:
path = defaults[-1]
setattr( self, var, resolve_path( path, self.root ) )
for var, defaults in listify_defaults.items():
for var, defaults in PATH_LIST_DEFAULTS.items():
paths = []
if kwargs.get( var, None ) is not None:
paths = listify( kwargs.get( var ) )
@@ -755,6 +781,31 @@ class Configuration( object ):
return [ parse( v ) for v in allowed_origin_hostnames if v ]
def parse_dependency_options(kwargs, root, dependency_resolvers_config_file):
# Location for tool dependencies.
tool_dependency_dir = kwargs.get("tool_dependency_dir", "database/dependencies")
if tool_dependency_dir.lower() == "none":
tool_dependency_dir = None
if tool_dependency_dir is not None:
tool_dependency_dir = resolve_path(tool_dependency_dir, root)
# Setting the following flag to true will ultimately cause tool dependencies
# to be located in the shell environment and used by the job that is executing
# the tool.
use_tool_dependencies = True
tool_dependency_cache_dir = kwargs.get('tool_dependency_cache_dir', os.path.join(tool_dependency_dir, '_cache'))
use_cached_dependency_manager = string_as_bool(kwargs.get("use_cached_dependency_manager", 'False'))
precache_dependencies = string_as_bool(kwargs.get("precache_dependencies", 'True'))
else:
tool_dependency_dir = None
use_tool_dependencies = os.path.exists(dependency_resolvers_config_file)
tool_dependency_cache_dir = None
precache_dependencies = False
use_cached_dependency_manager = False
return use_tool_dependencies, tool_dependency_dir, use_cached_dependency_manager, tool_dependency_cache_dir, precache_dependencies
def get_database_engine_options( kwargs, model_prefix='' ):
"""
Allow options for the SQLAlchemy database engine to be passed by using
@@ -784,15 +835,21 @@ def get_database_engine_options( kwargs, model_prefix='' ):
def configure_logging( config ):
"""
Allow some basic logging configuration to be read from ini file.
"""Allow some basic logging configuration to be read from ini file.
This should be able to consume either a galaxy.config.Configuration object
or a simple dictionary of configuration variables.
"""
# Get root logger
root = logging.getLogger()
# PasteScript will have already configured the logger if the
# 'loggers' section was found in the config file, otherwise we do
# some simple setup using the 'log_*' values from the config.
paste_configures_logging = config.global_conf_parser.has_section( "loggers" )
parser = getattr(config, "global_conf_parser", None)
if parser:
paste_configures_logging = config.global_conf_parser.has_section( "loggers" )
else:
paste_configures_logging = False
auto_configure_logging = not paste_configures_logging and string_as_bool( config.get( "auto_configure_logging", "True" ) )
if auto_configure_logging:
format = config.get( "log_format", "%(name)s %(levelname)s %(asctime)s %(message)s" )
@@ -823,7 +880,7 @@ def configure_logging( config ):
handler.setFormatter( formatter )
root.addHandler( handler )
# If sentry is configured, also log to it
if config.sentry_dsn:
if getattr(config, "sentry_dsn", None):
from raven.handlers.logging import SentryHandler
sentry_handler = SentryHandler( config.sentry_dsn )
sentry_handler.setLevel( logging.WARN )
@@ -911,7 +968,7 @@ class ConfiguresGalaxyMixin:
def _configure_datatypes_registry( self, installed_repository_manager=None ):
from galaxy.datatypes import registry
# Create an empty datatypes registry.
self.datatypes_registry = registry.Registry()
self.datatypes_registry = registry.Registry( self.config )
if installed_repository_manager:
# Load proprietary datatypes defined in datatypes_conf.xml files in all installed tool shed repositories. We
# load proprietary datatypes before datatypes in the distribution because Galaxy's default sniffers include some
@@ -985,7 +1042,8 @@ class ConfiguresGalaxyMixin:
database_query_profiling_proxy=self.config.database_query_profiling_proxy,
object_store=self.object_store,
trace_logger=getattr(self, "trace_logger", None),
use_pbkdf2=self.config.get_bool( 'use_pbkdf2', True ) )
use_pbkdf2=self.config.get_bool( 'use_pbkdf2', True ),
slow_query_log_threshold=self.config.slow_query_log_threshold )
if combined_install_database:
log.info("Install database targetting Galaxy's database configuration.")
@@ -1,13 +1,18 @@
from galaxy import exceptions
from abc import ABCMeta
from abc import abstractmethod
import logging
from abc import (
ABCMeta,
abstractmethod
)
import six
from galaxy import exceptions
log = logging.getLogger( __name__ )
@six.add_metaclass(ABCMeta)
class DatasetCollectionType(object):
__metaclass__ = ABCMeta
@abstractmethod
def generate_elements( self, dataset_instances ):
+31 -31
View File
@@ -15,6 +15,7 @@ import six
from galaxy import util
from galaxy.datatypes.metadata import MetadataElement # import directly to maintain ease of use in Datatype class definitions
from galaxy.util import compression_utils
from galaxy.util import FILENAME_VALID_CHARS
from galaxy.util import inflector
from galaxy.util import unicodify
@@ -593,8 +594,8 @@ class Data( object ):
files[ substitute_composite_key( key, value ) ] = value
return files
def generate_auto_primary_file( self, dataset=None ):
raise Exception( "generate_auto_primary_file is not implemented for this datatype." )
def generate_primary_file( self, dataset=None ):
raise Exception( "generate_primary_file is not implemented for this datatype." )
@property
def has_resolution(self):
@@ -976,39 +977,38 @@ def get_file_peek( file_name, is_multi_byte=False, WIDTH=256, LINE_COUNT=5, skip
count = 0
file_type = None
data_checked = False
temp = open( file_name, "U" )
while count < LINE_COUNT:
line = temp.readline( WIDTH )
if line and not is_multi_byte and not data_checked:
# See if we have a compressed or binary file
if line[0:2] == util.gzip_magic:
file_type = 'gzipped'
else:
temp = compression_utils.get_fileobj( file_name, "U" )
try:
while count < LINE_COUNT:
line = temp.readline( WIDTH )
if line and not is_multi_byte and not data_checked:
# See if we have a compressed or binary file
for char in line:
if ord( char ) > 128:
file_type = 'binary'
break
data_checked = True
if file_type in [ 'gzipped', 'binary' ]:
break
if not line_wrap:
if line.endswith('\n'):
line = line[:-1]
else:
while True:
i = temp.read(1)
if not i or i == '\n':
break
skip_line = False
for skipchar in skipchars:
if line.startswith( skipchar ):
skip_line = True
break
if not skip_line:
lines.append( line )
count += 1
temp.close()
if file_type in [ 'gzipped', 'binary' ]:
data_checked = True
if file_type == 'binary':
break
if not line_wrap:
if line.endswith('\n'):
line = line[:-1]
else:
while True:
i = temp.read(1)
if not i or i == '\n':
break
skip_line = False
for skipchar in skipchars:
if line.startswith( skipchar ):
skip_line = True
break
if not skip_line:
lines.append( line )
count += 1
finally:
temp.close()
if file_type == 'binary':
text = "%s file" % file_type
else:
try:
+32 -32
View File
@@ -11,18 +11,18 @@ subsequent row values are all numeric ! Will fail if any non numeric (eg '+' or
ross lazarus for rgenetics
august 20 2007
"""
import logging
import os
import re
import sys
import urllib
from cgi import escape
from six.moves.urllib.parse import quote_plus
from galaxy.datatypes import metadata
from galaxy.datatypes.text import Html
from galaxy.datatypes.metadata import MetadataElement
from galaxy.datatypes.tabular import Tabular
from galaxy.datatypes.text import Html
from galaxy.util import nice_size
from galaxy.web import url_for
@@ -95,9 +95,9 @@ class GenomeGraphs( Tabular ):
action='display_at',
filename='ucsc_' + site_name )
display_url = "%s%s/display_as?id=%i&display_app=%s&authz_method=display_at" % (base_url, url_for( controller='root' ), dataset.id, type)
display_url = urllib.quote_plus( display_url )
# was display_url = urllib.quote_plus( "%s/display_as?id=%i&display_app=%s" % (base_url, dataset.id, type) )
# redirect_url = urllib.quote_plus( "%sdb=%s&position=%s:%s-%s&hgt.customText=%%s" % (site_url, dataset.dbkey, chrom, start, stop) )
display_url = quote_plus( display_url )
# was display_url = quote_plus( "%s/display_as?id=%i&display_app=%s" % (base_url, dataset.id, type) )
# redirect_url = quote_plus( "%sdb=%s&position=%s:%s-%s&hgt.customText=%%s" % (site_url, dataset.dbkey, chrom, start, stop) )
sl = ["%sdb=%s" % (site_url, dataset.dbkey ), ]
# sl.append("&hgt.customText=%s")
sl.append("&hgGenome_dataSetName=%s&hgGenome_dataSetDescription=%s" % (dataset.name, 'GalaxyGG_data'))
@@ -106,7 +106,7 @@ class GenomeGraphs( Tabular ):
sl.append("&hgGenome_doSubmitUpload=submit")
sl.append("&hgGenome_maxGapToFill=25000000&hgGenome_uploadFile=%s" % display_url)
s = ''.join(sl)
s = urllib.quote_plus(s)
s = quote_plus(s)
redirect_url = s
link = '%s?redirect_url=%s&display_url=%s' % ( internal_url, redirect_url, display_url )
ret_val.append( (site_name, link) )
@@ -117,17 +117,17 @@ class GenomeGraphs( Tabular ):
Create HTML table, used for displaying peek
"""
out = ['<table cellspacing="0" cellpadding="3">']
f = open(dataset.file_name, 'r')
d = f.readlines()[:5]
if len(d) == 0:
out = "Cannot find anything to parse in %s" % dataset.name
return out
hasheader = 0
try:
['%f' % x for x in d[0][1:]] # first is name - see if starts all numerics
except:
hasheader = 1
try:
with open(dataset.file_name, 'r') as f:
d = f.readlines()[:5]
if len(d) == 0:
out = "Cannot find anything to parse in %s" % dataset.name
return out
hasheader = 0
try:
['%f' % x for x in d[0][1:]] # first is name - see if starts all numerics
except:
hasheader = 1
# Generate column header
out.append( '<tr>' )
if hasheader:
@@ -150,16 +150,16 @@ class GenomeGraphs( Tabular ):
Validate a gg file - all numeric after header row
"""
errors = list()
infile = open(dataset.file_name, "r")
infile.next() # header
for i, row in enumerate(infile):
ll = row.strip().split('\t')[1:] # first is alpha feature identifier
badvals = []
for j, x in enumerate(ll):
try:
x = float(x)
except:
badvals.append('col%d:%s' % (j + 1, x))
with open(dataset.file_name, "r") as infile:
next(infile) # header
for i, row in enumerate(infile):
ll = row.strip().split('\t')[1:] # first is alpha feature identifier
badvals = []
for j, x in enumerate(ll):
try:
x = float(x)
except:
badvals.append('col%d:%s' % (j + 1, x))
if len(badvals) > 0:
errors.append('row %d, %s' % (' '.join(badvals)))
return errors
@@ -219,7 +219,7 @@ class rgTabList(Tabular):
def display_peek( self, dataset ):
"""Returns formated html of peek"""
return Tabular.make_html_table( self, dataset, column_names=self.column_names )
return self.make_html_table( dataset, column_names=self.column_names )
def get_mime(self):
"""Returns the mime type of the datatype"""
@@ -246,8 +246,8 @@ class rgSampleList(rgTabList):
# this is what Plink wants as at 2009
def sniff(self, filename):
infile = open(filename, "r")
header = infile.next() # header
with open(filename, "r") as infile:
header = next(infile) # header
if header[0] == 'FID' and header[1] == 'IID':
return True
else:
@@ -287,7 +287,7 @@ class Rgenetics(Html):
def generate_primary_file( self, dataset=None ):
rval = ['<html><head><title>Rgenetics Galaxy Composite Dataset </title></head><p/>']
rval.append('<div>This composite dataset is composed of the following files:<p/><ul>')
for composite_name, composite_file in self.get_composite_files( dataset=dataset ).iteritems():
for composite_name, composite_file in self.get_composite_files( dataset=dataset ).items():
fn = composite_name
opt_text = ''
if composite_file.optional:
@@ -617,7 +617,7 @@ class RexpBase( Html ):
del useConc[i] # get rid of concordance
del useCols[i] # and usecols entry
for i, conc in enumerate(useConc): # these are all unique columns for the design matrix
ccounts = sorted([(conc.get(code, 0), code) for code in conc.keys()]) # decorate
ccounts = sorted((conc.get(code, 0), code) for code in conc.keys()) # decorate
cc = [(x[1], x[0]) for x in ccounts] # list of code count tuples
codeDetails = (head[useCols[i]], cc) # ('foo',[('a',3),('b',11),..])
listCol.append(codeDetails)
+32 -30
View File
@@ -6,10 +6,10 @@ import math
import os
import sys
import tempfile
import urllib
import numpy
from bx.intervals.io import GenomicIntervalReader, ParseError
from six.moves.urllib.parse import quote_plus
from galaxy import util
from galaxy.datatypes import metadata
@@ -19,8 +19,10 @@ from galaxy.datatypes.tabular import Tabular
from galaxy.datatypes.util.gff_util import parse_gff_attributes
from galaxy.web import url_for
import data
import dataproviders
from . import (
data,
dataproviders
)
log = logging.getLogger(__name__)
@@ -86,7 +88,7 @@ class Interval( Tabular ):
self.init_meta( dataset )
line = line.strip( '#' )
elems = line.split( '\t' )
for meta_name, header_list in alias_spec.iteritems():
for meta_name, header_list in alias_spec.items():
for header_val in header_list:
if header_val in elems:
# found highest priority header to meta_name
@@ -239,7 +241,7 @@ class Interval( Tabular ):
def display_peek( self, dataset ):
"""Returns formated html of peek"""
return Tabular.make_html_table( self, dataset, column_parameter_alias={'chromCol': 'Chrom', 'startCol': 'Start', 'endCol': 'End', 'strandCol': 'Strand', 'nameCol': 'Name'} )
return self.make_html_table( dataset, column_parameter_alias={'chromCol': 'Chrom', 'startCol': 'Start', 'endCol': 'End', 'strandCol': 'Strand', 'nameCol': 'Name'} )
def ucsc_links( self, dataset, type, app, base_url ):
"""
@@ -263,10 +265,10 @@ class Interval( Tabular ):
for site_name, site_url in valid_sites:
internal_url = url_for( controller='dataset', dataset_id=dataset.id,
action='display_at', filename='ucsc_' + site_name )
display_url = urllib.quote_plus( "%s%s/display_as?id=%i&display_app=%s&authz_method=display_at"
% (base_url, url_for( controller='root' ), dataset.id, type) )
redirect_url = urllib.quote_plus( "%sdb=%s&position=%s:%s-%s&hgt.customText=%%s"
% (site_url, dataset.dbkey, chrom, start, stop ) )
display_url = quote_plus( "%s%s/display_as?id=%i&display_app=%s&authz_method=display_at" %
(base_url, url_for( controller='root' ), dataset.id, type) )
redirect_url = quote_plus( "%sdb=%s&position=%s:%s-%s&hgt.customText=%%s" %
(site_url, dataset.dbkey, chrom, start, stop ) )
link = '%s?redirect_url=%s&display_url=%s' % ( internal_url, redirect_url, display_url )
ret_val.append( ( site_name, link ) )
return ret_val
@@ -286,7 +288,7 @@ class Interval( Tabular ):
while True:
try:
reader.next()
next(reader)
except ParseError as e:
errors.append(e)
except StopIteration:
@@ -635,8 +637,8 @@ class _RemoteCallMixin:
"""
internal_url = "%s" % url_for( controller='dataset', dataset_id=dataset.id, action='display_at', filename='%s_%s' % ( type, site_name ) )
base_url = app.config.get( "display_at_callback", base_url )
display_url = urllib.quote_plus( "%s%s/display_as?id=%i&display_app=%s&authz_method=display_at" %
( base_url, url_for( controller='root' ), dataset.id, type ) )
display_url = quote_plus( "%s%s/display_as?id=%i&display_app=%s&authz_method=display_at" %
( base_url, url_for( controller='root' ), dataset.id, type ) )
link = '%s?redirect_url=%s&display_url=%s' % ( internal_url, redirect_url, display_url )
return link
@@ -723,7 +725,7 @@ class Gff( Tabular, _RemoteCallMixin ):
def display_peek( self, dataset ):
"""Returns formated html of peek"""
return Tabular.make_html_table( self, dataset, column_names=self.column_names )
return self.make_html_table( dataset, column_names=self.column_names )
def get_estimated_display_viewport( self, dataset ):
"""
@@ -808,7 +810,7 @@ class Gff( Tabular, _RemoteCallMixin ):
if seqid is not None:
for site_name, site_url in app.datatypes_registry.get_legacy_sites_by_build('ucsc', dataset.dbkey ):
if site_name in app.datatypes_registry.get_display_sites('ucsc'):
redirect_url = urllib.quote_plus(
redirect_url = quote_plus(
"%sdb=%s&position=%s:%s-%s&hgt.customText=%%s" %
( site_url, dataset.dbkey, seqid, start, stop ) )
link = self._get_remote_call_url( redirect_url, site_name, dataset, type, app, base_url )
@@ -823,7 +825,7 @@ class Gff( Tabular, _RemoteCallMixin ):
if site_name in app.datatypes_registry.get_display_sites('gbrowse'):
if seqid.startswith( 'chr' ) and len( seqid ) > 3:
seqid = seqid[3:]
redirect_url = urllib.quote_plus( "%s/?q=%s:%s..%s&eurl=%%s" % ( site_url, seqid, start, stop ) )
redirect_url = quote_plus( "%s/?q=%s:%s..%s&eurl=%%s" % ( site_url, seqid, start, stop ) )
link = self._get_remote_call_url( redirect_url, site_name, dataset, type, app, base_url )
ret_val.append( ( site_name, link ) )
return ret_val
@@ -1170,7 +1172,7 @@ class Wiggle( Tabular, _RemoteCallMixin ):
if site_name in app.datatypes_registry.get_display_sites('gbrowse'):
if chrom.startswith( 'chr' ) and len( chrom ) > 3:
chrom = chrom[3:]
redirect_url = urllib.quote_plus( "%s/?q=%s:%s..%s&eurl=%%s" % ( site_url, chrom, start, stop ) )
redirect_url = quote_plus( "%s/?q=%s:%s..%s&eurl=%%s" % ( site_url, chrom, start, stop ) )
link = self._get_remote_call_url( redirect_url, site_name, dataset, type, app, base_url )
ret_val.append( ( site_name, link ) )
return ret_val
@@ -1181,14 +1183,14 @@ class Wiggle( Tabular, _RemoteCallMixin ):
if chrom is not None:
for site_name, site_url in app.datatypes_registry.get_legacy_sites_by_build('ucsc', dataset.dbkey ):
if site_name in app.datatypes_registry.get_display_sites('ucsc'):
redirect_url = urllib.quote_plus( "%sdb=%s&position=%s:%s-%s&hgt.customText=%%s" % ( site_url, dataset.dbkey, chrom, start, stop ) )
redirect_url = quote_plus( "%sdb=%s&position=%s:%s-%s&hgt.customText=%%s" % ( site_url, dataset.dbkey, chrom, start, stop ) )
link = self._get_remote_call_url( redirect_url, site_name, dataset, type, app, base_url )
ret_val.append( ( site_name, link ) )
return ret_val
def display_peek( self, dataset ):
"""Returns formated html of peek"""
return Tabular.make_html_table( self, dataset, skipchars=['track', '#'] )
return self.make_html_table( dataset, skipchars=['track', '#'] )
def set_meta( self, dataset, overwrite=True, **kwd ):
max_data_lines = None
@@ -1266,7 +1268,7 @@ class Wiggle( Tabular, _RemoteCallMixin ):
x = numpy.arange( t_start, t_end ) * resolution
y = data[ t_start : t_end ]
return zip(x.tolist(), y.tolist())
return list(zip(x.tolist(), y.tolist()))
def get_track_resolution( self, dataset, start, end):
range = end - start
@@ -1305,7 +1307,7 @@ class CustomTrack ( Tabular ):
def display_peek( self, dataset ):
"""Returns formated html of peek"""
return Tabular.make_html_table( self, dataset, skipchars=['track', '#'] )
return self.make_html_table( dataset, skipchars=['track', '#'] )
def get_estimated_display_viewport( self, dataset, chrom_col=None, start_col=None, end_col=None ):
"""Return a chrom, start, stop tuple for viewing a file."""
@@ -1372,8 +1374,8 @@ class CustomTrack ( Tabular ):
for site_name, site_url in app.datatypes_registry.get_legacy_sites_by_build('ucsc', dataset.dbkey):
if site_name in app.datatypes_registry.get_display_sites('ucsc'):
internal_url = "%s" % url_for( controller='dataset', dataset_id=dataset.id, action='display_at', filename='ucsc_' + site_name )
display_url = urllib.quote_plus( "%s%s/display_as?id=%i&display_app=%s&authz_method=display_at" % (base_url, url_for( controller='root' ), dataset.id, type) )
redirect_url = urllib.quote_plus( "%sdb=%s&position=%s:%s-%s&hgt.customText=%%s" % (site_url, dataset.dbkey, chrom, start, stop ) )
display_url = quote_plus( "%s%s/display_as?id=%i&display_app=%s&authz_method=display_at" % (base_url, url_for( controller='root' ), dataset.id, type) )
redirect_url = quote_plus( "%sdb=%s&position=%s:%s-%s&hgt.customText=%%s" % (site_url, dataset.dbkey, chrom, start, stop ) )
link = '%s?redirect_url=%s&display_url=%s' % ( internal_url, redirect_url, display_url )
ret_val.append( (site_name, link) )
return ret_val
@@ -1519,6 +1521,14 @@ class ScIdx(Tabular):
fh = open(filename, "r")
while True:
line = fh.readline()
if not line:
# EOF
if count > 1:
# The second line is always the labels:
# chrom index forward reverse value
# We need at least the column labels and a data line.
return True
return False
line = line.strip()
# The first line is always a comment like this:
# 2015-11-23 20:18:56.51;input.bam;READ1
@@ -1528,14 +1538,6 @@ class ScIdx(Tabular):
continue
else:
return False
if not line:
# EOF
if count > 1:
# The second line is always the labels:
# chrom index forward reverse value
# We need at least the column labels and a data line.
return True
return False
# Skip first line.
if count > 1:
items = line.split('\t')
+4 -2
View File
@@ -270,7 +270,8 @@ class AlignCheck(Tabular):
dataset.metadata.column_names = self.column_names
dataset.metadata.column_types = self.column_types
dataset.metadata.comment_lines = self.comment_lines
dataset.metadata.data_lines -= self.comment_lines
if isinstance(dataset.metadata.data_lines, int):
dataset.metadata.data_lines -= self.comment_lines
class AlignReport(Tabular):
@@ -735,7 +736,8 @@ class CountTable(Tabular):
dataset.metadata.groups = colnames[2:]
dataset.metadata.comment_lines = 1
dataset.metadata.data_lines -= 1
if isinstance(dataset.metadata.data_lines, int):
dataset.metadata.data_lines -= 1
class RefTaxonomy(Tabular):
+12 -4
View File
@@ -61,12 +61,12 @@ class PepXmlReport(Tabular):
file_ext = "pepxml.tsv"
def __init__(self, **kwd):
Tabular.__init__(self, **kwd)
super(PepXmlReport, self).__init__(**kwd)
self.column_names = ['Protein', 'Peptide', 'Assumed Charge', 'Neutral Pep Mass (calculated)', 'Neutral Mass', 'Retention Time', 'Start Scan', 'End Scan', 'Search Engine', 'PeptideProphet Probability', 'Interprophet Probabaility']
def display_peek(self, dataset):
"""Returns formated html of peek"""
return Tabular.make_html_table(self, dataset, column_names=self.column_names)
return self.make_html_table(dataset, column_names=self.column_names)
class ProtXmlReport(Tabular):
@@ -76,7 +76,7 @@ class ProtXmlReport(Tabular):
comment_lines = 1
def __init__(self, **kwd):
Tabular.__init__(self, **kwd)
super(ProtXmlReport, self).__init__(**kwd)
self.column_names = [
"Entry Number", "Group Probability",
"Protein", "Protein Link", "Protein Probability",
@@ -91,7 +91,7 @@ class ProtXmlReport(Tabular):
def display_peek(self, dataset):
"""Returns formated html of peek"""
return Tabular.make_html_table(self, dataset, column_names=self.column_names)
return self.make_html_table(dataset, column_names=self.column_names)
class ProteomicsXml(GenericXml):
@@ -152,6 +152,14 @@ class MzXML(ProteomicsXml):
root = "mzXML"
class MzData(ProteomicsXml):
"""mzData data"""
edam_format = "format_3245"
file_ext = "mzdata"
blurb = "mzData Mass Spectrometry data"
root = "mzData"
class MzIdentML(ProteomicsXml):
edam_format = "format_3247"
file_ext = "mzid"
+54 -22
View File
@@ -4,9 +4,14 @@ Provides mapping between extensions and datatypes, mime-types, etc.
from __future__ import absolute_import
import os
import tempfile
import logging
import imp
import logging
import tempfile
import yaml
import galaxy.util
from . import data
from . import tabular
from . import interval
@@ -18,7 +23,6 @@ from . import coverage
from . import tracks
from . import binary
from . import text
import galaxy.util
from galaxy.util.odict import odict
from .display_applications.application import DisplayApplication
@@ -29,9 +33,10 @@ class ConfigurationError( Exception ):
class Registry( object ):
def __init__( self ):
def __init__( self, config=None ):
self.log = logging.getLogger(__name__)
self.log.addHandler( logging.NullHandler() )
self.config = config
self.datatypes_by_extension = {}
self.mimetypes_by_extension = {}
self.datatype_converters = odict()
@@ -295,7 +300,7 @@ class Registry( object ):
override=override )
self.upload_file_formats.sort()
# Load build sites
self.load_build_sites( root )
self._load_build_sites( root )
# Persist the xml form of the registry into a temporary file so that it can be loaded from the command line by tools and
# set_metadata processing.
self.to_xml_file()
@@ -314,23 +319,50 @@ class Registry( object ):
self.sniff_order.append( datatype )
append_to_sniff_order()
def load_build_sites( self, root ):
def _load_build_sites( self, root ):
def load_build_site( build_site_config ):
# Take in either an XML element or simple dictionary from YAML and add build site for this.
if not (build_site_config.get( 'type' ) and build_site_config.get( 'file' )):
self.log.exception( "Site is missing required 'type' and 'file' attributes: %s" )
return
site_type = build_site_config.get( 'type' )
path = build_site_config.get( 'file' )
if not os.path.exists( path ):
sample_path = "%s.sample" % path
if os.path.exists( sample_path ):
self.log.debug( "Build site file [%s] not found using sample [%s]." % ( path, sample_path ) )
path = sample_path
self.build_sites[site_type] = path
if site_type in ('ucsc', 'gbrowse'):
self.legacy_build_sites[site_type] = galaxy.util.read_build_sites( path )
if build_site_config.get( 'display', None ):
display = build_site_config.get( 'display' )
if not isinstance( display, list ):
display = [ x.strip() for x in display.lower().split( ',' ) ]
self.display_sites[site_type] = display
self.log.debug( "Loaded build site '%s': %s with display sites: %s", site_type, path, display )
else:
self.log.debug( "Loaded build site '%s': %s", site_type, path )
if root.find( 'build_sites' ) is not None:
for elem in root.find( 'build_sites' ).findall( 'site' ):
if not (elem.get( 'type' ) and elem.get( 'file' )):
self.log.exception( "Site is missing required 'type' and 'file' attributes: %s" )
else:
site_type = elem.get( 'type' )
file = elem.get( 'file' )
self.build_sites[site_type] = file
if site_type in ('ucsc', 'gbrowse'):
self.legacy_build_sites[site_type] = galaxy.util.read_build_sites( file )
if elem.get( 'display', None ):
display = elem.get( 'display' )
self.display_sites[site_type] = [ x.strip() for x in display.lower().split( ',' ) ]
self.log.debug( "Loaded build site '%s': %s with display sites: %s", site_type, file, display )
else:
self.log.debug( "Loaded build site '%s': %s", site_type, file )
load_build_site( elem )
else:
build_sites_config_file = getattr( self.config, "build_sites_config_file", None )
if build_sites_config_file and os.path.exists( build_sites_config_file ):
with open( build_sites_config_file, "r" ) as f:
build_sites_config = yaml.load( f )
if not isinstance( build_sites_config, list ):
self.log.exception( "Build sites configuration YAML file does not declare list of sites." )
return
for build_site_config in build_sites_config:
load_build_site( build_site_config )
else:
self.log.debug("No build sites source located.")
def get_legacy_sites_by_build( self, site_type, build ):
sites = []
@@ -478,7 +510,7 @@ class Registry( object ):
data.init_meta( copy_from=data )
return data
def load_datatype_converters( self, toolbox, installed_repository_dict=None, deactivate=False ):
def load_datatype_converters( self, toolbox, installed_repository_dict=None, deactivate=False, use_cached=False ):
"""
If deactivate is False, add datatype converters from self.converters or self.proprietary_converters
to the calling app's toolbox. If deactivate is True, eliminates relevant converters from the calling
@@ -500,7 +532,7 @@ class Registry( object ):
converter_path = self.converters_path
try:
config_path = os.path.join( converter_path, tool_config )
converter = toolbox.load_tool( config_path )
converter = toolbox.load_tool( config_path, use_cached=use_cached )
if installed_repository_dict:
# If the converter is included in an installed tool shed repository, set the tool
# shed related tool attributes.
+48 -56
View File
@@ -2,8 +2,6 @@
Sequence classes
"""
import bz2
import gzip
import json
import logging
import os
@@ -19,7 +17,10 @@ from galaxy.datatypes import metadata
from galaxy.datatypes.binary import Binary
from galaxy.datatypes.metadata import MetadataElement
from galaxy.datatypes.sniff import get_headers
from galaxy.util import nice_size
from galaxy.util import (
compression_utils,
nice_size
)
from galaxy.util.checkers import (
is_bz2,
is_gzip
@@ -33,6 +34,8 @@ if sys.version_info > (3,):
log = logging.getLogger(__name__)
SNIFF_COMPRESSED_FASTQS = os.environ.get("GALAXY_ENABLE_BETA_COMPRESSED_FASTQ_SNIFFING", "0") == "1"
class SequenceSplitLocations( data.Text ):
"""
@@ -140,22 +143,13 @@ class Sequence( data.Text ):
if input_datasets[0].metadata is not None and input_datasets[0].metadata.sequences is not None:
total_sequences = input_datasets[0].metadata.sequences
else:
input_file = input_datasets[0].file_name
compress = is_gzip(input_file)
if compress:
# gzip is really slow before python 2.7!
in_file = gzip.GzipFile(input_file, 'r')
else:
# TODO
# if a file is not compressed, seek locations can be calculated and stored
# ideally, this would be done in metadata
# TODO
# Add BufferedReader if python 2.7?
in_file = open(input_file, 'rt')
total_sequences = long(0)
for i, line in enumerate(in_file):
total_sequences += 1
in_file.close()
in_file = compression_utils.get_fileobj(input_datasets[0].file_name)
try:
total_sequences = long(0)
for i, line in enumerate(in_file):
total_sequences += 1
finally:
in_file.close()
total_sequences /= 4
sequences_per_file = cls.get_sequences_per_file(total_sequences, split_params)
@@ -576,15 +570,8 @@ class BaseFastq ( Sequence ):
data_lines = 0
sequences = 0
seq_counter = 0 # blocks should be 4 lines long
compressed_gzip = is_gzip(dataset.file_name)
compressed_bzip2 = is_bz2(dataset.file_name)
in_file = compression_utils.get_fileobj(dataset.file_name)
try:
if compressed_gzip:
in_file = gzip.GzipFile(dataset.file_name)
elif compressed_bzip2:
in_file = bz2.BZ2File(dataset.file_name)
else:
in_file = open(dataset.file_name)
for line in in_file:
line = line.strip()
if line and line.startswith( '#' ) and not data_lines:
@@ -638,6 +625,20 @@ class BaseFastq ( Sequence ):
except:
return False
def display_data(self, trans, dataset, preview=False, filename=None, to_ext=None, **kwd):
if preview:
fh = compression_utils.get_fileobj(dataset.file_name)
max_peek_size = 1000000 # 1 MB
if os.stat( dataset.file_name ).st_size < max_peek_size:
mime = "text/plain"
self._clean_and_set_mime_type( trans, mime )
return fh.read()
return trans.stream_template_mako( "/dataset/large_file.mako",
truncated_data=fh.read(max_peek_size),
data=dataset)
else:
return Sequence.display_data(self, trans, dataset, preview, filename, to_ext, **kwd)
def split( cls, input_datasets, subdir_generator_function, split_params):
"""
FASTQ files are split on cluster boundaries, in increments of 4 lines
@@ -720,9 +721,17 @@ class FastqGz ( BaseFastq, Binary ):
"""Class representing a generic compressed FASTQ sequence"""
edam_format = "format_1930"
file_ext = "fastq.gz"
compressed = True
def sniff( self, filename ):
"""Determines whether the file is in gzip-compressed FASTQ format"""
if not is_gzip(filename):
return False
return BaseFastq.sniff( self, filename )
Binary.register_sniffable_binary_format("fastq.gz", "fastq.gz", FastqGz)
if SNIFF_COMPRESSED_FASTQS:
Binary.register_sniffable_binary_format("fastq.gz", "fastq.gz", FastqGz)
class FastqSangerGz( FastqGz ):
@@ -731,42 +740,38 @@ class FastqSangerGz( FastqGz ):
file_ext = "fastqsanger.gz"
Binary.register_sniffable_binary_format("fastqsanger.gz", "fastqsanger.gz", FastqSangerGz)
class FastqSolexaGz( FastqGz ):
"""Class representing a compressed FASTQ sequence ( the Solexa variant )"""
edam_format = "format_1933"
file_ext = "fastqsolexa.gz"
Binary.register_sniffable_binary_format("fastqsolexa.gz", "fastqsolexa.gz", FastqSolexaGz)
class FastqIlluminaGz( FastqGz ):
"""Class representing a compressed FASTQ sequence ( the Illumina 1.3+ variant )"""
edam_format = "format_1931"
file_ext = "fastqillumina.gz"
Binary.register_sniffable_binary_format("fastqillumina.gz", "fastqillumina.gz", FastqIlluminaGz)
class FastqCSSangerGz( FastqGz ):
"""Class representing a Color Space compressed FASTQ sequence ( e.g a SOLiD variant )"""
file_ext = "fastqcssanger.gz"
Binary.register_sniffable_binary_format("fastqcssanger.gz", "fastqcssanger.gz", FastqCSSangerGz)
class FastqBz2 ( BaseFastq, Binary ):
"""Class representing a generic compressed FASTQ sequence"""
edam_format = "format_1930"
file_ext = "fastq.gz"
file_ext = "fastq.bz2"
compressed = True
def sniff( self, filename ):
"""Determine whether the file is in bzip2-compressed FASTQ format"""
if not is_bz2(filename):
return False
return BaseFastq.sniff( self, filename )
Binary.register_sniffable_binary_format("fastq.gz", "fastq.gz", FastqGz)
if SNIFF_COMPRESSED_FASTQS:
Binary.register_sniffable_binary_format("fastq.bz2", "fastq.bz2", FastqBz2)
class FastqSangerBz2( FastqBz2 ):
@@ -775,35 +780,23 @@ class FastqSangerBz2( FastqBz2 ):
file_ext = "fastqsanger.bz2"
Binary.register_sniffable_binary_format("fastqsanger.bz2", "fastqsanger.bz2", FastqSangerBz2)
class FastqSolexaBz2( FastqBz2 ):
"""Class representing a compressed FASTQ sequence ( the Solexa variant )"""
edam_format = "format_1933"
file_ext = "fastqsolexa.bz2"
Binary.register_sniffable_binary_format("fastqsolexa.bz2", "fastqsolexa.bz2", FastqSolexaBz2)
class FastqIlluminaBz2( FastqBz2 ):
"""Class representing a compressed FASTQ sequence ( the Illumina 1.3+ variant )"""
edam_format = "format_1931"
file_ext = "fastqillumina.bz2"
Binary.register_sniffable_binary_format("fastqillumina.bz2", "fastqillumina.bz2", FastqIlluminaBz2)
class FastqCSSangerBz2( FastqBz2 ):
"""Class representing a Color Space compressed FASTQ sequence ( e.g a SOLiD variant )"""
file_ext = "fastqcssanger.bz2"
Binary.register_sniffable_binary_format("fastqcssanger.bz2", "fastqcssanger.bz2", FastqCSSangerBz2)
class Maf( Alignment ):
"""Class describing a Maf alignment"""
edam_format = "format_3008"
@@ -1190,8 +1183,7 @@ class Genbank(data.Text):
def sniff(self, filename):
try:
with open(filename, 'r') as handle:
line = handle.readline().strip()
return line.startswith('LOCUS ')
return 'LOCUS ' == handle.read(6)
except:
pass
+8 -12
View File
@@ -18,7 +18,10 @@ from six import text_type
from galaxy import util
from galaxy.util import multi_byte
from galaxy.util import unicodify
from galaxy.util import (
compression_utils,
unicodify
)
from galaxy.util.checkers import (
check_binary,
check_html,
@@ -204,15 +207,8 @@ def get_headers( fname, sep, count=60, is_multi_byte=False ):
[['chr7', '127475281', '127491632', 'NM_000230', '0', '+', '127486022', '127488767', '0', '3', '29,172,3225,', '0,10713,13126,'], ['chr7', '127486011', '127488900', 'D49487', '0', '+', '127486022', '127488767', '0', '2', '155,490,', '0,2399']]
"""
headers = []
compressed_gzip = is_gzip(fname)
compressed_bzip2 = is_bz2(fname)
in_file = compression_utils.get_fileobj(fname)
try:
if compressed_gzip:
in_file = gzip.GzipFile(fname, 'r')
elif compressed_bzip2:
in_file = bz2.BZ2File(fname, 'r')
else:
in_file = open(fname, 'rt')
for idx, line in enumerate(in_file):
line = line.rstrip('\n\r')
if is_multi_byte:
@@ -490,9 +486,9 @@ def handle_uploaded_dataset_file( filename, datatypes_registry, ext='auto', is_m
AUTO_DETECT_EXTENSIONS = [ 'auto' ] # should 'data' also cause auto detect?
DECOMPRESSION_FUNCTIONS = dict( gzip=gzip.GzipFile )
COMPRESSION_CHECK_FUNCTIONS = [ ( 'gzip', is_gzip ) ]
COMPRESSION_DATATYPES = dict( gzip=[ 'bam', 'fastq.gz', 'fastqsanger.gz', 'fastqillumina.gz', 'fastqsolexa.gz', 'fastqcssanger.gz', 'fastq.bz2', 'fastqsanger.bz2', 'fastqillumina.bz2', 'fastqsolexa.bz2', 'fastqcssanger.bz2' ] )
DECOMPRESSION_FUNCTIONS = dict( gzip=gzip.GzipFile, bz2=bz2.BZ2File )
COMPRESSION_CHECK_FUNCTIONS = [ ( 'gzip', is_gzip ), ('bz2', is_bz2) ]
COMPRESSION_DATATYPES = dict( gzip=[ 'bam', 'fastq.gz', 'fastqsanger.gz', 'fastqillumina.gz', 'fastqsolexa.gz', 'fastqcssanger.gz'], bz2=['fastq.bz2', 'fastqsanger.bz2', 'fastqillumina.bz2', 'fastqsolexa.bz2', 'fastqcssanger.bz2' ] )
COMPRESSED_EXTENSIONS = []
for exts in COMPRESSION_DATATYPES.values():
COMPRESSED_EXTENSIONS.extend( exts )
+31 -38
View File
@@ -5,7 +5,6 @@ from __future__ import absolute_import
import abc
import csv
import gzip
import logging
import os
import re
@@ -19,7 +18,7 @@ from galaxy import util
from galaxy.datatypes import data, metadata
from galaxy.datatypes.metadata import MetadataElement
from galaxy.datatypes.sniff import get_headers
from galaxy.util.checkers import is_gzip
from galaxy.util import compression_utils
from . import dataproviders
@@ -408,7 +407,7 @@ class Taxonomy( Tabular ):
def display_peek( self, dataset ):
"""Returns formated html of peek"""
return super(Taxonomy, self).make_html_table( dataset, column_names=self.column_names )
return self.make_html_table( dataset, column_names=self.column_names )
@dataproviders.decorators.has_dataproviders
@@ -428,7 +427,7 @@ class Sam( Tabular ):
def display_peek( self, dataset ):
"""Returns formated html of peek"""
return super( Sam, self ).make_html_table( dataset, column_names=self.column_names )
return self.make_html_table( dataset, column_names=self.column_names )
def sniff( self, filename ):
"""
@@ -614,7 +613,7 @@ class Pileup( Tabular ):
def display_peek( self, dataset ):
"""Returns formated html of peek"""
return super( Pileup, self ).make_html_table( dataset, column_parameter_alias={'chromCol': 'Chrom', 'startCol': 'Start', 'baseCol': 'Base'} )
return self.make_html_table( dataset, column_parameter_alias={'chromCol': 'Chrom', 'startCol': 'Start', 'baseCol': 'Base'} )
def repair_methods( self, dataset ):
"""Return options for removing errors along with a description"""
@@ -691,7 +690,7 @@ class Vcf( Tabular ):
def display_peek( self, dataset ):
"""Returns formated html of peek"""
return super( Vcf, self ).make_html_table( dataset, column_names=self.column_names )
return self.make_html_table( dataset, column_names=self.column_names )
def set_meta( self, dataset, **kwd ):
super( Vcf, self ).set_meta( dataset, **kwd )
@@ -789,11 +788,7 @@ class Eland( Tabular ):
- We will only check that up to the first 5 alignments are correctly formatted.
"""
try:
compress = is_gzip(filename)
if compress:
fh = gzip.GzipFile(filename, 'r')
else:
fh = open( filename )
fh = compression_utils.get_fileobj(filename, gzip_only=True)
count = 0
while True:
line = fh.readline()
@@ -830,33 +825,31 @@ class Eland( Tabular ):
def set_meta( self, dataset, overwrite=True, skip=None, max_data_lines=5, **kwd ):
if dataset.has_data():
compress = is_gzip(dataset.file_name)
if compress:
dataset_fh = gzip.GzipFile(dataset.file_name, 'r')
else:
dataset_fh = open( dataset.file_name )
lanes = {}
tiles = {}
barcodes = {}
reads = {}
# Should always read the entire file (until we devise a more clever way to pass metadata on)
# if self.max_optional_metadata_filesize >= 0 and dataset.get_size() > self.max_optional_metadata_filesize:
# If the dataset is larger than optional_metadata, just count comment lines.
# dataset.metadata.data_lines = None
# else:
# Otherwise, read the whole thing and set num data lines.
for i, line in enumerate(dataset_fh):
if line:
line_pieces = line.split('\t')
if len(line_pieces) != 22:
raise Exception('%s:%d:Corrupt line!' % (dataset.file_name, i))
lanes[line_pieces[2]] = 1
tiles[line_pieces[3]] = 1
barcodes[line_pieces[6]] = 1
reads[line_pieces[7]] = 1
pass
dataset.metadata.data_lines = i + 1
dataset_fh.close()
dataset_fh = compression_utils.get_fileobj(dataset.file_name, gzip_only=True)
try:
lanes = {}
tiles = {}
barcodes = {}
reads = {}
# Should always read the entire file (until we devise a more clever way to pass metadata on)
# if self.max_optional_metadata_filesize >= 0 and dataset.get_size() > self.max_optional_metadata_filesize:
# If the dataset is larger than optional_metadata, just count comment lines.
# dataset.metadata.data_lines = None
# else:
# Otherwise, read the whole thing and set num data lines.
for i, line in enumerate(dataset_fh):
if line:
line_pieces = line.split('\t')
if len(line_pieces) != 22:
raise Exception('%s:%d:Corrupt line!' % (dataset.file_name, i))
lanes[line_pieces[2]] = 1
tiles[line_pieces[3]] = 1
barcodes[line_pieces[6]] = 1
reads[line_pieces[7]] = 1
pass
dataset.metadata.data_lines = i + 1
finally:
dataset_fh.close()
dataset.metadata.comment_lines = 0
dataset.metadata.columns = 21
dataset.metadata.column_types = ['str', 'int', 'int', 'int', 'int', 'int', 'str', 'int', 'str', 'str', 'str', 'str', 'str', 'str', 'str', 'str', 'str', 'str', 'str', 'str', 'str']
+47
View File
@@ -605,3 +605,50 @@ class Smat(Text):
if re.match(r"[-+]?\d+$", item) is None:
return False
return True
class PlantTribesOrtho(Html):
"""
PlantTribes sequences classified into precomputed, orthologous gene family
clusters.
"""
file_ext = "ptortho"
def set_peek(self, dataset, is_multi_byte=False):
super(PlantTribesOrtho, self).set_peek(dataset, is_multi_byte=is_multi_byte)
dataset.blurb = "PlantTribes gene family clusters: %d files" % dataset.metadata.data_lines
class PlantTribesOrthoCodingSequence(Html):
"""
PlantTribes sequences classified into precomputed, orthologous gene family
clusters and corresponding coding sequences.
"""
file_ext = "ptorthocs"
def set_peek(self, dataset, is_multi_byte=False):
super(PlantTribesOrthoCodingSequence, self).set_peek(dataset, is_multi_byte=is_multi_byte)
dataset.blurb = "PlantTribes gene family clusters with corresponding coding sequences: %d files" % dataset.metadata.data_lines
class PlantTribesPhylogeneticTree(Html):
"""
PlantTribes multiple sequence alignments and inferred maximum likelihood
phylogenies for orthogroups.
"""
file_ext = "pttree"
def set_peek(self, dataset, is_multi_byte=False):
super(PlantTribesPhylogeneticTree, self).set_peek(dataset, is_multi_byte=is_multi_byte)
dataset.blurb = "PlantTribes phylogenetic trees: %d files" % dataset.metadata.data_lines
class PlantTribesMultipleSequenceAlignment(Html):
"""
PlantTribes multiple sequence alignments for orthogroups.
"""
file_ext = "ptalign"
def set_peek(self, dataset, is_multi_byte=False):
super(PlantTribesMultipleSequenceAlignment, self).set_peek(dataset, is_multi_byte=is_multi_byte)
dataset.blurb = "PlantTribes multiple sequence alignments: %d files" % dataset.metadata.data_lines
@@ -27,9 +27,10 @@ Beaker==1.7.0
dictobj==0.3.1
nose==1.3.7
Parsley==1.3
six==1.9.0
six==1.10.0
Whoosh==2.7.4
testfixtures==4.10.0
galaxy_sequence_utils==1.0.2
# Cheetah and dependencies
Cheetah==2.4.4
+1
View File
@@ -30,6 +30,7 @@ nose
Parsley
six
Whoosh
galaxy_sequence_utils
# Cheetah and dependencies
Cheetah
+5
View File
@@ -99,6 +99,11 @@ class ToolMetaParameterException( MessageException ):
err_code = error_codes.USER_TOOL_META_PARAMETER_PROBLEM
class ToolMissingException( MessageException ):
status_code = 400
err_code = error_codes.USER_TOOL_MISSING_PROBLEM
class RequestParameterInvalidException( MessageException ):
status_code = 400
err_code = error_codes.USER_REQUEST_INVALID_PARAMETER

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