mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Merge remote-tracking branch 'upstream/dev' into api.batch
This commit is contained in:
+48
-4
@@ -1,5 +1,19 @@
|
||||
lib/galaxy/util/
|
||||
lib/galaxy/jobs/runners/util/
|
||||
contrib/
|
||||
cron/
|
||||
lib/galaxy/actions/
|
||||
lib/galaxy/auth/
|
||||
lib/galaxy/config.py
|
||||
lib/galaxy/dependencies/
|
||||
lib/galaxy/eggs/
|
||||
lib/galaxy/exceptions/
|
||||
lib/galaxy/external_services/
|
||||
lib/galaxy/forms/
|
||||
lib/galaxy/jobs/
|
||||
lib/galaxy/objectstore/
|
||||
lib/galaxy/openid/
|
||||
lib/galaxy/quota/
|
||||
lib/galaxy/sample_tracking/
|
||||
lib/galaxy/tags/
|
||||
lib/galaxy/tools/cwl/
|
||||
lib/galaxy/tools/parser/
|
||||
lib/galaxy/tools/lint.py
|
||||
@@ -10,8 +24,38 @@ lib/galaxy/tools/linters/
|
||||
lib/galaxy/tools/deps/
|
||||
lib/galaxy/tools/toolbox/
|
||||
lib/galaxy/tools/parser/
|
||||
lib/galaxy/jobs/metrics/
|
||||
lib/galaxy/objectstore/
|
||||
lib/galaxy/tours/
|
||||
lib/galaxy/util/
|
||||
lib/galaxy/work/
|
||||
lib/galaxy_ext/
|
||||
lib/galaxy_utils/
|
||||
lib/log_tempfile.py
|
||||
lib/psyco_full.py
|
||||
lib/tool_shed/capsule/
|
||||
lib/tool_shed/dependencies/
|
||||
lib/tool_shed/grids/
|
||||
lib/tool_shed/managers/
|
||||
lib/tool_shed/metadata/
|
||||
lib/tool_shed/repository_types/
|
||||
lib/tool_shed/tools/
|
||||
lib/tool_shed/util/
|
||||
lib/tool_shed/utility_containers/
|
||||
scripts/api/common.py
|
||||
scripts/api/display.py
|
||||
scripts/api/workflow_execute_parameters.py
|
||||
scripts/auth/
|
||||
scripts/cleanup_datasets/admin_cleanup_datasets.py
|
||||
scripts/cleanup_datasets/cleanup_datasets.py
|
||||
test/api/test_workflows_from_yaml.py
|
||||
test/base/
|
||||
test/casperjs/
|
||||
test/functional/
|
||||
test/integration/
|
||||
test/manual/
|
||||
test/unit/tools/test_actions.py
|
||||
test/unit/workflows/test_run_parameters.py
|
||||
tool_list.py
|
||||
tools/data_source/
|
||||
tools/evolution/
|
||||
tools/sr_mapping/
|
||||
tools/visualization/
|
||||
|
||||
@@ -5,6 +5,7 @@ RELEASE_NEXT:=16.04
|
||||
#RELEASE_NEXT_BRANCH:=release_$(RELEASE_NEXT)
|
||||
RELEASE_NEXT_BRANCH:=dev
|
||||
RELEASE_UPSTREAM:=upstream
|
||||
MY_UPSTREAM:=origin
|
||||
# Location of virtualenv used for development.
|
||||
VENV?=.venv
|
||||
# Source virtualenv to execute command (flake8, sphinx, twine, etc...)
|
||||
@@ -79,9 +80,9 @@ clean-grunt-docker-image: ## Remove grunt docker image
|
||||
release-create-rc: release-ensure-upstream ## Create a release-candidate branch
|
||||
git checkout dev
|
||||
git pull --ff-only $(RELEASE_UPSTREAM) dev
|
||||
git push origin dev
|
||||
git push $(MY_UPSTREAM) dev
|
||||
git checkout -b release_$(RELEASE_CURR)
|
||||
git push origin release_$(RELEASE_CURR)
|
||||
git push $(MY_UPSTREAM) release_$(RELEASE_CURR)
|
||||
git push $(RELEASE_UPSTREAM) release_$(RELEASE_CURR)
|
||||
git checkout -b version-$(RELEASE_CURR)
|
||||
sed -i "s/^VERSION_MAJOR = .*/VERSION_MAJOR = \"$(RELEASE_CURR)\"/" lib/galaxy/version.py
|
||||
@@ -99,24 +100,25 @@ release-create-rc: release-ensure-upstream ## Create a release-candidate branch
|
||||
git checkout --ours lib/galaxy/version.py
|
||||
git add lib/galaxy/version.py
|
||||
git commit -m "Merge branch 'version-$(RELEASE_CURR)' into version-$(RELEASE_NEXT).dev"
|
||||
git push origin version-$(RELEASE_CURR):version-$(RELEASE_CURR)
|
||||
git push origin version-$(RELEASE_NEXT).dev:version-$(RELEASE_NEXT).dev
|
||||
git push $(MY_UPSTREAM) version-$(RELEASE_CURR):version-$(RELEASE_CURR)
|
||||
git push $(MY_UPSTREAM) version-$(RELEASE_NEXT).dev:version-$(RELEASE_NEXT).dev
|
||||
git branch -d version-$(RELEASE_CURR)
|
||||
git branch -d version-$(RELEASE_NEXT).dev
|
||||
# TODO: Use hub to automate these PR creations or push directly.
|
||||
@echo "Open a PR from version-$(RELEASE_CURR) of your fork to release_$(RELEASE_CURR)"
|
||||
@echo "Open a PR from version-$(RELEASE_NEXT).dev of your fork to dev"
|
||||
|
||||
create_release: release-ensure-upstream ## Create a release branch
|
||||
release-create: release-ensure-upstream ## Create a release branch
|
||||
git checkout master
|
||||
git pull --ff-only $(RELEASE_UPSTREAM) master
|
||||
git push origin master
|
||||
git push $(MY_UPSTREAM) master
|
||||
git checkout release_$(RELEASE_CURR)
|
||||
git pull --ff-only $(RELEASE_UPSTREAM) release_$(RELEASE_CURR)
|
||||
#git push origin release_$(RELEASE_CURR)
|
||||
#git push $(MY_UPSTREAM) release_$(RELEASE_CURR)
|
||||
git checkout dev
|
||||
git pull --ff-only $(RELEASE_UPSTREAM) dev
|
||||
#git push origin dev
|
||||
# Test run of merging. If there are conflicts, it will fail here here.
|
||||
#git push $(MY_UPSTREAM) dev
|
||||
# Test run of merging. If there are conflicts, it will fail here.
|
||||
git merge release_$(RELEASE_CURR)
|
||||
git checkout release_$(RELEASE_CURR)
|
||||
sed -i "s/^VERSION_MINOR = .*/VERSION_MINOR = None/" lib/galaxy/version.py
|
||||
@@ -131,20 +133,20 @@ create_release: release-ensure-upstream ## Create a release branch
|
||||
git commit -m "Merge branch 'release_$(RELEASE_CURR)' into dev"
|
||||
git checkout master
|
||||
git merge release_$(RELEASE_CURR)
|
||||
#git push origin release_$(RELEASE_CURR):release_$(RELEASE_CURR)
|
||||
#git push origin dev:dev
|
||||
#git push origin master:master
|
||||
#git push origin --tags
|
||||
#git push $(RELEASE_UPSTREAM) release_$(RELEASE_CURR):release_$(RELEASE_CURR)
|
||||
#git push $(RELEASE_UPSTREAM) dev:dev
|
||||
#git push $(RELEASE_UPSTREAM) master:master
|
||||
#git push $(RELEASE_UPSTREAM) --tags
|
||||
|
||||
create_point_release: ## Create a point release
|
||||
release-create-point: ## Create a point release
|
||||
git pull --ff-only $(RELEASE_UPSTREAM) master
|
||||
git push origin master
|
||||
git push $(MY_UPSTREAM) master
|
||||
git checkout release_$(RELEASE_CURR)
|
||||
git pull --ff-only $(RELEASE_UPSTREAM) release_$(RELEASE_CURR)
|
||||
#git push origin release_$(RELEASE_CURR)
|
||||
#git push $(MY_UPSTREAM) release_$(RELEASE_CURR)
|
||||
git checkout $(RELEASE_NEXT_BRANCH)
|
||||
git pull --ff-only $(RELEASE_UPSTREAM) $(RELEASE_NEXT_BRANCH)
|
||||
#git push origin $(RELEASE_NEXT_BRANCH)
|
||||
#git push $(MY_UPSTREAM) $(RELEASE_NEXT_BRANCH)
|
||||
git merge release_$(RELEASE_CURR)
|
||||
git checkout release_$(RELEASE_CURR)
|
||||
sed -i "s/^VERSION_MINOR = .*/VERSION_MINOR = \"$(RELEASE_CURR_MINOR_NEXT)\"/" lib/galaxy/version.py
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ The latest information about Galaxy is available via `https://galaxyproject.org/
|
||||
Galaxy Quickstart
|
||||
=================
|
||||
|
||||
Galaxy requires Python 2.6 or 2.7. To check your python version, run:
|
||||
Galaxy requires Python 2.7 To check your python version, run:
|
||||
|
||||
.. code:: console
|
||||
|
||||
|
||||
+9
-11
@@ -8,14 +8,13 @@
|
||||
],
|
||||
"homepage": "usegalaxy.org",
|
||||
"dependencies": {
|
||||
"jquery": "~1.11.1",
|
||||
"tracekit": "*",
|
||||
"ravenjs": "~1.1.16",
|
||||
"underscore": "~1.7.0",
|
||||
"backbone": "~1.1.2",
|
||||
"jquery": "~1.12",
|
||||
"ravenjs": "~3",
|
||||
"underscore": "~1",
|
||||
"backbone": "~1.3",
|
||||
"bootstrap": "~3.3.2",
|
||||
"bootstrap-tour": "~0.10.2",
|
||||
"d3": "~3.5.3",
|
||||
"d3": "~3",
|
||||
"farbtastic": "~2.0.0-alpha.1",
|
||||
"toastr": "~2.1.0",
|
||||
"jQTouch": "git://github.com/senchalabs/jQTouch#~1.0.0",
|
||||
@@ -31,11 +30,10 @@
|
||||
"jstree": "~3.0.9",
|
||||
"jquery-ui": "git://github.com/jquery/jquery-ui.git#~1.11.2",
|
||||
"threedubmedia.jquery.event": "*",
|
||||
"jquery-migrate": "~1.2.1",
|
||||
"requirejs": "~2.1.17"
|
||||
"jquery-migrate": "~1.4",
|
||||
"requirejs": "~2"
|
||||
},
|
||||
"resolutions": {
|
||||
"jquery": "~1.11.1"
|
||||
},
|
||||
"devDependencies": {}
|
||||
"jquery": "~1.12"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,45 +41,82 @@ return Backbone.View.extend({
|
||||
}).on( 'show hide ', function() {
|
||||
self.buttonLoad.set( { 'toggle': this.visible, 'icon': this.visible && 'fa-eye' || 'fa-eye-slash' } );
|
||||
});
|
||||
this.history_cache = {};
|
||||
},
|
||||
|
||||
/** Add a dataset to the frames */
|
||||
addDataset: function( dataset_id ) {
|
||||
var self = this;
|
||||
var current_dataset = null;
|
||||
if ( Galaxy && Galaxy.currHistoryPanel ) {
|
||||
var history_id = Galaxy.currHistoryPanel.collection.historyId;
|
||||
this.history_cache[ history_id ] = { name: Galaxy.currHistoryPanel.model.get( 'name' ), dataset_ids: [] };
|
||||
Galaxy.currHistoryPanel.collection.each( function( model ) {
|
||||
!model.get( 'deleted' ) && model.get( 'visible' ) && self.history_cache[ history_id ].dataset_ids.push( model.get( 'id' ) );
|
||||
});
|
||||
}
|
||||
var _findDataset = function( dataset, offset ) {
|
||||
if ( dataset ) {
|
||||
var history_details = self.history_cache[ dataset.get( 'history_id' ) ];
|
||||
if ( history_details && history_details.dataset_ids ) {
|
||||
var dataset_list = history_details.dataset_ids;
|
||||
var pos = dataset_list.indexOf( dataset.get( 'id' ) );
|
||||
if ( pos !== -1 && pos + offset >= 0 && pos + offset < dataset_list.length ) {
|
||||
return dataset_list[ pos + offset ];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
var _loadDatasetOffset = function( dataset, offset, frame ) {
|
||||
var new_dataset_id = _findDataset( dataset, offset );
|
||||
if ( new_dataset_id ) {
|
||||
self._loadDataset( new_dataset_id, function( new_dataset, config ) {
|
||||
current_dataset = new_dataset;
|
||||
frame.model.set( config );
|
||||
});
|
||||
} else {
|
||||
frame.model.trigger( 'change' );
|
||||
}
|
||||
}
|
||||
this._loadDataset( dataset_id, function( dataset, config ) {
|
||||
current_dataset = dataset;
|
||||
self.add( _.extend( { menu: [ { icon : 'fa fa-chevron-circle-left',
|
||||
tooltip : 'Previous in History',
|
||||
onclick : function( frame ) { _loadDatasetOffset( current_dataset, -1, frame ) },
|
||||
disabled : function() { return !_findDataset( current_dataset, -1 ) } },
|
||||
{ icon : 'fa fa-chevron-circle-right',
|
||||
tooltip : 'Next in History',
|
||||
onclick : function( frame ) { _loadDatasetOffset( current_dataset, 1, frame ) },
|
||||
disabled : function() { return !_findDataset( current_dataset, 1 ) } } ] }, config ) )
|
||||
});
|
||||
},
|
||||
|
||||
_loadDataset: function( dataset_id, callback ) {
|
||||
var self = this;
|
||||
require([ 'mvc/dataset/data' ], function( DATA ) {
|
||||
var dataset = new DATA.Dataset( { id : dataset_id } );
|
||||
$.when( dataset.fetch() ).then( function() {
|
||||
// Construct frame config based on dataset's type.
|
||||
var frame_config = {
|
||||
title: dataset.get('name')
|
||||
},
|
||||
// HACK: For now, assume 'tabular' and 'interval' are the only
|
||||
// modules that contain tabular files. This needs to be replaced
|
||||
// will a is_datatype() function.
|
||||
is_tabular = _.find( [ 'tabular', 'interval' ] , function( data_type ) {
|
||||
return dataset.get( 'data_type' ).indexOf( data_type ) !== -1;
|
||||
});
|
||||
|
||||
// Use tabular chunked display if dataset is tabular; otherwise load via URL.
|
||||
if ( is_tabular ) {
|
||||
var tabular_dataset = new DATA.TabularDataset( dataset.toJSON() );
|
||||
_.extend( frame_config, {
|
||||
content: function( parent_elt ) {
|
||||
DATA.createTabularDatasetChunkedView({
|
||||
model : tabular_dataset,
|
||||
parent_elt : parent_elt,
|
||||
embedded : true,
|
||||
height : '100%'
|
||||
});
|
||||
}
|
||||
});
|
||||
var is_tabular = _.find( [ 'tabular', 'interval' ] , function( data_type ) {
|
||||
return dataset.get( 'data_type' ).indexOf( data_type ) !== -1;
|
||||
});
|
||||
var title = dataset.get( 'name' );
|
||||
var history_details = self.history_cache[ dataset.get( 'history_id' ) ];
|
||||
if ( history_details ) {
|
||||
title = history_details.name + ': ' + title;
|
||||
}
|
||||
else {
|
||||
_.extend( frame_config, {
|
||||
url: Galaxy.root + 'datasets/' + dataset.id + '/display/?preview=True'
|
||||
});
|
||||
}
|
||||
self.add( frame_config );
|
||||
callback( dataset, is_tabular ? {
|
||||
title : title,
|
||||
url : null,
|
||||
content : DATA.createTabularDatasetChunkedView({
|
||||
model : new DATA.TabularDataset( dataset.toJSON() ),
|
||||
embedded : true,
|
||||
height : '100%'
|
||||
}).$el
|
||||
} : {
|
||||
title : title,
|
||||
url : Galaxy.root + 'datasets/' + dataset_id + '/display/?preview=True',
|
||||
content : null
|
||||
} );
|
||||
});
|
||||
});
|
||||
},
|
||||
@@ -136,15 +173,9 @@ return Backbone.View.extend({
|
||||
window.location = options.url;
|
||||
} else if ( !this.active ) {
|
||||
var $galaxy_main = $( window.parent.document ).find( '#galaxy_main' );
|
||||
if ( options.target == 'galaxy_main' || options.target == 'center' ){
|
||||
if ( $galaxy_main.length === 0 ){
|
||||
var href = options.url;
|
||||
if ( href.indexOf( '?' ) == -1 )
|
||||
href += '?';
|
||||
else
|
||||
href += '&';
|
||||
href += 'use_panels=True';
|
||||
window.location = href;
|
||||
if ( options.target == 'galaxy_main' || options.target == 'center' ) {
|
||||
if ( $galaxy_main.length === 0 ) {
|
||||
window.location = options.url + ( href.indexOf( '?' ) == -1 ? '?' : '&' ) + 'use_panels=True';
|
||||
} else {
|
||||
$galaxy_main.attr( 'src', options.url );
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+162
-37
@@ -1,15 +1,15 @@
|
||||
/* ========================================================================
|
||||
* bootstrap-tour - v0.10.1
|
||||
* bootstrap-tour - v0.10.2
|
||||
* http://bootstraptour.com
|
||||
* ========================================================================
|
||||
* Copyright 2012-2013 Ulrich Sossou
|
||||
* Copyright 2012-2015 Ulrich Sossou
|
||||
*
|
||||
* ========================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* Licensed under the MIT License (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* https://opensource.org/licenses/MIT
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -39,6 +39,7 @@
|
||||
storage: storage,
|
||||
debug: false,
|
||||
backdrop: false,
|
||||
backdropContainer: 'body',
|
||||
backdropPadding: 0,
|
||||
redirect: true,
|
||||
orphan: false,
|
||||
@@ -58,10 +59,12 @@
|
||||
onNext: function(tour) {},
|
||||
onPrev: function(tour) {},
|
||||
onPause: function(tour, duration) {},
|
||||
onResume: function(tour, duration) {}
|
||||
onResume: function(tour, duration) {},
|
||||
onRedirectError: function(tour) {}
|
||||
}, options);
|
||||
this._force = false;
|
||||
this._inited = false;
|
||||
this._current = null;
|
||||
this.backdrop = {
|
||||
overlay: null,
|
||||
$element: null,
|
||||
@@ -91,6 +94,7 @@
|
||||
return $.extend({
|
||||
id: "step-" + i,
|
||||
path: '',
|
||||
host: '',
|
||||
placement: 'right',
|
||||
title: '',
|
||||
content: '<p></p>',
|
||||
@@ -100,8 +104,10 @@
|
||||
container: this._options.container,
|
||||
autoscroll: this._options.autoscroll,
|
||||
backdrop: this._options.backdrop,
|
||||
backdropContainer: this._options.backdropContainer,
|
||||
backdropPadding: this._options.backdropPadding,
|
||||
redirect: this._options.redirect,
|
||||
reflexElement: this._options.steps[i].element,
|
||||
orphan: this._options.orphan,
|
||||
duration: this._options.duration,
|
||||
delay: this._options.delay,
|
||||
@@ -113,7 +119,8 @@
|
||||
onNext: this._options.onNext,
|
||||
onPrev: this._options.onPrev,
|
||||
onPause: this._options.onPause,
|
||||
onResume: this._options.onResume
|
||||
onResume: this._options.onResume,
|
||||
onRedirectError: this._options.onRedirectError
|
||||
}, this._options.steps[i]);
|
||||
}
|
||||
};
|
||||
@@ -199,6 +206,7 @@
|
||||
Tour.prototype.restart = function() {
|
||||
this._removeState('current_step');
|
||||
this._removeState('end');
|
||||
this._removeState('redirect_to');
|
||||
return this.start();
|
||||
};
|
||||
|
||||
@@ -257,8 +265,9 @@
|
||||
$element = $('body');
|
||||
}
|
||||
$element.popover('destroy').removeClass("tour-" + _this._options.name + "-element tour-" + _this._options.name + "-" + i + "-element");
|
||||
$element.removeData('bs.popover');
|
||||
if (step.reflex) {
|
||||
$element.removeClass('tour-step-element-reflex').off("" + (_this._reflexEvent(step.reflex)) + ".tour-" + _this._options.name);
|
||||
$(step.reflexElement).removeClass('tour-step-element-reflex').off("" + (_this._reflexEvent(step.reflex)) + ".tour-" + _this._options.name);
|
||||
}
|
||||
if (step.backdrop) {
|
||||
_this._hideBackdrop();
|
||||
@@ -286,7 +295,7 @@
|
||||
promise = this._makePromise(step.onShow != null ? step.onShow(this, i) : void 0);
|
||||
showStepHelper = (function(_this) {
|
||||
return function(e) {
|
||||
var current_path, path, showPopoverAndOverlay;
|
||||
var path, showPopoverAndOverlay;
|
||||
_this.setCurrentStep(i);
|
||||
path = (function() {
|
||||
switch ({}.toString.call(step.path)) {
|
||||
@@ -298,13 +307,14 @@
|
||||
return step.path;
|
||||
}
|
||||
}).call(_this);
|
||||
current_path = [document.location.pathname, document.location.hash].join('');
|
||||
if (_this._isRedirect(path, current_path)) {
|
||||
_this._redirect(step, path);
|
||||
return;
|
||||
if (_this._isRedirect(step.host, path, document.location)) {
|
||||
_this._redirect(step, i, path);
|
||||
if (!_this._isJustPathHashDifferent(step.host, path, document.location)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (_this._isOrphan(step)) {
|
||||
if (!step.orphan) {
|
||||
if (step.orphan === false) {
|
||||
_this._debug("Skip the orphan step " + (_this._current + 1) + ".\nOrphan option is false and the element does not exist or is hidden.");
|
||||
if (skipToPrevious) {
|
||||
_this._showPrevStep();
|
||||
@@ -316,10 +326,10 @@
|
||||
_this._debug("Show the orphan step " + (_this._current + 1) + ". Orphans option is true.");
|
||||
}
|
||||
if (step.backdrop) {
|
||||
_this._showBackdrop(!_this._isOrphan(step) ? step.element : void 0);
|
||||
_this._showBackdrop(step);
|
||||
}
|
||||
showPopoverAndOverlay = function() {
|
||||
if (_this.getCurrentStep() !== i) {
|
||||
if (_this.getCurrentStep() !== i || _this.ended()) {
|
||||
return;
|
||||
}
|
||||
if ((step.element != null) && step.backdrop) {
|
||||
@@ -369,6 +379,10 @@
|
||||
return this;
|
||||
};
|
||||
|
||||
Tour.prototype.redraw = function() {
|
||||
return this._showOverlayElement(this.getStep(this.getCurrentStep()).element, true);
|
||||
};
|
||||
|
||||
Tour.prototype._setState = function(key, value) {
|
||||
var e, keyName;
|
||||
if (this._options.storage) {
|
||||
@@ -450,16 +464,54 @@
|
||||
}
|
||||
};
|
||||
|
||||
Tour.prototype._isRedirect = function(path, currentPath) {
|
||||
return (path != null) && path !== '' && (({}.toString.call(path) === '[object RegExp]' && !path.test(currentPath)) || ({}.toString.call(path) === '[object String]' && path.replace(/\?.*$/, '').replace(/\/?$/, '') !== currentPath.replace(/\/?$/, '')));
|
||||
Tour.prototype._isRedirect = function(host, path, location) {
|
||||
var currentPath;
|
||||
if (host !== '') {
|
||||
if (this._isHostDifferent(host, location.href)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
currentPath = [location.pathname, location.search, location.hash].join('');
|
||||
return (path != null) && path !== '' && (({}.toString.call(path) === '[object RegExp]' && !path.test(currentPath)) || ({}.toString.call(path) === '[object String]' && this._isPathDifferent(path, currentPath)));
|
||||
};
|
||||
|
||||
Tour.prototype._redirect = function(step, path) {
|
||||
Tour.prototype._isHostDifferent = function(host, currentURL) {
|
||||
return this._getProtocol(host) !== this._getProtocol(currentURL) || this._getHost(host) !== this._getHost(currentURL);
|
||||
};
|
||||
|
||||
Tour.prototype._isPathDifferent = function(path, currentPath) {
|
||||
return this._getPath(path) !== this._getPath(currentPath) || !this._equal(this._getQuery(path), this._getQuery(currentPath)) || !this._equal(this._getHash(path), this._getHash(currentPath));
|
||||
};
|
||||
|
||||
Tour.prototype._isJustPathHashDifferent = function(host, path, location) {
|
||||
var currentPath;
|
||||
if (host !== '') {
|
||||
if (this._isHostDifferent(host, location.href)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
currentPath = [location.pathname, location.search, location.hash].join('');
|
||||
if ({}.toString.call(path) === '[object String]') {
|
||||
return this._getPath(path) === this._getPath(currentPath) && this._equal(this._getQuery(path), this._getQuery(currentPath)) && !this._equal(this._getHash(path), this._getHash(currentPath));
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
Tour.prototype._redirect = function(step, i, path) {
|
||||
if ($.isFunction(step.redirect)) {
|
||||
return step.redirect.call(this, path);
|
||||
} else if (step.redirect === true) {
|
||||
this._debug("Redirect to " + path);
|
||||
return document.location.href = path;
|
||||
this._debug("Redirect to " + step.host + path);
|
||||
if (this._getState('redirect_to') === ("" + i)) {
|
||||
this._debug("Error redirection loop to " + path);
|
||||
this._removeState('redirect_to');
|
||||
if (step.onRedirectError != null) {
|
||||
return step.onRedirectError(this);
|
||||
}
|
||||
} else {
|
||||
this._setState('redirect_to', "" + i);
|
||||
return document.location.href = "" + step.host + path;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -472,7 +524,7 @@
|
||||
};
|
||||
|
||||
Tour.prototype._showPopover = function(step, i) {
|
||||
var $element, $tip, isOrphan, options;
|
||||
var $element, $tip, isOrphan, options, shouldAddSmart;
|
||||
$(".tour-" + this._options.name).remove();
|
||||
options = $.extend({}, this._options);
|
||||
isOrphan = this._isOrphan(step);
|
||||
@@ -487,9 +539,7 @@
|
||||
$.extend(options, step.options);
|
||||
}
|
||||
if (step.reflex && !isOrphan) {
|
||||
$element.addClass('tour-step-element-reflex');
|
||||
$element.off("" + (this._reflexEvent(step.reflex)) + ".tour-" + this._options.name);
|
||||
$element.on("" + (this._reflexEvent(step.reflex)) + ".tour-" + this._options.name, (function(_this) {
|
||||
$(step.reflexElement).addClass('tour-step-element-reflex').off("" + (this._reflexEvent(step.reflex)) + ".tour-" + this._options.name).on("" + (this._reflexEvent(step.reflex)) + ".tour-" + this._options.name, (function(_this) {
|
||||
return function() {
|
||||
if (_this._isLast()) {
|
||||
return _this.next();
|
||||
@@ -499,8 +549,9 @@
|
||||
};
|
||||
})(this));
|
||||
}
|
||||
shouldAddSmart = step.smartPlacement === true && step.placement.search(/auto/i) === -1;
|
||||
$element.popover({
|
||||
placement: step.placement,
|
||||
placement: shouldAddSmart ? "auto " + step.placement : step.placement,
|
||||
trigger: 'manual',
|
||||
title: step.title,
|
||||
content: step.content,
|
||||
@@ -519,8 +570,12 @@
|
||||
};
|
||||
|
||||
Tour.prototype._template = function(step, i) {
|
||||
var $navigation, $next, $prev, $resume, $template;
|
||||
$template = $.isFunction(step.template) ? $(step.template(i, step)) : $(step.template);
|
||||
var $navigation, $next, $prev, $resume, $template, template;
|
||||
template = step.template;
|
||||
if (this._isOrphan(step) && {}.toString.call(step.orphan) !== '[object Boolean]') {
|
||||
template = step.orphan;
|
||||
}
|
||||
$template = $.isFunction(template) ? $(template(i, step)) : $(template);
|
||||
$navigation = $template.find('.popover-navigation');
|
||||
$prev = $navigation.find('[data-role="prev"]');
|
||||
$next = $navigation.find('[data-role="next"]');
|
||||
@@ -529,11 +584,16 @@
|
||||
$template.addClass('orphan');
|
||||
}
|
||||
$template.addClass("tour-" + this._options.name + " tour-" + this._options.name + "-" + i);
|
||||
if (step.reflex) {
|
||||
$template.addClass("tour-" + this._options.name + "-reflex");
|
||||
}
|
||||
if (step.prev < 0) {
|
||||
$prev.addClass('disabled');
|
||||
$prev.prop('disabled', true);
|
||||
}
|
||||
if (step.next < 0) {
|
||||
$next.addClass('disabled');
|
||||
$next.prop('disabled', true);
|
||||
}
|
||||
if (!step.duration) {
|
||||
$resume.remove();
|
||||
@@ -704,7 +764,7 @@
|
||||
}
|
||||
};
|
||||
|
||||
Tour.prototype._showBackdrop = function(element) {
|
||||
Tour.prototype._showBackdrop = function(step) {
|
||||
if (this.backdrop.backgroundShown) {
|
||||
return;
|
||||
}
|
||||
@@ -712,7 +772,7 @@
|
||||
"class": 'tour-backdrop'
|
||||
});
|
||||
this.backdrop.backgroundShown = true;
|
||||
return $('body').append(this.backdrop);
|
||||
return $(step.backdropContainer).append(this.backdrop);
|
||||
};
|
||||
|
||||
Tour.prototype._hideBackdrop = function() {
|
||||
@@ -728,23 +788,25 @@
|
||||
}
|
||||
};
|
||||
|
||||
Tour.prototype._showOverlayElement = function(step) {
|
||||
Tour.prototype._showOverlayElement = function(step, force) {
|
||||
var $element, elementData;
|
||||
$element = $(step.element);
|
||||
if (!$element || $element.length === 0 || this.backdrop.overlayElementShown) {
|
||||
if (!$element || $element.length === 0 || this.backdrop.overlayElementShown && !force) {
|
||||
return;
|
||||
}
|
||||
this.backdrop.overlayElementShown = true;
|
||||
this.backdrop.$element = $element.addClass('tour-step-backdrop');
|
||||
this.backdrop.$background = $('<div>', {
|
||||
"class": 'tour-step-background'
|
||||
});
|
||||
if (!this.backdrop.overlayElementShown) {
|
||||
this.backdrop.$element = $element.addClass('tour-step-backdrop');
|
||||
this.backdrop.$background = $('<div>', {
|
||||
"class": 'tour-step-background'
|
||||
});
|
||||
this.backdrop.$background.appendTo(step.backdropContainer);
|
||||
this.backdrop.overlayElementShown = true;
|
||||
}
|
||||
elementData = {
|
||||
width: $element.innerWidth(),
|
||||
height: $element.innerHeight(),
|
||||
offset: $element.offset()
|
||||
};
|
||||
this.backdrop.$background.appendTo('body');
|
||||
if (step.backdropPadding) {
|
||||
elementData = this._applyBackdropPadding(step.backdropPadding, elementData);
|
||||
}
|
||||
@@ -795,6 +857,69 @@
|
||||
return this._duration = null;
|
||||
};
|
||||
|
||||
Tour.prototype._getProtocol = function(url) {
|
||||
url = url.split('://');
|
||||
if (url.length > 1) {
|
||||
return url[0];
|
||||
} else {
|
||||
return 'http';
|
||||
}
|
||||
};
|
||||
|
||||
Tour.prototype._getHost = function(url) {
|
||||
url = url.split('//');
|
||||
url = url.length > 1 ? url[1] : url[0];
|
||||
return url.split('/')[0];
|
||||
};
|
||||
|
||||
Tour.prototype._getPath = function(path) {
|
||||
return path.replace(/\/?$/, '').split('?')[0].split('#')[0];
|
||||
};
|
||||
|
||||
Tour.prototype._getQuery = function(path) {
|
||||
return this._getParams(path, '?');
|
||||
};
|
||||
|
||||
Tour.prototype._getHash = function(path) {
|
||||
return this._getParams(path, '#');
|
||||
};
|
||||
|
||||
Tour.prototype._getParams = function(path, start) {
|
||||
var param, params, paramsObject, _i, _len;
|
||||
params = path.split(start);
|
||||
if (params.length === 1) {
|
||||
return {};
|
||||
}
|
||||
params = params[1].split('&');
|
||||
paramsObject = {};
|
||||
for (_i = 0, _len = params.length; _i < _len; _i++) {
|
||||
param = params[_i];
|
||||
param = param.split('=');
|
||||
paramsObject[param[0]] = param[1] || '';
|
||||
}
|
||||
return paramsObject;
|
||||
};
|
||||
|
||||
Tour.prototype._equal = function(obj1, obj2) {
|
||||
var k, v;
|
||||
if ({}.toString.call(obj1) === '[object Object]' && {}.toString.call(obj2) === '[object Object]') {
|
||||
for (k in obj1) {
|
||||
v = obj1[k];
|
||||
if (obj2[k] !== v) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (k in obj2) {
|
||||
v = obj2[k];
|
||||
if (obj1[k] !== v) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return obj1 === obj2;
|
||||
};
|
||||
|
||||
return Tour;
|
||||
|
||||
})();
|
||||
|
||||
Vendored
+200
-150
@@ -1,6 +1,6 @@
|
||||
!function() {
|
||||
var d3 = {
|
||||
version: "3.5.6"
|
||||
version: "3.5.17"
|
||||
};
|
||||
var d3_arraySlice = [].slice, d3_array = function(list) {
|
||||
return d3_arraySlice.call(list);
|
||||
@@ -220,20 +220,20 @@
|
||||
while (i < n) pairs[i] = [ p0 = p1, p1 = array[++i] ];
|
||||
return pairs;
|
||||
};
|
||||
d3.zip = function() {
|
||||
if (!(n = arguments.length)) return [];
|
||||
for (var i = -1, m = d3.min(arguments, d3_zipLength), zips = new Array(m); ++i < m; ) {
|
||||
for (var j = -1, n, zip = zips[i] = new Array(n); ++j < n; ) {
|
||||
zip[j] = arguments[j][i];
|
||||
d3.transpose = function(matrix) {
|
||||
if (!(n = matrix.length)) return [];
|
||||
for (var i = -1, m = d3.min(matrix, d3_transposeLength), transpose = new Array(m); ++i < m; ) {
|
||||
for (var j = -1, n, row = transpose[i] = new Array(n); ++j < n; ) {
|
||||
row[j] = matrix[j][i];
|
||||
}
|
||||
}
|
||||
return zips;
|
||||
return transpose;
|
||||
};
|
||||
function d3_zipLength(d) {
|
||||
function d3_transposeLength(d) {
|
||||
return d.length;
|
||||
}
|
||||
d3.transpose = function(matrix) {
|
||||
return d3.zip.apply(d3, matrix);
|
||||
d3.zip = function() {
|
||||
return d3.transpose(arguments);
|
||||
};
|
||||
d3.keys = function(map) {
|
||||
var keys = [];
|
||||
@@ -620,9 +620,10 @@
|
||||
return d3_selectAll(selector, this);
|
||||
};
|
||||
}
|
||||
var d3_nsXhtml = "http://www.w3.org/1999/xhtml";
|
||||
var d3_nsPrefix = {
|
||||
svg: "http://www.w3.org/2000/svg",
|
||||
xhtml: "http://www.w3.org/1999/xhtml",
|
||||
xhtml: d3_nsXhtml,
|
||||
xlink: "http://www.w3.org/1999/xlink",
|
||||
xml: "http://www.w3.org/XML/1998/namespace",
|
||||
xmlns: "http://www.w3.org/2000/xmlns/"
|
||||
@@ -631,10 +632,7 @@
|
||||
prefix: d3_nsPrefix,
|
||||
qualify: function(name) {
|
||||
var i = name.indexOf(":"), prefix = name;
|
||||
if (i >= 0) {
|
||||
prefix = name.slice(0, i);
|
||||
name = name.slice(i + 1);
|
||||
}
|
||||
if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1);
|
||||
return d3_nsPrefix.hasOwnProperty(prefix) ? {
|
||||
space: d3_nsPrefix[prefix],
|
||||
local: name
|
||||
@@ -808,7 +806,7 @@
|
||||
function d3_selection_creator(name) {
|
||||
function create() {
|
||||
var document = this.ownerDocument, namespace = this.namespaceURI;
|
||||
return namespace ? document.createElementNS(namespace, name) : document.createElement(name);
|
||||
return namespace === d3_nsXhtml && document.documentElement.namespaceURI === d3_nsXhtml ? document.createElement(name) : document.createElementNS(namespace, name);
|
||||
}
|
||||
function createNS() {
|
||||
return this.ownerDocument.createElementNS(name.space, name.local);
|
||||
@@ -845,12 +843,14 @@
|
||||
if (key) {
|
||||
var nodeByKeyValue = new d3_Map(), keyValues = new Array(n), keyValue;
|
||||
for (i = -1; ++i < n; ) {
|
||||
if (nodeByKeyValue.has(keyValue = key.call(node = group[i], node.__data__, i))) {
|
||||
exitNodes[i] = node;
|
||||
} else {
|
||||
nodeByKeyValue.set(keyValue, node);
|
||||
if (node = group[i]) {
|
||||
if (nodeByKeyValue.has(keyValue = key.call(node, node.__data__, i))) {
|
||||
exitNodes[i] = node;
|
||||
} else {
|
||||
nodeByKeyValue.set(keyValue, node);
|
||||
}
|
||||
keyValues[i] = keyValue;
|
||||
}
|
||||
keyValues[i] = keyValue;
|
||||
}
|
||||
for (i = -1; ++i < m; ) {
|
||||
if (!(node = nodeByKeyValue.get(keyValue = key.call(groupData, nodeData = groupData[i], i)))) {
|
||||
@@ -862,7 +862,7 @@
|
||||
nodeByKeyValue.set(keyValue, true);
|
||||
}
|
||||
for (i = -1; ++i < n; ) {
|
||||
if (nodeByKeyValue.get(keyValues[i]) !== true) {
|
||||
if (i in keyValues && nodeByKeyValue.get(keyValues[i]) !== true) {
|
||||
exitNodes[i] = group[i];
|
||||
}
|
||||
}
|
||||
@@ -1054,7 +1054,7 @@
|
||||
group = d3_array(d3_selectAll(nodes, d3_document));
|
||||
group.parentNode = d3_document.documentElement;
|
||||
} else {
|
||||
group = nodes;
|
||||
group = d3_array(nodes);
|
||||
group.parentNode = null;
|
||||
}
|
||||
return d3_selection([ group ]);
|
||||
@@ -1205,7 +1205,7 @@
|
||||
}
|
||||
function dragstart(id, position, subject, move, end) {
|
||||
return function() {
|
||||
var that = this, target = d3.event.target, parent = that.parentNode, dispatch = event.of(that, arguments), dragged = 0, dragId = id(), dragName = ".drag" + (dragId == null ? "" : "-" + dragId), dragOffset, dragSubject = d3.select(subject(target)).on(move + dragName, moved).on(end + dragName, ended), dragRestore = d3_event_dragSuppress(target), position0 = position(parent, dragId);
|
||||
var that = this, target = d3.event.target.correspondingElement || d3.event.target, parent = that.parentNode, dispatch = event.of(that, arguments), dragged = 0, dragId = id(), dragName = ".drag" + (dragId == null ? "" : "-" + dragId), dragOffset, dragSubject = d3.select(subject(target)).on(move + dragName, moved).on(end + dragName, ended), dragRestore = d3_event_dragSuppress(target), position0 = position(parent, dragId);
|
||||
if (origin) {
|
||||
dragOffset = origin.apply(that, arguments);
|
||||
dragOffset = [ dragOffset.x - position0[0], dragOffset.y - position0[1] ];
|
||||
@@ -1233,7 +1233,7 @@
|
||||
function ended() {
|
||||
if (!position(parent, dragId)) return;
|
||||
dragSubject.on(move + dragName, null).on(end + dragName, null);
|
||||
dragRestore(dragged && d3.event.target === target);
|
||||
dragRestore(dragged);
|
||||
dispatch({
|
||||
type: "dragend"
|
||||
});
|
||||
@@ -1285,18 +1285,22 @@
|
||||
}
|
||||
var ρ = Math.SQRT2, ρ2 = 2, ρ4 = 4;
|
||||
d3.interpolateZoom = function(p0, p1) {
|
||||
var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], ux1 = p1[0], uy1 = p1[1], w1 = p1[2];
|
||||
var dx = ux1 - ux0, dy = uy1 - uy0, d2 = dx * dx + dy * dy, d1 = Math.sqrt(d2), b0 = (w1 * w1 - w0 * w0 + ρ4 * d2) / (2 * w0 * ρ2 * d1), b1 = (w1 * w1 - w0 * w0 - ρ4 * d2) / (2 * w1 * ρ2 * d1), r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1), dr = r1 - r0, S = (dr || Math.log(w1 / w0)) / ρ;
|
||||
function interpolate(t) {
|
||||
var s = t * S;
|
||||
if (dr) {
|
||||
var coshr0 = d3_cosh(r0), u = w0 / (ρ2 * d1) * (coshr0 * d3_tanh(ρ * s + r0) - d3_sinh(r0));
|
||||
var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], ux1 = p1[0], uy1 = p1[1], w1 = p1[2], dx = ux1 - ux0, dy = uy1 - uy0, d2 = dx * dx + dy * dy, i, S;
|
||||
if (d2 < ε2) {
|
||||
S = Math.log(w1 / w0) / ρ;
|
||||
i = function(t) {
|
||||
return [ ux0 + t * dx, uy0 + t * dy, w0 * Math.exp(ρ * t * S) ];
|
||||
};
|
||||
} else {
|
||||
var d1 = Math.sqrt(d2), b0 = (w1 * w1 - w0 * w0 + ρ4 * d2) / (2 * w0 * ρ2 * d1), b1 = (w1 * w1 - w0 * w0 - ρ4 * d2) / (2 * w1 * ρ2 * d1), r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1);
|
||||
S = (r1 - r0) / ρ;
|
||||
i = function(t) {
|
||||
var s = t * S, coshr0 = d3_cosh(r0), u = w0 / (ρ2 * d1) * (coshr0 * d3_tanh(ρ * s + r0) - d3_sinh(r0));
|
||||
return [ ux0 + u * dx, uy0 + u * dy, w0 * coshr0 / d3_cosh(ρ * s + r0) ];
|
||||
}
|
||||
return [ ux0 + t * dx, uy0 + t * dy, w0 * Math.exp(ρ * s) ];
|
||||
};
|
||||
}
|
||||
interpolate.duration = S * 1e3;
|
||||
return interpolate;
|
||||
i.duration = S * 1e3;
|
||||
return i;
|
||||
};
|
||||
d3.behavior.zoom = function() {
|
||||
var view = {
|
||||
@@ -1366,8 +1370,9 @@
|
||||
view = {
|
||||
x: view.x,
|
||||
y: view.y,
|
||||
k: +_
|
||||
k: null
|
||||
};
|
||||
scaleTo(+_);
|
||||
rescale();
|
||||
return zoom;
|
||||
};
|
||||
@@ -1466,7 +1471,7 @@
|
||||
}), center0 = null;
|
||||
}
|
||||
function mousedowned() {
|
||||
var that = this, target = d3.event.target, dispatch = event.of(that, arguments), dragged = 0, subject = d3.select(d3_window(that)).on(mousemove, moved).on(mouseup, ended), location0 = location(d3.mouse(that)), dragRestore = d3_event_dragSuppress(that);
|
||||
var that = this, dispatch = event.of(that, arguments), dragged = 0, subject = d3.select(d3_window(that)).on(mousemove, moved).on(mouseup, ended), location0 = location(d3.mouse(that)), dragRestore = d3_event_dragSuppress(that);
|
||||
d3_selection_interrupt.call(that);
|
||||
zoomstarted(dispatch);
|
||||
function moved() {
|
||||
@@ -1476,7 +1481,7 @@
|
||||
}
|
||||
function ended() {
|
||||
subject.on(mousemove, null).on(mouseup, null);
|
||||
dragRestore(dragged && d3.event.target === target);
|
||||
dragRestore(dragged);
|
||||
zoomended(dispatch);
|
||||
}
|
||||
}
|
||||
@@ -1698,9 +1703,8 @@
|
||||
return v < 16 ? "0" + Math.max(0, v).toString(16) : Math.min(255, v).toString(16);
|
||||
}
|
||||
function d3_rgb_parse(format, rgb, hsl) {
|
||||
format = format.toLowerCase();
|
||||
var r = 0, g = 0, b = 0, m1, m2, color;
|
||||
m1 = /([a-z]+)\((.*)\)/.exec(format);
|
||||
m1 = /([a-z]+)\((.*)\)/.exec(format = format.toLowerCase());
|
||||
if (m1) {
|
||||
m2 = m1[2].split(",");
|
||||
switch (m1[1]) {
|
||||
@@ -2115,17 +2119,19 @@
|
||||
};
|
||||
d3.csv = d3.dsv(",", "text/csv");
|
||||
d3.tsv = d3.dsv(" ", "text/tab-separated-values");
|
||||
var d3_timer_queueHead, d3_timer_queueTail, d3_timer_interval, d3_timer_timeout, d3_timer_active, d3_timer_frame = this[d3_vendorSymbol(this, "requestAnimationFrame")] || function(callback) {
|
||||
var d3_timer_queueHead, d3_timer_queueTail, d3_timer_interval, d3_timer_timeout, d3_timer_frame = this[d3_vendorSymbol(this, "requestAnimationFrame")] || function(callback) {
|
||||
setTimeout(callback, 17);
|
||||
};
|
||||
d3.timer = function(callback, delay, then) {
|
||||
d3.timer = function() {
|
||||
d3_timer.apply(this, arguments);
|
||||
};
|
||||
function d3_timer(callback, delay, then) {
|
||||
var n = arguments.length;
|
||||
if (n < 2) delay = 0;
|
||||
if (n < 3) then = Date.now();
|
||||
var time = then + delay, timer = {
|
||||
c: callback,
|
||||
t: time,
|
||||
f: false,
|
||||
n: null
|
||||
};
|
||||
if (d3_timer_queueTail) d3_timer_queueTail.n = timer; else d3_timer_queueHead = timer;
|
||||
@@ -2135,7 +2141,8 @@
|
||||
d3_timer_interval = 1;
|
||||
d3_timer_frame(d3_timer_step);
|
||||
}
|
||||
};
|
||||
return timer;
|
||||
}
|
||||
function d3_timer_step() {
|
||||
var now = d3_timer_mark(), delay = d3_timer_sweep() - now;
|
||||
if (delay > 24) {
|
||||
@@ -2154,22 +2161,21 @@
|
||||
d3_timer_sweep();
|
||||
};
|
||||
function d3_timer_mark() {
|
||||
var now = Date.now();
|
||||
d3_timer_active = d3_timer_queueHead;
|
||||
while (d3_timer_active) {
|
||||
if (now >= d3_timer_active.t) d3_timer_active.f = d3_timer_active.c(now - d3_timer_active.t);
|
||||
d3_timer_active = d3_timer_active.n;
|
||||
var now = Date.now(), timer = d3_timer_queueHead;
|
||||
while (timer) {
|
||||
if (now >= timer.t && timer.c(now - timer.t)) timer.c = null;
|
||||
timer = timer.n;
|
||||
}
|
||||
return now;
|
||||
}
|
||||
function d3_timer_sweep() {
|
||||
var t0, t1 = d3_timer_queueHead, time = Infinity;
|
||||
while (t1) {
|
||||
if (t1.f) {
|
||||
t1 = t0 ? t0.n = t1.n : d3_timer_queueHead = t1.n;
|
||||
} else {
|
||||
if (t1.c) {
|
||||
if (t1.t < time) time = t1.t;
|
||||
t1 = (t0 = t1).n;
|
||||
} else {
|
||||
t1 = t0 ? t0.n = t1.n : d3_timer_queueHead = t1.n;
|
||||
}
|
||||
}
|
||||
d3_timer_queueTail = t0;
|
||||
@@ -2184,7 +2190,7 @@
|
||||
var d3_formatPrefixes = [ "y", "z", "a", "f", "p", "n", "µ", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y" ].map(d3_formatPrefix);
|
||||
d3.formatPrefix = function(value, precision) {
|
||||
var i = 0;
|
||||
if (value) {
|
||||
if (value = +value) {
|
||||
if (value < 0) value *= -1;
|
||||
if (precision) value = d3.round(value, d3_format_precision(value, precision));
|
||||
i = 1 + Math.floor(1e-12 + Math.log(value) / Math.LN10);
|
||||
@@ -2534,7 +2540,8 @@
|
||||
if (i != string.length) return null;
|
||||
if ("p" in d) d.H = d.H % 12 + d.p * 12;
|
||||
var localZ = d.Z != null && d3_date !== d3_date_utc, date = new (localZ ? d3_date_utc : d3_date)();
|
||||
if ("j" in d) date.setFullYear(d.y, 0, d.j); else if ("w" in d && ("W" in d || "U" in d)) {
|
||||
if ("j" in d) date.setFullYear(d.y, 0, d.j); else if ("W" in d || "U" in d) {
|
||||
if (!("w" in d)) d.w = "W" in d ? 1 : 0;
|
||||
date.setFullYear(d.y, 0, 1);
|
||||
date.setFullYear(d.y, 0, "W" in d ? (d.w + 6) % 7 + d.W * 7 - (date.getDay() + 5) % 7 : d.w + d.U * 7 - (date.getDay() + 6) % 7);
|
||||
} else date.setFullYear(d.y, d.m, d.d);
|
||||
@@ -3518,7 +3525,7 @@
|
||||
λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ, point0 = point;
|
||||
}
|
||||
}
|
||||
return (polarAngle < -ε || polarAngle < ε && d3_geo_areaRingSum < 0) ^ winding & 1;
|
||||
return (polarAngle < -ε || polarAngle < ε && d3_geo_areaRingSum < -ε) ^ winding & 1;
|
||||
}
|
||||
function d3_geo_clipCircle(radius) {
|
||||
var cr = Math.cos(radius), smallRadius = cr > 0, notHemisphere = abs(cr) > ε, interpolate = d3_geo_circleInterpolate(radius, 6 * d3_radians);
|
||||
@@ -5986,54 +5993,68 @@
|
||||
f: 0
|
||||
};
|
||||
d3.interpolateTransform = d3_interpolateTransform;
|
||||
function d3_interpolateTransform(a, b) {
|
||||
var s = [], q = [], n, A = d3.transform(a), B = d3.transform(b), ta = A.translate, tb = B.translate, ra = A.rotate, rb = B.rotate, wa = A.skew, wb = B.skew, ka = A.scale, kb = B.scale;
|
||||
if (ta[0] != tb[0] || ta[1] != tb[1]) {
|
||||
s.push("translate(", null, ",", null, ")");
|
||||
function d3_interpolateTransformPop(s) {
|
||||
return s.length ? s.pop() + "," : "";
|
||||
}
|
||||
function d3_interpolateTranslate(ta, tb, s, q) {
|
||||
if (ta[0] !== tb[0] || ta[1] !== tb[1]) {
|
||||
var i = s.push("translate(", null, ",", null, ")");
|
||||
q.push({
|
||||
i: 1,
|
||||
i: i - 4,
|
||||
x: d3_interpolateNumber(ta[0], tb[0])
|
||||
}, {
|
||||
i: 3,
|
||||
i: i - 2,
|
||||
x: d3_interpolateNumber(ta[1], tb[1])
|
||||
});
|
||||
} else if (tb[0] || tb[1]) {
|
||||
s.push("translate(" + tb + ")");
|
||||
} else {
|
||||
s.push("");
|
||||
}
|
||||
if (ra != rb) {
|
||||
}
|
||||
function d3_interpolateRotate(ra, rb, s, q) {
|
||||
if (ra !== rb) {
|
||||
if (ra - rb > 180) rb += 360; else if (rb - ra > 180) ra += 360;
|
||||
q.push({
|
||||
i: s.push(s.pop() + "rotate(", null, ")") - 2,
|
||||
i: s.push(d3_interpolateTransformPop(s) + "rotate(", null, ")") - 2,
|
||||
x: d3_interpolateNumber(ra, rb)
|
||||
});
|
||||
} else if (rb) {
|
||||
s.push(s.pop() + "rotate(" + rb + ")");
|
||||
s.push(d3_interpolateTransformPop(s) + "rotate(" + rb + ")");
|
||||
}
|
||||
if (wa != wb) {
|
||||
}
|
||||
function d3_interpolateSkew(wa, wb, s, q) {
|
||||
if (wa !== wb) {
|
||||
q.push({
|
||||
i: s.push(s.pop() + "skewX(", null, ")") - 2,
|
||||
i: s.push(d3_interpolateTransformPop(s) + "skewX(", null, ")") - 2,
|
||||
x: d3_interpolateNumber(wa, wb)
|
||||
});
|
||||
} else if (wb) {
|
||||
s.push(s.pop() + "skewX(" + wb + ")");
|
||||
s.push(d3_interpolateTransformPop(s) + "skewX(" + wb + ")");
|
||||
}
|
||||
if (ka[0] != kb[0] || ka[1] != kb[1]) {
|
||||
n = s.push(s.pop() + "scale(", null, ",", null, ")");
|
||||
}
|
||||
function d3_interpolateScale(ka, kb, s, q) {
|
||||
if (ka[0] !== kb[0] || ka[1] !== kb[1]) {
|
||||
var i = s.push(d3_interpolateTransformPop(s) + "scale(", null, ",", null, ")");
|
||||
q.push({
|
||||
i: n - 4,
|
||||
i: i - 4,
|
||||
x: d3_interpolateNumber(ka[0], kb[0])
|
||||
}, {
|
||||
i: n - 2,
|
||||
i: i - 2,
|
||||
x: d3_interpolateNumber(ka[1], kb[1])
|
||||
});
|
||||
} else if (kb[0] != 1 || kb[1] != 1) {
|
||||
s.push(s.pop() + "scale(" + kb + ")");
|
||||
} else if (kb[0] !== 1 || kb[1] !== 1) {
|
||||
s.push(d3_interpolateTransformPop(s) + "scale(" + kb + ")");
|
||||
}
|
||||
n = q.length;
|
||||
}
|
||||
function d3_interpolateTransform(a, b) {
|
||||
var s = [], q = [];
|
||||
a = d3.transform(a), b = d3.transform(b);
|
||||
d3_interpolateTranslate(a.translate, b.translate, s, q);
|
||||
d3_interpolateRotate(a.rotate, b.rotate, s, q);
|
||||
d3_interpolateSkew(a.skew, b.skew, s, q);
|
||||
d3_interpolateScale(a.scale, b.scale, s, q);
|
||||
a = b = null;
|
||||
return function(t) {
|
||||
var i = -1, o;
|
||||
var i = -1, n = q.length, o;
|
||||
while (++i < n) s[(o = q[i]).i] = o.x(t);
|
||||
return s.join("");
|
||||
};
|
||||
@@ -6137,7 +6158,7 @@
|
||||
index: di,
|
||||
startAngle: x0,
|
||||
endAngle: x,
|
||||
value: (x - x0) / k
|
||||
value: groupSums[di]
|
||||
};
|
||||
x += padding;
|
||||
}
|
||||
@@ -6205,7 +6226,7 @@
|
||||
return chord;
|
||||
};
|
||||
d3.layout.force = function() {
|
||||
var force = {}, event = d3.dispatch("start", "tick", "end"), size = [ 1, 1 ], drag, alpha, friction = .9, linkDistance = d3_layout_forceLinkDistance, linkStrength = d3_layout_forceLinkStrength, charge = -30, chargeDistance2 = d3_layout_forceChargeDistance2, gravity = .1, theta2 = .64, nodes = [], links = [], distances, strengths, charges;
|
||||
var force = {}, event = d3.dispatch("start", "tick", "end"), timer, size = [ 1, 1 ], drag, alpha, friction = .9, linkDistance = d3_layout_forceLinkDistance, linkStrength = d3_layout_forceLinkStrength, charge = -30, chargeDistance2 = d3_layout_forceChargeDistance2, gravity = .1, theta2 = .64, nodes = [], links = [], distances, strengths, charges;
|
||||
function repulse(node) {
|
||||
return function(quad, x1, _, x2) {
|
||||
if (quad.point !== node) {
|
||||
@@ -6229,6 +6250,7 @@
|
||||
}
|
||||
force.tick = function() {
|
||||
if ((alpha *= .99) < .005) {
|
||||
timer = null;
|
||||
event.end({
|
||||
type: "end",
|
||||
alpha: alpha = 0
|
||||
@@ -6246,7 +6268,7 @@
|
||||
l = alpha * strengths[i] * ((l = Math.sqrt(l)) - distances[i]) / l;
|
||||
x *= l;
|
||||
y *= l;
|
||||
t.x -= x * (k = s.weight / (t.weight + s.weight));
|
||||
t.x -= x * (k = s.weight + t.weight ? s.weight / (s.weight + t.weight) : .5);
|
||||
t.y -= y * k;
|
||||
s.x += x * (k = 1 - k);
|
||||
s.y += y * k;
|
||||
@@ -6342,13 +6364,21 @@
|
||||
if (!arguments.length) return alpha;
|
||||
x = +x;
|
||||
if (alpha) {
|
||||
if (x > 0) alpha = x; else alpha = 0;
|
||||
if (x > 0) {
|
||||
alpha = x;
|
||||
} else {
|
||||
timer.c = null, timer.t = NaN, timer = null;
|
||||
event.end({
|
||||
type: "end",
|
||||
alpha: alpha = 0
|
||||
});
|
||||
}
|
||||
} else if (x > 0) {
|
||||
event.start({
|
||||
type: "start",
|
||||
alpha: alpha = x
|
||||
});
|
||||
d3.timer(force.tick);
|
||||
timer = d3_timer(force.tick);
|
||||
}
|
||||
return force;
|
||||
};
|
||||
@@ -6602,7 +6632,7 @@
|
||||
function pie(data) {
|
||||
var n = data.length, values = data.map(function(d, i) {
|
||||
return +value.call(pie, d, i);
|
||||
}), a = +(typeof startAngle === "function" ? startAngle.apply(this, arguments) : startAngle), da = (typeof endAngle === "function" ? endAngle.apply(this, arguments) : endAngle) - a, p = Math.min(Math.abs(da) / n, +(typeof padAngle === "function" ? padAngle.apply(this, arguments) : padAngle)), pa = p * (da < 0 ? -1 : 1), k = (da - n * pa) / d3.sum(values), index = d3.range(n), arcs = [], v;
|
||||
}), a = +(typeof startAngle === "function" ? startAngle.apply(this, arguments) : startAngle), da = (typeof endAngle === "function" ? endAngle.apply(this, arguments) : endAngle) - a, p = Math.min(Math.abs(da) / n, +(typeof padAngle === "function" ? padAngle.apply(this, arguments) : padAngle)), pa = p * (da < 0 ? -1 : 1), sum = d3.sum(values), k = sum ? (da - n * pa) / sum : 0, index = d3.range(n), arcs = [], v;
|
||||
if (sort != null) index.sort(sort === d3_layout_pieSortByValue ? function(i, j) {
|
||||
return values[j] - values[i];
|
||||
} : function(i, j) {
|
||||
@@ -7315,10 +7345,8 @@
|
||||
}
|
||||
function treemap(d) {
|
||||
var nodes = stickies || hierarchy(d), root = nodes[0];
|
||||
root.x = 0;
|
||||
root.y = 0;
|
||||
root.dx = size[0];
|
||||
root.dy = size[1];
|
||||
root.x = root.y = 0;
|
||||
if (root.value) root.dx = size[0], root.dy = size[1]; else root.dx = root.dy = 0;
|
||||
if (stickies) hierarchy.revalue(root);
|
||||
scale([ root ], root.dx * root.dy / root.value);
|
||||
(stickies ? stickify : squarify)(root);
|
||||
@@ -7538,7 +7566,9 @@
|
||||
return d3.rebind(scale, linear, "range", "rangeRound", "interpolate", "clamp");
|
||||
}
|
||||
function d3_scale_linearNice(domain, m) {
|
||||
return d3_scale_nice(domain, d3_scale_niceStep(d3_scale_linearTickRange(domain, m)[2]));
|
||||
d3_scale_nice(domain, d3_scale_niceStep(d3_scale_linearTickRange(domain, m)[2]));
|
||||
d3_scale_nice(domain, d3_scale_niceStep(d3_scale_linearTickRange(domain, m)[2]));
|
||||
return domain;
|
||||
}
|
||||
function d3_scale_linearTickRange(domain, m) {
|
||||
if (m == null) m = 10;
|
||||
@@ -7640,10 +7670,11 @@
|
||||
scale.tickFormat = function(n, format) {
|
||||
if (!arguments.length) return d3_scale_logFormat;
|
||||
if (arguments.length < 2) format = d3_scale_logFormat; else if (typeof format !== "function") format = d3.format(format);
|
||||
var k = Math.max(.1, n / scale.ticks().length), f = positive ? (e = 1e-12, Math.ceil) : (e = -1e-12,
|
||||
Math.floor), e;
|
||||
var k = Math.max(1, base * n / scale.ticks().length);
|
||||
return function(d) {
|
||||
return d / pow(f(log(d) + e)) <= k ? format(d) : "";
|
||||
var i = d / pow(Math.round(log(d)));
|
||||
if (i * base < base - .5) i *= base;
|
||||
return i <= k ? format(d) : "";
|
||||
};
|
||||
};
|
||||
scale.copy = function() {
|
||||
@@ -7982,11 +8013,16 @@
|
||||
} else {
|
||||
x2 = y2 = 0;
|
||||
}
|
||||
if ((rc = Math.min(Math.abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments))) > .001) {
|
||||
if (da > ε && (rc = Math.min(Math.abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments))) > .001) {
|
||||
cr = r0 < r1 ^ cw ? 0 : 1;
|
||||
var oc = x3 == null ? [ x2, y2 ] : x1 == null ? [ x0, y0 ] : d3_geom_polygonIntersect([ x0, y0 ], [ x3, y3 ], [ x1, y1 ], [ x2, y2 ]), ax = x0 - oc[0], ay = y0 - oc[1], bx = x1 - oc[0], by = y1 - oc[1], kc = 1 / Math.sin(Math.acos((ax * bx + ay * by) / (Math.sqrt(ax * ax + ay * ay) * Math.sqrt(bx * bx + by * by))) / 2), lc = Math.sqrt(oc[0] * oc[0] + oc[1] * oc[1]);
|
||||
var rc1 = rc, rc0 = rc;
|
||||
if (da < π) {
|
||||
var oc = x3 == null ? [ x2, y2 ] : x1 == null ? [ x0, y0 ] : d3_geom_polygonIntersect([ x0, y0 ], [ x3, y3 ], [ x1, y1 ], [ x2, y2 ]), ax = x0 - oc[0], ay = y0 - oc[1], bx = x1 - oc[0], by = y1 - oc[1], kc = 1 / Math.sin(Math.acos((ax * bx + ay * by) / (Math.sqrt(ax * ax + ay * ay) * Math.sqrt(bx * bx + by * by))) / 2), lc = Math.sqrt(oc[0] * oc[0] + oc[1] * oc[1]);
|
||||
rc0 = Math.min(rc, (r0 - lc) / (kc - 1));
|
||||
rc1 = Math.min(rc, (r1 - lc) / (kc + 1));
|
||||
}
|
||||
if (x1 != null) {
|
||||
var rc1 = Math.min(rc, (r1 - lc) / (kc + 1)), t30 = d3_svg_arcCornerTangents(x3 == null ? [ x2, y2 ] : [ x3, y3 ], [ x0, y0 ], r1, rc1, cw), t12 = d3_svg_arcCornerTangents([ x1, y1 ], [ x2, y2 ], r1, rc1, cw);
|
||||
var t30 = d3_svg_arcCornerTangents(x3 == null ? [ x2, y2 ] : [ x3, y3 ], [ x0, y0 ], r1, rc1, cw), t12 = d3_svg_arcCornerTangents([ x1, y1 ], [ x2, y2 ], r1, rc1, cw);
|
||||
if (rc === rc1) {
|
||||
path.push("M", t30[0], "A", rc1, ",", rc1, " 0 0,", cr, " ", t30[1], "A", r1, ",", r1, " 0 ", 1 - cw ^ d3_svg_arcSweep(t30[1][0], t30[1][1], t12[1][0], t12[1][1]), ",", cw, " ", t12[1], "A", rc1, ",", rc1, " 0 0,", cr, " ", t12[0]);
|
||||
} else {
|
||||
@@ -7996,7 +8032,7 @@
|
||||
path.push("M", x0, ",", y0);
|
||||
}
|
||||
if (x3 != null) {
|
||||
var rc0 = Math.min(rc, (r0 - lc) / (kc - 1)), t03 = d3_svg_arcCornerTangents([ x0, y0 ], [ x3, y3 ], r0, -rc0, cw), t21 = d3_svg_arcCornerTangents([ x2, y2 ], x1 == null ? [ x0, y0 ] : [ x1, y1 ], r0, -rc0, cw);
|
||||
var t03 = d3_svg_arcCornerTangents([ x0, y0 ], [ x3, y3 ], r0, -rc0, cw), t21 = d3_svg_arcCornerTangents([ x2, y2 ], x1 == null ? [ x0, y0 ] : [ x1, y1 ], r0, -rc0, cw);
|
||||
if (rc === rc0) {
|
||||
path.push("L", t21[0], "A", rc0, ",", rc0, " 0 0,", cr, " ", t21[1], "A", r0, ",", r0, " 0 ", cw ^ d3_svg_arcSweep(t21[1][0], t21[1][1], t03[1][0], t03[1][1]), ",", 1 - cw, " ", t03[1], "A", rc0, ",", rc0, " 0 0,", cr, " ", t03[0]);
|
||||
} else {
|
||||
@@ -8078,7 +8114,7 @@
|
||||
return (x0 - x1) * y0 - (y0 - y1) * x0 > 0 ? 0 : 1;
|
||||
}
|
||||
function d3_svg_arcCornerTangents(p0, p1, r1, rc, cw) {
|
||||
var x01 = p0[0] - p1[0], y01 = p0[1] - p1[1], lo = (cw ? rc : -rc) / Math.sqrt(x01 * x01 + y01 * y01), ox = lo * y01, oy = -lo * x01, x1 = p0[0] + ox, y1 = p0[1] + oy, x2 = p1[0] + ox, y2 = p1[1] + oy, x3 = (x1 + x2) / 2, y3 = (y1 + y2) / 2, dx = x2 - x1, dy = y2 - y1, d2 = dx * dx + dy * dy, r = r1 - rc, D = x1 * y2 - x2 * y1, d = (dy < 0 ? -1 : 1) * Math.sqrt(r * r * d2 - D * D), cx0 = (D * dy - dx * d) / d2, cy0 = (-D * dx - dy * d) / d2, cx1 = (D * dy + dx * d) / d2, cy1 = (-D * dx + dy * d) / d2, dx0 = cx0 - x3, dy0 = cy0 - y3, dx1 = cx1 - x3, dy1 = cy1 - y3;
|
||||
var x01 = p0[0] - p1[0], y01 = p0[1] - p1[1], lo = (cw ? rc : -rc) / Math.sqrt(x01 * x01 + y01 * y01), ox = lo * y01, oy = -lo * x01, x1 = p0[0] + ox, y1 = p0[1] + oy, x2 = p1[0] + ox, y2 = p1[1] + oy, x3 = (x1 + x2) / 2, y3 = (y1 + y2) / 2, dx = x2 - x1, dy = y2 - y1, d2 = dx * dx + dy * dy, r = r1 - rc, D = x1 * y2 - x2 * y1, d = (dy < 0 ? -1 : 1) * Math.sqrt(Math.max(0, r * r * d2 - D * D)), cx0 = (D * dy - dx * d) / d2, cy0 = (-D * dx - dy * d) / d2, cx1 = (D * dy + dx * d) / d2, cy1 = (-D * dx + dy * d) / d2, dx0 = cx0 - x3, dy0 = cy0 - y3, dx1 = cx1 - x3, dy1 = cy1 - y3;
|
||||
if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1;
|
||||
return [ [ cx0 - ox, cy0 - oy ], [ cx0 * r1 / r, cy0 * r1 / r ] ];
|
||||
}
|
||||
@@ -8150,10 +8186,10 @@
|
||||
value.closed = /-closed$/.test(key);
|
||||
});
|
||||
function d3_svg_lineLinear(points) {
|
||||
return points.join("L");
|
||||
return points.length > 1 ? points.join("L") : points + "Z";
|
||||
}
|
||||
function d3_svg_lineLinearClosed(points) {
|
||||
return d3_svg_lineLinear(points) + "Z";
|
||||
return points.join("L") + "Z";
|
||||
}
|
||||
function d3_svg_lineStep(points) {
|
||||
var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ];
|
||||
@@ -8175,7 +8211,7 @@
|
||||
return points.length < 4 ? d3_svg_lineLinear(points) : points[1] + d3_svg_lineHermite(points.slice(1, -1), d3_svg_lineCardinalTangents(points, tension));
|
||||
}
|
||||
function d3_svg_lineCardinalClosed(points, tension) {
|
||||
return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite((points.push(points[0]),
|
||||
return points.length < 3 ? d3_svg_lineLinearClosed(points) : points[0] + d3_svg_lineHermite((points.push(points[0]),
|
||||
points), d3_svg_lineCardinalTangents([ points[points.length - 2] ].concat(points, [ points[1] ]), tension));
|
||||
}
|
||||
function d3_svg_lineCardinal(points, tension) {
|
||||
@@ -8611,9 +8647,11 @@
|
||||
var d3_selection_interrupt = d3_selection_interruptNS(d3_transitionNamespace());
|
||||
function d3_selection_interruptNS(ns) {
|
||||
return function() {
|
||||
var lock, active;
|
||||
if ((lock = this[ns]) && (active = lock[lock.active])) {
|
||||
if (--lock.count) delete lock[lock.active]; else delete this[ns];
|
||||
var lock, activeId, active;
|
||||
if ((lock = this[ns]) && (active = lock[activeId = lock.active])) {
|
||||
active.timer.c = null;
|
||||
active.timer.t = NaN;
|
||||
if (--lock.count) delete lock[activeId]; else delete this[ns];
|
||||
lock.active += .5;
|
||||
active.event && active.event.interrupt.call(this, this.__data__, active.index);
|
||||
}
|
||||
@@ -8868,12 +8906,68 @@
|
||||
var lock = node[ns] || (node[ns] = {
|
||||
active: 0,
|
||||
count: 0
|
||||
}), transition = lock[id];
|
||||
}), transition = lock[id], time, timer, duration, ease, tweens;
|
||||
function schedule(elapsed) {
|
||||
var delay = transition.delay;
|
||||
timer.t = delay + time;
|
||||
if (delay <= elapsed) return start(elapsed - delay);
|
||||
timer.c = start;
|
||||
}
|
||||
function start(elapsed) {
|
||||
var activeId = lock.active, active = lock[activeId];
|
||||
if (active) {
|
||||
active.timer.c = null;
|
||||
active.timer.t = NaN;
|
||||
--lock.count;
|
||||
delete lock[activeId];
|
||||
active.event && active.event.interrupt.call(node, node.__data__, active.index);
|
||||
}
|
||||
for (var cancelId in lock) {
|
||||
if (+cancelId < id) {
|
||||
var cancel = lock[cancelId];
|
||||
cancel.timer.c = null;
|
||||
cancel.timer.t = NaN;
|
||||
--lock.count;
|
||||
delete lock[cancelId];
|
||||
}
|
||||
}
|
||||
timer.c = tick;
|
||||
d3_timer(function() {
|
||||
if (timer.c && tick(elapsed || 1)) {
|
||||
timer.c = null;
|
||||
timer.t = NaN;
|
||||
}
|
||||
return 1;
|
||||
}, 0, time);
|
||||
lock.active = id;
|
||||
transition.event && transition.event.start.call(node, node.__data__, i);
|
||||
tweens = [];
|
||||
transition.tween.forEach(function(key, value) {
|
||||
if (value = value.call(node, node.__data__, i)) {
|
||||
tweens.push(value);
|
||||
}
|
||||
});
|
||||
ease = transition.ease;
|
||||
duration = transition.duration;
|
||||
}
|
||||
function tick(elapsed) {
|
||||
var t = elapsed / duration, e = ease(t), n = tweens.length;
|
||||
while (n > 0) {
|
||||
tweens[--n].call(node, e);
|
||||
}
|
||||
if (t >= 1) {
|
||||
transition.event && transition.event.end.call(node, node.__data__, i);
|
||||
if (--lock.count) delete lock[id]; else delete node[ns];
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (!transition) {
|
||||
var time = inherit.time;
|
||||
time = inherit.time;
|
||||
timer = d3_timer(schedule, 0, time);
|
||||
transition = lock[id] = {
|
||||
tween: new d3_Map(),
|
||||
time: time,
|
||||
timer: timer,
|
||||
delay: inherit.delay,
|
||||
duration: inherit.duration,
|
||||
ease: inherit.ease,
|
||||
@@ -8881,49 +8975,6 @@
|
||||
};
|
||||
inherit = null;
|
||||
++lock.count;
|
||||
d3.timer(function(elapsed) {
|
||||
var delay = transition.delay, duration, ease, timer = d3_timer_active, tweened = [];
|
||||
timer.t = delay + time;
|
||||
if (delay <= elapsed) return start(elapsed - delay);
|
||||
timer.c = start;
|
||||
function start(elapsed) {
|
||||
if (lock.active > id) return stop();
|
||||
var active = lock[lock.active];
|
||||
if (active) {
|
||||
--lock.count;
|
||||
delete lock[lock.active];
|
||||
active.event && active.event.interrupt.call(node, node.__data__, active.index);
|
||||
}
|
||||
lock.active = id;
|
||||
transition.event && transition.event.start.call(node, node.__data__, i);
|
||||
transition.tween.forEach(function(key, value) {
|
||||
if (value = value.call(node, node.__data__, i)) {
|
||||
tweened.push(value);
|
||||
}
|
||||
});
|
||||
ease = transition.ease;
|
||||
duration = transition.duration;
|
||||
d3.timer(function() {
|
||||
timer.c = tick(elapsed || 1) ? d3_true : tick;
|
||||
return 1;
|
||||
}, 0, time);
|
||||
}
|
||||
function tick(elapsed) {
|
||||
if (lock.active !== id) return 1;
|
||||
var t = elapsed / duration, e = ease(t), n = tweened.length;
|
||||
while (n > 0) {
|
||||
tweened[--n].call(node, e);
|
||||
}
|
||||
if (t >= 1) {
|
||||
transition.event && transition.event.end.call(node, node.__data__, i);
|
||||
return stop();
|
||||
}
|
||||
}
|
||||
function stop() {
|
||||
if (--lock.count) delete lock[id]; else delete node[ns];
|
||||
return 1;
|
||||
}
|
||||
}, 0, time);
|
||||
}
|
||||
}
|
||||
d3.svg.axis = function() {
|
||||
@@ -8977,7 +9028,7 @@
|
||||
};
|
||||
axis.ticks = function() {
|
||||
if (!arguments.length) return tickArguments_;
|
||||
tickArguments_ = arguments;
|
||||
tickArguments_ = d3_array(arguments);
|
||||
return axis;
|
||||
};
|
||||
axis.tickValues = function(x) {
|
||||
@@ -9499,6 +9550,5 @@
|
||||
d3.xml = d3_xhrType(function(request) {
|
||||
return request.responseXML;
|
||||
});
|
||||
if (typeof define === "function" && define.amd) define(d3); else if (typeof module === "object" && module.exports) module.exports = d3;
|
||||
this.d3 = d3;
|
||||
if (typeof define === "function" && define.amd) this.d3 = d3, define(d3); else if (typeof module === "object" && module.exports) module.exports = d3; else this.d3 = d3;
|
||||
}();
|
||||
+2607
-1943
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+1836
-1231
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,6 @@
|
||||
/** vim: et:ts=4:sw=4:sts=4
|
||||
* @license RequireJS 2.1.20 Copyright (c) 2010-2015, The Dojo Foundation All Rights Reserved.
|
||||
* Available via the MIT or new BSD license.
|
||||
* see: http://github.com/jrburke/requirejs for details
|
||||
* @license RequireJS 2.2.0 Copyright jQuery Foundation and other contributors.
|
||||
* Released under MIT license, http://github.com/requirejs/requirejs/LICENSE
|
||||
*/
|
||||
//Not using strict: uneven strict support in browsers, #392, and causes
|
||||
//problems with requirejs.exec()/transpiler plugins that may not be strict.
|
||||
@@ -12,7 +11,7 @@ var requirejs, require, define;
|
||||
(function (global) {
|
||||
var req, s, head, baseElement, dataMain, src,
|
||||
interactiveScript, currentlyAddingScript, mainScript, subPath,
|
||||
version = '2.1.20',
|
||||
version = '2.2.0',
|
||||
commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,
|
||||
cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,
|
||||
jsSuffixRegExp = /\.js$/,
|
||||
@@ -20,7 +19,6 @@ var requirejs, require, define;
|
||||
op = Object.prototype,
|
||||
ostring = op.toString,
|
||||
hasOwn = op.hasOwnProperty,
|
||||
ap = Array.prototype,
|
||||
isBrowser = !!(typeof window !== 'undefined' && typeof navigator !== 'undefined' && window.document),
|
||||
isWebWorker = !isBrowser && typeof importScripts !== 'undefined',
|
||||
//PS3 indicates loaded and complete, but need to wait for complete
|
||||
@@ -37,6 +35,11 @@ var requirejs, require, define;
|
||||
globalDefQueue = [],
|
||||
useInteractive = false;
|
||||
|
||||
//Could match something like ')//comment', do not lose the prefix to comment.
|
||||
function commentReplace(match, multi, multiText, singlePrefix) {
|
||||
return singlePrefix || '';
|
||||
}
|
||||
|
||||
function isFunction(it) {
|
||||
return ostring.call(it) === '[object Function]';
|
||||
}
|
||||
@@ -909,7 +912,11 @@ var requirejs, require, define;
|
||||
defined[id] = exports;
|
||||
|
||||
if (req.onResourceLoad) {
|
||||
req.onResourceLoad(context, this.map, this.depMaps);
|
||||
var resLoadMaps = [];
|
||||
each(this.depMaps, function (depMap) {
|
||||
resLoadMaps.push(depMap.normalizedMap || depMap);
|
||||
});
|
||||
req.onResourceLoad(context, this.map, resLoadMaps);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -968,6 +975,7 @@ var requirejs, require, define;
|
||||
this.map.parentMap);
|
||||
on(normalizedMap,
|
||||
'defined', bind(this, function (value) {
|
||||
this.map.normalizedMap = normalizedMap;
|
||||
this.init([], function () { return value; }, null, {
|
||||
enabled: true,
|
||||
ignore: true
|
||||
@@ -1276,6 +1284,14 @@ var requirejs, require, define;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert old style urlArgs string to a function.
|
||||
if (typeof cfg.urlArgs === 'string') {
|
||||
var urlArgs = cfg.urlArgs;
|
||||
cfg.urlArgs = function(id, url) {
|
||||
return (url.indexOf('?') === -1 ? '?' : '&') + urlArgs;
|
||||
};
|
||||
}
|
||||
|
||||
//Save off the paths since they require special processing,
|
||||
//they are additive.
|
||||
var shim = config.shim,
|
||||
@@ -1652,13 +1668,12 @@ var requirejs, require, define;
|
||||
|
||||
//Join the path parts together, then figure out if baseUrl is needed.
|
||||
url = syms.join('/');
|
||||
url += (ext || (/^data\:|\?/.test(url) || skipExt ? '' : '.js'));
|
||||
url += (ext || (/^data\:|^blob\:|\?/.test(url) || skipExt ? '' : '.js'));
|
||||
url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url;
|
||||
}
|
||||
|
||||
return config.urlArgs ? url +
|
||||
((url.indexOf('?') === -1 ? '?' : '&') +
|
||||
config.urlArgs) : url;
|
||||
return config.urlArgs && !/^blob\:/.test(url) ?
|
||||
url + config.urlArgs(moduleName, url) : url;
|
||||
},
|
||||
|
||||
//Delegates to req.load. Broken out as a separate function to
|
||||
@@ -1706,7 +1721,21 @@ var requirejs, require, define;
|
||||
onScriptError: function (evt) {
|
||||
var data = getScriptData(evt);
|
||||
if (!hasPathFallback(data.id)) {
|
||||
return onError(makeError('scripterror', 'Script error for: ' + data.id, evt, [data.id]));
|
||||
var parents = [];
|
||||
eachProp(registry, function(value, key) {
|
||||
if (key.indexOf('_@r') !== 0) {
|
||||
each(value.depMaps, function(depMap) {
|
||||
if (depMap.id === data.id) {
|
||||
parents.push(key);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
return onError(makeError('scripterror', 'Script error for "' + data.id +
|
||||
(parents.length ?
|
||||
'", needed by: ' + parents.join(', ') :
|
||||
'"'), evt, [data.id]));
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1865,9 +1894,6 @@ var requirejs, require, define;
|
||||
if (isBrowser) {
|
||||
//In the browser so use a script tag
|
||||
node = req.createNode(config, moduleName, url);
|
||||
if (config.onNodeCreated) {
|
||||
config.onNodeCreated(node, config, moduleName, url);
|
||||
}
|
||||
|
||||
node.setAttribute('data-requirecontext', context.contextName);
|
||||
node.setAttribute('data-requiremodule', moduleName);
|
||||
@@ -1883,11 +1909,11 @@ var requirejs, require, define;
|
||||
if (node.attachEvent &&
|
||||
//Check if node.attachEvent is artificially added by custom script or
|
||||
//natively supported by browser
|
||||
//read https://github.com/jrburke/requirejs/issues/187
|
||||
//read https://github.com/requirejs/requirejs/issues/187
|
||||
//if we can NOT find [native code] then it must NOT natively supported.
|
||||
//in IE8, node.attachEvent does not have toString()
|
||||
//Note the test for "[native code" with no closing brace, see:
|
||||
//https://github.com/jrburke/requirejs/issues/273
|
||||
//https://github.com/requirejs/requirejs/issues/273
|
||||
!(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) &&
|
||||
!isOpera) {
|
||||
//Probably IE. IE (at least 6-8) do not fire
|
||||
@@ -1915,6 +1941,12 @@ var requirejs, require, define;
|
||||
}
|
||||
node.src = url;
|
||||
|
||||
//Calling onNodeCreated after all properties on the node have been
|
||||
//set, but before it is placed in the DOM.
|
||||
if (config.onNodeCreated) {
|
||||
config.onNodeCreated(node, config, moduleName, url);
|
||||
}
|
||||
|
||||
//For some cache cases in IE 6-8, the script executes before the end
|
||||
//of the appendChild execution, so to tie an anonymous define
|
||||
//call to the module name (which is stored on the node), hold on
|
||||
@@ -1933,9 +1965,14 @@ var requirejs, require, define;
|
||||
//In a web worker, use importScripts. This is not a very
|
||||
//efficient use of importScripts, importScripts will block until
|
||||
//its script is downloaded and evaluated. However, if web workers
|
||||
//are in play, the expectation that a build has been done so that
|
||||
//only one script needs to be loaded anyway. This may need to be
|
||||
//reevaluated if other use cases become common.
|
||||
//are in play, the expectation is that a build has been done so
|
||||
//that only one script needs to be loaded anyway. This may need
|
||||
//to be reevaluated if other use cases become common.
|
||||
|
||||
// Post a task to the event loop to work around a bug in WebKit
|
||||
// where the worker gets garbage-collected after calling
|
||||
// importScripts(): https://webkit.org/b/153317
|
||||
setTimeout(function() {}, 0);
|
||||
importScripts(url);
|
||||
|
||||
//Account for anonymous modules
|
||||
@@ -1981,8 +2018,10 @@ var requirejs, require, define;
|
||||
//Preserve dataMain in case it is a path (i.e. contains '?')
|
||||
mainScript = dataMain;
|
||||
|
||||
//Set final baseUrl if there is not already an explicit one.
|
||||
if (!cfg.baseUrl) {
|
||||
//Set final baseUrl if there is not already an explicit one,
|
||||
//but only do so if the data-main value is not a loader plugin
|
||||
//module ID.
|
||||
if (!cfg.baseUrl && mainScript.indexOf('!') === -1) {
|
||||
//Pull off the directory of data-main for use as the
|
||||
//baseUrl.
|
||||
src = mainScript.split('/');
|
||||
@@ -2043,7 +2082,7 @@ var requirejs, require, define;
|
||||
if (callback.length) {
|
||||
callback
|
||||
.toString()
|
||||
.replace(commentRegExp, '')
|
||||
.replace(commentRegExp, commentReplace)
|
||||
.replace(cjsRequireRegExp, function (match, dep) {
|
||||
deps.push(dep);
|
||||
});
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -33,30 +33,23 @@ var DCListItemView = FoldoutListItemView.extend(
|
||||
/** event listeners */
|
||||
_setUpListeners : function(){
|
||||
FoldoutListItemView.prototype._setUpListeners.call( this );
|
||||
// re-rendering on deletion
|
||||
this.listenTo( this.model, 'change', function( model, options ){
|
||||
if( _.isEqual( _.keys( model.changed ), [ 'deleted' ] ) ){
|
||||
// if the model has changed deletion status render it entirely
|
||||
if( _.has( model.changed, 'deleted' ) ){
|
||||
this.render();
|
||||
|
||||
// if the model has been decorated after the fact with the element count,
|
||||
// render the subtitle where the count is displayed
|
||||
} else if( _.has( model.changed, 'element_count' ) ){
|
||||
this.$( '> .title-bar .subtitle' ).replaceWith( this._renderSubtitle() );
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// ......................................................................... rendering
|
||||
//TODO:?? possibly move to listItem
|
||||
/** render a subtitle to show the user what sort of collection this is */
|
||||
_renderSubtitle : function(){
|
||||
var $subtitle = $( '<div class="subtitle"></div>' );
|
||||
//TODO: would be good to get this in the subtitle
|
||||
//var len = this.model.elements.length;
|
||||
switch( this.model.get( 'collection_type' ) ){
|
||||
case 'list':
|
||||
return $subtitle.text( _l( 'a list of datasets' ) );
|
||||
case 'paired':
|
||||
return $subtitle.text( _l( 'a pair of datasets' ) );
|
||||
case 'list:paired':
|
||||
return $subtitle.text( _l( 'a list of paired datasets' ) );
|
||||
}
|
||||
return $subtitle;
|
||||
return $( this.templates.subtitle( this.model.toJSON(), this ) );
|
||||
},
|
||||
|
||||
// ......................................................................... foldout
|
||||
@@ -122,9 +115,24 @@ DCListItemView.prototype.templates = (function(){
|
||||
'</div>'
|
||||
], 'collection' );
|
||||
|
||||
// use element identifier
|
||||
var subtitleTemplate = BASE_MVC.wrapTemplate([
|
||||
'<div class="subtitle">',
|
||||
'<% var countText = collection.element_count? ( collection.element_count + " " ) : ""; %>',
|
||||
'<% if( collection.collection_type === "list" ){ %>',
|
||||
_l( 'a list of <%- countText %>datasets' ),
|
||||
'<% } else if( collection.collection_type === "paired" ){ %>',
|
||||
_l( 'a pair of datasets' ),
|
||||
'<% } else if( collection.collection_type === "list:paired" ){ %>',
|
||||
_l( 'a list of <%- countText %>dataset pairs' ),
|
||||
'<% } %>',
|
||||
'</div>'
|
||||
], 'collection' );
|
||||
|
||||
return _.extend( {}, FoldoutListItemView.prototype.templates, {
|
||||
warnings : warnings,
|
||||
titleBar : titleBarTemplate
|
||||
warnings : warnings,
|
||||
titleBar : titleBarTemplate,
|
||||
subtitle : subtitleTemplate
|
||||
});
|
||||
}());
|
||||
|
||||
|
||||
@@ -700,7 +700,7 @@ var ListCollectionCreator = Backbone.View.extend( BASE_MVC.LoggableMixin ).exten
|
||||
//TODO: no need to re-create - move instead
|
||||
this.$( '.element-drop-placeholder' ).remove();
|
||||
var $placeholder = $( '<div class="element-drop-placeholder"></div>' );
|
||||
if( !$nearest.size() ){
|
||||
if( !$nearest.length ){
|
||||
$list.append( $placeholder );
|
||||
} else {
|
||||
$nearest.before( $placeholder );
|
||||
@@ -747,7 +747,7 @@ var ListCollectionCreator = Backbone.View.extend( BASE_MVC.LoggableMixin ).exten
|
||||
|
||||
// insert before the nearest element or after the last.
|
||||
var $nearest = this._getNearestElement( ev.clientY );
|
||||
if( $nearest.size() ){
|
||||
if( $nearest.length ){
|
||||
this.$dragging.insertBefore( $nearest );
|
||||
} else {
|
||||
// no nearest before - insert after last element
|
||||
|
||||
@@ -764,7 +764,7 @@ var PairedCollectionCreator = Backbone.View.extend( baseMVC.LoggableMixin ).exte
|
||||
_adjUnpairedOnScrollbar : function(){
|
||||
var $unpairedColumns = this.$( '.unpaired-columns' ).last(),
|
||||
$firstDataset = this.$( '.unpaired-columns .reverse-column .dataset' ).first();
|
||||
if( !$firstDataset.size() ){ return; }
|
||||
if( !$firstDataset.length ){ return; }
|
||||
var ucRight = $unpairedColumns.offset().left + $unpairedColumns.outerWidth(),
|
||||
dsRight = $firstDataset.offset().left + $firstDataset.outerWidth(),
|
||||
rightDiff = Math.floor( ucRight ) - Math.floor( dsRight );
|
||||
@@ -1105,7 +1105,7 @@ var PairedCollectionCreator = Backbone.View.extend( baseMVC.LoggableMixin ).exte
|
||||
var dataset = $dataset.data( 'dataset' ),
|
||||
select = options.force !== undefined? options.force: !$dataset.hasClass( 'selected' );
|
||||
//this.debug( id, options.force, $dataset, dataset );
|
||||
if( !$dataset.size() || dataset === undefined ){ return $dataset; }
|
||||
if( !$dataset.length || dataset === undefined ){ return $dataset; }
|
||||
|
||||
if( select ){
|
||||
$dataset.addClass( 'selected' );
|
||||
@@ -1321,7 +1321,7 @@ var PairedCollectionCreator = Backbone.View.extend( baseMVC.LoggableMixin ).exte
|
||||
|
||||
$( '.element-drop-placeholder' ).remove();
|
||||
var $placeholder = $( '<div class="element-drop-placeholder"></div>' );
|
||||
if( !$nearest.size() ){
|
||||
if( !$nearest.length ){
|
||||
$list.append( $placeholder );
|
||||
} else {
|
||||
$nearest.before( $placeholder );
|
||||
@@ -1367,7 +1367,7 @@ var PairedCollectionCreator = Backbone.View.extend( baseMVC.LoggableMixin ).exte
|
||||
ev.dataTransfer.dropEffect = 'move';
|
||||
|
||||
var $nearest = this._getNearestPairedDatasetLi( ev.originalEvent.clientY );
|
||||
if( $nearest.size() ){
|
||||
if( $nearest.length ){
|
||||
this.$dragging.insertBefore( $nearest );
|
||||
|
||||
} else {
|
||||
|
||||
@@ -130,6 +130,8 @@ var DatasetAssociation = Backbone.Model
|
||||
|
||||
/** Does this model already contain detailed data (as opposed to just summary level data)? */
|
||||
hasDetails : function(){
|
||||
// if it's inaccessible assume it has everything it needs
|
||||
if( !this.get( 'accessible' ) ){ return true; }
|
||||
//?? this may not be reliable
|
||||
return _.has( this.attributes, 'genome_build' );
|
||||
},
|
||||
|
||||
@@ -122,7 +122,10 @@ define([ 'utils/utils' ], function( Utils ) {
|
||||
/** Matches a new tool model to the current input elements e.g. used to update dynamic options
|
||||
*/
|
||||
matchModel: function( model, callback ) {
|
||||
return matchIds( model.inputs, this.flat_dict, callback );
|
||||
var self = this;
|
||||
visitInputs( model.inputs, function( input, name ) {
|
||||
self.flat_dict[ name ] && callback ( input, self.flat_dict[ name ] );
|
||||
});
|
||||
},
|
||||
|
||||
/** Matches identifier from api response to input elements e.g. used to display validation errors
|
||||
@@ -191,66 +194,50 @@ define([ 'utils/utils' ], function( Utils ) {
|
||||
return -1;
|
||||
};
|
||||
|
||||
/** Match context
|
||||
* @param{dict} inputs - Dictionary of input elements
|
||||
* @param{dict} key - Reference key which is matched to an input name e.g. data_ref
|
||||
* @param{dict} callback - Called with matched context i.e. callback( input, referenced_input )
|
||||
*/
|
||||
var matchContext = function( inputs, key, callback, context ) {
|
||||
context = $.extend( true, {}, context );
|
||||
_.each( inputs, function ( input ) {
|
||||
input && input.type && ( context[ input.name ] = input );
|
||||
});
|
||||
_.each( inputs, function ( input ) {
|
||||
if ( _.isObject( input ) ) {
|
||||
if ( input.type && context[ input[ key ] ] ) {
|
||||
callback ( input, context[ input[ key ] ] );
|
||||
} else {
|
||||
matchContext( input, key, callback, context );
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/** Matches a tool model to a dictionary, indexed with flat ids
|
||||
* @param{dict} inputs - Dictionary of input elements
|
||||
* @param{dict} mapping - Dictionary containing flat ids
|
||||
/** Visits tool inputs
|
||||
* @param{dict} inputs - Nested dictionary of input elements
|
||||
* @param{dict} callback - Called with the mapped dictionary object and corresponding model node
|
||||
*/
|
||||
var matchIds = function( inputs, mapping, callback ) {
|
||||
var result = {};
|
||||
var self = this;
|
||||
function search ( id, head ) {
|
||||
for ( var i in head ) {
|
||||
var node = head[ i ];
|
||||
var index = node.name;
|
||||
id != '' && ( index = id + '|' + index );
|
||||
switch ( node.type ) {
|
||||
case 'repeat':
|
||||
for ( var j in node.cache ) {
|
||||
search ( index + '_' + j, node.cache[ j ] );
|
||||
var visitInputs = function( inputs, callback, prefix, context ) {
|
||||
context = $.extend( true, {}, context );
|
||||
_.each( inputs, function ( input ) {
|
||||
if ( input && input.type && input.name ) {
|
||||
context[ input.name ] = input;
|
||||
}
|
||||
});
|
||||
for ( var i in inputs ) {
|
||||
var node = inputs[ i ];
|
||||
var name = prefix ? prefix + '|' + node.name : node.name;
|
||||
switch ( node.type ) {
|
||||
case 'repeat':
|
||||
_.each( node.cache, function( cache, j ) {
|
||||
visitInputs( cache, callback, name + '_' + j, context );
|
||||
});
|
||||
break;
|
||||
case 'conditional':
|
||||
if ( node.test_param ) {
|
||||
callback( node.test_param, name + '|' + node.test_param.name, context );
|
||||
var selectedCase = matchCase( node, node.test_param.value );
|
||||
if ( selectedCase != -1 ) {
|
||||
visitInputs( node.cases[ selectedCase ].inputs, callback, name, context );
|
||||
} else {
|
||||
Galaxy.emit.debug( 'form-data::visitInputs() - Invalid case for ' + name + '.' );
|
||||
}
|
||||
break;
|
||||
case 'conditional':
|
||||
var selectedCase = matchCase( node, node.test_param && node.test_param.value );
|
||||
selectedCase != -1 && search ( index, node.cases[ selectedCase ].inputs );
|
||||
break;
|
||||
case 'section':
|
||||
search ( index, node.inputs );
|
||||
break;
|
||||
default:
|
||||
var mapped = mapping[ index ];
|
||||
mapped && callback( mapped, node );
|
||||
}
|
||||
} else {
|
||||
Galaxy.emit.debug( 'form-data::visitInputs() - Conditional test parameter missing for ' + name + '.' );
|
||||
}
|
||||
break;
|
||||
case 'section':
|
||||
visitInputs( node.inputs, callback, name, context )
|
||||
break;
|
||||
default:
|
||||
callback( node, name, context );
|
||||
}
|
||||
}
|
||||
search( '', inputs );
|
||||
return result;
|
||||
};
|
||||
|
||||
return {
|
||||
Manager : Manager,
|
||||
matchIds : matchIds,
|
||||
matchContext : matchContext
|
||||
visitInputs : visitInputs
|
||||
}
|
||||
});
|
||||
@@ -46,10 +46,10 @@ define([], function() {
|
||||
});
|
||||
},
|
||||
|
||||
/** Disable input element
|
||||
/** Set backdrop for input element
|
||||
*/
|
||||
disable: function( silent ) {
|
||||
this.model.set( 'backdrop', silent ? 'silent' : 'default' );
|
||||
backdrop: function() {
|
||||
this.model.set( 'backdrop', true );
|
||||
},
|
||||
|
||||
/** Set error text
|
||||
@@ -73,21 +73,21 @@ define([], function() {
|
||||
help_text += ' (' + help_argument + ')';
|
||||
}
|
||||
this.$info.html( help_text );
|
||||
// render input field
|
||||
this.field.collapsed ? this.$field.hide() : this.$field.fadeIn( 'fast' );
|
||||
// render preview view for collapsed fields
|
||||
this.$preview[ this.field.collapsed && this.model.get( 'collapsible_preview' ) ? 'show' : 'hide' ]()
|
||||
this.$preview[ ( this.field.collapsed && this.model.get( 'collapsible_preview' ) || this.model.get( 'disabled' ) ) ? 'show' : 'hide' ]()
|
||||
.html( _.escape( this.model.get( 'text_value' ) ) );
|
||||
// render error messages
|
||||
var error_text = this.model.get( 'error_text' );
|
||||
this.$error[ error_text ? 'show' : 'hide' ]();
|
||||
this.$el[ error_text ? 'addClass' : 'removeClass' ]( 'ui-error' );
|
||||
this.$error_text.html( error_text );
|
||||
// render backdrop to disable field
|
||||
this.$backdrop.removeClass()
|
||||
.addClass( 'ui-form-backdrop' )
|
||||
.addClass( 'ui-form-backdrop-' + this.model.get( 'backdrop' ) );
|
||||
// render collapsible state and title
|
||||
// render backdrop
|
||||
this.$backdrop[ this.model.get( 'backdrop' ) ? 'show' : 'hide' ]();
|
||||
// render input field
|
||||
this.field.collapsed || this.model.get( 'disabled' ) ? this.$field.hide() : this.$field.fadeIn( 'fast' );
|
||||
// render input field color and style
|
||||
this.field.model && this.field.model.set( { 'color': this.model.get( 'color' ), 'style': this.model.get( 'style' ) } );
|
||||
// render collapsible options
|
||||
if ( !this.model.get( 'disabled' ) && this.model.get( 'collapsible_value' ) !== undefined ) {
|
||||
var collapsible_state = this.field.collapsed ? 'enable' : 'disable';
|
||||
this.$title_text.hide();
|
||||
@@ -118,9 +118,9 @@ define([], function() {
|
||||
)
|
||||
.append( $( '<div/>' ).addClass( 'ui-form-field' )
|
||||
.append( $( '<span/>' ).addClass( 'ui-form-info' ) )
|
||||
.append( $( '<span/>' ).addClass( 'ui-form-backdrop' ) )
|
||||
.append( $( '<div/>' ).addClass( 'ui-form-backdrop' ) )
|
||||
)
|
||||
.append( $( '<div/>' ).addClass( 'ui-form-preview' ) );
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -60,6 +60,7 @@ define(['utils/utils',
|
||||
optional : input_def.optional,
|
||||
multiple : input_def.multiple,
|
||||
type : input_def.type,
|
||||
flavor : input_def.flavor,
|
||||
data : input_def.options,
|
||||
onchange : function() {
|
||||
self.app.trigger( 'change' );
|
||||
@@ -248,4 +249,4 @@ define(['utils/utils',
|
||||
return {
|
||||
View: View
|
||||
};
|
||||
});
|
||||
});
|
||||
@@ -168,57 +168,20 @@ define(['utils/utils',
|
||||
/** Add a customized section
|
||||
*/
|
||||
_addSection: function(input_def) {
|
||||
var self = this;
|
||||
|
||||
// create sub section
|
||||
var sub_section = new View(self.app, {
|
||||
inputs : input_def.inputs
|
||||
});
|
||||
|
||||
// delete button
|
||||
var button_visible = new Ui.ButtonIcon({
|
||||
icon : 'fa-eye-slash',
|
||||
tooltip : 'Show/hide section',
|
||||
cls : 'ui-button-icon-plain'
|
||||
});
|
||||
|
||||
// create portlet for sub section
|
||||
var portlet = new Portlet.View({
|
||||
title : input_def.title || input_def.name,
|
||||
cls : 'ui-portlet-section',
|
||||
collapsible : true,
|
||||
collapsed : true,
|
||||
operations : {
|
||||
button_visible: button_visible
|
||||
}
|
||||
title : input_def.title || input_def.name,
|
||||
cls : 'ui-portlet-section',
|
||||
collapsible : true,
|
||||
collapsible_button : true,
|
||||
collapsed : !input_def.expanded
|
||||
});
|
||||
portlet.append( sub_section.$el );
|
||||
portlet.append( new View( this.app, { inputs: input_def.inputs } ).$el );
|
||||
portlet.append( $( '<div/>' ).addClass( 'ui-form-info' ).html( input_def.help ) );
|
||||
portlet.setOperation( 'button_visible', function() {
|
||||
if( portlet.collapsed ) {
|
||||
portlet.expand();
|
||||
} else {
|
||||
portlet.collapse();
|
||||
}
|
||||
});
|
||||
|
||||
// add expansion event handler
|
||||
portlet.on( 'expanded', function() {
|
||||
button_visible.setIcon( 'fa-eye' );
|
||||
});
|
||||
portlet.on( 'collapsed', function() {
|
||||
button_visible.setIcon( 'fa-eye-slash' );
|
||||
});
|
||||
this.app.on( 'expand', function( input_id ) {
|
||||
( portlet.$( '#' + input_id ).length > 0 ) && portlet.expand();
|
||||
});
|
||||
|
||||
// show sub section if requested
|
||||
input_def.expanded && portlet.expand();
|
||||
|
||||
// create table row
|
||||
this.table.add(portlet.$el);
|
||||
this.table.append(input_def.id);
|
||||
this.table.add( portlet.$el );
|
||||
this.table.append( input_def.id );
|
||||
},
|
||||
|
||||
/** Add a single input field element
|
||||
@@ -231,12 +194,15 @@ define(['utils/utils',
|
||||
name : input_def.name,
|
||||
label : input_def.label || input_def.name,
|
||||
value : input_def.value,
|
||||
text_value : input_def.text_value || input_def.value,
|
||||
text_value : input_def.text_value,
|
||||
collapsible_value : input_def.collapsible_value,
|
||||
collapsible_preview : input_def.collapsible_preview,
|
||||
help : input_def.help,
|
||||
argument : input_def.argument,
|
||||
disabled : input_def.disabled,
|
||||
color : input_def.color,
|
||||
style : input_def.style,
|
||||
backdrop : input_def.backdrop,
|
||||
field : field
|
||||
});
|
||||
this.app.element_list[id] = input_element;
|
||||
|
||||
@@ -8,9 +8,8 @@ define(['utils/utils', 'mvc/ui/ui-portlet', 'mvc/ui/ui-misc', 'mvc/form/form-sec
|
||||
this.options = Utils.merge(options, {
|
||||
initial_errors : false,
|
||||
cls : 'ui-portlet-limited',
|
||||
icon : ''
|
||||
icon : null
|
||||
});
|
||||
this.modal = ( parent.Galaxy && parent.Galaxy.modal ) || new Ui.Modal.View();
|
||||
this.setElement('<div/>');
|
||||
this.render();
|
||||
},
|
||||
@@ -18,7 +17,7 @@ define(['utils/utils', 'mvc/ui/ui-portlet', 'mvc/ui/ui-misc', 'mvc/form/form-sec
|
||||
/** Update available options */
|
||||
update: function(new_model){
|
||||
var self = this;
|
||||
this.data.matchModel(new_model, function(input_id, node) {
|
||||
this.data.matchModel(new_model, function(node, input_id) {
|
||||
var input = self.input_list[input_id];
|
||||
if (input && input.options) {
|
||||
if (!_.isEqual(input.options, node.options)) {
|
||||
@@ -69,18 +68,11 @@ define(['utils/utils', 'mvc/ui/ui-portlet', 'mvc/ui/ui-misc', 'mvc/form/form-sec
|
||||
/** Highlight and scroll to input element (currently only used for error notifications)
|
||||
*/
|
||||
highlight: function (input_id, message, silent) {
|
||||
// get input field
|
||||
var input_element = this.element_list[input_id];
|
||||
|
||||
// check input element
|
||||
if (input_element) {
|
||||
// mark error
|
||||
input_element.error(message || 'Please verify this parameter.');
|
||||
|
||||
// trigger expand event for parent containers
|
||||
this.portlet.expand();
|
||||
this.trigger('expand', input_id);
|
||||
|
||||
// scroll to first input element
|
||||
if (!silent) {
|
||||
if (self==top) {
|
||||
var $panel = this.$el.parents().filter(function() {
|
||||
@@ -97,10 +89,7 @@ define(['utils/utils', 'mvc/ui/ui-portlet', 'mvc/ui/ui-misc', 'mvc/form/form-sec
|
||||
/** Highlights errors
|
||||
*/
|
||||
errors: function(options) {
|
||||
// hide previous error statements
|
||||
this.trigger('reset');
|
||||
|
||||
// highlight all errors
|
||||
if (options && options.errors) {
|
||||
var error_messages = this.data.matchResponse(options.errors);
|
||||
for (var input_id in this.element_list) {
|
||||
@@ -147,9 +136,9 @@ define(['utils/utils', 'mvc/ui/ui-portlet', 'mvc/ui/ui-misc', 'mvc/form/form-sec
|
||||
|
||||
// add listener which triggers on checksum change
|
||||
var current_check = this.data.checksum();
|
||||
this.on('change', function() {
|
||||
this.on('change', function( force ) {
|
||||
var new_check = self.data.checksum();
|
||||
if (new_check != current_check) {
|
||||
if (new_check != current_check || force ) {
|
||||
current_check = new_check;
|
||||
self.options.onchange && self.options.onchange();
|
||||
}
|
||||
|
||||
@@ -205,6 +205,19 @@ var HistoryContents = Backbone.Collection
|
||||
return this.fetch( options );
|
||||
},
|
||||
|
||||
/** specialty fetch method for retrieving the element_counts of all hdcas in the history */
|
||||
fetchCollectionCounts : function( options ){
|
||||
options = options || {};
|
||||
options.data = _.defaults({
|
||||
keys : [ 'type_id', 'element_count' ].join( ',' ),
|
||||
q : 'history_content_type',
|
||||
qv : 'dataset_collection',
|
||||
}, options.data || {} );
|
||||
options.merge = true;
|
||||
options.remove = false;
|
||||
return this.fetch( options );
|
||||
},
|
||||
|
||||
/** using a queue, perform ajaxFn on each of the models in this collection */
|
||||
ajaxQueue : function( ajaxFn, options ){
|
||||
var deferred = jQuery.Deferred(),
|
||||
@@ -292,17 +305,6 @@ var HistoryContents = Backbone.Collection
|
||||
},
|
||||
|
||||
// ........................................................................ misc
|
||||
/** override to ensure type id is set */
|
||||
set : function( models, options ){
|
||||
models = _.isArray( models )? models : [ models ];
|
||||
_.each( models, function( model ){
|
||||
if( !model.type_id || !model.get || !model.get( 'type_id' ) ){
|
||||
model.type_id = HISTORY_CONTENT.typeIdStr( model.history_content_type, model.id );
|
||||
}
|
||||
});
|
||||
Backbone.Collection.prototype.set.call( this, models, options );
|
||||
},
|
||||
|
||||
/** */
|
||||
createHDCA : function( elementIdentifiers, collectionType, name, options ){
|
||||
//precondition: elementIdentifiers is an array of plain js objects
|
||||
|
||||
@@ -435,6 +435,7 @@ var ControlledFetchMixin = {
|
||||
_.each( filters, function( v, k ){
|
||||
if( v === true ){ v = 'True'; }
|
||||
if( v === false ){ v = 'False'; }
|
||||
if( v === null ){ v = 'None'; }
|
||||
filterMap.q.push( k );
|
||||
filterMap.qv.push( v );
|
||||
});
|
||||
@@ -522,6 +523,11 @@ var HistoryCollection = Backbone.Collection
|
||||
deleted : false,
|
||||
purged : false,
|
||||
};
|
||||
} else {
|
||||
defaults.filters = {
|
||||
// TODO: for bypassing defaults on current API
|
||||
deleted : null,
|
||||
};
|
||||
}
|
||||
return defaults;
|
||||
},
|
||||
|
||||
@@ -102,7 +102,7 @@ var AnnotatedHistoryView = _super.extend(
|
||||
// stopProp will prevent bootstrap from getting the click needed to open a dropdown
|
||||
// in the case of metafile download buttons - workaround here
|
||||
var $currTarget = $( ev.currentTarget );
|
||||
if( $currTarget.size() && $currTarget.attr( 'data-toggle' ) === 'dropdown' ){
|
||||
if( $currTarget.length && $currTarget.attr( 'data-toggle' ) === 'dropdown' ){
|
||||
$currTarget.dropdown( 'toggle' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,7 +227,7 @@ var CurrentHistoryView = _super.extend(
|
||||
$toolMenu = $( '.toolMenuContainer' );
|
||||
|
||||
if( ( _.isEmpty( panel.views ) && !panel.searchFor )
|
||||
&& ( Galaxy && Galaxy.upload && $toolMenu.size() ) ){
|
||||
&& ( Galaxy && Galaxy.upload && $toolMenu.length ) ){
|
||||
$emptyMsg.empty();
|
||||
|
||||
$emptyMsg.html([
|
||||
|
||||
@@ -180,6 +180,9 @@ var HistoryView = _super.extend(
|
||||
return this.loadHistory( historyId, attributes, historyFn, contentsFn, detailIdsFn );
|
||||
},
|
||||
|
||||
/** @type {Number} ms to wait after history load to fetch/decorate hdcas with element_count */
|
||||
FETCH_COLLECTION_COUNTS_DELAY : 2000,
|
||||
|
||||
/** loads a history & contents (but does not make them the current history) */
|
||||
loadHistory : function( historyId, attributes, historyFn, contentsFn, detailIdsFn ){
|
||||
this.info( 'loadHistory:', historyId, attributes, historyFn, contentsFn, detailIdsFn );
|
||||
@@ -200,6 +203,12 @@ var HistoryView = _super.extend(
|
||||
panel.trigger( 'error', panel, xhr, attributes, _l( 'An error was encountered while ' + where ),
|
||||
{ historyId: historyId, history: history || {} });
|
||||
})
|
||||
.done( function(){
|
||||
// after the initial load, decorate with more time consuming fields (like HDCA element_counts)
|
||||
_.delay( function(){
|
||||
panel.model.contents.fetchCollectionCounts();
|
||||
}, panel.FETCH_COLLECTION_COUNTS_DELAY );
|
||||
})
|
||||
.always( function(){
|
||||
// bc _hideLoadingIndicator relies on this firing
|
||||
panel.trigger( 'loading-done', panel );
|
||||
@@ -209,14 +218,15 @@ var HistoryView = _super.extend(
|
||||
/** given an xhr that will provide both history and contents data, pass data to set model or handle xhr errors */
|
||||
_loadHistoryFromXHR : function( xhr, attributes ){
|
||||
var panel = this;
|
||||
xhr.then( function( historyJSON, contentsJSON ){
|
||||
panel.JSONToModel( historyJSON, contentsJSON, attributes );
|
||||
panel.render();
|
||||
});
|
||||
xhr.fail( function( xhr, where ){
|
||||
// render anyways - whether we get a model or not
|
||||
panel.render();
|
||||
});
|
||||
xhr
|
||||
.then( function( historyJSON, contentsJSON ){
|
||||
panel.JSONToModel( historyJSON, contentsJSON, attributes );
|
||||
panel.render();
|
||||
})
|
||||
.fail( function( xhr, where ){
|
||||
// render anyways - whether we get a model or not
|
||||
panel.render();
|
||||
});
|
||||
return xhr;
|
||||
},
|
||||
|
||||
@@ -328,7 +338,7 @@ var HistoryView = _super.extend(
|
||||
}
|
||||
// don't bother rendering if there's one already
|
||||
var $existing = $where.find( '.controls .actions .show-selectors-btn' );
|
||||
if( $existing.size() ){
|
||||
if( $existing.length ){
|
||||
return $existing;
|
||||
}
|
||||
|
||||
|
||||
@@ -1156,10 +1156,10 @@ var FolderToolbarView = Backbone.View.extend({
|
||||
// toolbar end
|
||||
'<div id="folder_items_element">',
|
||||
'</div>',
|
||||
// paginator will append here
|
||||
'<div class="folder-paginator paginator-bottom"></div>',
|
||||
// container end
|
||||
'</div>',
|
||||
// paginator will append here
|
||||
'<div class="folder-paginator paginator-bottom"></div>'
|
||||
].join(''));
|
||||
},
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
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/tool/tool-template', 'mvc/citation/citation-model', 'mvc/citation/citation-view'],
|
||||
function(Utils, Deferred, Ui, FormBase, ToolTemplate, CitationModel, CitationView) {
|
||||
'mvc/citation/citation-model', 'mvc/citation/citation-view'],
|
||||
function(Utils, Deferred, Ui, FormBase, CitationModel, CitationView) {
|
||||
return FormBase.extend({
|
||||
initialize: function(options) {
|
||||
var self = this;
|
||||
@@ -11,9 +11,6 @@ define(['utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view',
|
||||
this.deferred = new Deferred();
|
||||
if (options.inputs) {
|
||||
this._buildForm(options);
|
||||
options.needs_update && this.deferred.execute( function( process ) {
|
||||
self._updateModel( process );
|
||||
});
|
||||
} else {
|
||||
this.deferred.execute(function(process) {
|
||||
self._buildModel(process, options, true);
|
||||
@@ -36,7 +33,7 @@ define(['utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view',
|
||||
var self = this;
|
||||
this.options = Utils.merge(options, this.options);
|
||||
this.options = Utils.merge({
|
||||
icon : ( (options.icon === undefined) && 'fa-wrench' ) || '',
|
||||
icon : options.icon,
|
||||
title : '<b>' + options.name + '</b> ' + options.description + ' (Galaxy Version ' + options.version + ')',
|
||||
operations : this._operations(),
|
||||
onchange : function() {
|
||||
@@ -74,8 +71,7 @@ define(['utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view',
|
||||
}
|
||||
|
||||
// get initial model
|
||||
Utils.request({
|
||||
type : 'GET',
|
||||
Utils.get({
|
||||
url : build_url,
|
||||
data : build_data,
|
||||
success : function(new_model) {
|
||||
@@ -105,7 +101,7 @@ define(['utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view',
|
||||
large : true
|
||||
})).$el);
|
||||
} else {
|
||||
Galaxy.modal.show({
|
||||
Galaxy.modal && Galaxy.modal.show({
|
||||
title : 'Tool request failed',
|
||||
body : error_message,
|
||||
buttons : {
|
||||
@@ -245,11 +241,12 @@ define(['utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view',
|
||||
title : 'Requirements',
|
||||
tooltip : 'Display tool requirements',
|
||||
onclick : function() {
|
||||
if (!this.visible) {
|
||||
if (!this.visible || self.portlet.collapsed ) {
|
||||
this.visible = true;
|
||||
self.portlet.expand();
|
||||
self.message.update({
|
||||
persistent : true,
|
||||
message : ToolTemplate.requirements(options),
|
||||
message : self._templateRequirements(options),
|
||||
status : 'info'
|
||||
});
|
||||
} else {
|
||||
@@ -284,7 +281,7 @@ define(['utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view',
|
||||
*/
|
||||
_footer: function() {
|
||||
var options = this.options;
|
||||
var $el = $( '<div/>' ).append( ToolTemplate.help( options ) );
|
||||
var $el = $( '<div/>' ).append( this._templateHelp( options ) );
|
||||
if ( options.citations ) {
|
||||
var $citations = $( '<div/>' );
|
||||
var citations = new CitationModel.ToolCitationCollection();
|
||||
@@ -295,6 +292,27 @@ define(['utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view',
|
||||
$el.append( $citations );
|
||||
}
|
||||
return $el;
|
||||
},
|
||||
|
||||
/** Templates
|
||||
*/
|
||||
_templateHelp: function( options ) {
|
||||
var $tmpl = $( '<div/>' ).addClass( 'ui-form-help' ).append( options.help );
|
||||
$tmpl.find( 'a' ).attr( 'target', '_blank' );
|
||||
return $tmpl;
|
||||
},
|
||||
|
||||
_templateRequirements: function( options ) {
|
||||
var nreq = options.requirements.length;
|
||||
if ( nreq > 0 ) {
|
||||
var requirements_message = 'This tool requires ';
|
||||
_.each( options.requirements, function( req, i ) {
|
||||
requirements_message += req.name + ( req.version ? ' (Version ' + req.version + ')' : '' ) + ( i < nreq - 2 ? ', ' : ( i == nreq - 2 ? ' and ' : '' ) );
|
||||
});
|
||||
var requirements_link = $( '<a/>' ).attr( 'target', '_blank' ).attr( 'href', 'https://wiki.galaxyproject.org/Tools/Requirements' ).text( 'here' );
|
||||
return $( '<span/>' ).append( requirements_message + '. Click ' ).append( requirements_link ).append( ' for more information.' );
|
||||
}
|
||||
return 'No requirements found.';
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,46 +1,40 @@
|
||||
/**
|
||||
This is the run workflow tool form.
|
||||
*/
|
||||
define([ 'utils/utils', 'mvc/ui/ui-misc', 'mvc/form/form-view', 'mvc/form/form-data', 'mvc/tool/tool-form-base' ],
|
||||
function( Utils, Ui, Form, FormData, ToolFormBase ) {
|
||||
/** This is the run workflow tool form view. */
|
||||
define([ 'utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view', 'mvc/form/form-data', 'mvc/tool/tool-form-base' ],
|
||||
function( Utils, Deferred, Ui, Form, FormData, ToolFormBase ) {
|
||||
var View = Backbone.View.extend({
|
||||
initialize: function( options ) {
|
||||
this.model = options && options.model || new Backbone.Model( options );
|
||||
this.deferred = new Deferred();
|
||||
this.setElement( $( '<div/>' ).addClass( 'ui-form-composite' )
|
||||
.append( this.$message = $( '<div/>' ) )
|
||||
.append( this.$header = $( '<div/>' ) )
|
||||
.append( this.$parameters = $( '<div/>' ) )
|
||||
.append( this.$steps = $( '<div/>' ) )
|
||||
.append( this.$history = $( '<div/>' ) )
|
||||
.append( this.$execute = $( '<div/>' ) ) );
|
||||
$( 'body' ).append( this.$el );
|
||||
this._configure();
|
||||
this.render();
|
||||
},
|
||||
|
||||
/** Configures form/step options for each workflow step */
|
||||
_configure: function() {
|
||||
var self = this;
|
||||
this.workflow_id = options.id;
|
||||
this.forms = [];
|
||||
this.steps = [];
|
||||
this.links = [];
|
||||
|
||||
// initialize elements
|
||||
this.setElement( '<div class="ui-form-composite"/>' );
|
||||
this.$header = $( '<div/>' ).addClass( 'ui-form-header' );
|
||||
this.$header.append( new Ui.Label({
|
||||
title : 'Workflow: ' + options.name
|
||||
}).$el );
|
||||
this.$header.append( new Ui.Button({
|
||||
title : 'Collapse',
|
||||
icon : 'fa-angle-double-up',
|
||||
onclick : function() { _.each( self.forms, function( form ) { form.portlet.collapse() }) }
|
||||
}).$el );
|
||||
this.$header.append( new Ui.Button({
|
||||
title : 'Expand all',
|
||||
icon : 'fa-angle-double-down',
|
||||
onclick : function() { _.each( self.forms, function( form ) { form.portlet.expand() }) }
|
||||
}).$el );
|
||||
this.$el.append( this.$header );
|
||||
|
||||
// initialize steps and configure connections
|
||||
_.each( options.steps, function( step, i ) {
|
||||
this.parms = [];
|
||||
_.each( this.model.get( 'steps' ), function( step, i ) {
|
||||
Galaxy.emit.debug( 'tool-form-composite::initialize()', i + ' : Preparing workflow step.' );
|
||||
step = Utils.merge( {
|
||||
index : i,
|
||||
name : 'Step ' + ( parseInt( i ) + 1 ) + ': ' + step.name,
|
||||
icon : '',
|
||||
help : null,
|
||||
description : step.annotation && ' - ' + step.annotation || step.description,
|
||||
citations : null,
|
||||
needs_update : true,
|
||||
collapsible : true,
|
||||
collapsed : i > 0,
|
||||
collapsed : i > 0 && !self._isDataStep( step ),
|
||||
sustain_version : true,
|
||||
sustain_repeats : true,
|
||||
sustain_conditionals : true,
|
||||
@@ -48,155 +42,256 @@ define([ 'utils/utils', 'mvc/ui/ui-misc', 'mvc/form/form-view', 'mvc/form/form-d
|
||||
text_enable : 'Edit',
|
||||
text_disable : 'Undo',
|
||||
cls_enable : 'fa fa-edit',
|
||||
cls_disable : 'fa fa-undo'
|
||||
cls_disable : 'fa fa-undo',
|
||||
errors : step.messages,
|
||||
initial_errors : true
|
||||
}, step );
|
||||
// convert all connected data inputs to hidden fields with proper labels
|
||||
_.each( options.steps, function( sub_step ) {
|
||||
self.steps[ i ] = step;
|
||||
self.links[ i ] = [];
|
||||
self.parms[ i ] = {};
|
||||
});
|
||||
|
||||
// build linear index of step input pairs
|
||||
_.each( this.steps, function( step, i ) {
|
||||
FormData.visitInputs( step.inputs, function( input, name ) {
|
||||
self.parms[ i ][ name ] = input;
|
||||
});
|
||||
});
|
||||
|
||||
// iterate through data input modules and collect linked sub steps
|
||||
_.each( this.steps, function( step, i ) {
|
||||
_.each( step.output_connections, function( output_connection ) {
|
||||
_.each( self.steps, function( sub_step, j ) {
|
||||
sub_step.step_id === output_connection.input_step_id && self.links[ i ].push( sub_step );
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// convert all connected data inputs to hidden fields with proper labels,
|
||||
// and track the linked source step
|
||||
_.each( this.steps, function( step, i ) {
|
||||
_.each( self.steps, function( sub_step, j ) {
|
||||
var connections_by_name = {};
|
||||
_.each( step.output_connections, function( connection ) {
|
||||
sub_step.step_id === connection.input_step_id && ( connections_by_name[ connection.input_name ] = connection );
|
||||
});
|
||||
FormData.matchIds( sub_step.inputs, connections_by_name, function( connection, input ) {
|
||||
if ( !input.linked ) {
|
||||
input.linked = step.step_type;
|
||||
_.each( self.parms[ j ], function( input, name ) {
|
||||
var connection = connections_by_name[ name ];
|
||||
if ( connection ) {
|
||||
input.type = 'hidden';
|
||||
input.help = '';
|
||||
} else {
|
||||
input.help += ', ';
|
||||
}
|
||||
input.help += 'Output dataset \'' + connection.output_name + '\' from step ' + ( parseInt( i ) + 1 );
|
||||
});
|
||||
});
|
||||
self.steps[ i ] = step;
|
||||
self.links[ i ] = [];
|
||||
});
|
||||
|
||||
// finalize configuration and build forms
|
||||
_.each( self.steps, function( step, i ) {
|
||||
var form = null;
|
||||
if ( String( step.step_type ).startsWith( 'data' ) ) {
|
||||
form = new Form( Utils.merge({
|
||||
title : '<b>' + step.name + '</b>',
|
||||
onchange: function() {
|
||||
var input_value = form.data.create().input;
|
||||
_.each( self.links[ i ], function( link ) {
|
||||
link.input.value ( input_value );
|
||||
link.form.trigger( 'change' );
|
||||
});
|
||||
}
|
||||
}, step ));
|
||||
} else if ( step.step_type == 'tool' ) {
|
||||
// select fields are shown for dynamic fields if all putative data inputs are available
|
||||
function visitInputs( inputs, data_resolved ) {
|
||||
data_resolved === undefined && ( data_resolved = true );
|
||||
_.each( inputs, function ( input ) {
|
||||
if ( _.isObject( input ) ) {
|
||||
if ( input.type ) {
|
||||
var is_data_input = [ 'data', 'data_collection' ].indexOf( input.type ) !== -1;
|
||||
var is_workflow_parameter = self._isWorkflowParameter( input.value );
|
||||
is_data_input && input.linked && !input.linked.startsWith( 'data' ) && ( data_resolved = false );
|
||||
input.options && ( ( input.options.length == 0 && !data_resolved ) || is_workflow_parameter ) && ( input.is_workflow = true );
|
||||
input.value && input.value.__class__ == 'RuntimeValue' && ( input.value = null );
|
||||
if ( !is_data_input && input.type !== 'hidden' && !is_workflow_parameter ) {
|
||||
if ( input.optional || ( !Utils.isEmpty( input.value ) && input.value !== '' ) ) {
|
||||
input.collapsible_value = input.value;
|
||||
input.collapsible_preview = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
visitInputs( input, data_resolved );
|
||||
}
|
||||
});
|
||||
};
|
||||
visitInputs( step.inputs );
|
||||
// or if a particular reference is specified and available
|
||||
FormData.matchContext( step.inputs, 'data_ref', function( input, reference ) {
|
||||
input.is_workflow = ( reference.linked && !reference.linked.startsWith( 'data' ) ) || self._isWorkflowParameter( input.value );
|
||||
});
|
||||
form = new ToolFormBase( step );
|
||||
}
|
||||
self.forms[ i ] = form;
|
||||
});
|
||||
|
||||
// create index of data output links
|
||||
_.each( this.steps, function( step, i ) {
|
||||
_.each( step.output_connections, function( output_connection ) {
|
||||
_.each( self.forms, function( form ) {
|
||||
if ( form.options.step_id === output_connection.input_step_id ) {
|
||||
var matched_input = form.field_list[ form.data.match( output_connection.input_name ) ];
|
||||
matched_input && self.links[ i ].push( { input: matched_input, form: form } );
|
||||
input.help = input.step_linked ? input.help + ', ' : '';
|
||||
input.help += 'Output dataset \'' + connection.output_name + '\' from step ' + ( parseInt( i ) + 1 );
|
||||
input.step_linked = input.step_linked || [];
|
||||
input.step_linked.push( step );
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// build workflow parameters
|
||||
var wp_fields = {};
|
||||
var wp_inputs = {};
|
||||
// identify and configure workflow parameters
|
||||
var wp_count = 0;
|
||||
var wp_style = function( wp_field, wp_color, wp_cls ) {
|
||||
var $wp_input = wp_field.$( 'input' );
|
||||
$wp_input.length === 0 && ( $wp_input = wp_field.$el );
|
||||
$wp_input.addClass( wp_cls ).css({ 'color': wp_color, 'border-color': wp_color });
|
||||
this.wp_inputs = {};
|
||||
function _handleWorkflowParameter( value, callback ) {
|
||||
var wp_name = self._isWorkflowParameter( value );
|
||||
wp_name && callback( self.wp_inputs[ wp_name ] = self.wp_inputs[ wp_name ] || {
|
||||
label : wp_name,
|
||||
name : wp_name,
|
||||
type : 'text',
|
||||
color : 'hsl( ' + ( ++wp_count * 100 ) + ', 70%, 30% )',
|
||||
style : 'ui-form-wp-source',
|
||||
links : []
|
||||
});
|
||||
}
|
||||
_.each( this.steps, function( step, i ) {
|
||||
_.each( step.inputs, function( input ) {
|
||||
var wp_name = self._isWorkflowParameter( input.value );
|
||||
if ( wp_name ) {
|
||||
var wp_field = self.forms[ i ].field_list[ input.id ];
|
||||
var wp_element = self.forms[ i ].element_list[ input.id ];
|
||||
wp_fields[ wp_name ] = wp_fields[ wp_name ] || [];
|
||||
wp_fields[ wp_name ].push( wp_field );
|
||||
wp_field.value( wp_name );
|
||||
wp_element.disable( true );
|
||||
wp_inputs[ wp_name ] = wp_inputs[ wp_name ] || {
|
||||
type : input.type,
|
||||
is_workflow : input.options,
|
||||
label : wp_name,
|
||||
name : wp_name,
|
||||
color : 'hsl( ' + ( ++wp_count * 100 ) + ', 70%, 30% )'
|
||||
};
|
||||
wp_style( wp_field, wp_inputs[ wp_name ].color, 'ui-form-wp-target' );
|
||||
}
|
||||
_.each( self.parms[ i ], function( input, name ) {
|
||||
_handleWorkflowParameter( input.value, function( wp_input ) {
|
||||
wp_input.links.push( step );
|
||||
input.wp_linked = wp_input.name;
|
||||
input.color = wp_input.color;
|
||||
input.type = 'text';
|
||||
input.value = null;
|
||||
input.backdrop = true;
|
||||
input.style = 'ui-form-wp-target';
|
||||
});
|
||||
});
|
||||
_.each( step.post_job_actions, function( pja ) {
|
||||
_.each( pja.action_arguments, function( arg ) {
|
||||
_handleWorkflowParameter( arg, function() {} );
|
||||
});
|
||||
});
|
||||
});
|
||||
if ( !_.isEmpty( wp_inputs ) ) {
|
||||
var wp_form = new Form({ title: '<b>Workflow Parameters</b>', inputs: wp_inputs, onchange: function() {
|
||||
_.each( wp_form.data.create(), function( wp_value, wp_name ) {
|
||||
_.each( wp_fields[ wp_name ], function( wp_field ) {
|
||||
wp_field.value( Utils.sanitize( wp_value ) || wp_name );
|
||||
|
||||
// select fields are shown for dynamic fields if all putative data inputs are available,
|
||||
// or if an explicit reference is specified as data_ref and available
|
||||
_.each( this.steps, function( step, i ) {
|
||||
if ( step.step_type == 'tool' ) {
|
||||
var data_resolved = true;
|
||||
FormData.visitInputs( step.inputs, function ( input, name, context ) {
|
||||
var is_data_input = ([ 'data', 'data_collection' ]).indexOf( input.type ) != -1;
|
||||
var data_ref = context[ input.data_ref ];
|
||||
input.step_linked && !self._isDataStep( input.step_linked ) && ( data_resolved = false );
|
||||
input.options && ( ( input.options.length == 0 && !data_resolved ) || input.wp_linked ) && ( input.is_workflow = true );
|
||||
data_ref && ( input.is_workflow = ( data_ref.step_linked && !self._isDataStep( data_ref.step_linked ) ) || input.wp_linked );
|
||||
( is_data_input || ( input.value && input.value.__class__ == 'RuntimeValue' && !input.step_linked ) ) && ( step.collapsed = false );
|
||||
input.value && input.value.__class__ == 'RuntimeValue' && ( input.value = null );
|
||||
input.flavor = 'workflow';
|
||||
if ( !is_data_input && input.type !== 'hidden' && !input.wp_linked ) {
|
||||
if ( input.optional || ( !Utils.isEmpty( input.value ) && input.value !== '' ) ) {
|
||||
input.collapsible_value = input.value;
|
||||
input.collapsible_preview = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var self = this;
|
||||
this.deferred.reset();
|
||||
this._renderHeader();
|
||||
this._renderMessage();
|
||||
this._renderParameters();
|
||||
this._renderHistory();
|
||||
_.each ( this.steps, function( step, i ) { self._renderStep( step, i ) } );
|
||||
this.deferred.execute( function() { self._renderExecute() } );
|
||||
},
|
||||
|
||||
/** Render header */
|
||||
_renderHeader: function() {
|
||||
var self = this;
|
||||
this.$header.addClass( 'ui-form-header' ).empty()
|
||||
.append( new Ui.Label({
|
||||
title : 'Workflow: ' + this.model.get( 'name' ) }).$el )
|
||||
.append( new Ui.Button({
|
||||
title : 'Collapse',
|
||||
icon : 'fa-angle-double-up',
|
||||
onclick : function() { _.each( self.forms, function( form ) { form.portlet.collapse() }) } }).$el )
|
||||
.append( new Ui.Button({
|
||||
title : 'Expand all',
|
||||
icon : 'fa-angle-double-down',
|
||||
onclick : function() { _.each( self.forms, function( form ) { form.portlet.expand() }) } }).$el );
|
||||
},
|
||||
|
||||
/** Render message */
|
||||
_renderMessage: function() {
|
||||
this.$message.empty();
|
||||
if ( this.model.get( 'has_upgrade_messages' ) ) {
|
||||
this.$message.append( new Ui.Message( {
|
||||
message : 'Some tools in this workflow may have changed since it was last saved or some errors were found. The workflow may still run, but any new options will have default values. Please review the messages below to make a decision about whether the changes will affect your analysis.',
|
||||
status : 'warning',
|
||||
persistent : true
|
||||
} ).$el );
|
||||
}
|
||||
},
|
||||
|
||||
/** Render workflow parameters */
|
||||
_renderParameters: function() {
|
||||
var self = this;
|
||||
this.wp_form = null;
|
||||
if ( !_.isEmpty( this.wp_inputs ) ) {
|
||||
this.wp_form = new Form({ title: '<b>Workflow Parameters</b>', inputs: this.wp_inputs, onchange: function() {
|
||||
_.each( self.wp_form.input_list, function( input_def, i ) {
|
||||
_.each( input_def.links, function( step ) {
|
||||
self._refreshStep( step );
|
||||
});
|
||||
});
|
||||
}});
|
||||
_.each( wp_form.field_list, function( wp_field, i ) {
|
||||
wp_style( wp_field, wp_form.input_list[ i ].color, 'ui-form-wp-source' );
|
||||
});
|
||||
this.$el.append( '<p/>' ).addClass( 'ui-margin-top' );
|
||||
this.$el.append( wp_form.$el );
|
||||
this._append( this.$parameters.empty(), this.wp_form.$el );
|
||||
}
|
||||
},
|
||||
|
||||
// append elements
|
||||
_.each( this.steps, function( step, i ) {
|
||||
var form = self.forms[ i ];
|
||||
self.$el.append( '<p/>' ).addClass( 'ui-margin-top' ).append( form.$el );
|
||||
if ( step.post_job_actions && step.post_job_actions.length ) {
|
||||
form.portlet.append( $( '<div/>' ).addClass( 'ui-form-footer-info fa fa-bolt' ).append(
|
||||
_.reduce( step.post_job_actions, function( memo, value ) {
|
||||
return memo + ' ' + value.short_str;
|
||||
}, '' ))
|
||||
);
|
||||
/** Render step */
|
||||
_renderStep: function( step, i ) {
|
||||
var self = this;
|
||||
var form = null;
|
||||
var current = null;
|
||||
this.deferred.execute( function( promise ) {
|
||||
current = promise;
|
||||
if ( step.step_type == 'tool' ) {
|
||||
form = new ToolFormBase( step );
|
||||
if ( step.post_job_actions && step.post_job_actions.length ) {
|
||||
form.portlet.append( $( '<div/>' ).addClass( 'ui-form-element-disabled' )
|
||||
.append( $( '<div/>' ).addClass( 'ui-form-title' ).html( 'Job Post Actions' ) )
|
||||
.append( $( '<div/>' ).addClass( 'ui-form-preview' ).html(
|
||||
_.reduce( step.post_job_actions, function( memo, value ) {
|
||||
return memo + ' ' + value.short_str;
|
||||
}, '' ) ) )
|
||||
);
|
||||
}
|
||||
self._append( self.$steps, form.$el );
|
||||
} else {
|
||||
_.each( step.inputs, function( input ) { input.flavor = 'module' } );
|
||||
form = new Form( Utils.merge({
|
||||
title : '<b>' + step.name + '</b>',
|
||||
onchange : function() { _.each( self.links[ i ], function( link ) { self._refreshStep( link ) } ) }
|
||||
}, step ) );
|
||||
self._append( self.$steps, form.$el );
|
||||
}
|
||||
self.forms[ i ] = form;
|
||||
self._refreshStep( step );
|
||||
Galaxy.emit.debug( 'tool-form-composite::initialize()', i + ' : Workflow step state ready.', step );
|
||||
});
|
||||
self._resolve( form.deferred, promise );
|
||||
} );
|
||||
},
|
||||
|
||||
// add history form
|
||||
/** This helps with rendering lazy loaded steps */
|
||||
_resolve: function( deferred, promise ) {
|
||||
var self = this;
|
||||
setTimeout( function() {
|
||||
if ( deferred && deferred.ready() || !deferred ) {
|
||||
promise.resolve();
|
||||
} else {
|
||||
self._resolve( deferred, promise );
|
||||
}
|
||||
}, 0 );
|
||||
},
|
||||
|
||||
/** Refreshes step values from source step values */
|
||||
_refreshStep: function( step ) {
|
||||
var self = this;
|
||||
var form = this.forms[ step.index ];
|
||||
if ( form ) {
|
||||
_.each( self.parms[ step.index ], function( input, name ) {
|
||||
if ( input.step_linked || input.wp_linked ) {
|
||||
var field = form.field_list[ form.data.match( name ) ];
|
||||
if ( field ) {
|
||||
var new_value = undefined;
|
||||
if ( input.step_linked ) {
|
||||
new_value = { values: [] };
|
||||
_.each( input.step_linked, function( source_step ) {
|
||||
if ( self._isDataStep( source_step ) ) {
|
||||
value = self.forms[ source_step.index ].data.create().input;
|
||||
value && _.each( value.values, function( v ) { new_value.values.push( v ) } );
|
||||
}
|
||||
});
|
||||
if ( !input.multiple && new_value.values.length > 0 ) {
|
||||
new_value = { values: [ new_value.values[ 0 ] ] };
|
||||
}
|
||||
} else if ( input.wp_linked ) {
|
||||
var wp_field = self.wp_form.field_list[ self.wp_form.data.match( input.wp_linked ) ];
|
||||
wp_field && ( new_value = wp_field.value() );
|
||||
}
|
||||
if ( new_value !== undefined ) {
|
||||
field.value( new_value );
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
form.trigger( 'change' );
|
||||
}
|
||||
},
|
||||
|
||||
/** Render history form */
|
||||
_renderHistory: function() {
|
||||
this.history_form = null;
|
||||
if ( !options.history_id ) {
|
||||
if ( !this.model.get( 'history_id' ) ) {
|
||||
this.history_form = new Form({
|
||||
inputs : [{
|
||||
type : 'conditional',
|
||||
name : 'new_history',
|
||||
test_param : {
|
||||
name : 'new_history',
|
||||
name : 'check',
|
||||
label : 'Send results to a new history',
|
||||
type : 'boolean',
|
||||
value : 'false',
|
||||
@@ -205,20 +300,21 @@ define([ 'utils/utils', 'mvc/ui/ui-misc', 'mvc/form/form-view', 'mvc/form/form-d
|
||||
cases : [{
|
||||
value : 'true',
|
||||
inputs : [{
|
||||
name : 'new_history_name',
|
||||
name : 'name',
|
||||
label : 'History name',
|
||||
type : 'text',
|
||||
value : options.name
|
||||
value : this.model.get( 'name' )
|
||||
}]
|
||||
}]
|
||||
}]
|
||||
});
|
||||
this.$el.append( '<p/>' ).addClass( 'ui-margin-top' );
|
||||
this.$el.append( this.history_form.$el );
|
||||
this._append( this.$history.empty(), this.history_form.$el );
|
||||
}
|
||||
},
|
||||
|
||||
// add execute button
|
||||
this.$el.append( '<p/>' ).addClass( 'ui-margin-top' );
|
||||
/** Render execute button */
|
||||
_renderExecute: function() {
|
||||
var self = this;
|
||||
this.execute_btn = new Ui.Button({
|
||||
icon : 'fa-check',
|
||||
title : 'Run workflow',
|
||||
@@ -226,81 +322,84 @@ define([ 'utils/utils', 'mvc/ui/ui-misc', 'mvc/form/form-view', 'mvc/form/form-d
|
||||
floating : 'clear',
|
||||
onclick : function() { self._execute() }
|
||||
});
|
||||
this.$el.append( this.execute_btn.$el );
|
||||
$( 'body' ).append( this.$el );
|
||||
this._append( this.$execute.empty(), this.execute_btn.$el );
|
||||
},
|
||||
|
||||
/** Execute workflow
|
||||
*/
|
||||
/** Execute workflow */
|
||||
_execute: function() {
|
||||
var self = this;
|
||||
var job_def = {
|
||||
inputs : {},
|
||||
parameters : {}
|
||||
new_history_name : this.history_form.data.create()[ 'new_history|name' ],
|
||||
wf_parm : this.wp_form ? this.wp_form.data.create() : {},
|
||||
inputs : {}
|
||||
};
|
||||
var validated = true;
|
||||
_.each( this.forms, function( form, i ) {
|
||||
for ( var i in this.forms ) {
|
||||
var form = this.forms[ i ];
|
||||
var job_inputs = form.data.create();
|
||||
var step = self.steps[ i ];
|
||||
var step_id = step.step_id;
|
||||
var step_type = step.step_type;
|
||||
var order_index = step.order_index;
|
||||
job_def.parameters[ step_id ] = {};
|
||||
form.trigger( 'reset' );
|
||||
for ( var job_input_id in job_inputs ) {
|
||||
var input_value = job_inputs[ job_input_id ];
|
||||
var input_id = form.data.match( job_input_id );
|
||||
var input_field = form.field_list[ input_id ];
|
||||
var input_def = form.input_list[ input_id ];
|
||||
if ( String( step_type ).startsWith( 'data' ) ) {
|
||||
if ( input_value && input_value.values && input_value.values.length > 0 ) {
|
||||
job_def.inputs[ order_index ] = input_value.values[ 0 ];
|
||||
} else if ( validated ) {
|
||||
if ( !input_def.step_linked ) {
|
||||
if ( this._isDataStep( step ) ) {
|
||||
validated = input_value && input_value.values && input_value.values.length > 0;
|
||||
} else {
|
||||
validated = input_def.optional || ( input_def.is_workflow && input_value !== '' ) || ( !input_def.is_workflow && input_value !== null );
|
||||
}
|
||||
if ( !validated ) {
|
||||
form.highlight( input_id );
|
||||
validated = false;
|
||||
}
|
||||
} else {
|
||||
if ( !String( input_def.type ).startsWith( 'data' ) ) {
|
||||
if ( input_def.optional || input_def.is_workflow || input_value != null ) {
|
||||
job_def.parameters[ step_id ][ job_input_id ] = input_value;
|
||||
} else {
|
||||
form.highlight( input_id );
|
||||
validated = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
job_def.inputs[ step_id ] = job_def.inputs[ step_id ] || {};
|
||||
job_def.inputs[ step_id ][ job_input_id ] = job_inputs[ job_input_id ];
|
||||
}
|
||||
}
|
||||
});
|
||||
console.log( JSON.stringify( job_def ) );
|
||||
if ( !validated ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !validated ) {
|
||||
self._enabled( true );
|
||||
Galaxy.emit.debug( 'tool-form-composite::submit()', 'Validation failed.', job_def );
|
||||
} else {
|
||||
self._enabled( false );
|
||||
Galaxy.emit.debug( 'tools-form-composite::submit()', 'Validation complete.', job_def );
|
||||
Galaxy.emit.debug( 'tool-form-composite::submit()', 'Validation complete.', job_def );
|
||||
Utils.request({
|
||||
type : 'POST',
|
||||
url : Galaxy.root + 'api/workflows/' + this.workflow_id + '/invocations',
|
||||
data : job_def,
|
||||
success : function( response ) {
|
||||
Galaxy.emit.debug( 'tool-form-composite::submit', 'Submission successful.', response );
|
||||
self.$el.empty().append( self._templateSuccess( response ) );
|
||||
parent.Galaxy && parent.Galaxy.currHistoryPanel && parent.Galaxy.currHistoryPanel.refreshContents();
|
||||
console.log( response );
|
||||
},
|
||||
error : function( response ) {
|
||||
console.log( response );
|
||||
Galaxy.emit.debug( 'tool-form-composite::submit', 'Submission failed.', response );
|
||||
if ( response && response.err_data ) {
|
||||
var error_messages = form.data.matchResponse( response.err_data );
|
||||
for ( var input_id in error_messages ) {
|
||||
form.highlight( input_id, error_messages[ input_id ] );
|
||||
break;
|
||||
for ( var i in self.forms ) {
|
||||
var form = self.forms[ i ];
|
||||
var step_related_errors = response.err_data[ form.options.step_id ];
|
||||
if ( step_related_errors ) {
|
||||
var error_messages = form.data.matchResponse( step_related_errors );
|
||||
for ( var input_id in error_messages ) {
|
||||
form.highlight( input_id, error_messages[ input_id ] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Galaxy.modal && Galaxy.modal.show({
|
||||
var modal = parent.Galaxy.modal;
|
||||
modal && modal.show({
|
||||
title : 'Job submission failed',
|
||||
body : ( response && response.err_msg ) || ToolTemplate.error( options.job_def ),
|
||||
body : self._templateError( response && response.err_msg || job_def ),
|
||||
buttons : {
|
||||
'Close' : function() {
|
||||
Galaxy.modal.hide();
|
||||
modal.hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -313,23 +412,69 @@ define([ 'utils/utils', 'mvc/ui/ui-misc', 'mvc/form/form-view', 'mvc/form/form-d
|
||||
}
|
||||
},
|
||||
|
||||
/** Set enabled/disabled state
|
||||
*/
|
||||
/** Append new dom to body */
|
||||
_append: function( $container, $el ) {
|
||||
$container.append( '<p/>' ).addClass( 'ui-margin-top' ).append( $el );
|
||||
},
|
||||
|
||||
/** Set enabled/disabled state */
|
||||
_enabled: function( enabled ) {
|
||||
if ( enabled ) { this.execute_btn.unwait() } else { this.execute_btn.wait() }
|
||||
if ( enabled ) { this.history_form.portlet.enable() } else { this.history_form.portlet.disable() }
|
||||
_.each( this.forms, function( form ) { if ( enabled ) { form.portlet.enable() } else { form.portlet.disable() } });
|
||||
},
|
||||
|
||||
/** Handle workflow parameter
|
||||
*/
|
||||
/** Handle workflow parameter */
|
||||
_isWorkflowParameter: function( value ) {
|
||||
if ( String( value ).substring( 0, 1 ) === '$' ) {
|
||||
return Utils.sanitize( value.substring( 2, value.length - 1 ) )
|
||||
}
|
||||
},
|
||||
|
||||
/** Is data input module/step */
|
||||
_isDataStep: function( steps ) {
|
||||
lst = $.isArray( steps ) ? steps : [ steps ] ;
|
||||
for ( var i = 0; i < lst.length; i++ ) {
|
||||
var step = lst[ i ];
|
||||
if ( !step || !step.step_type || !step.step_type.startsWith( 'data' ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
/** Templates */
|
||||
_templateSuccess: function( response ) {
|
||||
if ( response && response.length > 0 ) {
|
||||
var $message = $( '<div/>' ).addClass( 'donemessagelarge' )
|
||||
.append( $( '<p/>' ).text( 'Successfully ran workflow \'' + this.model.get( 'name' ) + '\' and datasets will appear as jobs are created - you may need to refresh your history panel to see these.' ) );
|
||||
for ( var i in response ) {
|
||||
var invocation = response[ i ];
|
||||
var $invocation = $( '<div/>' ).addClass( 'workflow-invocation-complete' );
|
||||
invocation.history && $invocation.append( $( '<p/>' ).text( 'These datasets will appear in a new history: ' )
|
||||
.append( $( '<a/>' ).addClass( 'new-history-link' )
|
||||
.attr( 'data-history-id', invocation.history.id )
|
||||
.attr( 'target', '_top' )
|
||||
.attr( 'href', '/history/switch_to_history?hist_id=' + invocation.history.id )
|
||||
.text( invocation.history.name ) ) );
|
||||
_.each( invocation.outputs, function( output ) {
|
||||
$invocation.append( $( '<div/>' ).addClass( 'messagerow' ).html( '<b>' + output.hid + '</b>: ' + output.name ) );
|
||||
});
|
||||
$message.append( $invocation );
|
||||
}
|
||||
return $message;
|
||||
} else {
|
||||
return this._templateError( response );
|
||||
}
|
||||
},
|
||||
|
||||
_templateError: function( response ) {
|
||||
return $( '<div/>' ).addClass( 'errormessagelarge' )
|
||||
.append( $( '<p/>' ).text( 'The server could not complete the request. Please contact the Galaxy Team if this error persists.' ) )
|
||||
.append( $( '<pre/>' ).text( JSON.stringify( response, null, 4 ) ) );
|
||||
}
|
||||
});
|
||||
return {
|
||||
View: View
|
||||
};
|
||||
});
|
||||
});
|
||||
@@ -1,16 +1,16 @@
|
||||
/**
|
||||
This is the regular tool form.
|
||||
*/
|
||||
define(['utils/utils', 'mvc/ui/ui-misc', 'mvc/tool/tool-form-base', 'mvc/tool/tool-template'],
|
||||
function( Utils, Ui, ToolFormBase, ToolTemplate ) {
|
||||
define([ 'utils/utils', 'mvc/ui/ui-misc', 'mvc/tool/tool-form-base' ],
|
||||
function( Utils, Ui, ToolFormBase ) {
|
||||
var View = ToolFormBase.extend({
|
||||
initialize: function( options ) {
|
||||
var self = this;
|
||||
ToolFormBase.prototype.initialize.call( this, Utils.merge({
|
||||
customize : function( options ) {
|
||||
customize: function( options ) {
|
||||
// build execute button
|
||||
options.buttons = {
|
||||
execute : execute_btn = new Ui.Button({
|
||||
execute: execute_btn = new Ui.Button({
|
||||
icon : 'fa-check',
|
||||
tooltip : 'Execute: ' + options.name + ' (' + options.version + ')',
|
||||
title : 'Execute',
|
||||
@@ -74,7 +74,7 @@ define(['utils/utils', 'mvc/ui/ui-misc', 'mvc/tool/tool-form-base', 'mvc/tool/to
|
||||
data : job_def,
|
||||
success : function( response ) {
|
||||
callback && callback();
|
||||
self.$el.empty().append( ToolTemplate.success( response ) );
|
||||
self.$el.empty().append( self._templateSuccess( response ) );
|
||||
parent.Galaxy && parent.Galaxy.currHistoryPanel && parent.Galaxy.currHistoryPanel.refreshContents();
|
||||
},
|
||||
error : function( response ) {
|
||||
@@ -87,12 +87,13 @@ define(['utils/utils', 'mvc/ui/ui-misc', 'mvc/tool/tool-form-base', 'mvc/tool/to
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
self.modal.show({
|
||||
var modal = parent.Galaxy.modal;
|
||||
modal && modal.show({
|
||||
title : 'Job submission failed',
|
||||
body : ( response && response.err_msg ) || ToolTemplate.error( job_def ),
|
||||
body : ( response && response.err_msg ) || self._templateError( job_def ),
|
||||
buttons : {
|
||||
'Close' : function() {
|
||||
self.modal.hide();
|
||||
modal.hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -141,6 +142,28 @@ define(['utils/utils', 'mvc/ui/ui-misc', 'mvc/tool/tool-form-base', 'mvc/tool/to
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
_templateSuccess: function( response ) {
|
||||
if ( response.jobs && response.jobs.length > 0 ) {
|
||||
var njobs = response.jobs.length;
|
||||
var njobs_text = njobs == 1 ? '1 job has' : njobs + ' jobs have';
|
||||
var $message = $( '<div/>' ).addClass( 'donemessagelarge' )
|
||||
.append( $( '<p/>' ).text( njobs_text + ' been successfully added to the queue - resulting in the following datasets:' ) );
|
||||
_.each( response.outputs, function( output ) {
|
||||
$message.append( $( '<p/>' ).addClass( 'messagerow' ).append( $( '<b/>' ).text( output.hid + ': ' + output.name ) ) );
|
||||
});
|
||||
$message.append( $( '<p/>' ).append( '<b/>' ).text( 'You can check the status of queued jobs and view the resulting data by refreshing the History pane. When the job has been run the status will change from \'running\' to \'finished\' if completed successfully or \'error\' if problems were encountered.' ) );
|
||||
return $message;
|
||||
} else {
|
||||
return this._templateError( response );
|
||||
}
|
||||
},
|
||||
|
||||
_templateError: function( response ) {
|
||||
return $( '<div/>' ).addClass( 'errormessagelarge' )
|
||||
.append( $( '<p/>' ).text( 'The server could not complete the request. Please contact the Galaxy Team if this error persists.' ) )
|
||||
.append( $( '<pre/>' ).text( JSON.stringify( response, null, 4 ) ) );
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
// dependencies
|
||||
define([], function() {
|
||||
|
||||
// tool form templates
|
||||
return {
|
||||
help: function( options ) {
|
||||
var $tmpl = $( '<div/>' ).addClass( 'ui-form-help' ).append( options.help );
|
||||
$tmpl.find( 'a' ).attr( 'target', '_blank' );
|
||||
return $tmpl;
|
||||
},
|
||||
|
||||
success: function(response) {
|
||||
// check
|
||||
if (!response.jobs || !response.jobs.length) {
|
||||
return this.error(response);
|
||||
}
|
||||
|
||||
// number of jobs
|
||||
var njobs = response.jobs.length;
|
||||
|
||||
// job count info text
|
||||
var njobs_text = '';
|
||||
if (njobs == 1) {
|
||||
njobs_text = '1 job has';
|
||||
} else {
|
||||
njobs_text = njobs + ' jobs have';
|
||||
}
|
||||
|
||||
// create template string
|
||||
var tmpl = '<div class="donemessagelarge">' +
|
||||
'<p>' + njobs_text + ' been successfully added to the queue - resulting in the following datasets:</p>';
|
||||
for (var i in response.outputs) {
|
||||
tmpl += '<p style="padding: 10px 20px;"><b>' + response.outputs[i].hid + ': ' + response.outputs[i].name + '</b></p>';
|
||||
}
|
||||
tmpl += '<p>You can check the status of queued jobs and view the resulting data by refreshing the History pane. When the job has been run the status will change from \'running\' to \'finished\' if completed successfully or \'error\' if problems were encountered.</p>' +
|
||||
'</div>';
|
||||
|
||||
// return success message element
|
||||
return tmpl;
|
||||
},
|
||||
|
||||
error: function(response) {
|
||||
return '<div>' +
|
||||
'<p>' +
|
||||
'The server could not complete the request. Please contact the Galaxy Team if this error persists.' +
|
||||
'</p>' +
|
||||
'<textarea class="ui-textarea" disabled style="color: black; height: 300px !important;">' +
|
||||
JSON.stringify(response, undefined, 4) +
|
||||
'</textarea>' +
|
||||
'</div>';
|
||||
},
|
||||
|
||||
requirements: function(options) {
|
||||
var requirements_message = 'This tool requires ';
|
||||
for (var i in options.requirements) {
|
||||
var req = options.requirements[i];
|
||||
requirements_message += req.name;
|
||||
if (req.version) {
|
||||
requirements_message += ' (Version ' + req.version + ')';
|
||||
}
|
||||
if (i < options.requirements.length - 2) {
|
||||
requirements_message += ', ';
|
||||
}
|
||||
if (i == options.requirements.length - 2) {
|
||||
requirements_message += ' and ';
|
||||
}
|
||||
}
|
||||
return requirements_message + '. Click <a target="_blank" href="https://wiki.galaxyproject.org/Tools/Requirements">here</a> for more information.';
|
||||
}
|
||||
};
|
||||
|
||||
});
|
||||
@@ -521,6 +521,7 @@ var ToolLinkView = BaseView.extend({
|
||||
var $link = $('<div/>');
|
||||
$link.append(templates.tool_link(this.model.toJSON()));
|
||||
|
||||
var formStyle = this.model.get( 'form_style', null );
|
||||
// open upload dialog for upload tool
|
||||
if (this.model.id === 'upload1') {
|
||||
$link.find('a').on('click', function(e) {
|
||||
@@ -528,7 +529,7 @@ var ToolLinkView = BaseView.extend({
|
||||
Galaxy.upload.show();
|
||||
});
|
||||
}
|
||||
else if ( this.model.get( 'model_class' ) === 'Tool' ) { // regular tools
|
||||
else if ( formStyle === 'regular' ) { // regular tools
|
||||
var self = this;
|
||||
$link.find('a').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
@@ -14,7 +14,7 @@ var PopupMenu = Backbone.View.extend({
|
||||
initialize: function( $button, options ){
|
||||
// default settings
|
||||
this.$button = $button;
|
||||
if( !this.$button.size() ){
|
||||
if( !this.$button.length ){
|
||||
this.$button = $( '<div/>' );
|
||||
}
|
||||
this.options = options || [];
|
||||
|
||||
@@ -1,50 +1,91 @@
|
||||
/** Scratchbook viewer */
|
||||
define([], function() {
|
||||
|
||||
/** Frame view */
|
||||
var FrameView = Backbone.View.extend({
|
||||
initialize: function( options ) {
|
||||
var self = this;
|
||||
this.model = options && options.model || new Backbone.Model( options );
|
||||
this.setElement( $( '<div/>' ).addClass( 'corner frame' ) );
|
||||
this.$el.append( $( '<div/>' ).addClass( 'f-header corner' )
|
||||
.append( $( '<div/>' ).addClass( 'f-title' ) )
|
||||
.append( $( '<div/>' ).addClass( 'f-icon f-close fa fa-close' )
|
||||
.tooltip( { title: 'Close', placement: 'bottom' } ) ) )
|
||||
.append( $( '<div/>' ).addClass( 'f-content' ) )
|
||||
.append( $( '<div/>' ).addClass( 'f-resize f-icon corner fa fa-expand' ).tooltip( { title: 'Resize' } ) )
|
||||
.append( $( '<div/>' ).addClass( 'f-cover' ) );
|
||||
this.$header = this.$( '.f-header' );
|
||||
this.$title = this.$( '.f-title' );
|
||||
this.$content = this.$( '.f-content' );
|
||||
this.render();
|
||||
this.listenTo( this.model, 'change', this.render, this );
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var self = this;
|
||||
var options = this.model.attributes;
|
||||
this.$title.html( options.title || '' );
|
||||
this.$header.find( '.f-icon-left' ).remove();
|
||||
_.each( options.menu, function( option ) {
|
||||
var $option = $( '<div/>' ).addClass( 'f-icon-left' ).addClass( option.icon );
|
||||
if ( _.isFunction( option.disabled ) && option.disabled() ) {
|
||||
$option.attr( 'disabled', true );
|
||||
} else {
|
||||
$option.on( 'click', function() { option.onclick( self ) } )
|
||||
.tooltip( { title: option.tooltip, placement: 'bottom' } );
|
||||
}
|
||||
self.$header.append( $option );
|
||||
} );
|
||||
if ( options.url ) {
|
||||
this.$content.html( $ ( '<iframe/>' ).addClass( 'f-iframe' )
|
||||
.attr( 'scrolling', 'auto' )
|
||||
.attr( 'src', options.url + ( options.url.indexOf( '?' ) === -1 ? '?' : '&' ) + 'widget=True' ) );
|
||||
} else if ( options.content ) {
|
||||
_.isFunction( options.content ) ? options.content( self.$content ) : self.$content.html( options.content );
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/** Scratchbook viewer */
|
||||
var View = Backbone.View.extend({
|
||||
defaultOptions: {
|
||||
frame: { // default frame size in cells
|
||||
frame: { // default frame size in cells
|
||||
cols : 6,
|
||||
rows : 3
|
||||
},
|
||||
rows : 1000, // maximum number of rows
|
||||
cell : 130, // cell size in px
|
||||
margin : 5,
|
||||
scroll : 5, // scroll speed
|
||||
top_min : 40, // top margin
|
||||
frame_max : 9, // maximum number of frames
|
||||
visible : true, // initial visibility
|
||||
rows : 1000, // maximum number of rows
|
||||
cell : 130, // cell size in px
|
||||
margin : 5, // margin between frames
|
||||
scroll : 5, // scroll speed
|
||||
top_min : 40, // top margin
|
||||
frame_max : 9, // maximum number of frames
|
||||
visible : true, // initial visibility
|
||||
},
|
||||
|
||||
cols : 0, // number of columns
|
||||
top : 0, // scroll/element top
|
||||
top_max : 0, // viewport scrolling state
|
||||
frame_z : 0, // frame z-index
|
||||
frame_counter : 0, // frame counter
|
||||
frame_uid : 0,
|
||||
frame_list : {}, // list of all frames
|
||||
frame_shadow : null,
|
||||
visible : false,
|
||||
event : {},
|
||||
cols : 0, // number of columns
|
||||
top : 0, // scroll/element top
|
||||
top_max : 0, // viewport scrolling state
|
||||
frame_z : 0, // frame z-index
|
||||
frame_counter : 0, // frame counter
|
||||
frame_uid : 0, // unique frame id counter
|
||||
frame_list : {}, // list of all frames
|
||||
frame_shadow : null, // frame shown as placeholder when moving active frames
|
||||
visible : false, // flag indicating if scratchbook viewer is visible or not
|
||||
event : {}, // dictionary keeping track of current event
|
||||
|
||||
initialize : function( options ) {
|
||||
var self = this;
|
||||
this.options = _.defaults( options || {}, this.defaultOptions );
|
||||
this.visible = this.options.visible;
|
||||
this.top = this.top_max = this.options.top_min;
|
||||
this.setElement( $( '<div/>' ).addClass( 'galaxy-frame' ) );
|
||||
this.$el.append( $( '<div/>' ).addClass( 'frame-background' ) );
|
||||
this.$el.append( $( '<div/>' ).addClass( 'frame-menu frame-scroll-up fa fa-chevron-up fa-2x' ) );
|
||||
this.$el.append( $( '<div/>' ).addClass( 'frame-menu frame-scroll-down fa fa-chevron-down fa-2x' ) );
|
||||
this.$el.append( $( '<div/>' ).addClass( 'frame-shadow corner' ).attr( 'id', 'frame-shadow' ) );
|
||||
this.setElement( $( '<div/>' ).addClass( 'galaxy-frame' )
|
||||
.append( $( '<div/>' ).addClass( 'frame-background' ) )
|
||||
.append( $( '<div/>' ).addClass( 'frame-menu frame-scroll-up fa fa-chevron-up fa-2x' ) )
|
||||
.append( $( '<div/>' ).addClass( 'frame-menu frame-scroll-down fa fa-chevron-down fa-2x' ) ) );
|
||||
|
||||
// initialize shadow to guiding drag/resize events
|
||||
this.frame_shadow = {
|
||||
id : '#frame-shadow',
|
||||
screen_location : {},
|
||||
grid_location : {},
|
||||
grid_rank : null,
|
||||
grid_lock : false
|
||||
};
|
||||
this.frame_shadow = new Backbone.View({ el: $( '<div/>' ).addClass( 'corner frame-shadow' ) } );
|
||||
this.$el.append( this.frame_shadow.$el );
|
||||
this._frameInit( this.frame_shadow, '#frame-shadow' );
|
||||
this._frameResize( this.frame_shadow, { width: 0, height: 0 } );
|
||||
this.frame_list[ '#frame-shadow' ] = this.frame_shadow;
|
||||
|
||||
@@ -87,38 +128,18 @@ var View = Backbone.View.extend({
|
||||
} else {
|
||||
// initialize new frame elements
|
||||
this.top = this.options.top_min;
|
||||
var $frame_el = $( this._frameTemplate( frame_id.substring( 1 ), options.title ) );
|
||||
var $frame_content = $frame_el.find( '.f-content' );
|
||||
this.$el.append( $frame_el );
|
||||
|
||||
// configure content
|
||||
if ( options.url ) {
|
||||
$frame_content.append(
|
||||
$ ( '<iframe/>' ).addClass( 'f-iframe' )
|
||||
.attr( 'scrolling', 'auto' )
|
||||
.attr( 'src', options.url + ( options.url.indexOf( '?' ) === -1 ? '?' : '&' ) + 'widget=True' )
|
||||
);
|
||||
} else if ( options.content ) {
|
||||
_.isFunction( options.content ) ? options.content( $frame_content ) : $frame_content.append( options.content );
|
||||
}
|
||||
|
||||
// construct a new frame
|
||||
var frame = {
|
||||
id : frame_id,
|
||||
screen_location : {},
|
||||
grid_location : {},
|
||||
grid_rank : null,
|
||||
grid_lock : false
|
||||
};
|
||||
var frame = new FrameView( options );
|
||||
this.$el.append( frame.$el );
|
||||
|
||||
// set dimensions
|
||||
options.width = this._toPixelCoord( 'width', this.options.frame.cols );
|
||||
options.height = this._toPixelCoord( 'height', this.options.frame.rows );
|
||||
|
||||
// set default z-index and add to ui and frame list
|
||||
this.frame_z = parseInt( $( frame.id ).css( 'z-index' ) );
|
||||
this.frame_z = parseInt( frame.$el.css( 'z-index' ) );
|
||||
this.frame_list[ frame_id ] = frame;
|
||||
this.frame_counter++;
|
||||
this._frameInit( frame, frame_id );
|
||||
this._frameResize( frame, { width: options.width, height: options.height } );
|
||||
this._frameInsert( frame, { top: 0, left: 0 }, true );
|
||||
!this.visible && this.show();
|
||||
@@ -128,12 +149,12 @@ var View = Backbone.View.extend({
|
||||
},
|
||||
|
||||
/** Remove a frame */
|
||||
del: function( frame_id ) {
|
||||
del: function( frame ) {
|
||||
var self = this;
|
||||
var $frame = this.$( frame_id );
|
||||
var $frame = frame.$el;
|
||||
$frame.fadeOut( 'fast', function() {
|
||||
$frame.remove();
|
||||
delete self.frame_list[ frame_id ];
|
||||
delete self.frame_list[ frame.id ];
|
||||
self.frame_counter--;
|
||||
self._panelRefresh( true );
|
||||
self._panelAnimationComplete();
|
||||
@@ -178,12 +199,12 @@ var View = Backbone.View.extend({
|
||||
'mousedown .frame-background' : '_eventHide',
|
||||
'mousedown .frame-scroll-up' : '_eventPanelScroll_up',
|
||||
'mousedown .frame-scroll-down' : '_eventPanelScroll_down',
|
||||
'mousedown .f-close' : '_eventFrameClose',
|
||||
'mousedown .f-pin' : '_eventFrameLock'
|
||||
'mousedown .f-close' : '_eventFrameClose'
|
||||
},
|
||||
|
||||
/** Start drag/resize event */
|
||||
_eventFrameMouseDown: function ( e ) {
|
||||
$( '.tooltip' ).hide();
|
||||
if ( !this.event.type ) {
|
||||
if ( $( e.target ).hasClass( 'f-header' ) || $( e.target ).hasClass( 'f-title' ) ) {
|
||||
this.event.type = 'drag';
|
||||
@@ -194,10 +215,6 @@ var View = Backbone.View.extend({
|
||||
if ( this.event.type ) {
|
||||
e.preventDefault();
|
||||
this.event.target = this._frameIdentify( e.target );
|
||||
if ( this.event.target.grid_lock ) {
|
||||
this.event.type = null;
|
||||
return;
|
||||
}
|
||||
this.event.xy = {
|
||||
x: e.originalEvent.pageX,
|
||||
y: e.originalEvent.pageY
|
||||
@@ -267,22 +284,7 @@ var View = Backbone.View.extend({
|
||||
_eventFrameClose: function ( e ) {
|
||||
if ( !this.event.type ) {
|
||||
e.preventDefault();
|
||||
this.del( this._frameIdentify( e.target ).id );
|
||||
}
|
||||
},
|
||||
|
||||
/** Lock/Unlock the frame location */
|
||||
_eventFrameLock: function ( e ) {
|
||||
if ( !this.event.type ) {
|
||||
e.preventDefault();
|
||||
var frame = this._frameIdentify( e.target );
|
||||
var locked = frame.grid_lock = !frame.grid_lock;
|
||||
var $el = $( frame.id );
|
||||
$el.find( '.f-pin' ) [ locked && 'addClass' || 'removeClass' ]( 'toggle' );
|
||||
$el.find( '.f-header' ) [ locked && 'removeClass' || 'addClass' ]( 'f-not-allowed' );
|
||||
$el.find( '.f-title' ) [ locked && 'removeClass' || 'addClass' ]( 'f-not-allowed' );
|
||||
$el.find( '.f-resize' ) [ locked && 'hide' || 'show' ]();
|
||||
$el.find( '.f-close' ) [ locked && 'hide' || 'show' ]();
|
||||
this.del( this._frameIdentify( e.target ) );
|
||||
}
|
||||
},
|
||||
|
||||
@@ -338,7 +340,7 @@ var View = Backbone.View.extend({
|
||||
this._frameResize( this.frame_shadow, p );
|
||||
this._frameGrid( this.frame_shadow, frame.grid_location );
|
||||
frame.grid_location = null;
|
||||
$( this.frame_shadow.id ).show();
|
||||
this.frame_shadow.$el.show();
|
||||
$( '.f-cover' ).show();
|
||||
},
|
||||
|
||||
@@ -349,7 +351,7 @@ var View = Backbone.View.extend({
|
||||
this._frameResize( frame, p );
|
||||
this._frameGrid( frame, this.frame_shadow.grid_location, true );
|
||||
this.frame_shadow.grid_location = null;
|
||||
$( this.frame_shadow.id ).hide();
|
||||
this.frame_shadow.$el.hide();
|
||||
$( '.f-cover' ).hide();
|
||||
this._panelAnimationComplete();
|
||||
},
|
||||
@@ -458,6 +460,15 @@ var View = Backbone.View.extend({
|
||||
FRAME FUNCTIONS
|
||||
*/
|
||||
|
||||
/** Initialize a new frame */
|
||||
_frameInit: function( frame, id ) {
|
||||
frame.id = id
|
||||
frame.screen_location = {};
|
||||
frame.grid_location = {};
|
||||
frame.grid_rank = null;
|
||||
frame.$el.attr( 'id', id.substring( 1 ) );
|
||||
},
|
||||
|
||||
/** Insert frame at given location */
|
||||
_frameInsert: function( frame, new_loc, animate ) {
|
||||
var self = this;
|
||||
@@ -467,7 +478,7 @@ var View = Backbone.View.extend({
|
||||
place_list.push( [ frame, this._locationRank( new_loc ) ] );
|
||||
}
|
||||
_.each( this.frame_list, function( f ) {
|
||||
if ( f.grid_location !== null && !f.grid_lock ) {
|
||||
if ( f.grid_location !== null ) {
|
||||
f.grid_location = null;
|
||||
place_list.push( [ f, f.grid_rank ] );
|
||||
}
|
||||
@@ -516,7 +527,7 @@ var View = Backbone.View.extend({
|
||||
|
||||
/** Handle frame focussing */
|
||||
_frameFocus: function( frame, has_focus ) {
|
||||
$( frame.id ).css( 'z-index', this.frame_z + ( has_focus ? 1 : 0 ) );
|
||||
frame.$el.css( 'z-index', this.frame_z + ( has_focus ? 1 : 0 ) );
|
||||
},
|
||||
|
||||
/** New left/top position frame */
|
||||
@@ -526,17 +537,17 @@ var View = Backbone.View.extend({
|
||||
if ( animate ) {
|
||||
this._frameFocus( frame, true );
|
||||
var self = this;
|
||||
$( frame.id ).animate({ top: p.top, left: p.left }, 'fast', function() {
|
||||
frame.$el.animate({ top: p.top, left: p.left }, 'fast', function() {
|
||||
self._frameFocus( frame, false );
|
||||
});
|
||||
} else {
|
||||
$( frame.id ).css( { top: p.top, left: p.left } );
|
||||
frame.$el.css( { top: p.top, left: p.left } );
|
||||
}
|
||||
},
|
||||
|
||||
/** Resize frame */
|
||||
_frameResize: function( frame, p ) {
|
||||
$( frame.id ).css( { width: p.width, height: p.height } );
|
||||
frame.$el.css( { width: p.width, height: p.height } );
|
||||
frame.screen_location.width = p.width;
|
||||
frame.screen_location.height = p.height;
|
||||
},
|
||||
@@ -552,21 +563,6 @@ var View = Backbone.View.extend({
|
||||
_frameScreen: function( frame ) {
|
||||
var p = frame.screen_location;
|
||||
return { top: p.top, left: p.left, width: p.width, height: p.height };
|
||||
},
|
||||
|
||||
/** Regular frame template */
|
||||
_frameTemplate: function( id, title ) {
|
||||
return '<div id="' + id + '" class="frame corner">' +
|
||||
'<div class="f-header corner">' +
|
||||
'<span class="f-title">' + ( title || '' ) + '</span>' +
|
||||
'<span class="f-icon f-close fa fa-close"/>' +
|
||||
'<span class="f-icon f-pin fa fa-thumb-tack"/>' +
|
||||
'</div>' +
|
||||
'<div class="f-content">' +
|
||||
'<div class="f-cover"/>' +
|
||||
'</div>' +
|
||||
'<span class="f-resize f-icon corner fa fa-expand"/>' +
|
||||
'</div>';
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -86,7 +86,9 @@ define(['utils/utils',
|
||||
disabled : false,
|
||||
visible : true,
|
||||
cls : '',
|
||||
area : false
|
||||
area : false,
|
||||
color : null,
|
||||
style : null
|
||||
}).set( options );
|
||||
this.tagName = this.model.get( 'area' ) ? 'textarea' : 'input';
|
||||
this.setElement( $( '<' + this.tagName + '/>' ) );
|
||||
@@ -104,9 +106,12 @@ define(['utils/utils',
|
||||
this.$el.removeClass()
|
||||
.addClass( 'ui-' + this.tagName )
|
||||
.addClass( this.model.get( 'cls' ) )
|
||||
.addClass( this.model.get( 'style' ) )
|
||||
.attr( 'id', this.model.id )
|
||||
.attr( 'type', this.model.get( 'type' ) )
|
||||
.attr( 'placeholder', this.model.get( 'placeholder' ) );
|
||||
.attr( 'placeholder', this.model.get( 'placeholder' ) )
|
||||
.css( 'color', this.model.get( 'color' ) || '' )
|
||||
.css( 'border-color', this.model.get( 'color' ) || '' );
|
||||
if ( this.model.get( 'value' ) !== this.$el.val() ) {
|
||||
this.$el.val( this.model.get( 'value' ) );
|
||||
}
|
||||
@@ -159,4 +164,4 @@ define(['utils/utils',
|
||||
Slider : Slider,
|
||||
Drilldown : Drilldown
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,206 +1,207 @@
|
||||
define(['utils/utils'], function( Utils ) {
|
||||
define([ 'utils/utils', 'mvc/ui/ui-misc' ], function( Utils, Ui ) {
|
||||
var View = Backbone.View.extend({
|
||||
visible : false,
|
||||
initialize : function( options ) {
|
||||
var self = this;
|
||||
this.options = Utils.merge( options, {
|
||||
id : Utils.uid(),
|
||||
title : '',
|
||||
icon : '',
|
||||
buttons : null,
|
||||
body : null,
|
||||
scrollable : true,
|
||||
nopadding : false,
|
||||
operations : null,
|
||||
placement : 'bottom',
|
||||
cls : 'ui-portlet',
|
||||
operations_flt : 'right',
|
||||
collapsible : false,
|
||||
collapsed : false
|
||||
this.model = options && options.model || new Backbone.Model( {
|
||||
id : Utils.uid(),
|
||||
cls : 'ui-portlet',
|
||||
title : '',
|
||||
icon : '',
|
||||
buttons : null,
|
||||
body : null,
|
||||
scrollable : true,
|
||||
nopadding : false,
|
||||
operations : null,
|
||||
collapsible : false,
|
||||
collapsible_button : false,
|
||||
collapsed : false
|
||||
} ).set( options );
|
||||
this.setElement( this._template() );
|
||||
|
||||
// link all dom elements
|
||||
this.$body = this.$( '.portlet-body' );
|
||||
this.$title_text = this.$( '.portlet-title-text' );
|
||||
this.$title_icon = this.$( '.portlet-title-icon' );
|
||||
this.$header = this.$( '.portlet-header' );
|
||||
this.$content = this.$( '.portlet-content' );
|
||||
this.$footer = this.$( '.portlet-footer' );
|
||||
this.$backdrop = this.$( '.portlet-backdrop' );
|
||||
this.$buttons = this.$( '.portlet-buttons' );
|
||||
this.$operations = this.$( '.portlet-operations' );
|
||||
|
||||
// add body to component list
|
||||
this.model.get( 'body' ) && this.append( this.model.get( 'body' ) );
|
||||
|
||||
// add icon for collapsible option
|
||||
this.collapsible_button = new Ui.ButtonIcon({
|
||||
icon : 'fa-eye',
|
||||
tooltip : 'Collapse/Expand',
|
||||
cls : 'ui-button-icon-plain',
|
||||
onclick : function() { self[ self.collapsed ? 'expand' : 'collapse' ]() }
|
||||
});
|
||||
this.setElement( this._template( this.options ) );
|
||||
this.render();
|
||||
},
|
||||
|
||||
// link content
|
||||
this.$body = this.$( '.portlet-body' );
|
||||
this.$title = this.$( '.portlet-title-text' );
|
||||
this.$header = this.$( '.portlet-header' );
|
||||
this.$content = this.$( '.portlet-content' );
|
||||
this.$footer = this.$( '.portlet-footer' );
|
||||
render: function() {
|
||||
var self = this;
|
||||
var options = this.model.attributes;
|
||||
this.$el.removeClass().addClass( options.cls ).attr( 'id', options.id );
|
||||
this.$header[ options.title ? 'show' : 'hide' ]();
|
||||
this.$title_text.html( options.title );
|
||||
_.each( [ this.$content, this.$body ], function( $el ) {
|
||||
$el[ options.nopadding ? 'addClass' : 'removeClass' ]( 'no-padding' );
|
||||
});
|
||||
|
||||
// set content padding
|
||||
if ( this.options.nopadding ) {
|
||||
this.$content.css( 'padding', '0px' );
|
||||
this.$body.css( 'padding', '0px' );
|
||||
// render title icon
|
||||
if ( options.icon ) {
|
||||
this.$title_icon.removeClass().addClass( 'portlet-title-icon fa' ).addClass( options.icon ).show();
|
||||
} else {
|
||||
this.$title_icon.hide();
|
||||
}
|
||||
|
||||
// append buttons
|
||||
this.$buttons = this.$( '.portlet-buttons' );
|
||||
if ( this.options.buttons ) {
|
||||
$.each( this.options.buttons, function( name, item ) {
|
||||
// make portlet collapsible
|
||||
this.$title_text[ options.collapsible ? 'addClass' : 'removeClass' ]( 'no-highlight collapsible' ).off();
|
||||
if ( options.collapsible ) {
|
||||
this.$title_text.on( 'click', function() { self[ self.collapsed ? 'expand' : 'collapse' ]() } );
|
||||
options.collapsed ? this.collapse() : this.expand();
|
||||
}
|
||||
|
||||
// render buttons
|
||||
if ( options.buttons ) {
|
||||
this.$buttons.empty().show();
|
||||
$.each( this.model.get( 'buttons' ), function( name, item ) {
|
||||
item.$el.prop( 'id', name );
|
||||
self.$buttons.append( item.$el );
|
||||
});
|
||||
} else {
|
||||
this.$buttons.remove();
|
||||
this.$buttons.hide();
|
||||
}
|
||||
|
||||
// append operations
|
||||
this.$operations = this.$( '.portlet-operations' );
|
||||
if ( this.options.operations ) {
|
||||
$.each( this.options.operations, function( name, item ) {
|
||||
// render operations
|
||||
this.$operations.empty;
|
||||
if ( options.collapsible_button ) {
|
||||
this.$operations.append( this.collapsible_button.$el );
|
||||
}
|
||||
if ( options.operations ) {
|
||||
$.each( options.operations, function( name, item ) {
|
||||
item.$el.prop( 'id', name );
|
||||
self.$operations.append( item.$el );
|
||||
});
|
||||
}
|
||||
|
||||
// add body
|
||||
this.options.body && this.append( this.options.body );
|
||||
|
||||
// make portlet collapsible
|
||||
this.collapsed = false;
|
||||
if ( this.options.collapsible ) {
|
||||
this.$title.addClass( 'no-highlight' ).css({
|
||||
'cursor' : 'pointer',
|
||||
'text-decoration' : 'underline'
|
||||
});
|
||||
this.$title.on( 'click', function() {
|
||||
if ( self.collapsed ) { self.expand(); } else { self.collapse(); }
|
||||
});
|
||||
this.options.collapsed && this.collapse();
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
// append
|
||||
/** Append new doms to body */
|
||||
append: function( $el ) {
|
||||
this.$body.append( $el );
|
||||
},
|
||||
|
||||
// remove all content
|
||||
/** Remove all content */
|
||||
empty: function() {
|
||||
this.$body.empty();
|
||||
},
|
||||
|
||||
// header
|
||||
/** Return header element */
|
||||
header: function() {
|
||||
return this.$header;
|
||||
},
|
||||
|
||||
// body
|
||||
/** Return body element */
|
||||
body: function() {
|
||||
return this.$body;
|
||||
},
|
||||
|
||||
// footer
|
||||
/** Return footer element */
|
||||
footer: function() {
|
||||
return this.$footer;
|
||||
},
|
||||
|
||||
// show
|
||||
/** Show portlet */
|
||||
show: function(){
|
||||
this.visible = true;
|
||||
this.$el.fadeIn( 'fast' );
|
||||
},
|
||||
|
||||
// hide
|
||||
/** Hide portlet */
|
||||
hide: function(){
|
||||
this.visible = false;
|
||||
this.$el.fadeOut( 'fast' );
|
||||
},
|
||||
|
||||
// enable buttons
|
||||
/** Enable a particular button */
|
||||
enableButton: function( id ) {
|
||||
this.$buttons.find( '#' + id ).prop( 'disabled', false );
|
||||
},
|
||||
|
||||
// disable buttons
|
||||
/** Disable a particular button */
|
||||
disableButton: function( id ) {
|
||||
this.$buttons.find( '#' + id ).prop( 'disabled', true );
|
||||
},
|
||||
|
||||
// hide operation
|
||||
/** Hide a particular operation */
|
||||
hideOperation: function( id ) {
|
||||
this.$operations.find( '#' + id ).hide();
|
||||
},
|
||||
|
||||
// show operation
|
||||
/** Show a particular operation */
|
||||
showOperation: function( id ) {
|
||||
this.$operations.find( '#' + id ).show();
|
||||
},
|
||||
|
||||
// set operation
|
||||
/** Replaces the event callback of an existing operation */
|
||||
setOperation: function( id, callback ) {
|
||||
var $el = this.$operations.find( '#' + id );
|
||||
$el.off( 'click' );
|
||||
$el.on( 'click', callback );
|
||||
this.$operations.find( '#' + id ).off( 'click' ).on( 'click', callback );
|
||||
},
|
||||
|
||||
// title
|
||||
/** Change title */
|
||||
title: function( new_title ) {
|
||||
var $el = this.$title;
|
||||
if ( new_title ) {
|
||||
$el.html( new_title );
|
||||
}
|
||||
return $el.html();
|
||||
new_title && this.$title_text.html( new_title );
|
||||
return this.$title_text.html();
|
||||
},
|
||||
|
||||
// collapse portlet
|
||||
/** Collapse portlet */
|
||||
collapse: function() {
|
||||
this.collapsed = true;
|
||||
this.$content.height( '0%' );
|
||||
this.$body.hide();
|
||||
this.$footer.hide();
|
||||
this.trigger( 'collapsed' );
|
||||
this.collapsible_button.setIcon( 'fa-eye-slash' );
|
||||
},
|
||||
|
||||
// expand portlet
|
||||
/** Expand portlet */
|
||||
expand: function() {
|
||||
this.collapsed = false;
|
||||
this.$content.height( '100%' );
|
||||
this.$body.fadeIn( 'fast' );
|
||||
this.$footer.fadeIn( 'fast' );
|
||||
this.trigger( 'expanded' );
|
||||
this.collapsible_button.setIcon( 'fa-eye' );
|
||||
},
|
||||
|
||||
// disable content access
|
||||
/** Disable content access */
|
||||
disable: function() {
|
||||
this.$( '.portlet-backdrop' ).show();
|
||||
this.$backdrop.show();
|
||||
},
|
||||
|
||||
// enable content access
|
||||
/** Enable content access */
|
||||
enable: function() {
|
||||
this.$( '.portlet-backdrop' ).hide();
|
||||
this.$backdrop.hide();
|
||||
},
|
||||
|
||||
// fill regular modal template
|
||||
_template: function( options ) {
|
||||
var tmpl = '<div id="' + options.id + '" class="' + options.cls + '">';
|
||||
if ( options.title ) {
|
||||
tmpl += '<div class="portlet-header">' +
|
||||
'<div class="portlet-operations" style="float: ' + options.operations_flt + ';"/>' +
|
||||
'<div class="portlet-title">';
|
||||
if ( options.icon ) {
|
||||
tmpl += '<i class="icon fa ' + options.icon + '"> </i>';
|
||||
}
|
||||
tmpl += '<span class="portlet-title-text">' + options.title + '</span>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
}
|
||||
tmpl += '<div class="portlet-content">';
|
||||
if ( options.placement == 'top' ) {
|
||||
tmpl += '<div class="portlet-buttons"/>';
|
||||
}
|
||||
tmpl += '<div class="portlet-body"/>';
|
||||
if ( options.placement == 'bottom' ) {
|
||||
tmpl += '<div class="portlet-buttons"/>';
|
||||
}
|
||||
tmpl += '</div>' +
|
||||
'<div class="portlet-footer"/>' +
|
||||
'<div class="portlet-backdrop"/>' +
|
||||
'</div>';
|
||||
return tmpl;
|
||||
_template: function() {
|
||||
return $( '<div/>' ).append( $( '<div/>' ).addClass( 'portlet-header' )
|
||||
.append( $( '<div/>' ).addClass( 'portlet-operations' ) )
|
||||
.append( $( '<div/>' ).addClass( 'portlet-title' )
|
||||
.append( $( '<i/>' ).addClass( 'portlet-title-icon' ) )
|
||||
.append( $( '<span/>' ).addClass( 'portlet-title-text' ) ) ) )
|
||||
.append( $( '<div/>' ).addClass( 'portlet-content' )
|
||||
.append( $( '<div/>' ).addClass( 'portlet-body' ) )
|
||||
.append( $( '<div/>' ).addClass( 'portlet-buttons' ) ) )
|
||||
.append( $( '<div/>' ).addClass( 'portlet-footer' ) )
|
||||
.append( $( '<div/>' ).addClass( 'portlet-backdrop' ) );
|
||||
}
|
||||
});
|
||||
return {
|
||||
View : View
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,22 +1,31 @@
|
||||
define([ 'utils/utils', 'mvc/ui/ui-misc', 'mvc/ui/ui-select-default' ], function( Utils, Ui, Select ) {
|
||||
|
||||
/** Batch mode variations */
|
||||
var Batch = { DISABLED: 'disabled', ENABLED: 'enabled', LINKED: 'linked' };
|
||||
|
||||
/** List of available content selectors options */
|
||||
var Configurations = {
|
||||
'data': [
|
||||
{ src: 'hda', icon: 'fa-file-o', tooltip: 'Single dataset', batchmode: false, multiple: false },
|
||||
{ src: 'hda', icon: 'fa-files-o', tooltip: 'Multiple datasets', batchmode: true, multiple: true },
|
||||
{ src: 'hdca', icon: 'fa-folder-o', tooltip: 'Dataset collection', batchmode: true, multiple: false } ],
|
||||
'data_multiple': [
|
||||
{ src: 'hda', icon: 'fa-files-o', tooltip: 'Multiple datasets', batchmode: false, multiple: true },
|
||||
{ src: 'hdca', icon: 'fa-folder-o', tooltip: 'Dataset collection', batchmode: false, multiple: false } ],
|
||||
'data_collection': [
|
||||
{ src: 'hdca', icon: 'fa-folder-o', tooltip: 'Dataset collection', batchmode: false, multiple: false } ],
|
||||
'workflow_data': [
|
||||
{ src: 'hda', icon: 'fa-file-o', tooltip: 'Single dataset', batchmode: false, multiple: false },
|
||||
{ src: 'hda', icon: 'fa-files-o', tooltip: 'Multiple datasets', batchmode: true, multiple: true } ],
|
||||
'workflow_collection': [
|
||||
{ src: 'hdca', icon: 'fa-folder-o', tooltip: 'Dataset collection', batchmode: false, multiple: false },
|
||||
{ src: 'hdca', icon: 'fa-folder', tooltip: 'Multiple collections', batchmode: true, multiple: true } ]
|
||||
data: [
|
||||
{ src: 'hda', icon: 'fa-file-o', tooltip: 'Single dataset', multiple: false, batch: Batch.DISABLED },
|
||||
{ src: 'hda', icon: 'fa-files-o', tooltip: 'Multiple datasets', multiple: true, batch: Batch.LINKED },
|
||||
{ src: 'hdca', icon: 'fa-folder-o', tooltip: 'Dataset collection', multiple: false, batch: Batch.LINKED } ],
|
||||
data_multiple: [
|
||||
{ src: 'hda', icon: 'fa-files-o', tooltip: 'Multiple datasets', multiple: true, batch: Batch.DISABLED },
|
||||
{ src: 'hdca', icon: 'fa-folder-o', tooltip: 'Dataset collection', multiple: false, batch: Batch.DISABLED } ],
|
||||
data_collection: [
|
||||
{ src: 'hdca', icon: 'fa-folder-o', tooltip: 'Dataset collection', multiple: false, batch: Batch.DISABLED } ],
|
||||
workflow_data: [
|
||||
{ src: 'hda', icon: 'fa-file-o', tooltip: 'Single dataset', multiple: false, batch: Batch.DISABLED } ],
|
||||
workflow_data_multiple: [
|
||||
{ src: 'hda', icon: 'fa-files-o', tooltip: 'Multiple datasets', multiple: true, batch: Batch.DISABLED } ],
|
||||
workflow_data_collection: [
|
||||
{ src: 'hdca', icon: 'fa-folder-o', tooltip: 'Dataset collection', multiple: false, batch: Batch.DISABLED } ],
|
||||
module_data: [
|
||||
{ src: 'hda', icon: 'fa-file-o', tooltip: 'Single dataset', multiple: false, batch: Batch.DISABLED },
|
||||
{ src: 'hda', icon: 'fa-files-o', tooltip: 'Multiple datasets', multiple: true, batch: Batch.ENABLED } ],
|
||||
module_data_collection: [
|
||||
{ src: 'hdca', icon: 'fa-folder-o', tooltip: 'Dataset collection', multiple: false, batch: Batch.DISABLED },
|
||||
{ src: 'hdca', icon: 'fa-folder', tooltip: 'Multiple collections', multiple: true, batch: Batch.ENABLED } ]
|
||||
};
|
||||
|
||||
/** View for hda and hdca content selector ui elements */
|
||||
@@ -27,9 +36,22 @@ var View = Backbone.View.extend({
|
||||
src_labels: { 'hda' : 'dataset', 'hdca': 'dataset collection' }
|
||||
}).set( options );
|
||||
this.setElement( $( '<div/>' ).addClass( 'ui-select-content' ) );
|
||||
this.$batch = $( '<div/>' ).addClass( 'ui-form-info' )
|
||||
.append( $( '<i/>' ).addClass( 'fa fa-sitemap' ) )
|
||||
.append( $( '<span/>' ).html( 'This is a batch mode input field. A separate job will be triggered for each dataset.' ) );
|
||||
this.button_product = new Ui.RadioButton.View( {
|
||||
value : 'false',
|
||||
data : [ { icon: 'fa fa-chain', value: 'false',
|
||||
tooltip: 'Linked inputs will be run in matched order with other datasets e.g. use this for matching forward and reverse reads.' },
|
||||
{ icon: 'fa fa-chain-broken', value: 'true',
|
||||
tooltip: 'Unlinked dataset inputs will be run against *all* other inputs.' } ] } );
|
||||
var $batch_div = $( '<div/>' ).addClass( 'ui-form-info' )
|
||||
.append( $( '<i/>' ).addClass( 'fa fa-sitemap' ) )
|
||||
.append( $( '<span/>' ).html( 'This is a batch mode input field. Separate jobs will be triggered for each dataset selection.' ) );
|
||||
this.$batch = {
|
||||
linked : $batch_div.clone(),
|
||||
enabled : $batch_div.clone().append( $( '<div/>' )
|
||||
.append( $( '<div/>' ).addClass( 'ui-form-title' ).html( 'Batch options:' ) )
|
||||
.append( this.button_product.$el ) )
|
||||
.append( $( '<div/>' ).css( 'clear', 'both' ) )
|
||||
};
|
||||
|
||||
// track current history elements
|
||||
this.history = {};
|
||||
@@ -76,13 +98,13 @@ var View = Backbone.View.extend({
|
||||
if (id_list !== null) {
|
||||
id_list = $.isArray( id_list ) ? id_list : [ id_list ];
|
||||
if ( id_list.length > 0 ) {
|
||||
var result = { batch: this._batch(), values: [] };
|
||||
var result = this._batch( { values: [] } );
|
||||
for ( var i in id_list ) {
|
||||
var details = this.history[ id_list[ i ] + '_' + this.config[ current ].src ];
|
||||
if ( details ) {
|
||||
result.values.push( details );
|
||||
} else {
|
||||
Galaxy.emit.debug( 'tools-select-content::value()', 'Requested details not found for \'' + id_list[ i ] + '\'.' );
|
||||
Galaxy.emit.debug( 'ui-select-content::value()', 'Requested details not found for \'' + id_list[ i ] + '\'.' );
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -91,7 +113,7 @@ var View = Backbone.View.extend({
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Galaxy.emit.debug( 'tools-select-content::value()', 'Invalid value/source \'' + new_value + '\'.' );
|
||||
Galaxy.emit.debug( 'ui-select-content::value()', 'Invalid value/source \'' + new_value + '\'.' );
|
||||
}
|
||||
return null;
|
||||
},
|
||||
@@ -102,7 +124,9 @@ var View = Backbone.View.extend({
|
||||
_.each( this.fields, function( field, i ) {
|
||||
if ( self.model.get( 'current' ) == i ) {
|
||||
field.$el.show();
|
||||
self.$batch[ self.config[ i ].batchmode && 'show' || 'hide' ]();
|
||||
_.each( self.$batch, function( $batchfield, batchmode ) {
|
||||
$batchfield[ self.config[ i ].batch == batchmode ? 'show' : 'hide' ]();
|
||||
});
|
||||
self.button_type.value( i );
|
||||
} else {
|
||||
field.$el.hide();
|
||||
@@ -114,13 +138,14 @@ var View = Backbone.View.extend({
|
||||
_changeType: function() {
|
||||
var self = this;
|
||||
|
||||
// identify selector type
|
||||
var config_id = String( this.model.get( 'type' ) ) + ( this.model.get( 'multiple' ) ? '_multiple' : '' );
|
||||
// identify selector type identifier i.e. [ flavor ]_[ type ]_[ multiple ]
|
||||
var config_id = ( this.model.get( 'flavor' ) ? this.model.get( 'flavor' ) + '_' : '' ) +
|
||||
String( this.model.get( 'type' ) ) + ( this.model.get( 'multiple' ) ? '_multiple' : '' );
|
||||
if ( Configurations[ config_id ] ) {
|
||||
this.config = Configurations[ config_id ];
|
||||
} else {
|
||||
this.config = Configurations[ 'data' ];
|
||||
Galaxy.emit.debug( 'tools-select-content::_changeType()', 'Invalid configuration/type id \'' + config_id + '\'.' );
|
||||
Galaxy.emit.debug( 'ui-select-content::_changeType()', 'Invalid configuration/type id \'' + config_id + '\'.' );
|
||||
}
|
||||
|
||||
// prepare extension component of error message
|
||||
@@ -167,7 +192,9 @@ var View = Backbone.View.extend({
|
||||
_.each( this.fields, function( field ) {
|
||||
self.$el.append( field.$el.css( { 'margin-left': button_width } ) );
|
||||
});
|
||||
this.$el.append( this.$batch.css( { 'margin-left': button_width } ) );
|
||||
_.each( this.$batch, function( $batchfield, batchmode ) {
|
||||
self.$el.append( $batchfield.css( { 'margin-left': button_width } ) );
|
||||
});
|
||||
this.model.set( 'current', 0 );
|
||||
this._changeCurrent();
|
||||
this._changeData();
|
||||
@@ -229,16 +256,23 @@ var View = Backbone.View.extend({
|
||||
},
|
||||
|
||||
/** Assists in identifying the batch mode */
|
||||
_batch: function() {
|
||||
_batch: function( result ) {
|
||||
result[ 'batch' ] = false;
|
||||
var current = this.model.get( 'current' );
|
||||
var config = this.config[ current ];
|
||||
if ( config.src == 'hdca' && !config.multiple ) {
|
||||
var hdca = this.history[ this.fields[ current ].value() + '_hdca' ];
|
||||
if ( hdca && hdca.map_over_type ) {
|
||||
return true;
|
||||
result[ 'batch' ] = true;
|
||||
}
|
||||
}
|
||||
return config.batchmode;
|
||||
if ( config.batch == Batch.LINKED || config.batch == Batch.ENABLED ) {
|
||||
result[ 'batch' ] = true;
|
||||
if ( config.batch == Batch.ENABLED && this.button_product.value() === 'true' ) {
|
||||
result[ 'product' ] = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -246,4 +280,4 @@ return {
|
||||
View: View
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
@@ -180,15 +180,8 @@ var View = Backbone.View.extend(
|
||||
|
||||
// get index
|
||||
_getIndex: function(value) {
|
||||
// search index
|
||||
for (var key in this.select_data) {
|
||||
if (this.select_data[key].id == value) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
// not found
|
||||
return -1;
|
||||
// returns the index of the searched value
|
||||
_.findIndex(this.select_data, {id: value});
|
||||
},
|
||||
|
||||
// get value
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
jQuery.fn.extend({
|
||||
hoverhighlight : function $hoverhighlight( scope, color ){
|
||||
scope = scope || 'body';
|
||||
if( !this.size() ){ return this; }
|
||||
if( !this.length ){ return this; }
|
||||
|
||||
$( this ).each( function(){
|
||||
var $this = $( this ),
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
|
||||
self.hide = function( speed, callback ){
|
||||
speed = speed || 'fast';
|
||||
if( self.$indicator && self.$indicator.size() ){
|
||||
if( self.$indicator && self.$indicator.length ){
|
||||
self.$indicator.fadeOut( speed, function(){
|
||||
self.$indicator.remove();
|
||||
if( callback ){ callback(); }
|
||||
|
||||
@@ -161,7 +161,7 @@
|
||||
|
||||
// as jq plugin
|
||||
$.fn.modeButton = function $modeButton( options ){
|
||||
if( !this.size() ){ return this; }
|
||||
if( !this.length ){ return this; }
|
||||
|
||||
//TODO: does map still work with jq multi selection (i.e. $( '.class-for-many-btns' ).modeButton)?
|
||||
if( $.type( options ) === 'object' ){
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
// scroll to show active page in center of scrollable area
|
||||
var $container = this.$element.find( '.pagination-scroll-container' );
|
||||
// no scroll container : don't scroll
|
||||
if( !$container.size() ){ return this; }
|
||||
if( !$container.length ){ return this; }
|
||||
|
||||
var $activePage = this.$element.find( 'li.active' ),
|
||||
midpoint = $container.width() / 2;
|
||||
|
||||
@@ -237,8 +237,8 @@
|
||||
var $peek = $( this ).addClass( PEEKCONTROL_CLASS ),
|
||||
$peektable = $peek.find( 'table' ),
|
||||
// get the size of the tables - width and height, number of comment rows
|
||||
columnCount = $peektable.find( 'th' ).size(),
|
||||
rowCount = $peektable.find( 'tr' ).size(),
|
||||
columnCount = $peektable.find( 'th' ).length,
|
||||
rowCount = $peektable.find( 'tr' ).length,
|
||||
// get the rows containing text starting with the comment char (also make them grey)
|
||||
$commentRows = $peektable.find( 'td[colspan]' ).map( function( e, i ){
|
||||
var $this = $( this );
|
||||
@@ -251,7 +251,7 @@
|
||||
// should comment rows in the peek be hidden?
|
||||
if( options.hideCommentRows ){
|
||||
$commentRows.hide();
|
||||
rowCount -= $commentRows.size();
|
||||
rowCount -= $commentRows.length;
|
||||
}
|
||||
//console.debug( 'rowCount:', rowCount, 'columnCount:', columnCount, '$commentRows:', $commentRows );
|
||||
|
||||
|
||||
@@ -242,7 +242,7 @@ MetricsLogger.prototype._postCache = function _postCache( options ){
|
||||
self._postSize = self.options.maxCacheSize;
|
||||
//TODO:??
|
||||
// log this failure to explain any gap in metrics
|
||||
this.emit( 'error', 'MetricsLogger', [ '_postCache error:',
|
||||
self.emit( 'error', 'MetricsLogger', [ '_postCache error:',
|
||||
xhr.readyState, xhr.status, xhr.responseJSON || xhr.responseText ]);
|
||||
//TODO: still doesn't solve the problem that when cache == max, post will be tried on every emit
|
||||
//TODO: see _delayPost
|
||||
|
||||
@@ -88,15 +88,16 @@ function textify( lst ) {
|
||||
*/
|
||||
function get (options) {
|
||||
top.__utils__get__ = top.__utils__get__ || {};
|
||||
if (options.cache && top.__utils__get__[options.url]) {
|
||||
options.success && options.success(top.__utils__get__[options.url]);
|
||||
console.debug('utils.js::get() - Fetching from cache [' + options.url + '].');
|
||||
var cache_key = JSON.stringify( options );
|
||||
if (options.cache && top.__utils__get__[cache_key]) {
|
||||
options.success && options.success(top.__utils__get__[cache_key]);
|
||||
window.console.debug('utils.js::get() - Fetching from cache [' + options.url + '].');
|
||||
} else {
|
||||
request({
|
||||
url : options.url,
|
||||
data : options.data,
|
||||
success : function(response) {
|
||||
top.__utils__get__[options.url] = response;
|
||||
top.__utils__get__[cache_key] = response;
|
||||
options.success && options.success(response);
|
||||
},
|
||||
error : function(response) {
|
||||
@@ -277,4 +278,4 @@ return {
|
||||
isJSON: isJSON
|
||||
};
|
||||
|
||||
});
|
||||
});
|
||||
@@ -757,6 +757,9 @@ input[type="submit"], button {
|
||||
background-image: url(error_large.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: 10px 8px;
|
||||
.messagerow {
|
||||
padding: 10px 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.errormessagelarge {
|
||||
|
||||
@@ -97,13 +97,22 @@
|
||||
border : 1px solid @black;
|
||||
background : @base-color-1;
|
||||
color : @white;
|
||||
.f-icon-left{
|
||||
cursor : pointer;
|
||||
font-size : 15px;
|
||||
margin-left : 3px;
|
||||
float : left;
|
||||
&[disabled] {
|
||||
opacity : 0.25;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.f-title {
|
||||
position : absolute;
|
||||
top : 2px;
|
||||
left : 16px;
|
||||
right : 16px;
|
||||
left : 32px;
|
||||
right : 32px;
|
||||
font-size : 12px;
|
||||
font-family : @font-family-sans-serif;
|
||||
text-align : center;
|
||||
@@ -113,27 +122,22 @@
|
||||
frame icons
|
||||
*/
|
||||
|
||||
.f-icon{
|
||||
position : absolute;
|
||||
cursor : pointer;
|
||||
font-size : 14px;
|
||||
}
|
||||
|
||||
.f-not-allowed{
|
||||
cursor : not-allowed;
|
||||
}
|
||||
|
||||
.f-close{
|
||||
cursor : pointer;
|
||||
position : absolute;
|
||||
font-size : 15px;
|
||||
right : 5px;
|
||||
top : 3px;
|
||||
}
|
||||
|
||||
.f-pin{
|
||||
left : 6px;
|
||||
top : 3px;
|
||||
top : 2px;
|
||||
}
|
||||
|
||||
.f-resize{
|
||||
cursor : pointer;
|
||||
position : absolute;
|
||||
font-size : 15px;
|
||||
right : 0px;
|
||||
bottom : 0px;
|
||||
background : @white;
|
||||
|
||||
@@ -1,10 +1,21 @@
|
||||
@import "galaxy_bootstrap/variables.less";
|
||||
@import "galaxy_variables.less";
|
||||
|
||||
.library_style_container .fa{
|
||||
.library_style_container{
|
||||
|
||||
width: 95%;
|
||||
margin: auto;
|
||||
margin-top:2em;
|
||||
overflow: auto !important;
|
||||
|
||||
tr {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.fa{
|
||||
font-size: 12px;
|
||||
}
|
||||
.library_style_container .fa-globe{
|
||||
.fa-globe{
|
||||
font-size: initial;
|
||||
margin-left: 0.6em;
|
||||
}
|
||||
@@ -63,15 +74,6 @@ td.right-center {
|
||||
}
|
||||
}
|
||||
}
|
||||
.library_style_container {
|
||||
width: 95%;
|
||||
margin: auto;
|
||||
margin-top:2em;
|
||||
overflow: auto !important;
|
||||
tr {
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
tr.light td
|
||||
{
|
||||
@@ -237,12 +239,6 @@ span.expandLink {
|
||||
.library-paginator {
|
||||
margin-left: 2em;
|
||||
}
|
||||
.paginator-bottom{
|
||||
width: 27em;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-top: 2em;
|
||||
}
|
||||
.import-type-switch{
|
||||
text-decoration: underline;
|
||||
}
|
||||
@@ -255,3 +251,12 @@ span.expandLink {
|
||||
margin-left: 1em;
|
||||
margin-right: 1em;
|
||||
}
|
||||
.paginator-bottom{
|
||||
width: 27em;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-top: 2em;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -264,13 +264,6 @@
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: @white;
|
||||
}
|
||||
.ui-form-backdrop-default {
|
||||
display: block;
|
||||
opacity: 0.2;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.ui-form-backdrop-silent {
|
||||
display: block;
|
||||
opacity: 0.0;
|
||||
cursor: default;
|
||||
@@ -283,6 +276,12 @@
|
||||
box-shadow: none !important;
|
||||
}
|
||||
}
|
||||
.ui-form-element-disabled {
|
||||
&:extend(.ui-form-element all);
|
||||
.ui-form-title {
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-form-separator {
|
||||
font-weight: bold;
|
||||
@@ -300,10 +299,11 @@
|
||||
font-size: 1.2em;
|
||||
padding: 2px 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-form-footer-info {
|
||||
line-height: 1.4em;
|
||||
.ui-form-title {
|
||||
clear:both;
|
||||
font-weight: bold;
|
||||
padding-right: @ui-margin-horizontal;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-form-error {
|
||||
@@ -327,6 +327,10 @@
|
||||
&:extend(.btn-default all);
|
||||
margin-left: @ui-margin-horizontal;
|
||||
}
|
||||
.ui-message {
|
||||
margin-top: 0px;
|
||||
margin-bottom:10px;
|
||||
}
|
||||
}
|
||||
|
||||
// portlets
|
||||
@@ -352,9 +356,14 @@
|
||||
vertical-align: middle;
|
||||
line-height: 22px;
|
||||
}
|
||||
.icon {
|
||||
.portlet-title-text.no-highlight.collapsible {
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.portlet-title-icon {
|
||||
font-size: 1.2em;
|
||||
vertical-align: middle;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
.portlet-operations {
|
||||
@@ -378,6 +387,9 @@
|
||||
margin-bottom: @ui-margin-vertical;
|
||||
}
|
||||
}
|
||||
.portlet-content.nopadding, .portlet-body.nopadding {
|
||||
padding: 0px;
|
||||
}
|
||||
.portlet-footer {
|
||||
margin-top: 5px;
|
||||
padding-left: 10px;
|
||||
|
||||
@@ -12,7 +12,6 @@ module.exports = function( grunt ){
|
||||
libraryLocations = {
|
||||
'jquery': [ 'dist/jquery.js', 'jquery/jquery.js' ],
|
||||
'jquery-migrate': [ 'jquery-migrate.js', 'jquery/jquery.migrate.js' ],
|
||||
'traceKit': [ 'tracekit.js', 'tracekit.js' ],
|
||||
'ravenjs': [ 'dist/raven.js', 'raven.js' ],
|
||||
'underscore': [ 'underscore.js', 'underscore.js' ],
|
||||
'backbone': [ 'backbone.js', 'backbone.js' ],
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
<datatype extension="gatk_tranche" type="galaxy.datatypes.tabular:Tabular" subclass="True" display_in_upload="True"/>
|
||||
<datatype extension="gatk_recal" type="galaxy.datatypes.tabular:Tabular" subclass="True" display_in_upload="True"/>
|
||||
<datatype extension="jpg" type="galaxy.datatypes.images:Jpg" mimetype="image/jpeg"/>
|
||||
<datatype extension="tiff" type="galaxy.datatypes.images:Tiff" mimetype="image/tiff"/>
|
||||
<datatype extension="tiff" type="galaxy.datatypes.images:Tiff" mimetype="image/tiff" display_in_upload="true"/>
|
||||
<datatype extension="bmp" type="galaxy.datatypes.images:Bmp" mimetype="image/bmp"/>
|
||||
<datatype extension="im" type="galaxy.datatypes.images:Im" mimetype="image/im"/>
|
||||
<datatype extension="pcd" type="galaxy.datatypes.images:Pcd" mimetype="image/pcd"/>
|
||||
@@ -317,9 +317,9 @@
|
||||
<datatype extension="sif" type="galaxy.datatypes.graph:Sif" display_in_upload="true"/>
|
||||
<!-- datatypes storing triples -->
|
||||
<datatype extension="triples" type="galaxy.datatypes.triples:Triples" display_in_upload="false"/>
|
||||
<datatype extension="nt" type="galaxy.datatypes.triples:NTriples" display_in_upload="true"/>
|
||||
<datatype extension="n3" type="galaxy.datatypes.triples:N3" display_in_upload="true"/>
|
||||
<datatype extension="ttl" type="galaxy.datatypes.triples:Turtle" display_in_upload="true"/>
|
||||
<datatype extension="nt" type="galaxy.datatypes.triples:NTriples" display_in_upload="true"/>
|
||||
<datatype extension="n3" type="galaxy.datatypes.triples:N3" display_in_upload="true"/>
|
||||
<datatype extension="ttl" type="galaxy.datatypes.triples:Turtle" display_in_upload="true"/>
|
||||
<datatype extension="rdf" type="galaxy.datatypes.triples:Rdf" display_in_upload="true"/>
|
||||
<datatype extension="jsonld" type="galaxy.datatypes.triples:Jsonld" display_in_upload="true"/>
|
||||
<!-- Excel datatypes -->
|
||||
@@ -512,6 +512,7 @@
|
||||
<datatype extension="mothur.align.report" type="galaxy.datatypes.mothur:AlignReport" display_in_upload="true"/>
|
||||
<datatype extension="mothur.filter" type="galaxy.datatypes.mothur:LaneMask" display_in_upload="true"/>
|
||||
<datatype extension="mothur.dist" type="galaxy.datatypes.mothur:DistanceMatrix" display_in_upload="true"/>
|
||||
<datatype extension="mothur.tre" type="galaxy.datatypes.data:Text" subclass="True" display_in_upload="true"/>
|
||||
<datatype extension="mothur.pair.dist" type="galaxy.datatypes.mothur:PairwiseDistanceMatrix" display_in_upload="true"/>
|
||||
<datatype extension="mothur.square.dist" type="galaxy.datatypes.mothur:SquareDistanceMatrix" display_in_upload="true"/>
|
||||
<datatype extension="mothur.lower.dist" type="galaxy.datatypes.mothur:LowerTriangleDistanceMatrix" display_in_upload="true"/>
|
||||
|
||||
@@ -168,9 +168,10 @@ paste.app_factory = galaxy.web.buildapp:app_factory
|
||||
# the tool shed to install dependencies and can also be used by administrators
|
||||
# to manually install or link to dependencies. For details, see:
|
||||
# https://wiki.galaxyproject.org/Admin/Config/ToolDependencies
|
||||
# If this option is not set to a valid path, installing tools with dependencies
|
||||
# from the Tool Shed will fail.
|
||||
#tool_dependency_dir = None
|
||||
# Set to the string none to explicitly disable tool dependency handling.
|
||||
# If this option is set to none or an invalid path, installing tools with dependencies
|
||||
# from the Tool Shed will fail.
|
||||
#tool_dependency_dir = database/dependencies
|
||||
|
||||
# The dependency resolves config file specifies an ordering and options for how
|
||||
# Galaxy resolves tool dependencies (requirement tags in Tool XML). The default
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
higher value (in seconds) (or `None` to use blocking connections). -->
|
||||
<!-- <param id="amqp_consumer_timeout">None</param> -->
|
||||
</plugin>
|
||||
<plugin id="pulsar_legacy" type="runner" load="galaxy.jobs.runners.pulsar:PulsarLegacyJobRunner">
|
||||
<plugin id="pulsar_legacy" type="runner" load="galaxy.jobs.runners.pulsar:PulsarLegacyJobRunner" shell="none">
|
||||
<!-- Pulsar job runner with default parameters matching those
|
||||
of old LWR job runner. If your Pulsar server is running on a
|
||||
Windows machine for instance this runner should still be used.
|
||||
@@ -117,6 +117,89 @@
|
||||
-->
|
||||
<!-- <param id="pulsar_config">path/to/pulsar/app.yml</param> -->
|
||||
</plugin>
|
||||
<plugin id="k8s" type="runner" load="galaxy.jobs.runners.kubernetes:kubernetes">
|
||||
<!-- The Kubernetes (k8s) plugin allows to send jobs to a k8s cluster which shares filesystem with Galaxy.
|
||||
|
||||
This requires installing pykube. Install pykube by activating Galaxy's virtual
|
||||
and then executing the following pip command:
|
||||
|
||||
pip install -e git+https://github.com/pcm32/pykube.git@feature/allMergedFeatures#egg=pykube
|
||||
|
||||
The shared file system needs to be exposed to k8s through a Persistent Volume (rw) and a Persistent
|
||||
Volume Claim. An example of a Persistent Volume could be, in yaml (access modes, reclaim policy and
|
||||
path are relevant) (persistent_volume.yaml):
|
||||
|
||||
kind: PersistentVolume
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: pv-galaxy-nfs
|
||||
labels:
|
||||
type: nfs
|
||||
spec:
|
||||
capacity:
|
||||
storage: 10Gi
|
||||
accessModes:
|
||||
- ReadWriteMany
|
||||
persistentVolumeReclaimPolicy: Retained
|
||||
nfs:
|
||||
path: /scratch1/galaxy_data
|
||||
server: 192.168.64.1
|
||||
|
||||
The path (nfs:path: in the example) set needs to be a parent directory of the directories used for
|
||||
variables “file_path” and “new_file_path” on the galaxy.ini files. Clearly, for this particular example
|
||||
to work, there needs to be a NFS server serving that directory on that ip. Please make sure that you
|
||||
use reasonable storage size for your set up (possibly larger that the 10Gi written).
|
||||
An example of the volume claim should be (this needs to be followed more closely) (pv_claim.yaml):
|
||||
|
||||
kind: PersistentVolumeClaim
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: galaxy-pvc
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteMany
|
||||
volumeName: pv-galaxy-nfs
|
||||
resources:
|
||||
requests:
|
||||
storage: 2Gi
|
||||
|
||||
The volume claim needs to reference the name of the volume in spec:volumeName. The name of the claim
|
||||
(metadat:name) is referenced in the plugin definition (see below), through param
|
||||
"k8s_persistent_volume_claim_name". These two k8s object need to be created before galaxy can use them:
|
||||
|
||||
kubectl create -f <path/to/persistent_volume.yaml>
|
||||
kubectl create -f <path/to/pv_claim.yaml>
|
||||
|
||||
pointing of course to the same Kubernetes cluster that you intend to use.
|
||||
-->
|
||||
|
||||
<param id="k8s_config_path">/path/to/kubeconfig</param>
|
||||
<!--- This is the path to the kube config file, which is normally on ~/.kube/config, but that will depend on
|
||||
your installation. This is the file that tells the plugin where the k8s cluster is, access credentials,
|
||||
etc. -->
|
||||
|
||||
<param id="k8s_persistent_volume_claim_name">galaxy_pvc</param>
|
||||
<!-- The name of the Persisten Volume Claim (PVC) to be used, details above, needs to match the PVC's
|
||||
metadata:name -->
|
||||
|
||||
<param id="k8s_persistent_volume_claim_mount_path">/scratch1/galaxy_data</param>
|
||||
<!-- The mount path needs to be parent directory of the "file_path" and "new_file_path" paths
|
||||
set in universe_wsgi.ini (or equivalent general galaxy config file). This is the mount path of the
|
||||
PVC within the docker container that will be actually running the tool -->
|
||||
|
||||
<param id="k8s_namespace">galaxy-instanceA</param>
|
||||
<!-- The namespace to be used on the Kubernetes cluster, if different from default, this needs to be set
|
||||
accordingly in the PV and PVC detailed above -->
|
||||
|
||||
<param id="k8s_pod_retrials">4</param>
|
||||
<!-- Allows pods to retry up to this number of times, before marking the galaxy job failed. k8s is a state
|
||||
setter essentially, so by default it will try to take a job submitted to successful completion. A job
|
||||
submits pods, until the number of successes (1 in this use case) is achieved, assuming that whatever is
|
||||
making the pods fail will be fixed (such as a stale disk or a dead node that it is being restarted).
|
||||
This option sets a limit of retrials, so that after that number of failed pods, the job is re-scaled to
|
||||
zero (no execution) and the stderr/stdout of the k8s job is reported in galaxy (and the galaxy job set
|
||||
to failed) -->
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
<handlers default="handlers">
|
||||
@@ -434,6 +517,26 @@
|
||||
<param> tags.
|
||||
-->
|
||||
<param id="request_cpus">8</param>
|
||||
|
||||
<!-- Recent version of HTCondor do have a `docker` universe to handle containers.
|
||||
Activate this feature by explicitly specifying the `docker` universe.
|
||||
-->
|
||||
<!-- <param id="universe">docker</param> -->
|
||||
|
||||
<!-- If the tool has a container specified this one is used.
|
||||
|
||||
<requirements>
|
||||
<container type="docker">bgruening/galaxy-stable</container>
|
||||
</requirements>
|
||||
|
||||
Unless the job destination specifies an override
|
||||
with docker_container_id_override. If neither of
|
||||
these is set a default container can be specified
|
||||
with docker_default_container_id. The resolved
|
||||
container ID will be passed along to condor as
|
||||
the docker_image submission parameter.
|
||||
-->
|
||||
<!-- <param id="docker_default_container_id">busybox:ubuntu-14.04</param> -->
|
||||
</destination>
|
||||
|
||||
<!-- Jobs that hit the walltime on one destination can be automatically
|
||||
@@ -475,6 +578,61 @@
|
||||
<param id="docker_enabled" from_config="use_docker">false</param>
|
||||
</destination>
|
||||
|
||||
<destination id="my-tool-container" runner="k8s">
|
||||
<!-- For the kubernetes (k8s) runner, each container is a destination.
|
||||
|
||||
Make sure that the container is able to execute the calls that will be passed by the galaxy built
|
||||
command. Most notably, containers that execute scripts through an interpreter in the form
|
||||
Rscript my-script.R <arguments>
|
||||
should have this wrapped as the container set working directory won't be the one actually used by
|
||||
galaxy (galaxy creates a new working director and moves to it). Recommendation is hence to wrap this
|
||||
type of calls on a shell script, and leave that script with execution privileges on the PATH of the
|
||||
container:
|
||||
|
||||
RUN echo '#!/bin/bash' > /usr/local/bin/myScriptExec
|
||||
RUN echo 'Rscript /path/to/my-script.r "$@"' >> /usr/local/bin/myScriptExec
|
||||
RUN chmod a+x /usr/local/bin/myScriptExec
|
||||
|
||||
-->
|
||||
|
||||
<!-- The following four fields assemble the container's full name:
|
||||
docker pull <repo>/<owner>/<image>:tag
|
||||
-->
|
||||
<param id="docker_repo_override">my-docker-registry.org</param>
|
||||
<param id="docker_owner_override">superbioinfo</param>
|
||||
<param id="docker_image_override">my-tool</param>
|
||||
<param id="docker_tag_override">latest</param>
|
||||
<!-- Alternatively you could specify a different type of container, such as rkt (not tested with Kubernetes)
|
||||
<param id="rkt_repo_override">my-docker-registry.org</param>
|
||||
<param id="rkt_owner_override">superbioinfo</param>
|
||||
<param id="rkt_image_override">my-tool</param>
|
||||
<param id="rkt_tag_override">latest</param>
|
||||
-->
|
||||
<!-- You can also allow the destination to accept the docker container set in the tool, and only fall into
|
||||
the docker image set by this destination if the tool doesn't set a docker container, by using the
|
||||
"default" suffix instead of "override".
|
||||
<param id="docker_repo_default">my-docker-registry.org</param>
|
||||
<param id="docker_owner_default">superbioinfo</param>
|
||||
<param id="docker_image_default">my-tool</param>
|
||||
<param id="docker_tag_default">latest</param>
|
||||
-->
|
||||
<param id="max_pod_retrials">3</param>
|
||||
<!-- Allows pods to retry up to this number of times, before marking the galaxy job failed. k8s is a state
|
||||
setter essentially, so by default it will try to take a job submitted to successful completion. A job
|
||||
submits pods, until the number of successes (1 in this use case) is achieved, assuming that whatever is
|
||||
making the pods fail will be fixed (such as a stale disk or a dead node that it is being restarted).
|
||||
This option sets a limit of retrials, so that after that number of failed pods, the job is re-scaled to
|
||||
zero (no execution) and the stderr/stdout of the k8s job is reported in galaxy (and the galaxy job set
|
||||
to failed).
|
||||
|
||||
Overrides the runner config. (Not implemented yet)
|
||||
-->
|
||||
<!-- REQUIRED: To play nicely with the existing galaxy setup for containers. This could be set though
|
||||
internally by the runner. -->
|
||||
<param id="docker_enabled">true</param>
|
||||
</destination>
|
||||
|
||||
|
||||
<!-- Templatized destinations - macros can be used to create templated
|
||||
destinations with reduced XML duplication. Here we are creating 4 destinations in 4 lines instead of 28 using the macros defined below.
|
||||
-->
|
||||
@@ -506,6 +664,11 @@
|
||||
and pass to dynamic destination (as resource_params argument). -->
|
||||
<tool id="longbar" destination="dynamic" resources="all" />
|
||||
<tool id="baz" handler="special_handlers" destination="bigmem"/>
|
||||
|
||||
<!-- Finally for Kubernetes runner, the following connects a particular tool to be executed with
|
||||
the container of choice in Kubernetes.
|
||||
-->
|
||||
<tool id="my-tool" destination="my-tool-container"/>
|
||||
</tools>
|
||||
<limits>
|
||||
<!-- Certain limits can be defined. The 'concurrent_jobs' limits all
|
||||
|
||||
@@ -30,6 +30,12 @@
|
||||
<section id="send" name="Send Data">
|
||||
<tool file="genomespace/genomespace_exporter.xml" />
|
||||
</section>
|
||||
<section id="collection_operations" name="Collection Operations">
|
||||
<tool file="${model_tools_path}/unzip_collection.xml" />
|
||||
<tool file="${model_tools_path}/zip_collection.xml" />
|
||||
<tool file="${model_tools_path}/filter_failed_collection.xml" />
|
||||
<tool file="${model_tools_path}/flatten_collection.xml" />
|
||||
</section>
|
||||
<section id="liftOver" name="Lift-Over">
|
||||
<tool file="extract/liftOver_wrapper.xml" />
|
||||
</section>
|
||||
|
||||
@@ -23,11 +23,14 @@ THE ORIGINAL WORK IS WITH YOU.
|
||||
|
||||
Script for merging specific local Galaxy config galaxy.ini.cri with default Galaxy galaxy.ini.sample
|
||||
'''
|
||||
import ConfigParser
|
||||
from __future__ import print_function
|
||||
|
||||
import logging
|
||||
import optparse
|
||||
import sys
|
||||
|
||||
from six.moves import configparser
|
||||
|
||||
|
||||
def main():
|
||||
# logging configuration
|
||||
@@ -42,15 +45,15 @@ def main():
|
||||
|
||||
for option in ['sample', 'config']:
|
||||
if getattr(options, option) is None:
|
||||
print "Please supply a --%s parameter.\n" % (option)
|
||||
print("Please supply a --%s parameter.\n" % (option))
|
||||
parser.print_help()
|
||||
sys.exit()
|
||||
|
||||
config_sample = ConfigParser.RawConfigParser()
|
||||
config_sample = configparser.RawConfigParser()
|
||||
config_sample.read(options.sample)
|
||||
config_sample_content = open(options.sample, 'r').read()
|
||||
|
||||
config = ConfigParser.RawConfigParser()
|
||||
config = configparser.RawConfigParser()
|
||||
config.read(options.config)
|
||||
|
||||
logging.info("Merging your own config file %s into the sample one %s." % (options.config, options.sample))
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
check_galaxy can be run by hand, although it is meant to run from cron
|
||||
via the check_galaxy.sh script in Galaxy's cron/ directory.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import filecmp
|
||||
import formatter
|
||||
@@ -30,26 +31,26 @@ else:
|
||||
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" :
|
||||
"Extract+genomic+DNA+1":
|
||||
[
|
||||
{
|
||||
"inputs" :
|
||||
"inputs":
|
||||
(
|
||||
{
|
||||
"file_path" : os.path.join( test_data_dir, "1.bed" ),
|
||||
"dbkey" : "hg17",
|
||||
"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" ) },
|
||||
{ "check_file": os.path.join( test_data_dir, "extract_genomic_dna_out1.fasta" ) },
|
||||
{
|
||||
"tool_run_options" :
|
||||
"tool_run_options":
|
||||
{
|
||||
"input" : "1.bed",
|
||||
"interpret_features" : "yes",
|
||||
"index_source" : "cached",
|
||||
"out_format" : "fasta"
|
||||
"input": "1.bed",
|
||||
"interpret_features": "yes",
|
||||
"index_source": "cached",
|
||||
"out_format": "fasta"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -62,8 +63,8 @@ def usage():
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt( sys.argv[1:], 'n' )
|
||||
except getopt.GetoptError, e:
|
||||
print str(e)
|
||||
except getopt.GetoptError as e:
|
||||
print(str(e))
|
||||
usage()
|
||||
if len( args ) < 1:
|
||||
usage()
|
||||
@@ -75,7 +76,7 @@ new_history = False
|
||||
for o, a in opts:
|
||||
if o == "-n":
|
||||
if debug:
|
||||
print "Specified -n, will create a new history"
|
||||
print("Specified -n, will create a new history")
|
||||
new_history = True
|
||||
else:
|
||||
usage()
|
||||
@@ -83,7 +84,7 @@ for o, a in opts:
|
||||
# state information
|
||||
var_dir = os.path.join( os.path.expanduser('~'), ".check_galaxy", server )
|
||||
if not os.access( var_dir, os.F_OK ):
|
||||
os.makedirs( var_dir, 0700 )
|
||||
os.makedirs( var_dir, 0o700 )
|
||||
|
||||
# default timeout for twill browser is never
|
||||
socket.setdefaulttimeout(300)
|
||||
@@ -133,7 +134,7 @@ class Browser:
|
||||
tc.get_browser()._browser.set_handle_redirect(True)
|
||||
dprint( "%s is returning redirect (302)" % url )
|
||||
return(True)
|
||||
except twill.errors.TwillAssertionError, e:
|
||||
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()
|
||||
@@ -256,7 +257,7 @@ class Browser:
|
||||
def check_state(self):
|
||||
if self.hda_state != "ok":
|
||||
self.get("/datasets/%s/stderr" % self.hda_id)
|
||||
print tc.browser.get_html()
|
||||
print(tc.browser.get_html())
|
||||
raise Exception("HDA %s NOT OK: %s" % (self.hda_id, self.hda_state))
|
||||
|
||||
def diff(self):
|
||||
@@ -281,7 +282,7 @@ class Browser:
|
||||
self.get('/datasets/%s/delete' % hda['id'])
|
||||
hdas = [hda['id'] for hda in self.undeleted_hdas]
|
||||
if hdas:
|
||||
print "Remaining datasets ids:", " ".join(hdas)
|
||||
print("Remaining datasets ids:", " ".join(hdas))
|
||||
raise Exception("History still contains datasets after attempting to delete them")
|
||||
|
||||
def check_if_logged_in(self):
|
||||
@@ -344,7 +345,7 @@ class loggedinParser(htmllib.HTMLParser):
|
||||
|
||||
def dprint(str):
|
||||
if debug:
|
||||
print str
|
||||
print(str)
|
||||
|
||||
# do stuff here
|
||||
if __name__ == "__main__":
|
||||
@@ -360,7 +361,7 @@ if __name__ == "__main__":
|
||||
dprint("not logged in... logging in")
|
||||
b.login(username, password)
|
||||
|
||||
for tool, params in tools.iteritems():
|
||||
for tool, params in tools.items():
|
||||
|
||||
check_file = ""
|
||||
|
||||
@@ -388,5 +389,5 @@ if __name__ == "__main__":
|
||||
b.diff()
|
||||
b.delete_datasets()
|
||||
|
||||
print "OK"
|
||||
print("OK")
|
||||
sys.exit(0)
|
||||
|
||||
+15
-13
@@ -1,5 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Connects to a UCSC table browser and scrapes chrominfo for every build
|
||||
specified by an input file (such as one output by parse_builds.py).
|
||||
@@ -12,29 +11,32 @@ All chromInfo is placed in a path with the convention
|
||||
Usage:
|
||||
python build_chrom_db.py dbpath/ [builds_file]
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import fileinput
|
||||
import os
|
||||
import sys
|
||||
import urllib
|
||||
|
||||
from six.moves.urllib.parse import urlencode
|
||||
from six.moves.urllib.request import urlopen
|
||||
|
||||
import parse_builds
|
||||
|
||||
|
||||
def getchrominfo(url, db):
|
||||
tableURL = "http://genome-test.cse.ucsc.edu/cgi-bin/hgTables?"
|
||||
URL = tableURL + urllib.urlencode({
|
||||
"clade" : "",
|
||||
"org" : "",
|
||||
"db" : db,
|
||||
URL = tableURL + urlencode({
|
||||
"clade": "",
|
||||
"org": "",
|
||||
"db": db,
|
||||
"hgta_outputType": "primaryTable",
|
||||
"hgta_group" : "allTables",
|
||||
"hgta_table" : "chromInfo",
|
||||
"hgta_track" : db,
|
||||
"hgta_group": "allTables",
|
||||
"hgta_table": "chromInfo",
|
||||
"hgta_track": db,
|
||||
"hgta_regionType": "",
|
||||
"position": "",
|
||||
"hgta_doTopSubmit": "get info"})
|
||||
page = urllib.urlopen(URL)
|
||||
page = urlopen(URL)
|
||||
for line in page:
|
||||
line = line.rstrip( "\r\n" )
|
||||
if line.startswith("#"):
|
||||
@@ -68,12 +70,12 @@ if __name__ == "__main__":
|
||||
for build in builds:
|
||||
if build == "?":
|
||||
continue # no lengths for unspecified chrom
|
||||
print "Retrieving " + build
|
||||
print("Retrieving " + build)
|
||||
outfile_name = dbpath + build + ".len"
|
||||
try:
|
||||
with open(outfile_name, "w") as outfile:
|
||||
for chrominfo in getchrominfo("http://genome-test.cse.ucsc.edu/cgi-bin/hgTables?", build):
|
||||
print >> outfile, "\t".join(chrominfo)
|
||||
print("\t".join(chrominfo), file=outfile)
|
||||
except Exception as e:
|
||||
print "Failed to retrieve %s: %s" % (build, e)
|
||||
print("Failed to retrieve %s: %s" % (build, e))
|
||||
os.remove(outfile_name)
|
||||
|
||||
+11
-10
@@ -1,34 +1,35 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Connects to the URL specified and outputs builds available at that
|
||||
DSN in tabular format. UCSC Main gateway is used as default.
|
||||
build description
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
import urllib
|
||||
import xml.etree.ElementTree as ElementTree
|
||||
|
||||
from six.moves.urllib.request import urlopen
|
||||
|
||||
|
||||
def getbuilds(url):
|
||||
try:
|
||||
page = urllib.urlopen(url)
|
||||
page = urlopen(url)
|
||||
except:
|
||||
print "#Unable to open " + url
|
||||
print "?\tunspecified (?)"
|
||||
print("#Unable to open " + url)
|
||||
print("?\tunspecified (?)")
|
||||
sys.exit(1)
|
||||
|
||||
text = page.read()
|
||||
try:
|
||||
tree = ElementTree.fromstring(text)
|
||||
except:
|
||||
print "#Invalid xml passed back from " + url
|
||||
print "?\tunspecified (?)"
|
||||
print("#Invalid xml passed back from " + url)
|
||||
print("?\tunspecified (?)")
|
||||
sys.exit(1)
|
||||
|
||||
print "#Harvested from " + url
|
||||
print "?\tunspecified (?)"
|
||||
print("#Harvested from " + url)
|
||||
print("?\tunspecified (?)")
|
||||
for dsn in tree:
|
||||
build = dsn.find("SOURCE").attrib['id']
|
||||
description = dsn.find("DESCRIPTION").text.replace(" - Genome at UCSC", "").replace(" Genome at UCSC", "")
|
||||
@@ -49,4 +50,4 @@ if __name__ == "__main__":
|
||||
else:
|
||||
URL = "http://genome.cse.ucsc.edu/cgi-bin/das/dsn"
|
||||
for build in getbuilds(URL):
|
||||
print build[0] + "\t" + build[1] + " (" + build[0] + ")"
|
||||
print(build[0] + "\t" + build[1] + " (" + build[0] + ")")
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
"""
|
||||
Connects to sites and determines which builds are available at each.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import urllib
|
||||
import xml.etree.ElementTree as ElementTree
|
||||
|
||||
from six.moves.urllib.request import urlopen
|
||||
|
||||
sites = ['http://genome.ucsc.edu/cgi-bin/',
|
||||
'http://archaea.ucsc.edu/cgi-bin/',
|
||||
'http://genome-test.cse.ucsc.edu/cgi-bin/']
|
||||
@@ -18,17 +20,17 @@ def main():
|
||||
trackurl = sites[i] + "hgTracks?"
|
||||
builds = []
|
||||
try:
|
||||
page = urllib.urlopen(site)
|
||||
page = urlopen(site)
|
||||
except:
|
||||
print "#Unable to connect to " + site
|
||||
print("#Unable to connect to " + site)
|
||||
continue
|
||||
text = page.read()
|
||||
try:
|
||||
tree = ElementTree.fromstring(text)
|
||||
except:
|
||||
print "#Invalid xml passed back from " + site
|
||||
print("#Invalid xml passed back from " + site)
|
||||
continue
|
||||
print "#Harvested from", site
|
||||
print("#Harvested from", site)
|
||||
|
||||
for dsn in tree:
|
||||
build = dsn.find("SOURCE").attrib['id']
|
||||
@@ -36,9 +38,9 @@ def main():
|
||||
build_dict = {}
|
||||
for build in builds:
|
||||
build_dict[build] = 0
|
||||
builds = build_dict.keys()
|
||||
builds = list(build_dict.keys())
|
||||
yield [names[i], trackurl, builds]
|
||||
|
||||
if __name__ == "__main__":
|
||||
for site in main():
|
||||
print site[0] + "\t" + site[1] + "\t" + ",".join(site[2])
|
||||
print(site[0] + "\t" + site[1] + "\t" + ",".join(site[2]))
|
||||
|
||||
@@ -4,7 +4,7 @@ How Do I...
|
||||
This section contains a number of smaller topics with links and examples meant
|
||||
to provide relatively concrete answers for specific Galaxy development scenarios.
|
||||
|
||||
... interact with the Galaxy codebase interactively?
|
||||
... interact with the Galaxy database interactively?
|
||||
----------------------------------------------------
|
||||
|
||||
This can be done with either IPython/Jupyter or a plain python console, depending on your preferences::
|
||||
@@ -14,12 +14,15 @@ This can be done with either IPython/Jupyter or a plain python console, dependin
|
||||
... build Galaxy Javascript frontend client?
|
||||
--------------------------------------------
|
||||
|
||||
We've added a makefile which will let you do this. If you have nodejs and npm installed, you can simple run::
|
||||
We've added a makefile which will let you do this. You can simple run::
|
||||
|
||||
make grunt
|
||||
make client
|
||||
|
||||
If you prefer docker and aren't a JS developer primarily, you can run
|
||||
|
||||
make grunt-docker
|
||||
|
||||
Please see the ``Makefile`` itself for details and other options. There is also a readme at
|
||||
``client/README.md``.
|
||||
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ Enhancements
|
||||
`Pull Request 428`_, `Pull Request 989`_, `Pull Request 988`_,
|
||||
`Pull Request 1389`_, `Pull Request 1485`_, `Pull Request 995`_,
|
||||
`Pull Request 996`_, `Pull Request 1006`_, `Pull Request 1017`_,
|
||||
`Pull Request 1037`_
|
||||
`Pull Request 1037`_, `Pull Request 1495`_
|
||||
* Implement nested workflows.
|
||||
`Pull Request 1306`_
|
||||
|
||||
@@ -500,6 +500,8 @@ Fixes
|
||||
`Pull Request 1366`_
|
||||
* Copy workflow objects when importing them.
|
||||
`Pull Request 1474`_
|
||||
* Undo user icon in masthead.
|
||||
`Pull Request 1493`_
|
||||
* Fix mime type when previewing certain tabular data.
|
||||
`Pull Request 1498`_
|
||||
* Fix disabled CSS.
|
||||
@@ -513,6 +515,13 @@ Fixes
|
||||
`Pull Request 1551`_
|
||||
* Force ``--skip-venv`` if we can detect that Python is Conda Python.
|
||||
`Pull Request 1554`_
|
||||
* Fix installation of Tool Shed repositories containing non-ASCII characters
|
||||
in the description.
|
||||
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__.)
|
||||
`Pull Request 1759`_
|
||||
* Fix pretty_print_time_interval for MySQL.
|
||||
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__.)
|
||||
`Pull Request 1761`_
|
||||
|
||||
.. _iobio: http://iobio.io/
|
||||
|
||||
@@ -751,7 +760,9 @@ Fixes
|
||||
.. _Pull Request 1474: https://github.com/galaxyproject/galaxy/pull/1474
|
||||
.. _Pull Request 1485: https://github.com/galaxyproject/galaxy/pull/1485
|
||||
.. _Pull Request 1487: https://github.com/galaxyproject/galaxy/pull/1487
|
||||
.. _Pull Request 1493: https://github.com/galaxyproject/galaxy/pull/1493
|
||||
.. _Pull Request 1494: https://github.com/galaxyproject/galaxy/pull/1494
|
||||
.. _Pull Request 1495: https://github.com/galaxyproject/galaxy/pull/1495
|
||||
.. _Pull Request 1498: https://github.com/galaxyproject/galaxy/pull/1498
|
||||
.. _Pull Request 1501: https://github.com/galaxyproject/galaxy/pull/1501
|
||||
.. _Pull Request 1511: https://github.com/galaxyproject/galaxy/pull/1511
|
||||
@@ -760,6 +771,8 @@ Fixes
|
||||
.. _Pull Request 1551: https://github.com/galaxyproject/galaxy/pull/1551
|
||||
.. _Pull Request 1554: https://github.com/galaxyproject/galaxy/pull/1554
|
||||
.. _Pull Request 1558: https://github.com/galaxyproject/galaxy/pull/1558
|
||||
.. _Pull Request 1759: https://github.com/galaxyproject/galaxy/pull/1759
|
||||
.. _Pull Request 1761: https://github.com/galaxyproject/galaxy/pull/1761
|
||||
|
||||
.. _Commit f540a16: https://github.com/galaxyproject/galaxy/commit/f540a16768307995ea49c5d241948537ebbfa540
|
||||
.. _Commit bf1c77d: https://github.com/galaxyproject/galaxy/commit/bf1c77d171f079f42d481ad465dbaef3bac8b4d4
|
||||
|
||||
@@ -0,0 +1,868 @@
|
||||
|
||||
.. to_doc
|
||||
|
||||
-------------------------------
|
||||
16.04
|
||||
-------------------------------
|
||||
|
||||
.. announce_start
|
||||
|
||||
Enhancements
|
||||
-------------------------------
|
||||
|
||||
.. major_feature
|
||||
|
||||
* Overhaul of Tools and Jobs
|
||||
`Pull Request 1688`_
|
||||
* Implement an Embedded Pulsar Job Runner
|
||||
`Pull Request 2057`_
|
||||
* Use the API to install repositories instead of loading the
|
||||
Tool Shed in an iframe. (Beta)
|
||||
`Pull Request 1392`_
|
||||
|
||||
.. feature
|
||||
|
||||
* Phinch interactive environment
|
||||
(thanks to `@shiltemann <https://github.com/shiltemann>`__.)
|
||||
`Pull Request 1647`_
|
||||
* Add iobio external display applications for BAM and VCF.
|
||||
`Pull Request 1926`_
|
||||
* add chemical datatypes
|
||||
(thanks to `@bgruening <https://github.com/bgruening>`__.)
|
||||
`Pull Request 1941`_
|
||||
* Scratchbook tour
|
||||
`Pull Request 1463`_
|
||||
* Work toward automating release management.
|
||||
`Pull Request 1613`_
|
||||
* Basic tool error Sentry reporting.
|
||||
`Pull Request 1900`_
|
||||
* disable 'hg push' to TS repositories
|
||||
`Pull Request 2033`_
|
||||
* Generic GIE Launcher, GIE Image Chooser, multiple datasets
|
||||
(thanks to `@erasche <https://github.com/erasche>`__.)
|
||||
`Pull Request 1403`_
|
||||
* The entire Python source code is now continuously checked with flake8 for
|
||||
PEP-8 style consistency and common errors. The last 3500 errors were fixed in
|
||||
this release
|
||||
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__.)
|
||||
`Pull Request 1489`_, `Pull Request 1713`_, `Pull Request 1755`_
|
||||
|
||||
.. enhancement
|
||||
|
||||
* Implement new GIE proxy
|
||||
(thanks to `@erasche <https://github.com/erasche>`__.)
|
||||
`Pull Request 1807`_
|
||||
* Workflow editor overview click navigation
|
||||
`Pull Request 1843`_
|
||||
* API, history contents: allow filters, limit/offset, and ordering
|
||||
`Pull Request 1602`_
|
||||
* datalibs: introduce folder management; fix various glitches; refactor
|
||||
`Pull Request 1562`_
|
||||
* Add makefile target for release process
|
||||
(thanks to `@erasche <https://github.com/erasche>`__.)
|
||||
`Pull Request 1433`_
|
||||
* libraries: provide select all/none options when importing
|
||||
`Pull Request 1970`_
|
||||
* libraries: add 'create history &import to it' feature
|
||||
`Pull Request 2017`_
|
||||
* Bcf.gz to bcf (and reverse) converters + bcf_bgzip data type
|
||||
(thanks to `@markiskander <https://github.com/markiskander>`__.)
|
||||
`Pull Request 1148`_
|
||||
* Update SnpEffDb and SnpSiftDbNSFP for SnpEff v4.1
|
||||
(thanks to `@jj-umn <https://github.com/jj-umn>`__.)
|
||||
`Pull Request 1280`_
|
||||
* Docker Testing - Newer versions of phantomjs and casperjs, in container
|
||||
wheels.
|
||||
`Pull Request 1449`_
|
||||
* Add run_toolshed_tests.html to .gitignore .
|
||||
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__.)
|
||||
`Pull Request 1456`_
|
||||
* Allow sorting of discover_datasets elements.
|
||||
`Pull Request 1512`_
|
||||
* Cleanup common ui elements, add test cases
|
||||
`Pull Request 1519`_
|
||||
* add minor styling to tour popover
|
||||
`Pull Request 1539`_
|
||||
* Code design and legacy cleanup of datatypes and metadata.
|
||||
`Pull Request 1556`_
|
||||
* show_params input walking
|
||||
`Pull Request 1561`_
|
||||
* Add API endpoint for fetching all metadata for a repository.
|
||||
`Pull Request 1565`_
|
||||
* Fix parameter validation
|
||||
`Pull Request 1572`_
|
||||
* Remove recovery hack for REALLY old jobs.
|
||||
`Pull Request 1574`_
|
||||
* Clarify area github tags.
|
||||
`Pull Request 1579`_
|
||||
* update pinned-requirements.txt
|
||||
(thanks to `@matthdsm <https://github.com/matthdsm>`__.)
|
||||
`Pull Request 1605`_
|
||||
* Improve dbkey handling for discovered datasets.
|
||||
`Pull Request 1610`_
|
||||
* Various improvements to the heartbeat
|
||||
`Pull Request 1614`_
|
||||
* Visualization plugins: add routes that more closely match potential static assets.
|
||||
`Pull Request 1615`_
|
||||
* Disable individual file metadata changes in upload
|
||||
`Pull Request 1625`_
|
||||
* added resolver dependency display to the tool view page
|
||||
(thanks to `@zipho <https://github.com/zipho>`__.)
|
||||
`Pull Request 1632`_
|
||||
* Cherry-picked changes from pull request `#1392
|
||||
<https://github.com/galaxyproject/galaxy/issues/1392>`__.
|
||||
`Pull Request 1821`_
|
||||
* Export toolshed repository information for workflow portability
|
||||
(thanks to `@mvdbeek <https://github.com/mvdbeek>`__.)
|
||||
`Pull Request 1636`_
|
||||
* Lint optional handling on conditional test parameters.
|
||||
`Pull Request 1639`_
|
||||
* Updated hashes for bioblend v0.7.0
|
||||
(thanks to `@matthdsm <https://github.com/matthdsm>`__.)
|
||||
`Pull Request 1646`_
|
||||
* Add tox startup (run.sh) test and test on OS X and linux
|
||||
(thanks to `@mvdbeek <https://github.com/mvdbeek>`__.)
|
||||
`Pull Request 1649`_
|
||||
* Optionally pass dataset lists as a single file within tool wrappers
|
||||
(thanks to `@einon <https://github.com/einon>`__.)
|
||||
`Pull Request 1658`_
|
||||
* add a zip datatype which won't be extracted
|
||||
(thanks to `@lecorguille <https://github.com/lecorguille>`__.)
|
||||
`Pull Request 1665`_
|
||||
* Tour improvements and bugfixes
|
||||
`Pull Request 1671`_
|
||||
* Add Marius van den Beek to Galaxy committer group.
|
||||
`Pull Request 1699`_
|
||||
* Revise tool parameter handling, remove redundancies
|
||||
`Pull Request 1711`_
|
||||
* Python 2/3 string handling
|
||||
(thanks to `@mvdbeek <https://github.com/mvdbeek>`__.)
|
||||
`Pull Request 1731`_
|
||||
* workaround for error message on tool lookup in case original toolshed had
|
||||
been disabled
|
||||
(thanks to `@mvdbeek <https://github.com/mvdbeek>`__.)
|
||||
`Pull Request 1738`_
|
||||
* Make api/tools return tool_shed_repository information.
|
||||
(thanks to `@mvdbeek <https://github.com/mvdbeek>`__.)
|
||||
`Pull Request 1752`_
|
||||
* Use visit inputs for check_and_update_param_values
|
||||
`Pull Request 1764`_
|
||||
* Update makefile and add the script I used to apply security patches for
|
||||
16.01
|
||||
`Pull Request 1793`_
|
||||
* Implement dataset empty input validator.
|
||||
`Pull Request 1808`_
|
||||
* Makefile help target + formatting
|
||||
(thanks to `@erasche <https://github.com/erasche>`__.)
|
||||
`Pull Request 1824`_
|
||||
* Add license and repository information to package.json.
|
||||
`Pull Request 1829`_
|
||||
* Improved logging during tool executions.
|
||||
`Pull Request 1832`_
|
||||
* Do not access the history when loading the workflow editor
|
||||
`Pull Request 1861`_
|
||||
* Tones down the warning message about tool changes
|
||||
(thanks to `@bwlang <https://github.com/bwlang>`__.)
|
||||
`Pull Request 1893`_
|
||||
* Use shared value serialization for tool model
|
||||
`Pull Request 1901`_
|
||||
* adding contrib init for reports and modifying status check to have output by process in case multiprocess
|
||||
(thanks to `@miloaec <https://github.com/miloaec>`__.)
|
||||
`Pull Request 1911`_
|
||||
* Retrieve authentification also for long urls
|
||||
(thanks to `@mvdbeek <https://github.com/mvdbeek>`__.)
|
||||
`Pull Request 1912`_
|
||||
* Modify run.sh to add --restart option, for a more consistent use of parameters.
|
||||
(thanks to `@remimarenco <https://github.com/remimarenco>`__.)
|
||||
`Pull Request 1914`_
|
||||
* Rename tool_shed_get to url_get.
|
||||
`Pull Request 1918`_
|
||||
* Allow testing element counts in tool output collections.
|
||||
`Pull Request 1942`_
|
||||
* Use database query rather than dataset iteration to compute dataset counts in saved histories grid.
|
||||
`Pull Request 1948`_
|
||||
* Add "new" state to list of dataset states in saved history list.
|
||||
`Pull Request 1949`_
|
||||
* Add IUC as a new default bioconda channel
|
||||
(thanks to `@bgruening <https://github.com/bgruening>`__.)
|
||||
`Pull Request 1950`_
|
||||
* More job related timing logging.
|
||||
`Pull Request 1956`_
|
||||
* Improvements to workflow scaling performance testing scripts.
|
||||
`Pull Request 1958`_
|
||||
* Optimization for discovering datasets for dynamic output collection.
|
||||
`Pull Request 1959`_
|
||||
* Improve tabular datatypes.
|
||||
(thanks to `@brenninc <https://github.com/brenninc>`__ and `@nsoranzo <https://github.com/nsoranzo>`__.)
|
||||
`Pull Request 1968`_, `Pull Request 2317`_
|
||||
* Optimize adding datasets to large histories.
|
||||
`Pull Request 1983`_
|
||||
* Much more friendly route mapping.
|
||||
`Pull Request 2002`_
|
||||
* Revise content selection, add test cases
|
||||
`Pull Request 2011`_
|
||||
* Don't setup a default tool_data_table_config_path in the shed.
|
||||
`Pull Request 2025`_
|
||||
* data_column to json config file
|
||||
(thanks to `@bgruening <https://github.com/bgruening>`__.)
|
||||
`Pull Request 2026`_
|
||||
* Revise input wrapper, add test cases
|
||||
`Pull Request 2027`_
|
||||
* enable obfs datatype during upload
|
||||
(thanks to `@bgruening <https://github.com/bgruening>`__.)
|
||||
`Pull Request 2028`_
|
||||
* Better element_identifier handling in repeat sections
|
||||
(thanks to `@mvdbeek <https://github.com/mvdbeek>`__.)
|
||||
`Pull Request 2029`_
|
||||
* Pulsar-As-A-Dependency
|
||||
`Pull Request 2052`_
|
||||
* Simplify Workflow sharing menu
|
||||
(thanks to `@nturaga <https://github.com/nturaga>`__.)
|
||||
`Pull Request 2060`_
|
||||
* Add Phinch as an external display application.
|
||||
`Pull Request 2069`_
|
||||
* For non-shed tool data - read loc from sample if available.
|
||||
`Pull Request 2070`_
|
||||
* tool lineage for versionless toolshed tool_ids
|
||||
(thanks to `@mvdbeek <https://github.com/mvdbeek>`__.)
|
||||
`Pull Request 2082`_
|
||||
* make new beta TS tools installation via API configurable
|
||||
`Pull Request 2088`_
|
||||
* Patch in visual separation of section parameters
|
||||
(thanks to `@erasche <https://github.com/erasche>`__.)
|
||||
`Pull Request 2091`_
|
||||
* Add sample supervisor config
|
||||
(thanks to `@mvdbeek <https://github.com/mvdbeek>`__.)
|
||||
`Pull Request 2096`_
|
||||
* Fix cli runner: use embed_metadata_in_job parameter
|
||||
(thanks to `@ThomasWollmann <https://github.com/ThomasWollmann>`__.)
|
||||
`Pull Request 2107`_
|
||||
* Switch Dockerized commands to use sh instead of bash.
|
||||
`Pull Request 2282`_
|
||||
|
||||
.. small_enhancement
|
||||
|
||||
* Remove IPython IE, which was replaced by Jupyter IE.
|
||||
(thanks to `@bgruening <https://github.com/bgruening>`__.)
|
||||
`Pull Request 1402`_
|
||||
* Added py34-lint tox target but forgot to update .travis.yml.
|
||||
`Pull Request 1457`_
|
||||
* fix old jobparam hack for importing files to library
|
||||
`Pull Request 1488`_
|
||||
* An attempt to add limit/offset to history contents
|
||||
`Pull Request 1490`_
|
||||
* Revise label handling in form
|
||||
`Pull Request 1496`_
|
||||
* History UI: clean up.
|
||||
`Pull Request 1522`_
|
||||
* Client-build, Webpack: add tasks to grunt for the common webpack tasks,
|
||||
update readme
|
||||
`Pull Request 1523`_
|
||||
* Remove handlebars and rely solely on underscore templates
|
||||
`Pull Request 1537`_
|
||||
* disable email notifications from travis
|
||||
`Pull Request 1592`_
|
||||
* Remove unnecessary variable and assignment of job command
|
||||
(thanks to `@einon <https://github.com/einon>`__.)
|
||||
`Pull Request 1616`_
|
||||
* Implement the ratable mixin
|
||||
`Pull Request 1618`_
|
||||
* Tour cleanup, remove a few globals.
|
||||
`Pull Request 1621`_
|
||||
* Refactor workflow loading.
|
||||
`Pull Request 1735`_
|
||||
* Swapping from svgfig to svgwrite
|
||||
`Pull Request 1747`_
|
||||
* various libraries refactoring and bugfixes
|
||||
`Pull Request 1751`_
|
||||
* Refactor the Html Datatype Class into text.py instead of images.py
|
||||
(thanks to `@remimarenco <https://github.com/remimarenco>`__.)
|
||||
`Pull Request 1760`_
|
||||
* Drop python2.6 (deprecated, will not be supported in 16.04) from testing.
|
||||
`Pull Request 1785`_
|
||||
* Rework history updating
|
||||
`Pull Request 1788`_
|
||||
* Tests for some of the 16.01 security vulnerabilities
|
||||
`Pull Request 1794`_
|
||||
* Reduce the use of mutable types in toolshed test framework's method
|
||||
definitions.
|
||||
`Pull Request 1813`_
|
||||
* Remove decryption/encryption of tool states
|
||||
`Pull Request 1838`_
|
||||
* Do not import dumps and loads from galaxy.util.json .
|
||||
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__.)
|
||||
`Pull Request 1840`_
|
||||
* Replace get_tool_shed_repository_by_tool_shed_name_owner_changeset_revision with get_repository_for_dependency_relationship.
|
||||
(thanks to `@mvdbeek <https://github.com/mvdbeek>`__.)
|
||||
`Pull Request 1868`_
|
||||
* Cosmetic comma fixes :)
|
||||
(thanks to `@remimarenco <https://github.com/remimarenco>`__.)
|
||||
`Pull Request 1874`_
|
||||
* More debugging for transiently failing tool shed test.
|
||||
`Pull Request 1939`_
|
||||
* Improve logging and retry for another TS test...
|
||||
`Pull Request 1961`_
|
||||
* Add page layout test cases
|
||||
`Pull Request 1991`_
|
||||
* Fix inconsistency in update state handling for tool modules
|
||||
`Pull Request 1993`_
|
||||
* Functional Test Drivers Overhaul
|
||||
`Pull Request 2016`_
|
||||
* Remove install and test code.
|
||||
`Pull Request 2018`_
|
||||
* Remove twill functional tests we don't actively run.
|
||||
`Pull Request 2019`_
|
||||
* Fix transiently failing tool shed tests.
|
||||
`Pull Request 2030`_
|
||||
* Libraries: faster, refactored, cleaned
|
||||
`Pull Request 2031`_
|
||||
* Adjust testing directories so no python root is ever "tool_shed".
|
||||
`Pull Request 2067`_
|
||||
* Fix pbs runner file touch.
|
||||
`Pull Request 2074`_
|
||||
* Move scripts out of lib/tool_shed.
|
||||
`Pull Request 2093`_
|
||||
* Consolidate duplicated method in tool_shed/model.
|
||||
`Pull Request 2099`_
|
||||
* Remove redundant ui divs, move masthead into #everything
|
||||
`Pull Request 2182`_
|
||||
* Remove SLURM memory limit warning from stderr if the job was successful
|
||||
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__).
|
||||
`Pull Request 2309`_
|
||||
|
||||
|
||||
Fixes
|
||||
-------------------------------
|
||||
|
||||
.. major_bug
|
||||
|
||||
* upgrade mercurial wheel to latest (fixing CVE issues)
|
||||
`Pull Request 2045`_
|
||||
* Add changeset_revision to tool attributes, avoid self.tool_shed_repository.
|
||||
(thanks to `@mvdbeek <https://github.com/mvdbeek>`__.)
|
||||
`Pull Request 1802`_
|
||||
* Do not convert spaces to tabs when importing datasets into a library
|
||||
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__).
|
||||
`Pull Request 1985`_
|
||||
|
||||
.. bug
|
||||
|
||||
* Fix that typo in relation_builder.
|
||||
`Pull Request 1453`_
|
||||
* URL generation tweaks for utils.js
|
||||
`Pull Request 1478`_
|
||||
* Fix project linting for new pep8
|
||||
`Pull Request 1483`_
|
||||
* Fix Python 3 problem causing Travis failure of dev.
|
||||
`Pull Request 1505`_
|
||||
* catch Exception and properly log errors
|
||||
`Pull Request 1510`_
|
||||
* Change python print() format to be backward compatible with older versions.
|
||||
(thanks to `@einon <https://github.com/einon>`__.)
|
||||
`Pull Request 1520`_
|
||||
* Add js for mako based masthead
|
||||
`Pull Request 1533`_
|
||||
* restrict blue popover to tours
|
||||
`Pull Request 1577`_
|
||||
* small spelling error
|
||||
(thanks to `@matthdsm <https://github.com/matthdsm>`__.)
|
||||
`Pull Request 1582`_
|
||||
* Fix installation of repository suites outside of tool panel section
|
||||
(thanks to `@mvdbeek <https://github.com/mvdbeek>`__.)
|
||||
`Pull Request 1601`_
|
||||
* Fixes `<param argument="--set" />` not working when `help=""` is not set
|
||||
(thanks to `@yhoogstrate <https://github.com/yhoogstrate>`__.)
|
||||
`Pull Request 1650`_
|
||||
* Fix validation for data source tools
|
||||
`Pull Request 1654`_
|
||||
* Better fix for missing element identifier
|
||||
(thanks to `@mvdbeek <https://github.com/mvdbeek>`__.)
|
||||
`Pull Request 1693`_
|
||||
* Update david identifier types
|
||||
(thanks to `@pavanvidem <https://github.com/pavanvidem>`__.)
|
||||
`Pull Request 1696`_
|
||||
* Drop Ross from the committers group.
|
||||
`Pull Request 1698`_
|
||||
* Wrap conditional test parameters
|
||||
`Pull Request 1714`_
|
||||
* Remove len(stderr), breaks on recent docker versions
|
||||
(thanks to `@mvdbeek <https://github.com/mvdbeek>`__.)
|
||||
`Pull Request 1769`_
|
||||
* Strip URL of download_file and download_by_url install actions.
|
||||
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__.)
|
||||
`Pull Request 1775`_
|
||||
* Fix tool form rendering of sections
|
||||
`Pull Request 1783`_
|
||||
* Fix unused import.
|
||||
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__.)
|
||||
`Pull Request 1796`_
|
||||
* Fix tool shed tests for commit e4a1d5727805168a9fd15aca1cdd21630ada2bbc
|
||||
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__).
|
||||
`Pull Request 1798`_
|
||||
* Checks for api_key before checking for header from SSO.
|
||||
(thanks to `@MatthewRalston <https://github.com/MatthewRalston>`__.)
|
||||
`Pull Request 1801`_
|
||||
* Ensure tool.changeset_revision is set...
|
||||
`Pull Request 1806`_
|
||||
* Change many job mapped properties to lazy loads
|
||||
`Pull Request 1809`_
|
||||
* Whitelist logging tweaks
|
||||
`Pull Request 1819`_
|
||||
* Fix upload tool routing
|
||||
`Pull Request 1827`_
|
||||
* Using node 5.7, 'grunt style' fails with the error:
|
||||
`Pull Request 1841`_
|
||||
* Do not create text values for failed inputs
|
||||
`Pull Request 1844`_
|
||||
* Prevent tours from kicking off within iframes
|
||||
`Pull Request 1846`_
|
||||
* Fix repeat prefix
|
||||
`Pull Request 1848`_
|
||||
* also update rrda when repairing or updating a repository
|
||||
(thanks to `@mvdbeek <https://github.com/mvdbeek>`__.)
|
||||
`Pull Request 1850`_
|
||||
* Fix regex validator
|
||||
`Pull Request 1862`_
|
||||
* Tour routing overhaul
|
||||
`Pull Request 1870`_
|
||||
* Add dedicated client endpoint to the root controller.
|
||||
`Pull Request 1879`_
|
||||
* Update check_python.py now dropping Python 2.6
|
||||
(thanks to `@peterjc <https://github.com/peterjc>`__.)
|
||||
`Pull Request 1883`_
|
||||
* Fix citation-model to fail silently/gracefully
|
||||
`Pull Request 1884`_
|
||||
* Change to sentry middleware to work with modern raven clients.
|
||||
`Pull Request 1895`_
|
||||
* svgfig->svgwrite in unpinned requirements
|
||||
`Pull Request 1896`_
|
||||
* Fix icon sizes
|
||||
`Pull Request 1934`_
|
||||
* Fix tool downloads in tool form
|
||||
`Pull Request 1935`_
|
||||
* Fixing error in run.sh script
|
||||
(thanks to `@kellrott <https://github.com/kellrott>`__.)
|
||||
`Pull Request 1954`_
|
||||
* Fix typo: send-->sent
|
||||
`Pull Request 1965`_
|
||||
* Fix farbtastic's use of deprecated jquery fns by loading jq-migrate in galaxy.panels.mako .
|
||||
`Pull Request 1972`_
|
||||
* Remove duplicate help target
|
||||
(thanks to `@erasche <https://github.com/erasche>`__.)
|
||||
`Pull Request 1980`_
|
||||
* Fix booleans in workflow editor
|
||||
`Pull Request 1990`_
|
||||
* libraries: change default size of fa in iconspans
|
||||
`Pull Request 2000`_
|
||||
* libraries: move text out of icon spans for library dataset view
|
||||
`Pull Request 2008`_
|
||||
* Fix unbound error that is possible if using tool bursting.
|
||||
`Pull Request 2009`_
|
||||
* Fix multiple flag for workflow dataset inputs
|
||||
`Pull Request 2021`_
|
||||
* fix duplication of select2 entries
|
||||
`Pull Request 2022`_
|
||||
* Fix fluent query log serialization when datetime types are in use.
|
||||
`Pull Request 2039`_
|
||||
* Workflow import fix when tools are missing.
|
||||
`Pull Request 2048`_
|
||||
* Managers: remove UTC zone when parsing dates
|
||||
(thanks also to `@nsoranzo <https://github.com/nsoranzo>`__).
|
||||
`Pull Request 2042`_, `Pull Request 2062`_, `Pull Request 2065`_
|
||||
* Change user disk usage pgcalc function up a bit to make a slightly safer dry-run.
|
||||
`Pull Request 2063`_
|
||||
* Allow tool confs with a tool_path to not be interpreted as shed confs.
|
||||
`Pull Request 2066`_
|
||||
* Fix deps.command.download_command on Mac OS X.
|
||||
`Pull Request 2075`_
|
||||
* Show sections in workflow run
|
||||
`Pull Request 2087`_
|
||||
* Workflow section fix backport
|
||||
(thanks to `@erasche <https://github.com/erasche>`__.)
|
||||
`Pull Request 2092`_
|
||||
* Run external local set_metadata jobs in the job's working directory
|
||||
`Pull Request 2094`_
|
||||
* make dependencies browsable again
|
||||
`Pull Request 2101`_
|
||||
* Convert the DRMAA runner to use Pulsar's DRMAA session wrapper
|
||||
`Pull Request 2102`_
|
||||
* Updated to Dependency change in b167a741a444c3988447b0d63a1ba3dc5e4e62f5
|
||||
(thanks to `@Christian-B <https://github.com/Christian-B>`__.)
|
||||
`Pull Request 2104`_
|
||||
* Fix datatype list in workflow editor
|
||||
`Pull Request 2105`_
|
||||
* Workaround for the toolshed's hgweb.
|
||||
`Pull Request 2106`_
|
||||
* Update debian init script
|
||||
(thanks to `@mvdbeek <https://github.com/mvdbeek>`__.)
|
||||
`Pull Request 2109`_
|
||||
* Rev Pulsar to 0.7.0.dev3.
|
||||
`Pull Request 2122`_
|
||||
* change run_tool_shed.py to see the file in the correct lcoation
|
||||
(thanks to `@nturaga <https://github.com/nturaga>`__.)
|
||||
`Pull Request 2131`_
|
||||
* Fixes due to `#2093 <https://github.com/galaxyproject/galaxy/issues/2093>`__
|
||||
and `#2018 <https://github.com/galaxyproject/galaxy/issues/2018>`__
|
||||
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__.)
|
||||
`Pull Request 2133`_
|
||||
* markupsafe.escape() in Python2 does not work on str containing non-ASCII
|
||||
characters
|
||||
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__.)
|
||||
`Pull Request 2138`_
|
||||
* load options from config, not from options
|
||||
`Pull Request 2139`_
|
||||
* fix/replace biomart data source
|
||||
`Pull Request 2149`_
|
||||
* Add tool parameters back to parameters and expose for certain tools
|
||||
`Pull Request 2156`_
|
||||
* Fix wrapper issue, overload __ne__
|
||||
`Pull Request 2161`_
|
||||
* Fix grouping tool and enhance performance when removing lines.
|
||||
`Pull Request 2166`_
|
||||
* libraries: always fetch new permissions as we are reusing the view
|
||||
`Pull Request 2176`_
|
||||
* Fix for redirecting a non-user when a tool has require_login=True.
|
||||
`Pull Request 2180`_
|
||||
* Fix.published history long titles have to be truncated
|
||||
`Pull Request 2189`_
|
||||
* fix a bug with missing history_id in libraries dataset import
|
||||
`Pull Request 2190`_
|
||||
* Fix message in legacy panel mako
|
||||
`Pull Request 2191`_
|
||||
* Prepass on remote user header based on maildomain and normalize config.
|
||||
`Pull Request 2195`_
|
||||
* Extend to_json for dataset tool parameters
|
||||
`Pull Request 2196`_
|
||||
* Pages parser fix
|
||||
`Pull Request 2197`_
|
||||
* Translate data source tool parameters on parameter expansion
|
||||
`Pull Request 2201`_
|
||||
* Sync job_script module with Pulsar to fix doctest.
|
||||
`Pull Request 2203`_
|
||||
* Improve error message for data source tools, executed through the
|
||||
tool_runner controller
|
||||
`Pull Request 2204`_
|
||||
* Add fixed validation check for data_source tools URL parameter
|
||||
`Pull Request 2208`_
|
||||
* Fix tool action redirect url for non-default tools
|
||||
`Pull Request 2211`_
|
||||
* Browse library date handling for non-ascii month abbreviations
|
||||
`Pull Request 2214`_
|
||||
* Avoid reset of cursor position for input fields during manual entry
|
||||
`Pull Request 2218`_
|
||||
* Add conditional statsd requirement
|
||||
`Pull Request 2227`_
|
||||
* Fix js value validator
|
||||
`Pull Request 2234`_
|
||||
* Encode collection reduce in serializable fashion
|
||||
`Pull Request 2238`_
|
||||
* Update `_condarc` automatically
|
||||
(thanks to `@bgruening <https://github.com/bgruening>`__.)
|
||||
`Pull Request 2255`_
|
||||
* Truncate job name in DRMAA runner by default for PBSPro.
|
||||
`Pull Request 2265`_
|
||||
* Cherrypick of encoding fix
|
||||
`Pull Request 2266`_
|
||||
* If a Slurm post-mortem determines that a job is in a non-terminal state,
|
||||
return the job to the monitor queue
|
||||
`Pull Request 2311`_
|
||||
* Unicodify pretty datetimes which can contain non-ASCII chars
|
||||
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__).
|
||||
`Pull Request 2312`_
|
||||
* Relax default value acceptance condition
|
||||
`Pull Request 2316`_
|
||||
* Fixes the proxy naming
|
||||
(thanks to `@bgruening <https://github.com/bgruening>`__.)
|
||||
`Pull Request 2333`_
|
||||
* Re-fix the bug with multiple preceding '/' characters in the GIE proxy
|
||||
prefix
|
||||
`Pull Request 2339`_
|
||||
* Do not pollute param_dict with a non JSONifiable dict
|
||||
(thanks to `@nsoranzo <https://github.com/nsoranzo>`__.)
|
||||
`Pull Request 2345`_
|
||||
|
||||
.. github_links
|
||||
.. _Pull Request 1148: https://github.com/galaxyproject/galaxy/pull/1148
|
||||
.. _Pull Request 1280: https://github.com/galaxyproject/galaxy/pull/1280
|
||||
.. _Pull Request 1331: https://github.com/galaxyproject/galaxy/pull/1331
|
||||
.. _Pull Request 1357: https://github.com/galaxyproject/galaxy/pull/1357
|
||||
.. _Pull Request 1392: https://github.com/galaxyproject/galaxy/pull/1392
|
||||
.. _Pull Request 1402: https://github.com/galaxyproject/galaxy/pull/1402
|
||||
.. _Pull Request 1403: https://github.com/galaxyproject/galaxy/pull/1403
|
||||
.. _Pull Request 1431: https://github.com/galaxyproject/galaxy/pull/1431
|
||||
.. _Pull Request 1433: https://github.com/galaxyproject/galaxy/pull/1433
|
||||
.. _Pull Request 1449: https://github.com/galaxyproject/galaxy/pull/1449
|
||||
.. _Pull Request 1453: https://github.com/galaxyproject/galaxy/pull/1453
|
||||
.. _Pull Request 1454: https://github.com/galaxyproject/galaxy/pull/1454
|
||||
.. _Pull Request 1456: https://github.com/galaxyproject/galaxy/pull/1456
|
||||
.. _Pull Request 1457: https://github.com/galaxyproject/galaxy/pull/1457
|
||||
.. _Pull Request 1463: https://github.com/galaxyproject/galaxy/pull/1463
|
||||
.. _Pull Request 1478: https://github.com/galaxyproject/galaxy/pull/1478
|
||||
.. _Pull Request 1483: https://github.com/galaxyproject/galaxy/pull/1483
|
||||
.. _Pull Request 1488: https://github.com/galaxyproject/galaxy/pull/1488
|
||||
.. _Pull Request 1489: https://github.com/galaxyproject/galaxy/pull/1489
|
||||
.. _Pull Request 1490: https://github.com/galaxyproject/galaxy/pull/1490
|
||||
.. _Pull Request 1496: https://github.com/galaxyproject/galaxy/pull/1496
|
||||
.. _Pull Request 1505: https://github.com/galaxyproject/galaxy/pull/1505
|
||||
.. _Pull Request 1510: https://github.com/galaxyproject/galaxy/pull/1510
|
||||
.. _Pull Request 1512: https://github.com/galaxyproject/galaxy/pull/1512
|
||||
.. _Pull Request 1519: https://github.com/galaxyproject/galaxy/pull/1519
|
||||
.. _Pull Request 1520: https://github.com/galaxyproject/galaxy/pull/1520
|
||||
.. _Pull Request 1522: https://github.com/galaxyproject/galaxy/pull/1522
|
||||
.. _Pull Request 1523: https://github.com/galaxyproject/galaxy/pull/1523
|
||||
.. _Pull Request 1533: https://github.com/galaxyproject/galaxy/pull/1533
|
||||
.. _Pull Request 1537: https://github.com/galaxyproject/galaxy/pull/1537
|
||||
.. _Pull Request 1539: https://github.com/galaxyproject/galaxy/pull/1539
|
||||
.. _Pull Request 1556: https://github.com/galaxyproject/galaxy/pull/1556
|
||||
.. _Pull Request 1561: https://github.com/galaxyproject/galaxy/pull/1561
|
||||
.. _Pull Request 1562: https://github.com/galaxyproject/galaxy/pull/1562
|
||||
.. _Pull Request 1565: https://github.com/galaxyproject/galaxy/pull/1565
|
||||
.. _Pull Request 1566: https://github.com/galaxyproject/galaxy/pull/1566
|
||||
.. _Pull Request 1572: https://github.com/galaxyproject/galaxy/pull/1572
|
||||
.. _Pull Request 1574: https://github.com/galaxyproject/galaxy/pull/1574
|
||||
.. _Pull Request 1577: https://github.com/galaxyproject/galaxy/pull/1577
|
||||
.. _Pull Request 1579: https://github.com/galaxyproject/galaxy/pull/1579
|
||||
.. _Pull Request 1582: https://github.com/galaxyproject/galaxy/pull/1582
|
||||
.. _Pull Request 1583: https://github.com/galaxyproject/galaxy/pull/1583
|
||||
.. _Pull Request 1591: https://github.com/galaxyproject/galaxy/pull/1591
|
||||
.. _Pull Request 1592: https://github.com/galaxyproject/galaxy/pull/1592
|
||||
.. _Pull Request 1601: https://github.com/galaxyproject/galaxy/pull/1601
|
||||
.. _Pull Request 1602: https://github.com/galaxyproject/galaxy/pull/1602
|
||||
.. _Pull Request 1605: https://github.com/galaxyproject/galaxy/pull/1605
|
||||
.. _Pull Request 1610: https://github.com/galaxyproject/galaxy/pull/1610
|
||||
.. _Pull Request 1613: https://github.com/galaxyproject/galaxy/pull/1613
|
||||
.. _Pull Request 1614: https://github.com/galaxyproject/galaxy/pull/1614
|
||||
.. _Pull Request 1615: https://github.com/galaxyproject/galaxy/pull/1615
|
||||
.. _Pull Request 1616: https://github.com/galaxyproject/galaxy/pull/1616
|
||||
.. _Pull Request 1618: https://github.com/galaxyproject/galaxy/pull/1618
|
||||
.. _Pull Request 1621: https://github.com/galaxyproject/galaxy/pull/1621
|
||||
.. _Pull Request 1625: https://github.com/galaxyproject/galaxy/pull/1625
|
||||
.. _Pull Request 1632: https://github.com/galaxyproject/galaxy/pull/1632
|
||||
.. _Pull Request 1636: https://github.com/galaxyproject/galaxy/pull/1636
|
||||
.. _Pull Request 1639: https://github.com/galaxyproject/galaxy/pull/1639
|
||||
.. _Pull Request 1646: https://github.com/galaxyproject/galaxy/pull/1646
|
||||
.. _Pull Request 1647: https://github.com/galaxyproject/galaxy/pull/1647
|
||||
.. _Pull Request 1649: https://github.com/galaxyproject/galaxy/pull/1649
|
||||
.. _Pull Request 1650: https://github.com/galaxyproject/galaxy/pull/1650
|
||||
.. _Pull Request 1654: https://github.com/galaxyproject/galaxy/pull/1654
|
||||
.. _Pull Request 1658: https://github.com/galaxyproject/galaxy/pull/1658
|
||||
.. _Pull Request 1665: https://github.com/galaxyproject/galaxy/pull/1665
|
||||
.. _Pull Request 1670: https://github.com/galaxyproject/galaxy/pull/1670
|
||||
.. _Pull Request 1671: https://github.com/galaxyproject/galaxy/pull/1671
|
||||
.. _Pull Request 1688: https://github.com/galaxyproject/galaxy/pull/1688
|
||||
.. _Pull Request 1693: https://github.com/galaxyproject/galaxy/pull/1693
|
||||
.. _Pull Request 1696: https://github.com/galaxyproject/galaxy/pull/1696
|
||||
.. _Pull Request 1698: https://github.com/galaxyproject/galaxy/pull/1698
|
||||
.. _Pull Request 1699: https://github.com/galaxyproject/galaxy/pull/1699
|
||||
.. _Pull Request 1711: https://github.com/galaxyproject/galaxy/pull/1711
|
||||
.. _Pull Request 1713: https://github.com/galaxyproject/galaxy/pull/1713
|
||||
.. _Pull Request 1714: https://github.com/galaxyproject/galaxy/pull/1714
|
||||
.. _Pull Request 1731: https://github.com/galaxyproject/galaxy/pull/1731
|
||||
.. _Pull Request 1735: https://github.com/galaxyproject/galaxy/pull/1735
|
||||
.. _Pull Request 1738: https://github.com/galaxyproject/galaxy/pull/1738
|
||||
.. _Pull Request 1742: https://github.com/galaxyproject/galaxy/pull/1742
|
||||
.. _Pull Request 1747: https://github.com/galaxyproject/galaxy/pull/1747
|
||||
.. _Pull Request 1751: https://github.com/galaxyproject/galaxy/pull/1751
|
||||
.. _Pull Request 1752: https://github.com/galaxyproject/galaxy/pull/1752
|
||||
.. _Pull Request 1755: https://github.com/galaxyproject/galaxy/pull/1755
|
||||
.. _Pull Request 1756: https://github.com/galaxyproject/galaxy/pull/1756
|
||||
.. _Pull Request 1760: https://github.com/galaxyproject/galaxy/pull/1760
|
||||
.. _Pull Request 1764: https://github.com/galaxyproject/galaxy/pull/1764
|
||||
.. _Pull Request 1769: https://github.com/galaxyproject/galaxy/pull/1769
|
||||
.. _Pull Request 1770: https://github.com/galaxyproject/galaxy/pull/1770
|
||||
.. _Pull Request 1775: https://github.com/galaxyproject/galaxy/pull/1775
|
||||
.. _Pull Request 1783: https://github.com/galaxyproject/galaxy/pull/1783
|
||||
.. _Pull Request 1785: https://github.com/galaxyproject/galaxy/pull/1785
|
||||
.. _Pull Request 1788: https://github.com/galaxyproject/galaxy/pull/1788
|
||||
.. _Pull Request 1793: https://github.com/galaxyproject/galaxy/pull/1793
|
||||
.. _Pull Request 1794: https://github.com/galaxyproject/galaxy/pull/1794
|
||||
.. _Pull Request 1796: https://github.com/galaxyproject/galaxy/pull/1796
|
||||
.. _Pull Request 1798: https://github.com/galaxyproject/galaxy/pull/1798
|
||||
.. _Pull Request 1800: https://github.com/galaxyproject/galaxy/pull/1800
|
||||
.. _Pull Request 1801: https://github.com/galaxyproject/galaxy/pull/1801
|
||||
.. _Pull Request 1802: https://github.com/galaxyproject/galaxy/pull/1802
|
||||
.. _Pull Request 1806: https://github.com/galaxyproject/galaxy/pull/1806
|
||||
.. _Pull Request 1807: https://github.com/galaxyproject/galaxy/pull/1807
|
||||
.. _Pull Request 1808: https://github.com/galaxyproject/galaxy/pull/1808
|
||||
.. _Pull Request 1809: https://github.com/galaxyproject/galaxy/pull/1809
|
||||
.. _Pull Request 1813: https://github.com/galaxyproject/galaxy/pull/1813
|
||||
.. _Pull Request 1819: https://github.com/galaxyproject/galaxy/pull/1819
|
||||
.. _Pull Request 1821: https://github.com/galaxyproject/galaxy/pull/1821
|
||||
.. _Pull Request 1824: https://github.com/galaxyproject/galaxy/pull/1824
|
||||
.. _Pull Request 1827: https://github.com/galaxyproject/galaxy/pull/1827
|
||||
.. _Pull Request 1829: https://github.com/galaxyproject/galaxy/pull/1829
|
||||
.. _Pull Request 1832: https://github.com/galaxyproject/galaxy/pull/1832
|
||||
.. _Pull Request 1835: https://github.com/galaxyproject/galaxy/pull/1835
|
||||
.. _Pull Request 1838: https://github.com/galaxyproject/galaxy/pull/1838
|
||||
.. _Pull Request 1840: https://github.com/galaxyproject/galaxy/pull/1840
|
||||
.. _Pull Request 1841: https://github.com/galaxyproject/galaxy/pull/1841
|
||||
.. _Pull Request 1843: https://github.com/galaxyproject/galaxy/pull/1843
|
||||
.. _Pull Request 1844: https://github.com/galaxyproject/galaxy/pull/1844
|
||||
.. _Pull Request 1846: https://github.com/galaxyproject/galaxy/pull/1846
|
||||
.. _Pull Request 1848: https://github.com/galaxyproject/galaxy/pull/1848
|
||||
.. _Pull Request 1850: https://github.com/galaxyproject/galaxy/pull/1850
|
||||
.. _Pull Request 1853: https://github.com/galaxyproject/galaxy/pull/1853
|
||||
.. _Pull Request 1861: https://github.com/galaxyproject/galaxy/pull/1861
|
||||
.. _Pull Request 1862: https://github.com/galaxyproject/galaxy/pull/1862
|
||||
.. _Pull Request 1868: https://github.com/galaxyproject/galaxy/pull/1868
|
||||
.. _Pull Request 1870: https://github.com/galaxyproject/galaxy/pull/1870
|
||||
.. _Pull Request 1874: https://github.com/galaxyproject/galaxy/pull/1874
|
||||
.. _Pull Request 1876: https://github.com/galaxyproject/galaxy/pull/1876
|
||||
.. _Pull Request 1879: https://github.com/galaxyproject/galaxy/pull/1879
|
||||
.. _Pull Request 1883: https://github.com/galaxyproject/galaxy/pull/1883
|
||||
.. _Pull Request 1884: https://github.com/galaxyproject/galaxy/pull/1884
|
||||
.. _Pull Request 1893: https://github.com/galaxyproject/galaxy/pull/1893
|
||||
.. _Pull Request 1895: https://github.com/galaxyproject/galaxy/pull/1895
|
||||
.. _Pull Request 1896: https://github.com/galaxyproject/galaxy/pull/1896
|
||||
.. _Pull Request 1900: https://github.com/galaxyproject/galaxy/pull/1900
|
||||
.. _Pull Request 1901: https://github.com/galaxyproject/galaxy/pull/1901
|
||||
.. _Pull Request 1910: https://github.com/galaxyproject/galaxy/pull/1910
|
||||
.. _Pull Request 1911: https://github.com/galaxyproject/galaxy/pull/1911
|
||||
.. _Pull Request 1912: https://github.com/galaxyproject/galaxy/pull/1912
|
||||
.. _Pull Request 1914: https://github.com/galaxyproject/galaxy/pull/1914
|
||||
.. _Pull Request 1918: https://github.com/galaxyproject/galaxy/pull/1918
|
||||
.. _Pull Request 1926: https://github.com/galaxyproject/galaxy/pull/1926
|
||||
.. _Pull Request 1934: https://github.com/galaxyproject/galaxy/pull/1934
|
||||
.. _Pull Request 1935: https://github.com/galaxyproject/galaxy/pull/1935
|
||||
.. _Pull Request 1936: https://github.com/galaxyproject/galaxy/pull/1936
|
||||
.. _Pull Request 1939: https://github.com/galaxyproject/galaxy/pull/1939
|
||||
.. _Pull Request 1941: https://github.com/galaxyproject/galaxy/pull/1941
|
||||
.. _Pull Request 1942: https://github.com/galaxyproject/galaxy/pull/1942
|
||||
.. _Pull Request 1943: https://github.com/galaxyproject/galaxy/pull/1943
|
||||
.. _Pull Request 1948: https://github.com/galaxyproject/galaxy/pull/1948
|
||||
.. _Pull Request 1949: https://github.com/galaxyproject/galaxy/pull/1949
|
||||
.. _Pull Request 1950: https://github.com/galaxyproject/galaxy/pull/1950
|
||||
.. _Pull Request 1953: https://github.com/galaxyproject/galaxy/pull/1953
|
||||
.. _Pull Request 1954: https://github.com/galaxyproject/galaxy/pull/1954
|
||||
.. _Pull Request 1956: https://github.com/galaxyproject/galaxy/pull/1956
|
||||
.. _Pull Request 1958: https://github.com/galaxyproject/galaxy/pull/1958
|
||||
.. _Pull Request 1959: https://github.com/galaxyproject/galaxy/pull/1959
|
||||
.. _Pull Request 1961: https://github.com/galaxyproject/galaxy/pull/1961
|
||||
.. _Pull Request 1962: https://github.com/galaxyproject/galaxy/pull/1962
|
||||
.. _Pull Request 1963: https://github.com/galaxyproject/galaxy/pull/1963
|
||||
.. _Pull Request 1965: https://github.com/galaxyproject/galaxy/pull/1965
|
||||
.. _Pull Request 1968: https://github.com/galaxyproject/galaxy/pull/1968
|
||||
.. _Pull Request 1969: https://github.com/galaxyproject/galaxy/pull/1969
|
||||
.. _Pull Request 1970: https://github.com/galaxyproject/galaxy/pull/1970
|
||||
.. _Pull Request 1971: https://github.com/galaxyproject/galaxy/pull/1971
|
||||
.. _Pull Request 1972: https://github.com/galaxyproject/galaxy/pull/1972
|
||||
.. _Pull Request 1974: https://github.com/galaxyproject/galaxy/pull/1974
|
||||
.. _Pull Request 1980: https://github.com/galaxyproject/galaxy/pull/1980
|
||||
.. _Pull Request 1983: https://github.com/galaxyproject/galaxy/pull/1983
|
||||
.. _Pull Request 1985: https://github.com/galaxyproject/galaxy/pull/1985
|
||||
.. _Pull Request 1990: https://github.com/galaxyproject/galaxy/pull/1990
|
||||
.. _Pull Request 1991: https://github.com/galaxyproject/galaxy/pull/1991
|
||||
.. _Pull Request 1993: https://github.com/galaxyproject/galaxy/pull/1993
|
||||
.. _Pull Request 1996: https://github.com/galaxyproject/galaxy/pull/1996
|
||||
.. _Pull Request 2000: https://github.com/galaxyproject/galaxy/pull/2000
|
||||
.. _Pull Request 2002: https://github.com/galaxyproject/galaxy/pull/2002
|
||||
.. _Pull Request 2004: https://github.com/galaxyproject/galaxy/pull/2004
|
||||
.. _Pull Request 2008: https://github.com/galaxyproject/galaxy/pull/2008
|
||||
.. _Pull Request 2009: https://github.com/galaxyproject/galaxy/pull/2009
|
||||
.. _Pull Request 2010: https://github.com/galaxyproject/galaxy/pull/2010
|
||||
.. _Pull Request 2011: https://github.com/galaxyproject/galaxy/pull/2011
|
||||
.. _Pull Request 2015: https://github.com/galaxyproject/galaxy/pull/2015
|
||||
.. _Pull Request 2016: https://github.com/galaxyproject/galaxy/pull/2016
|
||||
.. _Pull Request 2017: https://github.com/galaxyproject/galaxy/pull/2017
|
||||
.. _Pull Request 2018: https://github.com/galaxyproject/galaxy/pull/2018
|
||||
.. _Pull Request 2019: https://github.com/galaxyproject/galaxy/pull/2019
|
||||
.. _Pull Request 2020: https://github.com/galaxyproject/galaxy/pull/2020
|
||||
.. _Pull Request 2021: https://github.com/galaxyproject/galaxy/pull/2021
|
||||
.. _Pull Request 2022: https://github.com/galaxyproject/galaxy/pull/2022
|
||||
.. _Pull Request 2025: https://github.com/galaxyproject/galaxy/pull/2025
|
||||
.. _Pull Request 2026: https://github.com/galaxyproject/galaxy/pull/2026
|
||||
.. _Pull Request 2027: https://github.com/galaxyproject/galaxy/pull/2027
|
||||
.. _Pull Request 2028: https://github.com/galaxyproject/galaxy/pull/2028
|
||||
.. _Pull Request 2029: https://github.com/galaxyproject/galaxy/pull/2029
|
||||
.. _Pull Request 2030: https://github.com/galaxyproject/galaxy/pull/2030
|
||||
.. _Pull Request 2031: https://github.com/galaxyproject/galaxy/pull/2031
|
||||
.. _Pull Request 2033: https://github.com/galaxyproject/galaxy/pull/2033
|
||||
.. _Pull Request 2039: https://github.com/galaxyproject/galaxy/pull/2039
|
||||
.. _Pull Request 2040: https://github.com/galaxyproject/galaxy/pull/2040
|
||||
.. _Pull Request 2042: https://github.com/galaxyproject/galaxy/pull/2042
|
||||
.. _Pull Request 2044: https://github.com/galaxyproject/galaxy/pull/2044
|
||||
.. _Pull Request 2045: https://github.com/galaxyproject/galaxy/pull/2045
|
||||
.. _Pull Request 2048: https://github.com/galaxyproject/galaxy/pull/2048
|
||||
.. _Pull Request 2052: https://github.com/galaxyproject/galaxy/pull/2052
|
||||
.. _Pull Request 2055: https://github.com/galaxyproject/galaxy/pull/2055
|
||||
.. _Pull Request 2057: https://github.com/galaxyproject/galaxy/pull/2057
|
||||
.. _Pull Request 2060: https://github.com/galaxyproject/galaxy/pull/2060
|
||||
.. _Pull Request 2061: https://github.com/galaxyproject/galaxy/pull/2061
|
||||
.. _Pull Request 2062: https://github.com/galaxyproject/galaxy/pull/2062
|
||||
.. _Pull Request 2063: https://github.com/galaxyproject/galaxy/pull/2063
|
||||
.. _Pull Request 2065: https://github.com/galaxyproject/galaxy/pull/2065
|
||||
.. _Pull Request 2066: https://github.com/galaxyproject/galaxy/pull/2066
|
||||
.. _Pull Request 2067: https://github.com/galaxyproject/galaxy/pull/2067
|
||||
.. _Pull Request 2069: https://github.com/galaxyproject/galaxy/pull/2069
|
||||
.. _Pull Request 2070: https://github.com/galaxyproject/galaxy/pull/2070
|
||||
.. _Pull Request 2071: https://github.com/galaxyproject/galaxy/pull/2071
|
||||
.. _Pull Request 2074: https://github.com/galaxyproject/galaxy/pull/2074
|
||||
.. _Pull Request 2075: https://github.com/galaxyproject/galaxy/pull/2075
|
||||
.. _Pull Request 2078: https://github.com/galaxyproject/galaxy/pull/2078
|
||||
.. _Pull Request 2082: https://github.com/galaxyproject/galaxy/pull/2082
|
||||
.. _Pull Request 2087: https://github.com/galaxyproject/galaxy/pull/2087
|
||||
.. _Pull Request 2088: https://github.com/galaxyproject/galaxy/pull/2088
|
||||
.. _Pull Request 2089: https://github.com/galaxyproject/galaxy/pull/2089
|
||||
.. _Pull Request 2091: https://github.com/galaxyproject/galaxy/pull/2091
|
||||
.. _Pull Request 2092: https://github.com/galaxyproject/galaxy/pull/2092
|
||||
.. _Pull Request 2093: https://github.com/galaxyproject/galaxy/pull/2093
|
||||
.. _Pull Request 2094: https://github.com/galaxyproject/galaxy/pull/2094
|
||||
.. _Pull Request 2096: https://github.com/galaxyproject/galaxy/pull/2096
|
||||
.. _Pull Request 2099: https://github.com/galaxyproject/galaxy/pull/2099
|
||||
.. _Pull Request 2101: https://github.com/galaxyproject/galaxy/pull/2101
|
||||
.. _Pull Request 2102: https://github.com/galaxyproject/galaxy/pull/2102
|
||||
.. _Pull Request 2104: https://github.com/galaxyproject/galaxy/pull/2104
|
||||
.. _Pull Request 2105: https://github.com/galaxyproject/galaxy/pull/2105
|
||||
.. _Pull Request 2106: https://github.com/galaxyproject/galaxy/pull/2106
|
||||
.. _Pull Request 2107: https://github.com/galaxyproject/galaxy/pull/2107
|
||||
.. _Pull Request 2109: https://github.com/galaxyproject/galaxy/pull/2109
|
||||
.. _Pull Request 2118: https://github.com/galaxyproject/galaxy/pull/2118
|
||||
.. _Pull Request 2122: https://github.com/galaxyproject/galaxy/pull/2122
|
||||
.. _Pull Request 2131: https://github.com/galaxyproject/galaxy/pull/2131
|
||||
.. _Pull Request 2133: https://github.com/galaxyproject/galaxy/pull/2133
|
||||
.. _Pull Request 2138: https://github.com/galaxyproject/galaxy/pull/2138
|
||||
.. _Pull Request 2139: https://github.com/galaxyproject/galaxy/pull/2139
|
||||
.. _Pull Request 2141: https://github.com/galaxyproject/galaxy/pull/2141
|
||||
.. _Pull Request 2149: https://github.com/galaxyproject/galaxy/pull/2149
|
||||
.. _Pull Request 2150: https://github.com/galaxyproject/galaxy/pull/2150
|
||||
.. _Pull Request 2154: https://github.com/galaxyproject/galaxy/pull/2154
|
||||
.. _Pull Request 2156: https://github.com/galaxyproject/galaxy/pull/2156
|
||||
.. _Pull Request 2161: https://github.com/galaxyproject/galaxy/pull/2161
|
||||
.. _Pull Request 2164: https://github.com/galaxyproject/galaxy/pull/2164
|
||||
.. _Pull Request 2166: https://github.com/galaxyproject/galaxy/pull/2166
|
||||
.. _Pull Request 2176: https://github.com/galaxyproject/galaxy/pull/2176
|
||||
.. _Pull Request 2180: https://github.com/galaxyproject/galaxy/pull/2180
|
||||
.. _Pull Request 2182: https://github.com/galaxyproject/galaxy/pull/2182
|
||||
.. _Pull Request 2184: https://github.com/galaxyproject/galaxy/pull/2184
|
||||
.. _Pull Request 2186: https://github.com/galaxyproject/galaxy/pull/2186
|
||||
.. _Pull Request 2189: https://github.com/galaxyproject/galaxy/pull/2189
|
||||
.. _Pull Request 2190: https://github.com/galaxyproject/galaxy/pull/2190
|
||||
.. _Pull Request 2191: https://github.com/galaxyproject/galaxy/pull/2191
|
||||
.. _Pull Request 2195: https://github.com/galaxyproject/galaxy/pull/2195
|
||||
.. _Pull Request 2196: https://github.com/galaxyproject/galaxy/pull/2196
|
||||
.. _Pull Request 2197: https://github.com/galaxyproject/galaxy/pull/2197
|
||||
.. _Pull Request 2201: https://github.com/galaxyproject/galaxy/pull/2201
|
||||
.. _Pull Request 2203: https://github.com/galaxyproject/galaxy/pull/2203
|
||||
.. _Pull Request 2204: https://github.com/galaxyproject/galaxy/pull/2204
|
||||
.. _Pull Request 2208: https://github.com/galaxyproject/galaxy/pull/2208
|
||||
.. _Pull Request 2211: https://github.com/galaxyproject/galaxy/pull/2211
|
||||
.. _Pull Request 2214: https://github.com/galaxyproject/galaxy/pull/2214
|
||||
.. _Pull Request 2218: https://github.com/galaxyproject/galaxy/pull/2218
|
||||
.. _Pull Request 2220: https://github.com/galaxyproject/galaxy/pull/2220
|
||||
.. _Pull Request 2227: https://github.com/galaxyproject/galaxy/pull/2227
|
||||
.. _Pull Request 2234: https://github.com/galaxyproject/galaxy/pull/2234
|
||||
.. _Pull Request 2238: https://github.com/galaxyproject/galaxy/pull/2238
|
||||
.. _Pull Request 2255: https://github.com/galaxyproject/galaxy/pull/2255
|
||||
.. _Pull Request 2265: https://github.com/galaxyproject/galaxy/pull/2265
|
||||
.. _Pull Request 2266: https://github.com/galaxyproject/galaxy/pull/2266
|
||||
.. _Pull Request 2282: https://github.com/galaxyproject/galaxy/pull/2282
|
||||
.. _Pull Request 2284: https://github.com/galaxyproject/galaxy/pull/2284
|
||||
.. _Pull Request 2309: https://github.com/galaxyproject/galaxy/pull/2309
|
||||
.. _Pull Request 2311: https://github.com/galaxyproject/galaxy/pull/2311
|
||||
.. _Pull Request 2312: https://github.com/galaxyproject/galaxy/pull/2312
|
||||
.. _Pull Request 2316: https://github.com/galaxyproject/galaxy/pull/2316
|
||||
.. _Pull Request 2317: https://github.com/galaxyproject/galaxy/pull/2317
|
||||
.. _Pull Request 2333: https://github.com/galaxyproject/galaxy/pull/2333
|
||||
.. _Pull Request 2339: https://github.com/galaxyproject/galaxy/pull/2339
|
||||
.. _Pull Request 2345: https://github.com/galaxyproject/galaxy/pull/2345
|
||||
|
||||
@@ -3,8 +3,117 @@
|
||||
April 2016 Galaxy Release (v 16.04)
|
||||
===========================================================
|
||||
|
||||
.. include:: _header.rst
|
||||
|
||||
Schedule
|
||||
Highlights
|
||||
===========================================================
|
||||
* Planned Freeze Date: 2016-04-04
|
||||
* Planned Release Date: 2016-04-25
|
||||
|
||||
**Tool Profile Versions**
|
||||
Tools may now `declare which version <http://planemo.readthedocs.io/en/latest/galaxy_changelog.html#tool-profile-version-pr-1688>`__
|
||||
of Galaxy they require. Tools requiring 16.04 or newer will
|
||||
have new default behaviors (such as using exit code for error detection) that should simplify tool development.
|
||||
See `PR #1688 <https://github.com/galaxyproject/galaxy/pull/1688>`__.
|
||||
|
||||
**Embedded Pulsar Job Runner**
|
||||
Galaxy can now start a Pulsar application embedded within
|
||||
the Galaxy process itself. This allows using Pulsar's
|
||||
job staging and isolation without requiring a RESTful
|
||||
web service or a message queue. This is enabling
|
||||
`usegalaxy.org <https://usegalaxy.org/>`__ to run jobs to
|
||||
on the new `JetStream cloud <http://jetstream-cloud.org/>`__.
|
||||
See `PR #2057 <https://github.com/galaxyproject/galaxy/pull/2057>`__.
|
||||
|
||||
**New chemical datatypes**
|
||||
Galaxy now detects and supports many molecular datatypes. See `Pull Request 1941`_.
|
||||
Thanks to `Björn Grüning (@bgruening) <https://github.com/bgruening>`__.
|
||||
|
||||
|
||||
.. _Pull Request 1941: https://github.com/galaxyproject/galaxy/pull/1941
|
||||
|
||||
`Github <https://github.com/galaxyproject/galaxy>`__
|
||||
===========================================================
|
||||
|
||||
New
|
||||
.. code-block:: shell
|
||||
|
||||
% git clone -b master https://github.com/galaxyproject/galaxy.git
|
||||
|
||||
Update to latest stable release
|
||||
.. code-block:: shell
|
||||
|
||||
% git checkout master && pull --ff-only origin master
|
||||
|
||||
Update to exact version
|
||||
.. code-block:: shell
|
||||
|
||||
% git checkout v16.04
|
||||
|
||||
|
||||
`BitBucket <https://bitbucket.org/galaxy/galaxy-dist>`__
|
||||
===========================================================
|
||||
|
||||
**Note**: Version 16.04 will be the *final* release to be pushed to Bitbucket. More details can be found in the `Deprecation Notices`_ below.
|
||||
|
||||
Upgrade
|
||||
.. code-block:: shell
|
||||
|
||||
% hg pull
|
||||
% hg update latest_16.04
|
||||
|
||||
|
||||
See `our wiki <https://wiki.galaxyproject.org/Develop/SourceCode>`__ for additional details regarding the source code locations.
|
||||
|
||||
Security
|
||||
===========================================================
|
||||
TL;DR
|
||||
**Only Tool Sheds newer than 16.01 should be deployed from now on.**
|
||||
(with commit 449098d8b14b45269be106f6410c0b9145c51d50 from Mar 30 present)
|
||||
|
||||
Due to the security fixes on the Mercurial_ side we had to update the hg version that
|
||||
both Galaxy and TS depend on because the fixes have not been backported to older versions.
|
||||
However this has broken the TS's ``hg push`` functionality as Mercurial changed their bundle
|
||||
format in a non-compatible manner. Given that we deprecated the ``hg push`` API
|
||||
functionality back in the 15.10 we decided to disable it fully from 16.01 (retroactively).
|
||||
|
||||
.. _Mercurial: https://www.mercurial-scm.org/wiki/WhatsNew#Mercurial_3.7.3_.282016-3-29.29
|
||||
|
||||
Deprecation Notices
|
||||
===========================================================
|
||||
|
||||
API deprecations
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
API for history contents, index:
|
||||
* **types**: is no longer a valid parameter but accessible using ``?q=history_content_type&qv=[dataset | dataset_collection]``
|
||||
* **ids**: is no longer a valid url parameter but is accessible using ``?q=type_id-in&qv=<e.g. dataset-abcdef123,dataset_collection-987fedcba, ...>``
|
||||
* **deleted** and **visible**: are no longer parameters but are still accessible using ``q=deleted&qv=[True | False]&q=visible&qv=[True | False]``
|
||||
|
||||
API for history contents, show:
|
||||
* **api_type**: removed and unavailable (was :code:`file` and constant across HDAs)
|
||||
* **display_apps**, **display_types**, **visualization**: removed from the default :code:`detailed` view but still available by calling url with ``?keys=display_apps,display_types,visualization``
|
||||
|
||||
API histories (removed from the available serialized data on all calls):
|
||||
* **state, state_details, state_ids** - can be replaced by specifically requesting a single array of contents, each containing :code:`{ id, state, deleted, visible }`
|
||||
|
||||
Galaxy no longer on Bitbucket
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Galaxy moved its code and development activities from Bitbucket to GitHub in early 2015. Since this time, releases have been mirrored back to Bitbucket. However, after this release, no new changes will be pushed to Bitbucket. Anyone still receiving updates to a Galaxy server via Bitbucket and Mercurial should switch to GitHub and Git. This can be done using the following process:
|
||||
|
||||
1. Backup everything.
|
||||
2. Find what branch and commit your Mercurial Galaxy is at using :code:`hg log -b $(hg branch)`
|
||||
3. :code:`git clone https://github.com/galaxyproject/galaxy` in a temporary directory.
|
||||
4. Find the corresponding commit in the cloned Git repository on the corresponding branch (Bitbucket default->GitHub dev; Bitbucket stable->GitHub master).
|
||||
5. Checkout the GitHub repository at the commit you found in the previous step.
|
||||
6. Backup your .hg/ folder.
|
||||
7. Replace your .hg/ folder with the .git/ folder from the new checkout.
|
||||
8. Your Galaxy should be switched to Git. Unless you have local changes, git status should show none.
|
||||
9. You can now update to the latest Git revision using :code:`git pull`
|
||||
|
||||
Release Notes
|
||||
===========================================================
|
||||
|
||||
.. include:: 16.04.rst
|
||||
:start-after: announce_start
|
||||
|
||||
.. include:: _thanks.rst
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
===========================================================
|
||||
July 2016 Galaxy Release (v 16.07)
|
||||
===========================================================
|
||||
|
||||
|
||||
Schedule
|
||||
===========================================================
|
||||
* Planned Freeze Date: 2016-07-04
|
||||
* Planned Release Date: 2016-07-25
|
||||
@@ -4,7 +4,7 @@ Releases
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
.. annoucements
|
||||
16.07_announce
|
||||
16.04_announce
|
||||
16.01_announce
|
||||
15.10_announce
|
||||
|
||||
@@ -135,7 +135,7 @@ class LDAP(AuthProvider):
|
||||
|
||||
# parse results
|
||||
if suser is None or len(suser) == 0:
|
||||
log.warn('LDAP authenticate: search returned no results')
|
||||
log.warning('LDAP authenticate: search returned no results')
|
||||
return (failure_mode, '', '')
|
||||
dn, attrs = suser[0]
|
||||
log.debug(("LDAP authenticate: dn is %s" % dn))
|
||||
@@ -169,7 +169,7 @@ class LDAP(AuthProvider):
|
||||
if whoami is None:
|
||||
raise RuntimeError('LDAP authenticate: anonymous bind')
|
||||
except Exception:
|
||||
log.warn('LDAP authenticate: bind exception', exc_info=True)
|
||||
log.warning('LDAP authenticate: bind exception', exc_info=True)
|
||||
return (failure_mode, '', '')
|
||||
|
||||
log.debug('LDAP authentication successful')
|
||||
|
||||
+19
-12
@@ -4,7 +4,6 @@ Universe configuration builder.
|
||||
# absolute_import needed for tool_shed package.
|
||||
from __future__ import absolute_import
|
||||
|
||||
import ConfigParser
|
||||
import logging
|
||||
import logging.config
|
||||
import os
|
||||
@@ -16,7 +15,9 @@ import sys
|
||||
import tempfile
|
||||
import threading
|
||||
from datetime import timedelta
|
||||
|
||||
from six import string_types
|
||||
from six.moves import configparser
|
||||
|
||||
from galaxy.exceptions import ConfigurationError
|
||||
from galaxy.util import listify
|
||||
@@ -57,7 +58,7 @@ class Configuration( object ):
|
||||
self.__parse_config_file_options( kwargs )
|
||||
|
||||
# Collect the umask and primary gid from the environment
|
||||
self.umask = os.umask( 077 ) # get the current umask
|
||||
self.umask = os.umask( 0o77 ) # get the current umask
|
||||
os.umask( self.umask ) # can't get w/o set, so set it back
|
||||
self.gid = os.getgid() # if running under newgrp(1) we'll need to fix the group of data created on the cluster
|
||||
|
||||
@@ -310,8 +311,13 @@ class Configuration( object ):
|
||||
self.tool_help_boost = kwargs.get( "tool_help_boost", 0.5 )
|
||||
self.tool_search_limit = kwargs.get( "tool_search_limit", 20 )
|
||||
# Location for tool dependencies.
|
||||
if 'tool_dependency_dir' in kwargs:
|
||||
self.tool_dependency_dir = resolve_path( kwargs.get( "tool_dependency_dir" ), self.root )
|
||||
# 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.
|
||||
@@ -356,7 +362,7 @@ class Configuration( object ):
|
||||
self.irods_default_resource = kwargs.get( 'irods_default_resource', None )
|
||||
# Parse global_conf and save the parser
|
||||
global_conf = kwargs.get( 'global_conf', None )
|
||||
global_conf_parser = ConfigParser.ConfigParser()
|
||||
global_conf_parser = configparser.ConfigParser()
|
||||
self.config_file = None
|
||||
self.global_conf_parser = global_conf_parser
|
||||
if global_conf and "__file__" in global_conf:
|
||||
@@ -415,7 +421,7 @@ class Configuration( object ):
|
||||
self.amqp = {}
|
||||
try:
|
||||
amqp_config = global_conf_parser.items("galaxy_amqp")
|
||||
except ConfigParser.NoSectionError:
|
||||
except configparser.NoSectionError:
|
||||
amqp_config = {}
|
||||
for k, v in amqp_config:
|
||||
self.amqp[k] = v
|
||||
@@ -613,7 +619,7 @@ class Configuration( object ):
|
||||
rval[ tool ].append( runner_dict )
|
||||
|
||||
return rval
|
||||
except ConfigParser.NoSectionError:
|
||||
except configparser.NoSectionError:
|
||||
return {}
|
||||
|
||||
def get( self, key, default ):
|
||||
@@ -632,7 +638,7 @@ class Configuration( object ):
|
||||
if path not in [ None, False ] and not os.path.isdir( path ):
|
||||
try:
|
||||
os.makedirs( path )
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
raise ConfigurationError( "Unable to create missing directory: %s\n%s" % ( path, e ) )
|
||||
|
||||
def check( self ):
|
||||
@@ -642,7 +648,7 @@ class Configuration( object ):
|
||||
if path not in [ None, False ] and not os.path.isdir( path ):
|
||||
try:
|
||||
os.makedirs( path )
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
raise ConfigurationError( "Unable to create missing directory: %s\n%s" % ( path, e ) )
|
||||
# Create the directories that it makes sense to create
|
||||
if self.object_store_config_file is None:
|
||||
@@ -685,7 +691,7 @@ class Configuration( object ):
|
||||
|
||||
def guess_galaxy_port(self):
|
||||
# Code derived from IPython work ie.mako
|
||||
config = ConfigParser.SafeConfigParser({'port': '8080'})
|
||||
config = configparser.SafeConfigParser({'port': '8080'})
|
||||
if self.config_file:
|
||||
config.read( self.config_file )
|
||||
|
||||
@@ -734,7 +740,7 @@ def get_database_engine_options( kwargs, model_prefix='' ):
|
||||
prefix = "%sdatabase_engine_option_" % model_prefix
|
||||
prefix_len = len( prefix )
|
||||
rval = {}
|
||||
for key, value in kwargs.iteritems():
|
||||
for key, value in kwargs.items():
|
||||
if key.startswith( prefix ):
|
||||
key = key[prefix_len:]
|
||||
if key in conversions:
|
||||
@@ -822,10 +828,11 @@ class ConfiguresGalaxyMixin:
|
||||
galaxy_root_dir = os.path.abspath(self.config.root)
|
||||
file_path = os.path.abspath(getattr(self.config, "file_path"))
|
||||
app_info = containers.AppInfo(
|
||||
galaxy_root_dir,
|
||||
galaxy_root_dir=galaxy_root_dir,
|
||||
default_file_path=file_path,
|
||||
outputs_to_working_directory=self.config.outputs_to_working_directory,
|
||||
container_image_cache_path=self.config.container_image_cache_path,
|
||||
library_import_dir=self.config.library_import_dir
|
||||
)
|
||||
self.container_finder = containers.ContainerFinder(app_info)
|
||||
|
||||
|
||||
@@ -19,7 +19,8 @@ log = logging.getLogger(__name__)
|
||||
|
||||
class Amos( data.Text ):
|
||||
"""Class describing the AMOS assembly file """
|
||||
edam_format = "format_2561"
|
||||
edam_data = "data_0925"
|
||||
edam_format = "format_3582"
|
||||
file_ext = 'afg'
|
||||
|
||||
def sniff( self, filename ):
|
||||
@@ -68,11 +69,12 @@ class Amos( data.Text ):
|
||||
|
||||
class Sequences( sequence.Fasta ):
|
||||
"""Class describing the Sequences file generated by velveth """
|
||||
edam_data = "data_0925"
|
||||
|
||||
def sniff( self, filename ):
|
||||
"""
|
||||
Determines whether the file is a velveth produced fasta format
|
||||
The id line has 3 fields separated by tabs: sequence_name sequence_index cataegory::
|
||||
The id line has 3 fields separated by tabs: sequence_name sequence_index category::
|
||||
|
||||
>SEQUENCE_0_length_35 1 1
|
||||
GGATATAGGGCCAACCCAACTCAACGGCCTGTCTT
|
||||
@@ -218,10 +220,9 @@ class Velvet( Html ):
|
||||
else:
|
||||
rval.append( '<li><a href="%s" type="text/plain">%s</a>%s</li>' % ( fn, fn, opt_text ) )
|
||||
rval.append( '</ul></div></html>' )
|
||||
f = file(dataset.file_name, 'w')
|
||||
f.write("\n".join( rval ))
|
||||
f.write('\n')
|
||||
f.close()
|
||||
with open(dataset.file_name, 'w') as f:
|
||||
f.write("\n".join( rval ))
|
||||
f.write('\n')
|
||||
|
||||
def set_meta( self, dataset, **kwd ):
|
||||
Html.set_meta( self, dataset, **kwd )
|
||||
|
||||
@@ -87,6 +87,8 @@ class Binary( data.Data ):
|
||||
class Ab1( Binary ):
|
||||
"""Class describing an ab1 binary sequence file"""
|
||||
file_ext = "ab1"
|
||||
edam_format = "format_3000"
|
||||
edam_data = "data_0924"
|
||||
|
||||
def set_peek( self, dataset, is_multi_byte=False ):
|
||||
if not dataset.dataset.purged:
|
||||
@@ -108,6 +110,8 @@ Binary.register_unsniffable_binary_ext("ab1")
|
||||
class Idat( Binary ):
|
||||
"""Binary data in idat format"""
|
||||
file_ext = "idat"
|
||||
edam_format = "format_2058"
|
||||
edam_data = "data_2603"
|
||||
|
||||
def sniff( self, filename ):
|
||||
try:
|
||||
@@ -174,6 +178,8 @@ Binary.register_unsniffable_binary_ext("zip")
|
||||
class GenericAsn1Binary( Binary ):
|
||||
"""Class for generic ASN.1 binary format"""
|
||||
file_ext = "asn1-binary"
|
||||
edam_format = "format_1966"
|
||||
edam_data = "data_0849"
|
||||
|
||||
Binary.register_unsniffable_binary_ext("asn1-binary")
|
||||
|
||||
@@ -182,6 +188,7 @@ Binary.register_unsniffable_binary_ext("asn1-binary")
|
||||
class Bam( Binary ):
|
||||
"""Class describing a BAM binary file"""
|
||||
edam_format = "format_2572"
|
||||
edam_data = "data_0863"
|
||||
file_ext = "bam"
|
||||
track_type = "ReadTrack"
|
||||
data_sources = { "data": "bai", "index": "bigwig" }
|
||||
@@ -489,6 +496,7 @@ Binary.register_sniffable_binary_format("bam", "bam", Bam)
|
||||
class CRAM( Binary ):
|
||||
file_ext = "cram"
|
||||
edam_format = "format_3462"
|
||||
edam_data = "format_0863"
|
||||
|
||||
MetadataElement( name="cram_version", default=None, desc="CRAM Version", param=MetadataParameter, readonly=True, visible=False, optional=False, no_value=None )
|
||||
MetadataElement( name="cram_index", desc="CRAM Index File", param=metadata.FileParameter, file_ext="crai", readonly=True, no_value=None, visible=False, optional=True )
|
||||
@@ -505,11 +513,11 @@ class CRAM( Binary ):
|
||||
|
||||
def get_cram_version( self, filename):
|
||||
try:
|
||||
with open( filename , "r") as fh:
|
||||
with open( filename, "r") as fh:
|
||||
header = fh.read(6)
|
||||
return ord( header[4] ), ord( header[5] )
|
||||
except Exception as exc:
|
||||
log.warn( '%s, get_cram_version Exception: %s', self, exc )
|
||||
log.warning( '%s, get_cram_version Exception: %s', self, exc )
|
||||
return -1, -1
|
||||
|
||||
def set_index_file(self, dataset, index_file):
|
||||
@@ -530,10 +538,10 @@ class CRAM( Binary ):
|
||||
return index_file.file_name
|
||||
else:
|
||||
os.unlink( dataset_symlink )
|
||||
log.warn( '%s, expected crai index not created for: %s', self, dataset.file_name )
|
||||
log.warning( '%s, expected crai index not created for: %s', self, dataset.file_name )
|
||||
return False
|
||||
except Exception as exc:
|
||||
log.warn( '%s, set_index_file Exception: %s', self, exc )
|
||||
log.warning( '%s, set_index_file Exception: %s', self, exc )
|
||||
return False
|
||||
|
||||
def set_peek( self, dataset, is_multi_byte=False ):
|
||||
@@ -559,6 +567,7 @@ Binary.register_sniffable_binary_format('cram', 'cram', CRAM)
|
||||
class Bcf( Binary):
|
||||
"""Class describing a BCF file"""
|
||||
edam_format = "format_3020"
|
||||
edam_data = "data_3498"
|
||||
file_ext = "bcf"
|
||||
|
||||
MetadataElement( name="bcf_index", desc="BCF Index File", param=metadata.FileParameter, file_ext="csi", readonly=True, no_value=None, visible=False, optional=True )
|
||||
@@ -618,6 +627,7 @@ class H5( Binary ):
|
||||
False
|
||||
"""
|
||||
file_ext = "h5"
|
||||
edam_format = "format_3590"
|
||||
|
||||
def __init__( self, **kwd ):
|
||||
Binary.__init__( self, **kwd )
|
||||
@@ -653,6 +663,7 @@ Binary.register_sniffable_binary_format("h5", "h5", H5)
|
||||
class Scf( Binary ):
|
||||
"""Class describing an scf binary sequence file"""
|
||||
edam_format = "format_1632"
|
||||
edam_data = "data_0924"
|
||||
file_ext = "scf"
|
||||
|
||||
def set_peek( self, dataset, is_multi_byte=False ):
|
||||
@@ -675,6 +686,7 @@ Binary.register_unsniffable_binary_ext("scf")
|
||||
class Sff( Binary ):
|
||||
""" Standard Flowgram Format (SFF) """
|
||||
edam_format = "format_3284"
|
||||
edam_data = "data_0924"
|
||||
file_ext = "sff"
|
||||
|
||||
def sniff( self, filename ):
|
||||
@@ -712,6 +724,7 @@ class BigWig(Binary):
|
||||
http://bioinformatics.oxfordjournals.org/cgi/content/abstract/btq351v1
|
||||
"""
|
||||
edam_format = "format_3006"
|
||||
edam_data = "data_3002"
|
||||
track_type = "LineTrack"
|
||||
data_sources = { "data_standalone": "bigwig" }
|
||||
|
||||
@@ -750,6 +763,7 @@ Binary.register_sniffable_binary_format("bigwig", "bigwig", BigWig)
|
||||
class BigBed(BigWig):
|
||||
"""BigBed support from UCSC."""
|
||||
edam_format = "format_3004"
|
||||
edam_data = "data_3002"
|
||||
data_sources = { "data_standalone": "bigbed" }
|
||||
|
||||
def __init__( self, **kwd ):
|
||||
@@ -763,6 +777,7 @@ Binary.register_sniffable_binary_format("bigbed", "bigbed", BigBed)
|
||||
class TwoBit (Binary):
|
||||
"""Class describing a TwoBit format nucleotide file"""
|
||||
edam_format = "format_3009"
|
||||
edam_data = "data_0848"
|
||||
file_ext = "twobit"
|
||||
|
||||
def sniff(self, filename):
|
||||
@@ -770,7 +785,7 @@ class TwoBit (Binary):
|
||||
# All twobit files start with a 16-byte header. If the file is smaller than 16 bytes, it's obviously not a valid twobit file.
|
||||
if os.path.getsize(filename) < 16:
|
||||
return False
|
||||
input = file(filename)
|
||||
input = open(filename)
|
||||
magic = struct.unpack(">L", input.read(TWOBIT_MAGIC_SIZE))[0]
|
||||
if magic == TWOBIT_MAGIC_NUMBER or magic == TWOBIT_MAGIC_NUMBER_SWAP:
|
||||
return True
|
||||
@@ -800,6 +815,7 @@ class SQlite ( Binary ):
|
||||
MetadataElement( name="table_columns", default={}, param=DictParameter, desc="Database Table Columns", readonly=True, visible=True, no_value={} )
|
||||
MetadataElement( name="table_row_count", default={}, param=DictParameter, desc="Database Table Row Count", readonly=True, visible=True, no_value={} )
|
||||
file_ext = "sqlite"
|
||||
edam_format = "format_3621"
|
||||
|
||||
def init_meta( self, dataset, copy_from=None ):
|
||||
Binary.init_meta( self, dataset, copy_from=copy_from )
|
||||
@@ -821,18 +837,18 @@ class SQlite ( Binary ):
|
||||
cols = [col[0] for col in cur.description]
|
||||
columns[table] = cols
|
||||
except Exception as exc:
|
||||
log.warn( '%s, set_meta Exception: %s', self, exc )
|
||||
log.warning( '%s, set_meta Exception: %s', self, exc )
|
||||
for table in tables:
|
||||
try:
|
||||
row_query = "SELECT count(*) FROM %s" % table
|
||||
rowcounts[table] = c.execute(row_query).fetchone()[0]
|
||||
except Exception as exc:
|
||||
log.warn( '%s, set_meta Exception: %s', self, exc )
|
||||
log.warning( '%s, set_meta Exception: %s', self, exc )
|
||||
dataset.metadata.tables = tables
|
||||
dataset.metadata.table_columns = columns
|
||||
dataset.metadata.table_row_count = rowcounts
|
||||
except Exception as exc:
|
||||
log.warn( '%s, set_meta Exception: %s', self, exc )
|
||||
log.warning( '%s, set_meta Exception: %s', self, exc )
|
||||
|
||||
def sniff( self, filename ):
|
||||
# The first 16 bytes of any SQLite3 database file is 'SQLite format 3\0', and the file is binary. For details
|
||||
@@ -888,9 +904,11 @@ class SQlite ( Binary ):
|
||||
|
||||
class GeminiSQLite( SQlite ):
|
||||
"""Class describing a Gemini Sqlite database """
|
||||
MetadataElement( name="gemini_version", default='0.10.0' , param=MetadataParameter, desc="Gemini Version",
|
||||
MetadataElement( name="gemini_version", default='0.10.0', param=MetadataParameter, desc="Gemini Version",
|
||||
readonly=True, visible=True, no_value='0.10.0' )
|
||||
file_ext = "gemini.sqlite"
|
||||
edam_format = "format_3622"
|
||||
edam_data = "data_3498"
|
||||
|
||||
def set_meta( self, dataset, overwrite=True, **kwd ):
|
||||
super( GeminiSQLite, self ).set_meta( dataset, overwrite=overwrite, **kwd )
|
||||
@@ -903,7 +921,7 @@ class GeminiSQLite( SQlite ):
|
||||
dataset.metadata.gemini_version = version
|
||||
# TODO: Can/should we detect even more attributes, such as use of PED file, what was input annotation type, etc.
|
||||
except Exception as e:
|
||||
log.warn( '%s, set_meta Exception: %s', self, e )
|
||||
log.warning( '%s, set_meta Exception: %s', self, e )
|
||||
|
||||
def sniff( self, filename ):
|
||||
if super( GeminiSQLite, self ).sniff( filename ):
|
||||
@@ -920,7 +938,7 @@ class GeminiSQLite( SQlite ):
|
||||
return False
|
||||
return True
|
||||
except Exception as e:
|
||||
log.warn( '%s, sniff Exception: %s', self, e )
|
||||
log.warning( '%s, sniff Exception: %s', self, e )
|
||||
return False
|
||||
|
||||
def set_peek( self, dataset, is_multi_byte=False ):
|
||||
@@ -958,8 +976,8 @@ class MzSQlite( SQlite ):
|
||||
if table_name not in result:
|
||||
return False
|
||||
return True
|
||||
except Exception, e:
|
||||
log.warn( '%s, sniff Exception: %s', self, e )
|
||||
except Exception as e:
|
||||
log.warning( '%s, sniff Exception: %s', self, e )
|
||||
return False
|
||||
|
||||
|
||||
@@ -993,8 +1011,8 @@ class IdpDB( SQlite ):
|
||||
if table_name not in result:
|
||||
return False
|
||||
return True
|
||||
except Exception, e:
|
||||
log.warn( '%s, sniff Exception: %s', self, e )
|
||||
except Exception as e:
|
||||
log.warning( '%s, sniff Exception: %s', self, e )
|
||||
return False
|
||||
|
||||
def set_peek( self, dataset, is_multi_byte=False ):
|
||||
@@ -1253,9 +1271,9 @@ Binary.register_sniffable_binary_format("oxli.graphlabels", "oxligl",
|
||||
|
||||
class SearchGuiArchive ( CompressedArchive ):
|
||||
"""Class describing a SearchGUI archive """
|
||||
MetadataElement( name="searchgui_version", default='1.28.0' , param=MetadataParameter, desc="SearchGui Version",
|
||||
MetadataElement( name="searchgui_version", default='1.28.0', param=MetadataParameter, desc="SearchGui Version",
|
||||
readonly=True, visible=True, no_value=None )
|
||||
MetadataElement( name="searchgui_major_version", default='1' , param=MetadataParameter, desc="SearchGui Major Version",
|
||||
MetadataElement( name="searchgui_major_version", default='1', param=MetadataParameter, desc="SearchGui Major Version",
|
||||
readonly=True, visible=True, no_value=None )
|
||||
file_ext = "searchgui_archive"
|
||||
|
||||
@@ -1274,7 +1292,7 @@ class SearchGuiArchive ( CompressedArchive ):
|
||||
fh.close()
|
||||
tempzip.close()
|
||||
except Exception as e:
|
||||
log.warn( '%s, set_meta Exception: %s', self, e )
|
||||
log.warning( '%s, set_meta Exception: %s', self, e )
|
||||
|
||||
def sniff( self, filename ):
|
||||
try:
|
||||
@@ -1284,7 +1302,7 @@ class SearchGuiArchive ( CompressedArchive ):
|
||||
tempzip.close()
|
||||
return is_searchgui
|
||||
except Exception as e:
|
||||
log.warn( '%s, sniff Exception: %s', self, e )
|
||||
log.warning( '%s, sniff Exception: %s', self, e )
|
||||
return False
|
||||
|
||||
def set_peek( self, dataset, is_multi_byte=False ):
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
"""Module proxies :module:`galaxy.util.checkers` for backward compatibility.
|
||||
|
||||
External datatypes may make use of these functions.
|
||||
"""
|
||||
from galaxy.util.checkers import (
|
||||
check_binary,
|
||||
check_bz2,
|
||||
check_gzip,
|
||||
check_html,
|
||||
check_image,
|
||||
check_zip,
|
||||
is_gzip,
|
||||
is_bz2,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
'check_binary',
|
||||
'check_bz2',
|
||||
'check_gzip',
|
||||
'check_html',
|
||||
'check_image',
|
||||
'check_zip',
|
||||
'is_gzip',
|
||||
'is_bz2',
|
||||
]
|
||||
@@ -14,7 +14,7 @@ def __main__():
|
||||
out.write( "##gff-version 2\n" )
|
||||
out.write( "##bed_to_gff_converter.py\n\n" )
|
||||
i = 0
|
||||
for i, line in enumerate( file( input_name ) ):
|
||||
for i, line in enumerate( open( input_name ) ):
|
||||
complete_bed = False
|
||||
line = line.rstrip( '\r\n' )
|
||||
if line and not line.startswith( '#' ) and not line.startswith( 'track' ) and not line.startswith( 'browser' ):
|
||||
|
||||
@@ -29,7 +29,7 @@ def __main__():
|
||||
fastq_block_lines = 0
|
||||
seq_title_startswith = ''
|
||||
|
||||
for i, line in enumerate( file( infile_name ) ):
|
||||
for i, line in enumerate( open( infile_name ) ):
|
||||
line = line.rstrip() # eliminate trailing space and new line characters
|
||||
if not line or line.startswith( '#' ):
|
||||
continue
|
||||
|
||||
@@ -32,7 +32,7 @@ def __main__():
|
||||
default_coding_value = 64
|
||||
fastq_block_lines = 0
|
||||
|
||||
for i, line in enumerate( file( infile_name ) ):
|
||||
for i, line in enumerate( open( infile_name ) ):
|
||||
line = line.rstrip()
|
||||
if not line or line.startswith( '#' ):
|
||||
continue
|
||||
|
||||
@@ -11,7 +11,7 @@ def __main__():
|
||||
first_skipped_line = 0
|
||||
out = open( output_name, 'w' )
|
||||
i = 0
|
||||
for i, line in enumerate( file( input_name ) ):
|
||||
for i, line in enumerate( open( input_name ) ):
|
||||
line = line.rstrip( '\r\n' )
|
||||
if line and not line.startswith( '#' ):
|
||||
try:
|
||||
|
||||
@@ -40,7 +40,7 @@ def rgConv(inpedfilepath, outhtmlname, outfilepath):
|
||||
outf = '%s.ped' % basename # note the fbat exe insists that this is the extension for the ped data
|
||||
outfpath = os.path.join(outfilepath, outf) # where to write the fbat format file to
|
||||
try:
|
||||
mf = file(inmap, 'r')
|
||||
mf = open(inmap, 'r')
|
||||
except:
|
||||
sys.stderr.write('%s cannot open inmap file %s - do you have permission?\n' % (prog, inmap))
|
||||
sys.exit(1)
|
||||
@@ -55,8 +55,8 @@ def rgConv(inpedfilepath, outhtmlname, outfilepath):
|
||||
pass # already exists
|
||||
head = ' '.join(rsl) # list of rs numbers
|
||||
# TODO add anno to rs but fbat will prolly barf?
|
||||
pedf = file(inped, 'r')
|
||||
o = file(outfpath, 'w', 2 ** 20)
|
||||
pedf = open(inped, 'r')
|
||||
o = open(outfpath, 'w', 2 ** 20)
|
||||
o.write(head)
|
||||
o.write('\n')
|
||||
for i, row in enumerate(pedf):
|
||||
@@ -97,15 +97,14 @@ def main():
|
||||
except:
|
||||
pass
|
||||
rgConv(inpedfilepath, outhtmlname, outfilepath)
|
||||
f = file(outhtmlname, 'w')
|
||||
f.write(galhtmlprefix % prog)
|
||||
flist = os.listdir(outfilepath)
|
||||
print '## Rgenetics: http://rgenetics.org Galaxy Tools %s %s' % (prog, timenow()) # becomes info
|
||||
f.write('<div>## Rgenetics: http://rgenetics.org Galaxy Tools %s %s\n<ol>' % (prog, timenow()))
|
||||
for i, data in enumerate( flist ):
|
||||
f.write('<li><a href="%s">%s</a></li>\n' % (os.path.split(data)[-1], os.path.split(data)[-1]))
|
||||
f.write("</div></body></html>")
|
||||
f.close()
|
||||
with open(outhtmlname, 'w') as f:
|
||||
f.write(galhtmlprefix % prog)
|
||||
print '## Rgenetics: http://rgenetics.org Galaxy Tools %s %s' % (prog, timenow()) # becomes info
|
||||
f.write('<div>## Rgenetics: http://rgenetics.org Galaxy Tools %s %s\n<ol>' % (prog, timenow()))
|
||||
for i, data in enumerate( flist ):
|
||||
f.write('<li><a href="%s">%s</a></li>\n' % (os.path.split(data)[-1], os.path.split(data)[-1]))
|
||||
f.write("</div></body></html>")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -39,7 +39,7 @@ def getMissval(inped=''):
|
||||
"""
|
||||
commonmissvals = {'N': 'N', '0': '0', 'n': 'n', '9': '9', '-': '-', '.': '.'}
|
||||
try:
|
||||
f = file(inped, 'r')
|
||||
f = open(inped, 'r')
|
||||
except:
|
||||
return None # signal no in file
|
||||
missval = None
|
||||
@@ -96,16 +96,15 @@ def main():
|
||||
pass
|
||||
plink = sys.argv[4]
|
||||
rgConv(inpedfilepath, outhtmlname, outfilepath, plink)
|
||||
f = file(outhtmlname, 'w')
|
||||
f.write(galhtmlprefix % prog)
|
||||
flist = os.listdir(outfilepath)
|
||||
s = '## Rgenetics: http://rgenetics.org Galaxy Tools %s %s' % (prog, timenow()) # becomes info
|
||||
print s
|
||||
f.write('<div>%s\n<ol>' % (s))
|
||||
for i, data in enumerate( flist ):
|
||||
f.write('<li><a href="%s">%s</a></li>\n' % (os.path.split(data)[-1], os.path.split(data)[-1]))
|
||||
f.write("</ol></div></div></body></html>")
|
||||
f.close()
|
||||
with open(outhtmlname, 'w') as f:
|
||||
f.write(galhtmlprefix % prog)
|
||||
s = '## Rgenetics: http://rgenetics.org Galaxy Tools %s %s' % (prog, timenow()) # becomes info
|
||||
print s
|
||||
f.write('<div>%s\n<ol>' % (s))
|
||||
for i, data in enumerate( flist ):
|
||||
f.write('<li><a href="%s">%s</a></li>\n' % (os.path.split(data)[-1], os.path.split(data)[-1]))
|
||||
f.write("</ol></div></div></body></html>")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -40,12 +40,11 @@ def pruneLD(plinktasks=[], cd='./', vclbase=[]):
|
||||
alog.append('## Rgenetics: http://rgenetics.org Galaxy Tools rgQC.py Plink pruneLD runner\n')
|
||||
for task in plinktasks: # each is a list
|
||||
vcl = vclbase + task
|
||||
sto = file(plog, 'w')
|
||||
x = subprocess.Popen(' '.join(vcl), shell=True, stdout=sto, stderr=sto, cwd=cd)
|
||||
x.wait()
|
||||
sto.close()
|
||||
with open(plog, 'w') as sto:
|
||||
x = subprocess.Popen(' '.join(vcl), shell=True, stdout=sto, stderr=sto, cwd=cd)
|
||||
x.wait()
|
||||
try:
|
||||
lplog = file(plog, 'r').readlines()
|
||||
lplog = open(plog, 'r').readlines()
|
||||
lplog = [elem for elem in lplog if elem.find('Pruning SNP') == -1]
|
||||
alog += lplog
|
||||
alog.append('\n')
|
||||
@@ -100,17 +99,16 @@ def main():
|
||||
plink = sys.argv[7]
|
||||
makeLDreduced(base_name, infpath=inpedfilepath, outfpath=outfilepath, plinke=plink, forcerebuild=False, returnFname=False,
|
||||
winsize=winsize, winmove=winmove, r2thresh=r2thresh)
|
||||
f = file(outhtmlname, 'w')
|
||||
f.write(galhtmlprefix % prog)
|
||||
flist = os.listdir(outfilepath)
|
||||
s1 = '## Rgenetics: http://rgenetics.org Galaxy Tools %s %s' % (prog, timenow()) # becomes info
|
||||
s2 = 'Input %s, winsize=%s, winmove=%s, r2thresh=%s' % (base_name, winsize, winmove, r2thresh)
|
||||
print '%s %s' % (s1, s2)
|
||||
f.write('<div>%s\n%s\n<ol>' % (s1, s2))
|
||||
for i, data in enumerate( flist ):
|
||||
f.write('<li><a href="%s">%s</a></li>\n' % (os.path.split(data)[-1], os.path.split(data)[-1]))
|
||||
f.write("</div></body></html>")
|
||||
f.close()
|
||||
with open(outhtmlname, 'w') as f:
|
||||
f.write(galhtmlprefix % prog)
|
||||
s1 = '## Rgenetics: http://rgenetics.org Galaxy Tools %s %s' % (prog, timenow()) # becomes info
|
||||
s2 = 'Input %s, winsize=%s, winmove=%s, r2thresh=%s' % (base_name, winsize, winmove, r2thresh)
|
||||
print '%s %s' % (s1, s2)
|
||||
f.write('<div>%s\n%s\n<ol>' % (s1, s2))
|
||||
for i, data in enumerate( flist ):
|
||||
f.write('<li><a href="%s">%s</a></li>\n' % (os.path.split(data)[-1], os.path.split(data)[-1]))
|
||||
f.write("</div></body></html>")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -64,16 +64,15 @@ def main():
|
||||
pass
|
||||
plink = sys.argv[4]
|
||||
rgConv(inpedfilepath, outhtmlname, outfilepath, plink)
|
||||
f = file(outhtmlname, 'w')
|
||||
f.write(galhtmlprefix % prog)
|
||||
flist = os.listdir(outfilepath)
|
||||
s = '## Rgenetics: http://bitbucket.org/rgalaxy Galaxy Tools %s %s' % (prog, timenow()) # becomes info
|
||||
print s
|
||||
f.write('<div>%s\n<ol>' % (s))
|
||||
for i, data in enumerate( flist ):
|
||||
f.write('<li><a href="%s">%s</a></li>\n' % (os.path.split(data)[-1], os.path.split(data)[-1]))
|
||||
f.write("</ol></div></div></body></html>")
|
||||
f.close()
|
||||
with open(outhtmlname, 'w') as f:
|
||||
f.write(galhtmlprefix % prog)
|
||||
s = '## Rgenetics: http://bitbucket.org/rgalaxy Galaxy Tools %s %s' % (prog, timenow()) # becomes info
|
||||
print s
|
||||
f.write('<div>%s\n<ol>' % (s))
|
||||
for i, data in enumerate( flist ):
|
||||
f.write('<li><a href="%s">%s</a></li>\n' % (os.path.split(data)[-1], os.path.split(data)[-1]))
|
||||
f.write("</ol></div></div></body></html>")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -64,6 +64,7 @@ class Data( object ):
|
||||
<class 'galaxy.model.metadata.MetadataParameter'>
|
||||
|
||||
"""
|
||||
edam_data = "data_0006"
|
||||
edam_format = "format_1915"
|
||||
# Data is not chunkable by default.
|
||||
CHUNKABLE = False
|
||||
@@ -123,7 +124,7 @@ class Data( object ):
|
||||
def get_raw_data( self, dataset ):
|
||||
"""Returns the full data. To stream it open the file_name and read/write as needed"""
|
||||
try:
|
||||
return file(dataset.file_name, 'rb').read(-1)
|
||||
return open(dataset.file_name, 'rb').read(-1)
|
||||
except OSError:
|
||||
log.exception('%s reading a file that does not exist %s' % (self.__class__.__name__, dataset.file_name))
|
||||
return ''
|
||||
@@ -688,7 +689,7 @@ class Text( Data ):
|
||||
os.close(fd)
|
||||
# rewrite the file with unix newlines
|
||||
fp = open(dataset.file_name, 'w')
|
||||
for line in file(temp_name, "U"):
|
||||
for line in open(temp_name, "U"):
|
||||
line = line.strip() + '\n'
|
||||
fp.write(line)
|
||||
fp.close()
|
||||
@@ -700,7 +701,7 @@ class Text( Data ):
|
||||
os.close(fd)
|
||||
# rewrite the file with unix newlines
|
||||
fp = open(dataset.file_name, 'w')
|
||||
for line in file(temp_name, "U"):
|
||||
for line in open(temp_name, "U"):
|
||||
line = line.strip() + '\n'
|
||||
fp.write(line)
|
||||
fp.close()
|
||||
@@ -734,7 +735,7 @@ class Text( Data ):
|
||||
skipping all blank lines and comments.
|
||||
"""
|
||||
data_lines = 0
|
||||
for line in file( dataset.file_name ):
|
||||
for line in open( dataset.file_name ):
|
||||
line = line.strip()
|
||||
if line and not line.startswith( '#' ):
|
||||
data_lines += 1
|
||||
@@ -867,6 +868,8 @@ class Text( Data ):
|
||||
|
||||
class GenericAsn1( Text ):
|
||||
"""Class for generic ASN.1 text format"""
|
||||
edam_data = "data_0849"
|
||||
edam_format = "format_1966"
|
||||
file_ext = 'asn1'
|
||||
|
||||
|
||||
@@ -880,6 +883,7 @@ class LineCount( Text ):
|
||||
|
||||
class Newick( Text ):
|
||||
"""New Hampshire/Newick Format"""
|
||||
edam_data = "data_0872"
|
||||
edam_format = "format_1910"
|
||||
file_ext = "nhx"
|
||||
|
||||
@@ -904,6 +908,7 @@ class Newick( Text ):
|
||||
|
||||
class Nexus( Text ):
|
||||
"""Nexus format as used By Paup, Mr Bayes, etc"""
|
||||
edam_data = "data_0872"
|
||||
edam_format = "format_1912"
|
||||
file_ext = "nex"
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ class GenomeGraphs( Tabular ):
|
||||
def set_meta(self, dataset, **kwd):
|
||||
Tabular.set_meta( self, dataset, **kwd)
|
||||
dataset.metadata.markerCol = 1
|
||||
header = file(dataset.file_name, 'r').readlines()[0].strip().split('\t')
|
||||
header = open(dataset.file_name, 'r').readlines()[0].strip().split('\t')
|
||||
dataset.metadata.columns = len(header)
|
||||
t = ['numeric' for x in header]
|
||||
t[0] = 'string'
|
||||
@@ -60,7 +60,7 @@ class GenomeGraphs( Tabular ):
|
||||
"""
|
||||
Returns file
|
||||
"""
|
||||
return file(dataset.file_name, 'r')
|
||||
return open(dataset.file_name, 'r')
|
||||
|
||||
def ucsc_links( self, dataset, type, app, base_url ):
|
||||
"""
|
||||
@@ -298,10 +298,9 @@ class Rgenetics(Html):
|
||||
f, e = os.path.splitext(fname)
|
||||
rval.append( '<li><a href="%s">%s</a></li>' % ( sfname, sfname) )
|
||||
rval.append( '</ul></body></html>' )
|
||||
f = file(dataset.file_name, 'w')
|
||||
f.write("\n".join( rval ))
|
||||
f.write('\n')
|
||||
f.close()
|
||||
with open(dataset.file_name, 'w') as f:
|
||||
f.write("\n".join( rval ))
|
||||
f.write('\n')
|
||||
|
||||
def get_mime(self):
|
||||
"""Returns the mime type of the datatype"""
|
||||
@@ -624,7 +623,7 @@ class RexpBase( Html ):
|
||||
A file can be written as
|
||||
write.table(file='foo.pheno',pData(foo),sep='\t',quote=F,row.names=F)
|
||||
"""
|
||||
p = file(dataset.metadata.pheno_path, 'r').readlines()
|
||||
p = open(dataset.metadata.pheno_path, 'r').readlines()
|
||||
if len(p) > 0: # should only need to fix an R pheno file once
|
||||
head = p[0].strip().split('\t')
|
||||
line1 = p[1].strip().split('\t')
|
||||
@@ -643,7 +642,7 @@ class RexpBase( Html ):
|
||||
if not dataset.dataset.purged:
|
||||
pp = os.path.join(dataset.extra_files_path, '%s.pheno' % dataset.metadata.base_name)
|
||||
try:
|
||||
p = file(pp, 'r').readlines()
|
||||
p = open(pp, 'r').readlines()
|
||||
except:
|
||||
p = ['##failed to find %s' % pp, ]
|
||||
dataset.peek = ''.join(p[:5])
|
||||
@@ -658,7 +657,7 @@ class RexpBase( Html ):
|
||||
"""
|
||||
pp = os.path.join(dataset.extra_files_path, '%s.pheno' % dataset.metadata.base_name)
|
||||
try:
|
||||
p = file(pp, 'r').readlines()
|
||||
p = open(pp, 'r').readlines()
|
||||
except:
|
||||
p = ['##failed to find %s' % pp]
|
||||
return ''.join(p[:5])
|
||||
@@ -669,7 +668,7 @@ class RexpBase( Html ):
|
||||
"""
|
||||
h = '## rexpression get_file_peek: no file found'
|
||||
try:
|
||||
h = file(filename, 'r').readlines()
|
||||
h = open(filename, 'r').readlines()
|
||||
except:
|
||||
pass
|
||||
return ''.join(h[:5])
|
||||
@@ -685,10 +684,9 @@ class RexpBase( Html ):
|
||||
sfname = os.path.split(fname)[-1]
|
||||
rval.append( '<li><a href="%s">%s</a>' % ( sfname, sfname ) )
|
||||
rval.append( '</ul></html>' )
|
||||
f = file(dataset.file_name, 'w')
|
||||
f.write("\n".join( rval ))
|
||||
f.write('\n')
|
||||
f.close()
|
||||
with open(dataset.file_name, 'w') as f:
|
||||
f.write("\n".join( rval ))
|
||||
f.write('\n')
|
||||
|
||||
def init_meta( self, dataset, copy_from=None ):
|
||||
if copy_from:
|
||||
@@ -721,7 +719,7 @@ class RexpBase( Html ):
|
||||
pp = os.path.join(dataset.extra_files_path, pn)
|
||||
dataset.metadata.pheno_path = pp
|
||||
try:
|
||||
pf = file(pp, 'r').readlines() # read the basename.phenodata in the extra_files_path
|
||||
pf = open(pp, 'r').readlines() # read the basename.phenodata in the extra_files_path
|
||||
except:
|
||||
pf = None
|
||||
if pf:
|
||||
|
||||
@@ -37,6 +37,7 @@ log = logging.getLogger(__name__)
|
||||
|
||||
class Image( data.Data ):
|
||||
"""Class describing an image"""
|
||||
edam_data = 'data_2968'
|
||||
edam_format = "format_3547"
|
||||
|
||||
def set_peek( self, dataset, is_multi_byte=False ):
|
||||
@@ -64,6 +65,7 @@ class Image( data.Data ):
|
||||
|
||||
|
||||
class Jpg( Image ):
|
||||
edam_format = "format_3579"
|
||||
file_ext = "jpg"
|
||||
|
||||
def sniff(self, filename, image=None):
|
||||
@@ -72,6 +74,7 @@ class Jpg( Image ):
|
||||
|
||||
|
||||
class Png( Image ):
|
||||
edam_format = "format_3603"
|
||||
file_ext = "png"
|
||||
|
||||
def sniff(self, filename, image=None):
|
||||
@@ -80,6 +83,7 @@ class Png( Image ):
|
||||
|
||||
|
||||
class Tiff( Image ):
|
||||
edam_format = "format_3591"
|
||||
file_ext = "tiff"
|
||||
|
||||
def sniff(self, filename, image=None):
|
||||
@@ -88,6 +92,7 @@ class Tiff( Image ):
|
||||
|
||||
|
||||
class Bmp( Image ):
|
||||
edam_format = "format_3592"
|
||||
file_ext = "bmp"
|
||||
|
||||
def sniff(self, filename, image=None):
|
||||
@@ -105,6 +110,7 @@ class Gif( Image ):
|
||||
|
||||
|
||||
class Im( Image ):
|
||||
edam_format = "format_3593"
|
||||
file_ext = "im"
|
||||
|
||||
def sniff(self, filename, image=None):
|
||||
@@ -113,6 +119,7 @@ class Im( Image ):
|
||||
|
||||
|
||||
class Pcd( Image ):
|
||||
edam_format = "format_3594"
|
||||
file_ext = "pcd"
|
||||
|
||||
def sniff(self, filename, image=None):
|
||||
@@ -121,6 +128,7 @@ class Pcd( Image ):
|
||||
|
||||
|
||||
class Pcx( Image ):
|
||||
edam_format = "format_3595"
|
||||
file_ext = "pcx"
|
||||
|
||||
def sniff(self, filename, image=None):
|
||||
@@ -129,6 +137,7 @@ class Pcx( Image ):
|
||||
|
||||
|
||||
class Ppm( Image ):
|
||||
edam_format = "format_3596"
|
||||
file_ext = "ppm"
|
||||
|
||||
def sniff(self, filename, image=None):
|
||||
@@ -137,6 +146,7 @@ class Ppm( Image ):
|
||||
|
||||
|
||||
class Psd( Image ):
|
||||
edam_format = "format_3597"
|
||||
file_ext = "psd"
|
||||
|
||||
def sniff(self, filename, image=None):
|
||||
@@ -145,6 +155,7 @@ class Psd( Image ):
|
||||
|
||||
|
||||
class Xbm( Image ):
|
||||
edam_format = "format_3598"
|
||||
file_ext = "xbm"
|
||||
|
||||
def sniff(self, filename, image=None):
|
||||
@@ -153,6 +164,7 @@ class Xbm( Image ):
|
||||
|
||||
|
||||
class Xpm( Image ):
|
||||
edam_format = "format_3599"
|
||||
file_ext = "xpm"
|
||||
|
||||
def sniff(self, filename, image=None):
|
||||
@@ -161,6 +173,7 @@ class Xpm( Image ):
|
||||
|
||||
|
||||
class Rgb( Image ):
|
||||
edam_format = "format_3600"
|
||||
file_ext = "rgb"
|
||||
|
||||
def sniff(self, filename, image=None):
|
||||
@@ -169,6 +182,7 @@ class Rgb( Image ):
|
||||
|
||||
|
||||
class Pbm( Image ):
|
||||
edam_format = "format_3601"
|
||||
file_ext = "pbm"
|
||||
|
||||
def sniff(self, filename, image=None):
|
||||
@@ -177,6 +191,7 @@ class Pbm( Image ):
|
||||
|
||||
|
||||
class Pgm( Image ):
|
||||
edam_format = "format_3602"
|
||||
file_ext = "pgm"
|
||||
|
||||
def sniff(self, filename, image=None):
|
||||
@@ -194,6 +209,7 @@ class Eps( Image ):
|
||||
|
||||
|
||||
class Rast( Image ):
|
||||
edam_format = "format_3605"
|
||||
file_ext = "rast"
|
||||
|
||||
def sniff(self, filename, image=None):
|
||||
|
||||
@@ -27,9 +27,9 @@ log = logging.getLogger(__name__)
|
||||
# Contains the meta columns and the words that map to it; list aliases on the
|
||||
# right side of the : in decreasing order of priority
|
||||
alias_spec = {
|
||||
'chromCol' : [ 'chrom' , 'CHROMOSOME' , 'CHROM', 'Chromosome Name' ],
|
||||
'startCol' : [ 'start' , 'START', 'chromStart', 'txStart', 'Start Position (bp)' ],
|
||||
'endCol' : [ 'end' , 'END' , 'STOP', 'chromEnd', 'txEnd', 'End Position (bp)' ],
|
||||
'chromCol' : [ 'chrom', 'CHROMOSOME', 'CHROM', 'Chromosome Name' ],
|
||||
'startCol' : [ 'start', 'START', 'chromStart', 'txStart', 'Start Position (bp)' ],
|
||||
'endCol' : [ 'end', 'END', 'STOP', 'chromEnd', 'txEnd', 'End Position (bp)' ],
|
||||
'strandCol' : [ 'strand', 'STRAND', 'Strand' ],
|
||||
'nameCol' : [ 'name', 'NAME', 'Name', 'name2', 'NAME2', 'Name2', 'Ensembl Gene ID', 'Ensembl Transcript ID', 'Ensembl Peptide ID' ]
|
||||
}
|
||||
@@ -50,6 +50,7 @@ VIEWPORT_MAX_READS_PER_LINE = 10
|
||||
@dataproviders.decorators.has_dataproviders
|
||||
class Interval( Tabular ):
|
||||
"""Tab delimited data containing interval information"""
|
||||
edam_data = "data_3002"
|
||||
edam_format = "format_3475"
|
||||
file_ext = "interval"
|
||||
line_class = "region"
|
||||
@@ -78,7 +79,7 @@ class Interval( Tabular ):
|
||||
if dataset.has_data():
|
||||
empty_line_count = 0
|
||||
num_check_lines = 100 # only check up to this many non empty lines
|
||||
for i, line in enumerate( file( dataset.file_name ) ):
|
||||
for i, line in enumerate( open( dataset.file_name ) ):
|
||||
line = line.rstrip( '\r\n' )
|
||||
if line:
|
||||
if ( first_line_is_header or line[0] == '#' ):
|
||||
@@ -375,7 +376,7 @@ class Interval( Tabular ):
|
||||
|
||||
class BedGraph( Interval ):
|
||||
"""Tab delimited chrom/start/end/datavalue dataset"""
|
||||
|
||||
edam_format = "format_3583"
|
||||
file_ext = "bedgraph"
|
||||
track_type = "LineTrack"
|
||||
data_sources = { "data": "bigwig", "index": "bigwig" }
|
||||
@@ -414,7 +415,7 @@ class Bed( Interval ):
|
||||
"""Sets the metadata information for datasets previously determined to be in bed format."""
|
||||
i = 0
|
||||
if dataset.has_data():
|
||||
for i, line in enumerate( file(dataset.file_name) ):
|
||||
for i, line in enumerate( open(dataset.file_name) ):
|
||||
metadata_set = False
|
||||
line = line.rstrip('\r\n')
|
||||
if line and not line.startswith('#'):
|
||||
@@ -582,7 +583,7 @@ class Bed( Interval ):
|
||||
|
||||
class BedStrict( Bed ):
|
||||
"""Tab delimited data in strict BED format - no non-standard columns allowed"""
|
||||
|
||||
edam_format = "format_3584"
|
||||
file_ext = "bedstrict"
|
||||
|
||||
# no user change of datatype allowed
|
||||
@@ -613,13 +614,13 @@ class BedStrict( Bed ):
|
||||
|
||||
class Bed6( BedStrict ):
|
||||
"""Tab delimited data in strict BED format - no non-standard columns allowed; column count forced to 6"""
|
||||
|
||||
edam_format = "format_3585"
|
||||
file_ext = "bed6"
|
||||
|
||||
|
||||
class Bed12( BedStrict ):
|
||||
"""Tab delimited data in strict BED format - no non-standard columns allowed; column count forced to 12"""
|
||||
|
||||
edam_format = "format_3586"
|
||||
file_ext = "bed12"
|
||||
|
||||
|
||||
@@ -641,6 +642,7 @@ class _RemoteCallMixin:
|
||||
@dataproviders.decorators.has_dataproviders
|
||||
class Gff( Tabular, _RemoteCallMixin ):
|
||||
"""Tab delimited data in Gff format"""
|
||||
edam_data = "data_1255"
|
||||
edam_format = "format_2305"
|
||||
file_ext = "gff"
|
||||
column_names = [ 'Seqname', 'Source', 'Feature', 'Start', 'End', 'Score', 'Strand', 'Frame', 'Group' ]
|
||||
@@ -670,7 +672,7 @@ class Gff( Tabular, _RemoteCallMixin ):
|
||||
# not found in the first N lines will not have metadata.
|
||||
num_lines = 200
|
||||
attribute_types = {}
|
||||
for i, line in enumerate( file( dataset.file_name ) ):
|
||||
for i, line in enumerate( open( dataset.file_name ) ):
|
||||
if line and not line.startswith( '#' ):
|
||||
elems = line.split( '\t' )
|
||||
if len( elems ) == 9:
|
||||
@@ -704,7 +706,7 @@ class Gff( Tabular, _RemoteCallMixin ):
|
||||
self.set_attribute_metadata( dataset )
|
||||
|
||||
i = 0
|
||||
for i, line in enumerate( file( dataset.file_name ) ):
|
||||
for i, line in enumerate( open( dataset.file_name ) ):
|
||||
line = line.rstrip('\r\n')
|
||||
if line and not line.startswith( '#' ):
|
||||
elems = line.split( '\t' )
|
||||
@@ -912,7 +914,7 @@ class Gff3( Gff ):
|
||||
self.set_attribute_metadata( dataset )
|
||||
|
||||
i = 0
|
||||
for i, line in enumerate( file( dataset.file_name ) ):
|
||||
for i, line in enumerate( open( dataset.file_name ) ):
|
||||
line = line.rstrip('\r\n')
|
||||
if line and not line.startswith( '#' ):
|
||||
elems = line.split( '\t' )
|
||||
@@ -1189,7 +1191,7 @@ class Wiggle( Tabular, _RemoteCallMixin ):
|
||||
def set_meta( self, dataset, overwrite=True, **kwd ):
|
||||
max_data_lines = None
|
||||
i = 0
|
||||
for i, line in enumerate( file( dataset.file_name ) ):
|
||||
for i, line in enumerate( open( dataset.file_name ) ):
|
||||
line = line.rstrip('\r\n')
|
||||
if line and not line.startswith( '#' ):
|
||||
elems = line.split( '\t' )
|
||||
@@ -1288,6 +1290,7 @@ class Wiggle( Tabular, _RemoteCallMixin ):
|
||||
|
||||
class CustomTrack ( Tabular ):
|
||||
"""UCSC CustomTrack"""
|
||||
edam_format = "format_3588"
|
||||
file_ext = "customtrack"
|
||||
|
||||
def __init__(self, **kwd):
|
||||
@@ -1440,7 +1443,7 @@ class ENCODEPeak( Interval ):
|
||||
This format is used to provide called peaks of signal enrichment based on
|
||||
pooled, normalized (interpreted) data. It is a BED6+4 format.
|
||||
'''
|
||||
|
||||
edam_format = "format_3612"
|
||||
file_ext = "encodepeak"
|
||||
column_names = [ 'Chrom', 'Start', 'End', 'Name', 'Score', 'Strand', 'SignalValue', 'pValue', 'qValue', 'Peak' ]
|
||||
data_sources = { "data": "tabix", "index": "bigwig" }
|
||||
@@ -1460,11 +1463,9 @@ class ChromatinInteractions( Interval ):
|
||||
'''
|
||||
Chromatin interactions obtained from 3C/5C/Hi-C experiments.
|
||||
'''
|
||||
|
||||
file_ext = "chrint"
|
||||
track_type = "DiagonalHeatmapTrack"
|
||||
data_sources = { "data": "tabix", "index": "bigwig" }
|
||||
|
||||
column_names = [ 'Chrom1', 'Start1', 'End1', 'Chrom2', 'Start2', 'End2', 'Value' ]
|
||||
|
||||
"""Add metadata elements"""
|
||||
|
||||
+820
-769
File diff suppressed because it is too large
Load Diff
@@ -16,18 +16,26 @@ class Otu(Text):
|
||||
file_ext = 'mothur.otu'
|
||||
MetadataElement(name="columns", default=0, desc="Number of columns", readonly=True, visible=True, no_value=0)
|
||||
MetadataElement(name="labels", default=[], desc="Label Names", readonly=True, visible=True, no_value=[])
|
||||
MetadataElement(name="otulabels", default=[], desc="OTU Names", readonly=True, visible=True, no_value=[])
|
||||
|
||||
def __init__(self, **kwd):
|
||||
Text.__init__(self, **kwd)
|
||||
super(Otu, self).__init__(**kwd)
|
||||
|
||||
def set_meta(self, dataset, overwrite=True, **kwd):
|
||||
super(Otu, self).set_meta(dataset, overwrite=overwrite, **kwd)
|
||||
|
||||
if dataset.has_data():
|
||||
label_names = set()
|
||||
otulabel_names = set()
|
||||
ncols = 0
|
||||
data_lines = 0
|
||||
comment_lines = 0
|
||||
|
||||
headers = get_headers(dataset.file_name, sep='\t', count=-1)
|
||||
# set otulabels
|
||||
if len(headers[0]) > 2:
|
||||
otulabel_names = headers[0][2:]
|
||||
# set label names and number of lines
|
||||
for line in headers:
|
||||
if len(line) >= 2 and not line[0].startswith('@'):
|
||||
data_lines += 1
|
||||
@@ -40,6 +48,8 @@ class Otu(Text):
|
||||
dataset.metadata.columns = ncols
|
||||
dataset.metadata.labels = list(label_names)
|
||||
dataset.metadata.labels.sort()
|
||||
dataset.metadata.otulabels = list(otulabel_names)
|
||||
dataset.metadata.otulabels.sort()
|
||||
|
||||
def sniff(self, filename):
|
||||
"""
|
||||
@@ -80,10 +90,10 @@ class Sabund(Otu):
|
||||
"""
|
||||
http://www.mothur.org/wiki/Sabund_file
|
||||
"""
|
||||
Otu.__init__(self, **kwd)
|
||||
super(Sabund, self).__init__(**kwd)
|
||||
|
||||
def init_meta(self, dataset, copy_from=None):
|
||||
Otu.init_meta(self, dataset, copy_from=copy_from)
|
||||
super(Sabund, self).init_meta(dataset, copy_from=copy_from)
|
||||
|
||||
def sniff(self, filename):
|
||||
"""
|
||||
@@ -124,16 +134,14 @@ class GroupAbund(Otu):
|
||||
MetadataElement(name="groups", default=[], desc="Group Names", readonly=True, visible=True, no_value=[])
|
||||
|
||||
def __init__(self, **kwd):
|
||||
Otu.__init__(self, **kwd)
|
||||
super(GroupAbund, self).__init__(**kwd)
|
||||
|
||||
"""
|
||||
def init_meta(self, dataset, copy_from=None):
|
||||
Otu.init_meta(self, dataset, copy_from=copy_from)
|
||||
"""
|
||||
def init_meta(self, dataset, copy_from=None):
|
||||
Otu.init_meta(self, dataset, copy_from=copy_from)
|
||||
super(GroupAbund, self).init_meta(dataset, copy_from=copy_from)
|
||||
|
||||
def set_meta(self, dataset, overwrite=True, skip=1, **kwd):
|
||||
super(GroupAbund, self).set_meta(dataset, overwrite=overwrite, **kwd)
|
||||
|
||||
def set_meta(self, dataset, overwrite=True, skip=1, max_data_lines=100000, **kwd):
|
||||
# See if file starts with header line
|
||||
if dataset.has_data():
|
||||
label_names = set()
|
||||
@@ -142,7 +150,7 @@ class GroupAbund(Otu):
|
||||
comment_lines = 0
|
||||
ncols = 0
|
||||
|
||||
headers = get_headers(dataset.file_name, sep='\t', count=max_data_lines)
|
||||
headers = get_headers(dataset.file_name, sep='\t', count=-1)
|
||||
for line in headers:
|
||||
if line[0] == 'label' and line[1] == 'Group':
|
||||
skip = 1
|
||||
@@ -207,7 +215,7 @@ class SecondaryStructureMap(Tabular):
|
||||
|
||||
def __init__(self, **kwd):
|
||||
"""Initialize secondary structure map datatype"""
|
||||
Tabular.__init__(self, **kwd)
|
||||
super(SecondaryStructureMap, self).__init__(**kwd)
|
||||
self.column_names = ['Map']
|
||||
|
||||
def sniff(self, filename):
|
||||
@@ -251,20 +259,18 @@ class AlignCheck(Tabular):
|
||||
|
||||
def __init__(self, **kwd):
|
||||
"""Initialize AlignCheck datatype"""
|
||||
Tabular.__init__(self, **kwd)
|
||||
super(AlignCheck, self).__init__(**kwd)
|
||||
self.column_names = ['name', 'pound', 'dash', 'plus', 'equal', 'loop', 'tilde', 'total']
|
||||
self.column_types = ['str', 'int', 'int', 'int', 'int', 'int', 'int', 'int']
|
||||
self.comment_lines = 1
|
||||
|
||||
def set_meta(self, dataset, overwrite=True, **kwd):
|
||||
data_lines = 0
|
||||
headers = get_headers(dataset.file_name, sep='\t', count=-1)
|
||||
for line in headers:
|
||||
data_lines += 1
|
||||
dataset.metadata.comment_lines = 1
|
||||
dataset.metadata.data_lines = data_lines - 1 if data_lines > 0 else 0
|
||||
super(AlignCheck, self).set_meta(dataset, overwrite=overwrite, **kwd)
|
||||
|
||||
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
|
||||
|
||||
|
||||
class AlignReport(Tabular):
|
||||
@@ -276,7 +282,7 @@ class AlignReport(Tabular):
|
||||
|
||||
def __init__(self, **kwd):
|
||||
"""Initialize AlignCheck datatype"""
|
||||
Tabular.__init__(self, **kwd)
|
||||
super(AlignReport, self).__init__(**kwd)
|
||||
self.column_names = ['QueryName', 'QueryLength', 'TemplateName', 'TemplateLength', 'SearchMethod', 'SearchScore',
|
||||
'AlignmentMethod', 'QueryStart', 'QueryEnd', 'TemplateStart', 'TemplateEnd',
|
||||
'PairwiseAlignmentLength', 'GapsInQuery', 'GapsInTemplate', 'LongestInsert', 'SimBtwnQuery&Template'
|
||||
@@ -289,19 +295,20 @@ class DistanceMatrix(Text):
|
||||
MetadataElement(name="sequence_count", default=0, desc="Number of sequences", readonly=True, visible=True, optional=True, no_value='?')
|
||||
|
||||
def init_meta(self, dataset, copy_from=None):
|
||||
Text.init_meta(self, dataset, copy_from=copy_from)
|
||||
super(DistanceMatrix, self).init_meta(dataset, copy_from=copy_from)
|
||||
|
||||
def set_meta(self, dataset, overwrite=True, skip=0, **kwd):
|
||||
Text.set_meta(self, dataset, overwrite=overwrite, skip=skip, **kwd)
|
||||
super(DistanceMatrix, self).set_meta(dataset, overwrite=overwrite, skip=skip, **kwd)
|
||||
|
||||
headers = get_headers(dataset.file_name, sep='\t', count=-1)
|
||||
headers = get_headers(dataset.file_name, sep='\t')
|
||||
for line in headers:
|
||||
if not line[0].startswith('@'):
|
||||
try:
|
||||
dataset.metadata.sequence_count = int(''.join(line)) # seq count sometimes preceded by tab
|
||||
break
|
||||
except Exception as e:
|
||||
log.warn("DistanceMatrix set_meta %s" % e)
|
||||
if not isinstance(self, PairwiseDistanceMatrix):
|
||||
log.warning("DistanceMatrix set_meta %s" % e)
|
||||
|
||||
|
||||
class LowerTriangleDistanceMatrix(DistanceMatrix):
|
||||
@@ -309,10 +316,10 @@ class LowerTriangleDistanceMatrix(DistanceMatrix):
|
||||
|
||||
def __init__(self, **kwd):
|
||||
"""Initialize secondary structure map datatype"""
|
||||
DistanceMatrix.__init__(self, **kwd)
|
||||
super(LowerTriangleDistanceMatrix, self).__init__(**kwd)
|
||||
|
||||
def init_meta(self, dataset, copy_from=None):
|
||||
DistanceMatrix.init_meta(self, dataset, copy_from=copy_from)
|
||||
super(LowerTriangleDistanceMatrix, self).init_meta(dataset, copy_from=copy_from)
|
||||
|
||||
def sniff(self, filename):
|
||||
"""
|
||||
@@ -371,10 +378,10 @@ class SquareDistanceMatrix(DistanceMatrix):
|
||||
file_ext = 'mothur.square.dist'
|
||||
|
||||
def __init__(self, **kwd):
|
||||
DistanceMatrix.__init__(self, **kwd)
|
||||
super(SquareDistanceMatrix, self).__init__(**kwd)
|
||||
|
||||
def init_meta(self, dataset, copy_from=None):
|
||||
DistanceMatrix.init_meta(self, dataset, copy_from=copy_from)
|
||||
super(SquareDistanceMatrix, self).init_meta(dataset, copy_from=copy_from)
|
||||
|
||||
def sniff(self, filename):
|
||||
"""
|
||||
@@ -432,12 +439,12 @@ class PairwiseDistanceMatrix(DistanceMatrix, Tabular):
|
||||
|
||||
def __init__(self, **kwd):
|
||||
"""Initialize secondary structure map datatype"""
|
||||
Tabular.__init__(self, **kwd)
|
||||
super(PairwiseDistanceMatrix, self).__init__(**kwd)
|
||||
self.column_names = ['Sequence', 'Sequence', 'Distance']
|
||||
self.column_types = ['str', 'str', 'float']
|
||||
|
||||
def set_meta(self, dataset, overwrite=True, skip=None, **kwd):
|
||||
Tabular.set_meta(self, dataset, overwrite=overwrite, skip=skip, **kwd)
|
||||
super(PairwiseDistanceMatrix, self).set_meta(dataset, overwrite=overwrite, skip=skip, **kwd)
|
||||
|
||||
def sniff(self, filename):
|
||||
"""
|
||||
@@ -484,7 +491,7 @@ class Names(Tabular):
|
||||
http://www.mothur.org/wiki/Name_file
|
||||
Name file shows the relationship between a representative sequence(col 1) and the sequences(comma-separated) it represents(col 2)
|
||||
"""
|
||||
Tabular.__init__(self, **kwd)
|
||||
super(Names, self).__init__(**kwd)
|
||||
self.column_names = ['name', 'representatives']
|
||||
self.columns = 2
|
||||
|
||||
@@ -494,7 +501,7 @@ class Summary(Tabular):
|
||||
|
||||
def __init__(self, **kwd):
|
||||
"""summarizes the quality of sequences in an unaligned or aligned fasta-formatted sequence file"""
|
||||
Tabular.__init__(self, **kwd)
|
||||
super(Summary, self).__init__(**kwd)
|
||||
self.column_names = ['seqname', 'start', 'end', 'nbases', 'ambigs', 'polymer']
|
||||
self.columns = 6
|
||||
|
||||
@@ -508,15 +515,15 @@ class Group(Tabular):
|
||||
http://www.mothur.org/wiki/Groups_file
|
||||
Group file assigns sequence (col 1) to a group (col 2)
|
||||
"""
|
||||
Tabular.__init__(self, **kwd)
|
||||
super(Group, self).__init__(**kwd)
|
||||
self.column_names = ['name', 'group']
|
||||
self.columns = 2
|
||||
|
||||
def set_meta(self, dataset, overwrite=True, skip=None, max_data_lines=None, **kwd):
|
||||
Tabular.set_meta(self, dataset, overwrite, skip, max_data_lines)
|
||||
group_names = set()
|
||||
super(Group, self).set_meta(dataset, overwrite, skip, max_data_lines)
|
||||
|
||||
headers = get_headers(dataset.file_name, sep='\t')
|
||||
group_names = set()
|
||||
headers = get_headers(dataset.file_name, sep='\t', count=-1)
|
||||
for line in headers:
|
||||
if len(line) > 1:
|
||||
group_names.add(line[1])
|
||||
@@ -528,7 +535,7 @@ class AccNos(Tabular):
|
||||
|
||||
def __init__(self, **kwd):
|
||||
"""A list of names"""
|
||||
Tabular.__init__(self, **kwd)
|
||||
super(AccNos, self).__init__(**kwd)
|
||||
self.column_names = ['name']
|
||||
self.columns = 1
|
||||
|
||||
@@ -572,7 +579,7 @@ class Frequency(Tabular):
|
||||
|
||||
def __init__(self, **kwd):
|
||||
"""A list of names"""
|
||||
Tabular.__init__(self, **kwd)
|
||||
super(Frequency, self).__init__(**kwd)
|
||||
self.column_names = ['position', 'frequency']
|
||||
self.column_types = ['int', 'float']
|
||||
|
||||
@@ -624,7 +631,7 @@ class Quantile(Tabular):
|
||||
|
||||
def __init__(self, **kwd):
|
||||
"""Quantiles for chimera analysis"""
|
||||
Tabular.__init__(self, **kwd)
|
||||
super(Quantile, self).__init__(**kwd)
|
||||
self.column_names = ['num', 'ten', 'twentyfive', 'fifty', 'seventyfive', 'ninetyfive', 'ninetynine']
|
||||
self.column_types = ['int', 'float', 'float', 'float', 'float', 'float', 'float']
|
||||
|
||||
@@ -706,37 +713,36 @@ class CountTable(Tabular):
|
||||
U68595 1
|
||||
U68600 1
|
||||
# Example 2 (with group columns):
|
||||
Representative_Sequence total forest pastur
|
||||
Representative_Sequence total forest pasture
|
||||
U68630 1 1 0
|
||||
U68595 1 1 0
|
||||
U68600 1 1 0
|
||||
U68591 1 1 0
|
||||
U68647 1 0 1
|
||||
"""
|
||||
Tabular.__init__(self, **kwd)
|
||||
super(CountTable, self).__init__(**kwd)
|
||||
self.column_names = ['name', 'total']
|
||||
|
||||
def set_meta(self, dataset, overwrite=True, skip=1, max_data_lines=None, **kwd):
|
||||
data_lines = 0
|
||||
headers = get_headers(dataset.file_name, sep='\t', count=-1)
|
||||
super(CountTable, self).set_meta(dataset, overwrite=overwrite, **kwd)
|
||||
|
||||
headers = get_headers(dataset.file_name, sep='\t', count=1)
|
||||
colnames = headers[0]
|
||||
dataset.metadata.column_types = ['str'] + (['int'] * ( len(headers[0]) - 1))
|
||||
if len(colnames) > 1:
|
||||
dataset.metadata.columns = len(colnames)
|
||||
if len(colnames) > 2:
|
||||
dataset.metadata.groups = colnames[2:]
|
||||
for line in headers[1:]:
|
||||
data_lines += 1
|
||||
|
||||
dataset.metadata.comment_lines = 1
|
||||
dataset.metadata.data_lines = data_lines
|
||||
dataset.metadata.data_lines -= 1
|
||||
|
||||
|
||||
class RefTaxonomy(Tabular):
|
||||
file_ext = 'mothur.ref.taxonomy'
|
||||
|
||||
def __init__(self, **kwd):
|
||||
Tabular.__init__(self, **kwd)
|
||||
super(RefTaxonomy, self).__init__(**kwd)
|
||||
self.column_names = ['name', 'taxonomy']
|
||||
|
||||
def sniff(self, filename):
|
||||
@@ -796,7 +802,7 @@ class ConsensusTaxonomy(Tabular):
|
||||
|
||||
def __init__(self, **kwd):
|
||||
"""A list of names"""
|
||||
Tabular.__init__(self, **kwd)
|
||||
super(ConsensusTaxonomy, self).__init__(**kwd)
|
||||
self.column_names = ['OTU', 'count', 'taxonomy']
|
||||
|
||||
|
||||
@@ -805,7 +811,7 @@ class TaxonomySummary(Tabular):
|
||||
|
||||
def __init__(self, **kwd):
|
||||
"""A Summary of taxon classification"""
|
||||
Tabular.__init__(self, **kwd)
|
||||
super(TaxonomySummary, self).__init__(**kwd)
|
||||
self.column_names = ['taxlevel', 'rankID', 'taxon', 'daughterlevels', 'total']
|
||||
|
||||
|
||||
@@ -814,7 +820,7 @@ class Axes(Tabular):
|
||||
|
||||
def __init__(self, **kwd):
|
||||
"""Initialize axes datatype"""
|
||||
Tabular.__init__(self, **kwd)
|
||||
super(Axes, self).__init__(**kwd)
|
||||
|
||||
def sniff(self, filename):
|
||||
"""
|
||||
@@ -892,17 +898,17 @@ class SffFlow(Tabular):
|
||||
GQY1XT001CF5YW 88 1.02 0.02 1.01 0.04 0.06 1.02 0.03 ...
|
||||
"""
|
||||
def __init__(self, **kwd):
|
||||
Tabular.__init__(self, **kwd)
|
||||
super(SffFlow, self).__init__(**kwd)
|
||||
|
||||
def set_meta(self, dataset, overwrite=True, skip=1, max_data_lines=None, **kwd):
|
||||
Tabular.set_meta(self, dataset, overwrite, 1, max_data_lines)
|
||||
super(SffFlow, self).set_meta(dataset, overwrite, 1, max_data_lines)
|
||||
|
||||
headers = get_headers(dataset.file_name, sep='\t')
|
||||
headers = get_headers(dataset.file_name, sep='\t', count=1)
|
||||
try:
|
||||
flow_values = int(headers[0][0])
|
||||
dataset.metadata.flow_values = flow_values
|
||||
except Exception as e:
|
||||
log.warn("SffFlow set_meta %s" % e)
|
||||
log.warning("SffFlow set_meta %s" % e)
|
||||
|
||||
def make_html_table(self, dataset, skipchars=[]):
|
||||
"""Create HTML table, used for displaying peek"""
|
||||
|
||||
@@ -11,6 +11,8 @@ log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Hmmer( Text ):
|
||||
edam_data = "data_1364"
|
||||
edam_format = "format_1370"
|
||||
file_ext = "hmm"
|
||||
|
||||
def set_peek(self, dataset, is_multi_byte=False):
|
||||
@@ -29,6 +31,7 @@ class Hmmer( Text ):
|
||||
|
||||
|
||||
class Hmmer2( Hmmer ):
|
||||
edam_format = "format_3328"
|
||||
|
||||
def sniff(self, filename):
|
||||
"""HMMER2 files start with HMMER2.0
|
||||
@@ -39,6 +42,7 @@ class Hmmer2( Hmmer ):
|
||||
|
||||
|
||||
class Hmmer3( Hmmer ):
|
||||
edam_format = "format_3329"
|
||||
|
||||
def sniff(self, filename):
|
||||
"""HMMER3 files start with HMMER3/f
|
||||
@@ -85,6 +89,8 @@ Binary.register_unsniffable_binary_ext("hmmpress")
|
||||
|
||||
|
||||
class Stockholm_1_0( Text ):
|
||||
edam_data = "data_0863"
|
||||
edam_format = "format_1961"
|
||||
file_ext = "stockholm"
|
||||
|
||||
MetadataElement( name="number_of_models", default=0, desc="Number of multiple alignments", readonly=True, visible=True, optional=True, no_value=0 )
|
||||
|
||||
@@ -41,10 +41,9 @@ class BowtieIndex( Html ):
|
||||
sfname = os.path.split(fname)[-1]
|
||||
rval.append( '<li><a href="%s">%s</a>' % ( sfname, sfname ) )
|
||||
rval.append( '</ul></html>' )
|
||||
f = file(dataset.file_name, 'w')
|
||||
f.write("\n".join( rval ))
|
||||
f.write('\n')
|
||||
f.close()
|
||||
with open(dataset.file_name, 'w') as f:
|
||||
f.write("\n".join( rval ))
|
||||
f.write('\n')
|
||||
|
||||
def set_peek( self, dataset, is_multi_byte=False ):
|
||||
if not dataset.dataset.purged:
|
||||
|
||||
@@ -18,6 +18,8 @@ log = logging.getLogger(__name__)
|
||||
|
||||
class Wiff(Binary):
|
||||
"""Class for wiff files."""
|
||||
edam_data = "data_2536"
|
||||
edam_format = "format_3710"
|
||||
file_ext = 'wiff'
|
||||
allow_datatype_change = False
|
||||
composite_type = 'auto_primary_file'
|
||||
@@ -55,6 +57,7 @@ Binary.register_sniffable_binary_format("wiff", "wiff", Wiff )
|
||||
|
||||
class PepXmlReport(Tabular):
|
||||
"""pepxml converted to tabular report"""
|
||||
edam_data = "data_2536"
|
||||
file_ext = "tsv"
|
||||
|
||||
def __init__(self, **kwd):
|
||||
@@ -68,6 +71,7 @@ class PepXmlReport(Tabular):
|
||||
|
||||
class ProtXmlReport(Tabular):
|
||||
"""protxml converted to tabular report"""
|
||||
edam_data = "data_2536"
|
||||
file_ext = "tsv"
|
||||
comment_lines = 1
|
||||
|
||||
@@ -93,6 +97,8 @@ class ProtXmlReport(Tabular):
|
||||
class ProteomicsXml(GenericXml):
|
||||
""" An enhanced XML datatype used to reuse code across several
|
||||
proteomic/mass-spec datatypes. """
|
||||
edam_data = "data_2536"
|
||||
edam_format = "format_2032"
|
||||
|
||||
def sniff(self, filename):
|
||||
""" Determines whether the file is the correct XML type. """
|
||||
@@ -117,6 +123,7 @@ class ProteomicsXml(GenericXml):
|
||||
|
||||
class PepXml(ProteomicsXml):
|
||||
"""pepXML data"""
|
||||
edam_format = "format_3655"
|
||||
file_ext = "pepxml"
|
||||
blurb = 'pepXML data'
|
||||
root = "msms_pipeline_analysis"
|
||||
@@ -124,8 +131,8 @@ class PepXml(ProteomicsXml):
|
||||
|
||||
class MzML(ProteomicsXml):
|
||||
"""mzML data"""
|
||||
file_ext = "mzml"
|
||||
edam_format = "format_3244"
|
||||
file_ext = "mzml"
|
||||
blurb = 'mzML Mass Spectrometry data'
|
||||
root = "(mzML|indexedmzML)"
|
||||
|
||||
@@ -139,28 +146,29 @@ class ProtXML(ProteomicsXml):
|
||||
|
||||
class MzXML(ProteomicsXml):
|
||||
"""mzXML data"""
|
||||
edam_format = "format_3654"
|
||||
file_ext = "mzxml"
|
||||
blurb = "mzXML Mass Spectrometry data"
|
||||
root = "mzXML"
|
||||
|
||||
|
||||
class MzIdentML(ProteomicsXml):
|
||||
file_ext = "mzid"
|
||||
edam_format = "format_3247"
|
||||
file_ext = "mzid"
|
||||
blurb = "XML identified peptides and proteins."
|
||||
root = "MzIdentML"
|
||||
|
||||
|
||||
class TraML(ProteomicsXml):
|
||||
file_ext = "traml"
|
||||
edam_format = "format_3246"
|
||||
file_ext = "traml"
|
||||
blurb = "TraML transition list"
|
||||
root = "TraML"
|
||||
|
||||
|
||||
class MzQuantML(ProteomicsXml):
|
||||
file_ext = "mzq"
|
||||
edam_format = "format_3248"
|
||||
file_ext = "mzq"
|
||||
blurb = "XML quantification data"
|
||||
root = "MzQuantML"
|
||||
|
||||
@@ -184,6 +192,7 @@ class IdXML(ProteomicsXml):
|
||||
|
||||
|
||||
class TandemXML(ProteomicsXml):
|
||||
edam_format = "format_3711"
|
||||
file_ext = "tandem"
|
||||
blurb = "X!Tandem search results file"
|
||||
root = "bioml"
|
||||
@@ -197,6 +206,8 @@ class UniProtXML(ProteomicsXml):
|
||||
|
||||
class Mgf(Text):
|
||||
"""Mascot Generic Format data"""
|
||||
edam_data = "data_2536"
|
||||
edam_format = "format_3651"
|
||||
file_ext = "mgf"
|
||||
|
||||
def set_peek(self, dataset, is_multi_byte=False):
|
||||
@@ -223,6 +234,8 @@ class Mgf(Text):
|
||||
|
||||
class MascotDat(Text):
|
||||
"""Mascot search results """
|
||||
edam_data = "data_2536"
|
||||
edam_format = "format_3713"
|
||||
file_ext = "mascotdat"
|
||||
|
||||
def set_peek(self, dataset, is_multi_byte=False):
|
||||
@@ -249,6 +262,8 @@ class MascotDat(Text):
|
||||
|
||||
class ThermoRAW(Binary):
|
||||
"""Class describing a Thermo Finnigan binary RAW file"""
|
||||
edam_data = "data_2536"
|
||||
edam_format = "format_3712"
|
||||
file_ext = "raw"
|
||||
|
||||
def sniff(self, filename):
|
||||
|
||||
@@ -11,6 +11,8 @@ class QualityScore ( data.Text ):
|
||||
"""
|
||||
until we know more about quality score formats
|
||||
"""
|
||||
edam_data = "data_2048"
|
||||
edam_format = "format_3606"
|
||||
file_ext = "qual"
|
||||
|
||||
|
||||
@@ -18,6 +20,7 @@ class QualityScoreSOLiD ( QualityScore ):
|
||||
"""
|
||||
until we know more about quality score formats
|
||||
"""
|
||||
edam_format = "format_3610"
|
||||
file_ext = "qualsolid"
|
||||
|
||||
def sniff( self, filename ):
|
||||
@@ -75,6 +78,7 @@ class QualityScore454 ( QualityScore ):
|
||||
"""
|
||||
until we know more about quality score formats
|
||||
"""
|
||||
edam_format = "format_3611"
|
||||
file_ext = "qual454"
|
||||
|
||||
def sniff( self, filename ):
|
||||
@@ -116,6 +120,7 @@ class QualityScoreSolexa ( QualityScore ):
|
||||
"""
|
||||
until we know more about quality score formats
|
||||
"""
|
||||
edam_format = "format_3608"
|
||||
file_ext = "qualsolexa"
|
||||
|
||||
|
||||
@@ -123,4 +128,5 @@ class QualityScoreIllumina ( QualityScore ):
|
||||
"""
|
||||
until we know more about quality score formats
|
||||
"""
|
||||
edam_format = "format_3609"
|
||||
file_ext = "qualillumina"
|
||||
|
||||
@@ -119,9 +119,7 @@ class Registry( object ):
|
||||
for elem in registration.findall( 'datatype' ):
|
||||
# Keep a status of the process steps to enable stopping the process of handling the datatype if necessary.
|
||||
ok = True
|
||||
extension = elem.get( 'extension', None )
|
||||
if extension:
|
||||
extension = extension.lower()
|
||||
extension = self.get_extension( elem )
|
||||
dtype = elem.get( 'type', None )
|
||||
type_extension = elem.get( 'type_extension', None )
|
||||
mimetype = elem.get( 'mimetype', None )
|
||||
@@ -131,7 +129,11 @@ class Registry( object ):
|
||||
make_subclass = galaxy.util.string_as_bool( elem.get( 'subclass', False ) )
|
||||
edam_format = elem.get( 'edam_format', None )
|
||||
if edam_format and not make_subclass:
|
||||
self.log.warn("Cannot specify edam_format without setting subclass to True, skipping datatype.")
|
||||
self.log.warning("Cannot specify edam_format without setting subclass to True, skipping datatype.")
|
||||
continue
|
||||
edam_data = elem.get( 'edam_data', None )
|
||||
if edam_data and not make_subclass:
|
||||
self.log.warning("Cannot specify edam_data without setting subclass to True, skipping datatype.")
|
||||
continue
|
||||
# Proprietary datatypes included in installed tool shed repositories will include two special attributes
|
||||
# (proprietary_path and proprietary_datatype_module) if they depend on proprietary datatypes classes.
|
||||
@@ -232,6 +234,8 @@ class Registry( object ):
|
||||
datatype_class = type( datatype_class_name, ( datatype_class, ), {} )
|
||||
if edam_format:
|
||||
datatype_class.edam_format = edam_format
|
||||
if edam_data:
|
||||
datatype_class.edam_data = edam_data
|
||||
self.datatypes_by_extension[ extension ] = datatype_class()
|
||||
if mimetype is None:
|
||||
# Use default mimetype per datatype specification.
|
||||
@@ -552,7 +556,7 @@ class Registry( object ):
|
||||
# Load display applications defined by local datatypes_conf.xml.
|
||||
datatype_elems = self.display_app_containers
|
||||
for elem in datatype_elems:
|
||||
extension = elem.get( 'extension', None )
|
||||
extension = self.get_extension( elem )
|
||||
for display_app in elem.findall( 'display' ):
|
||||
display_file = display_app.get( 'file', None )
|
||||
if installed_repository_dict:
|
||||
@@ -818,9 +822,14 @@ class Registry( object ):
|
||||
def edam_formats( self ):
|
||||
"""
|
||||
"""
|
||||
mapping = {}
|
||||
for k, v in self.datatypes_by_extension.iteritems():
|
||||
mapping[k] = v.edam_format
|
||||
mapping = dict((k, v.edam_format) for k, v in self.datatypes_by_extension.items())
|
||||
return mapping
|
||||
|
||||
@property
|
||||
def edam_data( self ):
|
||||
"""
|
||||
"""
|
||||
mapping = dict((k, v.edam_data) for k, v in self.datatypes_by_extension.items())
|
||||
return mapping
|
||||
|
||||
@property
|
||||
@@ -861,3 +870,17 @@ class Registry( object ):
|
||||
os.write( fd, '</datatypes>\n' )
|
||||
os.close( fd )
|
||||
os.chmod( self.xml_filename, 0o644 )
|
||||
|
||||
def get_extension( self, elem ):
|
||||
"""
|
||||
Function which returns the extension lowercased
|
||||
:param elem:
|
||||
:return extension:
|
||||
"""
|
||||
extension = elem.get('extension', None)
|
||||
# If extension is not None and is uppercase or mixed case, we need to lowercase it
|
||||
if extension is not None and not extension.islower():
|
||||
self.log.debug( "%s is not lower case, that could cause troubles in the future. \
|
||||
Please change it to lower case" % extension )
|
||||
extension = extension.lower()
|
||||
return extension
|
||||
|
||||
@@ -38,6 +38,8 @@ class SequenceSplitLocations( data.Text ):
|
||||
]}
|
||||
|
||||
"""
|
||||
file_ext = "fqtoc"
|
||||
|
||||
def set_peek( self, dataset, is_multi_byte=False ):
|
||||
if not dataset.dataset.purged:
|
||||
try:
|
||||
@@ -52,8 +54,6 @@ class SequenceSplitLocations( data.Text ):
|
||||
dataset.peek = 'file does not exist'
|
||||
dataset.blurb = 'file purged from disk'
|
||||
|
||||
file_ext = "fqtoc"
|
||||
|
||||
def sniff( self, filename ):
|
||||
if os.path.getsize(filename) < 50000:
|
||||
try:
|
||||
@@ -70,6 +70,7 @@ class SequenceSplitLocations( data.Text ):
|
||||
|
||||
class Sequence( data.Text ):
|
||||
"""Class describing a sequence"""
|
||||
edam_data = "data_2044"
|
||||
|
||||
"""Add metadata elements"""
|
||||
MetadataElement( name="sequences", default=0, desc="Number of sequences", readonly=True, visible=False, optional=True, no_value=0 )
|
||||
@@ -80,7 +81,7 @@ class Sequence( data.Text ):
|
||||
"""
|
||||
data_lines = 0
|
||||
sequences = 0
|
||||
for line in file( dataset.file_name ):
|
||||
for line in open( dataset.file_name ):
|
||||
line = line.strip()
|
||||
if line and line.startswith( '#' ):
|
||||
# We don't count comment lines for sequence data types
|
||||
@@ -294,6 +295,7 @@ class Sequence( data.Text ):
|
||||
|
||||
class Alignment( data.Text ):
|
||||
"""Class describing an alignment"""
|
||||
edam_data = "data_0863"
|
||||
|
||||
"""Add metadata elements"""
|
||||
MetadataElement( name="species", desc="Species", default=[], param=metadata.SelectParameter, multiple=True, readonly=True, no_value=None )
|
||||
@@ -498,7 +500,7 @@ class Fasta( Sequence ):
|
||||
|
||||
class csFasta( Sequence ):
|
||||
""" Class representing the SOLID Color-Space sequence ( csfasta ) """
|
||||
edam_format = "format_1929"
|
||||
edam_format = "format_3589"
|
||||
file_ext = "csfasta"
|
||||
|
||||
def sniff( self, filename ):
|
||||
@@ -565,7 +567,7 @@ class Fastq ( Sequence ):
|
||||
data_lines = 0
|
||||
sequences = 0
|
||||
seq_counter = 0 # blocks should be 4 lines long
|
||||
for line in file( dataset.file_name ):
|
||||
for line in open( dataset.file_name ):
|
||||
line = line.strip()
|
||||
if line and line.startswith( '#' ) and not data_lines:
|
||||
# We don't count comment lines for sequence data types
|
||||
@@ -841,11 +843,12 @@ class MafCustomTrack( data.Text ):
|
||||
|
||||
class Axt( data.Text ):
|
||||
"""Class describing an axt alignment"""
|
||||
|
||||
# gvk- 11/19/09 - This is really an alignment, but we no longer have tools that use this data type, and it is
|
||||
# here simply for backward compatibility ( although it is still in the datatypes registry ). Subclassing
|
||||
# from data.Text eliminates managing metadata elements inherited from the Alignemnt class.
|
||||
|
||||
edam_data = "data_0863"
|
||||
edam_format = "format_3013"
|
||||
file_ext = "axt"
|
||||
|
||||
def sniff( self, filename ):
|
||||
@@ -895,13 +898,14 @@ class Axt( data.Text ):
|
||||
|
||||
class Lav( data.Text ):
|
||||
"""Class describing a LAV alignment"""
|
||||
edam_format = "format_3014"
|
||||
file_ext = "lav"
|
||||
|
||||
# gvk- 11/19/09 - This is really an alignment, but we no longer have tools that use this data type, and it is
|
||||
# here simply for backward compatibility ( although it is still in the datatypes registry ). Subclassing
|
||||
# from data.Text eliminates managing metadata elements inherited from the Alignemnt class.
|
||||
|
||||
edam_data = "data_0863"
|
||||
edam_format = "format_3014"
|
||||
file_ext = "lav"
|
||||
|
||||
def sniff( self, filename ):
|
||||
"""
|
||||
Determines whether the file is in lav format
|
||||
@@ -963,6 +967,7 @@ class RNADotPlotMatrix( data.Data ):
|
||||
|
||||
|
||||
class DotBracket ( Sequence ):
|
||||
edam_data = "data_0880"
|
||||
edam_format = "format_1457"
|
||||
file_ext = "dbn"
|
||||
|
||||
@@ -983,7 +988,7 @@ class DotBracket ( Sequence ):
|
||||
data_lines = 0
|
||||
sequences = 0
|
||||
|
||||
for line in file( dataset.file_name ):
|
||||
for line in open( dataset.file_name ):
|
||||
line = line.strip()
|
||||
data_lines += 1
|
||||
|
||||
|
||||
@@ -105,16 +105,16 @@ def convert_newlines( fname, in_place=True, tmp_dir=None, tmp_prefix=None ):
|
||||
to Posix line endings.
|
||||
|
||||
>>> fname = get_test_fname('temp.txt')
|
||||
>>> file(fname, 'wt').write("1 2\\r3 4")
|
||||
>>> open(fname, 'wt').write("1 2\\r3 4")
|
||||
>>> convert_newlines(fname, tmp_prefix="gxtest", tmp_dir=tempfile.gettempdir())
|
||||
(2, None)
|
||||
>>> file(fname).read()
|
||||
>>> open(fname).read()
|
||||
'1 2\\n3 4\\n'
|
||||
"""
|
||||
fd, temp_name = tempfile.mkstemp( prefix=tmp_prefix, dir=tmp_dir )
|
||||
fp = os.fdopen( fd, "wt" )
|
||||
i = None
|
||||
for i, line in enumerate( file( fname, "U" ) ):
|
||||
for i, line in enumerate( open( fname, "U" ) ):
|
||||
fp.write( "%s\n" % line.rstrip( "\r\n" ) )
|
||||
fp.close()
|
||||
if i is None:
|
||||
@@ -134,17 +134,17 @@ def sep2tabs( fname, in_place=True, patt="\\s+" ):
|
||||
Transforms in place a 'sep' separated file to a tab separated one
|
||||
|
||||
>>> fname = get_test_fname('temp.txt')
|
||||
>>> file(fname, 'wt').write("1 2\\n3 4\\n")
|
||||
>>> open(fname, 'wt').write("1 2\\n3 4\\n")
|
||||
>>> sep2tabs(fname)
|
||||
(2, None)
|
||||
>>> file(fname).read()
|
||||
>>> open(fname).read()
|
||||
'1\\t2\\n3\\t4\\n'
|
||||
"""
|
||||
regexp = re.compile( patt )
|
||||
fd, temp_name = tempfile.mkstemp()
|
||||
fp = os.fdopen( fd, "wt" )
|
||||
i = None
|
||||
for i, line in enumerate( file( fname ) ):
|
||||
for i, line in enumerate( open( fname ) ):
|
||||
line = line.rstrip( '\r\n' )
|
||||
elems = regexp.split( line )
|
||||
fp.write( "%s\n" % '\t'.join( elems ) )
|
||||
@@ -167,16 +167,16 @@ def convert_newlines_sep2tabs( fname, in_place=True, patt="\\s+", tmp_dir=None,
|
||||
so that files do not need to be read twice
|
||||
|
||||
>>> fname = get_test_fname('temp.txt')
|
||||
>>> file(fname, 'wt').write("1 2\\r3 4")
|
||||
>>> open(fname, 'wt').write("1 2\\r3 4")
|
||||
>>> convert_newlines_sep2tabs(fname, tmp_prefix="gxtest", tmp_dir=tempfile.gettempdir())
|
||||
(2, None)
|
||||
>>> file(fname).read()
|
||||
>>> open(fname).read()
|
||||
'1\\t2\\n3\\t4\\n'
|
||||
"""
|
||||
regexp = re.compile( patt )
|
||||
fd, temp_name = tempfile.mkstemp( prefix=tmp_prefix, dir=tmp_dir )
|
||||
fp = os.fdopen( fd, "wt" )
|
||||
for i, line in enumerate( file( fname, "U" ) ):
|
||||
for i, line in enumerate( open( fname, "U" ) ):
|
||||
line = line.rstrip( '\r\n' )
|
||||
elems = regexp.split( line )
|
||||
fp.write( "%s\n" % '\t'.join( elems ) )
|
||||
@@ -297,15 +297,15 @@ def guess_ext( fname, sniff_order, is_multi_byte=False ):
|
||||
>>> guess_ext(fname, sniff_order)
|
||||
'gff3'
|
||||
>>> fname = get_test_fname('temp.txt')
|
||||
>>> file(fname, 'wt').write("a\\t2")
|
||||
>>> open(fname, 'wt').write("a\\t2")
|
||||
>>> guess_ext(fname, sniff_order)
|
||||
'txt'
|
||||
>>> fname = get_test_fname('temp.txt')
|
||||
>>> file(fname, 'wt').write("a\\t2\\nc\\t1\\nd\\t0")
|
||||
>>> open(fname, 'wt').write("a\\t2\\nc\\t1\\nd\\t0")
|
||||
>>> guess_ext(fname, sniff_order)
|
||||
'tabular'
|
||||
>>> fname = get_test_fname('temp.txt')
|
||||
>>> file(fname, 'wt').write("a 1 2 x\\nb 3 4 y\\nc 5 6 z")
|
||||
>>> open(fname, 'wt').write("a 1 2 x\\nb 3 4 y\\nc 5 6 z")
|
||||
>>> guess_ext(fname, sniff_order)
|
||||
'txt'
|
||||
>>> fname = get_test_fname('test_tab1.tabular')
|
||||
|
||||
@@ -408,6 +408,7 @@ class Taxonomy( Tabular ):
|
||||
@dataproviders.decorators.has_dataproviders
|
||||
class Sam( Tabular ):
|
||||
edam_format = "format_2573"
|
||||
edam_data = "data_0863"
|
||||
file_ext = 'sam'
|
||||
track_type = "ReadTrack"
|
||||
data_sources = { "data": "bam", "index": "bigwig" }
|
||||
@@ -1047,7 +1048,7 @@ class ConnectivityTable( Tabular ):
|
||||
def set_meta( self, dataset, **kwd ):
|
||||
data_lines = 0
|
||||
|
||||
for line in file( dataset.file_name ):
|
||||
for line in open( dataset.file_name ):
|
||||
data_lines += 1
|
||||
|
||||
dataset.metadata.data_lines = data_lines
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
REMARK 9 active torsions:
|
||||
REMARK status: ('A' for Active; 'I' for Inactive)
|
||||
REMARK 1 A between atoms: C_2 and O_3
|
||||
REMARK 2 A between atoms: C_2 and C_14
|
||||
REMARK 3 A between atoms: O_3 and C_4
|
||||
REMARK 4 A between atoms: C_4 and C_5
|
||||
REMARK 5 A between atoms: C_6 and C_8
|
||||
REMARK 6 A between atoms: C_8 and C_9
|
||||
REMARK 7 A between atoms: C_9 and C_10
|
||||
REMARK 8 A between atoms: C_16 and O_17
|
||||
REMARK 9 A between atoms: C_19 and O_20
|
||||
ROOT
|
||||
ATOM 1 O LIG d 1 -0.947 -0.436 -3.210 0.00 0.00 -0.259 OA
|
||||
ATOM 2 C LIG d 1 -1.207 0.245 -2.235 0.00 0.00 0.293 C
|
||||
ENDROOT
|
||||
BRANCH 2 3
|
||||
ATOM 3 O LIG d 1 -1.935 -0.114 -1.151 0.00 0.00 -0.314 OA
|
||||
BRANCH 3 4
|
||||
ATOM 4 C LIG d 1 -2.338 -1.483 -1.065 0.00 0.00 0.206 C
|
||||
BRANCH 4 5
|
||||
ATOM 5 C LIG d 1 -1.745 -2.032 0.200 0.00 0.00 0.002 C
|
||||
ATOM 6 C LIG d 1 -0.550 -2.644 0.338 0.00 0.00 -0.085 C
|
||||
ATOM 7 C LIG d 1 0.405 -2.885 -0.801 0.00 0.00 0.043 C
|
||||
BRANCH 6 8
|
||||
ATOM 8 C LIG d 1 -0.086 -3.153 1.694 0.00 0.00 0.037 C
|
||||
BRANCH 8 9
|
||||
ATOM 9 C LIG d 1 0.730 -2.114 2.473 0.00 0.00 0.031 C
|
||||
BRANCH 9 10
|
||||
ATOM 10 C LIG d 1 1.187 -2.618 3.818 0.00 0.00 -0.024 C
|
||||
ATOM 11 C LIG d 1 2.352 -3.233 4.110 0.00 0.00 -0.091 C
|
||||
ATOM 12 C LIG d 1 3.401 -3.605 3.099 0.00 0.00 0.042 C
|
||||
ATOM 13 C LIG d 1 2.699 -3.614 5.527 0.00 0.00 0.042 C
|
||||
ENDBRANCH 9 10
|
||||
ENDBRANCH 8 9
|
||||
ENDBRANCH 6 8
|
||||
ENDBRANCH 4 5
|
||||
ENDBRANCH 3 4
|
||||
ENDBRANCH 2 3
|
||||
BRANCH 2 14
|
||||
ATOM 14 C LIG d 1 -0.778 1.657 -2.066 0.00 0.00 0.042 A
|
||||
ATOM 15 C LIG d 1 -0.640 2.224 -0.790 0.00 0.00 0.057 A
|
||||
ATOM 16 C LIG d 1 -0.249 3.551 -0.677 0.00 0.00 0.099 A
|
||||
ATOM 17 C LIG d 1 0.012 4.308 -1.816 0.00 0.00 0.098 A
|
||||
ATOM 18 C LIG d 1 -0.102 3.753 -3.083 0.00 0.00 0.040 A
|
||||
ATOM 19 C LIG d 1 -0.494 2.419 -3.212 0.00 0.00 0.020 A
|
||||
BRANCH 16 20
|
||||
ATOM 20 O LIG d 1 -0.104 4.159 0.540 0.00 0.00 -0.358 OA
|
||||
ATOM 21 HO LIG d 1 0.164 5.067 0.617 1.00 0.00 0.217 HD
|
||||
ENDBRANCH 16 20
|
||||
BRANCH 17 22
|
||||
ATOM 22 O LIG d 1 0.389 5.614 -1.691 0.00 0.00 -0.358 OA
|
||||
ATOM 23 HO LIG d 1 0.567 6.131 -2.469 1.00 0.00 0.217 HD
|
||||
ENDBRANCH 17 22
|
||||
ENDBRANCH 2 14
|
||||
TORSDOF 9
|
||||
@@ -260,6 +260,7 @@ class Obo( Text ):
|
||||
OBO file format description
|
||||
http://www.geneontology.org/GO.format.obo-1_2.shtml
|
||||
"""
|
||||
edam_data = "data_0582"
|
||||
edam_format = "format_2549"
|
||||
file_ext = "obo"
|
||||
|
||||
@@ -295,6 +296,7 @@ class Arff( Text ):
|
||||
An ARFF (Attribute-Relation File Format) file is an ASCII text file that describes a list of instances sharing a set of attributes.
|
||||
http://weka.wikispaces.com/ARFF
|
||||
"""
|
||||
edam_format = "format_3581"
|
||||
file_ext = "arff"
|
||||
|
||||
"""Add metadata elements"""
|
||||
@@ -393,6 +395,7 @@ class Arff( Text ):
|
||||
|
||||
class SnpEffDb( Text ):
|
||||
"""Class describing a SnpEff genome build"""
|
||||
edam_format = "format_3624"
|
||||
file_ext = "snpeffdb"
|
||||
MetadataElement( name="genome_version", default=None, desc="Genome Version", readonly=True, visible=True, no_value=None )
|
||||
MetadataElement( name="snpeff_version", default="SnpEff4.0", desc="SnpEff Version", readonly=True, visible=True, no_value=None )
|
||||
@@ -451,21 +454,20 @@ class SnpEffDb( Text ):
|
||||
dataset.metadata.regulation = regulations
|
||||
dataset.metadata.annotation = annotations
|
||||
try:
|
||||
fh = file(dataset.file_name, 'w')
|
||||
fh.write("%s\n" % genome_version if genome_version else 'Genome unknown')
|
||||
fh.write("%s\n" % snpeff_version if snpeff_version else 'SnpEff version unknown')
|
||||
if annotations:
|
||||
fh.write("annotations: %s\n" % ','.join(annotations))
|
||||
if regulations:
|
||||
fh.write("regulations: %s\n" % ','.join(regulations))
|
||||
fh.close()
|
||||
with open(dataset.file_name, 'w') as fh:
|
||||
fh.write("%s\n" % genome_version if genome_version else 'Genome unknown')
|
||||
fh.write("%s\n" % snpeff_version if snpeff_version else 'SnpEff version unknown')
|
||||
if annotations:
|
||||
fh.write("annotations: %s\n" % ','.join(annotations))
|
||||
if regulations:
|
||||
fh.write("regulations: %s\n" % ','.join(regulations))
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
class SnpSiftDbNSFP( Text ):
|
||||
"""Class describing a dbNSFP database prepared fpr use by SnpSift dbnsfp """
|
||||
MetadataElement( name='reference_name', default='dbSNFP' , desc='Reference Name', readonly=True, visible=True, set_in_upload=True, no_value='dbSNFP' )
|
||||
MetadataElement( name='reference_name', default='dbSNFP', desc='Reference Name', readonly=True, visible=True, set_in_upload=True, no_value='dbSNFP' )
|
||||
MetadataElement( name="bgzip", default=None, desc="dbNSFP bgzip", readonly=True, visible=True, no_value=None )
|
||||
MetadataElement( name="index", default=None, desc="Tabix Index File", readonly=True, visible=True, no_value=None)
|
||||
MetadataElement( name="annotation", default=[], desc="Annotation Names", readonly=True, visible=True, no_value=[] )
|
||||
@@ -526,14 +528,14 @@ class SnpSiftDbNSFP( Text ):
|
||||
headers = lines[0].split('\t')
|
||||
dataset.metadata.annotation = headers[4:]
|
||||
except Exception as e:
|
||||
log.warn("set_meta fname: %s %s" % (fname, str(e)))
|
||||
log.warning("set_meta fname: %s %s" % (fname, str(e)))
|
||||
finally:
|
||||
fh.close()
|
||||
if fname.endswith('.tbi'):
|
||||
dataset.metadata.index = fname
|
||||
self.regenerate_primary_file(dataset)
|
||||
except Exception as e:
|
||||
log.warn("set_meta fname: %s %s" % (dataset.file_name if dataset and dataset.file_name else 'Unkwown', str(e)))
|
||||
log.warning("set_meta fname: %s %s" % (dataset.file_name if dataset and dataset.file_name else 'Unkwown', str(e)))
|
||||
|
||||
def set_peek( self, dataset, is_multi_byte=False ):
|
||||
if not dataset.dataset.purged:
|
||||
|
||||
@@ -12,6 +12,7 @@ log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class GeneTrack( binary.Binary ):
|
||||
edam_data = "data_3002"
|
||||
edam_format = "format_2919"
|
||||
file_ext = "genetrack"
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ class Triples( data.Text ):
|
||||
"""
|
||||
The abstract base class for the file format that can contain triples
|
||||
"""
|
||||
edam_data = "data_0582"
|
||||
edam_format = "format_2376"
|
||||
file_ext = "triples"
|
||||
|
||||
|
||||
@@ -94,6 +94,8 @@ class CisML( GenericXml ):
|
||||
|
||||
class Phyloxml( GenericXml ):
|
||||
"""Format for defining phyloxml data http://www.phyloxml.org/"""
|
||||
edam_data = "data_0872"
|
||||
edam_format = "format_3159"
|
||||
file_ext = "phyloxml"
|
||||
|
||||
def set_peek( self, dataset, is_multi_byte=False ):
|
||||
|
||||
@@ -3,7 +3,6 @@ Determine what optional dependencies are needed.
|
||||
"""
|
||||
import pkg_resources
|
||||
|
||||
from sys import version_info
|
||||
from os.path import dirname, join
|
||||
from xml.etree import ElementTree
|
||||
|
||||
@@ -77,12 +76,6 @@ class ConditionalDependencies( object ):
|
||||
# pygments is a dependency of weberror and only weberror
|
||||
return self.check_weberror()
|
||||
|
||||
def check_importlib( self ):
|
||||
return version_info < (2, 7)
|
||||
|
||||
def check_ordereddict( self ):
|
||||
return version_info < (2, 7)
|
||||
|
||||
|
||||
def optional( config_file ):
|
||||
rval = []
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user