galaxy-commits
Threads by month
- ----- 2026 -----
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- 15302 discussions
commit/galaxy-central: carlfeberhard: History API: update documentation
by commits-noreply@bitbucket.org 29 Jan '15
by commits-noreply@bitbucket.org 29 Jan '15
29 Jan '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/c805913c4646/
Changeset: c805913c4646
User: carlfeberhard
Date: 2015-01-29 16:13:28+00:00
Summary: History API: update documentation
Affected #: 2 files
diff -r e0441a0f85307fb9caf854fd10133f71cc3852d3 -r c805913c4646238890e727a5f1c203058c6413b6 lib/galaxy/managers/histories.py
--- a/lib/galaxy/managers/histories.py
+++ b/lib/galaxy/managers/histories.py
@@ -384,12 +384,12 @@
#TODO: I'm not entirely convinced this (or tags) are a good idea for filters since they involve a/the user
self.fn_filter_parsers.update({
#TODO: add this in annotatable mixin
- 'annotation' : { 'op': { 'in' : self.filter_annotation_contains, } },
+ 'annotation' : { 'op': { 'has' : self.filter_annotation_contains, } },
#TODO: add this in taggable mixin
'tag' : {
'op': {
'eq' : self.filter_has_tag,
- 'in' : self.filter_has_partial_tag,
+ 'has': self.filter_has_partial_tag,
}
}
})
diff -r e0441a0f85307fb9caf854fd10133f71cc3852d3 -r c805913c4646238890e727a5f1c203058c6413b6 lib/galaxy/webapps/galaxy/api/histories.py
--- a/lib/galaxy/webapps/galaxy/api/histories.py
+++ b/lib/galaxy/webapps/galaxy/api/histories.py
@@ -56,6 +56,44 @@
:rtype: list
:returns: list of dictionaries containing summary history information
+
+ The following are optional parameters:
+ view: string, one of ('summary','detailed'), defaults to 'summary'
+ controls which set of properties to return
+ keys: comma separated strings, unused by default
+ keys/names of individual properties to return
+
+ If neither keys or views are sent, the default view (set of keys) is returned.
+ If both a view and keys are sent, the key list and the view's keys are
+ combined.
+ If keys are send and no view, only those properties in keys are returned.
+
+ For which properties are available see:
+ galaxy/managers/histories/HistorySerializer
+
+ The list returned can be filtered by using two optional parameters:
+ q: string, generally a property name to filter by followed
+ by an (often optional) hyphen and operator string.
+ qv: string, the value to filter by
+
+ ..example:
+ To filter the list to only those created after 2015-01-29,
+ the query string would look like:
+ '?q=create_time-gt&qv=2015-01-29'
+
+ Multiple filters can be sent in using multiple q/qv pairs:
+ '?q=create_time-gt&qv=2015-01-29&q=tag-has&qv=experiment-1'
+
+ The list returned can be paginated using two optional parameters:
+ limit: integer, defaults to no value and no limit (return all)
+ how many items to return
+ offset: integer, defaults to 0 and starts at the beginning
+ skip the first ( offset - 1 ) items and begin returning
+ at the Nth item
+
+ ..example:
+ limit and offset can be combined. Skip the first two and return five:
+ '?limit=5&offset=3'
"""
serialization_params = self._parse_serialization_params( kwd, 'summary' )
limit, offset = self.parse_limit_offset( kwd )
@@ -126,6 +164,9 @@
:type deleted: boolean
:param deleted: if True, allow information on a deleted history to be shown.
+ :param keys: same as the use of `keys` in the `index` function above
+ :param view: same as the use of `view` in the `index` function above
+
:rtype: dictionary
:returns: detailed history information
"""
@@ -172,6 +213,9 @@
* archive_source: the url that will generate the archive to import
* archive_type: 'url' (default)
+ :param keys: same as the use of `keys` in the `index` function above
+ :param view: same as the use of `view` in the `index` function above
+
:rtype: dict
:returns: element view of new history
"""
@@ -220,6 +264,9 @@
* payload: a dictionary itself containing:
* purge: if True, purge the history and all of its HDAs
+ :param keys: same as the use of `keys` in the `index` function above
+ :param view: same as the use of `view` in the `index` function above
+
:rtype: dict
:returns: an error object if an error occurred or a dictionary containing:
* id: the encoded id of the history,
@@ -250,6 +297,9 @@
:type id: str
:param id: the encoded id of the history to undelete
+ :param keys: same as the use of `keys` in the `index` function above
+ :param view: same as the use of `view` in the `index` function above
+
:rtype: str
:returns: 'OK' if the history was undeleted
"""
@@ -275,6 +325,9 @@
* annotation: an annotation for the history
+ :param keys: same as the use of `keys` in the `index` function above
+ :param view: same as the use of `view` in the `index` function above
+
:rtype: dict
:returns: an error object if an error occurred or a dictionary containing
any values that were different from the original and, therefore, updated
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: guerler: Workflow: Revise action form
by commits-noreply@bitbucket.org 29 Jan '15
by commits-noreply@bitbucket.org 29 Jan '15
29 Jan '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/e0441a0f8530/
Changeset: e0441a0f8530
User: guerler
Date: 2015-01-29 15:56:15+00:00
Summary: Workflow: Revise action form
Affected #: 9 files
diff -r 68f0ed37e08942acb1bb84b63911b22d7d4b6f65 -r e0441a0f85307fb9caf854fd10133f71cc3852d3 client/galaxy/scripts/mvc/tools/tools-form-workflow.js
--- a/client/galaxy/scripts/mvc/tools/tools-form-workflow.js
+++ b/client/galaxy/scripts/mvc/tools/tools-form-workflow.js
@@ -9,27 +9,29 @@
initialize: function(options) {
// link with node representation in workflow module
this.node = workflow.active_node;
-
if (!this.node) {
console.debug('FAILED - tools-form-workflow:initialize() - Node not found in workflow.');
return;
}
-
+
+ // link actions
+ this.post_job_actions = this.node.post_job_actions || {};
+
// initialize parameters
this.options = options;
-
+
// set labels
this.options.text_enable = 'In Advance';
this.options.text_disable = 'At Runtime';
this.options.use_defaults = true;
-
+
// declare fields as optional
Utils.deepeach(options.inputs, function(item) {
if (item.type) {
item.optional = (['data', 'data_hidden', 'hidden', 'drill_down', 'repeat', 'conditional']).indexOf(item.type) == -1;
}
});
-
+
// declare conditional fields as not optional
Utils.deepeach(options.inputs, function(item) {
if (item.type) {
@@ -51,32 +53,53 @@
}
});
},
-
+
/** Builds all sub sections
*/
_makeSections: function(inputs){
// for annotation
inputs[Utils.uuid()] = {
- label : 'Edit Step Attributes',
- type : 'section',
- expand : this.node.annotation,
- inputs : [{
- label : 'Annotation / Notes',
- name : 'annotation',
- type : 'text',
- area : true,
- help : 'Add an annotation or notes to this step; annotations are available when a workflow is viewed.',
- value : this.node.annotation
- }]
+ label : 'Annotation / Notes',
+ name : 'annotation',
+ type : 'text',
+ area : true,
+ help : 'Add an annotation or note for this step. It will be shown with the workflow.',
+ value : this.node.annotation
}
-
- // for actions
- this.post_job_actions = this.node.post_job_actions;
- for (var i in this.node.output_terminals) {
- inputs[Utils.uuid()] = this._makeSection(i);
+
+ // get first output id
+ var output_id = this.node.output_terminals && Object.keys(this.node.output_terminals)[0];
+ if (output_id) {
+ // send email on job completion
+ inputs[Utils.uuid()] = {
+ name : 'pja__' + output_id + '__EmailAction',
+ label : 'Email notification',
+ type : 'boolean',
+ value : String(Boolean(this.post_job_actions['EmailAction' + output_id])),
+ ignore : 'false',
+ help : 'An email notification will be send when the job has completed.',
+ payload : {
+ 'host' : window.location.host
+ }
+ };
+
+ // delete non-output files
+ inputs[Utils.uuid()] = {
+ name : 'pja__' + output_id + '__DeleteIntermediatesAction',
+ label : 'Output cleanup',
+ type : 'boolean',
+ value : String(Boolean(this.post_job_actions['DeleteIntermediatesAction' + output_id])),
+ ignore : 'false',
+ help : 'Delete intermediate outputs if they are not used as input for another job.'
+ };
+
+ // add output specific actions
+ for (var i in this.node.output_terminals) {
+ inputs[Utils.uuid()] = this._makeSection(i);
+ }
}
},
-
+
/** Builds sub section with step actions/annotation
*/
_makeSection: function(output_id){
@@ -88,12 +111,12 @@
1 : this.datatypes[key]
});
}
-
+
// sort extensions
extensions.sort(function(a, b) {
return a.label > b.label ? 1 : a.label < b.label ? -1 : 0;
});
-
+
// add additional options
extensions.unshift({
0 : 'Sequences',
@@ -105,12 +128,12 @@
});
extensions.unshift({
0 : 'Leave unchanged',
- 1 : 'None'
+ 1 : ''
});
-
+
// create custom sub section
var input_config = {
- label : 'Edit Step Action: \'' + output_id + '\'',
+ label : 'Add Actions: \'' + output_id + '\'',
type : 'section',
inputs : [{
action : 'RenameDatasetAction',
@@ -125,7 +148,7 @@
argument : 'newtype',
label : 'Change datatype',
type : 'select',
- ignore : 'None',
+ ignore : '',
options : extensions,
help : 'This action will change the datatype of the output to the indicated value.'
},{
@@ -143,59 +166,42 @@
action : 'ColumnSetAction',
argument : 'chromCol',
label : 'Chrom column',
- type : 'text',
+ type : 'integer',
value : '',
ignore : ''
},{
action : 'ColumnSetAction',
argument : 'startCol',
label : 'Start column',
- type : 'text',
+ type : 'integer',
value : '',
ignore : ''
},{
action : 'ColumnSetAction',
argument : 'endCol',
label : 'End column',
- type : 'text',
+ type : 'integer',
value : '',
ignore : ''
},{
action : 'ColumnSetAction',
argument : 'strandCol',
label : 'Strand column',
- type : 'text',
+ type : 'integer',
value : '',
ignore : ''
},{
action : 'ColumnSetAction',
argument : 'nameCol',
label : 'Name column',
- type : 'text',
+ type : 'integer',
value : '',
ignore : ''
}],
help : 'This action will set column assignments in the output dataset. Blank fields are ignored.'
- },{
- action : 'EmailAction',
- label : 'Email notification',
- type : 'boolean',
- value : 'false',
- ignore : 'false',
- help : 'This action will send an email notifying you when the job is done.',
- payload : {
- 'host' : window.location.host
- }
- },{
- action : 'DeleteIntermediatesAction',
- label : 'Delete non-outputs',
- type : 'boolean',
- value : 'false',
- ignore : 'false',
- help : 'All non-output steps of this workflow will have datasets deleted if they are no longer being used as job inputs when the job this action is attached to is finished. You *must* be using workflow outputs (the snowflake) in your workflow for this to have any effect.'
}]
};
-
+
// visit input nodes and enrich by name/value pairs from server data
var self = this;
function visit (head, head_list) {
@@ -209,7 +215,7 @@
if (input.argument) {
input.name += '__' + input.argument;
}
-
+
// modify names of payload arguments
if (input.payload) {
for (var p_id in input.payload) {
@@ -218,7 +224,7 @@
delete p;
}
}
-
+
// access/verify existence of value
var d = self.post_job_actions[input.action + output_id];
if (d) {
@@ -242,11 +248,11 @@
}
}
visit(input_config);
-
+
// return final configuration
return input_config;
},
-
+
/** Builds a new model through api call and recreates the entire form
*/
_buildModel: function() {
@@ -260,24 +266,24 @@
}
});
},
-
+
/** Request a new model for an already created tool form and updates the form inputs
*/
_updateModel: function() {
// create the request dictionary
var self = this;
var current_state = this.tree.finalize();
-
+
// log tool state
console.debug('tools-form-workflow::_refreshForm() - Refreshing states.');
console.debug(current_state);
-
+
// register process
var process_id = this.deferred.register();
// build model url for request
var model_url = galaxy_config.root + 'workflow/editor_form_post?tool_id=' + this.options.id + '&__is_dynamic__=False';
-
+
// post job
Utils.request({
type : 'GET',
diff -r 68f0ed37e08942acb1bb84b63911b22d7d4b6f65 -r e0441a0f85307fb9caf854fd10133f71cc3852d3 client/galaxy/scripts/mvc/tools/tools-section.js
--- a/client/galaxy/scripts/mvc/tools/tools-section.js
+++ b/client/galaxy/scripts/mvc/tools/tools-section.js
@@ -275,6 +275,7 @@
}
});
portlet.append(sub_section.$el);
+ portlet.append($('<div/>').addClass('ui-table-form-info').html(input_def.help));
// add event handler visibility button
var visible = false;
diff -r 68f0ed37e08942acb1bb84b63911b22d7d4b6f65 -r e0441a0f85307fb9caf854fd10133f71cc3852d3 client/galaxy/scripts/mvc/ui/ui-slider.js
--- a/client/galaxy/scripts/mvc/ui/ui-slider.js
+++ b/client/galaxy/scripts/mvc/ui/ui-slider.js
@@ -54,7 +54,7 @@
}
// add text field event
- this.$text.on('change', function () {
+ this.$text.on('input', function () {
self.value($(this).val());
});
diff -r 68f0ed37e08942acb1bb84b63911b22d7d4b6f65 -r e0441a0f85307fb9caf854fd10133f71cc3852d3 static/scripts/mvc/tools/tools-form-workflow.js
--- a/static/scripts/mvc/tools/tools-form-workflow.js
+++ b/static/scripts/mvc/tools/tools-form-workflow.js
@@ -9,27 +9,29 @@
initialize: function(options) {
// link with node representation in workflow module
this.node = workflow.active_node;
-
if (!this.node) {
console.debug('FAILED - tools-form-workflow:initialize() - Node not found in workflow.');
return;
}
-
+
+ // link actions
+ this.post_job_actions = this.node.post_job_actions || {};
+
// initialize parameters
this.options = options;
-
+
// set labels
this.options.text_enable = 'In Advance';
this.options.text_disable = 'At Runtime';
this.options.use_defaults = true;
-
+
// declare fields as optional
Utils.deepeach(options.inputs, function(item) {
if (item.type) {
item.optional = (['data', 'data_hidden', 'hidden', 'drill_down', 'repeat', 'conditional']).indexOf(item.type) == -1;
}
});
-
+
// declare conditional fields as not optional
Utils.deepeach(options.inputs, function(item) {
if (item.type) {
@@ -51,32 +53,53 @@
}
});
},
-
+
/** Builds all sub sections
*/
_makeSections: function(inputs){
// for annotation
inputs[Utils.uuid()] = {
- label : 'Edit Step Attributes',
- type : 'section',
- expand : this.node.annotation,
- inputs : [{
- label : 'Annotation / Notes',
- name : 'annotation',
- type : 'text',
- area : true,
- help : 'Add an annotation or notes to this step; annotations are available when a workflow is viewed.',
- value : this.node.annotation
- }]
+ label : 'Annotation / Notes',
+ name : 'annotation',
+ type : 'text',
+ area : true,
+ help : 'Add an annotation or note for this step. It will be shown with the workflow.',
+ value : this.node.annotation
}
-
- // for actions
- this.post_job_actions = this.node.post_job_actions;
- for (var i in this.node.output_terminals) {
- inputs[Utils.uuid()] = this._makeSection(i);
+
+ // get first output id
+ var output_id = this.node.output_terminals && Object.keys(this.node.output_terminals)[0];
+ if (output_id) {
+ // send email on job completion
+ inputs[Utils.uuid()] = {
+ name : 'pja__' + output_id + '__EmailAction',
+ label : 'Email notification',
+ type : 'boolean',
+ value : String(Boolean(this.post_job_actions['EmailAction' + output_id])),
+ ignore : 'false',
+ help : 'An email notification will be send when the job has completed.',
+ payload : {
+ 'host' : window.location.host
+ }
+ };
+
+ // delete non-output files
+ inputs[Utils.uuid()] = {
+ name : 'pja__' + output_id + '__DeleteIntermediatesAction',
+ label : 'Output cleanup',
+ type : 'boolean',
+ value : String(Boolean(this.post_job_actions['DeleteIntermediatesAction' + output_id])),
+ ignore : 'false',
+ help : 'Delete intermediate outputs if they are not used as input for another job.'
+ };
+
+ // add output specific actions
+ for (var i in this.node.output_terminals) {
+ inputs[Utils.uuid()] = this._makeSection(i);
+ }
}
},
-
+
/** Builds sub section with step actions/annotation
*/
_makeSection: function(output_id){
@@ -88,12 +111,12 @@
1 : this.datatypes[key]
});
}
-
+
// sort extensions
extensions.sort(function(a, b) {
return a.label > b.label ? 1 : a.label < b.label ? -1 : 0;
});
-
+
// add additional options
extensions.unshift({
0 : 'Sequences',
@@ -105,12 +128,12 @@
});
extensions.unshift({
0 : 'Leave unchanged',
- 1 : 'None'
+ 1 : ''
});
-
+
// create custom sub section
var input_config = {
- label : 'Edit Step Action: \'' + output_id + '\'',
+ label : 'Add Actions: \'' + output_id + '\'',
type : 'section',
inputs : [{
action : 'RenameDatasetAction',
@@ -125,7 +148,7 @@
argument : 'newtype',
label : 'Change datatype',
type : 'select',
- ignore : 'None',
+ ignore : '',
options : extensions,
help : 'This action will change the datatype of the output to the indicated value.'
},{
@@ -143,59 +166,42 @@
action : 'ColumnSetAction',
argument : 'chromCol',
label : 'Chrom column',
- type : 'text',
+ type : 'integer',
value : '',
ignore : ''
},{
action : 'ColumnSetAction',
argument : 'startCol',
label : 'Start column',
- type : 'text',
+ type : 'integer',
value : '',
ignore : ''
},{
action : 'ColumnSetAction',
argument : 'endCol',
label : 'End column',
- type : 'text',
+ type : 'integer',
value : '',
ignore : ''
},{
action : 'ColumnSetAction',
argument : 'strandCol',
label : 'Strand column',
- type : 'text',
+ type : 'integer',
value : '',
ignore : ''
},{
action : 'ColumnSetAction',
argument : 'nameCol',
label : 'Name column',
- type : 'text',
+ type : 'integer',
value : '',
ignore : ''
}],
help : 'This action will set column assignments in the output dataset. Blank fields are ignored.'
- },{
- action : 'EmailAction',
- label : 'Email notification',
- type : 'boolean',
- value : 'false',
- ignore : 'false',
- help : 'This action will send an email notifying you when the job is done.',
- payload : {
- 'host' : window.location.host
- }
- },{
- action : 'DeleteIntermediatesAction',
- label : 'Delete non-outputs',
- type : 'boolean',
- value : 'false',
- ignore : 'false',
- help : 'All non-output steps of this workflow will have datasets deleted if they are no longer being used as job inputs when the job this action is attached to is finished. You *must* be using workflow outputs (the snowflake) in your workflow for this to have any effect.'
}]
};
-
+
// visit input nodes and enrich by name/value pairs from server data
var self = this;
function visit (head, head_list) {
@@ -209,7 +215,7 @@
if (input.argument) {
input.name += '__' + input.argument;
}
-
+
// modify names of payload arguments
if (input.payload) {
for (var p_id in input.payload) {
@@ -218,7 +224,7 @@
delete p;
}
}
-
+
// access/verify existence of value
var d = self.post_job_actions[input.action + output_id];
if (d) {
@@ -242,11 +248,11 @@
}
}
visit(input_config);
-
+
// return final configuration
return input_config;
},
-
+
/** Builds a new model through api call and recreates the entire form
*/
_buildModel: function() {
@@ -260,24 +266,24 @@
}
});
},
-
+
/** Request a new model for an already created tool form and updates the form inputs
*/
_updateModel: function() {
// create the request dictionary
var self = this;
var current_state = this.tree.finalize();
-
+
// log tool state
console.debug('tools-form-workflow::_refreshForm() - Refreshing states.');
console.debug(current_state);
-
+
// register process
var process_id = this.deferred.register();
// build model url for request
var model_url = galaxy_config.root + 'workflow/editor_form_post?tool_id=' + this.options.id + '&__is_dynamic__=False';
-
+
// post job
Utils.request({
type : 'GET',
diff -r 68f0ed37e08942acb1bb84b63911b22d7d4b6f65 -r e0441a0f85307fb9caf854fd10133f71cc3852d3 static/scripts/mvc/tools/tools-section.js
--- a/static/scripts/mvc/tools/tools-section.js
+++ b/static/scripts/mvc/tools/tools-section.js
@@ -275,6 +275,7 @@
}
});
portlet.append(sub_section.$el);
+ portlet.append($('<div/>').addClass('ui-table-form-info').html(input_def.help));
// add event handler visibility button
var visible = false;
diff -r 68f0ed37e08942acb1bb84b63911b22d7d4b6f65 -r e0441a0f85307fb9caf854fd10133f71cc3852d3 static/scripts/mvc/ui/ui-slider.js
--- a/static/scripts/mvc/ui/ui-slider.js
+++ b/static/scripts/mvc/ui/ui-slider.js
@@ -54,7 +54,7 @@
}
// add text field event
- this.$text.on('change', function () {
+ this.$text.on('input', function () {
self.value($(this).val());
});
diff -r 68f0ed37e08942acb1bb84b63911b22d7d4b6f65 -r e0441a0f85307fb9caf854fd10133f71cc3852d3 static/scripts/packed/mvc/tools/tools-form-workflow.js
--- a/static/scripts/packed/mvc/tools/tools-form-workflow.js
+++ b/static/scripts/packed/mvc/tools/tools-form-workflow.js
@@ -1,1 +1,1 @@
-define(["utils/utils","mvc/tools/tools-form-base"],function(b,a){var c=a.extend({initialize:function(e){this.node=workflow.active_node;if(!this.node){console.debug("FAILED - tools-form-workflow:initialize() - Node not found in workflow.");return}this.options=e;this.options.text_enable="In Advance";this.options.text_disable="At Runtime";this.options.use_defaults=true;b.deepeach(e.inputs,function(f){if(f.type){f.optional=(["data","data_hidden","hidden","drill_down","repeat","conditional"]).indexOf(f.type)==-1}});b.deepeach(e.inputs,function(f){if(f.type){if(f.type=="conditional"){f.test_param.optional=false}}});var d=this;b.get({url:galaxy_config.root+"api/datatypes",cache:true,success:function(f){d.datatypes=f;d._makeSections(e.inputs);a.prototype.initialize.call(d,e)}})},_makeSections:function(d){d[b.uuid()]={label:"Edit Step Attributes",type:"section",expand:this.node.annotation,inputs:[{label:"Annotation / Notes",name:"annotation",type:"text",area:true,help:"Add an annotation or notes to this step; annotations are available when a workflow is viewed.",value:this.node.annotation}]};this.post_job_actions=this.node.post_job_actions;for(var e in this.node.output_terminals){d[b.uuid()]=this._makeSection(e)}},_makeSection:function(h){var g=[];for(key in this.datatypes){g.push({0:this.datatypes[key],1:this.datatypes[key]})}g.sort(function(j,i){return j.label>i.label?1:j.label<i.label?-1:0});g.unshift({0:"Sequences",1:"Sequences"});g.unshift({0:"Roadmaps",1:"Roadmaps"});g.unshift({0:"Leave unchanged",1:"None"});var f={label:"Edit Step Action: '"+h+"'",type:"section",inputs:[{action:"RenameDatasetAction",argument:"newname",label:"Rename dataset",type:"text",value:"",ignore:"",help:'This action will rename the result dataset. Click <a href="https://wiki.galaxyproject.org/Learn/AdvancedWorkflow/Variables">here</a> for more information.'},{action:"ChangeDatatypeAction",argument:"newtype",label:"Change datatype",type:"select",ignore:"None",options:g,help:"This action will change the datatype of the output to the indicated value."},{action:"TagDatasetAction",argument:"tags",label:"Tags",type:"text",value:"",ignore:"",help:"This action will set tags for the dataset."},{label:"Assign columns",type:"section",inputs:[{action:"ColumnSetAction",argument:"chromCol",label:"Chrom column",type:"text",value:"",ignore:""},{action:"ColumnSetAction",argument:"startCol",label:"Start column",type:"text",value:"",ignore:""},{action:"ColumnSetAction",argument:"endCol",label:"End column",type:"text",value:"",ignore:""},{action:"ColumnSetAction",argument:"strandCol",label:"Strand column",type:"text",value:"",ignore:""},{action:"ColumnSetAction",argument:"nameCol",label:"Name column",type:"text",value:"",ignore:""}],help:"This action will set column assignments in the output dataset. Blank fields are ignored."},{action:"EmailAction",label:"Email notification",type:"boolean",value:"false",ignore:"false",help:"This action will send an email notifying you when the job is done.",payload:{host:window.location.host}},{action:"DeleteIntermediatesAction",label:"Delete non-outputs",type:"boolean",value:"false",ignore:"false",help:"All non-output steps of this workflow will have datasets deleted if they are no longer being used as job inputs when the job this action is attached to is finished. You *must* be using workflow outputs (the snowflake) in your workflow for this to have any effect."}]};var d=this;function e(n,o){o=o||[];o.push(n);for(var m in n.inputs){var k=n.inputs[m];if(k.action){k.name="pja__"+h+"__"+k.action;if(k.argument){k.name+="__"+k.argument}if(k.payload){for(var s in k.payload){var q=k.payload[s];k.payload[k.name+"__"+s]=q;delete q}}var r=d.post_job_actions[k.action+h];if(r){for(var l in o){o[l].expand=true}if(k.argument){k.value=r.action_arguments&&r.action_arguments[k.argument]||k.value}else{k.value="true"}}}if(k.inputs){e(k,o.slice(0))}}}e(f);return f},_buildModel:function(){Galaxy.modal.show({title:"Coming soon...",body:"This feature has not been implemented yet.",buttons:{Close:function(){Galaxy.modal.hide()}}})},_updateModel:function(){var d=this;var e=this.tree.finalize();console.debug("tools-form-workflow::_refreshForm() - Refreshing states.");console.debug(e);var g=this.deferred.register();var f=galaxy_config.root+"workflow/editor_form_post?tool_id="+this.options.id+"&__is_dynamic__=False";b.request({type:"GET",url:f,data:e,success:function(h){d.node.update_field_data(h);d._errors(h&&h.tool_model);d.deferred.done(g);console.debug("tools-form::_refreshForm() - States refreshed.");console.debug(h)},error:function(h){d.deferred.done(g);console.debug("tools-form::_refreshForm() - Refresh request failed.");console.debug(h)}})}});return{View:c}});
\ No newline at end of file
+define(["utils/utils","mvc/tools/tools-form-base"],function(b,a){var c=a.extend({initialize:function(e){this.node=workflow.active_node;if(!this.node){console.debug("FAILED - tools-form-workflow:initialize() - Node not found in workflow.");return}this.post_job_actions=this.node.post_job_actions||{};this.options=e;this.options.text_enable="In Advance";this.options.text_disable="At Runtime";this.options.use_defaults=true;b.deepeach(e.inputs,function(f){if(f.type){f.optional=(["data","data_hidden","hidden","drill_down","repeat","conditional"]).indexOf(f.type)==-1}});b.deepeach(e.inputs,function(f){if(f.type){if(f.type=="conditional"){f.test_param.optional=false}}});var d=this;b.get({url:galaxy_config.root+"api/datatypes",cache:true,success:function(f){d.datatypes=f;d._makeSections(e.inputs);a.prototype.initialize.call(d,e)}})},_makeSections:function(d){d[b.uuid()]={label:"Annotation / Notes",name:"annotation",type:"text",area:true,help:"Add an annotation or note for this step. It will be shown with the workflow.",value:this.node.annotation};var f=this.node.output_terminals&&Object.keys(this.node.output_terminals)[0];if(f){d[b.uuid()]={name:"pja__"+f+"__EmailAction",label:"Email notification",type:"boolean",value:String(Boolean(this.post_job_actions["EmailAction"+f])),ignore:"false",help:"An email notification will be send when the job has completed.",payload:{host:window.location.host}};d[b.uuid()]={name:"pja__"+f+"__DeleteIntermediatesAction",label:"Output cleanup",type:"boolean",value:String(Boolean(this.post_job_actions["DeleteIntermediatesAction"+f])),ignore:"false",help:"Delete intermediate outputs if they are not used as input for another job."};for(var e in this.node.output_terminals){d[b.uuid()]=this._makeSection(e)}}},_makeSection:function(h){var g=[];for(key in this.datatypes){g.push({0:this.datatypes[key],1:this.datatypes[key]})}g.sort(function(j,i){return j.label>i.label?1:j.label<i.label?-1:0});g.unshift({0:"Sequences",1:"Sequences"});g.unshift({0:"Roadmaps",1:"Roadmaps"});g.unshift({0:"Leave unchanged",1:""});var f={label:"Add Actions: '"+h+"'",type:"section",inputs:[{action:"RenameDatasetAction",argument:"newname",label:"Rename dataset",type:"text",value:"",ignore:"",help:'This action will rename the result dataset. Click <a href="https://wiki.galaxyproject.org/Learn/AdvancedWorkflow/Variables">here</a> for more information.'},{action:"ChangeDatatypeAction",argument:"newtype",label:"Change datatype",type:"select",ignore:"",options:g,help:"This action will change the datatype of the output to the indicated value."},{action:"TagDatasetAction",argument:"tags",label:"Tags",type:"text",value:"",ignore:"",help:"This action will set tags for the dataset."},{label:"Assign columns",type:"section",inputs:[{action:"ColumnSetAction",argument:"chromCol",label:"Chrom column",type:"integer",value:"",ignore:""},{action:"ColumnSetAction",argument:"startCol",label:"Start column",type:"integer",value:"",ignore:""},{action:"ColumnSetAction",argument:"endCol",label:"End column",type:"integer",value:"",ignore:""},{action:"ColumnSetAction",argument:"strandCol",label:"Strand column",type:"integer",value:"",ignore:""},{action:"ColumnSetAction",argument:"nameCol",label:"Name column",type:"integer",value:"",ignore:""}],help:"This action will set column assignments in the output dataset. Blank fields are ignored."}]};var d=this;function e(n,o){o=o||[];o.push(n);for(var m in n.inputs){var k=n.inputs[m];if(k.action){k.name="pja__"+h+"__"+k.action;if(k.argument){k.name+="__"+k.argument}if(k.payload){for(var s in k.payload){var q=k.payload[s];k.payload[k.name+"__"+s]=q;delete q}}var r=d.post_job_actions[k.action+h];if(r){for(var l in o){o[l].expand=true}if(k.argument){k.value=r.action_arguments&&r.action_arguments[k.argument]||k.value}else{k.value="true"}}}if(k.inputs){e(k,o.slice(0))}}}e(f);return f},_buildModel:function(){Galaxy.modal.show({title:"Coming soon...",body:"This feature has not been implemented yet.",buttons:{Close:function(){Galaxy.modal.hide()}}})},_updateModel:function(){var d=this;var e=this.tree.finalize();console.debug("tools-form-workflow::_refreshForm() - Refreshing states.");console.debug(e);var g=this.deferred.register();var f=galaxy_config.root+"workflow/editor_form_post?tool_id="+this.options.id+"&__is_dynamic__=False";b.request({type:"GET",url:f,data:e,success:function(h){d.node.update_field_data(h);d._errors(h&&h.tool_model);d.deferred.done(g);console.debug("tools-form::_refreshForm() - States refreshed.");console.debug(h)},error:function(h){d.deferred.done(g);console.debug("tools-form::_refreshForm() - Refresh request failed.");console.debug(h)}})}});return{View:c}});
\ No newline at end of file
diff -r 68f0ed37e08942acb1bb84b63911b22d7d4b6f65 -r e0441a0f85307fb9caf854fd10133f71cc3852d3 static/scripts/packed/mvc/tools/tools-section.js
--- a/static/scripts/packed/mvc/tools/tools-section.js
+++ b/static/scripts/packed/mvc/tools/tools-section.js
@@ -1,1 +1,1 @@
-define(["utils/utils","mvc/ui/ui-table","mvc/ui/ui-misc","mvc/ui/ui-portlet","mvc/tools/tools-repeat","mvc/tools/tools-select-content","mvc/tools/tools-input"],function(e,b,h,d,c,a,f){var g=Backbone.View.extend({initialize:function(j,i){this.app=j;this.inputs=i.inputs;i.cls="ui-table-plain";i.cls_tr="section-row";this.table=new b.View(i);this.setElement(this.table.$el);this.render()},render:function(){this.table.delAll();for(var j in this.inputs){this.add(this.inputs[j])}},add:function(k){var j=this;var i=jQuery.extend(true,{},k);i.id=k.id=e.uuid();this.app.input_list[i.id]=i;var l=i.type;switch(l){case"conditional":this._addConditional(i);break;case"repeat":this._addRepeat(i);break;case"section":this._addSection(i);break;default:this._addRow(i)}},_addConditional:function(j){var k=this;j.test_param.id=j.id;var n=this._addRow(j.test_param);n.options.onchange=function(w){var v=k.app.tree.matchCase(j,w);for(var u in j.cases){var q=j.cases[u];var t=j.id+"-section-"+u;var p=k.table.get(t);var s=false;for(var r in q.inputs){if(!q.inputs[r].hidden){s=true;break}}if(u==v&&s){p.fadeIn("fast")}else{p.hide()}}k.app.trigger("refresh")};for(var m in j.cases){var l=j.id+"-section-"+m;var o=new g(this.app,{inputs:j.cases[m].inputs});o.$el.addClass("ui-table-form-section");this.table.add(o.$el);this.table.append(l)}n.trigger("change")},_addRepeat:function(p){var s=this;var q=0;function n(i,u){var t=p.id+"-section-"+(q++);var v=null;if(u){v=function(){l.del(t);l.retitle(p.title);s.app.trigger("refresh")}}var w=new g(s.app,{inputs:i});l.add({id:t,title:p.title,$el:w.$el,ondel:v});l.retitle(p.title)}var l=new c.View({title_new:p.title,max:p.max,onnew:function(){n(p.inputs,true);s.app.trigger("refresh")}});var j=p.min;var r=_.size(p.cache);for(var m=0;m<Math.max(r,j);m++){var o=null;if(m<r){o=p.cache[m]}else{o=p.inputs}n(o,m>=j)}var k=new f(this.app,{label:p.title,help:p.help,field:l});k.$el.addClass("ui-table-form-section");this.table.add(k.$el);this.table.append(p.id)},_addSection:function(i){var j=this;var n=new g(j.app,{inputs:i.inputs});var m=new h.ButtonIcon({icon:"fa-eye-slash",tooltip:"Show/hide section",cls:"ui-button-icon-plain"});var l=new d.View({title:i.label,cls:"ui-portlet-section",operations:{button_visible:m}});l.append(n.$el);var k=false;l.$content.hide();l.$header.css("cursor","pointer");l.$header.on("click",function(){if(k){k=false;l.$content.hide();m.setIcon("fa-eye-slash")}else{k=true;l.$content.fadeIn("fast");m.setIcon("fa-eye")}});if(i.expand){l.$header.trigger("click")}this.table.add(l.$el);this.table.append(i.id)},_addRow:function(i){var l=i.id;var j=this._createField(i);this.app.field_list[l]=j;var k=new f(this.app,{label:i.label,default_value:i.default_value,optional:i.optional,help:i.help,field:j});this.app.element_list[l]=k;this.table.add(k.$el);this.table.append(l);if(i.hidden){this.table.get(l).hide()}return j},_createField:function(i){var j=null;switch(i.type){case"text":j=this._fieldText(i);break;case"select":j=this._fieldSelect(i);break;case"data":j=this._fieldData(i);break;case"data_collection":j=this._fieldData(i);break;case"data_column":i.error_text="Missing columns in referenced dataset.";j=this._fieldSelect(i);break;case"hidden":j=this._fieldHidden(i);break;case"hidden_data":j=this._fieldHidden(i);break;case"integer":j=this._fieldSlider(i);break;case"float":j=this._fieldSlider(i);break;case"boolean":j=this._fieldBoolean(i);break;case"genomebuild":i.searchable=true;j=this._fieldSelect(i);break;case"drill_down":j=this._fieldDrilldown(i);break;case"baseurl":j=this._fieldHidden(i);break;default:this.app.incompatible=true;if(i.options){j=this._fieldSelect(i)}else{j=this._fieldText(i)}console.debug("tools-form::_addRow() : Auto matched field type ("+i.type+").")}if(i.value!==undefined){j.value(i.value)}return j},_fieldData:function(i){if(!this.app.options.is_dynamic){i.info="Data input '"+i.name+"' ("+e.textify(i.extensions.toString())+")";i.value=null;return this._fieldHidden(i)}var j=this;return new a.View(this.app,{id:"field-"+i.id,extensions:i.extensions,optional:i.optional,multiple:i.multiple,type:i.type,data:i.options,onchange:function(){j.app.trigger("refresh")}})},_fieldSelect:function(j){if(!this.app.options.is_dynamic&&j.is_dynamic){return this._fieldText(j)}var l=[];for(var m in j.options){var n=j.options[m];l.push({label:n[0],value:n[1]})}var o=h.Select;switch(j.display){case"checkboxes":o=h.Checkbox;break;case"radio":o=h.Radio;break}var k=this;return new o.View({id:"field-"+j.id,data:l,error_text:j.error_text||"No options available",multiple:j.multiple,searchable:j.searchable,onchange:function(){k.app.trigger("refresh")}})},_fieldDrilldown:function(i){if(!this.app.options.is_dynamic&&i.is_dynamic){return this._fieldText(i)}var j=this;return new h.Drilldown.View({id:"field-"+i.id,data:i.options,display:i.display,onchange:function(){j.app.trigger("refresh")}})},_fieldText:function(i){if(i.options){i.area=i.multiple;if(!e.validate(i.value)){i.value=""}else{if(i.value instanceof Array){i.value=value.toString()}else{i.value=String(i.value).replace(/[\[\]'"\s]/g,"");if(i.multiple){i.value=i.value.replace(/,/g,"\n")}}}}var j=this;return new h.Input({id:"field-"+i.id,area:i.area,onchange:function(){j.app.trigger("refresh")}})},_fieldSlider:function(i){var j=this;return new h.Slider.View({id:"field-"+i.id,precise:i.type=="float",min:i.min,max:i.max,onchange:function(){j.app.trigger("refresh")}})},_fieldHidden:function(i){return new h.Hidden({id:"field-"+i.id,info:i.info})},_fieldBoolean:function(i){var j=this;return new h.RadioButton.View({id:"field-"+i.id,data:[{label:"Yes",value:"true"},{label:"No",value:"false"}],onchange:function(){j.app.trigger("refresh")}})}});return{View:g}});
\ No newline at end of file
+define(["utils/utils","mvc/ui/ui-table","mvc/ui/ui-misc","mvc/ui/ui-portlet","mvc/tools/tools-repeat","mvc/tools/tools-select-content","mvc/tools/tools-input"],function(e,b,h,d,c,a,f){var g=Backbone.View.extend({initialize:function(j,i){this.app=j;this.inputs=i.inputs;i.cls="ui-table-plain";i.cls_tr="section-row";this.table=new b.View(i);this.setElement(this.table.$el);this.render()},render:function(){this.table.delAll();for(var j in this.inputs){this.add(this.inputs[j])}},add:function(k){var j=this;var i=jQuery.extend(true,{},k);i.id=k.id=e.uuid();this.app.input_list[i.id]=i;var l=i.type;switch(l){case"conditional":this._addConditional(i);break;case"repeat":this._addRepeat(i);break;case"section":this._addSection(i);break;default:this._addRow(i)}},_addConditional:function(j){var k=this;j.test_param.id=j.id;var n=this._addRow(j.test_param);n.options.onchange=function(w){var v=k.app.tree.matchCase(j,w);for(var u in j.cases){var q=j.cases[u];var t=j.id+"-section-"+u;var p=k.table.get(t);var s=false;for(var r in q.inputs){if(!q.inputs[r].hidden){s=true;break}}if(u==v&&s){p.fadeIn("fast")}else{p.hide()}}k.app.trigger("refresh")};for(var m in j.cases){var l=j.id+"-section-"+m;var o=new g(this.app,{inputs:j.cases[m].inputs});o.$el.addClass("ui-table-form-section");this.table.add(o.$el);this.table.append(l)}n.trigger("change")},_addRepeat:function(p){var s=this;var q=0;function n(i,u){var t=p.id+"-section-"+(q++);var v=null;if(u){v=function(){l.del(t);l.retitle(p.title);s.app.trigger("refresh")}}var w=new g(s.app,{inputs:i});l.add({id:t,title:p.title,$el:w.$el,ondel:v});l.retitle(p.title)}var l=new c.View({title_new:p.title,max:p.max,onnew:function(){n(p.inputs,true);s.app.trigger("refresh")}});var j=p.min;var r=_.size(p.cache);for(var m=0;m<Math.max(r,j);m++){var o=null;if(m<r){o=p.cache[m]}else{o=p.inputs}n(o,m>=j)}var k=new f(this.app,{label:p.title,help:p.help,field:l});k.$el.addClass("ui-table-form-section");this.table.add(k.$el);this.table.append(p.id)},_addSection:function(i){var j=this;var n=new g(j.app,{inputs:i.inputs});var m=new h.ButtonIcon({icon:"fa-eye-slash",tooltip:"Show/hide section",cls:"ui-button-icon-plain"});var l=new d.View({title:i.label,cls:"ui-portlet-section",operations:{button_visible:m}});l.append(n.$el);l.append($("<div/>").addClass("ui-table-form-info").html(i.help));var k=false;l.$content.hide();l.$header.css("cursor","pointer");l.$header.on("click",function(){if(k){k=false;l.$content.hide();m.setIcon("fa-eye-slash")}else{k=true;l.$content.fadeIn("fast");m.setIcon("fa-eye")}});if(i.expand){l.$header.trigger("click")}this.table.add(l.$el);this.table.append(i.id)},_addRow:function(i){var l=i.id;var j=this._createField(i);this.app.field_list[l]=j;var k=new f(this.app,{label:i.label,default_value:i.default_value,optional:i.optional,help:i.help,field:j});this.app.element_list[l]=k;this.table.add(k.$el);this.table.append(l);if(i.hidden){this.table.get(l).hide()}return j},_createField:function(i){var j=null;switch(i.type){case"text":j=this._fieldText(i);break;case"select":j=this._fieldSelect(i);break;case"data":j=this._fieldData(i);break;case"data_collection":j=this._fieldData(i);break;case"data_column":i.error_text="Missing columns in referenced dataset.";j=this._fieldSelect(i);break;case"hidden":j=this._fieldHidden(i);break;case"hidden_data":j=this._fieldHidden(i);break;case"integer":j=this._fieldSlider(i);break;case"float":j=this._fieldSlider(i);break;case"boolean":j=this._fieldBoolean(i);break;case"genomebuild":i.searchable=true;j=this._fieldSelect(i);break;case"drill_down":j=this._fieldDrilldown(i);break;case"baseurl":j=this._fieldHidden(i);break;default:this.app.incompatible=true;if(i.options){j=this._fieldSelect(i)}else{j=this._fieldText(i)}console.debug("tools-form::_addRow() : Auto matched field type ("+i.type+").")}if(i.value!==undefined){j.value(i.value)}return j},_fieldData:function(i){if(!this.app.options.is_dynamic){i.info="Data input '"+i.name+"' ("+e.textify(i.extensions.toString())+")";i.value=null;return this._fieldHidden(i)}var j=this;return new a.View(this.app,{id:"field-"+i.id,extensions:i.extensions,optional:i.optional,multiple:i.multiple,type:i.type,data:i.options,onchange:function(){j.app.trigger("refresh")}})},_fieldSelect:function(j){if(!this.app.options.is_dynamic&&j.is_dynamic){return this._fieldText(j)}var l=[];for(var m in j.options){var n=j.options[m];l.push({label:n[0],value:n[1]})}var o=h.Select;switch(j.display){case"checkboxes":o=h.Checkbox;break;case"radio":o=h.Radio;break}var k=this;return new o.View({id:"field-"+j.id,data:l,error_text:j.error_text||"No options available",multiple:j.multiple,searchable:j.searchable,onchange:function(){k.app.trigger("refresh")}})},_fieldDrilldown:function(i){if(!this.app.options.is_dynamic&&i.is_dynamic){return this._fieldText(i)}var j=this;return new h.Drilldown.View({id:"field-"+i.id,data:i.options,display:i.display,onchange:function(){j.app.trigger("refresh")}})},_fieldText:function(i){if(i.options){i.area=i.multiple;if(!e.validate(i.value)){i.value=""}else{if(i.value instanceof Array){i.value=value.toString()}else{i.value=String(i.value).replace(/[\[\]'"\s]/g,"");if(i.multiple){i.value=i.value.replace(/,/g,"\n")}}}}var j=this;return new h.Input({id:"field-"+i.id,area:i.area,onchange:function(){j.app.trigger("refresh")}})},_fieldSlider:function(i){var j=this;return new h.Slider.View({id:"field-"+i.id,precise:i.type=="float",min:i.min,max:i.max,onchange:function(){j.app.trigger("refresh")}})},_fieldHidden:function(i){return new h.Hidden({id:"field-"+i.id,info:i.info})},_fieldBoolean:function(i){var j=this;return new h.RadioButton.View({id:"field-"+i.id,data:[{label:"Yes",value:"true"},{label:"No",value:"false"}],onchange:function(){j.app.trigger("refresh")}})}});return{View:g}});
\ No newline at end of file
diff -r 68f0ed37e08942acb1bb84b63911b22d7d4b6f65 -r e0441a0f85307fb9caf854fd10133f71cc3852d3 static/scripts/packed/mvc/ui/ui-slider.js
--- a/static/scripts/packed/mvc/ui/ui-slider.js
+++ b/static/scripts/packed/mvc/ui/ui-slider.js
@@ -1,1 +1,1 @@
-define(["utils/utils"],function(a){var b=Backbone.View.extend({optionsDefault:{min:null,max:null,step:null,precise:false,split:10000},initialize:function(d){var c=this;this.options=a.merge(d,this.optionsDefault);this.setElement(this._template(this.options));this.useslider=this.options.max!==null&&this.options.min!==null&&this.options.max>this.options.min;if(this.options.step===null){this.options.step=1;if(this.options.precise&&this.useslider){this.options.step=(this.options.max-this.options.min)/this.options.split}}if(this.useslider){this.$slider=this.$el.find("#slider");this.$slider.slider(this.options);this.$slider.on("slide",function(f,g){c.value(g.value)})}else{this.$el.find(".ui-form-slider-text").css("width","100%")}this.$text=this.$el.find("#text");if(this.options.value!==undefined){this.value(this.options.value)}this.$text.on("change",function(){c.value($(this).val())});var e=[];this.$text.on("keyup",function(f){e[f.which]=false});this.$text.on("keydown",function(g){var f=g.which;e[f]=true;if(!(f==8||f==9||f==13||f==37||f==39||(f>=48&&f<=57)||(f==190&&$(this).val().indexOf(".")==-1&&c.options.precise)||(f==189&&$(this).val().indexOf("-")==-1)||e[91]||e[17])){event.preventDefault()}})},value:function(c){if(c!==undefined){if(isNaN(c)){c=0}if(this.options.max!==null){c=Math.min(c,this.options.max)}if(this.options.min!==null){c=Math.max(c,this.options.min)}if(this.options.onchange){this.options.onchange(c)}this.$slider&&this.$slider.slider("value",c);this.$text.val(c)}return this.$text.val()},_template:function(c){return'<div id="'+c.id+'" class="ui-form-slider"><input id="text" type="text" class="ui-form-slider-text"/><div id="slider" class="ui-form-slider-element"/></div>'}});return{View:b}});
\ No newline at end of file
+define(["utils/utils"],function(a){var b=Backbone.View.extend({optionsDefault:{min:null,max:null,step:null,precise:false,split:10000},initialize:function(d){var c=this;this.options=a.merge(d,this.optionsDefault);this.setElement(this._template(this.options));this.useslider=this.options.max!==null&&this.options.min!==null&&this.options.max>this.options.min;if(this.options.step===null){this.options.step=1;if(this.options.precise&&this.useslider){this.options.step=(this.options.max-this.options.min)/this.options.split}}if(this.useslider){this.$slider=this.$el.find("#slider");this.$slider.slider(this.options);this.$slider.on("slide",function(f,g){c.value(g.value)})}else{this.$el.find(".ui-form-slider-text").css("width","100%")}this.$text=this.$el.find("#text");if(this.options.value!==undefined){this.value(this.options.value)}this.$text.on("input",function(){c.value($(this).val())});var e=[];this.$text.on("keyup",function(f){e[f.which]=false});this.$text.on("keydown",function(g){var f=g.which;e[f]=true;if(!(f==8||f==9||f==13||f==37||f==39||(f>=48&&f<=57)||(f==190&&$(this).val().indexOf(".")==-1&&c.options.precise)||(f==189&&$(this).val().indexOf("-")==-1)||e[91]||e[17])){event.preventDefault()}})},value:function(c){if(c!==undefined){if(isNaN(c)){c=0}if(this.options.max!==null){c=Math.min(c,this.options.max)}if(this.options.min!==null){c=Math.max(c,this.options.min)}if(this.options.onchange){this.options.onchange(c)}this.$slider&&this.$slider.slider("value",c);this.$text.val(c)}return this.$text.val()},_template:function(c){return'<div id="'+c.id+'" class="ui-form-slider"><input id="text" type="text" class="ui-form-slider-text"/><div id="slider" class="ui-form-slider-element"/></div>'}});return{View:b}});
\ No newline at end of file
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
29 Jan '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/68f0ed37e089/
Changeset: 68f0ed37e089
User: carlfeberhard
Date: 2015-01-29 15:42:54+00:00
Summary: History API: allow filtering, limit, and offset in index params; Implement managers/base.FilterParser to configure how models can be filtered; Change ModelManager.list to allow limit, offset, and post-query (functional) filters; Add user filter, limit, and offset parsers to BaseController; Add tests for previous; Remove some UserManager functions; Continue filling out Annotatable mixin
Affected #: 13 files
diff -r 8a234cd86e8a972a43f0e13617c9f09ae1216fee -r 68f0ed37e08942acb1bb84b63911b22d7d4b6f65 lib/galaxy/managers/annotatable.py
--- a/lib/galaxy/managers/annotatable.py
+++ b/lib/galaxy/managers/annotatable.py
@@ -11,6 +11,26 @@
annotation_assoc = None
# TODO: most of this seems to be covered by item_attrs.UsesAnnotations
+ # TODO: use these below (serializer/deserializer)
+ def user_annotation( self, trans, item, user ):
+ return item.get_item_annotation_str( self.app.model.context, user, item )
+
+ def owner_annotation( self, trans, item ):
+ return self.user_annotation( trans, item, item.user )
+
+ def delete_annotation( self, trans, item, user ):
+ return item.delete_item_annotation( self.app.model.context, user, item )
+
+ def annotate( self, trans, item, user, annotation ):
+ if annotation is None:
+ self.delete_annotation( self, trans, item, user )
+ return None
+
+ annotation_obj = item.add_item_annotation( self.app.model.context, user, item, annotation )
+ return annotation_obj.annotation
+
+ #def by_user( self, trans, user, **kwargs ):
+ # pass
class AnnotatableSerializer( object ):
diff -r 8a234cd86e8a972a43f0e13617c9f09ae1216fee -r 68f0ed37e08942acb1bb84b63911b22d7d4b6f65 lib/galaxy/managers/base.py
--- a/lib/galaxy/managers/base.py
+++ b/lib/galaxy/managers/base.py
@@ -32,6 +32,7 @@
from galaxy import exceptions
from galaxy import model
from galaxy.model import tool_shed_install
+from galaxy.managers import filters as filter_parser
import logging
log = logging.getLogger( __name__ )
@@ -159,12 +160,7 @@
def __init__( self, app ):
self.app = app
- def _default_order_by( self ):
- """
- Returns a tuple of columns for the default order when getting multiple models.
- """
- return ( self.model_class.create_time, )
-
+ # .... query foundation wrapper
def query( self, trans, eagerloads=True, filters=None, order_by=None, limit=None, offset=None, **kwargs ):
"""
Return a basic query from model_class, filters, order_by, and limit and offset.
@@ -172,17 +168,17 @@
Set eagerloads to False to disable them for this query.
"""
query = trans.sa_session.query( self.model_class )
-
# joined table loading
if eagerloads is False:
query = query.enable_eagerloads( False )
- # TODO: if non-orm filters are the only option, here is where they'd go
- query = self._apply_filters( query, filters )
- query = self._apply_order_by_limit_offset( query, order_by, limit, offset )
+ query = self._apply_orm_filters( query, filters )
+ query = self._apply_order_by( query, order_by )
+ query = self._apply_orm_limit_offset( query, limit, offset )
return query
- def _apply_filters( self, query, filters ):
+ # .... filters
+ def _apply_orm_filters( self, query, filters ):
"""
Add any filters to the given query.
"""
@@ -213,13 +209,7 @@
filtersB = [ filtersB ]
return filtersA + filtersB
- def _apply_order_by_limit_offset( self, query, order_by, limit, offset ):
- """
- Return the query after adding the order_by, limit, and offset clauses.
- """
- query = self._apply_order_by( query, order_by )
- return self._apply_limit_offset( query, limit, offset )
-
+ # .... order, limit, and offset
def _apply_order_by( self, query, order_by ):
"""
Return the query after adding the order_by clauses.
@@ -233,7 +223,13 @@
return query.order_by( *order_by )
return query.order_by( order_by )
- def _apply_limit_offset( self, query, limit, offset ):
+ def _default_order_by( self ):
+ """
+ Returns a tuple of columns for the default order when getting multiple models.
+ """
+ return ( self.model_class.create_time, )
+
+ def _apply_orm_limit_offset( self, query, limit, offset ):
"""
Return the query after applying the given limit and offset (if not None).
"""
@@ -243,6 +239,7 @@
query = query.offset( offset )
return query
+ # .... query resolution
def one( self, trans, **kwargs ):
"""
Sends kwargs to build the query and returns one and only one model.
@@ -284,25 +281,94 @@
id_filter = self.model_class.id == id
return self.one( trans, filters=id_filter, **kwargs )
- def list( self, trans, query=None, **kwargs ):
+ # .... multirow queries
+ def _orm_list( self, trans, query=None, **kwargs ):
"""
Sends kwargs to build the query return all models found.
"""
query = query or self.query( trans, **kwargs )
return query.all()
- def _query_by_ids( self, trans, ids, filters=None, **kwargs ):
+ #def list( self, trans, query=None, filters=None, order_by=None, limit=None, offset=None, **kwargs ):
+ def list( self, trans, filters=None, order_by=None, limit=None, offset=None, **kwargs ):
"""
- Builds a query to find a list of models with the given list of `ids`.
+ Returns all objects matching the given filters
"""
- ids_filter = self.model_class.id.in_( ids )
- return self.query( trans, filters=self._munge_filters( ids_filter, filters ), **kwargs )
+ orm_filters, fn_filters = self._split_filters( filters )
+ if not fn_filters:
+ # if no fn_filtering required, we can use the 'all orm' version with limit offset
+ return self._orm_list( trans, filters=orm_filters, order_by=order_by, limit=limit, offset=offset, **kwargs )
- def by_ids( self, trans, ids, **kwargs ):
+ # fn filters will change the number of items returnable by limit/offset - remove them here from the orm query
+ query = self.query( trans, filters=orm_filters, order_by=order_by, limit=None, offset=None, **kwargs )
+ items = query.all()
+
+ # apply limit, offset after SQL filtering
+ items = self._apply_fn_filters_gen( items, fn_filters )
+ return list( self._apply_fn_limit_offset_gen( items, limit, offset ) )
+
+ def _split_filters( self, filters ):
+ """
+ Splits `filters` into a tuple of two lists:
+ a list of filters to be added to the SQL query
+ and a list of functional filters to be applied after the SQL query.
+ """
+ orm_filters, fn_filters = ( [], [] )
+ if filters is None:
+ return ( orm_filters, fn_filters )
+ if not isinstance( filters, list ):
+ filters = [ filters ]
+ for filter_ in filters:
+ if self._is_fn_filter( filter_ ):
+ fn_filters.append( filter_ )
+ else:
+ orm_filters.append( filter_ )
+ return ( orm_filters, fn_filters )
+
+ def _is_fn_filter( self, filter_ ):
+ """
+ Returns True if `filter_` is a functional filter to be applied after the SQL query.
+ """
+ return callable( filter_ )
+
+ def _apply_fn_filters_gen( self, items, filters ):
+ """
+ If all the filter functions in `filters` return True for an item in `items`,
+ yield that item.
+ """
+ #cpu-expensive
+ for item in items:
+ filter_results = map( lambda f: f( item ), filters )
+ if all( filter_results ):
+ yield item
+
+ def _apply_fn_limit_offset_gen( self, items, limit, offset ):
+ """
+ Iterate over `items` and begin yielding items after
+ `offset` number of items and stop when we've yielded
+ `limit` number of items.
+ """
+ # change negative limit, offset to None
+ if limit is not None and limit < 0:
+ limit = None
+ if offset is not None and offset < 0:
+ offset = None
+
+ yielded = 0
+ for i, item in enumerate( items ):
+ if offset is not None and i < offset:
+ continue
+ if limit is not None and yielded >= limit:
+ break
+ yield item
+ yielded += 1
+
+ def by_ids( self, trans, ids, filters=None, **kwargs ):
"""
Returns an in-order list of models with the matching ids in `ids`.
"""
- found = self._query_by_ids( trans, ids, **kwargs ).all()
+ ids_filter = self.model_class.id.in_( ids )
+ found = self.list( trans, filters=self._munge_filters( ids_filter, filters ), **kwargs )
# TODO: this does not order by the original 'ids' array
# ...could use get (supposedly since found are in the session, the db won't be hit twice)
@@ -607,6 +673,9 @@
val = self.validate.int_range( key, val, min, max )
return self.default_deserializer( trans, item, key, val )
+ #def deserialize_date( self, trans, item, key, val ):
+ # #TODO: parse isoformat date into date object
+
# ... common deserializers for Galaxy
def deserialize_genome_build( self, trans, item, key, val ):
"""
@@ -691,6 +760,229 @@
# pass
+# ==== Building query filters based on model data
+class FilterParser( object ):
+ """
+ Converts string tuples (partially converted query string params) of
+ attr, op, val into either:
+ - ORM based filters (filters that can be applied by the ORM at the SQL
+ level) or
+ - functional filters (filters that use derived values or values not
+ within the SQL tables)
+ These filters can then be applied to queries.
+
+ This abstraction allows 'smarter' application of limit and offset at either the
+ SQL level or the generator/list level based on the presence of functional
+ filters. In other words, if no functional filters are present, limit and offset
+ may be applied at the SQL level. If functional filters are present, limit and
+ offset need to applied at the list level.
+
+ These might be safely be replaced in the future by creating SQLAlchemy
+ hybrid properties or more thoroughly mapping derived values.
+ """
+ #??: this class kindof 'lives' in both the world of the controllers/param-parsing and to models/orm
+ # (as the model informs how the filter params are parsed)
+ # I have no great idea where this 'belongs', so it's here for now
+
+ #: model class
+ model_class = None
+
+ def __init__( self, app ):
+ """
+ Set up serializer map, any additional serializable keys, and views here.
+ """
+ self.app = app
+
+ #: dictionary containing parsing data for ORM/SQLAlchemy-based filters
+ #..note: although kind of a pain in the ass and verbose, opt-in/whitelisting allows more control
+ #: over potentially expensive queries
+ self.orm_filter_parsers = {}
+
+ #: dictionary containing parsing data for functional filters - applied after a query is made
+ self.fn_filter_parsers = {}
+
+ # set up both of the above
+ self._add_parsers()
+
+ def _add_parsers( self ):
+ """
+ Set up, extend, or alter `orm_filter_parsers` and `fn_filter_parsers`.
+ """
+ pass
+
+ def parse_filters( self, filter_tuple_list ):
+ """
+ Parse string 3-tuples (attr, op, val) into orm or functional filters.
+ """
+ parsed = []
+ for ( attr, op, val ) in filter_tuple_list:
+ filter_ = self.parse_filter( attr, op, val )
+ parsed.append( filter_ )
+ return parsed
+
+ def parse_filter( self, attr, op, val ):
+ """
+ Attempt to parse filter as a custom/fn filter, then an orm filter, and
+ if neither work - raise an error.
+
+ :raises exceptions.RequestParameterInvalidException: if no functional or orm
+ filter can be parsed.
+ """
+ try:
+ # check for a custom filter
+ fn_filter = self._parse_fn_filter( attr, op, val )
+ if fn_filter is not None:
+ return fn_filter
+
+ # if no custom filter found, try to make an ORM filter
+ #note: have to use explicit is None here, bool( sqlalx.filter ) == False
+ orm_filter = self._parse_orm_filter( attr, op, val )
+ if orm_filter is not None:
+ return orm_filter
+
+ # by convention, assume most val parsers raise ValueError
+ except ValueError, val_err:
+ raise exceptions.RequestParameterInvalidException( 'unparsable value for filter',
+ column=attr, operation=op, value=val )
+
+ # if neither of the above work, raise an error with how-to info
+ #TODO: send back all valid filter keys in exception for added user help
+ raise exceptions.RequestParameterInvalidException( 'bad filter', column=attr, operation=op )
+
+ # ---- fn filters
+ def _parse_fn_filter( self, attr, op, val ):
+ """
+ """
+ # fn_filter_list is a dict: fn_filter_list[ attr ] = { 'opname1' : opfn1, 'opname2' : opfn2, etc. }
+
+ # attr, op is a nested dictionary pointing to the filter fn
+ attr_map = self.fn_filter_parsers.get( attr, None )
+ if not attr_map:
+ return None
+ allowed_ops = attr_map.get( 'op' )
+ # allowed ops is a map here, op => fn
+ filter_fn = allowed_ops.get( op, None )
+ if not filter_fn:
+ return None
+ # parse the val from string using the 'val' parser if present (otherwise, leave as string)
+ val_parser = attr_map.get( 'val', None )
+ if val_parser:
+ val = val_parser( val )
+
+ # curry/partial and fold the val in there now
+ return lambda i: filter_fn( i, val )
+
+ # ---- ORM filters
+ def _parse_orm_filter( self, attr, op, val ):
+ """
+ """
+ # orm_filter_list is a dict: orm_filter_list[ attr ] = <list of allowed ops>
+ # attr must be a whitelisted column
+ column = self.model_class.table.columns.get( attr )
+ column_map = self.orm_filter_parsers.get( attr, None )
+ if column is None or not column_map:
+ return None
+ # op must be whitelisted: contained in the list orm_filter_list[ attr ][ 'op' ]
+ allowed_ops = column_map.get( 'op' )
+ if op not in allowed_ops:
+ return None
+ op = self._convert_op_string_to_fn( column, op )
+ # parse the val from string using the 'val' parser if present (otherwise, leave as string)
+ val_parser = column_map.get( 'val', None )
+ if val_parser:
+ val = val_parser( val )
+
+ orm_filter = op( val )
+ return orm_filter
+
+ #: these are the easier/shorter string equivalents to the python operator fn names that need '__' around them
+ UNDERSCORED_OPS = ( 'lt', 'le', 'eq', 'ne', 'ge', 'gt' )
+ #UNCHANGED_OPS = ( 'like' )
+ def _convert_op_string_to_fn( self, column, op_string ):
+ """
+ """
+ # correct op_string to usable function key
+ fn_name = op_string
+ if op_string in self.UNDERSCORED_OPS:
+ fn_name = '__' + op_string + '__'
+ elif op_string == 'in':
+ fn_name = 'in_'
+
+ # get the column fn using the op_string and error if not a callable attr
+ #TODO: special case 'not in' - or disallow?
+ op_fn = getattr( column, fn_name, None )
+ if not op_fn or not callable( op_fn ):
+ return None
+ return op_fn
+
+ # --- more parsers! yay!
+#TODO: These should go somewhere central - we've got ~6 parser modules/sections now
+ #TODO: to annotatable
+ def _owner_annotation( self, item ):
+ """
+ Get the annotation by the item's owner.
+ """
+ if not item.user:
+ return None
+ for annotation in item.annotations:
+ if annotation.user == item.user:
+ return annotation.annotation
+ return None
+
+ def filter_annotation_contains( self, item, val ):
+ """
+ Test whether `val` is in the owner's annotation.
+ """
+ owner_annotation = self._owner_annotation( item )
+ if owner_annotation is None:
+ return False
+ return val in owner_annotation
+
+ #TODO: to taggable
+ def _filter_tags( self, item, val, fn_name='__eq__' ):
+ """
+ Test whether the string version of any tag `fn_name`s (__eq__, contains)
+ `val`.
+ """
+ #TODO: which user is this? all?
+ for tag in item.tags:
+ tag_str = tag.user_tname
+ if tag.value is not None:
+ tag_str += ":" + tag.user_value
+ if tag_str[ fn_name ]( val ):
+ return True
+ return False
+
+ def filter_has_partial_tag( self, item, val ):
+ """
+ Return True if any tag partially contains `val`.
+ """
+ return self._filter_tags( item, val, fn_name='contains' )
+
+ def filter_has_tag( self, item, val ):
+ """
+ Return True if any tag exactly equals `val`.
+ """
+ return self._filter_tags( item, val, fn_name='__eq__' )
+
+ def parse_bool( self, bool_string ):
+ """
+ Parse a boolean from a string.
+ """
+ #Be strict here to remove complexity of options.
+ if bool_string in ( 'True', True ):
+ return True
+ if bool_string in ( 'False', False ):
+ return False
+ raise ValueError( 'invalid boolean: ' + str( bool_string ) )
+
+ def parse_id_list( self, id_list_string, sep=',' ):
+ """
+ Split `id_list_string` at `sep`.
+ """
+ return id_list_string.split( sep )
+
+
# ==== Security Mixins
class AccessibleModelInterface( object ):
"""
@@ -794,8 +1086,9 @@
:raises exceptions.ItemAccessibilityException:
"""
+ raise exceptions.NotImplemented( "Abstract Interface Method" )
# just alias to by_user (easier/same thing)
- return self.by_user( trans, user, **kwargs )
+ #return self.by_user( trans, user, **kwargs )
def filter_owned( self, trans, user, **kwargs ):
"""
diff -r 8a234cd86e8a972a43f0e13617c9f09ae1216fee -r 68f0ed37e08942acb1bb84b63911b22d7d4b6f65 lib/galaxy/managers/histories.py
--- a/lib/galaxy/managers/histories.py
+++ b/lib/galaxy/managers/histories.py
@@ -63,7 +63,7 @@
return super( HistoryManager, self ).is_owner( trans, history, user )
#TODO: possibly to sharable
- def most_recent( self, trans, user, **kwargs ):
+ def most_recent( self, trans, user, filters=None, **kwargs ):
"""
Return the most recently update history for the user.
"""
@@ -71,7 +71,8 @@
if not user:
return None if trans.history.deleted else trans.history
desc_update_time = self.model_class.table.c.update_time
- return self._query_by_user( trans, user, order_by=desc_update_time, limit=1, **kwargs ).first()
+ filters = self._munge_filters( filters, self.model_class.user_id == user.id )
+ return self.query( trans, filters=filters, order_by=desc_update_time, limit=1, **kwargs ).first()
# .... purgable
def purge( self, trans, history, flush=True, **kwargs ):
@@ -109,7 +110,7 @@
return self.set_current( trans, self.by_id( trans, history_id ) )
# .... serialization
- #TODO: move to serializer (i.e. history with contents attr)
+#TODO: move to serializer (i.e. history with contents attr)
def _get_history_data( self, trans, history ):
"""
Returns a dictionary containing ``history`` and ``contents``, serialized
@@ -342,7 +343,6 @@
super( HistoryDeserializer, self ).__init__( app )
self.history_manager = self.manager
- #assumes: incoming from json.loads and sanitized
def add_deserializers( self ):
super( HistoryDeserializer, self ).add_deserializers()
base.PurgableModelDeserializer.add_deserializers( self )
@@ -351,3 +351,45 @@
'name' : self.deserialize_basestring,
'genome_build' : self.deserialize_genome_build,
})
+
+
+class HistoryFilters( base.FilterParser ):
+ model_class = model.History
+
+ def _add_parsers( self ):
+ super( HistoryFilters, self )._add_parsers()
+ self.orm_filter_parsers.update({
+ #TODO: these three are (prob.) applicable to all models
+ 'id' : { 'op': ( 'in' ), 'val': self.parse_id_list },
+ # dates can be directly passed through the orm into a filter (no need to parse into datetime object)
+ 'create_time' : { 'op': ( 'le', 'ge' ) },
+ 'update_time' : { 'op': ( 'le', 'ge' ) },
+
+ # history specific
+ 'name' : { 'op': ( 'eq', 'contains', 'like' ) },
+ 'genome_build' : { 'op': ( 'eq', 'contains', 'like' ) },
+
+ #TODO: purgable
+ 'deleted' : { 'op': ( 'eq' ), 'val': self.parse_bool },
+ 'purged' : { 'op': ( 'eq' ), 'val': self.parse_bool },
+
+ #TODO: sharable
+ 'importable' : { 'op': ( 'eq' ), 'val': self.parse_bool },
+ 'published' : { 'op': ( 'eq' ), 'val': self.parse_bool },
+ 'slug' : { 'op': ( 'eq', 'contains', 'like' ) },
+ # chose by user should prob. only be available for admin? (most often we'll only need trans.user)
+ #'user' : { 'op': ( 'eq' ), 'val': self.parse_id_list },
+ })
+
+ #TODO: I'm not entirely convinced this (or tags) are a good idea for filters since they involve a/the user
+ self.fn_filter_parsers.update({
+ #TODO: add this in annotatable mixin
+ 'annotation' : { 'op': { 'in' : self.filter_annotation_contains, } },
+ #TODO: add this in taggable mixin
+ 'tag' : {
+ 'op': {
+ 'eq' : self.filter_has_tag,
+ 'in' : self.filter_has_partial_tag,
+ }
+ }
+ })
diff -r 8a234cd86e8a972a43f0e13617c9f09ae1216fee -r 68f0ed37e08942acb1bb84b63911b22d7d4b6f65 lib/galaxy/managers/ratable.py
--- a/lib/galaxy/managers/ratable.py
+++ b/lib/galaxy/managers/ratable.py
@@ -16,6 +16,9 @@
#TODO: most of this seems to be covered by item_attrs.UsesItemRatings
+ #def by_user( self, trans, user, **kwargs ):
+ # pass
+
class RatableSerializer( object ):
@@ -33,6 +36,7 @@
"""
pass
+
class RatableDeserializer( object ):
def add_deserializers( self ):
diff -r 8a234cd86e8a972a43f0e13617c9f09ae1216fee -r 68f0ed37e08942acb1bb84b63911b22d7d4b6f65 lib/galaxy/managers/sharable.py
--- a/lib/galaxy/managers/sharable.py
+++ b/lib/galaxy/managers/sharable.py
@@ -41,22 +41,14 @@
self.user_manager = users.UserManager( app )
# .... has a user
- def _query_by_user( self, trans, user, filters=None, **kwargs ):
+ def by_user( self, trans, user, filters=None, **kwargs ):
"""
- Return query for all items (of model_class type) associated with the given
+ Return list for all items (of model_class type) associated with the given
`user`.
"""
user_filter = self.model_class.user_id == user.id
filters=self._munge_filters( user_filter, filters )
- return self.query( trans, filters=filters, **kwargs )
-
- def by_user( self, trans, user, **kwargs ):
- """
- Return list for all items (of model_class type) associated with the given
- `user`.
- """
- query = self._query_by_user( trans, user, **kwargs )
- return self.list( trans, query=query, **kwargs )
+ return self.list( trans, filters=filters, **kwargs )
# .... owned model interface
def is_owner( self, trans, item, user ):
diff -r 8a234cd86e8a972a43f0e13617c9f09ae1216fee -r 68f0ed37e08942acb1bb84b63911b22d7d4b6f65 lib/galaxy/managers/taggable.py
--- a/lib/galaxy/managers/taggable.py
+++ b/lib/galaxy/managers/taggable.py
@@ -15,6 +15,9 @@
#TODO: most of this can be done by delegating to the TagManager?
+ #def by_user( self, trans, user, **kwargs ):
+ # pass
+
class TaggableSerializer( object ):
diff -r 8a234cd86e8a972a43f0e13617c9f09ae1216fee -r 68f0ed37e08942acb1bb84b63911b22d7d4b6f65 lib/galaxy/managers/users.py
--- a/lib/galaxy/managers/users.py
+++ b/lib/galaxy/managers/users.py
@@ -145,37 +145,9 @@
return user
# ---- current
- def is_current_user( self, trans, user ):
- """
- Return True if this user is the trans' current user.
- """
+ def current_user( self, trans ):
# define here for single point of change and make more readable
- return user == trans.user
-
- def is_current_user_anonymous( self, trans ):
- """
- Return True if the current user is anonymous.
- """
- return self.is_anonymous( trans.user )
-
- def is_current_user_admin( self, trans ):
- """
- Return True if the current user is admin.
- """
- return self.is_admin( trans, trans.user )
-
- # ---- User-created notes/metadata on other models
- #def tags( self, trans, user, **kwargs ):
- # """
- # Return all tags created by this user.
- # """
- # pass
-
- #def annotations( self, trans, user, **kwargs ):
- # """
- # Return all annotations created by this user.
- # """
- # pass
+ return trans.user
# ---- api keys
def create_api_key( self, trans, user ):
diff -r 8a234cd86e8a972a43f0e13617c9f09ae1216fee -r 68f0ed37e08942acb1bb84b63911b22d7d4b6f65 lib/galaxy/web/base/controller.py
--- a/lib/galaxy/web/base/controller.py
+++ b/lib/galaxy/web/base/controller.py
@@ -100,6 +100,7 @@
def get_role( self, trans, id, check_ownership=False, check_accessible=False, deleted=None ):
return self.get_object( trans, id, 'Role', check_ownership=False, check_accessible=False, deleted=deleted )
+ # ---- parsing query params
def decode_id( self, id ):
try:
return self.app.security.decode_id( id )
@@ -115,6 +116,53 @@
"""
return trans.security.encode_all_ids( rval, recursive=recursive )
+ def parse_filter_params( self, qdict, filter_attr_key='q', filter_value_key='qv', attr_op_split_char='-' ):
+ """
+ """
+ #TODO: import DEFAULT_OP from FilterParser
+ DEFAULT_OP = 'eq'
+ if filter_attr_key not in qdict:
+ return []
+ #precondition: attrs/value pairs are in-order in the qstring
+ attrs = qdict.get( filter_attr_key )
+ if not isinstance( attrs, list ):
+ attrs = [ attrs ]
+ # ops are strings placed after the attr strings and separated by a split char (e.g. 'create_time-lt')
+ # ops are optional and default to 'eq'
+ reparsed_attrs = []
+ ops = []
+ for attr in attrs:
+ op = DEFAULT_OP
+ if attr_op_split_char in attr:
+ #note: only split the last (e.g. q=community-tags-in&qv=rna yields ( 'community-tags', 'in', 'rna' )
+ attr, op = attr.rsplit( attr_op_split_char, 1 )
+ ops.append( op )
+ reparsed_attrs.append( attr )
+ attrs = reparsed_attrs
+
+ values = qdict.get( filter_value_key, [] )
+ if not isinstance( values, list ):
+ values = [ values ]
+ #TODO: it may be more helpful to the consumer if we error on incomplete 3-tuples
+ # (instead of relying on zip to shorten)
+ return zip( attrs, ops, values )
+
+ def parse_limit_offset( self, qdict ):
+ """
+ """
+ def _parse_pos_int( i ):
+ try:
+ new_val = int( i )
+ if new_val >= 0:
+ return new_val
+ except ( TypeError, ValueError ):
+ pass
+ return None
+
+ limit = _parse_pos_int( qdict.get( 'limit', None ) )
+ offset = _parse_pos_int( qdict.get( 'offset', None ) )
+ return ( limit, offset )
+
Root = BaseController
diff -r 8a234cd86e8a972a43f0e13617c9f09ae1216fee -r 68f0ed37e08942acb1bb84b63911b22d7d4b6f65 lib/galaxy/webapps/galaxy/api/histories.py
--- a/lib/galaxy/webapps/galaxy/api/histories.py
+++ b/lib/galaxy/webapps/galaxy/api/histories.py
@@ -19,7 +19,7 @@
from galaxy.web.base.controller import ExportsHistoryMixin
from galaxy.web.base.controller import ImportsHistoryMixin
-from galaxy.managers import histories, citations
+from galaxy.managers import histories, citations, users
from galaxy import util
from galaxy.util import string_as_bool
@@ -35,9 +35,11 @@
def __init__( self, app ):
super( HistoriesController, self ).__init__( app )
self.citations_manager = citations.CitationsManager( app )
+ self.user_manager = users.UserManager( app )
self.history_manager = histories.HistoryManager( app )
self.history_serializer = histories.HistorySerializer( app )
self.history_deserializer = histories.HistoryDeserializer( app )
+ self.history_filters = histories.HistoryFilters( app )
@expose_api_anonymous
def index( self, trans, deleted='False', **kwd ):
@@ -55,21 +57,58 @@
:rtype: list
:returns: list of dictionaries containing summary history information
"""
+ serialization_params = self._parse_serialization_params( kwd, 'summary' )
+ limit, offset = self.parse_limit_offset( kwd )
+ filter_params = self.parse_filter_params( kwd )
+
+ # bail early with current history if user is anonymous
+ current_user = self.user_manager.current_user( trans )
+ if self.user_manager.is_anonymous( current_user ):
+ current_history = self.history_manager.get_current( trans )
+ #note: ignores filters, limit, offset
+ return [ self.history_serializer.serialize_to_view( trans, current_history, **serialization_params ) ]
+
+ filters = []
+ # support the old default of not-returning/filtering-out deleted histories
+ filters += self._get_deleted_filter( deleted, filter_params )
+ # users are limited to requesting only their own histories (here)
+ filters += [ self.app.model.History.user == current_user ]
+ # and any sent in from the query string
+ filters += self.history_filters.parse_filters( filter_params )
+
+ #TODO: eventually make order_by a param as well
+ order_by = sqlalchemy.desc( self.app.model.History.create_time )
+ histories = self.history_manager.list( trans, filters=filters, order_by=order_by, limit=limit, offset=offset )
+
rval = []
- serialization_params = self._parse_serialization_params( kwd, 'summary' )
-
- deleted_filter = ( self.app.model.History.deleted == False )
- if string_as_bool( deleted ):
- deleted_filter = ( self.app.model.History.deleted == True )
-
- #TODO: create time? is this right?
- order_by = sqlalchemy.desc( self.app.model.History.create_time )
- histories = self.history_manager.by_user( trans, user=trans.user, filters=deleted_filter, order_by=order_by )
for history in histories:
history_dict = self.history_serializer.serialize_to_view( trans, history, **serialization_params )
rval.append( history_dict )
+ return rval
- return rval
+ def _get_deleted_filter( self, deleted, filter_params ):
+ #TODO: this should all be removed (along with the default) in v2
+ # support the old default of not-returning/filtering-out deleted histories
+ try:
+ # the consumer must explicitly ask for both deleted and non-deleted
+ # but pull it from the parsed params (as the filter system will error on None)
+ deleted_filter_index = filter_params.index( ( 'deleted', 'eq', 'None' ) )
+ filter_params.pop( deleted_filter_index )
+ return []
+ except ValueError:
+ pass
+
+ # the deleted string bool was also used as an 'include deleted' flag
+ if deleted in ( 'True', 'true' ):
+ return [ self.app.model.History.deleted == True ]
+
+ # the third option not handled here is 'return only deleted'
+ # if this is passed in (in the form below), simply return and let the filter system handle it
+ if ( 'deleted', 'eq', 'True' ) in filter_params:
+ return []
+
+ # otherwise, do the default filter of removing the deleted histories
+ return [ self.app.model.History.deleted == False ]
@expose_api_anonymous
def show( self, trans, id, deleted='False', **kwd ):
diff -r 8a234cd86e8a972a43f0e13617c9f09ae1216fee -r 68f0ed37e08942acb1bb84b63911b22d7d4b6f65 test/unit/managers/mock.py
--- a/test/unit/managers/mock.py
+++ b/test/unit/managers/mock.py
@@ -18,6 +18,9 @@
# =============================================================================
+class OpenObject( object ):
+ pass
+
class MockAppConfig( Bunch ):
def __init__( self, **kwargs ):
Bunch.__init__( self, **kwargs )
diff -r 8a234cd86e8a972a43f0e13617c9f09ae1216fee -r 68f0ed37e08942acb1bb84b63911b22d7d4b6f65 test/unit/managers/test_HistoryManager.py
--- a/test/unit/managers/test_HistoryManager.py
+++ b/test/unit/managers/test_HistoryManager.py
@@ -20,6 +20,7 @@
import mock
from test_ModelManager import BaseTestCase
from galaxy.managers.histories import HistoryManager
+from galaxy.managers.histories import HistoryFilters
# =============================================================================
@@ -92,9 +93,6 @@
user_histories = self.history_mgr.by_user( self.trans, owner )
self.assertEqual( user_histories, [ item1, item2 ] )
- query = self.history_mgr._query_by_user( self.trans, owner )
- self.assertEqual( query.all(), user_histories )
-
def test_ownable( self ):
owner = self.user_mgr.create( self.trans, **user2_data )
non_owner = self.user_mgr.create( self.trans, **user3_data )
@@ -307,6 +305,239 @@
self.assertEqual( self.history_mgr.get_current( self.trans ), history1 )
+ # ---- functional and orm filter splitting and resolution
+ def test_parse_filters( self ):
+ filter_parser = HistoryFilters( self.app )
+ filters = filter_parser.parse_filters([
+ ( 'name', 'eq', 'wot' ),
+ ( 'deleted', 'eq', 'True' ),
+ ( 'annotation', 'in', 'hrrmm' )
+ ])
+ self.log( 'both orm and fn filters should be parsed and returned' )
+ self.assertEqual( len( filters ), 3 )
+
+ self.log( 'values should be parsed' )
+ self.assertEqual( filters[1].right.value, True )
+
+ def test_parse_filters_invalid_filters( self ):
+ filter_parser = HistoryFilters( self.app )
+ self.log( 'should error on non-column attr')
+ self.assertRaises( exceptions.RequestParameterInvalidException, filter_parser.parse_filters, [
+ ( 'merp', 'eq', 'wot' ),
+ ])
+ self.log( 'should error on non-whitelisted attr')
+ self.assertRaises( exceptions.RequestParameterInvalidException, filter_parser.parse_filters, [
+ ( 'user_id', 'eq', 'wot' ),
+ ])
+ self.log( 'should error on non-whitelisted op')
+ self.assertRaises( exceptions.RequestParameterInvalidException, filter_parser.parse_filters, [
+ ( 'name', 'lt', 'wot' ),
+ ])
+ self.log( 'should error on non-listed fn op')
+ self.assertRaises( exceptions.RequestParameterInvalidException, filter_parser.parse_filters, [
+ ( 'annotation', 'like', 'wot' ),
+ ])
+ self.log( 'should error on val parsing error')
+ self.assertRaises( exceptions.RequestParameterInvalidException, filter_parser.parse_filters, [
+ ( 'deleted', 'eq', 'true' ),
+ ])
+
+ def test_orm_filter_parsing( self ):
+ filter_parser = HistoryFilters( self.app )
+ user2 = self.user_mgr.create( self.trans, **user2_data )
+ history1 = self.history_mgr.create( self.trans, name='history1', user=user2 )
+ history2 = self.history_mgr.create( self.trans, name='history2', user=user2 )
+ history3 = self.history_mgr.create( self.trans, name='history3', user=user2 )
+
+ filters = filter_parser.parse_filters([
+ ( 'name', 'like', 'history%' ),
+ ])
+ histories = self.history_mgr.list( self.trans, filters=filters )
+ #for h in histories:
+ # print h.name
+ self.assertEqual( histories, [ history1, history2, history3 ])
+
+ filters = filter_parser.parse_filters([ ( 'name', 'like', '%2' ), ])
+ self.assertEqual( self.history_mgr.list( self.trans, filters=filters ), [ history2 ])
+
+ filters = filter_parser.parse_filters([ ( 'name', 'eq', 'history2' ), ])
+ self.assertEqual( self.history_mgr.list( self.trans, filters=filters ), [ history2 ])
+
+ self.history_mgr.update( self.trans, history1, dict( deleted=True ) )
+ filters = filter_parser.parse_filters([ ( 'deleted', 'eq', 'True' ), ])
+ self.assertEqual( self.history_mgr.list( self.trans, filters=filters ), [ history1 ])
+ filters = filter_parser.parse_filters([ ( 'deleted', 'eq', 'False' ), ])
+ self.assertEqual( self.history_mgr.list( self.trans, filters=filters ), [ history2, history3 ])
+ self.assertEqual( self.history_mgr.list( self.trans ), [ history1, history2, history3 ])
+
+ self.history_mgr.update( self.trans, history3, dict( deleted=True ) )
+ self.history_mgr.update( self.trans, history1, dict( importable=True ) )
+ self.history_mgr.update( self.trans, history2, dict( importable=True ) )
+ filters = filter_parser.parse_filters([
+ ( 'deleted', 'eq', 'True' ),
+ ( 'importable', 'eq', 'True' ),
+ ])
+ self.assertEqual( self.history_mgr.list( self.trans, filters=filters ), [ history1 ])
+ self.assertEqual( self.history_mgr.list( self.trans ), [ history1, history2, history3 ])
+
+ def test_fn_filter_parsing( self ):
+ filter_parser = HistoryFilters( self.app )
+ user2 = self.user_mgr.create( self.trans, **user2_data )
+ history1 = self.history_mgr.create( self.trans, name='history1', user=user2 )
+ history2 = self.history_mgr.create( self.trans, name='history2', user=user2 )
+ history3 = self.history_mgr.create( self.trans, name='history3', user=user2 )
+
+ filters = filter_parser.parse_filters([ ( 'annotation', 'in', 'no play' ), ])
+ anno_filter = filters[0]
+
+ history3.add_item_annotation( self.trans.sa_session, user2, history3, "All work and no play" )
+ self.trans.sa_session.flush()
+
+ self.assertTrue( anno_filter( history3 ) )
+ self.assertFalse( anno_filter( history2 ) )
+
+ self.assertEqual( self.history_mgr.list( self.trans, filters=filters ), [ history3 ])
+
+ self.log( 'should allow combinations of orm and fn filters' )
+ self.history_mgr.update( self.trans, history3, dict( importable=True ) )
+ self.history_mgr.update( self.trans, history2, dict( importable=True ) )
+ history1.add_item_annotation( self.trans.sa_session, user2, history1, "All work and no play" )
+ self.trans.sa_session.flush()
+
+ shining_examples = self.history_mgr.list( self.trans, filters=filter_parser.parse_filters([
+ ( 'importable', 'eq', 'True' ),
+ ( 'annotation', 'in', 'no play' ),
+ ]))
+ self.assertEqual( shining_examples, [ history3 ])
+
+ def test_fn_filter_currying( self ):
+ filter_parser = HistoryFilters( self.app )
+ filter_parser.fn_filter_parsers = {
+ 'name_len' : { 'op': { 'lt' : lambda i, v: len( i.name ) < v }, 'val': int }
+ }
+ self.log( 'should be 2 filters now' )
+ self.assertEqual( len( filter_parser.fn_filter_parsers ), 1 )
+ filters = filter_parser.parse_filters([
+ ( 'name_len', 'lt', '4' )
+ ])
+ self.log( 'should have parsed out a single filter' )
+ self.assertEqual( len( filters ), 1 )
+
+ filter_ = filters[0]
+ fake = mock.OpenObject()
+ fake.name = '123'
+ self.log( '123 should return true through the filter' )
+ self.assertTrue( filter_( fake ) )
+ fake.name = '1234'
+ self.log( '1234 should return false through the filter' )
+ self.assertFalse( filter_( fake ) )
+
+ def test_list( self ):
+ """
+ Test limit and offset in conjunction with both orm and fn filtering.
+ """
+ filter_parser = HistoryFilters( self.app )
+ user2 = self.user_mgr.create( self.trans, **user2_data )
+ history1 = self.history_mgr.create( self.trans, name='history1', user=user2 )
+ history2 = self.history_mgr.create( self.trans, name='history2', user=user2 )
+ history3 = self.history_mgr.create( self.trans, name='history3', user=user2 )
+ history4 = self.history_mgr.create( self.trans, name='history4', user=user2 )
+
+ self.history_mgr.delete( self.trans, history1 )
+ self.history_mgr.delete( self.trans, history2 )
+ self.history_mgr.delete( self.trans, history3 )
+
+ test_annotation = "testing"
+ history2.add_item_annotation( self.trans.sa_session, user2, history2, test_annotation )
+ self.trans.sa_session.flush()
+ history3.add_item_annotation( self.trans.sa_session, user2, history3, test_annotation )
+ self.trans.sa_session.flush()
+ history3.add_item_annotation( self.trans.sa_session, user2, history4, test_annotation )
+ self.trans.sa_session.flush()
+
+ all_histories = [ history1, history2, history3, history4 ]
+ deleted_and_annotated = [ history2, history3 ]
+
+ self.log( "no offset, no limit should work" )
+ self.assertEqual( self.history_mgr.list( self.trans, offset=None, limit=None ), all_histories )
+ self.assertEqual( self.history_mgr.list( self.trans ), all_histories )
+ self.log( "no offset, limit should work" )
+ self.assertEqual( self.history_mgr.list( self.trans, limit=2 ), [ history1, history2 ] )
+ self.log( "offset, no limit should work" )
+ self.assertEqual( self.history_mgr.list( self.trans, offset=1 ), [ history2, history3, history4 ] )
+ self.log( "offset, limit should work" )
+ self.assertEqual( self.history_mgr.list( self.trans, offset=1, limit=1 ), [ history2 ] )
+
+ self.log( "zero limit should return empty list" )
+ self.assertEqual( self.history_mgr.list( self.trans, limit=0 ), [] )
+ self.log( "past len offset should return empty list" )
+ self.assertEqual( self.history_mgr.list( self.trans, offset=len( all_histories ) ), [] )
+ self.log( "negative limit should return full list" )
+ self.assertEqual( self.history_mgr.list( self.trans, limit=-1 ), all_histories )
+ self.log( "negative offset should return full list" )
+ self.assertEqual( self.history_mgr.list( self.trans, offset=-1 ), all_histories )
+
+ filters = [ model.History.deleted == True ]
+ self.log( "orm filtered, no offset, no limit should work" )
+ found = self.history_mgr.list( self.trans, filters=filters )
+ self.assertEqual( found, [ history1, history2, history3 ] )
+ self.log( "orm filtered, no offset, limit should work" )
+ found = self.history_mgr.list( self.trans, filters=filters, limit=2 )
+ self.assertEqual( found, [ history1, history2 ] )
+ self.log( "orm filtered, offset, no limit should work" )
+ found = self.history_mgr.list( self.trans, filters=filters, offset=1 )
+ self.assertEqual( found, [ history2, history3 ] )
+ self.log( "orm filtered, offset, limit should work" )
+ found = self.history_mgr.list( self.trans, filters=filters, offset=1, limit=1 )
+ self.assertEqual( found, [ history2 ] )
+
+ filters = filter_parser.parse_filters([ ( 'annotation', 'in', test_annotation ) ])
+ self.log( "fn filtered, no offset, no limit should work" )
+ found = self.history_mgr.list( self.trans, filters=filters )
+ self.assertEqual( found, [ history2, history3, history4 ] )
+ self.log( "fn filtered, no offset, limit should work" )
+ found = self.history_mgr.list( self.trans, filters=filters, limit=2 )
+ self.assertEqual( found, [ history2, history3 ] )
+ self.log( "fn filtered, offset, no limit should work" )
+ found = self.history_mgr.list( self.trans, filters=filters, offset=1 )
+ self.assertEqual( found, [ history3, history4 ] )
+ self.log( "fn filtered, offset, limit should work" )
+ found = self.history_mgr.list( self.trans, filters=filters, offset=1, limit=1 )
+ self.assertEqual( found, [ history3 ] )
+
+ filters = filter_parser.parse_filters([
+ ( 'deleted', 'eq', 'True' ),
+ ( 'annotation', 'in', test_annotation )
+ ])
+ self.log( "orm and fn filtered, no offset, no limit should work" )
+ found = self.history_mgr.list( self.trans, filters=filters )
+ self.assertEqual( found, [ history2, history3 ] )
+ self.log( "orm and fn filtered, no offset, limit should work" )
+ found = self.history_mgr.list( self.trans, filters=filters, limit=1 )
+ self.assertEqual( found, [ history2 ] )
+ self.log( "orm and fn filtered, offset, no limit should work" )
+ found = self.history_mgr.list( self.trans, filters=filters, offset=1 )
+ self.assertEqual( found, [ history3 ] )
+ self.log( "orm and fn filtered, offset, limit should work" )
+ found = self.history_mgr.list( self.trans, filters=filters, offset=1, limit=1 )
+ self.assertEqual( found, [ history3 ] )
+
+ self.log( "orm and fn filtered, zero limit should return empty list" )
+ found = self.history_mgr.list( self.trans, filters=filters, limit=0 )
+ self.assertEqual( found, [] )
+ self.log( "orm and fn filtered, past len offset should return empty list" )
+ found = self.history_mgr.list( self.trans, filters=filters, offset=len( deleted_and_annotated ) )
+ self.assertEqual( found, [] )
+ self.log( "orm and fn filtered, negative limit should return full list" )
+ found = self.history_mgr.list( self.trans, filters=filters, limit=-1 )
+ self.assertEqual( found, deleted_and_annotated )
+ self.log( "orm and fn filtered, negative offset should return full list" )
+ found = self.history_mgr.list( self.trans, filters=filters, offset=-1 )
+ self.assertEqual( found, deleted_and_annotated )
+
+
+
+
# =============================================================================
if __name__ == '__main__':
# or more generally, nosetests test_resourcemanagers.py -s -v
diff -r 8a234cd86e8a972a43f0e13617c9f09ae1216fee -r 68f0ed37e08942acb1bb84b63911b22d7d4b6f65 test/unit/managers/test_ModelManager.py
--- a/test/unit/managers/test_ModelManager.py
+++ b/test/unit/managers/test_ModelManager.py
@@ -22,6 +22,7 @@
import mock
from galaxy.managers.users import UserManager
+from galaxy.managers import base
# =============================================================================
admin_email = 'admin(a)admin.admin'
diff -r 8a234cd86e8a972a43f0e13617c9f09ae1216fee -r 68f0ed37e08942acb1bb84b63911b22d7d4b6f65 test/unit/managers/test_UserManager.py
--- a/test/unit/managers/test_UserManager.py
+++ b/test/unit/managers/test_UserManager.py
@@ -110,8 +110,8 @@
user3 = self.user_mgr.create( self.trans, **user3_data )
self.log( "should be able to tell if a user is the current (trans) user" )
- self.assertTrue( self.user_mgr.is_current_user( self.trans, self.admin_user ) )
- self.assertFalse( self.user_mgr.is_current_user( self.trans, user2 ) )
+ self.assertEqual( self.user_mgr.current_user( self.trans ), self.admin_user )
+ self.assertNotEqual( self.user_mgr.current_user( self.trans ), user2 )
def test_api_keys( self ):
user2 = self.user_mgr.create( self.trans, **user2_data )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
3 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/156321d8d23b/
Changeset: 156321d8d23b
User: nsoranzo
Date: 2015-01-29 13:52:19+00:00
Summary: Fix INTEGRATED_TOOL_PANEL_DESCRIPTION .
Affected #: 1 file
diff -r 2171bcc223ca38613f50bba79df7739aefeb701b -r 156321d8d23bb777be1b5dde6b89c1bb776b9ddd lib/galaxy/tools/toolbox/base.py
--- a/lib/galaxy/tools/toolbox/base.py
+++ b/lib/galaxy/tools/toolbox/base.py
@@ -38,13 +38,17 @@
INTEGRATED_TOOL_PANEL_DESCRIPTION = """
-This is Galaxy's integrated tool panel and probably should not be modified
-directly. It will be regenerated each time Galaxy starts up. To modify locally
-managed tools (e.g. from tool_conf.xml) modify that file directly and restart
-Galaxy. Whenever possible Tool Shed managed tools (e.g. from shed_tool_conf.xml)
-should be managed from within the Galaxy interface of via is UI - but if changes
-are nessecary (such as to hide a tool or re-assign its section) modify that file
-and restart Galaxy.
+This is Galaxy's integrated tool panel and should be modified directly only for
+reordering tools inside a section. Each time Galaxy starts up, this file is
+synchronized with the various tool config files: tools, sections and labels
+added to one of these files, will be added also here in the appropriate place,
+while elements removed from the tool config files will be correspondingly
+deleted from this file.
+To modify locally managed tools (e.g. from tool_conf.xml) modify that file
+directly and restart Galaxy. Whenever possible Tool Shed managed tools (e.g.
+from shed_tool_conf.xml) should be managed from within the Galaxy interface or
+via its API - but if changes are necessary (such as to hide a tool or re-assign
+its section) modify that file and restart Galaxy.
"""
https://bitbucket.org/galaxy/galaxy-central/commits/d55ccd0bd71e/
Changeset: d55ccd0bd71e
User: nsoranzo
Date: 2015-01-29 14:43:59+00:00
Summary: Enhancements for galaxy.ini documentation
Affected #: 1 file
diff -r 156321d8d23bb777be1b5dde6b89c1bb776b9ddd -r d55ccd0bd71e688c69753edf15cbff2f6a2b82ba config/galaxy.ini.sample
--- a/config/galaxy.ini.sample
+++ b/config/galaxy.ini.sample
@@ -42,7 +42,8 @@
# Number of threads in the web server thread pool.
#threadpool_workers = 10
-# Set the number of seconds a thread can work before you should kill it (assuming it will never finish) to 3 hours.
+# Set the number of seconds a thread can work before you should kill it
+# (assuming it will never finish) to 3 hours. Default is 600 (10 minutes).
threadpool_kill_thread_limit = 10800
# ---- Filters --------------------------------------------------------------
@@ -172,10 +173,11 @@
# install from in the admin interface (.sample used if default does not exist).
#tool_sheds_config_file = config/tool_sheds_conf.xml
-# If the following option is set to True - Galaxy will monitor individual tools
-# and tool directories specified in tool_conf.xml for changes and reload these
-# tools. Watchdog must be installed and available to Galaxy to use this option.
-# See https://pypi.python.org/pypi/watchdog.
+# Enable monitoring of tools and tool directories listed in any tool config file
+# specified in tool_config_file option. If changes are found, tools are
+# automatically reloaded.
+# Watchdog ( https://pypi.python.org/pypi/watchdog ) must be installed and
+# available to Galaxy to use this option.
#watch_tools = False
# Enable automatic polling of relative tool sheds to see if any updates
@@ -685,6 +687,8 @@
# used by the algorithm that encodes and decodes these values. It can be any
# string. If left unchanged, anyone could construct a cookie that would grant
# them access to others' sessions.
+# One simple way to generate a value for this is with the shell command:
+# python -c 'import time; print time.time()' | md5sum | cut -f 1 -d ' '
#id_secret = USING THE DEFAULT IS NOT SECURE!
# User authentication can be delegated to an upstream proxy server (usually
https://bitbucket.org/galaxy/galaxy-central/commits/8a234cd86e8a/
Changeset: 8a234cd86e8a
User: nsoranzo
Date: 2015-01-29 14:47:47+00:00
Summary: Whitespace fixes. 80 character limit. Small rewordings.
Affected #: 1 file
diff -r d55ccd0bd71e688c69753edf15cbff2f6a2b82ba -r 8a234cd86e8a972a43f0e13617c9f09ae1216fee config/galaxy.ini.sample
--- a/config/galaxy.ini.sample
+++ b/config/galaxy.ini.sample
@@ -8,7 +8,7 @@
# Throughout this sample configuration file, except where stated otherwise,
# uncommented values override the default if left unset, whereas commented
-# values are set to the default value. Relative paths are relative to the root
+# values are set to the default value. Relative paths are relative to the root
# Galaxy directory.
#
# Examples of many of these options are explained in more detail in the wiki:
@@ -118,10 +118,10 @@
#database_query_profiling_proxy = False
# By default, Galaxy will use the same database to track user data and
-# tool shed install data. There are many situtations in which it is
+# tool shed install data. There are many situtations in which it is
# valuable to seperate these - for instance bootstrapping fresh Galaxy
-# instances with pretested installs. The following optin can be used to
-# separate the tool shed install database (all other options listed above
+# instances with pretested installs. The following optin can be used to
+# separate the tool shed install database (all other options listed above
# but prefixed with install_ are also available).
#install_database_connection = sqlite:///./database/universe.sqlite?isolation_level=IMMEDIATE
@@ -139,14 +139,16 @@
# config/tool_conf.xml does not exist).
#tool_config_file = config/tool_conf.xml,config/shed_tool_conf.xml
-# Enable / disable checking if any tools defined in the above non-shed tool_config_files
-# (i.e., tool_conf.xml) have been migrated from the Galaxy code distribution to the Tool
-# Shed. This setting should generally be set to False only for development Galaxy environments
-# that are often rebuilt from scratch where migrated tools do not need to be available in the
-# Galaxy tool panel. If the following setting remains commented, the default setting will be True.
+# Enable / disable checking if any tools defined in the above non-shed
+# tool_config_files (i.e., tool_conf.xml) have been migrated from the Galaxy
+# code distribution to the Tool Shed. This setting should generally be set to
+# False only for development Galaxy environments that are often rebuilt from
+# scratch where migrated tools do not need to be available in the Galaxy tool
+# panel. If the following setting remains commented, the default setting will
+# be True.
#check_migrate_tools = True
-# Tool config maintained by tool migration scripts. If you use the migration
+# Tool config maintained by tool migration scripts. If you use the migration
# scripts to install tools that have been migrated to the tool shed upon a new
# release, they will be added to this tool config file.
#migrated_tools_config = config/migrated_tools_conf.xml
@@ -154,11 +156,12 @@
# File that contains the XML section and tool tags from all tool panel config
# files integrated into a single file that defines the tool panel layout. This
# file can be changed by the Galaxy administrator to alter the layout of the
-# tool panel. If not present, Galaxy will create it.
+# tool panel. If not present, Galaxy will create it.
#integrated_tool_panel_config = integrated_tool_panel.xml
# Default path to the directory containing the tools defined in tool_conf.xml.
-# Other tool config files must include the tool_path as an attribute in the <toolbox> tag.
+# Other tool config files must include the tool_path as an attribute in the
+# <toolbox> tag.
#tool_path = tools
# Path to the directory in which tool dependencies are placed. This is used by
@@ -181,26 +184,28 @@
#watch_tools = False
# Enable automatic polling of relative tool sheds to see if any updates
-# are available for installed repositories. Ideally only one Galaxy
+# are available for installed repositories. Ideally only one Galaxy
# server process should be able to check for repository updates. The
# setting for hours_between_check should be an integer between 1 and 24.
#enable_tool_shed_check = False
#hours_between_check = 12
-# Enable use of an in-memory registry with bi-directional relationships
-# between repositories (i.e., in addition to lists of dependencies for a
-# repository, keep an in-memory registry of dependent items for each repository.
+# Enable use of an in-memory registry with bi-directional relationships between
+# repositories (i.e., in addition to lists of dependencies for a repository,
+# keep an in-memory registry of dependent items for each repository.
#manage_dependency_relationships = False
# XML config file that contains data table entries for the
-# ToolDataTableManager. This file is manually # maintained by the Galaxy
+# ToolDataTableManager. This file is manually # maintained by the Galaxy
# administrator (.sample used if default does not exist).
#tool_data_table_config_path = config/tool_data_table_conf.xml
-# XML config file that contains additional data table entries for the ToolDataTableManager. This file
-# is automatically generated based on the current installed tool shed repositories that contain valid
-# tool_data_table_conf.xml.sample files. At the time of installation, these entries are automatically
-# added to the following file, which is parsed and applied to the ToolDataTableManager at server start up.
+# XML config file that contains additional data table entries for the
+# ToolDataTableManager. This file is automatically generated based on the
+# current installed tool shed repositories that contain valid
+# tool_data_table_conf.xml.sample files. At the time of installation, these
+# entries are automatically added to the following file, which is parsed and
+# applied to the ToolDataTableManager at server start up.
#shed_tool_data_table_config = config/shed_tool_data_table_conf.xml
# Directory where data used by tools is located, see the samples in that
@@ -215,24 +220,26 @@
#len_file_path = tool-data/shared/ucsc/chrom
# Datatypes config file(s), defines what data (file) types are available in
-# Galaxy (.sample is used if default does not exist). If a datatype appears in
-# multiple files - the last definition is used (though the first sniffer is used
+# Galaxy (.sample is used if default does not exist). If a datatype appears in
+# multiple files, the last definition is used (though the first sniffer is used
# so limit sniffer definitions to one file).
#datatypes_config_file = config/datatypes_conf.xml
# Disable the 'Auto-detect' option for file uploads
#datatypes_disable_auto = False
-# Visualizations config directory: where to look for individual visualization plugins.
-# The path is relative to the Galaxy root dir. To use an absolute path begin the path
-# with '/'. This is a comma separated list. Defaults to "config/plugins/visualizations".
+# Visualizations config directory: where to look for individual visualization
+# plugins. The path is relative to the Galaxy root dir. To use an absolute
+# path begin the path with '/'. This is a comma separated list.
+# Defaults to "config/plugins/visualizations".
#visualization_plugins_directory = config/plugins/visualizations
-# Interactive environment plugins root directory: where to look for interactive environment
-# plugins. By default none will be loaded. Set to config/plugins/interactive_environments
-# to load Galaxy's stock plugins (currently just IPython). These will require Docker
-# to be configured and have security considerations so proceed with caution.
-#interactive_environment_plugins_directory =
+# Interactive environment plugins root directory: where to look for interactive
+# environment plugins. By default none will be loaded. Set to
+# config/plugins/interactive_environments to load Galaxy's stock plugins
+# (currently just IPython). These will require Docker to be configured and
+# have security considerations, so proceed with caution.
+#interactive_environment_plugins_directory =
# Each job is given a unique empty directory as its current working directory.
# This option defines in what parent directory those directories will be
@@ -247,18 +254,20 @@
# used for the cache
#template_cache_path = database/compiled_templates
-# Citation related caching. Tool citations information maybe fetched from
-# external sources such as http://dx.doi.org/ by Galaxy - the following parameters
-# can be used to control the caching used to store this information.
+# Citation related caching. Tool citations information maybe fetched from
+# external sources such as http://dx.doi.org/ by Galaxy - the following
+# parameters can be used to control the caching used to store this information.
#citation_cache_type = file
#citation_cache_data_dir = database/citations/data
#citation_cache_lock_dir = database/citations/lock
-# External service types config file, defines what types of external_services configurations
-# are available in Galaxy (.sample is used if default does not exist).
+# External service types config file, defining what types of external_services
+# configurations are available in Galaxy (.sample is used if default does not
+# exist).
#external_service_type_config_file = config/external_service_types_conf.xml
-# Path to the directory containing the external_service_types defined in the config.
+# Path to the directory containing the external_service_types defined in the
+# config.
#external_service_type_path = external_service_types
# Tools with a number of outputs not known until runtime can write these
@@ -316,10 +325,11 @@
# -- Mail and notification
-# Galaxy sends mail for various things: Subscribing users to the mailing list
-# if they request it, emailing password resets, notification from the Galaxy
-# Sample Tracking system, reporting dataset errors, and sending activation emails.
-# To do this, it needs to send mail through an SMTP server, which you may define here (host:port).
+# Galaxy sends mail for various things: subscribing users to the mailing list
+# if they request it, password resets, notifications from the Galaxy Sample
+# Tracking system, reporting dataset errors, and sending activation emails.
+# To do this, it needs to send mail through an SMTP server, which you may
+# define here (host:port).
# Galaxy will automatically try STARTTLS but will continue upon failure.
#smtp_server = None
@@ -337,37 +347,44 @@
#mailing_join_addr = galaxy-announce-join(a)bx.psu.edu
# Datasets in an error state include a link to report the error. Those reports
-# will be sent to this address. Error reports are disabled if no address is set.
-# Also this email is shown as a contact to user in case of Galaxy misconfiguration and other events user may encounter.
+# will be sent to this address. Error reports are disabled if no address is
+# set. Also this email is shown as a contact to user in case of Galaxy
+# misconfiguration and other events user may encounter.
#error_email_to = None
-# Activation email is used as a sender ('from' field) for the account activation mail.
-# We recommend using string in the following format: Galaxy Project <galaxy-no-reply(a)example.com>
+# Activation email is used as a sender ('from' field) for the account
+# activation mail. We recommend using string in the following format:
+# Galaxy Project <galaxy-no-reply(a)example.com>
#activation_email = None
-# URL of the support resource for the galaxy instance. Used in activation emails.
+# URL of the support resource for the galaxy instance. Used in activation
+# emails.
#instance_resource_url = http://wiki.galaxyproject.org/
-# E-mail domains blacklist is used for filtering out users that are using disposable email address
-# during the registration. If their address domain matches any domain in the BL they are refused the registration.
+# E-mail domains blacklist is used for filtering out users that are using
+# disposable email address during the registration. If their address domain
+# matches any domain in the blacklist, they are refused the registration.
#blacklist_file = config/disposable_email_blacklist.conf
-# Registration warning message is used to discourage people from registering multiple accounts. Applies mostly for the main Galaxy instance.
+# Registration warning message is used to discourage people from registering
+# multiple accounts. Applies mostly for the main Galaxy instance.
# If no message specified the warning box will not be shown.
#registration_warning_message = Please register only one account - we provide this service free of charge and have limited computational resources. Multi-accounts are tracked and will be subjected to account termination and data deletion.
# -- Account activation
-# This is user account activation feature global flag. If set to "False" the rest of the Account
-# activation configuration is ignored and user activation is disabled (a.k.a. accounts are active since registration).
-# Note the activation is also not working in case the smtp server is not defined.
+# User account activation feature global flag. If set to "False", the rest of
+# the Account activation configuration is ignored and user activation is
+# disabled (i.e. accounts are active since registration).
+# The activation is also not working in case the SMTP server is not defined.
#user_activation_on = False
-# Activation grace period. Activation is not forced (login is not disabled) until
-# grace period has passed. Users under grace period can't run jobs (see inactivity_box_content).
-# In hours. Default is 3. Enter 0 to disable grace period.
-# Users with OpenID logins have grace period forever.
+# Activation grace period (in hours). Activation is not forced (login is not
+# disabled) until grace period has passed. Users under grace period can't run
+# jobs (see inactivity_box_content). Default is 3. Enter 0 to disable grace
+# period.
+# Users with OpenID logins have grace period forever.
#activation_grace_period = 0
# Used for warning box for inactive accounts (unable to run jobs).
@@ -378,7 +395,7 @@
# -- Analytics
# You can enter tracking code here to track visitor's behavior
-# through your Google Analytics account. Example: UA-XXXXXXXX-Y
+# through your Google Analytics account. Example: UA-XXXXXXXX-Y
#ga_code = None
# -- Display sites
@@ -401,17 +418,19 @@
# them).
#display_servers = hgw1.cse.ucsc.edu,hgw2.cse.ucsc.edu,hgw3.cse.ucsc.edu,hgw4.cse.ucsc.edu,hgw…
-# To disable the old-style display applications that are hardcoded into datatype classes,
-# set enable_old_display_applications = False.
-# This may be desirable due to using the new-style, XML-defined, display applications that
-# have been defined for many of the datatypes that have the old-style.
+# To disable the old-style display applications that are hardcoded into
+# datatype classes, set enable_old_display_applications = False.
+# This may be desirable due to using the new-style, XML-defined, display
+# applications that have been defined for many of the datatypes that have the
+# old-style.
# There is also a potential security concern with the old-style applications,
-# where a malicious party could provide a link that appears to reference the Galaxy server,
-# but contains a redirect to a third-party server, tricking a Galaxy user to access said
-# site.
+# where a malicious party could provide a link that appears to reference the
+# Galaxy server, but contains a redirect to a third-party server, tricking a
+# Galaxy user to access said site.
#enable_old_display_applications = True
-# -- Next gen LIMS interface on top of existing Galaxy Sample/Request management code.
+# -- Next gen LIMS interface on top of existing Galaxy Sample/Request
+# management code.
use_nglims = False
nglims_config_file = tool-data/nglims.yaml
@@ -428,18 +447,20 @@
# Format string used when showing date and time information.
# The string may contain:
-# - the directives used by Python time.strftime() function (see http://docs.python.org/2/library/time.html#time.strftime ),
+# - the directives used by Python time.strftime() function (see
+# http://docs.python.org/2/library/time.html#time.strftime ),
# - $locale (complete format string for the server locale),
-# - $iso8601 (complete format string as specified by ISO 8601 international standard).
+# - $iso8601 (complete format string as specified by ISO 8601 international
+# standard).
# pretty_datetime_format = $locale (UTC)
-# URL (with schema http/https) of the Galaxy instance as accessible within your local
-# network - if specified used as a default by pulsar file staging and IPython docker
-# container for communicating back with Galaxy via the API.
+# URL (with schema http/https) of the Galaxy instance as accessible within your
+# local network - if specified used as a default by pulsar file staging and
+# IPython Docker container for communicating back with Galaxy via the API.
#galaxy_infrastructure_url = http://localhost:8080
-# The URL of the page to display in Galaxy's middle pane when loaded. This can be
-# an absolute or relative URL.
+# The URL of the page to display in Galaxy's middle pane when loaded. This can
+# be an absolute or relative URL.
#welcome_url = /static/welcome.html
# The URL linked by the "Galaxy/brand" text.
@@ -470,7 +491,7 @@
# The URL linked by the "Galaxy Q&A" link in the "Help" menu
# The Galaxy Q&A site is under development; when the site is done, this URL
# will be set and uncommented.
-#qa_url =
+#qa_url =
# Serve static content, which must be enabled if you're not serving it via a
# proxy server. These options should be self explanatory and so are not
@@ -527,9 +548,9 @@
# will cause modern web browsers to not allow Galaxy to be embedded in
# the frames of web applications hosted at other hosts - this can help
# prevent a class of attack called clickjacking
-# (https://www.owasp.org/index.php/Clickjacking) If you configure a
+# (https://www.owasp.org/index.php/Clickjacking) If you configure a
# proxy in front of Galaxy - please ensure this header remains intact
-# to protect your users. Uncomment and leave empty to not set the
+# to protect your users. Uncomment and leave empty to not set the
# `X-Frame-Options` header.
#x_frame_options = SAMEORIGIN
@@ -545,10 +566,10 @@
#nginx_upload_path = False
# Have Galaxy manage dynamic proxy component for routing requests to other
-# services based on Galaxy's session cookie. It will attempt to do this by
+# services based on Galaxy's session cookie. It will attempt to do this by
# default though you do need to install node+npm and do an npm install from
-# `lib/galaxy/web/proxy/js`. It is generally more robust to configure this
-# externally managing it however Galaxy is managed. If True Galaxy will only
+# `lib/galaxy/web/proxy/js`. It is generally more robust to configure this
+# externally managing it however Galaxy is managed. If True Galaxy will only
# launch the proxy if it is actually going to be used (e.g. for IPython).
#dynamic_proxy_manage=True
@@ -564,7 +585,8 @@
# Enable verbose debugging of Galaxy-managed dynamic proxy.
#dynamic_proxy_debug=False
-# The dynamic proxy is proxied by an external proxy (e.g. apache frontend to nodejs to wrap connections in SSL)
+# The dynamic proxy is proxied by an external proxy (e.g. apache frontend to
+# nodejs to wrap connections in SSL).
#dynamic_proxy_external_proxy=False
# -- Logging and Debugging
@@ -582,28 +604,28 @@
# Turn on logging of application events and some user events to the database.
#log_events = True
-# Turn on logging of user actions to the database. Actions currently logged are
-# grid views, tool searches, and use of "recently" used tools menu. The
+# Turn on logging of user actions to the database. Actions currently logged
+# are grid views, tool searches, and use of "recently" used tools menu. The
# log_events and log_actions functionality will eventually be merged.
#log_actions = True
-# Sanitize All HTML Tool Output By default, all tool output served as
-# 'text/html' will be sanitized thoroughly. This can be disabled if
-# you have special tools that require unaltered output. WARNING:
-# Disabling this does make the Galxy instance susceptible to XSS
-# attacks initiated by your users.
+# Sanitize all HTML tool output. By default, all tool output served as
+# 'text/html' will be sanitized thoroughly. This can be disabled if you have
+# special tools that require unaltered output. WARNING: disabling this does
+# make the Galaxy instance susceptible to XSS attacks initiated by your users.
#sanitize_all_html = True
# By default Galaxy will serve non-HTML tool output that may potentially
-# contain browser executable JavaScript content as plain text. This will for
+# contain browser executable JavaScript content as plain text. This will for
# instance cause SVG datasets to not render properly and so may be disabled
# by setting the following option to True.
#serve_xss_vulnerable_mimetypes = False
-# Set the following to True to use ipython nbconvert to build HTML from IPython
-# notebooks in Galaxy histories. This process may allow users to execute arbitrary
-# code or serve arbitrary HTML. If enabled ipython must be available and on Galaxy's
-# PATH, to do this run `pip install jinja2 pygments ipython` in Galaxy's virtualenv.
+# Set the following to True to use IPython nbconvert to build HTML from IPython
+# notebooks in Galaxy histories. This process may allow users to execute
+# arbitrary code or serve arbitrary HTML. If enabled, IPython must be
+# available and on Galaxy's PATH, to do this run
+# `pip install jinja2 pygments ipython` in Galaxy's virtualenv.
#trust_ipython_notebook_conversion = False
# Debug enables access to various config options useful for development and
@@ -659,7 +681,7 @@
# if testing shows that Galaxy is able to create files using these formats.
# Specific formats can be disabled with this option, separate more than one
# format with commas. Available formats are currently 'zip', 'gz', and 'bz2'.
-#disable_library_comptypes =
+#disable_library_comptypes =
# Some sequencer integration features in beta allow you to automatically
# transfer datasets. This is done using a lightweight transfer manager which
@@ -710,10 +732,11 @@
#remote_user_header = HTTP_REMOTE_USER
# If use_remote_user is enabled, anyone who can log in to the Galaxy host may
-# impersonate any other user by simply sending the appropriate header. Thus a
+# impersonate any other user by simply sending the appropriate header. Thus a
# secret shared between the upstream proxy server, and Galaxy is required.
-# If anyone other than the Galaxy user is using the server, then apache/nginx should
-# pass a value in the header 'GX_SECRET' that is identical the one below
+# If anyone other than the Galaxy user is using the server, then apache/nginx
+# should pass a value in the header 'GX_SECRET' that is identical to the one
+# below.
#remote_user_secret = USING THE DEFAULT IS NOT SECURE!
# If use_remote_user is enabled, you can set this to a URL that will log your
@@ -798,8 +821,9 @@
#api_allow_run_as = None
# Master key that allows many API admin actions to be used without actually
-# having a defined admin user in the database/config. Only set this if you need
-# to bootstrap Galaxy, you probably do not want to set this on public servers.
+# having a defined admin user in the database/config. Only set this if you
+# need to bootstrap Galaxy, you probably do not want to set this on public
+# servers.
#master_api_key = changethis
# Enable tool tags (associating tools with tags). This has its own option
@@ -807,7 +831,7 @@
# large servers.
#enable_tool_tags = False
-# Enable a feature when running workflows. When enabled, default datasets
+# Enable a feature when running workflows. When enabled, default datasets
# are selected for "Set at Runtime" inputs from the history such that the
# same input will not be selected twice, unless there are more inputs than
# compatible datasets in the history.
@@ -843,7 +867,7 @@
# File where Data Managers are configured (.sample used if default does not
# exist)
#data_manager_config_file = config/data_manager_conf.xml
-# File where Tool Shed based Data Managers are configured
+# File where Tool Shed based Data Managers are configured
#shed_data_manager_config_file = config/shed_data_manager_conf.xml
# Directory to store Data Manager based tool-data; defaults to tool_data_path
#galaxy_data_manager_data_path = tool-data
@@ -870,7 +894,8 @@
# following option to True or False.
#track_jobs_in_database = None
-# This enables splitting of jobs into tasks, if specified by the particular tool config.
+# This enables splitting of jobs into tasks, if specified by the particular tool
+# config.
# This is a new feature and not recommended for production servers yet.
#use_tasked_jobs = False
#local_task_queue_workers = 2
@@ -921,7 +946,8 @@
# Optional file containing job resource data entry fields definition.
# These fields will be presented to users in the tool forms and allow them to
-# overwrite default job resources such as number of processors, memory, and walltime.
+# overwrite default job resources such as number of processors, memory and
+# walltime.
#job_resource_params_file = config/job_resource_params_conf.xml
# If using job concurrency limits (configured in job_config_file), several
@@ -940,7 +966,7 @@
# the following lines. tool_* filters will be applied for all users
# and can not be changed by them. user_tool_* filters will be shown
# under user preferences and can be toogled on and off by
-# runtime. Example shown below are not real defaults (no custom
+# runtime. Example shown below are not real defaults (no custom
# filters applied by defualt) but can be enabled with by renaming the
# example.py.sample in the filters directory to example.py.
@@ -972,11 +998,12 @@
# ---- Galaxy External Message Queue -------------------------------------------------
-# Galaxy uses AMQ protocol to receive messages from external sources like
-# bar code scanners. Galaxy has been tested against RabbitMQ AMQP implementation.
-# For Galaxy to receive messages from a message queue the RabbitMQ server has
-# to be set up with a user account and other parameters listed below. The 'host'
-# and 'port' fields should point to where the RabbitMQ server is running.
+# Galaxy uses Advanced Message Queuing Protocol (AMQP) to receive messages from
+# external sources like barcode scanners. Galaxy has been tested against
+# RabbitMQ AMQP implementation. For Galaxy to receive messages from a message
+# queue, the RabbitMQ server has to be set up with a user account and other
+# parameters listed below. The 'host' and 'port' fields should point to where
+# the RabbitMQ server is running.
[galaxy_amqp]
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: natefoo: Update tag latest_2015.01.13 for changeset a481d17c0448
by commits-noreply@bitbucket.org 29 Jan '15
by commits-noreply@bitbucket.org 29 Jan '15
29 Jan '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/d386cf71d4f7/
Changeset: d386cf71d4f7
Branch: stable
User: natefoo
Date: 2015-01-29 14:00:24+00:00
Summary: Update tag latest_2015.01.13 for changeset a481d17c0448
Affected #: 1 file
diff -r a481d17c04482b069e6b2ebdda4fbca01448fa9c -r d386cf71d4f71faeb49ec871b742e81011bee266 .hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -22,4 +22,4 @@
2092948937ac30ef82f71463a235c66d34987088 release_2014.10.06
9bd6f8b5b8153db752f4e61ed62f2b6c01ae4a11 latest_2014.10.06
2e8dd2949dd3eee0f56f9a3a5ebf1b2baca24aee release_2015.01.13
-1b96d3a4ff28da2bd547b65ad86c5ad5a9bbfb90 latest_2015.01.13
+a481d17c04482b069e6b2ebdda4fbca01448fa9c latest_2015.01.13
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: guerler: ToolForm: Update validation
by commits-noreply@bitbucket.org 29 Jan '15
by commits-noreply@bitbucket.org 29 Jan '15
29 Jan '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/2171bcc223ca/
Changeset: 2171bcc223ca
User: guerler
Date: 2015-01-29 09:30:33+00:00
Summary: ToolForm: Update validation
Affected #: 4 files
diff -r 708c937803503af156be3dde0c403095edcb1e31 -r 2171bcc223ca38613f50bba79df7739aefeb701b client/galaxy/scripts/mvc/tools/tools-tree.js
--- a/client/galaxy/scripts/mvc/tools/tools-tree.js
+++ b/client/galaxy/scripts/mvc/tools/tools-tree.js
@@ -122,15 +122,11 @@
value = patch[input.type](value);
}
- // validate value
- var skipped = field.skip && input.optional;
- var unvalidated = field.validate && !field.validate();
- if (!self.app.options.use_defaults) {
- if (skipped || unvalidated) {
- value = null;
- }
- } else {
- if (!skipped && unvalidated) {
+ // validate field value
+ if (field.skip || (field.validate && !field.validate())) {
+ if (self.app.options.use_defaults) {
+ value = input.default_value;
+ } else {
value = null;
}
}
diff -r 708c937803503af156be3dde0c403095edcb1e31 -r 2171bcc223ca38613f50bba79df7739aefeb701b lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -2405,7 +2405,9 @@
pass
group_state[input.test_param.name] = value
else:
- default_value = incoming.get(key, state.get(input.name, None))
+ default_value = incoming.get(key, None)
+ if not default_value:
+ default_value = state[input.name]
value, error = check_state(trans, input, default_value, context)
if error:
errors[key] = error
@@ -2456,10 +2458,6 @@
# sanitize values
sanitize(tool_dict, 'value')
sanitize(tool_dict, 'default_value')
-
- # set default value if necessary
- if not tool_dict['value']:
- tool_dict['value'] = tool_dict['default_value']
# backup final input dictionary
group_inputs[input_index] = tool_dict
diff -r 708c937803503af156be3dde0c403095edcb1e31 -r 2171bcc223ca38613f50bba79df7739aefeb701b static/scripts/mvc/tools/tools-tree.js
--- a/static/scripts/mvc/tools/tools-tree.js
+++ b/static/scripts/mvc/tools/tools-tree.js
@@ -122,15 +122,11 @@
value = patch[input.type](value);
}
- // validate value
- var skipped = field.skip && input.optional;
- var unvalidated = field.validate && !field.validate();
- if (!self.app.options.use_defaults) {
- if (skipped || unvalidated) {
- value = null;
- }
- } else {
- if (!skipped && unvalidated) {
+ // validate field value
+ if (field.skip || (field.validate && !field.validate())) {
+ if (self.app.options.use_defaults) {
+ value = input.default_value;
+ } else {
value = null;
}
}
diff -r 708c937803503af156be3dde0c403095edcb1e31 -r 2171bcc223ca38613f50bba79df7739aefeb701b static/scripts/packed/mvc/tools/tools-tree.js
--- a/static/scripts/packed/mvc/tools/tools-tree.js
+++ b/static/scripts/packed/mvc/tools/tools-tree.js
@@ -1,1 +1,1 @@
-define(["utils/utils"],function(a){return Backbone.Model.extend({initialize:function(b){this.app=b},finalize:function(g){var b=this;this.map_dict={};if(!this.app.section){return{}}g=g||{};var f={};var e={};this._iterate(this.app.section.$el,e);function d(j,i,h){f[j]=h;b.map_dict[j]=i}function c(l,n){for(var p in n){var w=n[p];if(w.input){var s=w.input;var t=l;if(l!=""){t+="|"}t+=s.name;switch(s.type){case"repeat":var k="section-";var q=[];var m=null;for(var r in w){var o=r.indexOf(k);if(o!=-1){o+=k.length;q.push(parseInt(r.substr(o)));if(!m){m=r.substr(0,o)}}}q.sort(function(A,i){return A-i});var p=0;for(var x in q){c(t+"_"+p++,w[m+q[x]])}break;case"conditional":var v=b.app.field_list[s.id].value();if(g[s.test_param.type]){v=g[s.test_param.type](v)}d(t+"|"+s.test_param.name,s.id,v);var u=b.matchCase(s,v);if(u!=-1){c(t,n[s.id+"-section-"+u])}break;case"section":c("",w);break;default:var j=b.app.field_list[s.id];if(j&&j.value){var v=j.value();if(g[s.type]){v=g[s.type](v)}var z=j.skip&&s.optional;var h=j.validate&&!j.validate();if(!b.app.options.use_defaults){if(z||h){v=null}}else{if(!z&&h){v=null}}if(s.ignore===undefined||(v!==null&&s.ignore!=v)){d(t,s.id,v);if(s.payload){for(var y in s.payload){d(y,s.id,s.payload[y])}}}}}}}}c("",e);return f},match:function(b){return this.map_dict&&this.map_dict[b]},matchCase:function(b,d){if(b.test_param.type=="boolean"){if(d=="true"){d=b.test_param.truevalue||"true"}else{d=b.test_param.falsevalue||"false"}}for(var c in b.cases){if(b.cases[c].value==d){return c}}return -1},matchModel:function(d,f){var b={};var c=this;function e(g,p){for(var m in p){var k=p[m];var n=k.name;if(g!=""){n=g+"|"+n}switch(k.type){case"repeat":for(var l in k.cache){e(n+"_"+l,k.cache[l])}break;case"conditional":var q=k.test_param&&k.test_param.value;var h=c.matchCase(k,q);if(h!=-1){e(n,k.cases[h].inputs)}break;default:var o=c.map_dict[n];if(o){f(o,k)}}}}e("",d.inputs);return b},matchResponse:function(d){var b={};var c=this;function e(l,j){if(typeof j==="string"){var g=c.map_dict[l];if(g){b[g]=j}}else{for(var h in j){var f=h;if(l!==""){var k="|";if(j instanceof Array){k="_"}f=l+k+f}e(f,j[h])}}}e("",d);return b},_iterate:function(d,e){var b=this;var c=$(d).children();c.each(function(){var h=this;var g=$(h).attr("id");if($(h).hasClass("section-row")){e[g]={};var f=b.app.input_list[g];if(f){e[g]={input:f}}b._iterate(h,e[g])}else{b._iterate(h,e)}})}})});
\ No newline at end of file
+define(["utils/utils"],function(a){return Backbone.Model.extend({initialize:function(b){this.app=b},finalize:function(g){var b=this;this.map_dict={};if(!this.app.section){return{}}g=g||{};var f={};var e={};this._iterate(this.app.section.$el,e);function d(j,i,h){f[j]=h;b.map_dict[j]=i}function c(p,s){for(var n in s){var k=s[n];if(k.input){var u=k.input;var o=p;if(p!=""){o+="|"}o+=u.name;switch(u.type){case"repeat":var j="section-";var x=[];var r=null;for(var w in k){var q=w.indexOf(j);if(q!=-1){q+=j.length;x.push(parseInt(w.substr(q)));if(!r){r=w.substr(0,q)}}}x.sort(function(y,i){return y-i});var n=0;for(var l in x){c(o+"_"+n++,k[r+x[l]])}break;case"conditional":var v=b.app.field_list[u.id].value();if(g[u.test_param.type]){v=g[u.test_param.type](v)}d(o+"|"+u.test_param.name,u.id,v);var h=b.matchCase(u,v);if(h!=-1){c(o,s[u.id+"-section-"+h])}break;case"section":c("",k);break;default:var t=b.app.field_list[u.id];if(t&&t.value){var v=t.value();if(g[u.type]){v=g[u.type](v)}if(t.skip||(t.validate&&!t.validate())){if(b.app.options.use_defaults){v=u.default_value}else{v=null}}if(u.ignore===undefined||(v!==null&&u.ignore!=v)){d(o,u.id,v);if(u.payload){for(var m in u.payload){d(m,u.id,u.payload[m])}}}}}}}}c("",e);return f},match:function(b){return this.map_dict&&this.map_dict[b]},matchCase:function(b,d){if(b.test_param.type=="boolean"){if(d=="true"){d=b.test_param.truevalue||"true"}else{d=b.test_param.falsevalue||"false"}}for(var c in b.cases){if(b.cases[c].value==d){return c}}return -1},matchModel:function(d,f){var b={};var c=this;function e(g,p){for(var m in p){var k=p[m];var n=k.name;if(g!=""){n=g+"|"+n}switch(k.type){case"repeat":for(var l in k.cache){e(n+"_"+l,k.cache[l])}break;case"conditional":var q=k.test_param&&k.test_param.value;var h=c.matchCase(k,q);if(h!=-1){e(n,k.cases[h].inputs)}break;default:var o=c.map_dict[n];if(o){f(o,k)}}}}e("",d.inputs);return b},matchResponse:function(d){var b={};var c=this;function e(l,j){if(typeof j==="string"){var g=c.map_dict[l];if(g){b[g]=j}}else{for(var h in j){var f=h;if(l!==""){var k="|";if(j instanceof Array){k="_"}f=l+k+f}e(f,j[h])}}}e("",d);return b},_iterate:function(d,e){var b=this;var c=$(d).children();c.each(function(){var h=this;var g=$(h).attr("id");if($(h).hasClass("section-row")){e[g]={};var f=b.app.input_list[g];if(f){e[g]={input:f}}b._iterate(h,e[g])}else{b._iterate(h,e)}})}})});
\ No newline at end of file
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: guerler: Upload: Remove style desc from js
by commits-noreply@bitbucket.org 29 Jan '15
by commits-noreply@bitbucket.org 29 Jan '15
29 Jan '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/708c93780350/
Changeset: 708c93780350
User: guerler
Date: 2015-01-29 08:10:36+00:00
Summary: Upload: Remove style desc from js
Affected #: 5 files
diff -r b46b6068fa0e9db3fa31f1b80a0494c3fb4d49b5 -r 708c937803503af156be3dde0c403095edcb1e31 client/galaxy/scripts/mvc/upload/upload-ftp.js
--- a/client/galaxy/scripts/mvc/upload/upload-ftp.js
+++ b/client/galaxy/scripts/mvc/upload/upload-ftp.js
@@ -171,11 +171,11 @@
// template row
_templateRow: function(options) {
- return '<tr class="upload-ftp-row" style="cursor: pointer;">' +
+ return '<tr class="upload-ftp-row">' +
'<td><div class="icon"/></td>' +
- '<td style="width: 200px"><p style="width: inherit; word-wrap: break-word;">' + options.path + '</p></td>' +
- '<td style="white-space: nowrap;">' + Utils.bytesToString(options.size) + '</td>' +
- '<td style="white-space: nowrap;">' + options.ctime + '</td>' +
+ '<td class="label"><p>' + options.path + '</p></td>' +
+ '<td class="nonlabel">' + Utils.bytesToString(options.size) + '</td>' +
+ '<td class="nonlabel">' + options.ctime + '</td>' +
'</tr>';
},
diff -r b46b6068fa0e9db3fa31f1b80a0494c3fb4d49b5 -r 708c937803503af156be3dde0c403095edcb1e31 static/scripts/mvc/upload/upload-ftp.js
--- a/static/scripts/mvc/upload/upload-ftp.js
+++ b/static/scripts/mvc/upload/upload-ftp.js
@@ -171,11 +171,11 @@
// template row
_templateRow: function(options) {
- return '<tr class="upload-ftp-row" style="cursor: pointer;">' +
+ return '<tr class="upload-ftp-row">' +
'<td><div class="icon"/></td>' +
- '<td style="width: 200px"><p style="width: inherit; word-wrap: break-word;">' + options.path + '</p></td>' +
- '<td style="white-space: nowrap;">' + Utils.bytesToString(options.size) + '</td>' +
- '<td style="white-space: nowrap;">' + options.ctime + '</td>' +
+ '<td class="label"><p>' + options.path + '</p></td>' +
+ '<td class="nonlabel">' + Utils.bytesToString(options.size) + '</td>' +
+ '<td class="nonlabel">' + options.ctime + '</td>' +
'</tr>';
},
diff -r b46b6068fa0e9db3fa31f1b80a0494c3fb4d49b5 -r 708c937803503af156be3dde0c403095edcb1e31 static/scripts/packed/mvc/upload/upload-ftp.js
--- a/static/scripts/packed/mvc/upload/upload-ftp.js
+++ b/static/scripts/packed/mvc/upload/upload-ftp.js
@@ -1,1 +1,1 @@
-define(["utils/utils"],function(a){return Backbone.View.extend({options:{class_add:"upload-icon-button fa fa-square-o",class_remove:"upload-icon-button fa fa-check-square-o",class_partial:"upload-icon-button fa fa-minus-square-o"},initialize:function(c){this.app=c;var b=this;this.setElement(this._template());this.rows=[];a.get({url:galaxy_config.root+"api/ftp_files",success:function(d){b._fill(d)},error:function(){b._fill()}})},events:{mousedown:function(b){b.preventDefault()}},_fill:function(d){if(d&&d.length>0){this.$el.find("#upload-ftp-content").html($(this._templateTable()));var c=0;for(key in d){this.rows.push(this._add(d[key]));c+=d[key].size}this.$el.find("#upload-ftp-number").html(d.length+" files");this.$el.find("#upload-ftp-disk").html(a.bytesToString(c,true));this.$select_all=$("#upload-selectall");this.$select_all.addClass(this.options.class_add);var b=this;this.$select_all.on("click",function(){var g=b.$select_all.hasClass(b.options.class_add);for(key in d){var f=d[key];var e=b._find(f);if(!e&&g||e&&!g){b.rows[key].trigger("click")}}});b._refresh()}else{this.$el.find("#upload-ftp-content").html($(this._templateInfo()))}this.$el.find("#upload-ftp-wait").hide()},_add:function(f){var d=this;var e=$(this._templateRow(f));var b=e.find(".icon");$(this.el).find("tbody").append(e);var c="";if(this._find(f)){c=this.options.class_remove}else{c=this.options.class_add}b.addClass(c);e.on("click",function(){var g=d._find(f);b.removeClass();if(!g){d.app.uploadbox.add([{mode:"ftp",name:f.path,size:f.size,path:f.path}]);b.addClass(d.options.class_remove)}else{d.app.collection.remove(g);b.addClass(d.options.class_add)}d._refresh()});return e},_refresh:function(){var b=this.app.collection.where({file_mode:"ftp"});this.$select_all.removeClass();if(b.length==0){this.$select_all.addClass(this.options.class_add)}else{if(b.length==this.rows.length){this.$select_all.addClass(this.options.class_remove)}else{this.$select_all.addClass(this.options.class_partial)}}},_find:function(c){var b=this.app.collection.findWhere({file_path:c.path,status:"init",file_mode:"ftp"});if(b){return b.get("id")}return null},_templateRow:function(b){return'<tr class="upload-ftp-row" style="cursor: pointer;"><td><div class="icon"/></td><td style="width: 200px"><p style="width: inherit; word-wrap: break-word;">'+b.path+'</p></td><td style="white-space: nowrap;">'+a.bytesToString(b.size)+'</td><td style="white-space: nowrap;">'+b.ctime+"</td></tr>"},_templateTable:function(){return'<span style="whitespace: nowrap; float: left;">Available files: </span><span style="whitespace: nowrap; float: right;"><span class="upload-icon fa fa-file-text-o"/><span id="upload-ftp-number"/> <span class="upload-icon fa fa-hdd-o"/><span id="upload-ftp-disk"/></span><table class="grid" style="float: left;"><thead><tr><th><div id="upload-selectall"></th><th>Name</th><th>Size</th><th>Created</th></tr></thead><tbody></tbody></table>'},_templateInfo:function(){return'<div class="upload-ftp-warning warningmessage">Your FTP directory does not contain any files.</div>'},_template:function(){return'<div class="upload-ftp"><div id="upload-ftp-wait" class="upload-ftp-wait fa fa-spinner fa-spin"/><div class="upload-ftp-help">This Galaxy server allows you to upload files via FTP. To upload some files, log in to the FTP server at <strong>'+this.app.options.ftp_upload_site+'</strong> using your Galaxy credentials (email address and password).</div><div id="upload-ftp-content"></div><div>'}})});
\ No newline at end of file
+define(["utils/utils"],function(a){return Backbone.View.extend({options:{class_add:"upload-icon-button fa fa-square-o",class_remove:"upload-icon-button fa fa-check-square-o",class_partial:"upload-icon-button fa fa-minus-square-o"},initialize:function(c){this.app=c;var b=this;this.setElement(this._template());this.rows=[];a.get({url:galaxy_config.root+"api/ftp_files",success:function(d){b._fill(d)},error:function(){b._fill()}})},events:{mousedown:function(b){b.preventDefault()}},_fill:function(d){if(d&&d.length>0){this.$el.find("#upload-ftp-content").html($(this._templateTable()));var c=0;for(key in d){this.rows.push(this._add(d[key]));c+=d[key].size}this.$el.find("#upload-ftp-number").html(d.length+" files");this.$el.find("#upload-ftp-disk").html(a.bytesToString(c,true));this.$select_all=$("#upload-selectall");this.$select_all.addClass(this.options.class_add);var b=this;this.$select_all.on("click",function(){var g=b.$select_all.hasClass(b.options.class_add);for(key in d){var f=d[key];var e=b._find(f);if(!e&&g||e&&!g){b.rows[key].trigger("click")}}});b._refresh()}else{this.$el.find("#upload-ftp-content").html($(this._templateInfo()))}this.$el.find("#upload-ftp-wait").hide()},_add:function(f){var d=this;var e=$(this._templateRow(f));var b=e.find(".icon");$(this.el).find("tbody").append(e);var c="";if(this._find(f)){c=this.options.class_remove}else{c=this.options.class_add}b.addClass(c);e.on("click",function(){var g=d._find(f);b.removeClass();if(!g){d.app.uploadbox.add([{mode:"ftp",name:f.path,size:f.size,path:f.path}]);b.addClass(d.options.class_remove)}else{d.app.collection.remove(g);b.addClass(d.options.class_add)}d._refresh()});return e},_refresh:function(){var b=this.app.collection.where({file_mode:"ftp"});this.$select_all.removeClass();if(b.length==0){this.$select_all.addClass(this.options.class_add)}else{if(b.length==this.rows.length){this.$select_all.addClass(this.options.class_remove)}else{this.$select_all.addClass(this.options.class_partial)}}},_find:function(c){var b=this.app.collection.findWhere({file_path:c.path,status:"init",file_mode:"ftp"});if(b){return b.get("id")}return null},_templateRow:function(b){return'<tr class="upload-ftp-row"><td><div class="icon"/></td><td class="label"><p>'+b.path+'</p></td><td class="nonlabel">'+a.bytesToString(b.size)+'</td><td class="nonlabel">'+b.ctime+"</td></tr>"},_templateTable:function(){return'<span style="whitespace: nowrap; float: left;">Available files: </span><span style="whitespace: nowrap; float: right;"><span class="upload-icon fa fa-file-text-o"/><span id="upload-ftp-number"/> <span class="upload-icon fa fa-hdd-o"/><span id="upload-ftp-disk"/></span><table class="grid" style="float: left;"><thead><tr><th><div id="upload-selectall"></th><th>Name</th><th>Size</th><th>Created</th></tr></thead><tbody></tbody></table>'},_templateInfo:function(){return'<div class="upload-ftp-warning warningmessage">Your FTP directory does not contain any files.</div>'},_template:function(){return'<div class="upload-ftp"><div id="upload-ftp-wait" class="upload-ftp-wait fa fa-spinner fa-spin"/><div class="upload-ftp-help">This Galaxy server allows you to upload files via FTP. To upload some files, log in to the FTP server at <strong>'+this.app.options.ftp_upload_site+'</strong> using your Galaxy credentials (email address and password).</div><div id="upload-ftp-content"></div><div>'}})});
\ No newline at end of file
diff -r b46b6068fa0e9db3fa31f1b80a0494c3fb4d49b5 -r 708c937803503af156be3dde0c403095edcb1e31 static/style/blue/base.css
--- a/static/style/blue/base.css
+++ b/static/style/blue/base.css
@@ -1388,6 +1388,8 @@
.upload-ftp{height:250px;width:500px;overflow:auto}.upload-ftp .upload-ftp-wait{font-size:1.2em;position:absolute;bottom:10px;right:10px}
.upload-ftp .upload-ftp-help{margin-bottom:10px}
.upload-ftp .upload-ftp-warning{text-align:center;margin-top:20px}
+.upload-ftp .upload-ftp-row{cursor:pointer}.upload-ftp .upload-ftp-row .label{width:240px}.upload-ftp .upload-ftp-row .label p{width:inherit;word-wrap:break-word}
+.upload-ftp .upload-ftp-row .nonlabel{white-space:nowrap}
.upload-settings .upload-settings-cover{position:absolute;width:100%;height:100%;top:0px;left:0px;background:#fff;opacity:0.4;cursor:no-drop}
.upload-header{height:5%;text-align:left;max-height:20px;line-height:18px;margin-top:10px}.upload-header .header-title{font-weight:bold;padding-left:60px;padding-right:20px}
.upload-header .header-selection{width:200px;min-width:200px;font-size:11px;padding-right:10px}
diff -r b46b6068fa0e9db3fa31f1b80a0494c3fb4d49b5 -r 708c937803503af156be3dde0c403095edcb1e31 static/style/src/less/upload.less
--- a/static/style/src/less/upload.less
+++ b/static/style/src/less/upload.less
@@ -198,6 +198,20 @@
text-align: center;
margin-top: 20px;
}
+
+ .upload-ftp-row {
+ cursor: pointer;
+ .label {
+ width: 240px;
+ p {
+ width: inherit;
+ word-wrap: break-word;
+ }
+ }
+ .nonlabel {
+ white-space: nowrap;
+ }
+ }
}
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
29 Jan '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/b46b6068fa0e/
Changeset: b46b6068fa0e
User: guerler
Date: 2015-01-29 08:00:51+00:00
Summary: Upload: Fix comment
Affected #: 2 files
diff -r b962897b1dfe60442bf5328637cb3e23b800d53f -r b46b6068fa0e9db3fa31f1b80a0494c3fb4d49b5 client/galaxy/scripts/mvc/upload/upload-view.js
--- a/client/galaxy/scripts/mvc/upload/upload-view.js
+++ b/client/galaxy/scripts/mvc/upload/upload-view.js
@@ -138,7 +138,7 @@
self.list_extensions.unshift(self.auto);
}
- // set default extensions
+ // set default extension
self.default_extension = self.list_extensions[0] && self.list_extensions[0].id;
}
});
@@ -159,7 +159,7 @@
return a.id > b.id ? 1 : a.id < b.id ? -1 : 0;
});
- // set default extensions
+ // set default genome
self.default_genome = self.list_genomes[0] && self.list_genomes[0].id;
}
});
diff -r b962897b1dfe60442bf5328637cb3e23b800d53f -r b46b6068fa0e9db3fa31f1b80a0494c3fb4d49b5 static/scripts/mvc/upload/upload-view.js
--- a/static/scripts/mvc/upload/upload-view.js
+++ b/static/scripts/mvc/upload/upload-view.js
@@ -138,7 +138,7 @@
self.list_extensions.unshift(self.auto);
}
- // set default extensions
+ // set default extension
self.default_extension = self.list_extensions[0] && self.list_extensions[0].id;
}
});
@@ -159,7 +159,7 @@
return a.id > b.id ? 1 : a.id < b.id ? -1 : 0;
});
- // set default extensions
+ // set default genome
self.default_genome = self.list_genomes[0] && self.list_genomes[0].id;
}
});
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: guerler: Upload: Improve user interaction
by commits-noreply@bitbucket.org 29 Jan '15
by commits-noreply@bitbucket.org 29 Jan '15
29 Jan '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/b962897b1dfe/
Changeset: b962897b1dfe
User: guerler
Date: 2015-01-29 07:55:56+00:00
Summary: Upload: Improve user interaction
Affected #: 3 files
diff -r c80c4227f2250a3b891d08b2c78d654dfd650691 -r b962897b1dfe60442bf5328637cb3e23b800d53f client/galaxy/scripts/mvc/upload/upload-view.js
--- a/client/galaxy/scripts/mvc/upload/upload-view.js
+++ b/client/galaxy/scripts/mvc/upload/upload-view.js
@@ -137,6 +137,9 @@
if (!self.options.datatypes_disable_auto) {
self.list_extensions.unshift(self.auto);
}
+
+ // set default extensions
+ self.default_extension = self.list_extensions[0] && self.list_extensions[0].id;
}
});
@@ -155,6 +158,9 @@
self.list_genomes.sort(function(a, b) {
return a.id > b.id ? 1 : a.id < b.id ? -1 : 0;
});
+
+ // set default extensions
+ self.default_genome = self.list_genomes[0] && self.list_genomes[0].id;
}
});
@@ -222,9 +228,16 @@
// select extension
this.select_extension = new Select.View({
css : 'header-selection',
- data : self.list_extensions,
- container : self.$el.parent().find('#header-extension'),
- value : self.list_extensions[0]
+ data : this.list_extensions,
+ container : this.$el.parent().find('#header-extension'),
+ value : this.default_extension,
+ onchange : function(extension) {
+ self.collection.each(function(item) {
+ if (item.get('status') == 'init' && item.get('extension') == self.default_extension) {
+ item.set('extension', extension);
+ }
+ });
+ }
});
// handle extension info popover
@@ -232,16 +245,24 @@
self.showExtensionInfo({
$el : $(e.target),
title : self.select_extension.text(),
- extension : self.select_extension.value()
+ extension : self.select_extension.value(),
+ placement : 'top'
});
}).on('mousedown', function(e) { e.preventDefault(); });
// genome extension
this.select_genome = new Select.View({
css : 'header-selection',
- data : self.list_genomes,
- container : self.$el.parent().find('#header-genome'),
- value : self.list_genomes[0]
+ data : this.list_genomes,
+ container : this.$el.parent().find('#header-genome'),
+ value : this.default_genome,
+ onchange : function(genome) {
+ self.collection.each(function(item) {
+ if (item.get('status') == 'init' && item.get('genome') == self.default_genome) {
+ item.set('genome', genome);
+ }
+ });
+ }
});
}
@@ -266,7 +287,7 @@
// create popup
this.extension_popup && this.extension_popup.remove();
this.extension_popup = new Popover.View({
- placement: 'bottom',
+ placement: options.placement || 'bottom',
container: $el,
destroy: true
});
@@ -403,7 +424,7 @@
it.set('percentage', percentage);
// update ui button
- this.ui_button.set('percentage', this._upload_percentage(percentage, file.size));
+ this.ui_button.set('percentage', this._uploadPercentage(percentage, file.size));
},
// success
@@ -417,7 +438,7 @@
var file_size = it.get('file_size');
// update ui button
- this.ui_button.set('percentage', this._upload_percentage(100, file_size));
+ this.ui_button.set('percentage', this._uploadPercentage(100, file_size));
// update completed
this.upload_completed += file_size * 100;
@@ -444,7 +465,7 @@
it.set('info', message);
// update ui button
- this.ui_button.set('percentage', this._upload_percentage(100, file.size));
+ this.ui_button.set('percentage', this._uploadPercentage(100, file.size));
this.ui_button.set('status', 'danger');
// update completed
@@ -563,8 +584,8 @@
this.uploadbox.reset();
// reset value for universal type drop-down
- this.select_extension.value(this.list_extensions[0]);
- this.select_genome.value(this.list_genomes[0]);
+ this.select_extension.value(this.default_extension);
+ this.select_genome.value(this.default_genome);
// reset button
this.ui_button.set('percentage', 0);
@@ -652,11 +673,10 @@
},
// calculate percentage of all queued uploads
- _upload_percentage: function(percentage, size) {
+ _uploadPercentage: function(percentage, size) {
return (this.upload_completed + (percentage * size)) / this.upload_size;
},
-
// template for extensions description
_templateDescription: function(options) {
if (options.description) {
diff -r c80c4227f2250a3b891d08b2c78d654dfd650691 -r b962897b1dfe60442bf5328637cb3e23b800d53f static/scripts/mvc/upload/upload-view.js
--- a/static/scripts/mvc/upload/upload-view.js
+++ b/static/scripts/mvc/upload/upload-view.js
@@ -137,6 +137,9 @@
if (!self.options.datatypes_disable_auto) {
self.list_extensions.unshift(self.auto);
}
+
+ // set default extensions
+ self.default_extension = self.list_extensions[0] && self.list_extensions[0].id;
}
});
@@ -155,6 +158,9 @@
self.list_genomes.sort(function(a, b) {
return a.id > b.id ? 1 : a.id < b.id ? -1 : 0;
});
+
+ // set default extensions
+ self.default_genome = self.list_genomes[0] && self.list_genomes[0].id;
}
});
@@ -222,9 +228,16 @@
// select extension
this.select_extension = new Select.View({
css : 'header-selection',
- data : self.list_extensions,
- container : self.$el.parent().find('#header-extension'),
- value : self.list_extensions[0]
+ data : this.list_extensions,
+ container : this.$el.parent().find('#header-extension'),
+ value : this.default_extension,
+ onchange : function(extension) {
+ self.collection.each(function(item) {
+ if (item.get('status') == 'init' && item.get('extension') == self.default_extension) {
+ item.set('extension', extension);
+ }
+ });
+ }
});
// handle extension info popover
@@ -232,16 +245,24 @@
self.showExtensionInfo({
$el : $(e.target),
title : self.select_extension.text(),
- extension : self.select_extension.value()
+ extension : self.select_extension.value(),
+ placement : 'top'
});
}).on('mousedown', function(e) { e.preventDefault(); });
// genome extension
this.select_genome = new Select.View({
css : 'header-selection',
- data : self.list_genomes,
- container : self.$el.parent().find('#header-genome'),
- value : self.list_genomes[0]
+ data : this.list_genomes,
+ container : this.$el.parent().find('#header-genome'),
+ value : this.default_genome,
+ onchange : function(genome) {
+ self.collection.each(function(item) {
+ if (item.get('status') == 'init' && item.get('genome') == self.default_genome) {
+ item.set('genome', genome);
+ }
+ });
+ }
});
}
@@ -266,7 +287,7 @@
// create popup
this.extension_popup && this.extension_popup.remove();
this.extension_popup = new Popover.View({
- placement: 'bottom',
+ placement: options.placement || 'bottom',
container: $el,
destroy: true
});
@@ -403,7 +424,7 @@
it.set('percentage', percentage);
// update ui button
- this.ui_button.set('percentage', this._upload_percentage(percentage, file.size));
+ this.ui_button.set('percentage', this._uploadPercentage(percentage, file.size));
},
// success
@@ -417,7 +438,7 @@
var file_size = it.get('file_size');
// update ui button
- this.ui_button.set('percentage', this._upload_percentage(100, file_size));
+ this.ui_button.set('percentage', this._uploadPercentage(100, file_size));
// update completed
this.upload_completed += file_size * 100;
@@ -444,7 +465,7 @@
it.set('info', message);
// update ui button
- this.ui_button.set('percentage', this._upload_percentage(100, file.size));
+ this.ui_button.set('percentage', this._uploadPercentage(100, file.size));
this.ui_button.set('status', 'danger');
// update completed
@@ -563,8 +584,8 @@
this.uploadbox.reset();
// reset value for universal type drop-down
- this.select_extension.value(this.list_extensions[0]);
- this.select_genome.value(this.list_genomes[0]);
+ this.select_extension.value(this.default_extension);
+ this.select_genome.value(this.default_genome);
// reset button
this.ui_button.set('percentage', 0);
@@ -652,11 +673,10 @@
},
// calculate percentage of all queued uploads
- _upload_percentage: function(percentage, size) {
+ _uploadPercentage: function(percentage, size) {
return (this.upload_completed + (percentage * size)) / this.upload_size;
},
-
// template for extensions description
_templateDescription: function(options) {
if (options.description) {
diff -r c80c4227f2250a3b891d08b2c78d654dfd650691 -r b962897b1dfe60442bf5328637cb3e23b800d53f static/scripts/packed/mvc/upload/upload-view.js
--- a/static/scripts/packed/mvc/upload/upload-view.js
+++ b/static/scripts/packed/mvc/upload/upload-view.js
@@ -1,1 +1,1 @@
-define(["utils/utils","mvc/upload/upload-button","mvc/upload/upload-model","mvc/upload/upload-row","mvc/upload/upload-ftp","mvc/ui/ui-popover","mvc/ui/ui-modal","mvc/ui/ui-select","utils/uploadbox"],function(f,e,c,b,g,d,a,h){return Backbone.View.extend({options:{nginx_upload_path:""},modal:null,ui_button:null,uploadbox:null,current_history:null,select_extension:null,select_genome:null,upload_size:0,list_extensions:[],list_genomes:[],auto:{id:"auto",text:"Auto-detect",description:"This system will try to detect the file type automatically. If your file is not detected properly as one of the known formats, it most likely means that it has some format problems (e.g., different number of columns on different rows). You can still coerce the system to set your data to the format you think it should be. You can also upload compressed files, which will automatically be decompressed."},collection:new c.Collection(),ftp:null,counter:{announce:0,success:0,error:0,running:0,reset:function(){this.announce=this.success=this.error=this.running=0}},initialize:function(j){var i=this;if(j){this.options=_.defaults(j,this.options)}this.ui_button=new e.Model({icon:"fa-upload",tooltip:"Download from URL or upload files from disk",label:"Load Data",onclick:function(k){if(k){k.preventDefault();i.show()}},onunload:function(){if(i.counter.running>0){return"Several uploads are still processing."}}});$(".with-upload-button").append((new e.View(this.ui_button)).$el);var i=this;f.get({url:galaxy_config.root+"api/datatypes?extension_only=False",success:function(k){for(key in k){i.list_extensions.push({id:k[key].extension,text:k[key].extension,description:k[key].description,description_url:k[key].description_url})}i.list_extensions.sort(function(m,l){return m.id>l.id?1:m.id<l.id?-1:0});if(!i.options.datatypes_disable_auto){i.list_extensions.unshift(i.auto)}}});f.get({url:galaxy_config.root+"api/genomes",success:function(k){for(key in k){i.list_genomes.push({id:k[key][1],text:k[key][0]})}i.list_genomes.sort(function(m,l){return m.id>l.id?1:m.id<l.id?-1:0})}});this.collection.on("remove",function(k){i._eventRemove(k)})},show:function(){var i=this;if(!Galaxy.currHistoryPanel||!Galaxy.currHistoryPanel.model){window.setTimeout(function(){i.show()},500);return}if(!this.modal){var i=this;this.modal=new a.View({title:"Download data directly from web or upload files from your disk",body:this._template("upload-box","upload-info"),buttons:{"Choose local file":function(){i.uploadbox.select()},"Choose FTP file":function(){i._eventFtp()},"Paste/Fetch data":function(){i._eventCreate()},Start:function(){i._eventStart()},Pause:function(){i._eventStop()},Reset:function(){i._eventReset()},Close:function(){i.modal.hide()},},height:"400",width:"900",closing_events:true});this.setElement("#upload-box");var i=this;this.uploadbox=this.$el.uploadbox({announce:function(k,l,m){i._eventAnnounce(k,l,m)},initialize:function(k,l,m){return i._eventInitialize(k,l,m)},progress:function(k,l,m){i._eventProgress(k,l,m)},success:function(k,l,m){i._eventSuccess(k,l,m)},error:function(k,l,m){i._eventError(k,l,m)},complete:function(){i._eventComplete()}});var j=this.modal.getButton("Choose FTP file");this.ftp=new d.View({title:"FTP files",container:j});this.select_extension=new h.View({css:"header-selection",data:i.list_extensions,container:i.$el.parent().find("#header-extension"),value:i.list_extensions[0]});i.$el.parent().find("#header-extension-info").on("click",function(k){i.showExtensionInfo({$el:$(k.target),title:i.select_extension.text(),extension:i.select_extension.value()})}).on("mousedown",function(k){k.preventDefault()});this.select_genome=new h.View({css:"header-selection",data:i.list_genomes,container:i.$el.parent().find("#header-genome"),value:i.list_genomes[0]})}this.modal.show();this._updateUser();this._updateScreen()},showExtensionInfo:function(j){var i=this;var k=j.$el;var n=j.extension;var m=j.title;var l=_.findWhere(i.list_extensions,{id:n});this.extension_popup&&this.extension_popup.remove();this.extension_popup=new d.View({placement:"bottom",container:k,destroy:true});this.extension_popup.title(m);this.extension_popup.empty();this.extension_popup.append(this._templateDescription(l));this.extension_popup.show()},_eventRemove:function(j){var i=j.get("status");if(i=="success"){this.counter.success--}else{if(i=="error"){this.counter.error--}else{this.counter.announce--}}this._updateScreen();this.uploadbox.remove(j.id)},_eventAnnounce:function(i,j,l){this.counter.announce++;this._updateScreen();var k=new b(this,{id:i,file_name:j.name,file_size:j.size,file_mode:j.mode,file_path:j.path});this.collection.add(k.model);$(this.el).find("tbody:first").append(k.$el);k.render()},_eventInitialize:function(n,k,t){var l=this.collection.get(n);l.set("status","running");var p=l.get("file_name");var o=l.get("file_path");var i=l.get("file_mode");var q=l.get("extension");var s=l.get("genome");var r=l.get("url_paste");var m=l.get("space_to_tabs");var j=l.get("to_posix_lines");if(!r&&!(k.size>0)){return null}this.uploadbox.configure({url:this.options.nginx_upload_path});if(i=="local"){this.uploadbox.configure({paramname:"files_0|file_data"})}else{this.uploadbox.configure({paramname:null})}tool_input={};if(i=="new"){tool_input["files_0|url_paste"]=r}if(i=="ftp"){tool_input["files_0|ftp_files"]=o}tool_input.dbkey=s;tool_input.file_type=q;tool_input["files_0|type"]="upload_dataset";tool_input["files_0|space_to_tab"]=m&&"Yes"||null;tool_input["files_0|to_posix_lines"]=j&&"Yes"||null;data={};data.history_id=this.current_history;data.tool_id="upload1";data.inputs=JSON.stringify(tool_input);return data},_eventProgress:function(j,k,i){var l=this.collection.get(j);l.set("percentage",i);this.ui_button.set("percentage",this._upload_percentage(i,k.size))},_eventSuccess:function(j,k,m){var l=this.collection.get(j);l.set("percentage",100);l.set("status","success");var i=l.get("file_size");this.ui_button.set("percentage",this._upload_percentage(100,i));this.upload_completed+=i*100;this.counter.announce--;this.counter.success++;this._updateScreen();Galaxy.currHistoryPanel.refreshContents()},_eventError:function(i,j,l){var k=this.collection.get(i);k.set("percentage",100);k.set("status","error");k.set("info",l);this.ui_button.set("percentage",this._upload_percentage(100,j.size));this.ui_button.set("status","danger");this.upload_completed+=j.size*100;this.counter.announce--;this.counter.error++;this._updateScreen()},_eventComplete:function(){this.collection.each(function(i){if(i.get("status")=="queued"){i.set("status","init")}});this.counter.running=0;this._updateScreen()},_eventFtp:function(){if(!this.ftp.visible){this.ftp.empty();this.ftp.append((new g(this)).$el);this.ftp.show()}else{this.ftp.hide()}},_eventCreate:function(){this.uploadbox.add([{name:"New File",size:0,mode:"new"}])},_eventStart:function(){if(this.counter.announce==0||this.counter.running>0){return}var i=this;this.upload_size=0;this.upload_completed=0;this.collection.each(function(j){if(j.get("status")=="init"){j.set("status","queued");i.upload_size+=j.get("file_size")}});this.ui_button.set("percentage",0);this.ui_button.set("status","success");this.counter.running=this.counter.announce;this._updateScreen();this.uploadbox.start()},_eventStop:function(){if(this.counter.running==0){return}this.ui_button.set("status","info");this.uploadbox.stop();$("#upload-info").html("Queue will pause after completing the current file...")},_eventReset:function(){if(this.counter.running==0){this.collection.reset();this.counter.reset();this._updateScreen();this.uploadbox.reset();this.select_extension.value(this.list_extensions[0]);this.select_genome.value(this.list_genomes[0]);this.ui_button.set("percentage",0)}},_updateUser:function(){this.current_user=Galaxy.currUser.get("id");this.current_history=null;if(this.current_user){this.current_history=Galaxy.currHistoryPanel.model.get("id")}},_updateScreen:function(){if(this.counter.announce==0){if(this.uploadbox.compatible()){message="You can Drag & Drop files into this box."}else{message="Unfortunately, your browser does not support multiple file uploads or drag&drop.<br>Some supported browsers are: Firefox 4+, Chrome 7+, IE 10+, Opera 12+ or Safari 6+."}}else{if(this.counter.running==0){message="You added "+this.counter.announce+" file(s) to the queue. Add more files or click 'Start' to proceed."}else{message="Please wait..."+this.counter.announce+" out of "+this.counter.running+" remaining."}}$("#upload-info").html(message);if(this.counter.running==0&&this.counter.announce+this.counter.success+this.counter.error>0){this.modal.enableButton("Reset")}else{this.modal.disableButton("Reset")}if(this.counter.running==0&&this.counter.announce>0){this.modal.enableButton("Start")}else{this.modal.disableButton("Start")}if(this.counter.running>0){this.modal.enableButton("Pause")}else{this.modal.disableButton("Pause")}if(this.counter.running==0){this.modal.enableButton("Choose local file");this.modal.enableButton("Choose FTP file");this.modal.enableButton("Paste/Fetch data")}else{this.modal.disableButton("Choose local file");this.modal.disableButton("Choose FTP file");this.modal.disableButton("Paste/Fetch data")}if(this.current_user&&this.options.ftp_upload_dir&&this.options.ftp_upload_site){this.modal.showButton("Choose FTP file")}else{this.modal.hideButton("Choose FTP file")}if(this.counter.announce+this.counter.success+this.counter.error>0){$(this.el).find("#upload-table").show()}else{$(this.el).find("#upload-table").hide()}},_upload_percentage:function(i,j){return(this.upload_completed+(i*j))/this.upload_size},_templateDescription:function(j){if(j.description){var i=j.description;if(j.description_url){i+=' (<a href="'+j.description_url+'" target="_blank">read more</a>)'}return i}else{return"There is no description available for this file extension."}},_template:function(j,i){return'<div class="upload-top"><h6 id="'+i+'" class="upload-info"></h6></div><div id="'+j+'" class="upload-box"><table id="upload-table" class="table table-striped" style="display: none;"><thead><tr><th>Name</th><th>Size</th><th>Type</th><th>Genome</th><th>Settings</th><th>Status</th><th></th></tr></thead><tbody></tbody></table></div><div id="upload-header" class="upload-header"><span class="header-title">Type (default):</span><span id="header-extension"/><span id="header-extension-info" class="upload-icon-button fa fa-search"/><span class="header-title">Genome (default):</span><span id="header-genome"/></div>'}})});
\ No newline at end of file
+define(["utils/utils","mvc/upload/upload-button","mvc/upload/upload-model","mvc/upload/upload-row","mvc/upload/upload-ftp","mvc/ui/ui-popover","mvc/ui/ui-modal","mvc/ui/ui-select","utils/uploadbox"],function(f,e,c,b,g,d,a,h){return Backbone.View.extend({options:{nginx_upload_path:""},modal:null,ui_button:null,uploadbox:null,current_history:null,select_extension:null,select_genome:null,upload_size:0,list_extensions:[],list_genomes:[],auto:{id:"auto",text:"Auto-detect",description:"This system will try to detect the file type automatically. If your file is not detected properly as one of the known formats, it most likely means that it has some format problems (e.g., different number of columns on different rows). You can still coerce the system to set your data to the format you think it should be. You can also upload compressed files, which will automatically be decompressed."},collection:new c.Collection(),ftp:null,counter:{announce:0,success:0,error:0,running:0,reset:function(){this.announce=this.success=this.error=this.running=0}},initialize:function(j){var i=this;if(j){this.options=_.defaults(j,this.options)}this.ui_button=new e.Model({icon:"fa-upload",tooltip:"Download from URL or upload files from disk",label:"Load Data",onclick:function(k){if(k){k.preventDefault();i.show()}},onunload:function(){if(i.counter.running>0){return"Several uploads are still processing."}}});$(".with-upload-button").append((new e.View(this.ui_button)).$el);var i=this;f.get({url:galaxy_config.root+"api/datatypes?extension_only=False",success:function(k){for(key in k){i.list_extensions.push({id:k[key].extension,text:k[key].extension,description:k[key].description,description_url:k[key].description_url})}i.list_extensions.sort(function(m,l){return m.id>l.id?1:m.id<l.id?-1:0});if(!i.options.datatypes_disable_auto){i.list_extensions.unshift(i.auto)}i.default_extension=i.list_extensions[0]&&i.list_extensions[0].id}});f.get({url:galaxy_config.root+"api/genomes",success:function(k){for(key in k){i.list_genomes.push({id:k[key][1],text:k[key][0]})}i.list_genomes.sort(function(m,l){return m.id>l.id?1:m.id<l.id?-1:0});i.default_genome=i.list_genomes[0]&&i.list_genomes[0].id}});this.collection.on("remove",function(k){i._eventRemove(k)})},show:function(){var i=this;if(!Galaxy.currHistoryPanel||!Galaxy.currHistoryPanel.model){window.setTimeout(function(){i.show()},500);return}if(!this.modal){var i=this;this.modal=new a.View({title:"Download data directly from web or upload files from your disk",body:this._template("upload-box","upload-info"),buttons:{"Choose local file":function(){i.uploadbox.select()},"Choose FTP file":function(){i._eventFtp()},"Paste/Fetch data":function(){i._eventCreate()},Start:function(){i._eventStart()},Pause:function(){i._eventStop()},Reset:function(){i._eventReset()},Close:function(){i.modal.hide()},},height:"400",width:"900",closing_events:true});this.setElement("#upload-box");var i=this;this.uploadbox=this.$el.uploadbox({announce:function(k,l,m){i._eventAnnounce(k,l,m)},initialize:function(k,l,m){return i._eventInitialize(k,l,m)},progress:function(k,l,m){i._eventProgress(k,l,m)},success:function(k,l,m){i._eventSuccess(k,l,m)},error:function(k,l,m){i._eventError(k,l,m)},complete:function(){i._eventComplete()}});var j=this.modal.getButton("Choose FTP file");this.ftp=new d.View({title:"FTP files",container:j});this.select_extension=new h.View({css:"header-selection",data:this.list_extensions,container:this.$el.parent().find("#header-extension"),value:this.default_extension,onchange:function(k){i.collection.each(function(l){if(l.get("status")=="init"&&l.get("extension")==i.default_extension){l.set("extension",k)}})}});i.$el.parent().find("#header-extension-info").on("click",function(k){i.showExtensionInfo({$el:$(k.target),title:i.select_extension.text(),extension:i.select_extension.value(),placement:"top"})}).on("mousedown",function(k){k.preventDefault()});this.select_genome=new h.View({css:"header-selection",data:this.list_genomes,container:this.$el.parent().find("#header-genome"),value:this.default_genome,onchange:function(k){i.collection.each(function(l){if(l.get("status")=="init"&&l.get("genome")==i.default_genome){l.set("genome",k)}})}})}this.modal.show();this._updateUser();this._updateScreen()},showExtensionInfo:function(j){var i=this;var k=j.$el;var n=j.extension;var m=j.title;var l=_.findWhere(i.list_extensions,{id:n});this.extension_popup&&this.extension_popup.remove();this.extension_popup=new d.View({placement:j.placement||"bottom",container:k,destroy:true});this.extension_popup.title(m);this.extension_popup.empty();this.extension_popup.append(this._templateDescription(l));this.extension_popup.show()},_eventRemove:function(j){var i=j.get("status");if(i=="success"){this.counter.success--}else{if(i=="error"){this.counter.error--}else{this.counter.announce--}}this._updateScreen();this.uploadbox.remove(j.id)},_eventAnnounce:function(i,j,l){this.counter.announce++;this._updateScreen();var k=new b(this,{id:i,file_name:j.name,file_size:j.size,file_mode:j.mode,file_path:j.path});this.collection.add(k.model);$(this.el).find("tbody:first").append(k.$el);k.render()},_eventInitialize:function(n,k,t){var l=this.collection.get(n);l.set("status","running");var p=l.get("file_name");var o=l.get("file_path");var i=l.get("file_mode");var q=l.get("extension");var s=l.get("genome");var r=l.get("url_paste");var m=l.get("space_to_tabs");var j=l.get("to_posix_lines");if(!r&&!(k.size>0)){return null}this.uploadbox.configure({url:this.options.nginx_upload_path});if(i=="local"){this.uploadbox.configure({paramname:"files_0|file_data"})}else{this.uploadbox.configure({paramname:null})}tool_input={};if(i=="new"){tool_input["files_0|url_paste"]=r}if(i=="ftp"){tool_input["files_0|ftp_files"]=o}tool_input.dbkey=s;tool_input.file_type=q;tool_input["files_0|type"]="upload_dataset";tool_input["files_0|space_to_tab"]=m&&"Yes"||null;tool_input["files_0|to_posix_lines"]=j&&"Yes"||null;data={};data.history_id=this.current_history;data.tool_id="upload1";data.inputs=JSON.stringify(tool_input);return data},_eventProgress:function(j,k,i){var l=this.collection.get(j);l.set("percentage",i);this.ui_button.set("percentage",this._uploadPercentage(i,k.size))},_eventSuccess:function(j,k,m){var l=this.collection.get(j);l.set("percentage",100);l.set("status","success");var i=l.get("file_size");this.ui_button.set("percentage",this._uploadPercentage(100,i));this.upload_completed+=i*100;this.counter.announce--;this.counter.success++;this._updateScreen();Galaxy.currHistoryPanel.refreshContents()},_eventError:function(i,j,l){var k=this.collection.get(i);k.set("percentage",100);k.set("status","error");k.set("info",l);this.ui_button.set("percentage",this._uploadPercentage(100,j.size));this.ui_button.set("status","danger");this.upload_completed+=j.size*100;this.counter.announce--;this.counter.error++;this._updateScreen()},_eventComplete:function(){this.collection.each(function(i){if(i.get("status")=="queued"){i.set("status","init")}});this.counter.running=0;this._updateScreen()},_eventFtp:function(){if(!this.ftp.visible){this.ftp.empty();this.ftp.append((new g(this)).$el);this.ftp.show()}else{this.ftp.hide()}},_eventCreate:function(){this.uploadbox.add([{name:"New File",size:0,mode:"new"}])},_eventStart:function(){if(this.counter.announce==0||this.counter.running>0){return}var i=this;this.upload_size=0;this.upload_completed=0;this.collection.each(function(j){if(j.get("status")=="init"){j.set("status","queued");i.upload_size+=j.get("file_size")}});this.ui_button.set("percentage",0);this.ui_button.set("status","success");this.counter.running=this.counter.announce;this._updateScreen();this.uploadbox.start()},_eventStop:function(){if(this.counter.running==0){return}this.ui_button.set("status","info");this.uploadbox.stop();$("#upload-info").html("Queue will pause after completing the current file...")},_eventReset:function(){if(this.counter.running==0){this.collection.reset();this.counter.reset();this._updateScreen();this.uploadbox.reset();this.select_extension.value(this.default_extension);this.select_genome.value(this.default_genome);this.ui_button.set("percentage",0)}},_updateUser:function(){this.current_user=Galaxy.currUser.get("id");this.current_history=null;if(this.current_user){this.current_history=Galaxy.currHistoryPanel.model.get("id")}},_updateScreen:function(){if(this.counter.announce==0){if(this.uploadbox.compatible()){message="You can Drag & Drop files into this box."}else{message="Unfortunately, your browser does not support multiple file uploads or drag&drop.<br>Some supported browsers are: Firefox 4+, Chrome 7+, IE 10+, Opera 12+ or Safari 6+."}}else{if(this.counter.running==0){message="You added "+this.counter.announce+" file(s) to the queue. Add more files or click 'Start' to proceed."}else{message="Please wait..."+this.counter.announce+" out of "+this.counter.running+" remaining."}}$("#upload-info").html(message);if(this.counter.running==0&&this.counter.announce+this.counter.success+this.counter.error>0){this.modal.enableButton("Reset")}else{this.modal.disableButton("Reset")}if(this.counter.running==0&&this.counter.announce>0){this.modal.enableButton("Start")}else{this.modal.disableButton("Start")}if(this.counter.running>0){this.modal.enableButton("Pause")}else{this.modal.disableButton("Pause")}if(this.counter.running==0){this.modal.enableButton("Choose local file");this.modal.enableButton("Choose FTP file");this.modal.enableButton("Paste/Fetch data")}else{this.modal.disableButton("Choose local file");this.modal.disableButton("Choose FTP file");this.modal.disableButton("Paste/Fetch data")}if(this.current_user&&this.options.ftp_upload_dir&&this.options.ftp_upload_site){this.modal.showButton("Choose FTP file")}else{this.modal.hideButton("Choose FTP file")}if(this.counter.announce+this.counter.success+this.counter.error>0){$(this.el).find("#upload-table").show()}else{$(this.el).find("#upload-table").hide()}},_uploadPercentage:function(i,j){return(this.upload_completed+(i*j))/this.upload_size},_templateDescription:function(j){if(j.description){var i=j.description;if(j.description_url){i+=' (<a href="'+j.description_url+'" target="_blank">read more</a>)'}return i}else{return"There is no description available for this file extension."}},_template:function(j,i){return'<div class="upload-top"><h6 id="'+i+'" class="upload-info"></h6></div><div id="'+j+'" class="upload-box"><table id="upload-table" class="table table-striped" style="display: none;"><thead><tr><th>Name</th><th>Size</th><th>Type</th><th>Genome</th><th>Settings</th><th>Status</th><th></th></tr></thead><tbody></tbody></table></div><div id="upload-header" class="upload-header"><span class="header-title">Type (default):</span><span id="header-extension"/><span id="header-extension-info" class="upload-icon-button fa fa-search"/><span class="header-title">Genome (default):</span><span id="header-genome"/></div>'}})});
\ No newline at end of file
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: guerler: Upload: Place default selectors into footer
by commits-noreply@bitbucket.org 29 Jan '15
by commits-noreply@bitbucket.org 29 Jan '15
29 Jan '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/c80c4227f225/
Changeset: c80c4227f225
User: guerler
Date: 2015-01-29 07:23:26+00:00
Summary: Upload: Place default selectors into footer
Affected #: 5 files
diff -r ab754acceaf9c786c7826dbd9d8316a384acdeb9 -r c80c4227f2250a3b891d08b2c78d654dfd650691 client/galaxy/scripts/mvc/upload/upload-view.js
--- a/client/galaxy/scripts/mvc/upload/upload-view.js
+++ b/client/galaxy/scripts/mvc/upload/upload-view.js
@@ -672,12 +672,8 @@
// load html template
_template: function(id, idInfo) {
- return '<div id="upload-header" class="upload-header">' +
- '<span class="header-title">Type (default):</span>' +
- '<span id="header-extension"/>' +
- '<span id="header-extension-info" class="upload-icon-button fa fa-search"/> ' +
- '<span class="header-title">Genome (default):</span>' +
- '<span id="header-genome"/>' +
+ return '<div class="upload-top">' +
+ '<h6 id="' + idInfo + '" class="upload-info"></h6>' +
'</div>' +
'<div id="' + id + '" class="upload-box">' +
'<table id="upload-table" class="table table-striped" style="display: none;">' +
@@ -695,9 +691,13 @@
'<tbody></tbody>' +
'</table>' +
'</div>' +
- '<div class="upload-footer">' +
- '<h6 id="' + idInfo + '" class="upload-info"></h6>' +
- '</div>' ;
+ '<div id="upload-header" class="upload-header">' +
+ '<span class="header-title">Type (default):</span>' +
+ '<span id="header-extension"/>' +
+ '<span id="header-extension-info" class="upload-icon-button fa fa-search"/> ' +
+ '<span class="header-title">Genome (default):</span>' +
+ '<span id="header-genome"/>' +
+ '</div>';
}
});
diff -r ab754acceaf9c786c7826dbd9d8316a384acdeb9 -r c80c4227f2250a3b891d08b2c78d654dfd650691 static/scripts/mvc/upload/upload-view.js
--- a/static/scripts/mvc/upload/upload-view.js
+++ b/static/scripts/mvc/upload/upload-view.js
@@ -672,12 +672,8 @@
// load html template
_template: function(id, idInfo) {
- return '<div id="upload-header" class="upload-header">' +
- '<span class="header-title">Type (default):</span>' +
- '<span id="header-extension"/>' +
- '<span id="header-extension-info" class="upload-icon-button fa fa-search"/> ' +
- '<span class="header-title">Genome (default):</span>' +
- '<span id="header-genome"/>' +
+ return '<div class="upload-top">' +
+ '<h6 id="' + idInfo + '" class="upload-info"></h6>' +
'</div>' +
'<div id="' + id + '" class="upload-box">' +
'<table id="upload-table" class="table table-striped" style="display: none;">' +
@@ -695,9 +691,13 @@
'<tbody></tbody>' +
'</table>' +
'</div>' +
- '<div class="upload-footer">' +
- '<h6 id="' + idInfo + '" class="upload-info"></h6>' +
- '</div>' ;
+ '<div id="upload-header" class="upload-header">' +
+ '<span class="header-title">Type (default):</span>' +
+ '<span id="header-extension"/>' +
+ '<span id="header-extension-info" class="upload-icon-button fa fa-search"/> ' +
+ '<span class="header-title">Genome (default):</span>' +
+ '<span id="header-genome"/>' +
+ '</div>';
}
});
diff -r ab754acceaf9c786c7826dbd9d8316a384acdeb9 -r c80c4227f2250a3b891d08b2c78d654dfd650691 static/scripts/packed/mvc/upload/upload-view.js
--- a/static/scripts/packed/mvc/upload/upload-view.js
+++ b/static/scripts/packed/mvc/upload/upload-view.js
@@ -1,1 +1,1 @@
-define(["utils/utils","mvc/upload/upload-button","mvc/upload/upload-model","mvc/upload/upload-row","mvc/upload/upload-ftp","mvc/ui/ui-popover","mvc/ui/ui-modal","mvc/ui/ui-select","utils/uploadbox"],function(f,e,c,b,g,d,a,h){return Backbone.View.extend({options:{nginx_upload_path:""},modal:null,ui_button:null,uploadbox:null,current_history:null,select_extension:null,select_genome:null,upload_size:0,list_extensions:[],list_genomes:[],auto:{id:"auto",text:"Auto-detect",description:"This system will try to detect the file type automatically. If your file is not detected properly as one of the known formats, it most likely means that it has some format problems (e.g., different number of columns on different rows). You can still coerce the system to set your data to the format you think it should be. You can also upload compressed files, which will automatically be decompressed."},collection:new c.Collection(),ftp:null,counter:{announce:0,success:0,error:0,running:0,reset:function(){this.announce=this.success=this.error=this.running=0}},initialize:function(j){var i=this;if(j){this.options=_.defaults(j,this.options)}this.ui_button=new e.Model({icon:"fa-upload",tooltip:"Download from URL or upload files from disk",label:"Load Data",onclick:function(k){if(k){k.preventDefault();i.show()}},onunload:function(){if(i.counter.running>0){return"Several uploads are still processing."}}});$(".with-upload-button").append((new e.View(this.ui_button)).$el);var i=this;f.get({url:galaxy_config.root+"api/datatypes?extension_only=False",success:function(k){for(key in k){i.list_extensions.push({id:k[key].extension,text:k[key].extension,description:k[key].description,description_url:k[key].description_url})}i.list_extensions.sort(function(m,l){return m.id>l.id?1:m.id<l.id?-1:0});if(!i.options.datatypes_disable_auto){i.list_extensions.unshift(i.auto)}}});f.get({url:galaxy_config.root+"api/genomes",success:function(k){for(key in k){i.list_genomes.push({id:k[key][1],text:k[key][0]})}i.list_genomes.sort(function(m,l){return m.id>l.id?1:m.id<l.id?-1:0})}});this.collection.on("remove",function(k){i._eventRemove(k)})},show:function(){var i=this;if(!Galaxy.currHistoryPanel||!Galaxy.currHistoryPanel.model){window.setTimeout(function(){i.show()},500);return}if(!this.modal){var i=this;this.modal=new a.View({title:"Download data directly from web or upload files from your disk",body:this._template("upload-box","upload-info"),buttons:{"Choose local file":function(){i.uploadbox.select()},"Choose FTP file":function(){i._eventFtp()},"Paste/Fetch data":function(){i._eventCreate()},Start:function(){i._eventStart()},Pause:function(){i._eventStop()},Reset:function(){i._eventReset()},Close:function(){i.modal.hide()},},height:"400",width:"900",closing_events:true});this.setElement("#upload-box");var i=this;this.uploadbox=this.$el.uploadbox({announce:function(k,l,m){i._eventAnnounce(k,l,m)},initialize:function(k,l,m){return i._eventInitialize(k,l,m)},progress:function(k,l,m){i._eventProgress(k,l,m)},success:function(k,l,m){i._eventSuccess(k,l,m)},error:function(k,l,m){i._eventError(k,l,m)},complete:function(){i._eventComplete()}});var j=this.modal.getButton("Choose FTP file");this.ftp=new d.View({title:"FTP files",container:j});this.select_extension=new h.View({css:"header-selection",data:i.list_extensions,container:i.$el.parent().find("#header-extension"),value:i.list_extensions[0]});i.$el.parent().find("#header-extension-info").on("click",function(k){i.showExtensionInfo({$el:$(k.target),title:i.select_extension.text(),extension:i.select_extension.value()})}).on("mousedown",function(k){k.preventDefault()});this.select_genome=new h.View({css:"header-selection",data:i.list_genomes,container:i.$el.parent().find("#header-genome"),value:i.list_genomes[0]})}this.modal.show();this._updateUser();this._updateScreen()},showExtensionInfo:function(j){var i=this;var k=j.$el;var n=j.extension;var m=j.title;var l=_.findWhere(i.list_extensions,{id:n});this.extension_popup&&this.extension_popup.remove();this.extension_popup=new d.View({placement:"bottom",container:k,destroy:true});this.extension_popup.title(m);this.extension_popup.empty();this.extension_popup.append(this._templateDescription(l));this.extension_popup.show()},_eventRemove:function(j){var i=j.get("status");if(i=="success"){this.counter.success--}else{if(i=="error"){this.counter.error--}else{this.counter.announce--}}this._updateScreen();this.uploadbox.remove(j.id)},_eventAnnounce:function(i,j,l){this.counter.announce++;this._updateScreen();var k=new b(this,{id:i,file_name:j.name,file_size:j.size,file_mode:j.mode,file_path:j.path});this.collection.add(k.model);$(this.el).find("tbody:first").append(k.$el);k.render()},_eventInitialize:function(n,k,t){var l=this.collection.get(n);l.set("status","running");var p=l.get("file_name");var o=l.get("file_path");var i=l.get("file_mode");var q=l.get("extension");var s=l.get("genome");var r=l.get("url_paste");var m=l.get("space_to_tabs");var j=l.get("to_posix_lines");if(!r&&!(k.size>0)){return null}this.uploadbox.configure({url:this.options.nginx_upload_path});if(i=="local"){this.uploadbox.configure({paramname:"files_0|file_data"})}else{this.uploadbox.configure({paramname:null})}tool_input={};if(i=="new"){tool_input["files_0|url_paste"]=r}if(i=="ftp"){tool_input["files_0|ftp_files"]=o}tool_input.dbkey=s;tool_input.file_type=q;tool_input["files_0|type"]="upload_dataset";tool_input["files_0|space_to_tab"]=m&&"Yes"||null;tool_input["files_0|to_posix_lines"]=j&&"Yes"||null;data={};data.history_id=this.current_history;data.tool_id="upload1";data.inputs=JSON.stringify(tool_input);return data},_eventProgress:function(j,k,i){var l=this.collection.get(j);l.set("percentage",i);this.ui_button.set("percentage",this._upload_percentage(i,k.size))},_eventSuccess:function(j,k,m){var l=this.collection.get(j);l.set("percentage",100);l.set("status","success");var i=l.get("file_size");this.ui_button.set("percentage",this._upload_percentage(100,i));this.upload_completed+=i*100;this.counter.announce--;this.counter.success++;this._updateScreen();Galaxy.currHistoryPanel.refreshContents()},_eventError:function(i,j,l){var k=this.collection.get(i);k.set("percentage",100);k.set("status","error");k.set("info",l);this.ui_button.set("percentage",this._upload_percentage(100,j.size));this.ui_button.set("status","danger");this.upload_completed+=j.size*100;this.counter.announce--;this.counter.error++;this._updateScreen()},_eventComplete:function(){this.collection.each(function(i){if(i.get("status")=="queued"){i.set("status","init")}});this.counter.running=0;this._updateScreen()},_eventFtp:function(){if(!this.ftp.visible){this.ftp.empty();this.ftp.append((new g(this)).$el);this.ftp.show()}else{this.ftp.hide()}},_eventCreate:function(){this.uploadbox.add([{name:"New File",size:0,mode:"new"}])},_eventStart:function(){if(this.counter.announce==0||this.counter.running>0){return}var i=this;this.upload_size=0;this.upload_completed=0;this.collection.each(function(j){if(j.get("status")=="init"){j.set("status","queued");i.upload_size+=j.get("file_size")}});this.ui_button.set("percentage",0);this.ui_button.set("status","success");this.counter.running=this.counter.announce;this._updateScreen();this.uploadbox.start()},_eventStop:function(){if(this.counter.running==0){return}this.ui_button.set("status","info");this.uploadbox.stop();$("#upload-info").html("Queue will pause after completing the current file...")},_eventReset:function(){if(this.counter.running==0){this.collection.reset();this.counter.reset();this._updateScreen();this.uploadbox.reset();this.select_extension.value(this.list_extensions[0]);this.select_genome.value(this.list_genomes[0]);this.ui_button.set("percentage",0)}},_updateUser:function(){this.current_user=Galaxy.currUser.get("id");this.current_history=null;if(this.current_user){this.current_history=Galaxy.currHistoryPanel.model.get("id")}},_updateScreen:function(){if(this.counter.announce==0){if(this.uploadbox.compatible()){message="You can Drag & Drop files into this box."}else{message="Unfortunately, your browser does not support multiple file uploads or drag&drop.<br>Some supported browsers are: Firefox 4+, Chrome 7+, IE 10+, Opera 12+ or Safari 6+."}}else{if(this.counter.running==0){message="You added "+this.counter.announce+" file(s) to the queue. Add more files or click 'Start' to proceed."}else{message="Please wait..."+this.counter.announce+" out of "+this.counter.running+" remaining."}}$("#upload-info").html(message);if(this.counter.running==0&&this.counter.announce+this.counter.success+this.counter.error>0){this.modal.enableButton("Reset")}else{this.modal.disableButton("Reset")}if(this.counter.running==0&&this.counter.announce>0){this.modal.enableButton("Start")}else{this.modal.disableButton("Start")}if(this.counter.running>0){this.modal.enableButton("Pause")}else{this.modal.disableButton("Pause")}if(this.counter.running==0){this.modal.enableButton("Choose local file");this.modal.enableButton("Choose FTP file");this.modal.enableButton("Paste/Fetch data")}else{this.modal.disableButton("Choose local file");this.modal.disableButton("Choose FTP file");this.modal.disableButton("Paste/Fetch data")}if(this.current_user&&this.options.ftp_upload_dir&&this.options.ftp_upload_site){this.modal.showButton("Choose FTP file")}else{this.modal.hideButton("Choose FTP file")}if(this.counter.announce+this.counter.success+this.counter.error>0){$(this.el).find("#upload-table").show()}else{$(this.el).find("#upload-table").hide()}},_upload_percentage:function(i,j){return(this.upload_completed+(i*j))/this.upload_size},_templateDescription:function(j){if(j.description){var i=j.description;if(j.description_url){i+=' (<a href="'+j.description_url+'" target="_blank">read more</a>)'}return i}else{return"There is no description available for this file extension."}},_template:function(j,i){return'<div id="upload-header" class="upload-header"><span class="header-title">Type (default):</span><span id="header-extension"/><span id="header-extension-info" class="upload-icon-button fa fa-search"/><span class="header-title">Genome (default):</span><span id="header-genome"/></div><div id="'+j+'" class="upload-box"><table id="upload-table" class="table table-striped" style="display: none;"><thead><tr><th>Name</th><th>Size</th><th>Type</th><th>Genome</th><th>Settings</th><th>Status</th><th></th></tr></thead><tbody></tbody></table></div><div class="upload-footer"><h6 id="'+i+'" class="upload-info"></h6></div>'}})});
\ No newline at end of file
+define(["utils/utils","mvc/upload/upload-button","mvc/upload/upload-model","mvc/upload/upload-row","mvc/upload/upload-ftp","mvc/ui/ui-popover","mvc/ui/ui-modal","mvc/ui/ui-select","utils/uploadbox"],function(f,e,c,b,g,d,a,h){return Backbone.View.extend({options:{nginx_upload_path:""},modal:null,ui_button:null,uploadbox:null,current_history:null,select_extension:null,select_genome:null,upload_size:0,list_extensions:[],list_genomes:[],auto:{id:"auto",text:"Auto-detect",description:"This system will try to detect the file type automatically. If your file is not detected properly as one of the known formats, it most likely means that it has some format problems (e.g., different number of columns on different rows). You can still coerce the system to set your data to the format you think it should be. You can also upload compressed files, which will automatically be decompressed."},collection:new c.Collection(),ftp:null,counter:{announce:0,success:0,error:0,running:0,reset:function(){this.announce=this.success=this.error=this.running=0}},initialize:function(j){var i=this;if(j){this.options=_.defaults(j,this.options)}this.ui_button=new e.Model({icon:"fa-upload",tooltip:"Download from URL or upload files from disk",label:"Load Data",onclick:function(k){if(k){k.preventDefault();i.show()}},onunload:function(){if(i.counter.running>0){return"Several uploads are still processing."}}});$(".with-upload-button").append((new e.View(this.ui_button)).$el);var i=this;f.get({url:galaxy_config.root+"api/datatypes?extension_only=False",success:function(k){for(key in k){i.list_extensions.push({id:k[key].extension,text:k[key].extension,description:k[key].description,description_url:k[key].description_url})}i.list_extensions.sort(function(m,l){return m.id>l.id?1:m.id<l.id?-1:0});if(!i.options.datatypes_disable_auto){i.list_extensions.unshift(i.auto)}}});f.get({url:galaxy_config.root+"api/genomes",success:function(k){for(key in k){i.list_genomes.push({id:k[key][1],text:k[key][0]})}i.list_genomes.sort(function(m,l){return m.id>l.id?1:m.id<l.id?-1:0})}});this.collection.on("remove",function(k){i._eventRemove(k)})},show:function(){var i=this;if(!Galaxy.currHistoryPanel||!Galaxy.currHistoryPanel.model){window.setTimeout(function(){i.show()},500);return}if(!this.modal){var i=this;this.modal=new a.View({title:"Download data directly from web or upload files from your disk",body:this._template("upload-box","upload-info"),buttons:{"Choose local file":function(){i.uploadbox.select()},"Choose FTP file":function(){i._eventFtp()},"Paste/Fetch data":function(){i._eventCreate()},Start:function(){i._eventStart()},Pause:function(){i._eventStop()},Reset:function(){i._eventReset()},Close:function(){i.modal.hide()},},height:"400",width:"900",closing_events:true});this.setElement("#upload-box");var i=this;this.uploadbox=this.$el.uploadbox({announce:function(k,l,m){i._eventAnnounce(k,l,m)},initialize:function(k,l,m){return i._eventInitialize(k,l,m)},progress:function(k,l,m){i._eventProgress(k,l,m)},success:function(k,l,m){i._eventSuccess(k,l,m)},error:function(k,l,m){i._eventError(k,l,m)},complete:function(){i._eventComplete()}});var j=this.modal.getButton("Choose FTP file");this.ftp=new d.View({title:"FTP files",container:j});this.select_extension=new h.View({css:"header-selection",data:i.list_extensions,container:i.$el.parent().find("#header-extension"),value:i.list_extensions[0]});i.$el.parent().find("#header-extension-info").on("click",function(k){i.showExtensionInfo({$el:$(k.target),title:i.select_extension.text(),extension:i.select_extension.value()})}).on("mousedown",function(k){k.preventDefault()});this.select_genome=new h.View({css:"header-selection",data:i.list_genomes,container:i.$el.parent().find("#header-genome"),value:i.list_genomes[0]})}this.modal.show();this._updateUser();this._updateScreen()},showExtensionInfo:function(j){var i=this;var k=j.$el;var n=j.extension;var m=j.title;var l=_.findWhere(i.list_extensions,{id:n});this.extension_popup&&this.extension_popup.remove();this.extension_popup=new d.View({placement:"bottom",container:k,destroy:true});this.extension_popup.title(m);this.extension_popup.empty();this.extension_popup.append(this._templateDescription(l));this.extension_popup.show()},_eventRemove:function(j){var i=j.get("status");if(i=="success"){this.counter.success--}else{if(i=="error"){this.counter.error--}else{this.counter.announce--}}this._updateScreen();this.uploadbox.remove(j.id)},_eventAnnounce:function(i,j,l){this.counter.announce++;this._updateScreen();var k=new b(this,{id:i,file_name:j.name,file_size:j.size,file_mode:j.mode,file_path:j.path});this.collection.add(k.model);$(this.el).find("tbody:first").append(k.$el);k.render()},_eventInitialize:function(n,k,t){var l=this.collection.get(n);l.set("status","running");var p=l.get("file_name");var o=l.get("file_path");var i=l.get("file_mode");var q=l.get("extension");var s=l.get("genome");var r=l.get("url_paste");var m=l.get("space_to_tabs");var j=l.get("to_posix_lines");if(!r&&!(k.size>0)){return null}this.uploadbox.configure({url:this.options.nginx_upload_path});if(i=="local"){this.uploadbox.configure({paramname:"files_0|file_data"})}else{this.uploadbox.configure({paramname:null})}tool_input={};if(i=="new"){tool_input["files_0|url_paste"]=r}if(i=="ftp"){tool_input["files_0|ftp_files"]=o}tool_input.dbkey=s;tool_input.file_type=q;tool_input["files_0|type"]="upload_dataset";tool_input["files_0|space_to_tab"]=m&&"Yes"||null;tool_input["files_0|to_posix_lines"]=j&&"Yes"||null;data={};data.history_id=this.current_history;data.tool_id="upload1";data.inputs=JSON.stringify(tool_input);return data},_eventProgress:function(j,k,i){var l=this.collection.get(j);l.set("percentage",i);this.ui_button.set("percentage",this._upload_percentage(i,k.size))},_eventSuccess:function(j,k,m){var l=this.collection.get(j);l.set("percentage",100);l.set("status","success");var i=l.get("file_size");this.ui_button.set("percentage",this._upload_percentage(100,i));this.upload_completed+=i*100;this.counter.announce--;this.counter.success++;this._updateScreen();Galaxy.currHistoryPanel.refreshContents()},_eventError:function(i,j,l){var k=this.collection.get(i);k.set("percentage",100);k.set("status","error");k.set("info",l);this.ui_button.set("percentage",this._upload_percentage(100,j.size));this.ui_button.set("status","danger");this.upload_completed+=j.size*100;this.counter.announce--;this.counter.error++;this._updateScreen()},_eventComplete:function(){this.collection.each(function(i){if(i.get("status")=="queued"){i.set("status","init")}});this.counter.running=0;this._updateScreen()},_eventFtp:function(){if(!this.ftp.visible){this.ftp.empty();this.ftp.append((new g(this)).$el);this.ftp.show()}else{this.ftp.hide()}},_eventCreate:function(){this.uploadbox.add([{name:"New File",size:0,mode:"new"}])},_eventStart:function(){if(this.counter.announce==0||this.counter.running>0){return}var i=this;this.upload_size=0;this.upload_completed=0;this.collection.each(function(j){if(j.get("status")=="init"){j.set("status","queued");i.upload_size+=j.get("file_size")}});this.ui_button.set("percentage",0);this.ui_button.set("status","success");this.counter.running=this.counter.announce;this._updateScreen();this.uploadbox.start()},_eventStop:function(){if(this.counter.running==0){return}this.ui_button.set("status","info");this.uploadbox.stop();$("#upload-info").html("Queue will pause after completing the current file...")},_eventReset:function(){if(this.counter.running==0){this.collection.reset();this.counter.reset();this._updateScreen();this.uploadbox.reset();this.select_extension.value(this.list_extensions[0]);this.select_genome.value(this.list_genomes[0]);this.ui_button.set("percentage",0)}},_updateUser:function(){this.current_user=Galaxy.currUser.get("id");this.current_history=null;if(this.current_user){this.current_history=Galaxy.currHistoryPanel.model.get("id")}},_updateScreen:function(){if(this.counter.announce==0){if(this.uploadbox.compatible()){message="You can Drag & Drop files into this box."}else{message="Unfortunately, your browser does not support multiple file uploads or drag&drop.<br>Some supported browsers are: Firefox 4+, Chrome 7+, IE 10+, Opera 12+ or Safari 6+."}}else{if(this.counter.running==0){message="You added "+this.counter.announce+" file(s) to the queue. Add more files or click 'Start' to proceed."}else{message="Please wait..."+this.counter.announce+" out of "+this.counter.running+" remaining."}}$("#upload-info").html(message);if(this.counter.running==0&&this.counter.announce+this.counter.success+this.counter.error>0){this.modal.enableButton("Reset")}else{this.modal.disableButton("Reset")}if(this.counter.running==0&&this.counter.announce>0){this.modal.enableButton("Start")}else{this.modal.disableButton("Start")}if(this.counter.running>0){this.modal.enableButton("Pause")}else{this.modal.disableButton("Pause")}if(this.counter.running==0){this.modal.enableButton("Choose local file");this.modal.enableButton("Choose FTP file");this.modal.enableButton("Paste/Fetch data")}else{this.modal.disableButton("Choose local file");this.modal.disableButton("Choose FTP file");this.modal.disableButton("Paste/Fetch data")}if(this.current_user&&this.options.ftp_upload_dir&&this.options.ftp_upload_site){this.modal.showButton("Choose FTP file")}else{this.modal.hideButton("Choose FTP file")}if(this.counter.announce+this.counter.success+this.counter.error>0){$(this.el).find("#upload-table").show()}else{$(this.el).find("#upload-table").hide()}},_upload_percentage:function(i,j){return(this.upload_completed+(i*j))/this.upload_size},_templateDescription:function(j){if(j.description){var i=j.description;if(j.description_url){i+=' (<a href="'+j.description_url+'" target="_blank">read more</a>)'}return i}else{return"There is no description available for this file extension."}},_template:function(j,i){return'<div class="upload-top"><h6 id="'+i+'" class="upload-info"></h6></div><div id="'+j+'" class="upload-box"><table id="upload-table" class="table table-striped" style="display: none;"><thead><tr><th>Name</th><th>Size</th><th>Type</th><th>Genome</th><th>Settings</th><th>Status</th><th></th></tr></thead><tbody></tbody></table></div><div id="upload-header" class="upload-header"><span class="header-title">Type (default):</span><span id="header-extension"/><span id="header-extension-info" class="upload-icon-button fa fa-search"/><span class="header-title">Genome (default):</span><span id="header-genome"/></div>'}})});
\ No newline at end of file
diff -r ab754acceaf9c786c7826dbd9d8316a384acdeb9 -r c80c4227f2250a3b891d08b2c78d654dfd650691 static/style/blue/base.css
--- a/static/style/blue/base.css
+++ b/static/style/blue/base.css
@@ -1389,10 +1389,10 @@
.upload-ftp .upload-ftp-help{margin-bottom:10px}
.upload-ftp .upload-ftp-warning{text-align:center;margin-top:20px}
.upload-settings .upload-settings-cover{position:absolute;width:100%;height:100%;top:0px;left:0px;background:#fff;opacity:0.4;cursor:no-drop}
-.upload-header{height:5%;text-align:left;max-height:20px;line-height:18px;margin-bottom:15px}.upload-header .header-title{font-weight:bold;padding-left:60px;padding-right:20px}
+.upload-header{height:5%;text-align:left;max-height:20px;line-height:18px;margin-top:10px}.upload-header .header-title{font-weight:bold;padding-left:60px;padding-right:20px}
.upload-header .header-selection{width:200px;min-width:200px;font-size:11px;padding-right:10px}
.upload-header .select2-choice{max-height:20px;line-height:18px;background:transparent;text-align:center;font-weight:normal}.upload-header .select2-choice .select2-arrow b{background-position:0 -3px}
-.upload-footer{height:5%;text-align:center}.upload-footer .upload-info{font-weight:normal;text-align:center}
+.upload-top{height:5%;text-align:center}.upload-top .upload-info{margin-top:0px;font-weight:normal;text-align:center}
.no-highlight,.ui-button-icon,.ui-portlet,.ui-portlet-slim,.ui-portlet-repeat,.ui-portlet-section{-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;-ms-user-select:none;}
.ui-error{-moz-border-radius:3px;border-radius:3px;background:#f9c7c5;padding:5px}
.ui-table-form-error{display:none}.ui-table-form-error .ui-table-form-error-text{padding-left:5px}
diff -r ab754acceaf9c786c7826dbd9d8316a384acdeb9 -r c80c4227f2250a3b891d08b2c78d654dfd650691 static/style/src/less/upload.less
--- a/static/style/src/less/upload.less
+++ b/static/style/src/less/upload.less
@@ -219,7 +219,7 @@
text-align:left;
max-height:20px;
line-height:18px;
- margin-bottom: 15px;
+ margin-top: 10px;
.header-title {
font-weight: bold;
padding-left: 60px;
@@ -243,10 +243,11 @@
}
}
-.upload-footer {
+.upload-top {
height:5%;
text-align:center;
.upload-info {
+ margin-top: 0px;
font-weight: normal;
text-align: center;
}
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: guerler: Parameters: Multiselect back to optional by default
by commits-noreply@bitbucket.org 29 Jan '15
by commits-noreply@bitbucket.org 29 Jan '15
29 Jan '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/ab754acceaf9/
Changeset: ab754acceaf9
User: guerler
Date: 2015-01-29 05:57:59+00:00
Summary: Parameters: Multiselect back to optional by default
Affected #: 1 file
diff -r c5415e67cae27304e628103d249264753ad0d7cc -r ab754acceaf9c786c7826dbd9d8316a384acdeb9 lib/galaxy/tools/parameters/basic.py
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -772,6 +772,8 @@
input_source = ensure_input_source( input_source )
ToolParameter.__init__( self, tool, input_source )
self.multiple = input_source.get_bool( 'multiple', False )
+ # Multiple selects are optional by default, single selection is the inverse.
+ self.optional = input_source.parse_optional( self.multiple )
self.display = input_source.get( 'display', None )
self.separator = input_source.get( 'separator', ',' )
self.legal_values = set()
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: guerler: Workflow: Add tool form switch to config, fix late validation check
by commits-noreply@bitbucket.org 29 Jan '15
by commits-noreply@bitbucket.org 29 Jan '15
29 Jan '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/c5415e67cae2/
Changeset: c5415e67cae2
User: guerler
Date: 2015-01-29 05:38:02+00:00
Summary: Workflow: Add tool form switch to config, fix late validation check
Affected #: 4 files
diff -r 2de1b7c819a2a1083b86d0d16ac2c6cd182578cf -r c5415e67cae27304e628103d249264753ad0d7cc config/galaxy.ini.sample
--- a/config/galaxy.ini.sample
+++ b/config/galaxy.ini.sample
@@ -757,6 +757,9 @@
# Use new tool form
#toolform_upgrade = True
+# Use new tool form in workflow editor
+#workflow_toolform_upgrade = False
+
# Enable Galaxy to communicate directly with a sequencer
#enable_sequencer_communication = False
diff -r 2de1b7c819a2a1083b86d0d16ac2c6cd182578cf -r c5415e67cae27304e628103d249264753ad0d7cc lib/galaxy/tools/parameters/basic.py
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -945,7 +945,7 @@
# Old style dynamic options, no dependency information so there isn't
# a lot we can do: if we're dealing with workflows, have to assume
# late validation no matter what.
- if self.dynamic_options is not None and ( trans is None or trans.workflow_building_mode ):
+ if (self.dynamic_options is not None or self.is_dynamic is not None) and ( trans is None or trans.workflow_building_mode ):
return True
# If we got this far, we can actually look at the dependencies
# to see if their values will not be available until runtime.
diff -r 2de1b7c819a2a1083b86d0d16ac2c6cd182578cf -r c5415e67cae27304e628103d249264753ad0d7cc templates/webapps/galaxy/workflow/editor.mako
--- a/templates/webapps/galaxy/workflow/editor.mako
+++ b/templates/webapps/galaxy/workflow/editor.mako
@@ -33,7 +33,9 @@
<script type='text/javascript'>
// Switch for new tool form
- __NEWTOOLFORM__ = false;
+ %if util.string_as_bool(trans.app.config.get('workflow_toolform_upgrade', False)):
+ __NEWTOOLFORM__ = true;
+ %endif
// Globals
workflow = null;
diff -r 2de1b7c819a2a1083b86d0d16ac2c6cd182578cf -r c5415e67cae27304e628103d249264753ad0d7cc templates/webapps/galaxy/workflow/editor_tool_form.mako
--- a/templates/webapps/galaxy/workflow/editor_tool_form.mako
+++ b/templates/webapps/galaxy/workflow/editor_tool_form.mako
@@ -1,5 +1,5 @@
## TEMPORARY SWITCH FOR THE NEW TOOL FORM
-%if False:
+%if util.string_as_bool(trans.app.config.get('workflow_toolform_upgrade', False)):
${h.js("libs/bibtex", "libs/jquery/jquery-ui")}
${h.css('jquery-ui/smoothness/jquery-ui')}
<%
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: guerler: ToolForm: Activate by default
by commits-noreply@bitbucket.org 29 Jan '15
by commits-noreply@bitbucket.org 29 Jan '15
29 Jan '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/2de1b7c819a2/
Changeset: 2de1b7c819a2
User: guerler
Date: 2015-01-29 04:59:43+00:00
Summary: ToolForm: Activate by default
Affected #: 2 files
diff -r 052c03f52326a5755013a6b5e9d7ad746d4dd940 -r 2de1b7c819a2a1083b86d0d16ac2c6cd182578cf config/galaxy.ini.sample
--- a/config/galaxy.ini.sample
+++ b/config/galaxy.ini.sample
@@ -755,7 +755,7 @@
# -- Beta features
# Use new tool form
-toolform_upgrade = True
+#toolform_upgrade = True
# Enable Galaxy to communicate directly with a sequencer
#enable_sequencer_communication = False
diff -r 052c03f52326a5755013a6b5e9d7ad746d4dd940 -r 2de1b7c819a2a1083b86d0d16ac2c6cd182578cf templates/webapps/galaxy/tool_form.mako
--- a/templates/webapps/galaxy/tool_form.mako
+++ b/templates/webapps/galaxy/tool_form.mako
@@ -4,7 +4,7 @@
${h.css('base', 'jquery-ui/smoothness/jquery-ui')}
## skip new tool form code if disabled
-##%if util.string_as_bool(trans.app.config.get('toolform_upgrade', False)):
+%if util.string_as_bool(trans.app.config.get('toolform_upgrade', True)):
<%
## TEMPORARY: create tool dictionary in mako while both tool forms are in use.
## This avoids making two separate requests since the classic form requires the mako anyway.
@@ -26,9 +26,9 @@
});
</script><div id="tool-form-classic" style="display: none;">
-##%else:
-## <div id="tool-form-classic">
-##%endif
+%else:
+ <div id="tool-form-classic">
+%endif
<%namespace file="/message.mako" import="render_msg" /><%namespace file="/base_panels.mako" import="overlay" />
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: guerler: Workflow: Insert conditional tool model creation
by commits-noreply@bitbucket.org 29 Jan '15
by commits-noreply@bitbucket.org 29 Jan '15
29 Jan '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/052c03f52326/
Changeset: 052c03f52326
User: guerler
Date: 2015-01-29 04:53:19+00:00
Summary: Workflow: Insert conditional tool model creation
Affected #: 1 file
diff -r c99e026b4b0a1a1f7ac5bf15e92859085c5bdab7 -r 052c03f52326a5755013a6b5e9d7ad746d4dd940 lib/galaxy/webapps/galaxy/controllers/workflow.py
--- a/lib/galaxy/webapps/galaxy/controllers/workflow.py
+++ b/lib/galaxy/webapps/galaxy/controllers/workflow.py
@@ -618,12 +618,18 @@
'tool_state': tool_state
} )
+ # create tool model and default tool state (if missing)
+ tool_model = None
+ if type == 'tool' and not tool_state:
+ tool_model = module.tool.to_json(trans, **incoming)
+ module.state.inputs = copy.deepcopy(tool_model['state_inputs'])
+
# update module state
module.update_state( incoming )
if type == 'tool':
return {
- 'tool_model': None,
+ 'tool_model': tool_model,
'tool_state': module.get_state(),
'data_inputs': module.get_data_inputs(),
'data_outputs': module.get_data_outputs(),
@@ -653,12 +659,15 @@
"""
trans.workflow_building_mode = True
module = module_factory.new( trans, type, **kwargs )
+ tool_model = None
+ if type == 'tool':
+ tool_model = module.tool.to_json(trans)
return {
'type': module.type,
'name': module.get_name(),
'tool_id': module.get_tool_id(),
'tool_state': module.get_state(),
- 'tool_model': None,
+ 'tool_model': tool_model,
'tooltip': module.get_tooltip( static_path=url_for( '/static' ) ),
'data_inputs': module.get_data_inputs(),
'data_outputs': module.get_data_outputs(),
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
[galaxyproject/usegalaxy-playbook] 252693: Disable options that were inexplicably preventing ...
by GitHub 29 Jan '15
by GitHub 29 Jan '15
29 Jan '15
Branch: refs/heads/master
Home: https://github.com/galaxyproject/usegalaxy-playbook
Commit: 25269362aad6d8dc13dd7e16c45d74f5747ae05e
https://github.com/galaxyproject/usegalaxy-playbook/commit/25269362aad6d8dc…
Author: Nate Coraor <nate(a)bx.psu.edu>
Date: 2015-01-28 (Wed, 28 Jan 2015)
Changed paths:
M production/group_vars/galaxyservers.yml
Log Message:
-----------
Disable options that were inexplicably preventing uWSGI from starting.
1
0
29 Jan '15
Branch: refs/heads/master
Home: https://github.com/galaxyproject/usegalaxy-playbook
Commit: 5058b8c1bbceebd4bbec39d1bd8968adb6b69ed8
https://github.com/galaxyproject/usegalaxy-playbook/commit/5058b8c1bbceebd4…
Author: Nate Coraor <nate(a)bx.psu.edu>
Date: 2015-01-28 (Wed, 28 Jan 2015)
Changed paths:
M production/group_vars/galaxyservers.yml
M production/host_vars/galaxy-web-01.tacc.utexas.edu.yml
M production/inventory
M production/secret_vars/galaxyservers.yml
M templates/supervisor/galaxy_group.conf.j2
Log Message:
-----------
supervisor fixes for Main
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/e3f50d8803e6/
Changeset: e3f50d8803e6
Branch: samtools1_bam_index
User: natefoo
Date: 2015-01-28 21:29:48+00:00
Summary: Close samtools1_bam_index branch.
Affected #: 0 files
https://bitbucket.org/galaxy/galaxy-central/commits/c99e026b4b0a/
Changeset: c99e026b4b0a
User: natefoo
Date: 2015-01-28 21:29:58+00:00
Summary: merge.
Affected #: 0 files
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: natefoo: Remove GeneTrack remnants.
by commits-noreply@bitbucket.org 29 Jan '15
by commits-noreply@bitbucket.org 29 Jan '15
29 Jan '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/0d832a69da40/
Changeset: 0d832a69da40
User: natefoo
Date: 2015-01-28 21:29:21+00:00
Summary: Remove GeneTrack remnants.
Affected #: 4 files
diff -r 1fa9a9409fc92cea7c1775e57c462a56d01c3185 -r 0d832a69da40612bbbcded0d71230b53a6a7c1e2 eggs.ini
--- a/eggs.ini
+++ b/eggs.ini
@@ -40,7 +40,6 @@
drmaa = 0.7.6
elementtree = 1.2.6_20050316
Fabric = 1.7.0
-GeneTrack = 2.0.0_beta_1
importlib = 1.0.3
kombu = 3.0.13
lrucache = 0.2
diff -r 1fa9a9409fc92cea7c1775e57c462a56d01c3185 -r 0d832a69da40612bbbcded0d71230b53a6a7c1e2 scripts/scramble/patches/GeneTrack/setup.py
--- a/scripts/scramble/patches/GeneTrack/setup.py
+++ /dev/null
@@ -1,15 +0,0 @@
-from os import walk
-from os.path import join
-from setuptools import setup, find_packages
-
-def walk_files( top ):
- for dir, dirs, files in walk( top ):
- yield( dir, [ join( dir, f ) for f in files ] )
-
-setup(
- name = "GeneTrack",
- version = "2.0.0-beta-1",
- packages = ['genetrack','genetrack.scripts'],
- data_files = [ f for f in walk_files('tests') ],
- zip_safe = False
-)
diff -r 1fa9a9409fc92cea7c1775e57c462a56d01c3185 -r 0d832a69da40612bbbcded0d71230b53a6a7c1e2 static/genetrack/genetrack.css
--- a/static/genetrack/genetrack.css
+++ /dev/null
@@ -1,78 +0,0 @@
-
-body {
- font-family: "Trebuchet MS", Arial, tahoma, sans-serif;
- font-size: 14px;
- line-height: 1.6em;
- margin: 0;
- padding: 0;
- border-top: 9px solid #CCD9FF;
-}
-
-/* Error message style */
-.error{
- background: #FFFF66;
-}
-
-/* Error message style */
-.message{
- background: #33FF66;
-}
-
-/* Odd data row in the table */
-.selected {
- background-color: #FFFFCC;
-}
-
-.nav_button{
- background-color:#EEEEEE;
- border:1px solid;
- color: #000000;
-}
-
-.nav_button:hover{
- background-color:#000000;
- border:1px solid;
- color: #FFFFFF;
-}
-
-.grey {
- background-color: #EFEFEF;
-}
-
-.odd {
- background-color: #ECECEC;
-}
-
-.even {
- background-color: #FFFFFF;
-}
-
-/* Text table style */
-.data_table {
- border: 1px solid #CCCCCC;
- background-color: white;
-}
-
-/* Footer is added to every page */
-#footer {
- background: #EFEFEF;
- text-align:center;
- padding:.2em;
- border-top: 1px solid #CCD9FF;
- border-bottom: 1px solid #CCD9FF;
- clear: both;
-}
-
-#footer p {
- font-size:.94em; line-height:2em; color:#cccccc; margin: 0;
- }
-
-#tag {
- font-size:.80em; margin: 4px; padding: 2px;
- }
-
-
-#footer img {
- vertical-align: middle; margin-left: 3px; padding-bottom: 2px;
-}
-
diff -r 1fa9a9409fc92cea7c1775e57c462a56d01c3185 -r 0d832a69da40612bbbcded0d71230b53a6a7c1e2 static/genetrack/genetrack.js
--- a/static/genetrack/genetrack.js
+++ /dev/null
@@ -1,79 +0,0 @@
-var cookie_name = "genetrack_ui"
-var now = new Date();
-now.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000);
-
-// this toggles between none and block
-function toggle(name){
- var elem = get(name)
- if (elem) {
- if (elem.style.display=="none"){
- elem.style.display="block"
- setCookie(cookie_name, name, now)
- } else {
- elem.style.display="none"
- setCookie(cookie_name, '', now)
- }
-
- }
-}
-
-function main(){
- //executed upon main body load
- var value = getCookie(cookie_name);
- toggle( value )
-}
-
-// this toggles between visible and hidden
-function show(name){
- var elem = get(name)
- if (elem.style.visibility=="hidden"){
- elem.style.visibility="visible";
- } else {
- elem.style.visibility="hidden";
- }
-}
-
-// utility function to get the length of on object
-function len(obj){
- return obj.length;
-}
-
-// utility function to get an element by id
-function get(name){
- return document.getElementById(name);
-}
-
-// pops up a window
-function pop_up(url) {
- day = new Date();
- id = day.getTime();
- eval("page" + id + " = window.open(url, '" + id + "', 'toolbar=0,scrollbars=1,location=0,statusbar=1,menubar=0,resizable=1,width=500,height=300');");
-}
-
-//
-// cookie management off the web
-// http://www.webreference.com/js/column8/property.html
-//
-function setCookie(name, value, expires, path, domain, secure) {
- var curCookie = name + "=" + escape(value) +
- ((expires) ? "; expires=" + expires.toGMTString() : "") +
- ((path) ? "; path=" + path : "") +
- ((domain) ? "; domain=" + domain : "") +
- ((secure) ? "; secure" : "");
- document.cookie = curCookie;
-}
-
-function getCookie(name) {
- var dc = document.cookie;
- var prefix = name + "=";
- var begin = dc.indexOf("; " + prefix);
- if (begin == -1) {
- begin = dc.indexOf(prefix);
- if (begin != 0) return null;
- } else
- begin += 2;
- var end = document.cookie.indexOf(";", begin);
- if (end == -1)
- end = dc.length;
- return unescape(dc.substring(begin + prefix.length, end));
-}
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: guerler: Parameters: Multiselect by default not optional
by commits-noreply@bitbucket.org 29 Jan '15
by commits-noreply@bitbucket.org 29 Jan '15
29 Jan '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/1fa9a9409fc9/
Changeset: 1fa9a9409fc9
User: guerler
Date: 2015-01-28 21:21:23+00:00
Summary: Parameters: Multiselect by default not optional
Affected #: 1 file
diff -r 9c767090274eb2a213854dcdb367135d782fecec -r 1fa9a9409fc92cea7c1775e57c462a56d01c3185 lib/galaxy/tools/parameters/basic.py
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -772,8 +772,6 @@
input_source = ensure_input_source( input_source )
ToolParameter.__init__( self, tool, input_source )
self.multiple = input_source.get_bool( 'multiple', False )
- # Multiple selects are optional by default, single selection is the inverse.
- self.optional = input_source.parse_optional( self.multiple )
self.display = input_source.get( 'display', None )
self.separator = input_source.get( 'separator', ',' )
self.legal_values = set()
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: natefoo: Remove memdump, which probably has not worked for many years.
by commits-noreply@bitbucket.org 29 Jan '15
by commits-noreply@bitbucket.org 29 Jan '15
29 Jan '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/9c767090274e/
Changeset: 9c767090274e
User: natefoo
Date: 2015-01-28 21:20:30+00:00
Summary: Remove memdump, which probably has not worked for many years.
Affected #: 9 files
diff -r c8b49753bf99d03462bace0dbb2f38b9c0f52915 -r 9c767090274eb2a213854dcdb367135d782fecec config/galaxy.ini.sample
--- a/config/galaxy.ini.sample
+++ b/config/galaxy.ini.sample
@@ -629,10 +629,6 @@
# lot of CPU.
#use_heartbeat = False
-# Enable the memory debugging interface (careful, negatively impacts server
-# performance).
-#use_memdump = False
-
# -- Data Libraries
# These library upload options are described in much more detail in the wiki:
diff -r c8b49753bf99d03462bace0dbb2f38b9c0f52915 -r 9c767090274eb2a213854dcdb367135d782fecec eggs.ini
--- a/eggs.ini
+++ b/eggs.ini
@@ -26,7 +26,6 @@
pysqlite = 2.5.6
python_lzo = 1.08_2.03_static
PyYAML = 3.10
-guppy = 0.1.10
SQLAlchemy = 0.7.9
; msgpack_python = 0.2.4
diff -r c8b49753bf99d03462bace0dbb2f38b9c0f52915 -r 9c767090274eb2a213854dcdb367135d782fecec lib/galaxy/app.py
--- a/lib/galaxy/app.py
+++ b/lib/galaxy/app.py
@@ -107,10 +107,8 @@
self.quota_agent = galaxy.quota.QuotaAgent( self.model )
else:
self.quota_agent = galaxy.quota.NoQuotaAgent( self.model )
- # Heartbeat and memdump for thread / heap profiling
+ # Heartbeat for thread profiling
self.heartbeat = None
- self.memdump = None
- self.memory_usage = None
# Container for OpenID authentication routines
if self.config.enable_openid:
from galaxy.web.framework import openid_manager
@@ -125,11 +123,6 @@
self.heartbeat = heartbeat.Heartbeat( fname=self.config.heartbeat_log )
self.heartbeat.daemon = True
self.heartbeat.start()
- # Enable the memdump signal catcher if configured and available
- if self.config.use_memdump:
- from galaxy.util import memdump
- if memdump.Memdump:
- self.memdump = memdump.Memdump()
# Transfer manager client
if self.config.get_bool( 'enable_beta_job_managers', False ):
from galaxy.jobs import transfer_manager
diff -r c8b49753bf99d03462bace0dbb2f38b9c0f52915 -r 9c767090274eb2a213854dcdb367135d782fecec lib/galaxy/config.py
--- a/lib/galaxy/config.py
+++ b/lib/galaxy/config.py
@@ -227,7 +227,6 @@
self.external_chown_script = kwargs.get('external_chown_script', None)
self.environment_setup_file = kwargs.get( 'environment_setup_file', None )
self.use_heartbeat = string_as_bool( kwargs.get( 'use_heartbeat', 'False' ) )
- self.use_memdump = string_as_bool( kwargs.get( 'use_memdump', 'False' ) )
self.log_actions = string_as_bool( kwargs.get( 'log_actions', 'False' ) )
self.log_events = string_as_bool( kwargs.get( 'log_events', 'False' ) )
self.sanitize_all_html = string_as_bool( kwargs.get( 'sanitize_all_html', True ) )
diff -r c8b49753bf99d03462bace0dbb2f38b9c0f52915 -r 9c767090274eb2a213854dcdb367135d782fecec lib/galaxy/eggs/__init__.py
--- a/lib/galaxy/eggs/__init__.py
+++ b/lib/galaxy/eggs/__init__.py
@@ -385,8 +385,6 @@
"DRMAA_python": lambda: "sge" in self.config.get( "app:main", "start_job_runners" ).split(","),
"drmaa": lambda: "drmaa" in self.config.get( "app:main", "start_job_runners" ).split(","),
"pbs_python": lambda: "pbs" in self.config.get( "app:main", "start_job_runners" ).split(","),
- "threadframe": lambda: self.config.get( "app:main", "use_heartbeat" ),
- "guppy": lambda: self.config.get( "app:main", "use_memdump" ),
"python_openid": lambda: self.config.get( "app:main", "enable_openid" ),
"python_daemon": lambda: sys.version_info[:2] >= ( 2, 5 ),
"pysam": lambda: check_pysam(),
diff -r c8b49753bf99d03462bace0dbb2f38b9c0f52915 -r 9c767090274eb2a213854dcdb367135d782fecec lib/galaxy/util/memdump.py
--- a/lib/galaxy/util/memdump.py
+++ /dev/null
@@ -1,50 +0,0 @@
-
-# Attempt to load guppy module, and only define Memdump class
-# if available
-
-try:
-
- import pkg_resources
- pkg_resources.require( "guppy" )
-
-except:
-
- import sys
- print >> sys.stderr, "No guppy module, Memdump not available"
- Memdump = None
-
-else:
-
- import os, sys, signal, time, guppy
-
- class Memdump( object ):
- def __init__( self, signum=signal.SIGUSR1, fname="memdump.log" ):
- self.fname = fname
- signal.signal( signum, self.dump )
- self.heapy = guppy.hpy()
- self.heap = None
- def dump( self, signum, stack ):
- file = open( self.fname, "a" )
- print >> file, "Memdump for pid %d at %s" % ( os.getpid(), time.asctime() )
- print >> file
- try:
- self.heap = self.heapy.heap()
- print >> file, "heap():"
- print >> file, self.heap
- print >> file, "\nbyrcs:"
- print >> file, self.heap.byrcs
- print >> file, "\nbyrcs[0].byid:"
- print >> file, self.heap.byrcs[0].byid
- print >> file, "\nget_rp():"
- print >> file, self.heap.get_rp()
- self.heapy.setref()
- except AssertionError:
- pass
- print >> file, "\nEnd dump\n"
- file.close()
- def setref( self ):
- self.heapy.setref()
- def get( self, update=False ):
- if update:
- self.heap = self.heapy.heap()
- return self.heap
diff -r c8b49753bf99d03462bace0dbb2f38b9c0f52915 -r 9c767090274eb2a213854dcdb367135d782fecec lib/galaxy/web/base/controllers/admin.py
--- a/lib/galaxy/web/base/controllers/admin.py
+++ b/lib/galaxy/web/base/controllers/admin.py
@@ -1026,48 +1026,6 @@
@web.expose
@web.require_admin
- def memdump( self, trans, ids = 'None', sorts = 'None', pages = 'None', new_id = None, new_sort = None, **kwd ):
- if self.app.memdump is None:
- return trans.show_error_message( "Memdump is not enabled (set <code>use_memdump = True</code> in galaxy.ini)" )
- heap = self.app.memdump.get()
- p = util.Params( kwd )
- msg = None
- if p.dump:
- heap = self.app.memdump.get( update = True )
- msg = "Heap dump complete"
- elif p.setref:
- self.app.memdump.setref()
- msg = "Reference point set (dump to see delta from this point)"
- ids = ids.split( ',' )
- sorts = sorts.split( ',' )
- if new_id is not None:
- ids.append( new_id )
- sorts.append( 'None' )
- elif new_sort is not None:
- sorts[-1] = new_sort
- breadcrumb = "<a href='%s' class='breadcrumb'>heap</a>" % web.url_for(controller='admin', action='memdump')
- # new lists so we can assemble breadcrumb links
- new_ids = []
- new_sorts = []
- for id, sort in zip( ids, sorts ):
- new_ids.append( id )
- if id != 'None':
- breadcrumb += "<a href='%s' class='breadcrumb'>[%s]</a>" % ( web.url_for(controller='admin', action='memdump', ids=','.join( new_ids ), sorts=','.join( new_sorts ) ), id )
- heap = heap[int(id)]
- new_sorts.append( sort )
- if sort != 'None':
- breadcrumb += "<a href='%s' class='breadcrumb'>.by('%s')</a>" % ( web.url_for(controller='admin', action='memdump', ids=','.join( new_ids ), sorts=','.join( new_sorts ) ), sort )
- heap = heap.by( sort )
- ids = ','.join( new_ids )
- sorts = ','.join( new_sorts )
- if p.theone:
- breadcrumb += ".theone"
- heap = heap.theone
- return trans.fill_template( '/admin/memdump.mako', heap = heap, ids = ids, sorts = sorts, breadcrumb = breadcrumb, msg = msg )
-
-
- @web.expose
- @web.require_admin
def jobs( self, trans, stop = [], stop_msg = None, cutoff = 180, job_lock = None, ajl_submit = None, **kwd ):
deleted = []
msg = None
diff -r c8b49753bf99d03462bace0dbb2f38b9c0f52915 -r 9c767090274eb2a213854dcdb367135d782fecec templates/admin/memdump.mako
--- a/templates/admin/memdump.mako
+++ /dev/null
@@ -1,76 +0,0 @@
-<%inherit file="/base.mako"/>
-<%namespace file="/message.mako" import="render_msg" />
-
-<%def name="title()">Memory Profiling</%def>
-<%
- import re
- from xml.sax.saxutils import escape, unescape
-%>
-
-<style type="text/css">
- a.breadcrumb:link,
- a.breadcrumb:visited,
- a.breadcrumb:active {
- text-decoration: none;
- }
- a.breadcrumb:hover {
- text-decoration: underline;
- }
-</style>
-
-<h2>Memory Profiling</h2>
-
-<ul class="manage-table-actions">
- <li><a class="action-button" href="${h.url_for( controller='admin', action='memdump', dump=True )}">Dump memory (warning: hangs server!)</a></li>
- <li><a class="action-button" href="${h.url_for( controller='admin', action='memdump', setref=True )}">Set reference point</a></li>
-</ul>
-
-<%def name="htmlize( heap )">
-<%
- s = escape( str( heap ) )
- new_s = ""
- id_re = re.compile('^(\s+)([0-9]+)')
- for line in s.split( '\n' ):
- try:
- id = id_re.search( line ).group( 2 )
- except:
- id = None
- new_s += re.sub( id_re, r'\1<a href="' + h.url_for( controller='admin', action='memdump', ids=ids, sorts=sorts, new_id=id ) + r'">\2</a>', line )
- if id and heap[int(id)].count == 1:
- new_s += " <a href='%s'>theone</a>\n" % h.url_for( controller='admin', action='memdump', ids=ids, sorts=sorts, new_id=id, theone=True )
- else:
- new_s += "\n"
- return new_s
-%>
-</%def>
-
-%if message:
- ${render_msg( message, status )}
-%endif
-
-%if heap is None:
- No memory dump available. Click "Dump memory" to create one.
-%else:
- <pre>
- <br/>
-You are here: ${breadcrumb}<br/>
- %if breadcrumb.endswith( 'theone' ):
- ${heap|h}
- %else:
- <nobr>
-Sort:
- <a href="${h.url_for( controller='admin', action='memdump', ids=ids, sorts=sorts, new_sort='Class')}">Class</a> |
- <a href="${h.url_for( controller='admin', action='memdump', ids=ids, sorts=sorts, new_sort='Clodo' )}">Clodo</a> |
- <a href="${h.url_for( controller='admin', action='memdump', ids=ids, sorts=sorts, new_sort='Id' )}">Id</a> |
- <a href="${h.url_for( controller='admin', action='memdump', ids=ids, sorts=sorts, new_sort='Idset' )}">Idset</a> |
- <a href="${h.url_for( controller='admin', action='memdump', ids=ids, sorts=sorts, new_sort='Module' )}">Module</a> |
- <a href="${h.url_for( controller='admin', action='memdump', ids=ids, sorts=sorts, new_sort='Unity' )}">Unity</a> |
- <a href="${h.url_for( controller='admin', action='memdump', ids=ids, sorts=sorts, new_sort='Rcs' )}">Rcs</a> |
- <a href="${h.url_for( controller='admin', action='memdump', ids=ids, sorts=sorts, new_sort='Size' )}">Size</a> |
- <a href="${h.url_for( controller='admin', action='memdump', ids=ids, sorts=sorts, new_sort='Type' )}">Type</a> |
- <a href="${h.url_for( controller='admin', action='memdump', ids=ids, sorts=sorts, new_sort='Via' )}">Via</a>
- </nobr>
- ${htmlize( heap )}
- %endif
- </pre>
-%endif
diff -r c8b49753bf99d03462bace0dbb2f38b9c0f52915 -r 9c767090274eb2a213854dcdb367135d782fecec templates/webapps/galaxy/admin/index.mako
--- a/templates/webapps/galaxy/admin/index.mako
+++ b/templates/webapps/galaxy/admin/index.mako
@@ -78,7 +78,6 @@
<div class="toolTitle"><a href="${h.url_for( controller='admin', action='tool_versions' )}" target="galaxy_main">View tool lineage</a></div><div class="toolTitle"><a href="${h.url_for( controller='admin', action='package_tool' )}" target="galaxy_main">Download tool tarball</a></div><div class="toolTitle"><a href="${h.url_for( controller='admin', action='reload_tool' )}" target="galaxy_main">Reload a tool's configuration</a></div>
- <div class="toolTitle"><a href="${h.url_for( controller='admin', action='memdump' )}" target="galaxy_main">Profile memory usage</a></div><div class="toolTitle"><a href="${h.url_for( controller='admin', action='jobs' )}" target="galaxy_main">Manage jobs</a></div><div class="toolTitle"><a href="${h.url_for( controller='admin', action='review_tool_migration_stages' )}" target="galaxy_main">Review tool migration stages</a></div>
%if installing_repository_ids:
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: guerler: ToolForm: Show errors for skipped fields
by commits-noreply@bitbucket.org 29 Jan '15
by commits-noreply@bitbucket.org 29 Jan '15
29 Jan '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/c8b49753bf99/
Changeset: c8b49753bf99
User: guerler
Date: 2015-01-28 20:43:42+00:00
Summary: ToolForm: Show errors for skipped fields
Affected #: 3 files
diff -r e0b649785f0a92c1030c42ea826d367ee7d5dc3c -r c8b49753bf99d03462bace0dbb2f38b9c0f52915 client/galaxy/scripts/mvc/tools/tools-input.js
--- a/client/galaxy/scripts/mvc/tools/tools-input.js
+++ b/client/galaxy/scripts/mvc/tools/tools-input.js
@@ -56,11 +56,9 @@
/** Set error text
*/
error: function(text) {
- if (!this.field.skip) {
- this.$error_text.html(text);
- this.$error.show();
- this.$el.addClass('ui-error');
- }
+ this.$error_text.html(text);
+ this.$error.show();
+ this.$el.addClass('ui-error');
},
/** Reset this view
diff -r e0b649785f0a92c1030c42ea826d367ee7d5dc3c -r c8b49753bf99d03462bace0dbb2f38b9c0f52915 static/scripts/mvc/tools/tools-input.js
--- a/static/scripts/mvc/tools/tools-input.js
+++ b/static/scripts/mvc/tools/tools-input.js
@@ -56,11 +56,9 @@
/** Set error text
*/
error: function(text) {
- if (!this.field.skip) {
- this.$error_text.html(text);
- this.$error.show();
- this.$el.addClass('ui-error');
- }
+ this.$error_text.html(text);
+ this.$error.show();
+ this.$el.addClass('ui-error');
},
/** Reset this view
diff -r e0b649785f0a92c1030c42ea826d367ee7d5dc3c -r c8b49753bf99d03462bace0dbb2f38b9c0f52915 static/scripts/packed/mvc/tools/tools-input.js
--- a/static/scripts/packed/mvc/tools/tools-input.js
+++ b/static/scripts/packed/mvc/tools/tools-input.js
@@ -1,1 +1,1 @@
-define([],function(){return Backbone.View.extend({initialize:function(d,c){this.app=d;this.text_enable=d.options.text_enable||"Enable";this.text_disable=d.options.text_disable||"Disable";this.field=c.field;this.default_value=c.default_value;this.setElement(this._template(c));this.$field=this.$el.find(".ui-table-form-field");this.$title_optional=this.$el.find(".ui-table-form-title-optional");this.$error_text=this.$el.find(".ui-table-form-error-text");this.$error=this.$el.find(".ui-table-form-error");this.$field.prepend(this.field.$el);this.field.skip=false;var b=this.field.value&&this.field.value();this.field.skip=Boolean(c.optional&&((this.default_value===undefined)||((this.field.validate&&!this.field.validate())||!b||(b==this.default_value)||(Number(b)==Number(this.default_value))||(JSON.stringify(b)==JSON.stringify(this.default_value)))));this._refresh();var a=this;this.$title_optional.on("click",function(){a.field.skip=!a.field.skip;a._refresh()})},error:function(a){if(!this.field.skip){this.$error_text.html(a);this.$error.show();this.$el.addClass("ui-error")}},reset:function(){this.$error.hide();this.$el.removeClass("ui-error")},_refresh:function(){if(!this.field.skip){this.$field.fadeIn("fast");this.$title_optional.html(this.text_disable)}else{this.reset();this.$field.hide();this.$title_optional.html(this.text_enable);this.field.value&&this.field.value(this.default_value)}this.app.trigger("refresh")},_template:function(a){var b='<div class="ui-table-form-element"><div class="ui-table-form-error ui-error"><span class="fa fa-arrow-down"/><span class="ui-table-form-error-text"/></div><div class="ui-table-form-title-strong">';if(a.optional){b+=a.label+'<span> [<span class="ui-table-form-title-optional"/>]</span>'}else{b+=a.label}b+='</div><div class="ui-table-form-field">';if(a.help){b+='<div class="ui-table-form-info">'+a.help+"</div>"}b+="</div></div>";return b}})});
\ No newline at end of file
+define([],function(){return Backbone.View.extend({initialize:function(d,c){this.app=d;this.text_enable=d.options.text_enable||"Enable";this.text_disable=d.options.text_disable||"Disable";this.field=c.field;this.default_value=c.default_value;this.setElement(this._template(c));this.$field=this.$el.find(".ui-table-form-field");this.$title_optional=this.$el.find(".ui-table-form-title-optional");this.$error_text=this.$el.find(".ui-table-form-error-text");this.$error=this.$el.find(".ui-table-form-error");this.$field.prepend(this.field.$el);this.field.skip=false;var b=this.field.value&&this.field.value();this.field.skip=Boolean(c.optional&&((this.default_value===undefined)||((this.field.validate&&!this.field.validate())||!b||(b==this.default_value)||(Number(b)==Number(this.default_value))||(JSON.stringify(b)==JSON.stringify(this.default_value)))));this._refresh();var a=this;this.$title_optional.on("click",function(){a.field.skip=!a.field.skip;a._refresh()})},error:function(a){this.$error_text.html(a);this.$error.show();this.$el.addClass("ui-error")},reset:function(){this.$error.hide();this.$el.removeClass("ui-error")},_refresh:function(){if(!this.field.skip){this.$field.fadeIn("fast");this.$title_optional.html(this.text_disable)}else{this.reset();this.$field.hide();this.$title_optional.html(this.text_enable);this.field.value&&this.field.value(this.default_value)}this.app.trigger("refresh")},_template:function(a){var b='<div class="ui-table-form-element"><div class="ui-table-form-error ui-error"><span class="fa fa-arrow-down"/><span class="ui-table-form-error-text"/></div><div class="ui-table-form-title-strong">';if(a.optional){b+=a.label+'<span> [<span class="ui-table-form-title-optional"/>]</span>'}else{b+=a.label}b+='</div><div class="ui-table-form-field">';if(a.help){b+='<div class="ui-table-form-info">'+a.help+"</div>"}b+="</div></div>";return b}})});
\ No newline at end of file
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: martenson: fix error in TS search schema
by commits-noreply@bitbucket.org 29 Jan '15
by commits-noreply@bitbucket.org 29 Jan '15
29 Jan '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/e0b649785f0a/
Changeset: e0b649785f0a
User: martenson
Date: 2015-01-28 20:25:42+00:00
Summary: fix error in TS search schema
Affected #: 1 file
diff -r bbebacb3a4e57063ad911d980c67182b6fe44522 -r e0b649785f0a92c1030c42ea826d367ee7d5dc3c lib/galaxy/webapps/tool_shed/search/repo_search.py
--- a/lib/galaxy/webapps/tool_shed/search/repo_search.py
+++ b/lib/galaxy/webapps/tool_shed/search/repo_search.py
@@ -21,14 +21,16 @@
schema = Schema(
id = STORED,
- name = TEXT( field_boost = 1.7 ),
- description = TEXT( field_boost = 1.5 ),
- long_description = TEXT,
- homepage_url = TEXT,
- remote_repository_url = TEXT,
- repo_owner_username = TEXT,
+ name = TEXT( field_boost = 1.7, stored = True ),
+ description = TEXT( field_boost = 1.5, stored = True ),
+ long_description = TEXT( stored = True ),
+ homepage_url = TEXT( stored = True ),
+ remote_repository_url = TEXT( stored = True ),
+ repo_owner_username = TEXT( stored = True ),
times_downloaded = STORED,
- approved = STORED )
+ approved = STORED,
+ last_updated = STORED,
+ full_last_updated = STORED )
except ImportError, e:
search_ready = False
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: martenson: way better search; dont query DB; repair final scoring functions
by commits-noreply@bitbucket.org 29 Jan '15
by commits-noreply@bitbucket.org 29 Jan '15
29 Jan '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/bbebacb3a4e5/
Changeset: bbebacb3a4e5
User: martenson
Date: 2015-01-28 20:24:10+00:00
Summary: way better search; dont query DB; repair final scoring functions
Affected #: 3 files
diff -r bc4403d1f81b560c8e0685eb1093b83ff6b348e4 -r bbebacb3a4e57063ad911d980c67182b6fe44522 lib/galaxy/webapps/tool_shed/api/search.py
--- a/lib/galaxy/webapps/tool_shed/api/search.py
+++ b/lib/galaxy/webapps/tool_shed/api/search.py
@@ -6,7 +6,9 @@
from galaxy.web import _future_expose_api_raw_anonymous as expose_api_raw_anonymous
from galaxy.web.base.controller import BaseAPIController
from galaxy.webapps.tool_shed.search.repo_search import RepoSearch
+from galaxy.web import url_for
import json
+
import logging
log = logging.getLogger( __name__ )
@@ -28,7 +30,6 @@
repo_search = RepoSearch()
results = repo_search.search( trans, search_term )
-
- response = '%s(%s);' % ( kwd.get('callback'), json.dumps(results) )
- log.debug(response)
+ results[ 'hostname' ] = url_for( '/', qualified = True )
+ response = '%s(%s);' % ( kwd.get( 'callback' ), json.dumps( results ) )
return response
diff -r bc4403d1f81b560c8e0685eb1093b83ff6b348e4 -r bbebacb3a4e57063ad911d980c67182b6fe44522 lib/galaxy/webapps/tool_shed/search/repo_search.py
--- a/lib/galaxy/webapps/tool_shed/search/repo_search.py
+++ b/lib/galaxy/webapps/tool_shed/search/repo_search.py
@@ -2,10 +2,7 @@
import datetime
from galaxy import exceptions
from galaxy import eggs
-from galaxy.util import pretty_print_time_interval
-from galaxy.web.base.controller import BaseAPIController
from galaxy.webapps.tool_shed import model
-from tool_shed.util.shed_util_common import generate_sharable_link_for_repository_in_tool_shed
import logging
log = logging.getLogger( __name__ )
@@ -27,11 +24,11 @@
name = TEXT( field_boost = 1.7 ),
description = TEXT( field_boost = 1.5 ),
long_description = TEXT,
- repo_type = TEXT,
homepage_url = TEXT,
remote_repository_url = TEXT,
repo_owner_username = TEXT,
- times_downloaded = STORED )
+ times_downloaded = STORED,
+ approved = STORED )
except ImportError, e:
search_ready = False
@@ -46,13 +43,25 @@
use_final = True
def final( self, searcher, docnum, score ):
+ log.debug('score before: ' + str(score) )
+
+ # Arbitrary for now
+ reasonable_hits = 100.0
+ times_downloaded = int( searcher.stored_fields( docnum )[ "times_downloaded" ] )
+ # Add 1 to prevent 0 being divided
+ if times_downloaded == 0:
+ times_downloaded = 1
+ popularity_modifier = ( times_downloaded / reasonable_hits )
+ log.debug('popularity_modifier: ' + str(popularity_modifier) )
- maxhits = 300
- hitcount = searcher.stored_fields( docnum )[ "times_downloaded" ]
- log.debug( 'hitcount: ' + str( hitcount ) )
+ cert_modifier = 2 if searcher.stored_fields( docnum )[ "approved" ] == 'yes' else 1
+ log.debug('cert_modifier: ' + str(cert_modifier) )
- # Multiply the computed score for this document by the popularity
- return score * ( hitcount / maxhits )
+ # Adjust the computed score for this document by the popularity
+ # and by the certification level.
+ final_score = score * popularity_modifier * cert_modifier
+ log.debug('score after: ' + str( final_score ) )
+ return final_score
class RepoSearch( object ):
@@ -80,8 +89,7 @@
'long_description_B' : 0.5,
'homepage_url_B' : 0.3,
'remote_repository_url_B' : 0.2,
- 'repo_owner_username' : 0.3,
- 'repo_type_B' : 0.1 } )
+ 'repo_owner_username' : 0.3 } )
# log.debug(repo_weighting.__dict__)
searcher = index.searcher( weighting = repo_weighting )
@@ -90,7 +98,6 @@
'name',
'description',
'long_description',
- 'repo_type',
'homepage_url',
'remote_repository_url',
'repo_owner_username' ], schema = schema )
@@ -99,30 +106,28 @@
user_query = parser.parse( '*' + search_term + '*' )
hits = searcher.search( user_query, terms = True )
+ # hits = searcher.search( user_query )
# hits = searcher.search_page( user_query, 1, pagelen = 1, terms = True )
log.debug( 'searching for: #' + str( search_term ) )
log.debug( 'total hits: ' + str( len( hits ) ) )
log.debug( 'scored hits: ' + str( hits.scored_length() ) )
results = {}
- results[ 'total_results'] = len( hits )
+ results[ 'total_results'] = str( hits.scored_length() )
results[ 'hits' ] = []
for hit in hits:
- repo = trans.sa_session.query( model.Repository ).filter_by( id = hit[ 'id' ] ).one()
- approved = 'no'
- for review in repo.reviews:
- if review.approved == 'yes':
- approved = 'yes'
- break
- hit_dict = repo.to_dict( view = 'element', value_mapper = { 'id': trans.security.encode_id, 'user_id': trans.security.encode_id } )
- hit_dict[ 'url'] = generate_sharable_link_for_repository_in_tool_shed( repo )
-
- # Format the time since last update to be nicely readable.
- time_ago = pretty_print_time_interval( repo.update_time )
- hit_dict[ 'last_updated' ] = time_ago
- hit_dict[ 'full_last_updated' ] = repo.update_time.strftime( "%Y-%m-%d %I:%M %p" )
- hit_dict[ 'times_downloaded' ] = repo.times_downloaded
- hit_dict[ 'approved' ] = approved
- results[ 'hits' ].append( {'repository': hit_dict, 'matched_terms': hit.matched_terms() } )
+ hit_dict = {}
+ hit_dict[ 'id' ] = trans.security.encode_id( hit.get( 'id' ) )
+ hit_dict[ 'repo_owner_username' ] = hit.get( 'repo_owner_username' )
+ hit_dict[ 'name' ] = hit.get( 'name' )
+ hit_dict[ 'long_description' ] = hit.get( 'long_description' )
+ hit_dict[ 'remote_repository_url' ] = hit.get( 'remote_repository_url' )
+ hit_dict[ 'homepage_url' ] = hit.get( 'homepage_url' )
+ hit_dict[ 'description' ] = hit.get( 'description' )
+ hit_dict[ 'last_updated' ] = hit.get( 'last_updated' )
+ hit_dict[ 'full_last_updated' ] = hit.get( 'full_last_updated' )
+ hit_dict[ 'approved' ] = hit.get( 'approved' )
+ hit_dict[ 'times_downloaded' ] = hit.get( 'times_downloaded' )
+ results[ 'hits' ].append( {'repository': hit_dict, 'matched_terms': hit.matched_terms(), 'score': hit.score } )
return results
finally:
searcher.close()
diff -r bc4403d1f81b560c8e0685eb1093b83ff6b348e4 -r bbebacb3a4e57063ad911d980c67182b6fe44522 scripts/tool_shed/build_ts_whoosh_index.py
--- a/scripts/tool_shed/build_ts_whoosh_index.py
+++ b/scripts/tool_shed/build_ts_whoosh_index.py
@@ -1,21 +1,26 @@
# !/usr/bin/env python
""" Build indeces for searching the TS """
-import sys, os, csv, urllib, urllib2, ConfigParser
+import sys
+import os
+import csv
+import urllib
+import urllib2
+import ConfigParser
new_path = [ os.path.join( os.getcwd(), "lib" ) ]
new_path.extend( sys.path[1:] ) # remove scripts/ from the path
sys.path = new_path
+from galaxy.util import pretty_print_time_interval
from galaxy import eggs
+eggs.require( "SQLAlchemy" )
+
+import galaxy.webapps.tool_shed.model.mapping
# Whoosh is compatible with Python 2.5+ Try to import Whoosh and set flag to indicate whether search is enabled.
try:
eggs.require( "Whoosh" )
- import pkg_resources
- pkg_resources.require( "SQLAlchemy >= 0.4" )
-
import whoosh.index
- import galaxy.webapps.tool_shed.model.mapping
from whoosh.filedb.filestore import FileStorage
from whoosh.fields import Schema, STORED, ID, KEYWORD, TEXT, STORED
from whoosh.scoring import BM25F
@@ -26,14 +31,16 @@
whoosh_ready = True
schema = Schema(
id = STORED,
- name = TEXT( field_boost = 1.7 ),
- description = TEXT( field_boost = 1.5 ),
- long_description = TEXT,
- repo_type = TEXT,
- homepage_url = TEXT,
- remote_repository_url = TEXT,
- repo_owner_username = TEXT,
- times_downloaded = STORED )
+ name = TEXT( field_boost = 1.7, stored = True ),
+ description = TEXT( field_boost = 1.5, stored = True ),
+ long_description = TEXT( stored = True ),
+ homepage_url = TEXT( stored = True ),
+ remote_repository_url = TEXT( stored = True ),
+ repo_owner_username = TEXT( stored = True ),
+ times_downloaded = STORED,
+ approved = STORED,
+ last_updated = STORED,
+ full_last_updated = STORED )
except ImportError, e:
print 'import error'
@@ -51,16 +58,29 @@
return a_basestr
repos_indexed = 0
- for id, name, description, long_description, repo_type, homepage_url, remote_repository_url, repo_owner_username, times_downloaded in get_repos( sa_session ):
+ for ( id,
+ name,
+ description,
+ long_description,
+ homepage_url,
+ remote_repository_url,
+ repo_owner_username,
+ times_downloaded,
+ approved,
+ last_updated,
+ full_last_updated ) in get_repos( sa_session ):
+
writer.add_document( id = id,
name = to_unicode( name ),
description = to_unicode( description ),
long_description = to_unicode( long_description ),
- repo_type = to_unicode( repo_type ),
homepage_url = to_unicode( homepage_url ),
remote_repository_url = to_unicode( remote_repository_url ),
repo_owner_username = to_unicode( repo_owner_username ),
- times_downloaded = times_downloaded )
+ times_downloaded = times_downloaded,
+ approved = approved,
+ last_updated = last_updated,
+ full_last_updated = full_last_updated )
repos_indexed += 1
writer.commit()
print "Number of repos indexed: ", repos_indexed
@@ -71,17 +91,36 @@
name = repo.name
description = repo.description
long_description = repo.long_description
- repo_type = repo.type
homepage_url = repo.homepage_url
remote_repository_url = repo.remote_repository_url
times_downloaded = repo.times_downloaded
- repo_owner_username = ""
+ repo_owner_username = ''
if repo.user_id is not None:
user = sa_session.query( model.User ).filter( model.User.id == repo.user_id ).one()
repo_owner_username = user.username
- yield id, name, description, long_description, repo_type, homepage_url, remote_repository_url, repo_owner_username, times_downloaded
+ approved = 'no'
+ for review in repo.reviews:
+ if review.approved == 'yes':
+ approved = 'yes'
+ break
+
+ # Format the time since last update to be nicely readable.
+ last_updated = pretty_print_time_interval( repo.update_time )
+ full_last_updated = repo.update_time.strftime( "%Y-%m-%d %I:%M %p" )
+
+ yield ( id,
+ name,
+ description,
+ long_description,
+ homepage_url,
+ remote_repository_url,
+ repo_owner_username,
+ times_downloaded,
+ approved,
+ last_updated,
+ full_last_updated )
def get_sa_session_and_needed_config_settings( ini_file ):
conf_parser = ConfigParser.ConfigParser( { 'here' : os.getcwd() } )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
3 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/7d7419ddad18/
Changeset: 7d7419ddad18
Branch: stable
User: natefoo
Date: 2015-01-28 15:38:22+00:00
Summary: Allow BAM's set_meta() to use samtools 1 to generate the index, if the samtools found on $PATH is samtools 1.
Affected #: 1 file
diff -r 837baf8a92add3084c7e230cf537016192a78b55 -r 7d7419ddad18212b60eaf1b5c30196bf9ad2328b lib/galaxy/datatypes/binary.py
--- a/lib/galaxy/datatypes/binary.py
+++ b/lib/galaxy/datatypes/binary.py
@@ -240,10 +240,19 @@
##$ samtools index
##Usage: samtools index <in.bam> [<out.index>]
stderr_name = tempfile.NamedTemporaryFile( prefix = "bam_index_stderr" ).name
- command = 'samtools index %s %s' % ( dataset.file_name, index_file.file_name )
- proc = subprocess.Popen( args=command, shell=True, stderr=open( stderr_name, 'wb' ) )
+ command = [ 'samtools', 'index', dataset.file_name, index_file.file_name ]
+ proc = subprocess.Popen( args=command, stderr=open( stderr_name, 'wb' ) )
exit_code = proc.wait()
#Did index succeed?
+ if exit_code == -6:
+ # SIGABRT, most likely samtools 1.0+ which does not accept the index name parameter.
+ command = [ 'samtools', 'index', dataset.file_name ]
+ proc = subprocess.Popen( args=command, stderr=open( stderr_name, 'wb' ) )
+ exit_code = proc.wait()
+ if os.path.exists( os.path.join( dataset.file_name, '.bai' ) ):
+ shutil.move( os.path.join( dataset.file_name, '.bai' ), index_file.file_name )
+ else:
+ open( stderr_name, 'ab+' ).write( 'Galaxy attempted to build the BAM index with samtools 1.0+ but failed\n')
stderr = open( stderr_name ).read().strip()
if stderr:
if exit_code != 0:
https://bitbucket.org/galaxy/galaxy-central/commits/d05da0df53b9/
Changeset: d05da0df53b9
Branch: stable
User: natefoo
Date: 2015-01-28 16:58:23+00:00
Summary: Use a symlink to the dataset in the same directory as the MetadataTempFile as the input to samtools index so there's no clobber risk. Thanks Dan.
Affected #: 1 file
diff -r 7d7419ddad18212b60eaf1b5c30196bf9ad2328b -r d05da0df53b98639d753d94e9ffaa1e99c918142 lib/galaxy/datatypes/binary.py
--- a/lib/galaxy/datatypes/binary.py
+++ b/lib/galaxy/datatypes/binary.py
@@ -246,13 +246,18 @@
#Did index succeed?
if exit_code == -6:
# SIGABRT, most likely samtools 1.0+ which does not accept the index name parameter.
- command = [ 'samtools', 'index', dataset.file_name ]
- proc = subprocess.Popen( args=command, stderr=open( stderr_name, 'wb' ) )
- exit_code = proc.wait()
- if os.path.exists( os.path.join( dataset.file_name, '.bai' ) ):
- shutil.move( os.path.join( dataset.file_name, '.bai' ), index_file.file_name )
- else:
- open( stderr_name, 'ab+' ).write( 'Galaxy attempted to build the BAM index with samtools 1.0+ but failed\n')
+ dataset_symlink = os.path.join( os.path.dirname( index_file.file_name ),
+ '__dataset_%d_%s' % ( dataset.id, os.path.basename( index_file.file_name ) ) )
+ os.symlink( dataset.file_name, dataset_symlink )
+ try:
+ command = [ 'samtools', 'index', dataset_symlink ]
+ proc = subprocess.Popen( args=command, stderr=open( stderr_name, 'wb' ) )
+ exit_code = proc.wait()
+ shutil.move( dataset_symlink + '.bai', index_file.file_name )
+ except Exception, e:
+ open( stderr_name, 'ab+' ).write( 'Galaxy attempted to build the BAM index with samtools 1.0+ but failed: %s\n' % e)
+ finally:
+ os.unlink( dataset_symlink )
stderr = open( stderr_name ).read().strip()
if stderr:
if exit_code != 0:
https://bitbucket.org/galaxy/galaxy-central/commits/a481d17c0448/
Changeset: a481d17c0448
Branch: stable
User: natefoo
Date: 2015-01-28 18:25:11+00:00
Summary: Use subprocess.call() rather than Popen(), thanks Nicola.
Affected #: 1 file
diff -r d05da0df53b98639d753d94e9ffaa1e99c918142 -r a481d17c04482b069e6b2ebdda4fbca01448fa9c lib/galaxy/datatypes/binary.py
--- a/lib/galaxy/datatypes/binary.py
+++ b/lib/galaxy/datatypes/binary.py
@@ -251,8 +251,7 @@
os.symlink( dataset.file_name, dataset_symlink )
try:
command = [ 'samtools', 'index', dataset_symlink ]
- proc = subprocess.Popen( args=command, stderr=open( stderr_name, 'wb' ) )
- exit_code = proc.wait()
+ exit_code = subprocess.call( args=command, stderr=open( stderr_name, 'wb' ) )
shutil.move( dataset_symlink + '.bai', index_file.file_name )
except Exception, e:
open( stderr_name, 'ab+' ).write( 'Galaxy attempted to build the BAM index with samtools 1.0+ but failed: %s\n' % e)
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: guerler: Workflow: Disable new tool form
by commits-noreply@bitbucket.org 29 Jan '15
by commits-noreply@bitbucket.org 29 Jan '15
29 Jan '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/bc4403d1f81b/
Changeset: bc4403d1f81b
User: guerler
Date: 2015-01-28 18:51:51+00:00
Summary: Workflow: Disable new tool form
Affected #: 1 file
diff -r f0a96002a5538b1b5e2ebafe8f80a64ed299b418 -r bc4403d1f81b560c8e0685eb1093b83ff6b348e4 lib/galaxy/webapps/galaxy/controllers/workflow.py
--- a/lib/galaxy/webapps/galaxy/controllers/workflow.py
+++ b/lib/galaxy/webapps/galaxy/controllers/workflow.py
@@ -618,18 +618,12 @@
'tool_state': tool_state
} )
- # create tool model and default tool state (if missing)
- tool_model = None
- if not tool_state:
- tool_model = module.tool.to_json(trans, **incoming)
- module.state.inputs = copy.deepcopy(tool_model['state_inputs'])
-
# update module state
module.update_state( incoming )
if type == 'tool':
return {
- 'tool_model': tool_model,
+ 'tool_model': None,
'tool_state': module.get_state(),
'data_inputs': module.get_data_inputs(),
'data_outputs': module.get_data_outputs(),
@@ -664,7 +658,7 @@
'name': module.get_name(),
'tool_id': module.get_tool_id(),
'tool_state': module.get_state(),
- 'tool_model': module.tool.to_json(trans),
+ 'tool_model': None,
'tooltip': module.get_tooltip( static_path=url_for( '/static' ) ),
'data_inputs': module.get_data_inputs(),
'data_outputs': module.get_data_outputs(),
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0