galaxy-commits
Threads by month
- ----- 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
November 2014
- 2 participants
- 184 discussions
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/c53f747732a1/
Changeset: c53f747732a1
Branch: next-stable
User: guerler
Date: 2014-11-25 19:04:43+00:00
Summary: Fixes security issue 2.2 for regular grid values
Affected #: 1 file
diff -r 8e001650dc70e9fe1230b5ffca7f1d167d77fd3c -r c53f747732a115c7ec6ed3e192bb059d12266865 lib/galaxy/web/framework/helpers/grids.py
--- a/lib/galaxy/web/framework/helpers/grids.py
+++ b/lib/galaxy/web/framework/helpers/grids.py
@@ -8,6 +8,7 @@
from galaxy.web.framework import decorators
from galaxy.web.framework import url_for
from galaxy.web.framework.helpers import iff
+from markupsafe import escape
from sqlalchemy.sql.expression import and_, func, or_
@@ -362,7 +363,7 @@
value = None
if self.format:
value = self.format( value )
- return value
+ return escape(value)
def get_link( self, trans, grid, item ):
if self.link and self.link( item ):
return self.link( item )
https://bitbucket.org/galaxy/galaxy-central/commits/c0a41931fcfc/
Changeset: c0a41931fcfc
User: guerler
Date: 2014-11-25 19:05:02+00:00
Summary: Merge
Affected #: 9 files
diff -r a0eda112fa3b6456a5ae663ff2ddcc0137c87714 -r c0a41931fcfc00b52423667d33910eeb59cf5ac6 client/galaxy/scripts/galaxy.menu.js
--- a/client/galaxy/scripts/galaxy.menu.js
+++ b/client/galaxy/scripts/galaxy.menu.js
@@ -24,7 +24,7 @@
var tab_analysis = new mod_masthead.GalaxyMastheadTab({
id : "analysis",
title : "Analyze Data",
- content : "root/index",
+ content : "",
title_attribute : 'Analysis home view'
});
this.masthead.append(tab_analysis);
diff -r a0eda112fa3b6456a5ae663ff2ddcc0137c87714 -r c0a41931fcfc00b52423667d33910eeb59cf5ac6 config/galaxy.ini.sample
--- a/config/galaxy.ini.sample
+++ b/config/galaxy.ini.sample
@@ -523,6 +523,15 @@
# it faster on the fly.
#upstream_gzip = False
+# The following default adds a header to web request responses that 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
+# configuring a proxy to sit infront of Galaxy - please ensure this header
+# remains intact to protect your users. Uncomment and leave empty to not set
+# the `X-Frame-Options` header.
+#x_frame_options = SAMEORIGIN
+
# nginx can also handle file uploads (user-to-Galaxy) via nginx_upload_module.
# Configuration for this is complex and explained in detail in the
# documentation linked above. The upload store is a temporary directory in
diff -r a0eda112fa3b6456a5ae663ff2ddcc0137c87714 -r c0a41931fcfc00b52423667d33910eeb59cf5ac6 lib/galaxy/config.py
--- a/lib/galaxy/config.py
+++ b/lib/galaxy/config.py
@@ -96,6 +96,7 @@
# been migrated from the Galaxy code distribution to the Tool Shed.
self.check_migrate_tools = string_as_bool( kwargs.get( 'check_migrate_tools', True ) )
self.shed_tool_data_path = kwargs.get( "shed_tool_data_path", None )
+ self.x_frame_options = kwargs.get( "x_frame_options", "SAMEORIGIN" )
if self.shed_tool_data_path:
self.shed_tool_data_path = resolve_path( self.shed_tool_data_path, self.root )
else:
diff -r a0eda112fa3b6456a5ae663ff2ddcc0137c87714 -r c0a41931fcfc00b52423667d33910eeb59cf5ac6 lib/galaxy/web/framework/helpers/__init__.py
--- a/lib/galaxy/web/framework/helpers/__init__.py
+++ b/lib/galaxy/web/framework/helpers/__init__.py
@@ -7,7 +7,7 @@
from datetime import datetime, timedelta
from galaxy import eggs
from galaxy.util import hash_util
-from galaxy.util.json import dumps
+from galaxy.util.json import safe_dumps as dumps
eggs.require( "MarkupSafe" ) #required by WebHelpers
eggs.require( "WebHelpers" )
from webhelpers import date
diff -r a0eda112fa3b6456a5ae663ff2ddcc0137c87714 -r c0a41931fcfc00b52423667d33910eeb59cf5ac6 lib/galaxy/web/framework/helpers/grids.py
--- a/lib/galaxy/web/framework/helpers/grids.py
+++ b/lib/galaxy/web/framework/helpers/grids.py
@@ -8,6 +8,7 @@
from galaxy.web.framework import decorators
from galaxy.web.framework import url_for
from galaxy.web.framework.helpers import iff
+from markupsafe import escape
from sqlalchemy.sql.expression import and_, func, or_
@@ -362,7 +363,7 @@
value = None
if self.format:
value = self.format( value )
- return value
+ return escape(value)
def get_link( self, trans, grid, item ):
if self.link and self.link( item ):
return self.link( item )
diff -r a0eda112fa3b6456a5ae663ff2ddcc0137c87714 -r c0a41931fcfc00b52423667d33910eeb59cf5ac6 lib/galaxy/web/framework/webapp.py
--- a/lib/galaxy/web/framework/webapp.py
+++ b/lib/galaxy/web/framework/webapp.py
@@ -175,7 +175,11 @@
base.DefaultWebTransaction.__init__( self, environ )
self.setup_i18n()
self.expunge_all()
- self.debug = asbool( self.app.config.get( 'debug', False ) )
+ config = self.app.config
+ self.debug = asbool( config.get( 'debug', False ) )
+ x_frame_options = getattr( config, 'x_frame_options', None )
+ if x_frame_options:
+ self.response.headers['X-Frame-Options'] = x_frame_options
# Flag indicating whether we are in workflow building mode (means
# that the current history should not be used for parameter values
# and such).
@@ -202,9 +206,9 @@
# When we've authenticated by session, we have to check the
# following.
# Prevent deleted users from accessing Galaxy
- if self.app.config.use_remote_user and self.galaxy_session.user.deleted:
+ if config.use_remote_user and self.galaxy_session.user.deleted:
self.response.send_redirect( url_for( '/static/user_disabled.html' ) )
- if self.app.config.require_login:
+ if config.require_login:
self._ensure_logged_in_user( environ, session_cookie )
def setup_i18n( self ):
@@ -261,6 +265,9 @@
tstamp = time.localtime( time.time() + 3600 * 24 * age )
self.response.cookies[name]['expires'] = time.strftime( '%a, %d-%b-%Y %H:%M:%S GMT', tstamp )
self.response.cookies[name]['version'] = version
+ https = self.request.environ[ "wsgi.url_scheme" ] == "https"
+ if https:
+ self.response.cookies[name]['secure'] = True
try:
self.response.cookies[name]['httponly'] = True
except CookieError, e:
diff -r a0eda112fa3b6456a5ae663ff2ddcc0137c87714 -r c0a41931fcfc00b52423667d33910eeb59cf5ac6 static/scripts/galaxy.menu.js
--- a/static/scripts/galaxy.menu.js
+++ b/static/scripts/galaxy.menu.js
@@ -24,7 +24,7 @@
var tab_analysis = new mod_masthead.GalaxyMastheadTab({
id : "analysis",
title : "Analyze Data",
- content : "root/index",
+ content : "",
title_attribute : 'Analysis home view'
});
this.masthead.append(tab_analysis);
diff -r a0eda112fa3b6456a5ae663ff2ddcc0137c87714 -r c0a41931fcfc00b52423667d33910eeb59cf5ac6 static/scripts/packed/galaxy.menu.js
--- a/static/scripts/packed/galaxy.menu.js
+++ b/static/scripts/packed/galaxy.menu.js
@@ -1,1 +1,1 @@
-define(["galaxy.masthead"],function(b){var a=Backbone.Model.extend({options:null,masthead:null,initialize:function(c){this.options=c.config;this.masthead=c.masthead;this.create()},create:function(){var e=new b.GalaxyMastheadTab({id:"analysis",title:"Analyze Data",content:"root/index",title_attribute:"Analysis home view"});this.masthead.append(e);var g={id:"workflow",title:"Workflow",content:"workflow",title_attribute:"Chain tools into workflows"};if(!this.options.user.valid){g.disabled=true}var d=new b.GalaxyMastheadTab(g);this.masthead.append(d);var i=new b.GalaxyMastheadTab({id:"shared",title:"Shared Data",content:"library/index",title_attribute:"Access published resources"});i.add({title:"Data Libraries",content:"library/index"});i.add({title:"Data Libraries Beta",content:"library/list",divider:true});i.add({title:"Published Histories",content:"history/list_published"});i.add({title:"Published Workflows",content:"workflow/list_published"});i.add({title:"Published Visualizations",content:"visualization/list_published"});i.add({title:"Published Pages",content:"page/list_published"});this.masthead.append(i);if(this.options.user.requests){var j=new b.GalaxyMastheadTab({id:"lab",title:"Lab"});j.add({title:"Sequencing Requests",content:"requests/index"});j.add({title:"Find Samples",content:"requests/find_samples_index"});j.add({title:"Help",content:this.options.lims_doc_url});this.masthead.append(j)}var c={id:"visualization",title:"Visualization",content:"visualization/list",title_attribute:"Visualize datasets"};if(!this.options.user.valid){c.disabled=true}var m=new b.GalaxyMastheadTab(c);if(this.options.user.valid){m.add({title:"New Track Browser",content:"visualization/trackster",target:"_frame"});m.add({title:"Saved Visualizations",content:"visualization/list",target:"_frame"})}this.masthead.append(m);if(this.options.enable_cloud_launch){var f=new b.GalaxyMastheadTab({id:"cloud",title:"Cloud",content:"cloudlaunch/index"});f.add({title:"New Cloud Cluster",content:"cloudlaunch/index"});this.masthead.append(f)}if(this.options.is_admin_user){var h=new b.GalaxyMastheadTab({id:"admin",title:"Admin",content:"admin/index",extra_class:"admin-only",title_attribute:"Administer this Galaxy"});this.masthead.append(h)}var l=new b.GalaxyMastheadTab({id:"help",title:"Help",title_attribute:"Support, contact, and community hubs"});if(this.options.biostar_url){l.add({title:"Galaxy Biostar",content:this.options.biostar_url_redirect,target:"_blank"});l.add({title:"Ask a question",content:"biostar/biostar_question_redirect",target:"_blank"})}l.add({title:"Support",content:this.options.support_url,target:"_blank"});l.add({title:"Search",content:this.options.search_url,target:"_blank"});l.add({title:"Mailing Lists",content:this.options.mailing_lists,target:"_blank"});l.add({title:"Videos",content:this.options.screencasts_url,target:"_blank"});l.add({title:"Wiki",content:this.options.wiki_url,target:"_blank"});l.add({title:"How to Cite Galaxy",content:this.options.citation_url,target:"_blank"});if(this.options.terms_url){l.add({title:"Terms and Conditions",content:this.options.terms_url,target:"_blank"})}this.masthead.append(l);if(!this.options.user.valid){var k=new b.GalaxyMastheadTab({id:"user",title:"User",extra_class:"loggedout-only",title_attribute:"Account registration or login"});k.add({title:"Login",content:"user/login",target:"galaxy_main"});if(this.options.allow_user_creation){k.add({title:"Register",content:"user/create",target:"galaxy_main"})}this.masthead.append(k)}else{var k=new b.GalaxyMastheadTab({id:"user",title:"User",extra_class:"loggedin-only",title_attribute:"Account preferences and saved data"});k.add({title:"Logged in as "+this.options.user.email});k.add({title:"Preferences",content:"user?cntrller=user",target:"galaxy_main"});k.add({title:"Custom Builds",content:"user/dbkeys",target:"galaxy_main"});k.add({title:"Logout",content:"user/logout",target:"_top",divider:true});k.add({title:"Saved Histories",content:"history/list",target:"galaxy_main"});k.add({title:"Saved Datasets",content:"dataset/list",target:"galaxy_main"});k.add({title:"Saved Pages",content:"page/list",target:"_top"});k.add({title:"API Keys",content:"user/api_keys?cntrller=user",target:"galaxy_main"});if(this.options.use_remote_user){k.add({title:"Public Name",content:"user/edit_username?cntrller=user",target:"galaxy_main"})}this.masthead.append(k)}if(this.options.active_view){this.masthead.highlight(this.options.active_view)}}});return{GalaxyMenu:a}});
\ No newline at end of file
+define(["galaxy.masthead"],function(b){var a=Backbone.Model.extend({options:null,masthead:null,initialize:function(c){this.options=c.config;this.masthead=c.masthead;this.create()},create:function(){var e=new b.GalaxyMastheadTab({id:"analysis",title:"Analyze Data",content:"",title_attribute:"Analysis home view"});this.masthead.append(e);var g={id:"workflow",title:"Workflow",content:"workflow",title_attribute:"Chain tools into workflows"};if(!this.options.user.valid){g.disabled=true}var d=new b.GalaxyMastheadTab(g);this.masthead.append(d);var i=new b.GalaxyMastheadTab({id:"shared",title:"Shared Data",content:"library/index",title_attribute:"Access published resources"});i.add({title:"Data Libraries",content:"library/index"});i.add({title:"Data Libraries Beta",content:"library/list",divider:true});i.add({title:"Published Histories",content:"history/list_published"});i.add({title:"Published Workflows",content:"workflow/list_published"});i.add({title:"Published Visualizations",content:"visualization/list_published"});i.add({title:"Published Pages",content:"page/list_published"});this.masthead.append(i);if(this.options.user.requests){var j=new b.GalaxyMastheadTab({id:"lab",title:"Lab"});j.add({title:"Sequencing Requests",content:"requests/index"});j.add({title:"Find Samples",content:"requests/find_samples_index"});j.add({title:"Help",content:this.options.lims_doc_url});this.masthead.append(j)}var c={id:"visualization",title:"Visualization",content:"visualization/list",title_attribute:"Visualize datasets"};if(!this.options.user.valid){c.disabled=true}var m=new b.GalaxyMastheadTab(c);if(this.options.user.valid){m.add({title:"New Track Browser",content:"visualization/trackster",target:"_frame"});m.add({title:"Saved Visualizations",content:"visualization/list",target:"_frame"})}this.masthead.append(m);if(this.options.enable_cloud_launch){var f=new b.GalaxyMastheadTab({id:"cloud",title:"Cloud",content:"cloudlaunch/index"});f.add({title:"New Cloud Cluster",content:"cloudlaunch/index"});this.masthead.append(f)}if(this.options.is_admin_user){var h=new b.GalaxyMastheadTab({id:"admin",title:"Admin",content:"admin/index",extra_class:"admin-only",title_attribute:"Administer this Galaxy"});this.masthead.append(h)}var l=new b.GalaxyMastheadTab({id:"help",title:"Help",title_attribute:"Support, contact, and community hubs"});if(this.options.biostar_url){l.add({title:"Galaxy Biostar",content:this.options.biostar_url_redirect,target:"_blank"});l.add({title:"Ask a question",content:"biostar/biostar_question_redirect",target:"_blank"})}l.add({title:"Support",content:this.options.support_url,target:"_blank"});l.add({title:"Search",content:this.options.search_url,target:"_blank"});l.add({title:"Mailing Lists",content:this.options.mailing_lists,target:"_blank"});l.add({title:"Videos",content:this.options.screencasts_url,target:"_blank"});l.add({title:"Wiki",content:this.options.wiki_url,target:"_blank"});l.add({title:"How to Cite Galaxy",content:this.options.citation_url,target:"_blank"});if(this.options.terms_url){l.add({title:"Terms and Conditions",content:this.options.terms_url,target:"_blank"})}this.masthead.append(l);if(!this.options.user.valid){var k=new b.GalaxyMastheadTab({id:"user",title:"User",extra_class:"loggedout-only",title_attribute:"Account registration or login"});k.add({title:"Login",content:"user/login",target:"galaxy_main"});if(this.options.allow_user_creation){k.add({title:"Register",content:"user/create",target:"galaxy_main"})}this.masthead.append(k)}else{var k=new b.GalaxyMastheadTab({id:"user",title:"User",extra_class:"loggedin-only",title_attribute:"Account preferences and saved data"});k.add({title:"Logged in as "+this.options.user.email});k.add({title:"Preferences",content:"user?cntrller=user",target:"galaxy_main"});k.add({title:"Custom Builds",content:"user/dbkeys",target:"galaxy_main"});k.add({title:"Logout",content:"user/logout",target:"_top",divider:true});k.add({title:"Saved Histories",content:"history/list",target:"galaxy_main"});k.add({title:"Saved Datasets",content:"dataset/list",target:"galaxy_main"});k.add({title:"Saved Pages",content:"page/list",target:"_top"});k.add({title:"API Keys",content:"user/api_keys?cntrller=user",target:"galaxy_main"});if(this.options.use_remote_user){k.add({title:"Public Name",content:"user/edit_username?cntrller=user",target:"galaxy_main"})}this.masthead.append(k)}if(this.options.active_view){this.masthead.highlight(this.options.active_view)}}});return{GalaxyMenu:a}});
\ 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: dannon: Swap webhelpers to use safe dumps.
by commits-noreply@bitbucket.org 25 Nov '14
by commits-noreply@bitbucket.org 25 Nov '14
25 Nov '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/8e001650dc70/
Changeset: 8e001650dc70
Branch: next-stable
User: dannon
Date: 2014-11-25 18:32:15+00:00
Summary: Swap webhelpers to use safe dumps.
Affected #: 1 file
diff -r 4d173afb6f7c0c59a36d35a23f4f0eecd30e79a6 -r 8e001650dc70e9fe1230b5ffca7f1d167d77fd3c lib/galaxy/web/framework/helpers/__init__.py
--- a/lib/galaxy/web/framework/helpers/__init__.py
+++ b/lib/galaxy/web/framework/helpers/__init__.py
@@ -7,7 +7,7 @@
from datetime import datetime, timedelta
from galaxy import eggs
from galaxy.util import hash_util
-from galaxy.util.json import dumps
+from galaxy.util.json import safe_dumps as dumps
eggs.require( "MarkupSafe" ) #required by WebHelpers
eggs.require( "WebHelpers" )
from webhelpers import date
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
6 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/45f1c89fc887/
Changeset: 45f1c89fc887
Branch: next-stable
User: guerler
Date: 2014-11-24 17:08:46+00:00
Summary: ToolForm: Fix optional parameters, add select2 fields, fix style
Affected #: 24 files
diff -r c7d09076b630f1ea42fc62e3e4c2dae5332b6892 -r 45f1c89fc887e1bbb48a18ebfac918cd1bc62cba client/galaxy/scripts/mvc/tools/tools-form.js
--- a/client/galaxy/scripts/mvc/tools/tools-form.js
+++ b/client/galaxy/scripts/mvc/tools/tools-form.js
@@ -84,14 +84,12 @@
// refreshes input states i.e. for dynamic parameters
refresh: function() {
// only refresh the state if the form contains dynamic parameters
- if (!this.is_dynamic) {
- return;
- }
-
- // place refresh process into deferred queue
- var self = this;
- this.deferred.reset();
- this.deferred.execute(function(){self._updateModel()});
+ // by using/reseting the deferred ajax queue the number of redundant calls is reduced
+ if (this.is_dynamic) {
+ var self = this;
+ this.deferred.reset();
+ this.deferred.execute(function(){self._updateModel()});
+ };
},
// build tool model through api call
@@ -141,10 +139,8 @@
// request a new model and update the form inputs
_updateModel: function() {
- // link this
+ // create the request dictionary
var self = this;
-
- // finalize data
var current_state = this.tree.finalize({
data : function(dict) {
if (dict.values.length > 0 && dict.values[0] && dict.values[0].src === 'hda') {
@@ -332,8 +328,9 @@
// create portlet
this.portlet = new Portlet.View({
- icon : 'fa-wrench',
- title: '<b>' + this.model.name + '</b> ' + this.model.description,
+ icon : 'fa-wrench',
+ title : '<b>' + this.model.name + '</b> ' + this.model.description,
+ cls : 'ui-portlet-slim',
operations: {
menu : menu
},
diff -r c7d09076b630f1ea42fc62e3e4c2dae5332b6892 -r 45f1c89fc887e1bbb48a18ebfac918cd1bc62cba 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
@@ -25,12 +25,8 @@
// add field element
this.$field.prepend(this.field.$el);
- // hide optional field on initialization
- if (options.optional) {
- this.field.skip = true;
- } else {
- this.field.skip = false;
- }
+ // start with enabled optional fields
+ this.field.skip = false;
// refresh view
this._refresh();
diff -r c7d09076b630f1ea42fc62e3e4c2dae5332b6892 -r 45f1c89fc887e1bbb48a18ebfac918cd1bc62cba client/galaxy/scripts/mvc/tools/tools-jobs.js
--- a/client/galaxy/scripts/mvc/tools/tools-jobs.js
+++ b/client/galaxy/scripts/mvc/tools/tools-jobs.js
@@ -108,15 +108,21 @@
var input_id = this.app.tree.match(job_input_id);
var input_field = this.app.field_list[input_id];
var input_def = this.app.input_list[input_id];
-
- // check basic field validation
- if (input_def && input_field && input_field.validate && !input_field.validate()) {
+
+ // check if objects where properly identified
+ if (!input_id || !input_def || !input_field) {
+ console.debug('tools-jobs::_validation - Retrieving input objects failed.');
+ continue;
+ }
+
+ // validate non-optional fields
+ if (!input_def.optional && input_field.validate && !input_field.validate()) {
this._foundError(input_id);
return false;
}
// check if input field is in batch mode
- if (input_value.batch) {
+ if (input_value && input_value.batch) {
// get values
var n = input_value.values.length;
@@ -148,7 +154,6 @@
}
}
}
-
}
// return validation result
diff -r c7d09076b630f1ea42fc62e3e4c2dae5332b6892 -r 45f1c89fc887e1bbb48a18ebfac918cd1bc62cba 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
@@ -334,6 +334,7 @@
// genome field
case 'genomebuild':
+ input_def.searchable = true;
field = this._fieldSelect(input_def);
break;
@@ -406,10 +407,11 @@
// select field
var self = this;
return new SelectClass.View({
- id : 'field-' + input_def.id,
- data : options,
- multiple: input_def.multiple,
- onchange: function() {
+ id : 'field-' + input_def.id,
+ data : options,
+ multiple : input_def.multiple,
+ searchable : input_def.searchable,
+ onchange : function() {
self.app.refresh();
}
});
diff -r c7d09076b630f1ea42fc62e3e4c2dae5332b6892 -r 45f1c89fc887e1bbb48a18ebfac918cd1bc62cba 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
@@ -98,8 +98,11 @@
break;
// handle conditionals
case 'conditional':
- // get conditional value
+ // get and patch conditional value
var value = self.app.field_list[input.id].value();
+ if (patch[input.test_param.type]) {
+ value = patch[input.test_param.type](value);
+ }
// add conditional value
add (job_input_id + '|' + input.test_param.name, input.id, value);
@@ -114,10 +117,8 @@
// get field
var field = self.app.field_list[input.id];
- // get value
+ // get and patch field value
var value = field.value();
-
- // patch value
if (patch[input.type]) {
value = patch[input.type](value);
}
diff -r c7d09076b630f1ea42fc62e3e4c2dae5332b6892 -r 45f1c89fc887e1bbb48a18ebfac918cd1bc62cba client/galaxy/scripts/mvc/ui/ui-options.js
--- a/client/galaxy/scripts/mvc/ui/ui-options.js
+++ b/client/galaxy/scripts/mvc/ui/ui-options.js
@@ -19,7 +19,7 @@
this.options = Utils.merge(options, this.optionsDefault);
// create new element
- this.setElement('<div style="display: inline-block;"/>');
+ this.setElement('<div/>');
// create elements
this.$message = $('<div/>');
diff -r c7d09076b630f1ea42fc62e3e4c2dae5332b6892 -r 45f1c89fc887e1bbb48a18ebfac918cd1bc62cba client/galaxy/scripts/mvc/ui/ui-select-default.js
--- a/client/galaxy/scripts/mvc/ui/ui-select-default.js
+++ b/client/galaxy/scripts/mvc/ui/ui-select-default.js
@@ -12,7 +12,8 @@
empty : 'No data available',
visible : true,
wait : false,
- multiple : false
+ multiple : false,
+ searchable : false
},
// initialize
@@ -24,8 +25,9 @@
this.setElement(this._template(this.options));
// link elements
- this.$select = this.$el.find('#select');
- this.$icon = this.$el.find('#icon');
+ this.$select = this.$el.find('.select');
+ this.$icon = this.$el.find('.icon');
+ this.$button = this.$el.find('.button');
// configure multiple
if (this.options.multiple) {
@@ -109,7 +111,7 @@
show: function() {
this.unwait();
this.$select.show();
- this.$el.css('display', 'inline-block');
+ this.$el.show();
},
/** Hide the select field
@@ -179,7 +181,7 @@
// remove all options
this.$select.find('option').remove();
-
+
// add new options
for (var key in options) {
this.$select.append(this._templateOption(options[key]));
@@ -195,6 +197,13 @@
if (!this.$select.val()) {
this.$select.val(this.first());
}
+
+ // update to searchable field (in this case select2)
+ if (this.options.searchable) {
+ this.$button.hide();
+ this.$select.select2('destroy');
+ this.$select.select2();
+ }
},
/** Set the custom onchange callback function
@@ -249,7 +258,7 @@
return '<div id="' + options.id + '">' +
'<select id="select" class="select ' + options.cls + ' ' + options.id + '"></select>' +
'<div class="button">' +
- '<i id="icon"/>' +
+ '<i class="icon"/>' +
'</div>' +
'</div>';
}
diff -r c7d09076b630f1ea42fc62e3e4c2dae5332b6892 -r 45f1c89fc887e1bbb48a18ebfac918cd1bc62cba lib/galaxy/tools/parameters/basic.py
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -1082,9 +1082,12 @@
value = option[1]
d.update({
- 'options': options,
- 'value': value
+ 'options' : options,
+ 'value' : value,
+ 'display' : self.display,
+ 'multiple' : self.multiple
})
+
return d
def _get_dbkey_names( self, trans=None ):
diff -r c7d09076b630f1ea42fc62e3e4c2dae5332b6892 -r 45f1c89fc887e1bbb48a18ebfac918cd1bc62cba static/scripts/mvc/tools/tools-form.js
--- a/static/scripts/mvc/tools/tools-form.js
+++ b/static/scripts/mvc/tools/tools-form.js
@@ -84,14 +84,12 @@
// refreshes input states i.e. for dynamic parameters
refresh: function() {
// only refresh the state if the form contains dynamic parameters
- if (!this.is_dynamic) {
- return;
- }
-
- // place refresh process into deferred queue
- var self = this;
- this.deferred.reset();
- this.deferred.execute(function(){self._updateModel()});
+ // by using/reseting the deferred ajax queue the number of redundant calls is reduced
+ if (this.is_dynamic) {
+ var self = this;
+ this.deferred.reset();
+ this.deferred.execute(function(){self._updateModel()});
+ };
},
// build tool model through api call
@@ -141,10 +139,8 @@
// request a new model and update the form inputs
_updateModel: function() {
- // link this
+ // create the request dictionary
var self = this;
-
- // finalize data
var current_state = this.tree.finalize({
data : function(dict) {
if (dict.values.length > 0 && dict.values[0] && dict.values[0].src === 'hda') {
@@ -332,8 +328,9 @@
// create portlet
this.portlet = new Portlet.View({
- icon : 'fa-wrench',
- title: '<b>' + this.model.name + '</b> ' + this.model.description,
+ icon : 'fa-wrench',
+ title : '<b>' + this.model.name + '</b> ' + this.model.description,
+ cls : 'ui-portlet-slim',
operations: {
menu : menu
},
diff -r c7d09076b630f1ea42fc62e3e4c2dae5332b6892 -r 45f1c89fc887e1bbb48a18ebfac918cd1bc62cba static/scripts/mvc/tools/tools-input.js
--- a/static/scripts/mvc/tools/tools-input.js
+++ b/static/scripts/mvc/tools/tools-input.js
@@ -25,12 +25,8 @@
// add field element
this.$field.prepend(this.field.$el);
- // hide optional field on initialization
- if (options.optional) {
- this.field.skip = true;
- } else {
- this.field.skip = false;
- }
+ // start with enabled optional fields
+ this.field.skip = false;
// refresh view
this._refresh();
diff -r c7d09076b630f1ea42fc62e3e4c2dae5332b6892 -r 45f1c89fc887e1bbb48a18ebfac918cd1bc62cba static/scripts/mvc/tools/tools-jobs.js
--- a/static/scripts/mvc/tools/tools-jobs.js
+++ b/static/scripts/mvc/tools/tools-jobs.js
@@ -108,15 +108,21 @@
var input_id = this.app.tree.match(job_input_id);
var input_field = this.app.field_list[input_id];
var input_def = this.app.input_list[input_id];
-
- // check basic field validation
- if (input_def && input_field && input_field.validate && !input_field.validate()) {
+
+ // check if objects where properly identified
+ if (!input_id || !input_def || !input_field) {
+ console.debug('tools-jobs::_validation - Retrieving input objects failed.');
+ continue;
+ }
+
+ // validate non-optional fields
+ if (!input_def.optional && input_field.validate && !input_field.validate()) {
this._foundError(input_id);
return false;
}
// check if input field is in batch mode
- if (input_value.batch) {
+ if (input_value && input_value.batch) {
// get values
var n = input_value.values.length;
@@ -148,7 +154,6 @@
}
}
}
-
}
// return validation result
diff -r c7d09076b630f1ea42fc62e3e4c2dae5332b6892 -r 45f1c89fc887e1bbb48a18ebfac918cd1bc62cba static/scripts/mvc/tools/tools-section.js
--- a/static/scripts/mvc/tools/tools-section.js
+++ b/static/scripts/mvc/tools/tools-section.js
@@ -334,6 +334,7 @@
// genome field
case 'genomebuild':
+ input_def.searchable = true;
field = this._fieldSelect(input_def);
break;
@@ -406,10 +407,11 @@
// select field
var self = this;
return new SelectClass.View({
- id : 'field-' + input_def.id,
- data : options,
- multiple: input_def.multiple,
- onchange: function() {
+ id : 'field-' + input_def.id,
+ data : options,
+ multiple : input_def.multiple,
+ searchable : input_def.searchable,
+ onchange : function() {
self.app.refresh();
}
});
diff -r c7d09076b630f1ea42fc62e3e4c2dae5332b6892 -r 45f1c89fc887e1bbb48a18ebfac918cd1bc62cba static/scripts/mvc/tools/tools-tree.js
--- a/static/scripts/mvc/tools/tools-tree.js
+++ b/static/scripts/mvc/tools/tools-tree.js
@@ -98,8 +98,11 @@
break;
// handle conditionals
case 'conditional':
- // get conditional value
+ // get and patch conditional value
var value = self.app.field_list[input.id].value();
+ if (patch[input.test_param.type]) {
+ value = patch[input.test_param.type](value);
+ }
// add conditional value
add (job_input_id + '|' + input.test_param.name, input.id, value);
@@ -114,10 +117,8 @@
// get field
var field = self.app.field_list[input.id];
- // get value
+ // get and patch field value
var value = field.value();
-
- // patch value
if (patch[input.type]) {
value = patch[input.type](value);
}
diff -r c7d09076b630f1ea42fc62e3e4c2dae5332b6892 -r 45f1c89fc887e1bbb48a18ebfac918cd1bc62cba static/scripts/mvc/ui/ui-options.js
--- a/static/scripts/mvc/ui/ui-options.js
+++ b/static/scripts/mvc/ui/ui-options.js
@@ -19,7 +19,7 @@
this.options = Utils.merge(options, this.optionsDefault);
// create new element
- this.setElement('<div style="display: inline-block;"/>');
+ this.setElement('<div/>');
// create elements
this.$message = $('<div/>');
diff -r c7d09076b630f1ea42fc62e3e4c2dae5332b6892 -r 45f1c89fc887e1bbb48a18ebfac918cd1bc62cba static/scripts/mvc/ui/ui-select-default.js
--- a/static/scripts/mvc/ui/ui-select-default.js
+++ b/static/scripts/mvc/ui/ui-select-default.js
@@ -12,7 +12,8 @@
empty : 'No data available',
visible : true,
wait : false,
- multiple : false
+ multiple : false,
+ searchable : false
},
// initialize
@@ -24,8 +25,9 @@
this.setElement(this._template(this.options));
// link elements
- this.$select = this.$el.find('#select');
- this.$icon = this.$el.find('#icon');
+ this.$select = this.$el.find('.select');
+ this.$icon = this.$el.find('.icon');
+ this.$button = this.$el.find('.button');
// configure multiple
if (this.options.multiple) {
@@ -109,7 +111,7 @@
show: function() {
this.unwait();
this.$select.show();
- this.$el.css('display', 'inline-block');
+ this.$el.show();
},
/** Hide the select field
@@ -179,7 +181,7 @@
// remove all options
this.$select.find('option').remove();
-
+
// add new options
for (var key in options) {
this.$select.append(this._templateOption(options[key]));
@@ -195,6 +197,13 @@
if (!this.$select.val()) {
this.$select.val(this.first());
}
+
+ // update to searchable field (in this case select2)
+ if (this.options.searchable) {
+ this.$button.hide();
+ this.$select.select2('destroy');
+ this.$select.select2();
+ }
},
/** Set the custom onchange callback function
@@ -249,7 +258,7 @@
return '<div id="' + options.id + '">' +
'<select id="select" class="select ' + options.cls + ' ' + options.id + '"></select>' +
'<div class="button">' +
- '<i id="icon"/>' +
+ '<i class="icon"/>' +
'</div>' +
'</div>';
}
diff -r c7d09076b630f1ea42fc62e3e4c2dae5332b6892 -r 45f1c89fc887e1bbb48a18ebfac918cd1bc62cba static/scripts/packed/mvc/tools/tools-form.js
--- a/static/scripts/packed/mvc/tools/tools-form.js
+++ b/static/scripts/packed/mvc/tools/tools-form.js
@@ -1,1 +1,1 @@
-define(["utils/utils","utils/deferred","mvc/ui/ui-portlet","mvc/ui/ui-misc","mvc/citation/citation-model","mvc/citation/citation-view","mvc/tools","mvc/tools/tools-template","mvc/tools/tools-content","mvc/tools/tools-section","mvc/tools/tools-tree","mvc/tools/tools-jobs"],function(i,j,h,m,k,a,e,d,f,l,c,g){var b=Backbone.View.extend({container:"body",initialize:function(o){console.debug(o);var n=this;var p=parent.Galaxy;if(p&&p.modal){this.modal=p.modal}else{this.modal=new m.Modal.View()}if(p&&p.currUser){this.is_admin=p.currUser.get("is_admin")}else{this.is_admin=false}this.options=o;this.deferred=new j();this.setElement("<div/>");$(this.container).append(this.$el);this.tree=new c(this);this.job_handler=new g(this);this.content=new f(this);this._buildForm(o)},message:function(n){$(this.container).empty();$(this.container).append(n)},reset:function(){for(var n in this.element_list){this.element_list[n].reset()}},rebuild:function(){this.tree.refresh();console.debug("tools-form::rebuild() - Rebuilding data structures.")},refresh:function(){if(!this.is_dynamic){return}var n=this;this.deferred.reset();this.deferred.execute(function(){n._updateModel()})},_buildModel:function(){var n=this;var o=galaxy_config.root+"api/tools/"+this.options.id+"/build?";if(this.options.job_id){o+="job_id="+this.options.job_id}else{if(this.options.dataset_id){o+="dataset_id="+this.options.dataset_id}else{var p=top.location.href;var q=p.indexOf("?");if(p.indexOf("tool_id=")!=-1&&q!==-1){o+=p.slice(q+1)}}}i.request({type:"GET",url:o,success:function(r){n.options=$.extend(n.options,r);n.model=r;n.inputs=r.inputs;console.debug("tools-form::initialize() - Initial tool model ready.");console.debug(r);n._buildForm()},error:function(r){console.debug("tools-form::initialize() - Initial tool model request failed.");console.debug(r)}})},_updateModel:function(){var n=this;var o=this.tree.finalize({data:function(r){if(r.values.length>0&&r.values[0]&&r.values[0].src==="hda"){return n.content.get({id:r.values[0].id,src:"hda"}).id_uncoded}return null}});console.debug("tools-form::_refreshForm() - Refreshing states.");console.debug(o);function q(u){for(var s in n.input_list){var t=n.field_list[s];var r=n.input_list[s];if(r.is_dynamic&&t.wait&&t.unwait){if(u){t.wait()}else{t.unwait()}}}}q(true);var p=this.deferred.register();i.request({type:"GET",url:galaxy_config.root+"api/tools/"+this.options.id+"/build",data:o,success:function(r){n._updateForm(r);q(false);n.deferred.done(p);console.debug("tools-form::_refreshForm() - States refreshed.");console.debug(r)},error:function(r){n.deferred.done(p);console.debug("tools-form::_refreshForm() - Refresh request failed.");console.debug(r)}})},_updateForm:function(n){var o=this;this.tree.matchModel(n,function(q,u){var p=o.input_list[q];if(p&&p.options){if(JSON.stringify(p.options)!=JSON.stringify(u.options)){p.options=u.options;var v=o.field_list[q];if(v.update){var t=[];switch(p.type){case"data":t=p.options;break;default:for(var s in u.options){var r=u.options[s];if(r.length>2){t.push({label:r[0],value:r[1]})}}}v.update(t);v.trigger("change");console.debug("Updating options for "+q)}}}})},_buildForm:function(p){var o=this;this.field_list={};this.input_list={};this.element_list={};this.model=p;this.inputs=p.inputs;var s=new m.ButtonMenu({icon:"fa-gear",tooltip:"Click to see a list of options."});if(p.biostar_url){s.addMenu({icon:"fa-question-circle",title:"Question?",tooltip:"Ask a question about this tool (Biostar)",onclick:function(){window.open(o.options.biostar_url+"/p/new/post/")}});s.addMenu({icon:"fa-search",title:"Search",tooltip:"Search help for this tool (Biostar)",onclick:function(){window.open(o.options.biostar_url+"/t/"+o.options.id+"/")}})}s.addMenu({icon:"fa-share",title:"Share",tooltip:"Share this tool",onclick:function(){prompt("Copy to clipboard: Ctrl+C, Enter",window.location.origin+galaxy_config.root+"root?tool_id="+o.options.id)}});if(this.is_admin){s.addMenu({icon:"fa-download",title:"Download",tooltip:"Download this tool",onclick:function(){window.location.href=galaxy_config.root+"api/tools/"+o.options.id+"/download"}})}this.section=new l.View(o,{inputs:this.inputs,cls:"ui-table-plain"});if(this.incompatible){this.$el.hide();$("#tool-form-classic").show();return}this.portlet=new h.View({icon:"fa-wrench",title:"<b>"+this.model.name+"</b> "+this.model.description,operations:{menu:s},buttons:{execute:new m.Button({icon:"fa-check",tooltip:"Execute the tool",title:"Execute",cls:"btn btn-primary",floating:"clear",onclick:function(){o.job_handler.submit()}})}});this.$el.empty();this.$el.append(this.portlet.$el);if(p.help!=""){this.$el.append(d.help(p.help))}if(p.citations){var r=$("<div/>");var n=new k.ToolCitationCollection();n.tool_id=p.id;var q=new a.CitationListView({el:r,collection:n});q.render();n.fetch();this.$el.append(r)}this.portlet.append(this.section.$el);this.rebuild()}});return{View:b}});
\ No newline at end of file
+define(["utils/utils","utils/deferred","mvc/ui/ui-portlet","mvc/ui/ui-misc","mvc/citation/citation-model","mvc/citation/citation-view","mvc/tools","mvc/tools/tools-template","mvc/tools/tools-content","mvc/tools/tools-section","mvc/tools/tools-tree","mvc/tools/tools-jobs"],function(i,j,h,m,k,a,e,d,f,l,c,g){var b=Backbone.View.extend({container:"body",initialize:function(o){console.debug(o);var n=this;var p=parent.Galaxy;if(p&&p.modal){this.modal=p.modal}else{this.modal=new m.Modal.View()}if(p&&p.currUser){this.is_admin=p.currUser.get("is_admin")}else{this.is_admin=false}this.options=o;this.deferred=new j();this.setElement("<div/>");$(this.container).append(this.$el);this.tree=new c(this);this.job_handler=new g(this);this.content=new f(this);this._buildForm(o)},message:function(n){$(this.container).empty();$(this.container).append(n)},reset:function(){for(var n in this.element_list){this.element_list[n].reset()}},rebuild:function(){this.tree.refresh();console.debug("tools-form::rebuild() - Rebuilding data structures.")},refresh:function(){if(this.is_dynamic){var n=this;this.deferred.reset();this.deferred.execute(function(){n._updateModel()})}},_buildModel:function(){var n=this;var o=galaxy_config.root+"api/tools/"+this.options.id+"/build?";if(this.options.job_id){o+="job_id="+this.options.job_id}else{if(this.options.dataset_id){o+="dataset_id="+this.options.dataset_id}else{var p=top.location.href;var q=p.indexOf("?");if(p.indexOf("tool_id=")!=-1&&q!==-1){o+=p.slice(q+1)}}}i.request({type:"GET",url:o,success:function(r){n.options=$.extend(n.options,r);n.model=r;n.inputs=r.inputs;console.debug("tools-form::initialize() - Initial tool model ready.");console.debug(r);n._buildForm()},error:function(r){console.debug("tools-form::initialize() - Initial tool model request failed.");console.debug(r)}})},_updateModel:function(){var n=this;var o=this.tree.finalize({data:function(r){if(r.values.length>0&&r.values[0]&&r.values[0].src==="hda"){return n.content.get({id:r.values[0].id,src:"hda"}).id_uncoded}return null}});console.debug("tools-form::_refreshForm() - Refreshing states.");console.debug(o);function q(u){for(var s in n.input_list){var t=n.field_list[s];var r=n.input_list[s];if(r.is_dynamic&&t.wait&&t.unwait){if(u){t.wait()}else{t.unwait()}}}}q(true);var p=this.deferred.register();i.request({type:"GET",url:galaxy_config.root+"api/tools/"+this.options.id+"/build",data:o,success:function(r){n._updateForm(r);q(false);n.deferred.done(p);console.debug("tools-form::_refreshForm() - States refreshed.");console.debug(r)},error:function(r){n.deferred.done(p);console.debug("tools-form::_refreshForm() - Refresh request failed.");console.debug(r)}})},_updateForm:function(n){var o=this;this.tree.matchModel(n,function(q,u){var p=o.input_list[q];if(p&&p.options){if(JSON.stringify(p.options)!=JSON.stringify(u.options)){p.options=u.options;var v=o.field_list[q];if(v.update){var t=[];switch(p.type){case"data":t=p.options;break;default:for(var s in u.options){var r=u.options[s];if(r.length>2){t.push({label:r[0],value:r[1]})}}}v.update(t);v.trigger("change");console.debug("Updating options for "+q)}}}})},_buildForm:function(p){var o=this;this.field_list={};this.input_list={};this.element_list={};this.model=p;this.inputs=p.inputs;var s=new m.ButtonMenu({icon:"fa-gear",tooltip:"Click to see a list of options."});if(p.biostar_url){s.addMenu({icon:"fa-question-circle",title:"Question?",tooltip:"Ask a question about this tool (Biostar)",onclick:function(){window.open(o.options.biostar_url+"/p/new/post/")}});s.addMenu({icon:"fa-search",title:"Search",tooltip:"Search help for this tool (Biostar)",onclick:function(){window.open(o.options.biostar_url+"/t/"+o.options.id+"/")}})}s.addMenu({icon:"fa-share",title:"Share",tooltip:"Share this tool",onclick:function(){prompt("Copy to clipboard: Ctrl+C, Enter",window.location.origin+galaxy_config.root+"root?tool_id="+o.options.id)}});if(this.is_admin){s.addMenu({icon:"fa-download",title:"Download",tooltip:"Download this tool",onclick:function(){window.location.href=galaxy_config.root+"api/tools/"+o.options.id+"/download"}})}this.section=new l.View(o,{inputs:this.inputs,cls:"ui-table-plain"});if(this.incompatible){this.$el.hide();$("#tool-form-classic").show();return}this.portlet=new h.View({icon:"fa-wrench",title:"<b>"+this.model.name+"</b> "+this.model.description,cls:"ui-portlet-slim",operations:{menu:s},buttons:{execute:new m.Button({icon:"fa-check",tooltip:"Execute the tool",title:"Execute",cls:"btn btn-primary",floating:"clear",onclick:function(){o.job_handler.submit()}})}});this.$el.empty();this.$el.append(this.portlet.$el);if(p.help!=""){this.$el.append(d.help(p.help))}if(p.citations){var r=$("<div/>");var n=new k.ToolCitationCollection();n.tool_id=p.id;var q=new a.CitationListView({el:r,collection:n});q.render();n.fetch();this.$el.append(r)}this.portlet.append(this.section.$el);this.rebuild()}});return{View:b}});
\ No newline at end of file
diff -r c7d09076b630f1ea42fc62e3e4c2dae5332b6892 -r 45f1c89fc887e1bbb48a18ebfac918cd1bc62cba 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(c,b){this.app=c;this.field=b.field;this.setElement(this._template(b));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);if(b.optional){this.field.skip=true}else{this.field.skip=false}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.fadeIn();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("Disable");this.app.refresh()}else{this.$field.hide();this.$title_optional.html("Enable")}},_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+="Optional: "+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(c,b){this.app=c;this.field=b.field;this.setElement(this._template(b));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;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.fadeIn();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("Disable");this.app.refresh()}else{this.$field.hide();this.$title_optional.html("Enable")}},_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+="Optional: "+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
diff -r c7d09076b630f1ea42fc62e3e4c2dae5332b6892 -r 45f1c89fc887e1bbb48a18ebfac918cd1bc62cba static/scripts/packed/mvc/tools/tools-jobs.js
--- a/static/scripts/packed/mvc/tools/tools-jobs.js
+++ b/static/scripts/packed/mvc/tools/tools-jobs.js
@@ -1,1 +1,1 @@
-define(["utils/utils","mvc/tools/tools-template"],function(b,a){return Backbone.Model.extend({initialize:function(d,c){this.app=d;this.options=b.merge(c,this.optionsDefault)},submit:function(){var c=this;var d={tool_id:this.app.options.id,inputs:this.app.tree.finalize()};this.app.reset();if(!this._validation(d)){console.debug("tools-jobs::submit - Submission canceled. Validation failed.");return}console.debug(d);this.app.modal.show({title:"Please wait...",body:"progress",closing_events:true,buttons:{Close:function(){c.app.modal.hide()}}});b.request({type:"POST",url:galaxy_config.root+"api/tools",data:d,success:function(e){c.app.modal.hide();c.app.message(a.success(e));c._refreshHdas()},error:function(e,g){c.app.modal.hide();if(e&&e.message&&e.message.data){var h=c.app.tree.matchResponse(e.message.data);for(var f in h){c._foundError(f,h[f]);break}}else{console.debug(e);c.app.modal.show({title:"Job submission failed",body:a.error(d),buttons:{Close:function(){c.app.modal.hide()}}})}}})},_foundError:function(c,d){var e=this.app.element_list[c];e.error(d||"Please verify this parameter.");$(this.app.container).animate({scrollTop:e.$el.offset().top-20},500)},_validation:function(h){var d=h.inputs;var m=-1;var i=null;for(var k in d){var f=d[k];var l=this.app.tree.match(k);var e=this.app.field_list[l];var j=this.app.input_list[l];if(j&&e&&e.validate&&!e.validate()){this._foundError(l);return false}if(f.batch){var g=f.values.length;var c=null;if(g>0){c=f.values[0]&&f.values[0].src}if(c){if(i===null){i=c}else{if(i!==c){this._foundError(l,"Please select either dataset or dataset list fields for all batch mode fields.");return false}}}if(m===-1){m=g}else{if(m!==g){this._foundError(l,"Please make sure that you select the same number of inputs for all batch mode fields. This field contains <b>"+g+"</b> selection(s) while a previous field contains <b>"+m+"</b>.");return false}}}}return true},_refreshHdas:function(){if(parent.Galaxy&&parent.Galaxy.currHistoryPanel){parent.Galaxy.currHistoryPanel.refreshContents()}}})});
\ No newline at end of file
+define(["utils/utils","mvc/tools/tools-template"],function(b,a){return Backbone.Model.extend({initialize:function(d,c){this.app=d;this.options=b.merge(c,this.optionsDefault)},submit:function(){var c=this;var d={tool_id:this.app.options.id,inputs:this.app.tree.finalize()};this.app.reset();if(!this._validation(d)){console.debug("tools-jobs::submit - Submission canceled. Validation failed.");return}console.debug(d);this.app.modal.show({title:"Please wait...",body:"progress",closing_events:true,buttons:{Close:function(){c.app.modal.hide()}}});b.request({type:"POST",url:galaxy_config.root+"api/tools",data:d,success:function(e){c.app.modal.hide();c.app.message(a.success(e));c._refreshHdas()},error:function(e,g){c.app.modal.hide();if(e&&e.message&&e.message.data){var h=c.app.tree.matchResponse(e.message.data);for(var f in h){c._foundError(f,h[f]);break}}else{console.debug(e);c.app.modal.show({title:"Job submission failed",body:a.error(d),buttons:{Close:function(){c.app.modal.hide()}}})}}})},_foundError:function(c,d){var e=this.app.element_list[c];e.error(d||"Please verify this parameter.");$(this.app.container).animate({scrollTop:e.$el.offset().top-20},500)},_validation:function(h){var d=h.inputs;var m=-1;var i=null;for(var k in d){var f=d[k];var l=this.app.tree.match(k);var e=this.app.field_list[l];var j=this.app.input_list[l];if(!l||!j||!e){console.debug("tools-jobs::_validation - Retrieving input objects failed.");continue}if(!j.optional&&e.validate&&!e.validate()){this._foundError(l);return false}if(f&&f.batch){var g=f.values.length;var c=null;if(g>0){c=f.values[0]&&f.values[0].src}if(c){if(i===null){i=c}else{if(i!==c){this._foundError(l,"Please select either dataset or dataset list fields for all batch mode fields.");return false}}}if(m===-1){m=g}else{if(m!==g){this._foundError(l,"Please make sure that you select the same number of inputs for all batch mode fields. This field contains <b>"+g+"</b> selection(s) while a previous field contains <b>"+m+"</b>.");return false}}}}return true},_refreshHdas:function(){if(parent.Galaxy&&parent.Galaxy.currHistoryPanel){parent.Galaxy.currHistoryPanel.refreshContents()}}})});
\ No newline at end of file
diff -r c7d09076b630f1ea42fc62e3e4c2dae5332b6892 -r 45f1c89fc887e1bbb48a18ebfac918cd1bc62cba 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/tools/tools-repeat","mvc/tools/tools-select-content","mvc/tools/tools-input"],function(d,b,g,c,a,e){var f=Backbone.View.extend({initialize:function(i,h){this.app=i;this.inputs=h.inputs;h.cls_tr="section-row";this.table=new b.View(h);this.setElement(this.table.$el);this.render()},render:function(){this.table.delAll();for(var h in this.inputs){this._add(this.inputs[h])}},_add:function(j){var i=this;var h=jQuery.extend(true,{},j);h.id=j.id=d.uuid();this.app.input_list[h.id]=h;var k=h.type;switch(k){case"conditional":this._addConditional(h);break;case"repeat":this._addRepeat(h);break;default:this._addRow(h)}},_addConditional:function(h){var j=this;h.test_param.id=h.id;var m=this._addRow(h.test_param);m.options.onchange=function(t){var p=j.app.tree.matchCase(h,t);for(var r in h.cases){var w=h.cases[r];var u=h.id+"-section-"+r;var o=j.table.get(u);var v=false;for(var q in w.inputs){var s=w.inputs[q].type;if(s&&s!=="hidden"){v=true;break}}if(r==p&&v){o.fadeIn("fast")}else{o.hide()}}j.app.refresh()};for(var l in h.cases){var k=h.id+"-section-"+l;var n=new f(this.app,{inputs:h.cases[l].inputs,cls:"ui-table-plain"});n.$el.addClass("ui-table-form-section");this.table.add(n.$el);this.table.append(k)}m.trigger("change")},_addRepeat:function(o){var r=this;var p=0;function m(i,t){var s=o.id+"-section-"+(p++);var u=null;if(t){u=function(){k.del(s);k.retitle(o.title);r.app.rebuild();r.app.refresh()}}var v=new f(r.app,{inputs:i,cls:"ui-table-plain"});k.add({id:s,title:o.title,$el:v.$el,ondel:u});k.retitle(o.title)}var k=new c.View({title_new:o.title,max:o.max,onnew:function(){m(o.inputs,true);r.app.rebuild();r.app.refresh()}});var h=o.min;var q=_.size(o.cache);for(var l=0;l<Math.max(q,h);l++){var n=null;if(l<q){n=o.cache[l]}else{n=o.inputs}m(n,l>=h)}var j=new e(this.app,{label:o.title,help:o.help,field:k});j.$el.addClass("ui-table-form-section");this.table.add(j.$el);this.table.append(o.id)},_addRow:function(h){var k=h.id;var i=this._createField(h);if(h.is_dynamic){this.app.is_dynamic=true}this.app.field_list[k]=i;var j=new e(this.app,{label:h.label,optional:h.optional,help:h.help,field:i});this.app.element_list[k]=j;this.table.add(j.$el);this.table.append(k);return i},_createField:function(h){var i=null;switch(h.type){case"text":i=this._fieldText(h);break;case"select":i=this._fieldSelect(h);break;case"data":i=this._fieldData(h);break;case"data_column":i=this._fieldSelect(h);break;case"hidden":i=this._fieldHidden(h);break;case"integer":i=this._fieldSlider(h);break;case"float":i=this._fieldSlider(h);break;case"boolean":i=this._fieldBoolean(h);break;case"genomebuild":i=this._fieldSelect(h);break;default:this.app.incompatible=true;if(h.options){i=this._fieldSelect(h)}else{i=this._fieldText(h)}console.debug("tools-form::_addRow() : Auto matched field type ("+h.type+").")}if(h.value!==undefined){i.value(h.value)}return i},_fieldData:function(h){var i=this;return new a.View(this.app,{id:"field-"+h.id,extensions:h.extensions,multiple:h.multiple,data:h.options,onchange:function(){i.app.refresh()}})},_fieldSelect:function(h){var k=[];for(var l in h.options){var m=h.options[l];k.push({label:m[0],value:m[1]})}var n=g.Select;switch(h.display){case"checkboxes":n=g.Checkbox;break;case"radio":n=g.Radio;break}var j=this;return new n.View({id:"field-"+h.id,data:k,multiple:h.multiple,onchange:function(){j.app.refresh()}})},_fieldText:function(h){var i=this;return new g.Input({id:"field-"+h.id,area:h.area,onchange:function(){i.app.refresh()}})},_fieldSlider:function(h){return new g.Slider.View({id:"field-"+h.id,precise:h.type=="float",min:h.min,max:h.max})},_fieldHidden:function(h){return new g.Hidden({id:"field-"+h.id})},_fieldBoolean:function(h){return new g.RadioButton.View({id:"field-"+h.id,data:[{label:"Yes",value:"true"},{label:"No",value:"false"}]})}});return{View:f}});
\ No newline at end of file
+define(["utils/utils","mvc/ui/ui-table","mvc/ui/ui-misc","mvc/tools/tools-repeat","mvc/tools/tools-select-content","mvc/tools/tools-input"],function(d,b,g,c,a,e){var f=Backbone.View.extend({initialize:function(i,h){this.app=i;this.inputs=h.inputs;h.cls_tr="section-row";this.table=new b.View(h);this.setElement(this.table.$el);this.render()},render:function(){this.table.delAll();for(var h in this.inputs){this._add(this.inputs[h])}},_add:function(j){var i=this;var h=jQuery.extend(true,{},j);h.id=j.id=d.uuid();this.app.input_list[h.id]=h;var k=h.type;switch(k){case"conditional":this._addConditional(h);break;case"repeat":this._addRepeat(h);break;default:this._addRow(h)}},_addConditional:function(h){var j=this;h.test_param.id=h.id;var m=this._addRow(h.test_param);m.options.onchange=function(t){var p=j.app.tree.matchCase(h,t);for(var r in h.cases){var w=h.cases[r];var u=h.id+"-section-"+r;var o=j.table.get(u);var v=false;for(var q in w.inputs){var s=w.inputs[q].type;if(s&&s!=="hidden"){v=true;break}}if(r==p&&v){o.fadeIn("fast")}else{o.hide()}}j.app.refresh()};for(var l in h.cases){var k=h.id+"-section-"+l;var n=new f(this.app,{inputs:h.cases[l].inputs,cls:"ui-table-plain"});n.$el.addClass("ui-table-form-section");this.table.add(n.$el);this.table.append(k)}m.trigger("change")},_addRepeat:function(o){var r=this;var p=0;function m(i,t){var s=o.id+"-section-"+(p++);var u=null;if(t){u=function(){k.del(s);k.retitle(o.title);r.app.rebuild();r.app.refresh()}}var v=new f(r.app,{inputs:i,cls:"ui-table-plain"});k.add({id:s,title:o.title,$el:v.$el,ondel:u});k.retitle(o.title)}var k=new c.View({title_new:o.title,max:o.max,onnew:function(){m(o.inputs,true);r.app.rebuild();r.app.refresh()}});var h=o.min;var q=_.size(o.cache);for(var l=0;l<Math.max(q,h);l++){var n=null;if(l<q){n=o.cache[l]}else{n=o.inputs}m(n,l>=h)}var j=new e(this.app,{label:o.title,help:o.help,field:k});j.$el.addClass("ui-table-form-section");this.table.add(j.$el);this.table.append(o.id)},_addRow:function(h){var k=h.id;var i=this._createField(h);if(h.is_dynamic){this.app.is_dynamic=true}this.app.field_list[k]=i;var j=new e(this.app,{label:h.label,optional:h.optional,help:h.help,field:i});this.app.element_list[k]=j;this.table.add(j.$el);this.table.append(k);return i},_createField:function(h){var i=null;switch(h.type){case"text":i=this._fieldText(h);break;case"select":i=this._fieldSelect(h);break;case"data":i=this._fieldData(h);break;case"data_column":i=this._fieldSelect(h);break;case"hidden":i=this._fieldHidden(h);break;case"integer":i=this._fieldSlider(h);break;case"float":i=this._fieldSlider(h);break;case"boolean":i=this._fieldBoolean(h);break;case"genomebuild":h.searchable=true;i=this._fieldSelect(h);break;default:this.app.incompatible=true;if(h.options){i=this._fieldSelect(h)}else{i=this._fieldText(h)}console.debug("tools-form::_addRow() : Auto matched field type ("+h.type+").")}if(h.value!==undefined){i.value(h.value)}return i},_fieldData:function(h){var i=this;return new a.View(this.app,{id:"field-"+h.id,extensions:h.extensions,multiple:h.multiple,data:h.options,onchange:function(){i.app.refresh()}})},_fieldSelect:function(h){var k=[];for(var l in h.options){var m=h.options[l];k.push({label:m[0],value:m[1]})}var n=g.Select;switch(h.display){case"checkboxes":n=g.Checkbox;break;case"radio":n=g.Radio;break}var j=this;return new n.View({id:"field-"+h.id,data:k,multiple:h.multiple,searchable:h.searchable,onchange:function(){j.app.refresh()}})},_fieldText:function(h){var i=this;return new g.Input({id:"field-"+h.id,area:h.area,onchange:function(){i.app.refresh()}})},_fieldSlider:function(h){return new g.Slider.View({id:"field-"+h.id,precise:h.type=="float",min:h.min,max:h.max})},_fieldHidden:function(h){return new g.Hidden({id:"field-"+h.id})},_fieldBoolean:function(h){return new g.RadioButton.View({id:"field-"+h.id,data:[{label:"Yes",value:"true"},{label:"No",value:"false"}]})}});return{View:f}});
\ No newline at end of file
diff -r c7d09076b630f1ea42fc62e3e4c2dae5332b6892 -r 45f1c89fc887e1bbb48a18ebfac918cd1bc62cba 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([],function(){return Backbone.Model.extend({initialize:function(a){this.app=a},refresh:function(){this.dict={};this.xml=$("<div/>");if(!this.app.section){return{}}this._iterate(this.app.section.$el,this.dict,this.xml)},finalize:function(d){d=d||{};var a=this;this.job_def={};this.job_ids={};function c(g,f,e){a.job_def[g]=e;a.job_ids[g]=f}function b(l,o){for(var j in o){var g=o[j];if(g.input){var q=g.input;var k=l;if(l!=""){k+="|"}k+=q.name;switch(q.type){case"repeat":var f="section-";var t=[];var n=null;for(var s in g){var m=s.indexOf(f);if(m!=-1){m+=f.length;t.push(parseInt(s.substr(m)));if(!n){n=s.substr(0,m)}}}t.sort(function(u,i){return u-i});var j=0;for(var h in t){b(k+"_"+j++,g[n+t[h]])}break;case"conditional":var r=a.app.field_list[q.id].value();c(k+"|"+q.test_param.name,q.id,r);var e=a.matchCase(q,r);if(e!=-1){b(k,o[q.id+"-section-"+e])}break;default:var p=a.app.field_list[q.id];var r=p.value();if(d[q.type]){r=d[q.type](r)}if(!p.skip){c(k,q.id,r)}}}}}b("",this.dict);return this.job_def},match:function(a){return this.job_ids&&this.job_ids[a]},matchCase:function(a,c){if(a.test_param.type=="boolean"){if(c=="true"){c=a.test_param.truevalue||"true"}else{c=a.test_param.falsevalue||"false"}}for(var b in a.cases){if(a.cases[b].value==c){return b}}return -1},matchModel:function(c,e){var a={};var b=this;function d(f,o){for(var l in o){var h=o[l];var m=h.name;if(f!=""){m=f+"|"+m}switch(h.type){case"repeat":for(var k in h.cache){d(m+"_"+k,h.cache[k])}break;case"conditional":var p=h.test_param&&h.test_param.value;var g=b.matchCase(h,p);if(g!=-1){d(m,h.cases[g].inputs)}break;default:var n=b.app.tree.job_ids[m];if(n){e(n,h)}}}}d("",c.inputs);return a},matchResponse:function(c){var a={};var b=this;function d(j,h){if(typeof h==="string"){var f=b.app.tree.job_ids[j];if(f){a[f]=h}}else{for(var g in h){var e=g;if(j!==""){e=j+"|"+e}d(e,h[g])}}}d("",c);return a},references:function(c,e){var g=[];var b=this;function d(h,j){var i=$(j).children();var l=[];var k=false;i.each(function(){var o=this;var n=$(o).attr("id");if(n!==c){var m=b.app.input_list[n];if(m){if(m.name==h){k=true;return false}if(m.data_ref==h&&m.type==e){l.push(n)}}}});if(!k){g=g.concat(l);i.each(function(){d(h,this)})}}var f=this.xml.find("#"+c);if(f.length>0){var a=this.app.input_list[c];if(a){d(a.name,f.parent())}}return g},_iterate:function(d,e,b){var a=this;var c=$(d).children();c.each(function(){var i=this;var h=$(i).attr("id");if($(i).hasClass("section-row")){e[h]={};var f=a.app.input_list[h];if(f){e[h]={input:f}}var g=$('<div id="'+h+'"/>');b.append(g);a._iterate(i,e[h],g)}else{a._iterate(i,e,b)}})}})});
\ No newline at end of file
+define([],function(){return Backbone.Model.extend({initialize:function(a){this.app=a},refresh:function(){this.dict={};this.xml=$("<div/>");if(!this.app.section){return{}}this._iterate(this.app.section.$el,this.dict,this.xml)},finalize:function(d){d=d||{};var a=this;this.job_def={};this.job_ids={};function c(g,f,e){a.job_def[g]=e;a.job_ids[g]=f}function b(l,o){for(var j in o){var g=o[j];if(g.input){var q=g.input;var k=l;if(l!=""){k+="|"}k+=q.name;switch(q.type){case"repeat":var f="section-";var t=[];var n=null;for(var s in g){var m=s.indexOf(f);if(m!=-1){m+=f.length;t.push(parseInt(s.substr(m)));if(!n){n=s.substr(0,m)}}}t.sort(function(u,i){return u-i});var j=0;for(var h in t){b(k+"_"+j++,g[n+t[h]])}break;case"conditional":var r=a.app.field_list[q.id].value();if(d[q.test_param.type]){r=d[q.test_param.type](r)}c(k+"|"+q.test_param.name,q.id,r);var e=a.matchCase(q,r);if(e!=-1){b(k,o[q.id+"-section-"+e])}break;default:var p=a.app.field_list[q.id];var r=p.value();if(d[q.type]){r=d[q.type](r)}if(!p.skip){c(k,q.id,r)}}}}}b("",this.dict);return this.job_def},match:function(a){return this.job_ids&&this.job_ids[a]},matchCase:function(a,c){if(a.test_param.type=="boolean"){if(c=="true"){c=a.test_param.truevalue||"true"}else{c=a.test_param.falsevalue||"false"}}for(var b in a.cases){if(a.cases[b].value==c){return b}}return -1},matchModel:function(c,e){var a={};var b=this;function d(f,o){for(var l in o){var h=o[l];var m=h.name;if(f!=""){m=f+"|"+m}switch(h.type){case"repeat":for(var k in h.cache){d(m+"_"+k,h.cache[k])}break;case"conditional":var p=h.test_param&&h.test_param.value;var g=b.matchCase(h,p);if(g!=-1){d(m,h.cases[g].inputs)}break;default:var n=b.app.tree.job_ids[m];if(n){e(n,h)}}}}d("",c.inputs);return a},matchResponse:function(c){var a={};var b=this;function d(j,h){if(typeof h==="string"){var f=b.app.tree.job_ids[j];if(f){a[f]=h}}else{for(var g in h){var e=g;if(j!==""){e=j+"|"+e}d(e,h[g])}}}d("",c);return a},references:function(c,e){var g=[];var b=this;function d(h,j){var i=$(j).children();var l=[];var k=false;i.each(function(){var o=this;var n=$(o).attr("id");if(n!==c){var m=b.app.input_list[n];if(m){if(m.name==h){k=true;return false}if(m.data_ref==h&&m.type==e){l.push(n)}}}});if(!k){g=g.concat(l);i.each(function(){d(h,this)})}}var f=this.xml.find("#"+c);if(f.length>0){var a=this.app.input_list[c];if(a){d(a.name,f.parent())}}return g},_iterate:function(d,e,b){var a=this;var c=$(d).children();c.each(function(){var i=this;var h=$(i).attr("id");if($(i).hasClass("section-row")){e[h]={};var f=a.app.input_list[h];if(f){e[h]={input:f}}var g=$('<div id="'+h+'"/>');b.append(g);a._iterate(i,e[h],g)}else{a._iterate(i,e,b)}})}})});
\ No newline at end of file
diff -r c7d09076b630f1ea42fc62e3e4c2dae5332b6892 -r 45f1c89fc887e1bbb48a18ebfac918cd1bc62cba static/scripts/packed/mvc/ui/ui-options.js
--- a/static/scripts/packed/mvc/ui/ui-options.js
+++ b/static/scripts/packed/mvc/ui/ui-options.js
@@ -1,1 +1,1 @@
-define(["utils/utils"],function(b){var a=Backbone.View.extend({initialize:function(g){this.optionsDefault={value:[],visible:true,data:[],id:b.uuid(),errorText:"No data available.",waitText:"Please wait..."};this.options=b.merge(g,this.optionsDefault);this.setElement('<div style="display: inline-block;"/>');this.$message=$("<div/>");this.$options=$(this._template(g));this.$el.append(this.$message);this.$el.append(this.$options);if(!this.options.visible){this.$el.hide()}this.update(this.options.data);if(this.options.value){this.value(this.options.value)}var f=this;this.on("change",function(){f._change()})},update:function(g){var j=this._getValue();this.$el.find(".ui-option").remove();for(var h in g){var i=$(this._templateOption(g[h]));i.addClass("ui-option");this.$options.append(i)}var f=this;this.$el.find("input").on("change",function(){f.value(f._getValue());f._change()});this._refresh();this.value(j)},exists:function(g){if(typeof g==="string"){g=[g]}for(var f in g){if(this.$el.find('input[value="'+g[f]+'"]').length>0){return true}}return false},first:function(){var f=this.$el.find("input");if(f.length>0){return f.val()}else{return undefined}},validate:function(){var g=this.value();if(!(g instanceof Array)){g=[g]}for(var f in g){if([null,"null",undefined].indexOf(g[f])>-1){return false}}return true},wait:function(){if(this._size()==0){this._messageShow(this.options.waitText,"info");this.$options.hide()}},unwait:function(){this._messageHide();this._refresh()},_change:function(){if(this.options.onchange){this.options.onchange(this._getValue())}},_refresh:function(){if(this._size()==0){this._messageShow(this.options.errorText,"danger");this.$options.hide()}else{this._messageHide();this.$options.css("display","inline-block")}},_getValue:function(){var g=this.$el.find(":checked");if(g.length==0){return"null"}if(this.options.multiple){var f=[];g.each(function(){f.push($(this).val())});return f}else{return g.val()}},_size:function(){return this.$el.find(".ui-option").length},_messageShow:function(g,f){this.$message.show();this.$message.removeClass();this.$message.addClass("ui-message alert alert-"+f);this.$message.html(g)},_messageHide:function(){this.$message.hide()}});var d={};d.View=a.extend({initialize:function(f){a.prototype.initialize.call(this,f)},value:function(f){if(typeof f==="string"){f=[f]}if(f!==undefined){this.$el.find("input").prop("checked",false);for(var g in f){this.$el.find('input[value="'+f[g]+'"]').prop("checked",true)}}return this._getValue()},_templateOption:function(f){return'<div><input type="radio" name="'+this.options.id+'" value="'+f.value+'"/>'+f.label+"<br></div>"},_template:function(){return'<div class="ui-options"/>'}});var c={};c.View=d.View.extend({initialize:function(f){f.multiple=true;d.View.prototype.initialize.call(this,f)},_templateOption:function(f){return'<div><input type="checkbox" name="'+this.options.id+'" value="'+f.value+'"/>'+f.label+"<br></div>"}});var e={};e.View=a.extend({initialize:function(f){a.prototype.initialize.call(this,f)},value:function(f){if(f!==undefined){this.$el.find("input").prop("checked",false);this.$el.find("label").removeClass("active");this.$el.find('[value="'+f+'"]').prop("checked",true).closest("label").addClass("active")}return this._getValue()},_templateOption:function(g){var f='<label class="btn btn-default">';if(g.icon){f+='<i class="fa '+g.icon+'"/>'}f+='<input type="radio" name="'+this.options.id+'" value="'+g.value+'">'+g.label+"</label>";return f},_template:function(){return'<div class="btn-group ui-radiobutton" data-toggle="buttons"/>'}});return{Radio:d,RadioButton:e,Checkbox:c}});
\ No newline at end of file
+define(["utils/utils"],function(b){var a=Backbone.View.extend({initialize:function(g){this.optionsDefault={value:[],visible:true,data:[],id:b.uuid(),errorText:"No data available.",waitText:"Please wait..."};this.options=b.merge(g,this.optionsDefault);this.setElement("<div/>");this.$message=$("<div/>");this.$options=$(this._template(g));this.$el.append(this.$message);this.$el.append(this.$options);if(!this.options.visible){this.$el.hide()}this.update(this.options.data);if(this.options.value){this.value(this.options.value)}var f=this;this.on("change",function(){f._change()})},update:function(g){var j=this._getValue();this.$el.find(".ui-option").remove();for(var h in g){var i=$(this._templateOption(g[h]));i.addClass("ui-option");this.$options.append(i)}var f=this;this.$el.find("input").on("change",function(){f.value(f._getValue());f._change()});this._refresh();this.value(j)},exists:function(g){if(typeof g==="string"){g=[g]}for(var f in g){if(this.$el.find('input[value="'+g[f]+'"]').length>0){return true}}return false},first:function(){var f=this.$el.find("input");if(f.length>0){return f.val()}else{return undefined}},validate:function(){var g=this.value();if(!(g instanceof Array)){g=[g]}for(var f in g){if([null,"null",undefined].indexOf(g[f])>-1){return false}}return true},wait:function(){if(this._size()==0){this._messageShow(this.options.waitText,"info");this.$options.hide()}},unwait:function(){this._messageHide();this._refresh()},_change:function(){if(this.options.onchange){this.options.onchange(this._getValue())}},_refresh:function(){if(this._size()==0){this._messageShow(this.options.errorText,"danger");this.$options.hide()}else{this._messageHide();this.$options.css("display","inline-block")}},_getValue:function(){var g=this.$el.find(":checked");if(g.length==0){return"null"}if(this.options.multiple){var f=[];g.each(function(){f.push($(this).val())});return f}else{return g.val()}},_size:function(){return this.$el.find(".ui-option").length},_messageShow:function(g,f){this.$message.show();this.$message.removeClass();this.$message.addClass("ui-message alert alert-"+f);this.$message.html(g)},_messageHide:function(){this.$message.hide()}});var d={};d.View=a.extend({initialize:function(f){a.prototype.initialize.call(this,f)},value:function(f){if(typeof f==="string"){f=[f]}if(f!==undefined){this.$el.find("input").prop("checked",false);for(var g in f){this.$el.find('input[value="'+f[g]+'"]').prop("checked",true)}}return this._getValue()},_templateOption:function(f){return'<div><input type="radio" name="'+this.options.id+'" value="'+f.value+'"/>'+f.label+"<br></div>"},_template:function(){return'<div class="ui-options"/>'}});var c={};c.View=d.View.extend({initialize:function(f){f.multiple=true;d.View.prototype.initialize.call(this,f)},_templateOption:function(f){return'<div><input type="checkbox" name="'+this.options.id+'" value="'+f.value+'"/>'+f.label+"<br></div>"}});var e={};e.View=a.extend({initialize:function(f){a.prototype.initialize.call(this,f)},value:function(f){if(f!==undefined){this.$el.find("input").prop("checked",false);this.$el.find("label").removeClass("active");this.$el.find('[value="'+f+'"]').prop("checked",true).closest("label").addClass("active")}return this._getValue()},_templateOption:function(g){var f='<label class="btn btn-default">';if(g.icon){f+='<i class="fa '+g.icon+'"/>'}f+='<input type="radio" name="'+this.options.id+'" value="'+g.value+'">'+g.label+"</label>";return f},_template:function(){return'<div class="btn-group ui-radiobutton" data-toggle="buttons"/>'}});return{Radio:d,RadioButton:e,Checkbox:c}});
\ No newline at end of file
diff -r c7d09076b630f1ea42fc62e3e4c2dae5332b6892 -r 45f1c89fc887e1bbb48a18ebfac918cd1bc62cba static/scripts/packed/mvc/ui/ui-select-default.js
--- a/static/scripts/packed/mvc/ui/ui-select-default.js
+++ b/static/scripts/packed/mvc/ui/ui-select-default.js
@@ -1,1 +1,1 @@
-define(["utils/utils"],function(a){var b=Backbone.View.extend({optionsDefault:{id:"",cls:"",empty:"No data available",visible:true,wait:false,multiple:false},initialize:function(d){this.options=a.merge(d,this.optionsDefault);this.setElement(this._template(this.options));this.$select=this.$el.find("#select");this.$icon=this.$el.find("#icon");if(this.options.multiple){this.$select.prop("multiple",true);this.$select.addClass("ui-select-multiple");this.$icon.remove()}else{this.$el.addClass("ui-select")}this.update(this.options.data);if(!this.options.visible){this.hide()}if(this.options.wait){this.wait()}else{this.show()}var c=this;this.$select.on("change",function(){c._change()});this.on("change",function(){c._change()})},value:function(c){if(c!==undefined){this.$select.val(c)}return this.$select.val()},first:function(){var c=this.$select.find("option");if(c.length>0){return c.val()}else{return undefined}},validate:function(){var d=this.value();if(!(d instanceof Array)){d=[d]}for(var c in d){if([null,"null",undefined].indexOf(d[c])>-1){return false}}return true},text:function(){return this.$select.find("option:selected").text()},show:function(){this.unwait();this.$select.show();this.$el.css("display","inline-block")},hide:function(){this.$el.hide()},wait:function(){this.$icon.removeClass();this.$icon.addClass("fa fa-spinner fa-spin")},unwait:function(){this.$icon.removeClass();this.$icon.addClass("fa fa-caret-down")},disabled:function(){return this.$select.is(":disabled")},enable:function(){this.$select.prop("disabled",false)},disable:function(){this.$select.prop("disabled",true)},add:function(c){this.$select.append(this._templateOption(c));this._refresh()},del:function(c){this.$select.find("option[value="+c+"]").remove();this.$select.trigger("change");this._refresh()},update:function(c){var e=this.$select.val();this.$select.find("option").remove();for(var d in c){this.$select.append(this._templateOption(c[d]))}this._refresh();this.$select.val(e);if(!this.$select.val()){this.$select.val(this.first())}},setOnChange:function(c){this.options.onchange=c},exists:function(c){return this.$select.find('option[value="'+c+'"]').length>0},_change:function(){if(this.options.onchange){this.options.onchange(this.$select.val())}},_refresh:function(){this.$select.find("option[value=null]").remove();var c=this.$select.find("option").length;if(c==0){this.disable();this.$select.append(this._templateOption({value:"null",label:this.options.empty}))}else{this.enable()}},_templateOption:function(c){return'<option value="'+c.value+'">'+c.label+"</option>"},_template:function(c){return'<div id="'+c.id+'"><select id="select" class="select '+c.cls+" "+c.id+'"></select><div class="button"><i id="icon"/></div></div>'}});return{View:b}});
\ No newline at end of file
+define(["utils/utils"],function(a){var b=Backbone.View.extend({optionsDefault:{id:"",cls:"",empty:"No data available",visible:true,wait:false,multiple:false,searchable:false},initialize:function(d){this.options=a.merge(d,this.optionsDefault);this.setElement(this._template(this.options));this.$select=this.$el.find(".select");this.$icon=this.$el.find(".icon");this.$button=this.$el.find(".button");if(this.options.multiple){this.$select.prop("multiple",true);this.$select.addClass("ui-select-multiple");this.$icon.remove()}else{this.$el.addClass("ui-select")}this.update(this.options.data);if(!this.options.visible){this.hide()}if(this.options.wait){this.wait()}else{this.show()}var c=this;this.$select.on("change",function(){c._change()});this.on("change",function(){c._change()})},value:function(c){if(c!==undefined){this.$select.val(c)}return this.$select.val()},first:function(){var c=this.$select.find("option");if(c.length>0){return c.val()}else{return undefined}},validate:function(){var d=this.value();if(!(d instanceof Array)){d=[d]}for(var c in d){if([null,"null",undefined].indexOf(d[c])>-1){return false}}return true},text:function(){return this.$select.find("option:selected").text()},show:function(){this.unwait();this.$select.show();this.$el.show()},hide:function(){this.$el.hide()},wait:function(){this.$icon.removeClass();this.$icon.addClass("fa fa-spinner fa-spin")},unwait:function(){this.$icon.removeClass();this.$icon.addClass("fa fa-caret-down")},disabled:function(){return this.$select.is(":disabled")},enable:function(){this.$select.prop("disabled",false)},disable:function(){this.$select.prop("disabled",true)},add:function(c){this.$select.append(this._templateOption(c));this._refresh()},del:function(c){this.$select.find("option[value="+c+"]").remove();this.$select.trigger("change");this._refresh()},update:function(c){var e=this.$select.val();this.$select.find("option").remove();for(var d in c){this.$select.append(this._templateOption(c[d]))}this._refresh();this.$select.val(e);if(!this.$select.val()){this.$select.val(this.first())}if(this.options.searchable){this.$button.hide();this.$select.select2("destroy");this.$select.select2()}},setOnChange:function(c){this.options.onchange=c},exists:function(c){return this.$select.find('option[value="'+c+'"]').length>0},_change:function(){if(this.options.onchange){this.options.onchange(this.$select.val())}},_refresh:function(){this.$select.find("option[value=null]").remove();var c=this.$select.find("option").length;if(c==0){this.disable();this.$select.append(this._templateOption({value:"null",label:this.options.empty}))}else{this.enable()}},_templateOption:function(c){return'<option value="'+c.value+'">'+c.label+"</option>"},_template:function(c){return'<div id="'+c.id+'"><select id="select" class="select '+c.cls+" "+c.id+'"></select><div class="button"><i class="icon"/></div></div>'}});return{View:b}});
\ No newline at end of file
diff -r c7d09076b630f1ea42fc62e3e4c2dae5332b6892 -r 45f1c89fc887e1bbb48a18ebfac918cd1bc62cba static/style/blue/base.css
--- a/static/style/blue/base.css
+++ b/static/style/blue/base.css
@@ -1279,7 +1279,7 @@
.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}
-.no-highlight,.ui-button-icon,.ui-portlet,.ui-portlet-repeat{-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;-ms-user-select:none;}
+.no-highlight,.ui-button-icon,.ui-portlet,.ui-portlet-slim,.ui-portlet-repeat{-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}
.ui-table tbody{cursor:pointer}
@@ -1302,12 +1302,13 @@
.ui-button-icon-plain{border:none !important;background:none !important;height:inherit !important;width:inherit !important;padding-right:3px !important}
.ui-tabs .ui-tabs-add{font-size:0.8em;margin-right:5px}
.ui-tabs .ui-tabs-delete{font-size:0.8em;margin-left:5px;cursor:pointer}
-.ui-portlet,.ui-portlet-repeat,.ui-portlet-repeat{border:solid #d6b161 1px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;position:relative;clear:both;width:auto;height:100%}.ui-portlet .portlet-header{background:#ebd9b2;border-bottom:solid #d6b161 1px;padding:2px 8px;overflow:visible;float:right;width:100%}.ui-portlet .portlet-header .portlet-title .portlet-title-text{vertical-align:middle}
-.ui-portlet .portlet-header .portlet-title .icon{font-size:1.2em;vertical-align:middle}
-.ui-portlet .portlet-buttons{height:50px;padding:10px}
-.ui-portlet .portlet-content{height:inherit;padding:10px;clear:both}.ui-portlet .portlet-content .content{padding:10px;height:100%;width:100%}.ui-portlet .portlet-content .content .buttons{height:50px;padding:10px}
-.ui-portlet .no-scroll{height:calc(100% - 80px)}
-.ui-portlet-repeat{border:none;border-left:solid 3px #ebd9b2;border-radius:5px;display:inline-block}.ui-portlet-repeat .portlet-header{background:#ebd9b2;border-radius:3px;border-bottom-left-radius:0px;padding:0px 2px}
+.ui-portlet,.ui-portlet-slim,.ui-portlet-repeat,.ui-portlet-slim,.ui-portlet-repeat{border:solid #d6b161 1px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;position:relative;clear:both;width:auto;height:100%}.ui-portlet .portlet-header,.ui-portlet-slim .portlet-header{background:#ebd9b2;border-bottom:solid #d6b161 1px;padding:2px 8px;overflow:visible;float:right;width:100%}.ui-portlet .portlet-header .portlet-title .portlet-title-text,.ui-portlet-slim .portlet-header .portlet-title .portlet-title-text{vertical-align:middle}
+.ui-portlet .portlet-header .portlet-title .icon,.ui-portlet-slim .portlet-header .portlet-title .icon{font-size:1.2em;vertical-align:middle}
+.ui-portlet .portlet-buttons,.ui-portlet-slim .portlet-buttons{height:50px;padding:10px}
+.ui-portlet .portlet-content,.ui-portlet-slim .portlet-content{height:inherit;padding:10px;clear:both}.ui-portlet .portlet-content .content,.ui-portlet-slim .portlet-content .content{padding:10px;height:100%;width:100%}.ui-portlet .portlet-content .content .buttons,.ui-portlet-slim .portlet-content .content .buttons{height:50px;padding:10px}
+.ui-portlet .no-scroll,.ui-portlet-slim .no-scroll{height:calc(100% - 80px)}
+.ui-portlet-slim{max-width:900px}
+.ui-portlet-repeat{border:none;border-left:solid 3px #ebd9b2;border-radius:5px}.ui-portlet-repeat .portlet-header{background:#ebd9b2;border-radius:3px;border-bottom-left-radius:0px;padding:0px 2px}
.ui-portlet-repeat .portlet-content{padding:0px}.ui-portlet-repeat .portlet-content .content{padding:0px;padding-left:10px}
.ui-popover{max-width:700px;display:none}.ui-popover .popover-close{position:absolute;right:10px;top:7px;font-size:1.2em;cursor:pointer}
.ui-popover .popover-title{padding:4px 10px}
@@ -1319,6 +1320,7 @@
.ui-radiobutton{width:100%}.ui-radiobutton label{height:23px;line-height:1em}
.ui-radiobutton i{padding-right:5px}
.ui-select{position:relative}.ui-select .button{position:absolute;top:5px;right:5px}
+.ui-select .select2-container{width:100%}
.ui-select select{position:relative;top:0px;height:27px;width:100%;padding-left:5px;padding-right:20px;cursor:pointer;background:transparent;-webkit-appearance:none;border:1px solid #bfbfbf;-moz-border-radius:3px;border-radius:3px}
.libraryRow{background-color:#ebd9b2}
.datasetHighlighted{background-color:#f9f9f9}
diff -r c7d09076b630f1ea42fc62e3e4c2dae5332b6892 -r 45f1c89fc887e1bbb48a18ebfac918cd1bc62cba static/style/src/less/ui.less
--- a/static/style/src/less/ui.less
+++ b/static/style/src/less/ui.less
@@ -200,12 +200,16 @@
}
}
+.ui-portlet-slim {
+ &:extend(.ui-portlet all);
+ max-width: 900px;
+}
+
.ui-portlet-repeat {
&:extend(.ui-portlet);
border: none;
border-left: solid 3px @form-heading-bg;
border-radius: 5px;
- display: inline-block;
.portlet-header {
background: @form-heading-bg;
border-radius: 3px;
@@ -291,6 +295,9 @@
top: 5px;
right: 5px;
}
+ .select2-container {
+ width: 100%;
+ }
select {
position: relative;
top: 0px;
https://bitbucket.org/galaxy/galaxy-central/commits/981ab2e3bb17/
Changeset: 981ab2e3bb17
Branch: next-stable
User: guerler
Date: 2014-11-24 17:30:29+00:00
Summary: ToolForm: Allow 1 to n selection for batch mode fields
Affected #: 3 files
diff -r 45f1c89fc887e1bbb48a18ebfac918cd1bc62cba -r 981ab2e3bb172ec3514b635fd993f33c859fbee9 client/galaxy/scripts/mvc/tools/tools-jobs.js
--- a/client/galaxy/scripts/mvc/tools/tools-jobs.js
+++ b/client/galaxy/scripts/mvc/tools/tools-jobs.js
@@ -145,12 +145,14 @@
}
// check number of inputs
- if (batch_n === -1) {
- batch_n = n;
- } else {
- if (batch_n !== n) {
- this._foundError(input_id, 'Please make sure that you select the same number of inputs for all batch mode fields. This field contains <b>' + n + '</b> selection(s) while a previous field contains <b>' + batch_n + '</b>.');
- return false;
+ if (n > 1) {
+ if (batch_n === -1) {
+ batch_n = n;
+ } else {
+ if (batch_n !== n) {
+ this._foundError(input_id, 'Please make sure that you select the same number or a single input for all batch mode fields. This field contains <b>' + n + '</b> selection(s) while a previous field contains <b>' + batch_n + '</b>.');
+ return false;
+ }
}
}
}
diff -r 45f1c89fc887e1bbb48a18ebfac918cd1bc62cba -r 981ab2e3bb172ec3514b635fd993f33c859fbee9 static/scripts/mvc/tools/tools-jobs.js
--- a/static/scripts/mvc/tools/tools-jobs.js
+++ b/static/scripts/mvc/tools/tools-jobs.js
@@ -145,12 +145,14 @@
}
// check number of inputs
- if (batch_n === -1) {
- batch_n = n;
- } else {
- if (batch_n !== n) {
- this._foundError(input_id, 'Please make sure that you select the same number of inputs for all batch mode fields. This field contains <b>' + n + '</b> selection(s) while a previous field contains <b>' + batch_n + '</b>.');
- return false;
+ if (n > 1) {
+ if (batch_n === -1) {
+ batch_n = n;
+ } else {
+ if (batch_n !== n) {
+ this._foundError(input_id, 'Please make sure that you select the same number or a single input for all batch mode fields. This field contains <b>' + n + '</b> selection(s) while a previous field contains <b>' + batch_n + '</b>.');
+ return false;
+ }
}
}
}
diff -r 45f1c89fc887e1bbb48a18ebfac918cd1bc62cba -r 981ab2e3bb172ec3514b635fd993f33c859fbee9 static/scripts/packed/mvc/tools/tools-jobs.js
--- a/static/scripts/packed/mvc/tools/tools-jobs.js
+++ b/static/scripts/packed/mvc/tools/tools-jobs.js
@@ -1,1 +1,1 @@
-define(["utils/utils","mvc/tools/tools-template"],function(b,a){return Backbone.Model.extend({initialize:function(d,c){this.app=d;this.options=b.merge(c,this.optionsDefault)},submit:function(){var c=this;var d={tool_id:this.app.options.id,inputs:this.app.tree.finalize()};this.app.reset();if(!this._validation(d)){console.debug("tools-jobs::submit - Submission canceled. Validation failed.");return}console.debug(d);this.app.modal.show({title:"Please wait...",body:"progress",closing_events:true,buttons:{Close:function(){c.app.modal.hide()}}});b.request({type:"POST",url:galaxy_config.root+"api/tools",data:d,success:function(e){c.app.modal.hide();c.app.message(a.success(e));c._refreshHdas()},error:function(e,g){c.app.modal.hide();if(e&&e.message&&e.message.data){var h=c.app.tree.matchResponse(e.message.data);for(var f in h){c._foundError(f,h[f]);break}}else{console.debug(e);c.app.modal.show({title:"Job submission failed",body:a.error(d),buttons:{Close:function(){c.app.modal.hide()}}})}}})},_foundError:function(c,d){var e=this.app.element_list[c];e.error(d||"Please verify this parameter.");$(this.app.container).animate({scrollTop:e.$el.offset().top-20},500)},_validation:function(h){var d=h.inputs;var m=-1;var i=null;for(var k in d){var f=d[k];var l=this.app.tree.match(k);var e=this.app.field_list[l];var j=this.app.input_list[l];if(!l||!j||!e){console.debug("tools-jobs::_validation - Retrieving input objects failed.");continue}if(!j.optional&&e.validate&&!e.validate()){this._foundError(l);return false}if(f&&f.batch){var g=f.values.length;var c=null;if(g>0){c=f.values[0]&&f.values[0].src}if(c){if(i===null){i=c}else{if(i!==c){this._foundError(l,"Please select either dataset or dataset list fields for all batch mode fields.");return false}}}if(m===-1){m=g}else{if(m!==g){this._foundError(l,"Please make sure that you select the same number of inputs for all batch mode fields. This field contains <b>"+g+"</b> selection(s) while a previous field contains <b>"+m+"</b>.");return false}}}}return true},_refreshHdas:function(){if(parent.Galaxy&&parent.Galaxy.currHistoryPanel){parent.Galaxy.currHistoryPanel.refreshContents()}}})});
\ No newline at end of file
+define(["utils/utils","mvc/tools/tools-template"],function(b,a){return Backbone.Model.extend({initialize:function(d,c){this.app=d;this.options=b.merge(c,this.optionsDefault)},submit:function(){var c=this;var d={tool_id:this.app.options.id,inputs:this.app.tree.finalize()};this.app.reset();if(!this._validation(d)){console.debug("tools-jobs::submit - Submission canceled. Validation failed.");return}console.debug(d);this.app.modal.show({title:"Please wait...",body:"progress",closing_events:true,buttons:{Close:function(){c.app.modal.hide()}}});b.request({type:"POST",url:galaxy_config.root+"api/tools",data:d,success:function(e){c.app.modal.hide();c.app.message(a.success(e));c._refreshHdas()},error:function(e,g){c.app.modal.hide();if(e&&e.message&&e.message.data){var h=c.app.tree.matchResponse(e.message.data);for(var f in h){c._foundError(f,h[f]);break}}else{console.debug(e);c.app.modal.show({title:"Job submission failed",body:a.error(d),buttons:{Close:function(){c.app.modal.hide()}}})}}})},_foundError:function(c,d){var e=this.app.element_list[c];e.error(d||"Please verify this parameter.");$(this.app.container).animate({scrollTop:e.$el.offset().top-20},500)},_validation:function(h){var d=h.inputs;var m=-1;var i=null;for(var k in d){var f=d[k];var l=this.app.tree.match(k);var e=this.app.field_list[l];var j=this.app.input_list[l];if(!l||!j||!e){console.debug("tools-jobs::_validation - Retrieving input objects failed.");continue}if(!j.optional&&e.validate&&!e.validate()){this._foundError(l);return false}if(f&&f.batch){var g=f.values.length;var c=null;if(g>0){c=f.values[0]&&f.values[0].src}if(c){if(i===null){i=c}else{if(i!==c){this._foundError(l,"Please select either dataset or dataset list fields for all batch mode fields.");return false}}}if(g>1){if(m===-1){m=g}else{if(m!==g){this._foundError(l,"Please make sure that you select the same number or a single input for all batch mode fields. This field contains <b>"+g+"</b> selection(s) while a previous field contains <b>"+m+"</b>.");return false}}}}}return true},_refreshHdas:function(){if(parent.Galaxy&&parent.Galaxy.currHistoryPanel){parent.Galaxy.currHistoryPanel.refreshContents()}}})});
\ No newline at end of file
https://bitbucket.org/galaxy/galaxy-central/commits/27c90523b08a/
Changeset: 27c90523b08a
Branch: next-stable
User: guerler
Date: 2014-11-24 18:36:24+00:00
Summary: ToolForm: Adjust batch mode submission
Affected #: 3 files
diff -r 981ab2e3bb172ec3514b635fd993f33c859fbee9 -r 27c90523b08ab9d260698c5bd827ace716994bd0 client/galaxy/scripts/mvc/tools/tools-select-content.js
--- a/client/galaxy/scripts/mvc/tools/tools-select-content.js
+++ b/client/galaxy/scripts/mvc/tools/tools-select-content.js
@@ -190,7 +190,7 @@
// prepare result dict
var result = {
- batch : !this.options.multiple,
+ batch : !this.options.multiple && id_list.length > 1,
values : []
}
diff -r 981ab2e3bb172ec3514b635fd993f33c859fbee9 -r 27c90523b08ab9d260698c5bd827ace716994bd0 static/scripts/mvc/tools/tools-select-content.js
--- a/static/scripts/mvc/tools/tools-select-content.js
+++ b/static/scripts/mvc/tools/tools-select-content.js
@@ -190,7 +190,7 @@
// prepare result dict
var result = {
- batch : !this.options.multiple,
+ batch : !this.options.multiple && id_list.length > 1,
values : []
}
diff -r 981ab2e3bb172ec3514b635fd993f33c859fbee9 -r 27c90523b08ab9d260698c5bd827ace716994bd0 static/scripts/packed/mvc/tools/tools-select-content.js
--- a/static/scripts/packed/mvc/tools/tools-select-content.js
+++ b/static/scripts/packed/mvc/tools/tools-select-content.js
@@ -1,1 +1,1 @@
-define(["utils/utils","mvc/ui/ui-misc","mvc/ui/ui-tabs","mvc/tools/tools-template"],function(c,e,b,a){var d=Backbone.View.extend({initialize:function(k,g){this.app=k;this.options=g;var f=this;this.setElement("<div/>");this.list={};var j=[];if(!g.multiple){this.current="single"}else{this.current="multiple"}if(!g.multiple){j.push({icon:"fa-file-o",label:"Single dataset",value:"single"});this.select_single=new e.Select.View({onchange:function(){f.trigger("change")}});this.list.single={field:this.select_single,type:"hda"}}j.push({icon:"fa-files-o",label:"Multiple datasets",value:"multiple"});this.select_multiple=new e.Select.View({multiple:true,onchange:function(){f.trigger("change")}});this.list.multiple={field:this.select_multiple,type:"hda"};j.push({icon:"fa-folder-o",label:"List of datasets",value:"collection"});this.select_collection=new e.Select.View({onchange:function(){f.trigger("change")}});this.list.collection={field:this.select_collection,type:"hdca"};this.button_type=new e.RadioButton.View({value:this.current,data:j,onchange:function(i){f.current=i;f.refresh();f.trigger("change")}});this.$batch=$(a.batchMode());this.$el.append(c.wrap(this.button_type.$el));for(var h in this.list){this.$el.append(this.list[h].field.$el)}this.$el.append(this.$batch);this.update(g.data);this.refresh();this.on("change",function(){if(g.onchange){g.onchange(f.value())}})},wait:function(){for(var f in this.list){this.list[f].field.wait()}},unwait:function(){for(var f in this.list){this.list[f].field.unwait()}},update:function(g){var l=[];for(var j in g.hda){var k=g.hda[j];l.push({label:k.hid+": "+k.name,value:k.id})}var f=[];for(var j in g.hdca){var h=g.hdca[j];f.push({label:h.hid+": "+h.name,value:h.id})}this.select_single&&this.select_single.update(l);this.select_multiple.update(l);this.select_collection.update(f);this.app.content.add(g)},value:function(m){if(m&&m.values){try{var l=[];for(var h in m.values){l.push(m.values[h].id)}if(m&&m.values.length>0&&m.values[0].src=="hcda"){this.current="collection";this.select_collection.value(l[0])}else{if(l.length>1||this.options.multiple){this.current="multiple";this.select_multiple.value(l)}else{this.current="single";this.select_single.value(l[0])}}this.refresh();var g=this._select();if(!g.validate()){g.value(g.first())}}catch(k){console.debug("tools-select-content::value() - Skipped.")}}var j=this._select().value();if(!(j instanceof Array)){j=[j]}var f={batch:!this.options.multiple,values:[]};for(var h in j){f.values.push({id:j[h],src:this.list[this.current].type})}return f},validate:function(){return this._select().validate()},refresh:function(){for(var g in this.list){var f=this.list[g].field.$el;if(this.current==g){f.show()}else{f.hide()}}if(this.current!="single"&&!this.options.multiple){this.$batch.show()}else{this.$batch.hide()}},_select:function(){return this.list[this.current].field}});return{View:d}});
\ No newline at end of file
+define(["utils/utils","mvc/ui/ui-misc","mvc/ui/ui-tabs","mvc/tools/tools-template"],function(c,e,b,a){var d=Backbone.View.extend({initialize:function(k,g){this.app=k;this.options=g;var f=this;this.setElement("<div/>");this.list={};var j=[];if(!g.multiple){this.current="single"}else{this.current="multiple"}if(!g.multiple){j.push({icon:"fa-file-o",label:"Single dataset",value:"single"});this.select_single=new e.Select.View({onchange:function(){f.trigger("change")}});this.list.single={field:this.select_single,type:"hda"}}j.push({icon:"fa-files-o",label:"Multiple datasets",value:"multiple"});this.select_multiple=new e.Select.View({multiple:true,onchange:function(){f.trigger("change")}});this.list.multiple={field:this.select_multiple,type:"hda"};j.push({icon:"fa-folder-o",label:"List of datasets",value:"collection"});this.select_collection=new e.Select.View({onchange:function(){f.trigger("change")}});this.list.collection={field:this.select_collection,type:"hdca"};this.button_type=new e.RadioButton.View({value:this.current,data:j,onchange:function(i){f.current=i;f.refresh();f.trigger("change")}});this.$batch=$(a.batchMode());this.$el.append(c.wrap(this.button_type.$el));for(var h in this.list){this.$el.append(this.list[h].field.$el)}this.$el.append(this.$batch);this.update(g.data);this.refresh();this.on("change",function(){if(g.onchange){g.onchange(f.value())}})},wait:function(){for(var f in this.list){this.list[f].field.wait()}},unwait:function(){for(var f in this.list){this.list[f].field.unwait()}},update:function(g){var l=[];for(var j in g.hda){var k=g.hda[j];l.push({label:k.hid+": "+k.name,value:k.id})}var f=[];for(var j in g.hdca){var h=g.hdca[j];f.push({label:h.hid+": "+h.name,value:h.id})}this.select_single&&this.select_single.update(l);this.select_multiple.update(l);this.select_collection.update(f);this.app.content.add(g)},value:function(m){if(m&&m.values){try{var l=[];for(var h in m.values){l.push(m.values[h].id)}if(m&&m.values.length>0&&m.values[0].src=="hcda"){this.current="collection";this.select_collection.value(l[0])}else{if(l.length>1||this.options.multiple){this.current="multiple";this.select_multiple.value(l)}else{this.current="single";this.select_single.value(l[0])}}this.refresh();var g=this._select();if(!g.validate()){g.value(g.first())}}catch(k){console.debug("tools-select-content::value() - Skipped.")}}var j=this._select().value();if(!(j instanceof Array)){j=[j]}var f={batch:!this.options.multiple&&j.length>1,values:[]};for(var h in j){f.values.push({id:j[h],src:this.list[this.current].type})}return f},validate:function(){return this._select().validate()},refresh:function(){for(var g in this.list){var f=this.list[g].field.$el;if(this.current==g){f.show()}else{f.hide()}}if(this.current!="single"&&!this.options.multiple){this.$batch.show()}else{this.$batch.hide()}},_select:function(){return this.list[this.current].field}});return{View:d}});
\ No newline at end of file
https://bitbucket.org/galaxy/galaxy-central/commits/7c2fb0684c2b/
Changeset: 7c2fb0684c2b
Branch: next-stable
User: guerler
Date: 2014-11-24 19:31:19+00:00
Summary: ToolForm: Adjust batch mode for collections
Affected #: 3 files
diff -r 27c90523b08ab9d260698c5bd827ace716994bd0 -r 7c2fb0684c2b0e4ef7a46ad506b25c65bfc75cce client/galaxy/scripts/mvc/tools/tools-select-content.js
--- a/client/galaxy/scripts/mvc/tools/tools-select-content.js
+++ b/client/galaxy/scripts/mvc/tools/tools-select-content.js
@@ -190,7 +190,7 @@
// prepare result dict
var result = {
- batch : !this.options.multiple && id_list.length > 1,
+ batch : !this.options.multiple && (this.current == 'collection' || id_list.length > 1),
values : []
}
diff -r 27c90523b08ab9d260698c5bd827ace716994bd0 -r 7c2fb0684c2b0e4ef7a46ad506b25c65bfc75cce static/scripts/mvc/tools/tools-select-content.js
--- a/static/scripts/mvc/tools/tools-select-content.js
+++ b/static/scripts/mvc/tools/tools-select-content.js
@@ -190,7 +190,7 @@
// prepare result dict
var result = {
- batch : !this.options.multiple && id_list.length > 1,
+ batch : !this.options.multiple && (this.current == 'collection' || id_list.length > 1),
values : []
}
diff -r 27c90523b08ab9d260698c5bd827ace716994bd0 -r 7c2fb0684c2b0e4ef7a46ad506b25c65bfc75cce static/scripts/packed/mvc/tools/tools-select-content.js
--- a/static/scripts/packed/mvc/tools/tools-select-content.js
+++ b/static/scripts/packed/mvc/tools/tools-select-content.js
@@ -1,1 +1,1 @@
-define(["utils/utils","mvc/ui/ui-misc","mvc/ui/ui-tabs","mvc/tools/tools-template"],function(c,e,b,a){var d=Backbone.View.extend({initialize:function(k,g){this.app=k;this.options=g;var f=this;this.setElement("<div/>");this.list={};var j=[];if(!g.multiple){this.current="single"}else{this.current="multiple"}if(!g.multiple){j.push({icon:"fa-file-o",label:"Single dataset",value:"single"});this.select_single=new e.Select.View({onchange:function(){f.trigger("change")}});this.list.single={field:this.select_single,type:"hda"}}j.push({icon:"fa-files-o",label:"Multiple datasets",value:"multiple"});this.select_multiple=new e.Select.View({multiple:true,onchange:function(){f.trigger("change")}});this.list.multiple={field:this.select_multiple,type:"hda"};j.push({icon:"fa-folder-o",label:"List of datasets",value:"collection"});this.select_collection=new e.Select.View({onchange:function(){f.trigger("change")}});this.list.collection={field:this.select_collection,type:"hdca"};this.button_type=new e.RadioButton.View({value:this.current,data:j,onchange:function(i){f.current=i;f.refresh();f.trigger("change")}});this.$batch=$(a.batchMode());this.$el.append(c.wrap(this.button_type.$el));for(var h in this.list){this.$el.append(this.list[h].field.$el)}this.$el.append(this.$batch);this.update(g.data);this.refresh();this.on("change",function(){if(g.onchange){g.onchange(f.value())}})},wait:function(){for(var f in this.list){this.list[f].field.wait()}},unwait:function(){for(var f in this.list){this.list[f].field.unwait()}},update:function(g){var l=[];for(var j in g.hda){var k=g.hda[j];l.push({label:k.hid+": "+k.name,value:k.id})}var f=[];for(var j in g.hdca){var h=g.hdca[j];f.push({label:h.hid+": "+h.name,value:h.id})}this.select_single&&this.select_single.update(l);this.select_multiple.update(l);this.select_collection.update(f);this.app.content.add(g)},value:function(m){if(m&&m.values){try{var l=[];for(var h in m.values){l.push(m.values[h].id)}if(m&&m.values.length>0&&m.values[0].src=="hcda"){this.current="collection";this.select_collection.value(l[0])}else{if(l.length>1||this.options.multiple){this.current="multiple";this.select_multiple.value(l)}else{this.current="single";this.select_single.value(l[0])}}this.refresh();var g=this._select();if(!g.validate()){g.value(g.first())}}catch(k){console.debug("tools-select-content::value() - Skipped.")}}var j=this._select().value();if(!(j instanceof Array)){j=[j]}var f={batch:!this.options.multiple&&j.length>1,values:[]};for(var h in j){f.values.push({id:j[h],src:this.list[this.current].type})}return f},validate:function(){return this._select().validate()},refresh:function(){for(var g in this.list){var f=this.list[g].field.$el;if(this.current==g){f.show()}else{f.hide()}}if(this.current!="single"&&!this.options.multiple){this.$batch.show()}else{this.$batch.hide()}},_select:function(){return this.list[this.current].field}});return{View:d}});
\ No newline at end of file
+define(["utils/utils","mvc/ui/ui-misc","mvc/ui/ui-tabs","mvc/tools/tools-template"],function(c,e,b,a){var d=Backbone.View.extend({initialize:function(k,g){this.app=k;this.options=g;var f=this;this.setElement("<div/>");this.list={};var j=[];if(!g.multiple){this.current="single"}else{this.current="multiple"}if(!g.multiple){j.push({icon:"fa-file-o",label:"Single dataset",value:"single"});this.select_single=new e.Select.View({onchange:function(){f.trigger("change")}});this.list.single={field:this.select_single,type:"hda"}}j.push({icon:"fa-files-o",label:"Multiple datasets",value:"multiple"});this.select_multiple=new e.Select.View({multiple:true,onchange:function(){f.trigger("change")}});this.list.multiple={field:this.select_multiple,type:"hda"};j.push({icon:"fa-folder-o",label:"List of datasets",value:"collection"});this.select_collection=new e.Select.View({onchange:function(){f.trigger("change")}});this.list.collection={field:this.select_collection,type:"hdca"};this.button_type=new e.RadioButton.View({value:this.current,data:j,onchange:function(i){f.current=i;f.refresh();f.trigger("change")}});this.$batch=$(a.batchMode());this.$el.append(c.wrap(this.button_type.$el));for(var h in this.list){this.$el.append(this.list[h].field.$el)}this.$el.append(this.$batch);this.update(g.data);this.refresh();this.on("change",function(){if(g.onchange){g.onchange(f.value())}})},wait:function(){for(var f in this.list){this.list[f].field.wait()}},unwait:function(){for(var f in this.list){this.list[f].field.unwait()}},update:function(g){var l=[];for(var j in g.hda){var k=g.hda[j];l.push({label:k.hid+": "+k.name,value:k.id})}var f=[];for(var j in g.hdca){var h=g.hdca[j];f.push({label:h.hid+": "+h.name,value:h.id})}this.select_single&&this.select_single.update(l);this.select_multiple.update(l);this.select_collection.update(f);this.app.content.add(g)},value:function(m){if(m&&m.values){try{var l=[];for(var h in m.values){l.push(m.values[h].id)}if(m&&m.values.length>0&&m.values[0].src=="hcda"){this.current="collection";this.select_collection.value(l[0])}else{if(l.length>1||this.options.multiple){this.current="multiple";this.select_multiple.value(l)}else{this.current="single";this.select_single.value(l[0])}}this.refresh();var g=this._select();if(!g.validate()){g.value(g.first())}}catch(k){console.debug("tools-select-content::value() - Skipped.")}}var j=this._select().value();if(!(j instanceof Array)){j=[j]}var f={batch:!this.options.multiple&&(this.current=="collection"||j.length>1),values:[]};for(var h in j){f.values.push({id:j[h],src:this.list[this.current].type})}return f},validate:function(){return this._select().validate()},refresh:function(){for(var g in this.list){var f=this.list[g].field.$el;if(this.current==g){f.show()}else{f.hide()}}if(this.current!="single"&&!this.options.multiple){this.$batch.show()}else{this.$batch.hide()}},_select:function(){return this.list[this.current].field}});return{View:d}});
\ No newline at end of file
https://bitbucket.org/galaxy/galaxy-central/commits/13f34bbe13f3/
Changeset: 13f34bbe13f3
Branch: next-stable
User: guerler
Date: 2014-11-24 19:48:09+00:00
Summary: ToolForm: More batch mode validation logic
Affected #: 6 files
diff -r 7c2fb0684c2b0e4ef7a46ad506b25c65bfc75cce -r 13f34bbe13f3e69dac88ead4dab9b60648d40171 client/galaxy/scripts/mvc/tools/tools-jobs.js
--- a/client/galaxy/scripts/mvc/tools/tools-jobs.js
+++ b/client/galaxy/scripts/mvc/tools/tools-jobs.js
@@ -145,14 +145,12 @@
}
// check number of inputs
- if (n > 1) {
- if (batch_n === -1) {
- batch_n = n;
- } else {
- if (batch_n !== n) {
- this._foundError(input_id, 'Please make sure that you select the same number or a single input for all batch mode fields. This field contains <b>' + n + '</b> selection(s) while a previous field contains <b>' + batch_n + '</b>.');
- return false;
- }
+ if (batch_n === -1) {
+ batch_n = n;
+ } else {
+ if (batch_n !== n) {
+ this._foundError(input_id, 'Please make sure that you select the same number of inputs for all batch mode fields. This field contains <b>' + n + '</b> selection(s) while a previous field contains <b>' + batch_n + '</b>.');
+ return false;
}
}
}
diff -r 7c2fb0684c2b0e4ef7a46ad506b25c65bfc75cce -r 13f34bbe13f3e69dac88ead4dab9b60648d40171 client/galaxy/scripts/mvc/tools/tools-select-content.js
--- a/client/galaxy/scripts/mvc/tools/tools-select-content.js
+++ b/client/galaxy/scripts/mvc/tools/tools-select-content.js
@@ -190,7 +190,7 @@
// prepare result dict
var result = {
- batch : !this.options.multiple && (this.current == 'collection' || id_list.length > 1),
+ batch : !this.options.multiple && this.current != 'single',
values : []
}
diff -r 7c2fb0684c2b0e4ef7a46ad506b25c65bfc75cce -r 13f34bbe13f3e69dac88ead4dab9b60648d40171 static/scripts/mvc/tools/tools-jobs.js
--- a/static/scripts/mvc/tools/tools-jobs.js
+++ b/static/scripts/mvc/tools/tools-jobs.js
@@ -145,14 +145,12 @@
}
// check number of inputs
- if (n > 1) {
- if (batch_n === -1) {
- batch_n = n;
- } else {
- if (batch_n !== n) {
- this._foundError(input_id, 'Please make sure that you select the same number or a single input for all batch mode fields. This field contains <b>' + n + '</b> selection(s) while a previous field contains <b>' + batch_n + '</b>.');
- return false;
- }
+ if (batch_n === -1) {
+ batch_n = n;
+ } else {
+ if (batch_n !== n) {
+ this._foundError(input_id, 'Please make sure that you select the same number of inputs for all batch mode fields. This field contains <b>' + n + '</b> selection(s) while a previous field contains <b>' + batch_n + '</b>.');
+ return false;
}
}
}
diff -r 7c2fb0684c2b0e4ef7a46ad506b25c65bfc75cce -r 13f34bbe13f3e69dac88ead4dab9b60648d40171 static/scripts/mvc/tools/tools-select-content.js
--- a/static/scripts/mvc/tools/tools-select-content.js
+++ b/static/scripts/mvc/tools/tools-select-content.js
@@ -190,7 +190,7 @@
// prepare result dict
var result = {
- batch : !this.options.multiple && (this.current == 'collection' || id_list.length > 1),
+ batch : !this.options.multiple && this.current != 'single',
values : []
}
diff -r 7c2fb0684c2b0e4ef7a46ad506b25c65bfc75cce -r 13f34bbe13f3e69dac88ead4dab9b60648d40171 static/scripts/packed/mvc/tools/tools-jobs.js
--- a/static/scripts/packed/mvc/tools/tools-jobs.js
+++ b/static/scripts/packed/mvc/tools/tools-jobs.js
@@ -1,1 +1,1 @@
-define(["utils/utils","mvc/tools/tools-template"],function(b,a){return Backbone.Model.extend({initialize:function(d,c){this.app=d;this.options=b.merge(c,this.optionsDefault)},submit:function(){var c=this;var d={tool_id:this.app.options.id,inputs:this.app.tree.finalize()};this.app.reset();if(!this._validation(d)){console.debug("tools-jobs::submit - Submission canceled. Validation failed.");return}console.debug(d);this.app.modal.show({title:"Please wait...",body:"progress",closing_events:true,buttons:{Close:function(){c.app.modal.hide()}}});b.request({type:"POST",url:galaxy_config.root+"api/tools",data:d,success:function(e){c.app.modal.hide();c.app.message(a.success(e));c._refreshHdas()},error:function(e,g){c.app.modal.hide();if(e&&e.message&&e.message.data){var h=c.app.tree.matchResponse(e.message.data);for(var f in h){c._foundError(f,h[f]);break}}else{console.debug(e);c.app.modal.show({title:"Job submission failed",body:a.error(d),buttons:{Close:function(){c.app.modal.hide()}}})}}})},_foundError:function(c,d){var e=this.app.element_list[c];e.error(d||"Please verify this parameter.");$(this.app.container).animate({scrollTop:e.$el.offset().top-20},500)},_validation:function(h){var d=h.inputs;var m=-1;var i=null;for(var k in d){var f=d[k];var l=this.app.tree.match(k);var e=this.app.field_list[l];var j=this.app.input_list[l];if(!l||!j||!e){console.debug("tools-jobs::_validation - Retrieving input objects failed.");continue}if(!j.optional&&e.validate&&!e.validate()){this._foundError(l);return false}if(f&&f.batch){var g=f.values.length;var c=null;if(g>0){c=f.values[0]&&f.values[0].src}if(c){if(i===null){i=c}else{if(i!==c){this._foundError(l,"Please select either dataset or dataset list fields for all batch mode fields.");return false}}}if(g>1){if(m===-1){m=g}else{if(m!==g){this._foundError(l,"Please make sure that you select the same number or a single input for all batch mode fields. This field contains <b>"+g+"</b> selection(s) while a previous field contains <b>"+m+"</b>.");return false}}}}}return true},_refreshHdas:function(){if(parent.Galaxy&&parent.Galaxy.currHistoryPanel){parent.Galaxy.currHistoryPanel.refreshContents()}}})});
\ No newline at end of file
+define(["utils/utils","mvc/tools/tools-template"],function(b,a){return Backbone.Model.extend({initialize:function(d,c){this.app=d;this.options=b.merge(c,this.optionsDefault)},submit:function(){var c=this;var d={tool_id:this.app.options.id,inputs:this.app.tree.finalize()};this.app.reset();if(!this._validation(d)){console.debug("tools-jobs::submit - Submission canceled. Validation failed.");return}console.debug(d);this.app.modal.show({title:"Please wait...",body:"progress",closing_events:true,buttons:{Close:function(){c.app.modal.hide()}}});b.request({type:"POST",url:galaxy_config.root+"api/tools",data:d,success:function(e){c.app.modal.hide();c.app.message(a.success(e));c._refreshHdas()},error:function(e,g){c.app.modal.hide();if(e&&e.message&&e.message.data){var h=c.app.tree.matchResponse(e.message.data);for(var f in h){c._foundError(f,h[f]);break}}else{console.debug(e);c.app.modal.show({title:"Job submission failed",body:a.error(d),buttons:{Close:function(){c.app.modal.hide()}}})}}})},_foundError:function(c,d){var e=this.app.element_list[c];e.error(d||"Please verify this parameter.");$(this.app.container).animate({scrollTop:e.$el.offset().top-20},500)},_validation:function(h){var d=h.inputs;var m=-1;var i=null;for(var k in d){var f=d[k];var l=this.app.tree.match(k);var e=this.app.field_list[l];var j=this.app.input_list[l];if(!l||!j||!e){console.debug("tools-jobs::_validation - Retrieving input objects failed.");continue}if(!j.optional&&e.validate&&!e.validate()){this._foundError(l);return false}if(f&&f.batch){var g=f.values.length;var c=null;if(g>0){c=f.values[0]&&f.values[0].src}if(c){if(i===null){i=c}else{if(i!==c){this._foundError(l,"Please select either dataset or dataset list fields for all batch mode fields.");return false}}}if(m===-1){m=g}else{if(m!==g){this._foundError(l,"Please make sure that you select the same number of inputs for all batch mode fields. This field contains <b>"+g+"</b> selection(s) while a previous field contains <b>"+m+"</b>.");return false}}}}return true},_refreshHdas:function(){if(parent.Galaxy&&parent.Galaxy.currHistoryPanel){parent.Galaxy.currHistoryPanel.refreshContents()}}})});
\ No newline at end of file
diff -r 7c2fb0684c2b0e4ef7a46ad506b25c65bfc75cce -r 13f34bbe13f3e69dac88ead4dab9b60648d40171 static/scripts/packed/mvc/tools/tools-select-content.js
--- a/static/scripts/packed/mvc/tools/tools-select-content.js
+++ b/static/scripts/packed/mvc/tools/tools-select-content.js
@@ -1,1 +1,1 @@
-define(["utils/utils","mvc/ui/ui-misc","mvc/ui/ui-tabs","mvc/tools/tools-template"],function(c,e,b,a){var d=Backbone.View.extend({initialize:function(k,g){this.app=k;this.options=g;var f=this;this.setElement("<div/>");this.list={};var j=[];if(!g.multiple){this.current="single"}else{this.current="multiple"}if(!g.multiple){j.push({icon:"fa-file-o",label:"Single dataset",value:"single"});this.select_single=new e.Select.View({onchange:function(){f.trigger("change")}});this.list.single={field:this.select_single,type:"hda"}}j.push({icon:"fa-files-o",label:"Multiple datasets",value:"multiple"});this.select_multiple=new e.Select.View({multiple:true,onchange:function(){f.trigger("change")}});this.list.multiple={field:this.select_multiple,type:"hda"};j.push({icon:"fa-folder-o",label:"List of datasets",value:"collection"});this.select_collection=new e.Select.View({onchange:function(){f.trigger("change")}});this.list.collection={field:this.select_collection,type:"hdca"};this.button_type=new e.RadioButton.View({value:this.current,data:j,onchange:function(i){f.current=i;f.refresh();f.trigger("change")}});this.$batch=$(a.batchMode());this.$el.append(c.wrap(this.button_type.$el));for(var h in this.list){this.$el.append(this.list[h].field.$el)}this.$el.append(this.$batch);this.update(g.data);this.refresh();this.on("change",function(){if(g.onchange){g.onchange(f.value())}})},wait:function(){for(var f in this.list){this.list[f].field.wait()}},unwait:function(){for(var f in this.list){this.list[f].field.unwait()}},update:function(g){var l=[];for(var j in g.hda){var k=g.hda[j];l.push({label:k.hid+": "+k.name,value:k.id})}var f=[];for(var j in g.hdca){var h=g.hdca[j];f.push({label:h.hid+": "+h.name,value:h.id})}this.select_single&&this.select_single.update(l);this.select_multiple.update(l);this.select_collection.update(f);this.app.content.add(g)},value:function(m){if(m&&m.values){try{var l=[];for(var h in m.values){l.push(m.values[h].id)}if(m&&m.values.length>0&&m.values[0].src=="hcda"){this.current="collection";this.select_collection.value(l[0])}else{if(l.length>1||this.options.multiple){this.current="multiple";this.select_multiple.value(l)}else{this.current="single";this.select_single.value(l[0])}}this.refresh();var g=this._select();if(!g.validate()){g.value(g.first())}}catch(k){console.debug("tools-select-content::value() - Skipped.")}}var j=this._select().value();if(!(j instanceof Array)){j=[j]}var f={batch:!this.options.multiple&&(this.current=="collection"||j.length>1),values:[]};for(var h in j){f.values.push({id:j[h],src:this.list[this.current].type})}return f},validate:function(){return this._select().validate()},refresh:function(){for(var g in this.list){var f=this.list[g].field.$el;if(this.current==g){f.show()}else{f.hide()}}if(this.current!="single"&&!this.options.multiple){this.$batch.show()}else{this.$batch.hide()}},_select:function(){return this.list[this.current].field}});return{View:d}});
\ No newline at end of file
+define(["utils/utils","mvc/ui/ui-misc","mvc/ui/ui-tabs","mvc/tools/tools-template"],function(c,e,b,a){var d=Backbone.View.extend({initialize:function(k,g){this.app=k;this.options=g;var f=this;this.setElement("<div/>");this.list={};var j=[];if(!g.multiple){this.current="single"}else{this.current="multiple"}if(!g.multiple){j.push({icon:"fa-file-o",label:"Single dataset",value:"single"});this.select_single=new e.Select.View({onchange:function(){f.trigger("change")}});this.list.single={field:this.select_single,type:"hda"}}j.push({icon:"fa-files-o",label:"Multiple datasets",value:"multiple"});this.select_multiple=new e.Select.View({multiple:true,onchange:function(){f.trigger("change")}});this.list.multiple={field:this.select_multiple,type:"hda"};j.push({icon:"fa-folder-o",label:"List of datasets",value:"collection"});this.select_collection=new e.Select.View({onchange:function(){f.trigger("change")}});this.list.collection={field:this.select_collection,type:"hdca"};this.button_type=new e.RadioButton.View({value:this.current,data:j,onchange:function(i){f.current=i;f.refresh();f.trigger("change")}});this.$batch=$(a.batchMode());this.$el.append(c.wrap(this.button_type.$el));for(var h in this.list){this.$el.append(this.list[h].field.$el)}this.$el.append(this.$batch);this.update(g.data);this.refresh();this.on("change",function(){if(g.onchange){g.onchange(f.value())}})},wait:function(){for(var f in this.list){this.list[f].field.wait()}},unwait:function(){for(var f in this.list){this.list[f].field.unwait()}},update:function(g){var l=[];for(var j in g.hda){var k=g.hda[j];l.push({label:k.hid+": "+k.name,value:k.id})}var f=[];for(var j in g.hdca){var h=g.hdca[j];f.push({label:h.hid+": "+h.name,value:h.id})}this.select_single&&this.select_single.update(l);this.select_multiple.update(l);this.select_collection.update(f);this.app.content.add(g)},value:function(m){if(m&&m.values){try{var l=[];for(var h in m.values){l.push(m.values[h].id)}if(m&&m.values.length>0&&m.values[0].src=="hcda"){this.current="collection";this.select_collection.value(l[0])}else{if(l.length>1||this.options.multiple){this.current="multiple";this.select_multiple.value(l)}else{this.current="single";this.select_single.value(l[0])}}this.refresh();var g=this._select();if(!g.validate()){g.value(g.first())}}catch(k){console.debug("tools-select-content::value() - Skipped.")}}var j=this._select().value();if(!(j instanceof Array)){j=[j]}var f={batch:!this.options.multiple&&this.current!="single",values:[]};for(var h in j){f.values.push({id:j[h],src:this.list[this.current].type})}return f},validate:function(){return this._select().validate()},refresh:function(){for(var g in this.list){var f=this.list[g].field.$el;if(this.current==g){f.show()}else{f.hide()}}if(this.current!="single"&&!this.options.multiple){this.$batch.show()}else{this.$batch.hide()}},_select:function(){return this.list[this.current].field}});return{View:d}});
\ No newline at end of file
https://bitbucket.org/galaxy/galaxy-central/commits/4d173afb6f7c/
Changeset: 4d173afb6f7c
Branch: next-stable
User: guerler
Date: 2014-11-25 03:34:33+00:00
Summary: ToolForm: Handle boolean definition without modifying shared code
Affected #: 1 file
diff -r 13f34bbe13f3e69dac88ead4dab9b60648d40171 -r 4d173afb6f7c0c59a36d35a23f4f0eecd30e79a6 lib/galaxy/webapps/galaxy/api/tools.py
--- a/lib/galaxy/webapps/galaxy/api/tools.py
+++ b/lib/galaxy/webapps/galaxy/api/tools.py
@@ -581,6 +581,21 @@
for input in inputs.itervalues():
state[input.name] = input.get_initial_value(trans, context)
+ # check the current state of a value and update it if necessary
+ def check_state(trans, input, default_value, context):
+ value = default_value
+ error = 'State validation failed.'
+ try:
+ # resolves the inconsistent definition of boolean parameters (see base.py) without modifying shared code
+ if input.type == 'boolean':
+ value, error = [util.string_as_bool(default_value), None]
+ else:
+ value, error = check_param(trans, input, default_value, context)
+ except Exception:
+ log.error('Checking parameter %s failed.', input.name)
+ pass
+ return [value, error]
+
# populates state with incoming url parameters
def populate_state(trans, inputs, state, incoming, prefix="", context=None ):
errors = dict()
@@ -613,9 +628,9 @@
group_prefix = "%s|" % ( key )
test_param_key = group_prefix + input.test_param.name
default_value = incoming.get(test_param_key, group_state.get(input.test_param.name, None))
- value, test_param_error = check_param( trans, input.test_param, default_value, context)
- if test_param_error:
- errors[input.name] = [test_param_error]
+ value, error = check_state(trans, input.test_param, default_value, context)
+ if error:
+ errors[input.name] = [error]
else:
current_case = input.get_current_case(value, trans)
group_state = state[input.name] = {}
@@ -624,16 +639,13 @@
if group_errors:
errors[input.name] = group_errors
group_state['__current_case__'] = current_case
- group_state[ input.test_param.name ] = value
+ group_state[input.test_param.name] = value
else:
- try:
- value, error = check_param(trans, input, incoming.get(key, state.get(input.name, None)), context)
- if error:
- errors[input.name] = error
- state[input.name] = value
- except Exception:
- log.error('Checking parameter %s failed.', input.name)
- pass
+ default_value = incoming.get(key, state.get(input.name, None))
+ value, error = check_state(trans, input, default_value, context)
+ if error:
+ errors[input.name] = error
+ state[input.name] = value
return errors
# builds tool model including all attributes
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: provide defaults for remote_repository_url and homepage_url, move the optional arguments to the end of the list
by commits-noreply@bitbucket.org 25 Nov '14
by commits-noreply@bitbucket.org 25 Nov '14
25 Nov '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/a0eda112fa3b/
Changeset: a0eda112fa3b
User: martenson
Date: 2014-11-25 17:27:56+00:00
Summary: provide defaults for remote_repository_url and homepage_url, move the optional arguments to the end of the list
Affected #: 2 files
diff -r 624c1f52f62771dda89de969eed67c94c4bfeef5 -r a0eda112fa3b6456a5ae663ff2ddcc0137c87714 lib/galaxy/webapps/tool_shed/controllers/repository.py
--- a/lib/galaxy/webapps/tool_shed/controllers/repository.py
+++ b/lib/galaxy/webapps/tool_shed/controllers/repository.py
@@ -1084,12 +1084,12 @@
repository, message = repository_util.create_repository( trans.app,
name,
repository_type,
- remote_repository_url,
- homepage_url,
description,
long_description,
user_id=trans.user.id,
- category_ids=category_ids )
+ category_ids=category_ids,
+ remote_repository_url=remote_repository_url,
+ homepage_url=homepage_url )
trans.response.send_redirect( web.url_for( controller='repository',
action='manage_repository',
message=message,
diff -r 624c1f52f62771dda89de969eed67c94c4bfeef5 -r a0eda112fa3b6456a5ae663ff2ddcc0137c87714 lib/tool_shed/util/repository_util.py
--- a/lib/tool_shed/util/repository_util.py
+++ b/lib/tool_shed/util/repository_util.py
@@ -120,7 +120,7 @@
tool_dependencies )
return repo_info_dict
-def create_repository( app, name, type, remote_repository_url, homepage_url, description, long_description, user_id, category_ids=[] ):
+def create_repository( app, name, type, description, long_description, user_id, category_ids=[], remote_repository_url=None, homepage_url=None ):
"""Create a new ToolShed repository"""
sa_session = app.model.context.current
# Add the repository record to the database.
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: dannon: Merged in jmchilton/galaxy-central-fork-1/next-stable (pull request #573)
by commits-noreply@bitbucket.org 25 Nov '14
by commits-noreply@bitbucket.org 25 Nov '14
25 Nov '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/c7d09076b630/
Changeset: c7d09076b630
Branch: next-stable
User: dannon
Date: 2014-11-25 17:27:41+00:00
Summary: Merged in jmchilton/galaxy-central-fork-1/next-stable (pull request #573)
Enhanced client security.
Affected #: 3 files
diff -r 39ebfe2e1f1806137bb3f117845f788daaf185aa -r c7d09076b630f1ea42fc62e3e4c2dae5332b6892 config/galaxy.ini.sample
--- a/config/galaxy.ini.sample
+++ b/config/galaxy.ini.sample
@@ -523,6 +523,15 @@
# it faster on the fly.
#upstream_gzip = False
+# The following default adds a header to web request responses that 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
+# configuring a proxy to sit infront of Galaxy - please ensure this header
+# remains intact to protect your users. Uncomment and leave empty to not set
+# the `X-Frame-Options` header.
+#x_frame_options = SAMEORIGIN
+
# nginx can also handle file uploads (user-to-Galaxy) via nginx_upload_module.
# Configuration for this is complex and explained in detail in the
# documentation linked above. The upload store is a temporary directory in
diff -r 39ebfe2e1f1806137bb3f117845f788daaf185aa -r c7d09076b630f1ea42fc62e3e4c2dae5332b6892 lib/galaxy/config.py
--- a/lib/galaxy/config.py
+++ b/lib/galaxy/config.py
@@ -96,6 +96,7 @@
# been migrated from the Galaxy code distribution to the Tool Shed.
self.check_migrate_tools = string_as_bool( kwargs.get( 'check_migrate_tools', True ) )
self.shed_tool_data_path = kwargs.get( "shed_tool_data_path", None )
+ self.x_frame_options = kwargs.get( "x_frame_options", "SAMEORIGIN" )
if self.shed_tool_data_path:
self.shed_tool_data_path = resolve_path( self.shed_tool_data_path, self.root )
else:
diff -r 39ebfe2e1f1806137bb3f117845f788daaf185aa -r c7d09076b630f1ea42fc62e3e4c2dae5332b6892 lib/galaxy/web/framework/webapp.py
--- a/lib/galaxy/web/framework/webapp.py
+++ b/lib/galaxy/web/framework/webapp.py
@@ -175,7 +175,11 @@
base.DefaultWebTransaction.__init__( self, environ )
self.setup_i18n()
self.expunge_all()
- self.debug = asbool( self.app.config.get( 'debug', False ) )
+ config = self.app.config
+ self.debug = asbool( config.get( 'debug', False ) )
+ x_frame_options = getattr( config, 'x_frame_options', None )
+ if x_frame_options:
+ self.response.headers['X-Frame-Options'] = x_frame_options
# Flag indicating whether we are in workflow building mode (means
# that the current history should not be used for parameter values
# and such).
@@ -202,9 +206,9 @@
# When we've authenticated by session, we have to check the
# following.
# Prevent deleted users from accessing Galaxy
- if self.app.config.use_remote_user and self.galaxy_session.user.deleted:
+ if config.use_remote_user and self.galaxy_session.user.deleted:
self.response.send_redirect( url_for( '/static/user_disabled.html' ) )
- if self.app.config.require_login:
+ if config.require_login:
self._ensure_logged_in_user( environ, session_cookie )
def setup_i18n( self ):
@@ -261,6 +265,9 @@
tstamp = time.localtime( time.time() + 3600 * 24 * age )
self.response.cookies[name]['expires'] = time.strftime( '%a, %d-%b-%Y %H:%M:%S GMT', tstamp )
self.response.cookies[name]['version'] = version
+ https = self.request.environ[ "wsgi.url_scheme" ] == "https"
+ if https:
+ self.response.cookies[name]['secure'] = True
try:
self.response.cookies[name]['httponly'] = True
except CookieError, 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
3 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/bca09a437845/
Changeset: bca09a437845
Branch: next-stable
User: jmchilton
Date: 2014-11-25 14:59:40+00:00
Summary: Enable defense against clickjacking out of the box.
Look in config/galaxy.ini.sample for the option 'x_frame_options' for more information.
Affected #: 3 files
diff -r c1a9ed13d5f71deb671ab83ed262c0a861c469d2 -r bca09a437845ad229b141a33174894e90f36d916 config/galaxy.ini.sample
--- a/config/galaxy.ini.sample
+++ b/config/galaxy.ini.sample
@@ -523,6 +523,15 @@
# it faster on the fly.
#upstream_gzip = False
+# The following default adds a header to web request responses that 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
+# configuring a proxy to sit infront of Galaxy - please ensure this header
+# remains intact to protect your users. Uncomment and leave empty to not set
+# the `X-Frame-Options` header.
+#x_frame_options = SAMEORIGIN
+
# nginx can also handle file uploads (user-to-Galaxy) via nginx_upload_module.
# Configuration for this is complex and explained in detail in the
# documentation linked above. The upload store is a temporary directory in
diff -r c1a9ed13d5f71deb671ab83ed262c0a861c469d2 -r bca09a437845ad229b141a33174894e90f36d916 lib/galaxy/config.py
--- a/lib/galaxy/config.py
+++ b/lib/galaxy/config.py
@@ -96,6 +96,7 @@
# been migrated from the Galaxy code distribution to the Tool Shed.
self.check_migrate_tools = string_as_bool( kwargs.get( 'check_migrate_tools', True ) )
self.shed_tool_data_path = kwargs.get( "shed_tool_data_path", None )
+ self.x_frame_options = kwargs.get( "x_frame_options", "SAMEORIGIN" )
if self.shed_tool_data_path:
self.shed_tool_data_path = resolve_path( self.shed_tool_data_path, self.root )
else:
diff -r c1a9ed13d5f71deb671ab83ed262c0a861c469d2 -r bca09a437845ad229b141a33174894e90f36d916 lib/galaxy/web/framework/webapp.py
--- a/lib/galaxy/web/framework/webapp.py
+++ b/lib/galaxy/web/framework/webapp.py
@@ -175,7 +175,11 @@
base.DefaultWebTransaction.__init__( self, environ )
self.setup_i18n()
self.expunge_all()
- self.debug = asbool( self.app.config.get( 'debug', False ) )
+ config = self.app.config
+ self.debug = asbool( config.get( 'debug', False ) )
+ x_frame_options = getattr( config, 'x_frame_options', None )
+ if x_frame_options:
+ self.response.headers['X-Frame-Options'] = x_frame_options
# Flag indicating whether we are in workflow building mode (means
# that the current history should not be used for parameter values
# and such).
@@ -202,9 +206,9 @@
# When we've authenticated by session, we have to check the
# following.
# Prevent deleted users from accessing Galaxy
- if self.app.config.use_remote_user and self.galaxy_session.user.deleted:
+ if config.use_remote_user and self.galaxy_session.user.deleted:
self.response.send_redirect( url_for( '/static/user_disabled.html' ) )
- if self.app.config.require_login:
+ if config.require_login:
self._ensure_logged_in_user( environ, session_cookie )
def setup_i18n( self ):
https://bitbucket.org/galaxy/galaxy-central/commits/696b29477881/
Changeset: 696b29477881
Branch: next-stable
User: jmchilton
Date: 2014-11-25 14:59:40+00:00
Summary: Issue session cookies using 'secure' flag for HTTPS requests.
For more information see https://www.owasp.org/index.php/SecureFlag.
Affected #: 1 file
diff -r bca09a437845ad229b141a33174894e90f36d916 -r 696b294778817e68975140bde91894dce5f82299 lib/galaxy/web/framework/webapp.py
--- a/lib/galaxy/web/framework/webapp.py
+++ b/lib/galaxy/web/framework/webapp.py
@@ -265,6 +265,9 @@
tstamp = time.localtime( time.time() + 3600 * 24 * age )
self.response.cookies[name]['expires'] = time.strftime( '%a, %d-%b-%Y %H:%M:%S GMT', tstamp )
self.response.cookies[name]['version'] = version
+ https = self.request.environ[ "wsgi.url_scheme" ] == "https"
+ if https:
+ self.response.cookies[name]['secure'] = True
try:
self.response.cookies[name]['httponly'] = True
except CookieError, e:
https://bitbucket.org/galaxy/galaxy-central/commits/c7d09076b630/
Changeset: c7d09076b630
Branch: next-stable
User: dannon
Date: 2014-11-25 17:27:41+00:00
Summary: Merged in jmchilton/galaxy-central-fork-1/next-stable (pull request #573)
Enhanced client security.
Affected #: 3 files
diff -r 39ebfe2e1f1806137bb3f117845f788daaf185aa -r c7d09076b630f1ea42fc62e3e4c2dae5332b6892 config/galaxy.ini.sample
--- a/config/galaxy.ini.sample
+++ b/config/galaxy.ini.sample
@@ -523,6 +523,15 @@
# it faster on the fly.
#upstream_gzip = False
+# The following default adds a header to web request responses that 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
+# configuring a proxy to sit infront of Galaxy - please ensure this header
+# remains intact to protect your users. Uncomment and leave empty to not set
+# the `X-Frame-Options` header.
+#x_frame_options = SAMEORIGIN
+
# nginx can also handle file uploads (user-to-Galaxy) via nginx_upload_module.
# Configuration for this is complex and explained in detail in the
# documentation linked above. The upload store is a temporary directory in
diff -r 39ebfe2e1f1806137bb3f117845f788daaf185aa -r c7d09076b630f1ea42fc62e3e4c2dae5332b6892 lib/galaxy/config.py
--- a/lib/galaxy/config.py
+++ b/lib/galaxy/config.py
@@ -96,6 +96,7 @@
# been migrated from the Galaxy code distribution to the Tool Shed.
self.check_migrate_tools = string_as_bool( kwargs.get( 'check_migrate_tools', True ) )
self.shed_tool_data_path = kwargs.get( "shed_tool_data_path", None )
+ self.x_frame_options = kwargs.get( "x_frame_options", "SAMEORIGIN" )
if self.shed_tool_data_path:
self.shed_tool_data_path = resolve_path( self.shed_tool_data_path, self.root )
else:
diff -r 39ebfe2e1f1806137bb3f117845f788daaf185aa -r c7d09076b630f1ea42fc62e3e4c2dae5332b6892 lib/galaxy/web/framework/webapp.py
--- a/lib/galaxy/web/framework/webapp.py
+++ b/lib/galaxy/web/framework/webapp.py
@@ -175,7 +175,11 @@
base.DefaultWebTransaction.__init__( self, environ )
self.setup_i18n()
self.expunge_all()
- self.debug = asbool( self.app.config.get( 'debug', False ) )
+ config = self.app.config
+ self.debug = asbool( config.get( 'debug', False ) )
+ x_frame_options = getattr( config, 'x_frame_options', None )
+ if x_frame_options:
+ self.response.headers['X-Frame-Options'] = x_frame_options
# Flag indicating whether we are in workflow building mode (means
# that the current history should not be used for parameter values
# and such).
@@ -202,9 +206,9 @@
# When we've authenticated by session, we have to check the
# following.
# Prevent deleted users from accessing Galaxy
- if self.app.config.use_remote_user and self.galaxy_session.user.deleted:
+ if config.use_remote_user and self.galaxy_session.user.deleted:
self.response.send_redirect( url_for( '/static/user_disabled.html' ) )
- if self.app.config.require_login:
+ if config.require_login:
self._ensure_logged_in_user( environ, session_cookie )
def setup_i18n( self ):
@@ -261,6 +265,9 @@
tstamp = time.localtime( time.time() + 3600 * 24 * age )
self.response.cookies[name]['expires'] = time.strftime( '%a, %d-%b-%Y %H:%M:%S GMT', tstamp )
self.response.cookies[name]['version'] = version
+ https = self.request.environ[ "wsgi.url_scheme" ] == "https"
+ if https:
+ self.response.cookies[name]['secure'] = True
try:
self.response.cookies[name]['httponly'] = True
except CookieError, 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: martenson: change masthead's 'Analyze data' link target to / instead of /root/index for analytics purposes
by commits-noreply@bitbucket.org 25 Nov '14
by commits-noreply@bitbucket.org 25 Nov '14
25 Nov '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/39ebfe2e1f18/
Changeset: 39ebfe2e1f18
Branch: next-stable
User: martenson
Date: 2014-11-25 17:00:31+00:00
Summary: change masthead's 'Analyze data' link target to / instead of /root/index for analytics purposes
Affected #: 3 files
diff -r df35b41ceaac11150513913f86926a379094b09d -r 39ebfe2e1f1806137bb3f117845f788daaf185aa client/galaxy/scripts/galaxy.menu.js
--- a/client/galaxy/scripts/galaxy.menu.js
+++ b/client/galaxy/scripts/galaxy.menu.js
@@ -24,7 +24,7 @@
var tab_analysis = new mod_masthead.GalaxyMastheadTab({
id : "analysis",
title : "Analyze Data",
- content : "root/index",
+ content : "",
title_attribute : 'Analysis home view'
});
this.masthead.append(tab_analysis);
diff -r df35b41ceaac11150513913f86926a379094b09d -r 39ebfe2e1f1806137bb3f117845f788daaf185aa static/scripts/galaxy.menu.js
--- a/static/scripts/galaxy.menu.js
+++ b/static/scripts/galaxy.menu.js
@@ -24,7 +24,7 @@
var tab_analysis = new mod_masthead.GalaxyMastheadTab({
id : "analysis",
title : "Analyze Data",
- content : "root/index",
+ content : "",
title_attribute : 'Analysis home view'
});
this.masthead.append(tab_analysis);
diff -r df35b41ceaac11150513913f86926a379094b09d -r 39ebfe2e1f1806137bb3f117845f788daaf185aa static/scripts/packed/galaxy.menu.js
--- a/static/scripts/packed/galaxy.menu.js
+++ b/static/scripts/packed/galaxy.menu.js
@@ -1,1 +1,1 @@
-define(["galaxy.masthead"],function(b){var a=Backbone.Model.extend({options:null,masthead:null,initialize:function(c){this.options=c.config;this.masthead=c.masthead;this.create()},create:function(){var e=new b.GalaxyMastheadTab({id:"analysis",title:"Analyze Data",content:"root/index",title_attribute:"Analysis home view"});this.masthead.append(e);var g={id:"workflow",title:"Workflow",content:"workflow",title_attribute:"Chain tools into workflows"};if(!this.options.user.valid){g.disabled=true}var d=new b.GalaxyMastheadTab(g);this.masthead.append(d);var i=new b.GalaxyMastheadTab({id:"shared",title:"Shared Data",content:"library/index",title_attribute:"Access published resources"});i.add({title:"Data Libraries",content:"library/index"});i.add({title:"Data Libraries Beta",content:"library/list",divider:true});i.add({title:"Published Histories",content:"history/list_published"});i.add({title:"Published Workflows",content:"workflow/list_published"});i.add({title:"Published Visualizations",content:"visualization/list_published"});i.add({title:"Published Pages",content:"page/list_published"});this.masthead.append(i);if(this.options.user.requests){var j=new b.GalaxyMastheadTab({id:"lab",title:"Lab"});j.add({title:"Sequencing Requests",content:"requests/index"});j.add({title:"Find Samples",content:"requests/find_samples_index"});j.add({title:"Help",content:this.options.lims_doc_url});this.masthead.append(j)}var c={id:"visualization",title:"Visualization",content:"visualization/list",title_attribute:"Visualize datasets"};if(!this.options.user.valid){c.disabled=true}var m=new b.GalaxyMastheadTab(c);if(this.options.user.valid){m.add({title:"New Track Browser",content:"visualization/trackster",target:"_frame"});m.add({title:"Saved Visualizations",content:"visualization/list",target:"_frame"})}this.masthead.append(m);if(this.options.enable_cloud_launch){var f=new b.GalaxyMastheadTab({id:"cloud",title:"Cloud",content:"cloudlaunch/index"});f.add({title:"New Cloud Cluster",content:"cloudlaunch/index"});this.masthead.append(f)}if(this.options.is_admin_user){var h=new b.GalaxyMastheadTab({id:"admin",title:"Admin",content:"admin/index",extra_class:"admin-only",title_attribute:"Administer this Galaxy"});this.masthead.append(h)}var l=new b.GalaxyMastheadTab({id:"help",title:"Help",title_attribute:"Support, contact, and community hubs"});if(this.options.biostar_url){l.add({title:"Galaxy Biostar",content:this.options.biostar_url_redirect,target:"_blank"});l.add({title:"Ask a question",content:"biostar/biostar_question_redirect",target:"_blank"})}l.add({title:"Support",content:this.options.support_url,target:"_blank"});l.add({title:"Search",content:this.options.search_url,target:"_blank"});l.add({title:"Mailing Lists",content:this.options.mailing_lists,target:"_blank"});l.add({title:"Videos",content:this.options.screencasts_url,target:"_blank"});l.add({title:"Wiki",content:this.options.wiki_url,target:"_blank"});l.add({title:"How to Cite Galaxy",content:this.options.citation_url,target:"_blank"});if(this.options.terms_url){l.add({title:"Terms and Conditions",content:this.options.terms_url,target:"_blank"})}this.masthead.append(l);if(!this.options.user.valid){var k=new b.GalaxyMastheadTab({id:"user",title:"User",extra_class:"loggedout-only",title_attribute:"Account registration or login"});k.add({title:"Login",content:"user/login",target:"galaxy_main"});if(this.options.allow_user_creation){k.add({title:"Register",content:"user/create",target:"galaxy_main"})}this.masthead.append(k)}else{var k=new b.GalaxyMastheadTab({id:"user",title:"User",extra_class:"loggedin-only",title_attribute:"Account preferences and saved data"});k.add({title:"Logged in as "+this.options.user.email});k.add({title:"Preferences",content:"user?cntrller=user",target:"galaxy_main"});k.add({title:"Custom Builds",content:"user/dbkeys",target:"galaxy_main"});k.add({title:"Logout",content:"user/logout",target:"_top",divider:true});k.add({title:"Saved Histories",content:"history/list",target:"galaxy_main"});k.add({title:"Saved Datasets",content:"dataset/list",target:"galaxy_main"});k.add({title:"Saved Pages",content:"page/list",target:"_top"});k.add({title:"API Keys",content:"user/api_keys?cntrller=user",target:"galaxy_main"});if(this.options.use_remote_user){k.add({title:"Public Name",content:"user/edit_username?cntrller=user",target:"galaxy_main"})}this.masthead.append(k)}if(this.options.active_view){this.masthead.highlight(this.options.active_view)}}});return{GalaxyMenu:a}});
\ No newline at end of file
+define(["galaxy.masthead"],function(b){var a=Backbone.Model.extend({options:null,masthead:null,initialize:function(c){this.options=c.config;this.masthead=c.masthead;this.create()},create:function(){var e=new b.GalaxyMastheadTab({id:"analysis",title:"Analyze Data",content:"",title_attribute:"Analysis home view"});this.masthead.append(e);var g={id:"workflow",title:"Workflow",content:"workflow",title_attribute:"Chain tools into workflows"};if(!this.options.user.valid){g.disabled=true}var d=new b.GalaxyMastheadTab(g);this.masthead.append(d);var i=new b.GalaxyMastheadTab({id:"shared",title:"Shared Data",content:"library/index",title_attribute:"Access published resources"});i.add({title:"Data Libraries",content:"library/index"});i.add({title:"Data Libraries Beta",content:"library/list",divider:true});i.add({title:"Published Histories",content:"history/list_published"});i.add({title:"Published Workflows",content:"workflow/list_published"});i.add({title:"Published Visualizations",content:"visualization/list_published"});i.add({title:"Published Pages",content:"page/list_published"});this.masthead.append(i);if(this.options.user.requests){var j=new b.GalaxyMastheadTab({id:"lab",title:"Lab"});j.add({title:"Sequencing Requests",content:"requests/index"});j.add({title:"Find Samples",content:"requests/find_samples_index"});j.add({title:"Help",content:this.options.lims_doc_url});this.masthead.append(j)}var c={id:"visualization",title:"Visualization",content:"visualization/list",title_attribute:"Visualize datasets"};if(!this.options.user.valid){c.disabled=true}var m=new b.GalaxyMastheadTab(c);if(this.options.user.valid){m.add({title:"New Track Browser",content:"visualization/trackster",target:"_frame"});m.add({title:"Saved Visualizations",content:"visualization/list",target:"_frame"})}this.masthead.append(m);if(this.options.enable_cloud_launch){var f=new b.GalaxyMastheadTab({id:"cloud",title:"Cloud",content:"cloudlaunch/index"});f.add({title:"New Cloud Cluster",content:"cloudlaunch/index"});this.masthead.append(f)}if(this.options.is_admin_user){var h=new b.GalaxyMastheadTab({id:"admin",title:"Admin",content:"admin/index",extra_class:"admin-only",title_attribute:"Administer this Galaxy"});this.masthead.append(h)}var l=new b.GalaxyMastheadTab({id:"help",title:"Help",title_attribute:"Support, contact, and community hubs"});if(this.options.biostar_url){l.add({title:"Galaxy Biostar",content:this.options.biostar_url_redirect,target:"_blank"});l.add({title:"Ask a question",content:"biostar/biostar_question_redirect",target:"_blank"})}l.add({title:"Support",content:this.options.support_url,target:"_blank"});l.add({title:"Search",content:this.options.search_url,target:"_blank"});l.add({title:"Mailing Lists",content:this.options.mailing_lists,target:"_blank"});l.add({title:"Videos",content:this.options.screencasts_url,target:"_blank"});l.add({title:"Wiki",content:this.options.wiki_url,target:"_blank"});l.add({title:"How to Cite Galaxy",content:this.options.citation_url,target:"_blank"});if(this.options.terms_url){l.add({title:"Terms and Conditions",content:this.options.terms_url,target:"_blank"})}this.masthead.append(l);if(!this.options.user.valid){var k=new b.GalaxyMastheadTab({id:"user",title:"User",extra_class:"loggedout-only",title_attribute:"Account registration or login"});k.add({title:"Login",content:"user/login",target:"galaxy_main"});if(this.options.allow_user_creation){k.add({title:"Register",content:"user/create",target:"galaxy_main"})}this.masthead.append(k)}else{var k=new b.GalaxyMastheadTab({id:"user",title:"User",extra_class:"loggedin-only",title_attribute:"Account preferences and saved data"});k.add({title:"Logged in as "+this.options.user.email});k.add({title:"Preferences",content:"user?cntrller=user",target:"galaxy_main"});k.add({title:"Custom Builds",content:"user/dbkeys",target:"galaxy_main"});k.add({title:"Logout",content:"user/logout",target:"_top",divider:true});k.add({title:"Saved Histories",content:"history/list",target:"galaxy_main"});k.add({title:"Saved Datasets",content:"dataset/list",target:"galaxy_main"});k.add({title:"Saved Pages",content:"page/list",target:"_top"});k.add({title:"API Keys",content:"user/api_keys?cntrller=user",target:"galaxy_main"});if(this.options.use_remote_user){k.add({title:"Public Name",content:"user/edit_username?cntrller=user",target:"galaxy_main"})}this.masthead.append(k)}if(this.options.active_view){this.masthead.highlight(this.options.active_view)}}});return{GalaxyMenu:a}});
\ 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: natefoo: Update tag latest_2014.10.06 for changeset adc4aa8b3d9a
by commits-noreply@bitbucket.org 25 Nov '14
by commits-noreply@bitbucket.org 25 Nov '14
25 Nov '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/c50a228167b0/
Changeset: c50a228167b0
Branch: stable
User: natefoo
Date: 2014-11-25 17:00:20+00:00
Summary: Update tag latest_2014.10.06 for changeset adc4aa8b3d9a
Affected #: 1 file
diff -r adc4aa8b3d9ad77ef85f8b0d7e4d90bd29775167 -r c50a228167b0a1a4541f46bb19b8d67c9010248d .hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -20,4 +20,4 @@
ca45b78adb4152fc6e7395514d46eba6b7d0b838 release_2014.08.11
548ab24667d6206780237bd807f7d857a484c461 latest_2014.08.11
2092948937ac30ef82f71463a235c66d34987088 release_2014.10.06
-bb79e87274d7ef4e043a84aeef8516a5418ef3b6 latest_2014.10.06
+adc4aa8b3d9ad77ef85f8b0d7e4d90bd29775167 latest_2014.10.06
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
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/46c3d2a06212/
Changeset: 46c3d2a06212
Branch: next-stable
User: JanKanis
Date: 2014-11-13 15:48:02+00:00
Summary: use first component of X-Forwarded-{For,Host,Scheme}
X-Forwarded-{For,Host,Scheme} can contain multiple comma-separated components if there are multiple reverse proxies. Use the first (outer) one.
See http://httpd.apache.org/docs/2.4/mod/mod_proxy.html#x-headers for apache docs.
Affected #: 1 file
diff -r c1a9ed13d5f71deb671ab83ed262c0a861c469d2 -r 46c3d2a06212b61a0ab14d7790bf1167dc65b653 lib/galaxy/web/framework/middleware/xforwardedhost.py
--- a/lib/galaxy/web/framework/middleware/xforwardedhost.py
+++ b/lib/galaxy/web/framework/middleware/xforwardedhost.py
@@ -9,13 +9,13 @@
x_forwarded_host = environ.get( 'HTTP_X_FORWARDED_HOST', None )
if x_forwarded_host:
environ[ 'ORGINAL_HTTP_HOST' ] = environ[ 'HTTP_HOST' ]
- environ[ 'HTTP_HOST' ] = x_forwarded_host
+ environ[ 'HTTP_HOST' ] = x_forwarded_host.split(', ', 1)[0]
x_forwarded_for = environ.get( 'HTTP_X_FORWARDED_FOR', None )
if x_forwarded_for:
environ[ 'ORGINAL_REMOTE_ADDR' ] = environ[ 'REMOTE_ADDR' ]
- environ[ 'REMOTE_ADDR' ] = x_forwarded_for
+ environ[ 'REMOTE_ADDR' ] = x_forwarded_for.split(', ', 1)[0]
x_url_scheme = environ.get( 'HTTP_X_URL_SCHEME', None )
if x_url_scheme:
environ[ 'original_wsgi.url_scheme' ] = environ[ 'wsgi.url_scheme' ]
- environ[ 'wsgi.url_scheme' ] = x_url_scheme
+ environ[ 'wsgi.url_scheme' ] = x_url_scheme.split(', ', 1)[0]
return self.app( environ, start_response )
https://bitbucket.org/galaxy/galaxy-central/commits/df35b41ceaac/
Changeset: df35b41ceaac
Branch: next-stable
User: dannon
Date: 2014-11-25 16:33:26+00:00
Summary: Remove unnecessary split on wsgi.url_scheme
Affected #: 1 file
diff -r 46c3d2a06212b61a0ab14d7790bf1167dc65b653 -r df35b41ceaac11150513913f86926a379094b09d lib/galaxy/web/framework/middleware/xforwardedhost.py
--- a/lib/galaxy/web/framework/middleware/xforwardedhost.py
+++ b/lib/galaxy/web/framework/middleware/xforwardedhost.py
@@ -5,6 +5,7 @@
"""
def __init__( self, app, global_conf=None ):
self.app = app
+
def __call__( self, environ, start_response ):
x_forwarded_host = environ.get( 'HTTP_X_FORWARDED_HOST', None )
if x_forwarded_host:
@@ -17,5 +18,5 @@
x_url_scheme = environ.get( 'HTTP_X_URL_SCHEME', None )
if x_url_scheme:
environ[ 'original_wsgi.url_scheme' ] = environ[ 'wsgi.url_scheme' ]
- environ[ 'wsgi.url_scheme' ] = x_url_scheme.split(', ', 1)[0]
+ environ[ 'wsgi.url_scheme' ] = x_url_scheme
return self.app( environ, start_response )
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: jmchilton: Sanitize object names throughout templates.
by commits-noreply@bitbucket.org 25 Nov '14
by commits-noreply@bitbucket.org 25 Nov '14
25 Nov '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/adc4aa8b3d9a/
Changeset: adc4aa8b3d9a
Branch: stable
User: jmchilton
Date: 2014-11-24 15:06:11+00:00
Summary: Sanitize object names throughout templates.
Affected #: 7 files
diff -r cae8a513079a183d16bd8a16b915d6aa5322a249 -r adc4aa8b3d9ad77ef85f8b0d7e4d90bd29775167 templates/display_base.mako
--- a/templates/display_base.mako
+++ b/templates/display_base.mako
@@ -214,7 +214,7 @@
%else:
Private ${get_class_display_name( item.__class__ )}
%endif
- | ${get_item_name( item )}
+ | ${get_item_name( item ) | h}
<div style="float: right">
${self.render_item_links( item )}
diff -r cae8a513079a183d16bd8a16b915d6aa5322a249 -r adc4aa8b3d9ad77ef85f8b0d7e4d90bd29775167 templates/embed_base.mako
--- a/templates/embed_base.mako
+++ b/templates/embed_base.mako
@@ -49,7 +49,7 @@
<div style="float: right;">
${self.render_item_links( item )}
</div>
- <h4><a class="toggle-embed" href="${display_href}" title="Show or hide ${item_display_name} content">Galaxy ${get_class_display_name( item.__class__ )} | ${get_item_name( item )}</a></h4>
+ <h4><a class="toggle-embed" href="${display_href}" title="Show or hide ${item_display_name} content">Galaxy ${get_class_display_name( item.__class__ )} | ${get_item_name( item ) | h}</a></h4>
%if hasattr( item, "annotation") and item.annotation:
<div class="annotation">${item.annotation}</div>
%endif
diff -r cae8a513079a183d16bd8a16b915d6aa5322a249 -r adc4aa8b3d9ad77ef85f8b0d7e4d90bd29775167 templates/export_base.mako
--- a/templates/export_base.mako
+++ b/templates/export_base.mako
@@ -42,7 +42,7 @@
</%def><%def name="title()">
- Export ${get_class_display_name( item.__class__ )} '${get_item_name( item )}'
+ Export ${get_class_display_name( item.__class__ )} '${get_item_name( item ) | h}'
</%def><%def name="stylesheets()">
@@ -108,7 +108,7 @@
<%
item_name = get_item_name(item)
%>
- <h2>Download or Export ${self.item_class_name} '${item_name}'</h2>
+ <h2>Download or Export ${self.item_class_name} '${item_name | h}'</h2>
${self.render_download_to_file(item)}
diff -r cae8a513079a183d16bd8a16b915d6aa5322a249 -r adc4aa8b3d9ad77ef85f8b0d7e4d90bd29775167 templates/ind_share_base.mako
--- a/templates/ind_share_base.mako
+++ b/templates/ind_share_base.mako
@@ -83,7 +83,7 @@
%><div class="toolForm">
- <div class="toolFormTitle">Share ${item_class_name} '${item_name}' with Another User</div>
+ <div class="toolFormTitle">Share ${item_class_name} '${item_name | h}' with Another User</div><div class="toolFormBody"><form action="${h.url_for(controller=item_controller, action='share', id=trans.security.encode_id( item.id ) )}" method="POST"><div class="form-row">
diff -r cae8a513079a183d16bd8a16b915d6aa5322a249 -r adc4aa8b3d9ad77ef85f8b0d7e4d90bd29775167 templates/sharing_base.mako
--- a/templates/sharing_base.mako
+++ b/templates/sharing_base.mako
@@ -35,7 +35,7 @@
</%def><%def name="title()">
- Sharing and Publishing ${get_class_display_name( item.__class__ )} '${get_item_name( item )}'
+ Sharing and Publishing ${get_class_display_name( item.__class__ )} '${get_item_name( item ) | h}'
</%def><%def name="javascripts()">
@@ -122,7 +122,7 @@
item_name = get_item_name(item)
%>
- <h2>Share or Publish ${item_class_name} '${item_name}'</h2>
+ <h2>Share or Publish ${item_class_name} '${item_name | h}'</h2>
## Require that user have a public username before sharing or publishing an item.
%if trans.get_user().username is None or trans.get_user().username is "":
diff -r cae8a513079a183d16bd8a16b915d6aa5322a249 -r adc4aa8b3d9ad77ef85f8b0d7e4d90bd29775167 templates/webapps/galaxy/history/embed.mako
--- a/templates/webapps/galaxy/history/embed.mako
+++ b/templates/webapps/galaxy/history/embed.mako
@@ -20,7 +20,7 @@
</div><h4><a class="toggle-embed" href="${display_href}" title="Show or hide history contents">
- Galaxy History | ${get_item_name( item )}
+ Galaxy History | ${get_item_name( item ) | h}
</a></h4>
%if hasattr( item, "annotation") and item.annotation:
diff -r cae8a513079a183d16bd8a16b915d6aa5322a249 -r adc4aa8b3d9ad77ef85f8b0d7e4d90bd29775167 templates/webapps/galaxy/mobile/history/list.mako
--- a/templates/webapps/galaxy/mobile/history/list.mako
+++ b/templates/webapps/galaxy/mobile/history/list.mako
@@ -20,7 +20,7 @@
<li><a href="${h.url_for(controller='mobile', action="history_detail", id=history.id )}">
- ${history.name}
+ ${history.name | h}
<div class="secondary">${h.date.distance_of_time_in_words( history.update_time, h.date.datetime.utcnow() )} ago</div>
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