galaxy-commits
Threads by month
- ----- 2026 -----
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- 15302 discussions
commit/galaxy-central: guerler: Webhelpers: Shorten time ago string
by commits-noreply@bitbucket.org 25 Jan '14
by commits-noreply@bitbucket.org 25 Jan '14
25 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/c5caf4ce55aa/
Changeset: c5caf4ce55aa
User: guerler
Date: 2014-01-25 06:07:12
Summary: Webhelpers: Shorten time ago string
Affected #: 1 file
diff -r 4362d887f48fe1891f46fc1ee435045b79c3779a -r c5caf4ce55aa0102b85032805ddd50445cb03002 lib/galaxy/web/framework/helpers/__init__.py
--- a/lib/galaxy/web/framework/helpers/__init__.py
+++ b/lib/galaxy/web/framework/helpers/__init__.py
@@ -28,7 +28,8 @@
if (datetime.utcnow() - x) > delta: # Greater than a week difference
return x.strftime("%b %d, %Y")
else:
- return date.distance_of_time_in_words( x, datetime.utcnow() ).replace("about", "~") + " ago"
+ date_array = date.distance_of_time_in_words( x, datetime.utcnow() ).replace(",", "").split(" ")
+ return "~%s %s ago" % (date_array[0], date_array[1])
def iff( a, b, c ):
"""
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: guerler: Upload: Reduce line height
by commits-noreply@bitbucket.org 25 Jan '14
by commits-noreply@bitbucket.org 25 Jan '14
25 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/4362d887f48f/
Changeset: 4362d887f48f
User: guerler
Date: 2014-01-25 00:12:47
Summary: Upload: Reduce line height
Affected #: 2 files
diff -r b48698ef4da4976dcd177e81a6e45381310337c6 -r 4362d887f48fe1891f46fc1ee435045b79c3779a static/style/blue/base.css
--- a/static/style/blue/base.css
+++ b/static/style/blue/base.css
@@ -1255,7 +1255,7 @@
.progress-button .progress-bar-success{background:#aff1af;border:0px}
.progress-button .progress-bar-info{background:#ffc}
.progress-button .progress-bar-notransition{-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none}
-.progress-button .label{position:absolute;top:0px;width:inherit;text-align:center;line-height:20px}
+.progress-button .label{position:absolute;top:0px;width:inherit;text-align:center;line-height:19px}
.upload-info{font-weight:normal;text-align:center}
.upload-box{width:100%;height:95%;text-align:center;overflow:scroll;font-size:12px;line-height:1.33;-moz-border-radius:5px;border-radius:5px;border:1px dashed #bfbfbf;padding:10px;overflow-x:hidden;-ms-overflow-style:none}.upload-box .table{width:100%}
.upload-box .table th{text-align:center;white-space:nowrap}
diff -r b48698ef4da4976dcd177e81a6e45381310337c6 -r 4362d887f48fe1891f46fc1ee435045b79c3779a static/style/src/less/upload.less
--- a/static/style/src/less/upload.less
+++ b/static/style/src/less/upload.less
@@ -39,7 +39,7 @@
top: 0px;
width: inherit;
text-align: center;
- line-height: 20px;
+ line-height: 19px;
}
}
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: guerler: Upload: Improve progress button styles
by commits-noreply@bitbucket.org 25 Jan '14
by commits-noreply@bitbucket.org 25 Jan '14
25 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/b48698ef4da4/
Changeset: b48698ef4da4
User: guerler
Date: 2014-01-25 00:08:37
Summary: Upload: Improve progress button styles
Affected #: 4 files
diff -r b7c11187252fd308a1c0878f33cc8742c9287eaa -r b48698ef4da4976dcd177e81a6e45381310337c6 static/scripts/mvc/upload/upload-view.js
--- a/static/scripts/mvc/upload/upload-view.js
+++ b/static/scripts/mvc/upload/upload-view.js
@@ -93,7 +93,8 @@
'<div class="progress">' +
'<div class="progress-bar"></div>' +
'</div>' +
- '<div id="label" class="label" style="position: absolute; top: 0px; width: inherit; text-align: center;"><div class="fa ' + options.icon + '"></div> ' + options.label + '</div>' +
+ '<div id="label" class="label">' +
+ '<div class="fa ' + options.icon + '"></div> ' + options.label + '</div>' +
'</div>';
}
});
diff -r b7c11187252fd308a1c0878f33cc8742c9287eaa -r b48698ef4da4976dcd177e81a6e45381310337c6 static/scripts/packed/mvc/upload/upload-view.js
--- a/static/scripts/packed/mvc/upload/upload-view.js
+++ b/static/scripts/packed/mvc/upload/upload-view.js
@@ -1,1 +1,1 @@
-define(["galaxy.modal","utils/utils","mvc/upload/upload-model","mvc/upload/upload-row","mvc/ui","utils/uploadbox"],function(c,f,e,d){var b=Backbone.Model.extend({defaults:{percentage:0,icon:"fa-circle",label:"",status:""}});var a=Backbone.View.extend({model:null,initialize:function(h){var g=this;this.model=h;this.options=this.model.attributes;this.setElement(this._template(this.options));$(this.el).on("click",this.options.onclick);if(this.options.tooltip){$(this.el).tooltip({title:this.options.tooltip,placement:"bottom"})}this.model.on("change:percentage",function(){g._percentage(g.model.get("percentage"))});this.model.on("change:status",function(){g._status(g.model.get("status"))});var g=this;$(window).on("beforeunload",function(){var i="";if(g.options.onunload){i=g.options.onunload()}if(i!=""){return i}})},_status:function(h){var g=this.$el.find(".progress-bar");g.removeClass();g.addClass("progress-bar");g.addClass("progress-bar-notransition");if(h!=""){g.addClass("progress-bar-"+h)}},_percentage:function(h){var g=this.$el.find(".progress-bar");g.css({width:h+"%"})},_template:function(g){return'<div class="progress-button"><div class="progress"><div class="progress-bar"></div></div><div id="label" class="label" style="position: absolute; top: 0px; width: inherit; text-align: center;"><div class="fa '+g.icon+'"></div> '+g.label+"</div></div>"}});return Backbone.View.extend({modal:null,button_show:null,uploadbox:null,current_history:null,upload_size:0,select_extension:[["Auto-detect","auto"]],select_genome:[["Unspecified (?)","?"]],collection:new e.Collection(),counter:{announce:0,success:0,error:0,running:0,reset:function(){this.announce=this.success=this.error=this.running=0}},options:{nginx_upload_path:""},initialize:function(h){var g=this;if(!Galaxy.currHistoryPanel||!Galaxy.currHistoryPanel.model){window.setTimeout(function(){g.initialize()},500);return}if(!Galaxy.currUser.get("id")){return}this.button_show=new b({icon:"fa-upload",tooltip:"Download from URL or upload files from disk",label:"Load Data",onclick:function(i){if(i){g._eventShow(i)}},onunload:function(){if(g.counter.running>0){return"Several uploads are still processing."}}});$("#left .unified-panel-header-inner").append((new a(this.button_show)).$el);var g=this;f.jsonFromUrl(galaxy_config.root+"api/datatypes",function(i){for(key in i){g.select_extension.push([i[key],i[key]])}});f.jsonFromUrl(galaxy_config.root+"api/genomes",function(i){var j=g.select_genome[0];g.select_genome=[];for(key in i){if(i[key].length>1){if(i[key][1]!==j[1]){g.select_genome.push(i[key])}}}g.select_genome.sort(function(l,k){return l[0]>k[0]?1:l[0]<k[0]?-1:0});g.select_genome.unshift(j)});if(h){this.options=_.defaults(h,this.options)}this.collection.on("remove",function(i){g._eventRemove(i)});this.collection.on("change:genome",function(j){var i=j.get("genome");g.collection.each(function(k){if(k.get("status")=="init"&&k.get("genome")=="?"){k.set("genome",i)}})})},_eventShow:function(h){h.preventDefault();h.stopPropagation();if(!this.modal){var g=this;this.modal=new c.GalaxyModal({title:"Download data directly from web or upload files from your disk",body:this._template("upload-box","upload-info"),buttons:{"Choose files":function(){g.uploadbox.select()},"Create file":function(){g._eventCreate()},Start:function(){g._eventStart()},Pause:function(){g._eventStop()},Reset:function(){g._eventReset()},Close:function(){g.modal.hide()},},height:"400",width:"900",closing_events:true});this.setElement("#upload-box");var g=this;this.uploadbox=this.$el.uploadbox({announce:function(i,j,k){g._eventAnnounce(i,j,k)},initialize:function(i,j,k){return g._eventInitialize(i,j,k)},progress:function(i,j,k){g._eventProgress(i,j,k)},success:function(i,j,k){g._eventSuccess(i,j,k)},error:function(i,j,k){g._eventError(i,j,k)},complete:function(){g._eventComplete()}});this._updateScreen()}this.modal.show()},_eventRemove:function(h){var g=h.get("status");if(g=="success"){this.counter.success--}else{if(g=="error"){this.counter.error--}else{this.counter.announce--}}this._updateScreen();this.uploadbox.remove(h.id)},_eventAnnounce:function(g,h,j){this.counter.announce++;this._updateScreen();var i=new d(this,{id:g,file_name:h.name,file_size:h.size});this.collection.add(i.model);$(this.el).find("tbody:last").append(i.$el);i.render()},_eventInitialize:function(k,g,o){var i=this.collection.get(k);i.set("status","running");var h=i.get("extension");var l=i.get("file_name");var n=i.get("genome");var m=i.get("url_paste");var j=i.get("space_to_tabs");if(!m&&!(g.size>0)){return null}this.uploadbox.configure({url:this.options.nginx_upload_path,paramname:"files_0|file_data"});tool_input={};tool_input.dbkey=n;tool_input.file_type=h;tool_input["files_0|NAME"]=l;tool_input["files_0|type"]="upload_dataset";tool_input["files_0|url_paste"]=m;tool_input.space_to_tabs=j;data={};data.history_id=this.current_history;data.tool_id="upload1";data.inputs=JSON.stringify(tool_input);return data},_eventProgress:function(h,i,g){var j=this.collection.get(h);j.set("percentage",g);this.button_show.set("percentage",this._upload_percentage(g,i.size))},_eventSuccess:function(h,i,k){var j=this.collection.get(h);j.set("status","success");var g=j.get("file_size");this.button_show.set("percentage",this._upload_percentage(100,g));this.upload_completed+=g*100;this.counter.announce--;this.counter.success++;this._updateScreen();Galaxy.currHistoryPanel.refreshHdas()},_eventError:function(g,h,j){var i=this.collection.get(g);i.set("status","error");i.set("info",j);this.button_show.set("percentage",this._upload_percentage(100,h.size));this.button_show.set("status","danger");this.upload_completed+=h.size*100;this.counter.announce--;this.counter.error++;this._updateScreen()},_eventComplete:function(){this.collection.each(function(g){if(g.get("status")=="queued"){g.set("status","init")}});this.counter.running=0;this._updateScreen()},_eventCreate:function(){this.uploadbox.add([{name:"New File",size:-1}])},_eventStart:function(){if(this.counter.announce==0||this.counter.running>0){return}var g=this;this.upload_size=0;this.upload_completed=0;this.collection.each(function(h){if(h.get("status")=="init"){h.set("status","queued");g.upload_size+=h.get("file_size")}});this.button_show.set("percentage",0);this.button_show.set("status","success");this.current_history=Galaxy.currHistoryPanel.model.get("id");this.counter.running=this.counter.announce;this._updateScreen();this.uploadbox.start()},_eventStop:function(){if(this.counter.running==0){return}this.button_show.set("status","info");this.uploadbox.stop();$("#upload-info").html("Queue will pause after completing the current file...")},_eventReset:function(){if(this.counter.running==0){this.collection.reset();this.counter.reset();this._updateScreen();this.uploadbox.reset();this.button_show.set("percentage",0)}},_updateScreen:function(){if(this.counter.announce==0){if(this.uploadbox.compatible()){message="You can Drag & Drop files into this box."}else{message="Unfortunately, your browser does not support multiple file uploads or drag&drop.<br>Some supported browsers are: Firefox 4+, Chrome 7+, IE 10+, Opera 12+ or Safari 6+."}}else{if(this.counter.running==0){message="You added "+this.counter.announce+" file(s) to the queue. Add more files or click 'Start' to proceed."}else{message="Please wait..."+this.counter.announce+" out of "+this.counter.running+" remaining."}}$("#upload-info").html(message);if(this.counter.running==0&&this.counter.announce+this.counter.success+this.counter.error>0){this.modal.enableButton("Reset")}else{this.modal.disableButton("Reset")}if(this.counter.running==0&&this.counter.announce>0){this.modal.enableButton("Start")}else{this.modal.disableButton("Start")}if(this.counter.running>0){this.modal.enableButton("Pause")}else{this.modal.disableButton("Pause")}if(this.counter.running==0){this.modal.enableButton("Choose files");this.modal.enableButton("Create file")}else{this.modal.disableButton("Choose files");this.modal.disableButton("Create file")}if(this.counter.announce+this.counter.success+this.counter.error>0){$(this.el).find("table").show()}else{$(this.el).find("table").hide()}},_upload_percentage:function(g,h){return(this.upload_completed+(g*h))/this.upload_size},_template:function(h,g){return'<div id="'+h+'" class="upload-box"><table class="table table-striped" style="display: none;"><thead><tr><th>Name</th><th>Size</th><th>Type</th><th>Genome</th><th>Space→Tab</th><th>Status</th><th></th></tr></thead><tbody></tbody></table></div><h6 id="'+g+'" class="upload-info"></h6>'}})});
\ No newline at end of file
+define(["galaxy.modal","utils/utils","mvc/upload/upload-model","mvc/upload/upload-row","mvc/ui","utils/uploadbox"],function(c,f,e,d){var b=Backbone.Model.extend({defaults:{percentage:0,icon:"fa-circle",label:"",status:""}});var a=Backbone.View.extend({model:null,initialize:function(h){var g=this;this.model=h;this.options=this.model.attributes;this.setElement(this._template(this.options));$(this.el).on("click",this.options.onclick);if(this.options.tooltip){$(this.el).tooltip({title:this.options.tooltip,placement:"bottom"})}this.model.on("change:percentage",function(){g._percentage(g.model.get("percentage"))});this.model.on("change:status",function(){g._status(g.model.get("status"))});var g=this;$(window).on("beforeunload",function(){var i="";if(g.options.onunload){i=g.options.onunload()}if(i!=""){return i}})},_status:function(h){var g=this.$el.find(".progress-bar");g.removeClass();g.addClass("progress-bar");g.addClass("progress-bar-notransition");if(h!=""){g.addClass("progress-bar-"+h)}},_percentage:function(h){var g=this.$el.find(".progress-bar");g.css({width:h+"%"})},_template:function(g){return'<div class="progress-button"><div class="progress"><div class="progress-bar"></div></div><div id="label" class="label"><div class="fa '+g.icon+'"></div> '+g.label+"</div></div>"}});return Backbone.View.extend({modal:null,button_show:null,uploadbox:null,current_history:null,upload_size:0,select_extension:[["Auto-detect","auto"]],select_genome:[["Unspecified (?)","?"]],collection:new e.Collection(),counter:{announce:0,success:0,error:0,running:0,reset:function(){this.announce=this.success=this.error=this.running=0}},options:{nginx_upload_path:""},initialize:function(h){var g=this;if(!Galaxy.currHistoryPanel||!Galaxy.currHistoryPanel.model){window.setTimeout(function(){g.initialize()},500);return}if(!Galaxy.currUser.get("id")){return}this.button_show=new b({icon:"fa-upload",tooltip:"Download from URL or upload files from disk",label:"Load Data",onclick:function(i){if(i){g._eventShow(i)}},onunload:function(){if(g.counter.running>0){return"Several uploads are still processing."}}});$("#left .unified-panel-header-inner").append((new a(this.button_show)).$el);var g=this;f.jsonFromUrl(galaxy_config.root+"api/datatypes",function(i){for(key in i){g.select_extension.push([i[key],i[key]])}});f.jsonFromUrl(galaxy_config.root+"api/genomes",function(i){var j=g.select_genome[0];g.select_genome=[];for(key in i){if(i[key].length>1){if(i[key][1]!==j[1]){g.select_genome.push(i[key])}}}g.select_genome.sort(function(l,k){return l[0]>k[0]?1:l[0]<k[0]?-1:0});g.select_genome.unshift(j)});if(h){this.options=_.defaults(h,this.options)}this.collection.on("remove",function(i){g._eventRemove(i)});this.collection.on("change:genome",function(j){var i=j.get("genome");g.collection.each(function(k){if(k.get("status")=="init"&&k.get("genome")=="?"){k.set("genome",i)}})})},_eventShow:function(h){h.preventDefault();h.stopPropagation();if(!this.modal){var g=this;this.modal=new c.GalaxyModal({title:"Download data directly from web or upload files from your disk",body:this._template("upload-box","upload-info"),buttons:{"Choose files":function(){g.uploadbox.select()},"Create file":function(){g._eventCreate()},Start:function(){g._eventStart()},Pause:function(){g._eventStop()},Reset:function(){g._eventReset()},Close:function(){g.modal.hide()},},height:"400",width:"900",closing_events:true});this.setElement("#upload-box");var g=this;this.uploadbox=this.$el.uploadbox({announce:function(i,j,k){g._eventAnnounce(i,j,k)},initialize:function(i,j,k){return g._eventInitialize(i,j,k)},progress:function(i,j,k){g._eventProgress(i,j,k)},success:function(i,j,k){g._eventSuccess(i,j,k)},error:function(i,j,k){g._eventError(i,j,k)},complete:function(){g._eventComplete()}});this._updateScreen()}this.modal.show()},_eventRemove:function(h){var g=h.get("status");if(g=="success"){this.counter.success--}else{if(g=="error"){this.counter.error--}else{this.counter.announce--}}this._updateScreen();this.uploadbox.remove(h.id)},_eventAnnounce:function(g,h,j){this.counter.announce++;this._updateScreen();var i=new d(this,{id:g,file_name:h.name,file_size:h.size});this.collection.add(i.model);$(this.el).find("tbody:last").append(i.$el);i.render()},_eventInitialize:function(k,g,o){var i=this.collection.get(k);i.set("status","running");var h=i.get("extension");var l=i.get("file_name");var n=i.get("genome");var m=i.get("url_paste");var j=i.get("space_to_tabs");if(!m&&!(g.size>0)){return null}this.uploadbox.configure({url:this.options.nginx_upload_path,paramname:"files_0|file_data"});tool_input={};tool_input.dbkey=n;tool_input.file_type=h;tool_input["files_0|NAME"]=l;tool_input["files_0|type"]="upload_dataset";tool_input["files_0|url_paste"]=m;tool_input.space_to_tabs=j;data={};data.history_id=this.current_history;data.tool_id="upload1";data.inputs=JSON.stringify(tool_input);return data},_eventProgress:function(h,i,g){var j=this.collection.get(h);j.set("percentage",g);this.button_show.set("percentage",this._upload_percentage(g,i.size))},_eventSuccess:function(h,i,k){var j=this.collection.get(h);j.set("status","success");var g=j.get("file_size");this.button_show.set("percentage",this._upload_percentage(100,g));this.upload_completed+=g*100;this.counter.announce--;this.counter.success++;this._updateScreen();Galaxy.currHistoryPanel.refreshHdas()},_eventError:function(g,h,j){var i=this.collection.get(g);i.set("status","error");i.set("info",j);this.button_show.set("percentage",this._upload_percentage(100,h.size));this.button_show.set("status","danger");this.upload_completed+=h.size*100;this.counter.announce--;this.counter.error++;this._updateScreen()},_eventComplete:function(){this.collection.each(function(g){if(g.get("status")=="queued"){g.set("status","init")}});this.counter.running=0;this._updateScreen()},_eventCreate:function(){this.uploadbox.add([{name:"New File",size:-1}])},_eventStart:function(){if(this.counter.announce==0||this.counter.running>0){return}var g=this;this.upload_size=0;this.upload_completed=0;this.collection.each(function(h){if(h.get("status")=="init"){h.set("status","queued");g.upload_size+=h.get("file_size")}});this.button_show.set("percentage",0);this.button_show.set("status","success");this.current_history=Galaxy.currHistoryPanel.model.get("id");this.counter.running=this.counter.announce;this._updateScreen();this.uploadbox.start()},_eventStop:function(){if(this.counter.running==0){return}this.button_show.set("status","info");this.uploadbox.stop();$("#upload-info").html("Queue will pause after completing the current file...")},_eventReset:function(){if(this.counter.running==0){this.collection.reset();this.counter.reset();this._updateScreen();this.uploadbox.reset();this.button_show.set("percentage",0)}},_updateScreen:function(){if(this.counter.announce==0){if(this.uploadbox.compatible()){message="You can Drag & Drop files into this box."}else{message="Unfortunately, your browser does not support multiple file uploads or drag&drop.<br>Some supported browsers are: Firefox 4+, Chrome 7+, IE 10+, Opera 12+ or Safari 6+."}}else{if(this.counter.running==0){message="You added "+this.counter.announce+" file(s) to the queue. Add more files or click 'Start' to proceed."}else{message="Please wait..."+this.counter.announce+" out of "+this.counter.running+" remaining."}}$("#upload-info").html(message);if(this.counter.running==0&&this.counter.announce+this.counter.success+this.counter.error>0){this.modal.enableButton("Reset")}else{this.modal.disableButton("Reset")}if(this.counter.running==0&&this.counter.announce>0){this.modal.enableButton("Start")}else{this.modal.disableButton("Start")}if(this.counter.running>0){this.modal.enableButton("Pause")}else{this.modal.disableButton("Pause")}if(this.counter.running==0){this.modal.enableButton("Choose files");this.modal.enableButton("Create file")}else{this.modal.disableButton("Choose files");this.modal.disableButton("Create file")}if(this.counter.announce+this.counter.success+this.counter.error>0){$(this.el).find("table").show()}else{$(this.el).find("table").hide()}},_upload_percentage:function(g,h){return(this.upload_completed+(g*h))/this.upload_size},_template:function(h,g){return'<div id="'+h+'" class="upload-box"><table class="table table-striped" style="display: none;"><thead><tr><th>Name</th><th>Size</th><th>Type</th><th>Genome</th><th>Space→Tab</th><th>Status</th><th></th></tr></thead><tbody></tbody></table></div><h6 id="'+g+'" class="upload-info"></h6>'}})});
\ No newline at end of file
diff -r b7c11187252fd308a1c0878f33cc8742c9287eaa -r b48698ef4da4976dcd177e81a6e45381310337c6 static/style/blue/base.css
--- a/static/style/blue/base.css
+++ b/static/style/blue/base.css
@@ -1250,10 +1250,12 @@
.galaxy-frame .frame .f-close{right:5px;top:3px}
.galaxy-frame .frame .f-pin{left:6px;top:3px}
.galaxy-frame .frame .f-resize{background:#fff;width:16px;height:16px;color:#2c3143;right:0px;bottom:0px;text-align:center;line-height:16px;border:0px}
-.progress-button{position:absolute;width:100px;right:10px;top:6px;cursor:pointer;height:19px;border:1px solid #aaa;-moz-border-radius:3px;border-radius:3px}.progress-button .progress-bar-danger{background:#f9c7c5}
+.progress-button{position:absolute;width:100px;right:10px;top:5px;cursor:pointer;height:20px;border:1px solid #aaa;-moz-border-radius:3px;border-radius:3px}.progress-button .progress{height:18px}
+.progress-button .progress-bar-danger{background:#f9c7c5}
.progress-button .progress-bar-success{background:#aff1af;border:0px}
.progress-button .progress-bar-info{background:#ffc}
.progress-button .progress-bar-notransition{-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none}
+.progress-button .label{position:absolute;top:0px;width:inherit;text-align:center;line-height:20px}
.upload-info{font-weight:normal;text-align:center}
.upload-box{width:100%;height:95%;text-align:center;overflow:scroll;font-size:12px;line-height:1.33;-moz-border-radius:5px;border-radius:5px;border:1px dashed #bfbfbf;padding:10px;overflow-x:hidden;-ms-overflow-style:none}.upload-box .table{width:100%}
.upload-box .table th{text-align:center;white-space:nowrap}
diff -r b7c11187252fd308a1c0878f33cc8742c9287eaa -r b48698ef4da4976dcd177e81a6e45381310337c6 static/style/src/less/upload.less
--- a/static/style/src/less/upload.less
+++ b/static/style/src/less/upload.less
@@ -2,13 +2,17 @@
position: absolute;
width: 100px;
right: 10px;
- top: 6px;
+ top: 5px;
cursor: pointer;
- height: 19px;
+ height: 20px;
border: 1px solid @input-border;
-moz-border-radius: @border-radius-base;
border-radius: @border-radius-base;
+ .progress {
+ height: 18px;
+ }
+
.progress-bar-danger {
background: @state-danger-bg;
}
@@ -29,6 +33,14 @@
-o-transition: none;
transition: none;
}
+
+ .label {
+ position: absolute;
+ top: 0px;
+ width: inherit;
+ text-align: center;
+ line-height: 20px;
+ }
}
.upload-info {
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: guerler: UI: Increase minimum sidebar width
by commits-noreply@bitbucket.org 24 Jan '14
by commits-noreply@bitbucket.org 24 Jan '14
24 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/b7c11187252f/
Changeset: b7c11187252f
User: guerler
Date: 2014-01-24 23:49:22
Summary: UI: Increase minimum sidebar width
Affected #: 2 files
diff -r 9b337a87d6eca3bf9f7448d49337d231e3b4582b -r b7c11187252fd308a1c0878f33cc8742c9287eaa static/scripts/galaxy.panels.js
--- a/static/scripts/galaxy.panels.js
+++ b/static/scripts/galaxy.panels.js
@@ -11,7 +11,7 @@
// Panels
-var MIN_PANEL_WIDTH = 150,
+var MIN_PANEL_WIDTH = 160,
MAX_PANEL_WIDTH = 800;
var Panel = function( options ) {
diff -r 9b337a87d6eca3bf9f7448d49337d231e3b4582b -r b7c11187252fd308a1c0878f33cc8742c9287eaa static/scripts/packed/galaxy.panels.js
--- a/static/scripts/packed/galaxy.panels.js
+++ b/static/scripts/packed/galaxy.panels.js
@@ -1,1 +1,1 @@
-!function(c,d){var e=function(){if(d("#DD-helper").length==0){d("<div id='DD-helper'/>").appendTo("body").hide()}};var b=150,h=800;var k=function(n){this.$panel=n.panel;this.$center=n.center;this.$drag=n.drag;this.$toggle=n.toggle;this.left=!n.right;this.hidden=false;this.hidden_by_tool=false;this.saved_size=null;this.init()};d.extend(k.prototype,{resize:function(n){this.$panel.css("width",n);if(this.left){this.$center.css("left",n)}else{this.$center.css("right",n)}if(document.recalc){document.recalc()}},do_toggle:function(){var n=this;if(this.hidden){this.$toggle.removeClass("hidden");if(this.left){this.$panel.css("left",-this.saved_size).show().animate({left:0},"fast",function(){n.resize(n.saved_size)})}else{this.$panel.css("right",-this.saved_size).show().animate({right:0},"fast",function(){n.resize(n.saved_size)})}n.hidden=false}else{n.saved_size=this.$panel.width();if(document.recalc){document.recalc()}if(this.left){this.$panel.animate({left:-this.saved_size},"fast")}else{this.$panel.animate({right:-this.saved_size},"fast")}if(this.left){this.$center.css("left",0)}else{this.$center.css("right",0)}n.hidden=true;n.$toggle.addClass("hidden")}this.hidden_by_tool=false},handle_minwidth_hint:function(n){var o=this.$center.width()-(this.hidden?this.saved_size:0);if(o<n){if(!this.hidden){this.do_toggle();this.hidden_by_tool=true}}else{if(this.hidden_by_tool){this.do_toggle();this.hidden_by_tool=false}}},force_panel:function(n){if((this.hidden&&n=="show")||(!this.hidden&&n=="hide")){this.do_toggle()}},init:function(){var n=this;this.$toggle.remove().appendTo("body");this.$drag.on("dragstart",function(o,p){d("#DD-helper").show();p.width=n.$panel.width()}).on("dragend",function(){d("#DD-helper").hide()}).on("drag",function(p,q){var o;if(n.left){o=q.width+q.deltaX}else{o=q.width-q.deltaX}o=Math.min(h,Math.max(b,o));n.resize(o)});n.$toggle.on("click",function(){n.do_toggle()})}});var f=function(n){this.$overlay=n.overlay;this.$dialog=n.dialog;this.$header=this.$dialog.find(".modal-header");this.$body=this.$dialog.find(".modal-body");this.$footer=this.$dialog.find(".modal-footer");this.$backdrop=n.backdrop;this.$header.find(".close").on("click",d.proxy(this.hide,this))};d.extend(f.prototype,{setContent:function(p){this.$header.hide();if(p.title){this.$header.find(".title").html(p.title);this.$header.show()}if(p.closeButton){this.$header.find(".close").show();this.$header.show()}else{this.$header.find(".close").hide()}this.$footer.hide();var o=this.$footer.find(".buttons").html("");if(p.buttons){d.each(p.buttons,function(r,s){o.append(d("<button></button> ").text(r).click(s)).append(" ")});this.$footer.show()}var q=this.$footer.find(".extra_buttons").html("");if(p.extra_buttons){d.each(p.extra_buttons,function(r,s){q.append(d("<button></button>").text(r).click(s)).append(" ")});this.$footer.show()}var n=p.body;if(n=="progress"){n=d("<div class='progress progress-striped active'><div class='progress-bar' style='width: 100%'></div></div>")}this.$body.html(n)},show:function(n,o){if(!this.$dialog.is(":visible")){if(n.backdrop){this.$backdrop.addClass("in")}else{this.$backdrop.removeClass("in")}this.$overlay.show();this.$dialog.show();this.$overlay.addClass("in");this.$body.css("min-width",this.$body.width());this.$body.css("max-height",d(window).height()-this.$footer.outerHeight()-this.$header.outerHeight()-parseInt(this.$dialog.css("padding-top"),10)-parseInt(this.$dialog.css("padding-bottom"),10))}if(o){o()}},hide:function(){var n=this;n.$dialog.fadeOut(function(){n.$overlay.hide();n.$backdrop.removeClass("in");n.$body.children().remove();n.$body.css("min-width",undefined)})}});var m;d(function(){m=new f({overlay:d("#top-modal"),dialog:d("#top-modal-dialog"),backdrop:d("#top-modal-backdrop")})});function a(){m.hide()}function l(r,n,p,o,q){m.setContent({title:r,body:n,buttons:p,extra_buttons:o});m.show({backdrop:true},q)}function g(r,n,p,o,q){m.setContent({title:r,body:n,buttons:p,extra_buttons:o});m.show({backdrop:false},q)}function j(p){var q=p.width||"600";var o=p.height||"400";var n=p.scroll||"auto";d("#overlay-background").bind("click.overlay",function(){a();d("#overlay-background").unbind("click.overlay")});m.setContent({closeButton:true,title:" ",body:d("<div style='margin: -5px;'><iframe style='margin: 0; padding: 0;' src='"+p.url+"' width='"+q+"' height='"+o+"' scrolling='"+n+"' frameborder='0'></iframe></div>")});m.show({backdrop:true})}function i(n,o){if(n){d(".loggedin-only").show();d(".loggedout-only").hide();d("#user-email").text(n);if(o){d(".admin-only").show()}}else{d(".loggedin-only").hide();d(".loggedout-only").show();d(".admin-only").hide()}}d(function(){var n=d("#masthead ul.nav > li.dropdown > .dropdown-menu");d("body").on("click.nav_popups",function(p){n.hide();d("#DD-helper").hide();if(d(p.target).closest("#masthead ul.nav > li.dropdown > .dropdown-menu").length){return}var o=d(p.target).closest("#masthead ul.nav > li.dropdown");if(o.length){d("#DD-helper").show();o.children(".dropdown-menu").show();p.preventDefault()}})});c.ensure_dd_helper=e;c.Panel=k;c.Modal=f;c.hide_modal=a;c.show_modal=l;c.show_message=g;c.show_in_overlay=j;c.user_changed=i}(window,window.jQuery);
\ No newline at end of file
+!function(c,d){var e=function(){if(d("#DD-helper").length==0){d("<div id='DD-helper'/>").appendTo("body").hide()}};var b=160,h=800;var k=function(n){this.$panel=n.panel;this.$center=n.center;this.$drag=n.drag;this.$toggle=n.toggle;this.left=!n.right;this.hidden=false;this.hidden_by_tool=false;this.saved_size=null;this.init()};d.extend(k.prototype,{resize:function(n){this.$panel.css("width",n);if(this.left){this.$center.css("left",n)}else{this.$center.css("right",n)}if(document.recalc){document.recalc()}},do_toggle:function(){var n=this;if(this.hidden){this.$toggle.removeClass("hidden");if(this.left){this.$panel.css("left",-this.saved_size).show().animate({left:0},"fast",function(){n.resize(n.saved_size)})}else{this.$panel.css("right",-this.saved_size).show().animate({right:0},"fast",function(){n.resize(n.saved_size)})}n.hidden=false}else{n.saved_size=this.$panel.width();if(document.recalc){document.recalc()}if(this.left){this.$panel.animate({left:-this.saved_size},"fast")}else{this.$panel.animate({right:-this.saved_size},"fast")}if(this.left){this.$center.css("left",0)}else{this.$center.css("right",0)}n.hidden=true;n.$toggle.addClass("hidden")}this.hidden_by_tool=false},handle_minwidth_hint:function(n){var o=this.$center.width()-(this.hidden?this.saved_size:0);if(o<n){if(!this.hidden){this.do_toggle();this.hidden_by_tool=true}}else{if(this.hidden_by_tool){this.do_toggle();this.hidden_by_tool=false}}},force_panel:function(n){if((this.hidden&&n=="show")||(!this.hidden&&n=="hide")){this.do_toggle()}},init:function(){var n=this;this.$toggle.remove().appendTo("body");this.$drag.on("dragstart",function(o,p){d("#DD-helper").show();p.width=n.$panel.width()}).on("dragend",function(){d("#DD-helper").hide()}).on("drag",function(p,q){var o;if(n.left){o=q.width+q.deltaX}else{o=q.width-q.deltaX}o=Math.min(h,Math.max(b,o));n.resize(o)});n.$toggle.on("click",function(){n.do_toggle()})}});var f=function(n){this.$overlay=n.overlay;this.$dialog=n.dialog;this.$header=this.$dialog.find(".modal-header");this.$body=this.$dialog.find(".modal-body");this.$footer=this.$dialog.find(".modal-footer");this.$backdrop=n.backdrop;this.$header.find(".close").on("click",d.proxy(this.hide,this))};d.extend(f.prototype,{setContent:function(p){this.$header.hide();if(p.title){this.$header.find(".title").html(p.title);this.$header.show()}if(p.closeButton){this.$header.find(".close").show();this.$header.show()}else{this.$header.find(".close").hide()}this.$footer.hide();var o=this.$footer.find(".buttons").html("");if(p.buttons){d.each(p.buttons,function(r,s){o.append(d("<button></button> ").text(r).click(s)).append(" ")});this.$footer.show()}var q=this.$footer.find(".extra_buttons").html("");if(p.extra_buttons){d.each(p.extra_buttons,function(r,s){q.append(d("<button></button>").text(r).click(s)).append(" ")});this.$footer.show()}var n=p.body;if(n=="progress"){n=d("<div class='progress progress-striped active'><div class='progress-bar' style='width: 100%'></div></div>")}this.$body.html(n)},show:function(n,o){if(!this.$dialog.is(":visible")){if(n.backdrop){this.$backdrop.addClass("in")}else{this.$backdrop.removeClass("in")}this.$overlay.show();this.$dialog.show();this.$overlay.addClass("in");this.$body.css("min-width",this.$body.width());this.$body.css("max-height",d(window).height()-this.$footer.outerHeight()-this.$header.outerHeight()-parseInt(this.$dialog.css("padding-top"),10)-parseInt(this.$dialog.css("padding-bottom"),10))}if(o){o()}},hide:function(){var n=this;n.$dialog.fadeOut(function(){n.$overlay.hide();n.$backdrop.removeClass("in");n.$body.children().remove();n.$body.css("min-width",undefined)})}});var m;d(function(){m=new f({overlay:d("#top-modal"),dialog:d("#top-modal-dialog"),backdrop:d("#top-modal-backdrop")})});function a(){m.hide()}function l(r,n,p,o,q){m.setContent({title:r,body:n,buttons:p,extra_buttons:o});m.show({backdrop:true},q)}function g(r,n,p,o,q){m.setContent({title:r,body:n,buttons:p,extra_buttons:o});m.show({backdrop:false},q)}function j(p){var q=p.width||"600";var o=p.height||"400";var n=p.scroll||"auto";d("#overlay-background").bind("click.overlay",function(){a();d("#overlay-background").unbind("click.overlay")});m.setContent({closeButton:true,title:" ",body:d("<div style='margin: -5px;'><iframe style='margin: 0; padding: 0;' src='"+p.url+"' width='"+q+"' height='"+o+"' scrolling='"+n+"' frameborder='0'></iframe></div>")});m.show({backdrop:true})}function i(n,o){if(n){d(".loggedin-only").show();d(".loggedout-only").hide();d("#user-email").text(n);if(o){d(".admin-only").show()}}else{d(".loggedin-only").hide();d(".loggedout-only").show();d(".admin-only").hide()}}d(function(){var n=d("#masthead ul.nav > li.dropdown > .dropdown-menu");d("body").on("click.nav_popups",function(p){n.hide();d("#DD-helper").hide();if(d(p.target).closest("#masthead ul.nav > li.dropdown > .dropdown-menu").length){return}var o=d(p.target).closest("#masthead ul.nav > li.dropdown");if(o.length){d("#DD-helper").show();o.children(".dropdown-menu").show();p.preventDefault()}})});c.ensure_dd_helper=e;c.Panel=k;c.Modal=f;c.hide_modal=a;c.show_modal=l;c.show_message=g;c.show_in_overlay=j;c.user_changed=i}(window,window.jQuery);
\ 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: inithello: Don't sync the filesystem with the database when running a tool migration install script.
by commits-noreply@bitbucket.org 24 Jan '14
by commits-noreply@bitbucket.org 24 Jan '14
24 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/9b337a87d6ec/
Changeset: 9b337a87d6ec
User: inithello
Date: 2014-01-24 22:38:43
Summary: Don't sync the filesystem with the database when running a tool migration install script.
Affected #: 6 files
diff -r cce4687a7ccc56a47db95498b0ae86f0f5986125 -r 9b337a87d6eca3bf9f7448d49337d231e3b4582b lib/galaxy/webapps/galaxy/controllers/admin_toolshed.py
--- a/lib/galaxy/webapps/galaxy/controllers/admin_toolshed.py
+++ b/lib/galaxy/webapps/galaxy/controllers/admin_toolshed.py
@@ -445,7 +445,8 @@
installed_tool_dependencies = common_install_util.handle_tool_dependencies( app=trans.app,
tool_shed_repository=tool_shed_repository,
tool_dependencies_config=tool_dependencies_config,
- tool_dependencies=tool_dependencies )
+ tool_dependencies=tool_dependencies,
+ from_install_manager=False )
for installed_tool_dependency in installed_tool_dependencies:
if installed_tool_dependency.status == trans.app.install_model.ToolDependency.installation_status.ERROR:
text = util.unicodify( installed_tool_dependency.error_message )
diff -r cce4687a7ccc56a47db95498b0ae86f0f5986125 -r 9b337a87d6eca3bf9f7448d49337d231e3b4582b lib/tool_shed/galaxy_install/install_manager.py
--- a/lib/tool_shed/galaxy_install/install_manager.py
+++ b/lib/tool_shed/galaxy_install/install_manager.py
@@ -440,7 +440,8 @@
installed_tool_dependencies = common_install_util.handle_tool_dependencies( app=self.app,
tool_shed_repository=tool_shed_repository,
tool_dependencies_config=tool_dependencies_config,
- tool_dependencies=tool_dependencies )
+ tool_dependencies=tool_dependencies,
+ from_install_manager=True )
for installed_tool_dependency in installed_tool_dependencies:
if installed_tool_dependency.status == self.app.install_model.ToolDependency.installation_status.ERROR:
print '\nThe following error occurred from the InstallManager while installing tool dependency ', installed_tool_dependency.name, ':'
diff -r cce4687a7ccc56a47db95498b0ae86f0f5986125 -r 9b337a87d6eca3bf9f7448d49337d231e3b4582b lib/tool_shed/galaxy_install/repository_util.py
--- a/lib/tool_shed/galaxy_install/repository_util.py
+++ b/lib/tool_shed/galaxy_install/repository_util.py
@@ -596,7 +596,8 @@
installed_tool_dependencies = common_install_util.handle_tool_dependencies( app=trans.app,
tool_shed_repository=tool_shed_repository,
tool_dependencies_config=tool_dependencies_config,
- tool_dependencies=tool_shed_repository.tool_dependencies )
+ tool_dependencies=tool_shed_repository.tool_dependencies,
+ from_install_manager=False )
suc.remove_dir( work_dir )
suc.update_tool_shed_repository_status( trans.app,
tool_shed_repository,
@@ -841,7 +842,8 @@
installed_tool_dependencies = common_install_util.handle_tool_dependencies( app=trans.app,
tool_shed_repository=repository,
tool_dependencies_config=tool_dependencies_config,
- tool_dependencies=repository.tool_dependencies )
+ tool_dependencies=repository.tool_dependencies,
+ from_install_manager=False )
for installed_tool_dependency in installed_tool_dependencies:
if installed_tool_dependency.status in [ trans.install_model.ToolDependency.installation_status.ERROR ]:
repair_dict = add_repair_dict_entry( repository.name, installed_tool_dependency.error_message )
diff -r cce4687a7ccc56a47db95498b0ae86f0f5986125 -r 9b337a87d6eca3bf9f7448d49337d231e3b4582b lib/tool_shed/galaxy_install/tool_dependencies/install_util.py
--- a/lib/tool_shed/galaxy_install/tool_dependencies/install_util.py
+++ b/lib/tool_shed/galaxy_install/tool_dependencies/install_util.py
@@ -285,7 +285,7 @@
tool_dependency = tool_dependency_util.mark_tool_dependency_installed( app, tool_dependency )
return tool_dependency
-def install_package( app, elem, tool_shed_repository, tool_dependencies=None ):
+def install_package( app, elem, tool_shed_repository, tool_dependencies=None, from_install_manager=False ):
# The value of tool_dependencies is a partial or full list of ToolDependency records associated with the tool_shed_repository.
sa_session = app.install_model.context
tool_dependency = None
@@ -317,14 +317,16 @@
tool_dependency_version=package_version )
can_install_tool_dependency = True
if os.path.exists( install_dir ):
- # Notice that we'll throw away the following tool_dependency if it can be installed.
- tool_dependency, can_install_tool_dependency = \
- tool_dependency_util.sync_database_with_file_system( app,
- tool_shed_repository,
- package_name,
- package_version,
- install_dir,
- tool_dependency_type='package' )
+ if not from_install_manager:
+ # Notice that we'll throw away the following tool_dependency if it can be installed.
+ print 'Calling sync_database_with_file_system 2'
+ tool_dependency, can_install_tool_dependency = \
+ tool_dependency_util.sync_database_with_file_system( app,
+ tool_shed_repository,
+ package_name,
+ package_version,
+ install_dir,
+ tool_dependency_type='package' )
else:
can_install_tool_dependency = True
if can_install_tool_dependency:
diff -r cce4687a7ccc56a47db95498b0ae86f0f5986125 -r 9b337a87d6eca3bf9f7448d49337d231e3b4582b lib/tool_shed/util/common_install_util.py
--- a/lib/tool_shed/util/common_install_util.py
+++ b/lib/tool_shed/util/common_install_util.py
@@ -435,7 +435,7 @@
all_required_repo_info_dict[ 'all_repo_info_dicts' ] = all_repo_info_dicts
return all_required_repo_info_dict
-def handle_tool_dependencies( app, tool_shed_repository, tool_dependencies_config, tool_dependencies ):
+def handle_tool_dependencies( app, tool_shed_repository, tool_dependencies_config, tool_dependencies, from_install_manager=False ):
"""
Install and build tool dependencies defined in the tool_dependencies_config. This config's tag sets can currently refer to installation
methods in Galaxy's tool_dependencies module. In the future, proprietary fabric scripts contained in the repository will be supported.
@@ -487,7 +487,11 @@
error_message=None,
remove_from_disk=False )
else:
- tool_dependency = install_package( app, elem, tool_shed_repository, tool_dependencies=tool_dependencies )
+ tool_dependency = install_package( app,
+ elem,
+ tool_shed_repository,
+ tool_dependencies=tool_dependencies,
+ from_install_manager=from_install_manager )
except Exception, e:
error_message = "Error installing tool dependency %s version %s: %s" % ( str( package_name ), str( package_version ), str( e ) )
log.exception( error_message )
diff -r cce4687a7ccc56a47db95498b0ae86f0f5986125 -r 9b337a87d6eca3bf9f7448d49337d231e3b4582b lib/tool_shed/util/common_util.py
--- a/lib/tool_shed/util/common_util.py
+++ b/lib/tool_shed/util/common_util.py
@@ -91,9 +91,9 @@
file_path = elem.get( 'file', None )
if file_path:
path, name = os.path.split( file_path )
- if name in migrated_tool_configs_dict:
- tool_dependencies = migrated_tool_configs_dict[ name ]
- missing_tool_configs_dict[ name ] = tool_dependencies
+ for migrated_tool_config in migrated_tool_configs_dict.keys():
+ if migrated_tool_config in [ file_path, name ]:
+ missing_tool_configs_dict[ name ] = migrated_tool_configs_dict[ migrated_tool_config ]
return missing_tool_configs_dict
def get_non_shed_tool_panel_configs( app ):
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: greg: Statistics fixes for the tool shed's install and test framework.
by commits-noreply@bitbucket.org 24 Jan '14
by commits-noreply@bitbucket.org 24 Jan '14
24 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/cce4687a7ccc/
Changeset: cce4687a7ccc
User: greg
Date: 2014-01-24 20:14:06
Summary: Statistics fixes for the tool shed's install and test framework.
Affected #: 1 file
diff -r ac32a07b4eea8cee714368ecb247ce22cac01a4c -r cce4687a7ccc56a47db95498b0ae86f0f5986125 test/install_and_test_tool_shed_repositories/base/util.py
--- a/test/install_and_test_tool_shed_repositories/base/util.py
+++ b/test/install_and_test_tool_shed_repositories/base/util.py
@@ -756,15 +756,16 @@
print 'Revision %s of repository %s owned by %s has the following installation error:' % ( changeset_revision, name, owner )
# Use log.debug here instead of print because print will throw UnicodeEncodeError exceptions.
log.debug( '%s' % error_message )
+ identity_tup = ( name, owner, changeset_revision )
+ processed_repositories_with_installation_error = \
+ install_and_test_statistics_dict.get( 'repositories_with_installation_error', [] )
+ if identity_tup not in processed_repositories_with_installation_error:
+ install_and_test_statistics_dict[ 'repositories_with_installation_error' ].append( identity_tup )
missing_repository_dependency_info_dict = dict( tool_shed=tool_shed,
name=name,
owner=owner,
changeset_revision=changeset_revision,
error_message=error_message )
- processed_repositories_with_installation_error = \
- install_and_test_statistics_dict.get( 'repositories_with_installation_error', [] )
- if missing_repository_dependency_info_dict not in processed_repositories_with_installation_error:
- install_and_test_statistics_dict[ 'repositories_with_installation_error' ].append( missing_repository_dependency_info_dict )
tool_test_results_dict[ 'installation_errors' ][ 'repository_dependencies' ].append( missing_repository_dependency_info_dict )
if repository.missing_tool_dependencies:
print 'The following tool dependencies for revision %s of repository %s owned by %s have installation errors:' % \
@@ -779,14 +780,15 @@
print 'Version %s of tool dependency %s %s has the following installation error:' % ( version, type, name )
# Use log.debug here instead of print because print will throw UnicodeEncodeError exceptions.
log.debug( '%s' % error_message )
+ identity_tup = ( name, type, version )
+ processed_tool_dependencies_with_installation_error = \
+ install_and_test_statistics_dict.get( 'tool_dependencies_with_installation_error', [] )
+ if identity_tup not in processed_tool_dependencies_with_installation_error:
+ install_and_test_statistics_dict[ 'tool_dependencies_with_installation_error' ].append( identity_tup )
missing_tool_dependency_info_dict = dict( type=type,
name=name,
version=version,
error_message=error_message )
- processed_tool_dependencies_with_installation_error = \
- install_and_test_statistics_dict.get( 'tool_dependencies_with_installation_error', [] )
- if missing_tool_dependency_info_dict not in processed_tool_dependencies_with_installation_error:
- install_and_test_statistics_dict[ 'tool_dependencies_with_installation_error' ].append( missing_tool_dependency_info_dict )
tool_test_results_dict[ 'installation_errors' ][ 'tool_dependencies' ].append( missing_tool_dependency_info_dict )
if repository.installed_repository_dependencies:
print 'The following repository dependencies for revision %s of repository %s owned by %s are installed:' % \
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: greg: Fix for discovering tools to eliminate from the toolbox for the tool shed's install and test framework.
by commits-noreply@bitbucket.org 24 Jan '14
by commits-noreply@bitbucket.org 24 Jan '14
24 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/ac32a07b4eea/
Changeset: ac32a07b4eea
User: greg
Date: 2014-01-24 19:56:29
Summary: Fix for discovering tools to eliminate from the toolbox for the tool shed's install and test framework.
Affected #: 1 file
diff -r 9fb269cab1cea862d5d5bb997c4d0fdce9607e6a -r ac32a07b4eea8cee714368ecb247ce22cac01a4c test/install_and_test_tool_shed_repositories/repositories_with_tools/functional_tests.py
--- a/test/install_and_test_tool_shed_repositories/repositories_with_tools/functional_tests.py
+++ b/test/install_and_test_tool_shed_repositories/repositories_with_tools/functional_tests.py
@@ -578,15 +578,22 @@
# Revisit this code if at some point we notice that Twill re-runs tests that should have been deleted.
# Undoubtedly the following if statement will need to be enhanced to find the tool id in question. For
# example, the following or is required because Twill replaces some spaces with underscores in test names.
- if app_tool_id == tool_id or app_tool_id.replace( '_', ' ' ) == tool_id.replace( '_', ' ' ):
- tools_to_delete_by_id.append( tool_id )
+ if app_tool_id == tool_id:
+ print 'Setting tool id %s for deletion from app.toolbox[ tools_by_id ].' % str( app_tool_id )
+ tools_to_delete_by_id.append( app_tool_id )
+ else:
+ reset_spaces_app_tool_id = app_tool_id.replace( '_', ' ' )
+ reset_spaces_tool_id = tool_id.replace( '_', ' ' )
+ if reset_spaces_app_tool_id == reset_spaces_tool_id:
+ print 'Setting tool id %s for deletion from app.toolbox[ tools_by_id ].' % str( app_tool_id )
+ tools_to_delete_by_id.append( app_tool_id )
# Delete the discovered twill-generated tests.
for key in tests_to_delete:
if key in test_toolbox.__dict__:
- log.debug( 'Deleting test %s from test_toolbox.' % str( key ) )
+ print 'Deleting test %s from test_toolbox.' % str( key )
del test_toolbox.__dict__[ key ]
for tool_id in tools_to_delete_by_id:
- log.debug( 'Deleting tool id %s from app.toolbox[ tools_by_id ].' % str( tool_id ) )
+ print 'Deleting tool id %s from app.toolbox[ tools_by_id ].' % str( tool_id )
del app.toolbox.tools_by_id[ tool_id ]
def test_repository_tools( app, repository, repository_dict, tool_test_results_dicts, tool_test_results_dict,
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
24 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/9fb269cab1ce/
Changeset: 9fb269cab1ce
User: guerler
Date: 2014-01-24 18:44:52
Summary: Fix popup menus
Affected #: 2 files
diff -r 9414cc43797afb77190abcbda0fdf173a6a100f3 -r 9fb269cab1cea862d5d5bb997c4d0fdce9607e6a static/scripts/galaxy.base.js
--- a/static/scripts/galaxy.base.js
+++ b/static/scripts/galaxy.base.js
@@ -179,6 +179,7 @@
// so manually do it here.
if (target) {
window.open(href, target);
+ return false;
}
// For all other links, do the default action.
else {
diff -r 9414cc43797afb77190abcbda0fdf173a6a100f3 -r 9fb269cab1cea862d5d5bb997c4d0fdce9607e6a static/scripts/packed/galaxy.base.js
--- a/static/scripts/packed/galaxy.base.js
+++ b/static/scripts/packed/galaxy.base.js
@@ -1,1 +1,1 @@
-(function(){var b=0;var c=["ms","moz","webkit","o"];for(var a=0;a<c.length&&!window.requestAnimationFrame;++a){window.requestAnimationFrame=window[c[a]+"RequestAnimationFrame"];window.cancelRequestAnimationFrame=window[c[a]+"CancelRequestAnimationFrame"]}if(!window.requestAnimationFrame){window.requestAnimationFrame=function(h,e){var d=new Date().getTime();var f=Math.max(0,16-(d-b));var g=window.setTimeout(function(){h(d+f)},f);b=d+f;return g}}if(!window.cancelAnimationFrame){window.cancelAnimationFrame=function(d){clearTimeout(d)}}}());if(!Array.indexOf){Array.prototype.indexOf=function(c){for(var b=0,a=this.length;b<a;b++){if(this[b]==c){return b}}return -1}}function obj_length(c){if(c.length!==undefined){return c.length}var b=0;for(var a in c){b++}return b}$.fn.makeAbsolute=function(a){return this.each(function(){var b=$(this);var c=b.position();b.css({position:"absolute",marginLeft:0,marginTop:0,top:c.top,left:c.left,right:$(window).width()-(c.left+b.width())});if(a){b.remove().appendTo("body")}})};function make_popupmenu(b,c){var a=(b.data("menu_options"));b.data("menu_options",c);if(a){return}b.bind("click.show_popup",function(d){$(".popmenu-wrapper").remove();setTimeout(function(){var g=$("<ul class='dropdown-menu' id='"+b.attr("id")+"-menu'></ul>");var f=b.data("menu_options");if(obj_length(f)<=0){$("<li>No Options.</li>").appendTo(g)}$.each(f,function(j,i){if(i){var l=i.action||i;g.append($("<li></li>").append($("<a>").attr("href",i.url).html(j).click(l)))}else{g.append($("<li></li>").addClass("head").append($("<a href='#'></a>").html(j)))}});var h=$("<div class='popmenu-wrapper' style='position: absolute;left: 0; top: -1000;'></div>").append(g).appendTo("body");var e=d.pageX-h.width()/2;e=Math.min(e,$(document).scrollLeft()+$(window).width()-$(h).width()-5);e=Math.max(e,$(document).scrollLeft()+5);h.css({top:d.pageY,left:e})},10);setTimeout(function(){var f=function(h){$(h).bind("click.close_popup",function(){$(".popmenu-wrapper").remove();h.unbind("click.close_popup")})};f($(window.document));f($(window.top.document));for(var e=window.top.frames.length;e--;){var g=$(window.top.frames[e].document);f(g)}},50);return false})}function make_popup_menus(a){a=a||document;$(a).find("div[popupmenu]").each(function(){var b={};var d=$(this);d.find("a").each(function(){var g=$(this),i=g.get(0),e=i.getAttribute("confirm"),f=i.getAttribute("href"),h=i.getAttribute("target");if(!f){b[g.text()]=null}else{b[g.text()]={url:f,action:function(){if(!e||confirm(e)){if(h){window.open(f,h)}else{g.click()}}}}}});var c=$(a).find("#"+d.attr("popupmenu"));c.find("a").bind("click",function(f){f.stopPropagation();return true});make_popupmenu(c,b);c.addClass("popup");d.remove()})}function naturalSort(j,h){var p=/(-?[0-9\.]+)/g,k=j.toString().toLowerCase()||"",g=h.toString().toLowerCase()||"",l=String.fromCharCode(0),n=k.replace(p,l+"$1"+l).split(l),e=g.replace(p,l+"$1"+l).split(l),d=(new Date(k)).getTime(),o=d?(new Date(g)).getTime():null;if(o){if(d<o){return -1}else{if(d>o){return 1}}}var m,f;for(var i=0,c=Math.max(n.length,e.length);i<c;i++){m=parseFloat(n[i])||n[i];f=parseFloat(e[i])||e[i];if(m<f){return -1}else{if(m>f){return 1}}}return 0}$.fn.refresh_select2=function(){var b=$(this);var a={width:"resolve",closeOnSelect:!b.is("[MULTIPLE]")};return b.select2(a)};function replace_big_select_inputs(a,c,b){if(!jQuery.fn.select2){return}if(a===undefined){a=20}if(c===undefined){c=3000}b=b||$("select");b.each(function(){var e=$(this);var d=e.find("option").length;if((d<a)||(d>c)){return}if(e.hasClass("no-autocomplete")){return}e.refresh_select2()})}$.fn.make_text_editable=function(g){var d=("num_cols" in g?g.num_cols:30),c=("num_rows" in g?g.num_rows:4),e=("use_textarea" in g?g.use_textarea:false),b=("on_finish" in g?g.on_finish:null),f=("help_text" in g?g.help_text:null);var a=$(this);a.addClass("editable-text").click(function(l){if($(this).children(":input").length>0){return}a.removeClass("editable-text");var i=function(m){a.find(":input").remove();if(m!==""){a.text(m)}else{a.html("<br>")}a.addClass("editable-text");if(b){b(m)}};var h=("cur_text" in g?g.cur_text:a.text()),k,j;if(e){k=$("<textarea/>").attr({rows:c,cols:d}).text($.trim(h)).keyup(function(m){if(m.keyCode===27){i(h)}});j=$("<button/>").text("Done").click(function(){i(k.val());return false})}else{k=$("<input type='text'/>").attr({value:$.trim(h),size:d}).blur(function(){i(h)}).keyup(function(m){if(m.keyCode===27){$(this).trigger("blur")}else{if(m.keyCode===13){i($(this).val())}}})}a.text("");a.append(k);if(j){a.append(j)}k.focus();k.select();l.stopPropagation()});if(f){a.attr("title",f).tooltip()}return a};function async_save_text(d,f,e,a,c,h,i,g,b){if(c===undefined){c=30}if(i===undefined){i=4}$("#"+d).click(function(){if($("#renaming-active").length>0){return}var l=$("#"+f),k=l.text(),j;if(h){j=$("<textarea></textarea>").attr({rows:i,cols:c}).text($.trim(k))}else{j=$("<input type='text'></input>").attr({value:$.trim(k),size:c})}j.attr("id","renaming-active");j.blur(function(){$(this).remove();l.show();if(b){b(j)}});j.keyup(function(n){if(n.keyCode===27){$(this).trigger("blur")}else{if(n.keyCode===13){var m={};m[a]=$(this).val();$(this).trigger("blur");$.ajax({url:e,data:m,error:function(){alert("Text editing for elt "+f+" failed")},success:function(o){if(o!==""){l.text(o)}else{l.html("<em>None</em>")}if(b){b(j)}}})}}});if(g){g(j)}l.hide();j.insertAfter(l);j.focus();j.select();return})}function init_history_items(d,a,c){var b=function(){try{var e=$.jStorage.get("history_expand_state");if(e){for(var g in e){$("#"+g+" div.historyItemBody").show()}}}catch(f){$.jStorage.deleteKey("history_expand_state")}if($.browser.mozilla){$("div.historyItemBody").each(function(){if(!$(this).is(":visible")){$(this).find("pre.peek").css("overflow","hidden")}})}d.each(function(){var j=this.id,h=$(this).children("div.historyItemBody"),i=h.find("pre.peek");$(this).find(".historyItemTitleBar > .historyItemTitle").wrap("<a href='javascript:void(0);'></a>").click(function(){var k;if(h.is(":visible")){if($.browser.mozilla){i.css("overflow","hidden")}h.slideUp("fast");if(!c){k=$.jStorage.get("history_expand_state");if(k){delete k[j];$.jStorage.set("history_expand_state",k)}}}else{h.slideDown("fast",function(){if($.browser.mozilla){i.css("overflow","auto")}});if(!c){k=$.jStorage.get("history_expand_state");if(!k){k={}}k[j]=true;$.jStorage.set("history_expand_state",k)}}return false})});$("#top-links > a.toggle").click(function(){var h=$.jStorage.get("history_expand_state");if(!h){h={}}$("div.historyItemBody:visible").each(function(){if($.browser.mozilla){$(this).find("pre.peek").css("overflow","hidden")}$(this).slideUp("fast");if(h){delete h[$(this).parent().attr("id")]}});$.jStorage.set("history_expand_state",h)}).show()};b()}function commatize(b){b+="";var a=/(\d+)(\d{3})/;while(a.test(b)){b=b.replace(a,"$1,$2")}return b}function reset_tool_search(a){var c=$("#galaxy_tools").contents();if(c.length===0){c=$(document)}$(this).removeClass("search_active");c.find(".toolTitle").removeClass("search_match");c.find(".toolSectionBody").hide();c.find(".toolTitle").show();c.find(".toolPanelLabel").show();c.find(".toolSectionWrapper").each(function(){if($(this).attr("id")!=="recently_used_wrapper"){$(this).show()}else{if($(this).hasClass("user_pref_visible")){$(this).show()}}});c.find("#search-no-results").hide();c.find("#search-spinner").hide();if(a){var b=c.find("#tool-search-query");b.val("search tools")}}var GalaxyAsync=function(a){this.url_dict={};this.log_action=(a===undefined?false:a)};GalaxyAsync.prototype.set_func_url=function(a,b){this.url_dict[a]=b};GalaxyAsync.prototype.set_user_pref=function(a,b){var c=this.url_dict[arguments.callee];if(c===undefined){return false}$.ajax({url:c,data:{pref_name:a,pref_value:b},error:function(){return false},success:function(){return true}})};GalaxyAsync.prototype.log_user_action=function(c,b,d){if(!this.log_action){return}var a=this.url_dict[arguments.callee];if(a===undefined){return false}$.ajax({url:a,data:{action:c,context:b,params:d},error:function(){return false},success:function(){return true}})};function init_refresh_on_change(){$("select[refresh_on_change='true']").off("change").change(function(){var a=$(this),e=a.val(),d=false,c=a.attr("refresh_on_change_values");if(c){c=c.split(",");var b=a.attr("last_selected_value");if($.inArray(e,c)===-1&&$.inArray(b,c)===-1){return}}$(window).trigger("refresh_on_change");$(document).trigger("convert_to_values");a.get(0).form.submit()});$(":checkbox[refresh_on_change='true']").off("click").click(function(){var a=$(this),e=a.val(),d=false,c=a.attr("refresh_on_change_values");if(c){c=c.split(",");var b=a.attr("last_selected_value");if($.inArray(e,c)===-1&&$.inArray(b,c)===-1){return}}$(window).trigger("refresh_on_change");a.get(0).form.submit()});$("a[confirm]").off("click").click(function(){return confirm($(this).attr("confirm"))})}$(document).ready(function(){init_refresh_on_change();if($.fn.tooltip){$(".unified-panel-header [title]").tooltip({placement:"bottom"});$("[title]").tooltip({placement:"top"})}make_popup_menus();replace_big_select_inputs(20,1500);$("a").click(function(){var b=$(this);var c=(parent.frames&&parent.frames.galaxy_main);if((b.attr("target")=="galaxy_main")&&(!c)){var a=b.attr("href");if(a.indexOf("?")==-1){a+="?"}else{a+="&"}a+="use_panels=True";b.attr("href",a);b.attr("target","_self")}return b})});
\ No newline at end of file
+(function(){var b=0;var c=["ms","moz","webkit","o"];for(var a=0;a<c.length&&!window.requestAnimationFrame;++a){window.requestAnimationFrame=window[c[a]+"RequestAnimationFrame"];window.cancelRequestAnimationFrame=window[c[a]+"CancelRequestAnimationFrame"]}if(!window.requestAnimationFrame){window.requestAnimationFrame=function(h,e){var d=new Date().getTime();var f=Math.max(0,16-(d-b));var g=window.setTimeout(function(){h(d+f)},f);b=d+f;return g}}if(!window.cancelAnimationFrame){window.cancelAnimationFrame=function(d){clearTimeout(d)}}}());if(!Array.indexOf){Array.prototype.indexOf=function(c){for(var b=0,a=this.length;b<a;b++){if(this[b]==c){return b}}return -1}}function obj_length(c){if(c.length!==undefined){return c.length}var b=0;for(var a in c){b++}return b}$.fn.makeAbsolute=function(a){return this.each(function(){var b=$(this);var c=b.position();b.css({position:"absolute",marginLeft:0,marginTop:0,top:c.top,left:c.left,right:$(window).width()-(c.left+b.width())});if(a){b.remove().appendTo("body")}})};function make_popupmenu(b,c){var a=(b.data("menu_options"));b.data("menu_options",c);if(a){return}b.bind("click.show_popup",function(d){$(".popmenu-wrapper").remove();setTimeout(function(){var g=$("<ul class='dropdown-menu' id='"+b.attr("id")+"-menu'></ul>");var f=b.data("menu_options");if(obj_length(f)<=0){$("<li>No Options.</li>").appendTo(g)}$.each(f,function(j,i){if(i){var l=i.action||i;g.append($("<li></li>").append($("<a>").attr("href",i.url).html(j).click(l)))}else{g.append($("<li></li>").addClass("head").append($("<a href='#'></a>").html(j)))}});var h=$("<div class='popmenu-wrapper' style='position: absolute;left: 0; top: -1000;'></div>").append(g).appendTo("body");var e=d.pageX-h.width()/2;e=Math.min(e,$(document).scrollLeft()+$(window).width()-$(h).width()-5);e=Math.max(e,$(document).scrollLeft()+5);h.css({top:d.pageY,left:e})},10);setTimeout(function(){var f=function(h){$(h).bind("click.close_popup",function(){$(".popmenu-wrapper").remove();h.unbind("click.close_popup")})};f($(window.document));f($(window.top.document));for(var e=window.top.frames.length;e--;){var g=$(window.top.frames[e].document);f(g)}},50);return false})}function make_popup_menus(a){a=a||document;$(a).find("div[popupmenu]").each(function(){var b={};var d=$(this);d.find("a").each(function(){var g=$(this),i=g.get(0),e=i.getAttribute("confirm"),f=i.getAttribute("href"),h=i.getAttribute("target");if(!f){b[g.text()]=null}else{b[g.text()]={url:f,action:function(){if(!e||confirm(e)){if(h){window.open(f,h);return false}else{g.click()}}}}}});var c=$(a).find("#"+d.attr("popupmenu"));c.find("a").bind("click",function(f){f.stopPropagation();return true});make_popupmenu(c,b);c.addClass("popup");d.remove()})}function naturalSort(j,h){var p=/(-?[0-9\.]+)/g,k=j.toString().toLowerCase()||"",g=h.toString().toLowerCase()||"",l=String.fromCharCode(0),n=k.replace(p,l+"$1"+l).split(l),e=g.replace(p,l+"$1"+l).split(l),d=(new Date(k)).getTime(),o=d?(new Date(g)).getTime():null;if(o){if(d<o){return -1}else{if(d>o){return 1}}}var m,f;for(var i=0,c=Math.max(n.length,e.length);i<c;i++){m=parseFloat(n[i])||n[i];f=parseFloat(e[i])||e[i];if(m<f){return -1}else{if(m>f){return 1}}}return 0}$.fn.refresh_select2=function(){var b=$(this);var a={width:"resolve",closeOnSelect:!b.is("[MULTIPLE]")};return b.select2(a)};function replace_big_select_inputs(a,c,b){if(!jQuery.fn.select2){return}if(a===undefined){a=20}if(c===undefined){c=3000}b=b||$("select");b.each(function(){var e=$(this);var d=e.find("option").length;if((d<a)||(d>c)){return}if(e.hasClass("no-autocomplete")){return}e.refresh_select2()})}$.fn.make_text_editable=function(g){var d=("num_cols" in g?g.num_cols:30),c=("num_rows" in g?g.num_rows:4),e=("use_textarea" in g?g.use_textarea:false),b=("on_finish" in g?g.on_finish:null),f=("help_text" in g?g.help_text:null);var a=$(this);a.addClass("editable-text").click(function(l){if($(this).children(":input").length>0){return}a.removeClass("editable-text");var i=function(m){a.find(":input").remove();if(m!==""){a.text(m)}else{a.html("<br>")}a.addClass("editable-text");if(b){b(m)}};var h=("cur_text" in g?g.cur_text:a.text()),k,j;if(e){k=$("<textarea/>").attr({rows:c,cols:d}).text($.trim(h)).keyup(function(m){if(m.keyCode===27){i(h)}});j=$("<button/>").text("Done").click(function(){i(k.val());return false})}else{k=$("<input type='text'/>").attr({value:$.trim(h),size:d}).blur(function(){i(h)}).keyup(function(m){if(m.keyCode===27){$(this).trigger("blur")}else{if(m.keyCode===13){i($(this).val())}}})}a.text("");a.append(k);if(j){a.append(j)}k.focus();k.select();l.stopPropagation()});if(f){a.attr("title",f).tooltip()}return a};function async_save_text(d,f,e,a,c,h,i,g,b){if(c===undefined){c=30}if(i===undefined){i=4}$("#"+d).click(function(){if($("#renaming-active").length>0){return}var l=$("#"+f),k=l.text(),j;if(h){j=$("<textarea></textarea>").attr({rows:i,cols:c}).text($.trim(k))}else{j=$("<input type='text'></input>").attr({value:$.trim(k),size:c})}j.attr("id","renaming-active");j.blur(function(){$(this).remove();l.show();if(b){b(j)}});j.keyup(function(n){if(n.keyCode===27){$(this).trigger("blur")}else{if(n.keyCode===13){var m={};m[a]=$(this).val();$(this).trigger("blur");$.ajax({url:e,data:m,error:function(){alert("Text editing for elt "+f+" failed")},success:function(o){if(o!==""){l.text(o)}else{l.html("<em>None</em>")}if(b){b(j)}}})}}});if(g){g(j)}l.hide();j.insertAfter(l);j.focus();j.select();return})}function init_history_items(d,a,c){var b=function(){try{var e=$.jStorage.get("history_expand_state");if(e){for(var g in e){$("#"+g+" div.historyItemBody").show()}}}catch(f){$.jStorage.deleteKey("history_expand_state")}if($.browser.mozilla){$("div.historyItemBody").each(function(){if(!$(this).is(":visible")){$(this).find("pre.peek").css("overflow","hidden")}})}d.each(function(){var j=this.id,h=$(this).children("div.historyItemBody"),i=h.find("pre.peek");$(this).find(".historyItemTitleBar > .historyItemTitle").wrap("<a href='javascript:void(0);'></a>").click(function(){var k;if(h.is(":visible")){if($.browser.mozilla){i.css("overflow","hidden")}h.slideUp("fast");if(!c){k=$.jStorage.get("history_expand_state");if(k){delete k[j];$.jStorage.set("history_expand_state",k)}}}else{h.slideDown("fast",function(){if($.browser.mozilla){i.css("overflow","auto")}});if(!c){k=$.jStorage.get("history_expand_state");if(!k){k={}}k[j]=true;$.jStorage.set("history_expand_state",k)}}return false})});$("#top-links > a.toggle").click(function(){var h=$.jStorage.get("history_expand_state");if(!h){h={}}$("div.historyItemBody:visible").each(function(){if($.browser.mozilla){$(this).find("pre.peek").css("overflow","hidden")}$(this).slideUp("fast");if(h){delete h[$(this).parent().attr("id")]}});$.jStorage.set("history_expand_state",h)}).show()};b()}function commatize(b){b+="";var a=/(\d+)(\d{3})/;while(a.test(b)){b=b.replace(a,"$1,$2")}return b}function reset_tool_search(a){var c=$("#galaxy_tools").contents();if(c.length===0){c=$(document)}$(this).removeClass("search_active");c.find(".toolTitle").removeClass("search_match");c.find(".toolSectionBody").hide();c.find(".toolTitle").show();c.find(".toolPanelLabel").show();c.find(".toolSectionWrapper").each(function(){if($(this).attr("id")!=="recently_used_wrapper"){$(this).show()}else{if($(this).hasClass("user_pref_visible")){$(this).show()}}});c.find("#search-no-results").hide();c.find("#search-spinner").hide();if(a){var b=c.find("#tool-search-query");b.val("search tools")}}var GalaxyAsync=function(a){this.url_dict={};this.log_action=(a===undefined?false:a)};GalaxyAsync.prototype.set_func_url=function(a,b){this.url_dict[a]=b};GalaxyAsync.prototype.set_user_pref=function(a,b){var c=this.url_dict[arguments.callee];if(c===undefined){return false}$.ajax({url:c,data:{pref_name:a,pref_value:b},error:function(){return false},success:function(){return true}})};GalaxyAsync.prototype.log_user_action=function(c,b,d){if(!this.log_action){return}var a=this.url_dict[arguments.callee];if(a===undefined){return false}$.ajax({url:a,data:{action:c,context:b,params:d},error:function(){return false},success:function(){return true}})};function init_refresh_on_change(){$("select[refresh_on_change='true']").off("change").change(function(){var a=$(this),e=a.val(),d=false,c=a.attr("refresh_on_change_values");if(c){c=c.split(",");var b=a.attr("last_selected_value");if($.inArray(e,c)===-1&&$.inArray(b,c)===-1){return}}$(window).trigger("refresh_on_change");$(document).trigger("convert_to_values");a.get(0).form.submit()});$(":checkbox[refresh_on_change='true']").off("click").click(function(){var a=$(this),e=a.val(),d=false,c=a.attr("refresh_on_change_values");if(c){c=c.split(",");var b=a.attr("last_selected_value");if($.inArray(e,c)===-1&&$.inArray(b,c)===-1){return}}$(window).trigger("refresh_on_change");a.get(0).form.submit()});$("a[confirm]").off("click").click(function(){return confirm($(this).attr("confirm"))})}$(document).ready(function(){init_refresh_on_change();if($.fn.tooltip){$(".unified-panel-header [title]").tooltip({placement:"bottom"});$("[title]").tooltip({placement:"top"})}make_popup_menus();replace_big_select_inputs(20,1500);$("a").click(function(){var b=$(this);var c=(parent.frames&&parent.frames.galaxy_main);if((b.attr("target")=="galaxy_main")&&(!c)){var a=b.attr("href");if(a.indexOf("?")==-1){a+="?"}else{a+="&"}a+="use_panels=True";b.attr("href",a);b.attr("target","_self")}return b})});
\ No newline at end of file
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: greg: Add the ability for a tool shed repository owner to grant administrative privileges on a repository to other users or groups. This feature incorporates the tool shed's role based authorization framework. Each repository and repository owner are associated with a repository administrative role which can then be associated with others.
by commits-noreply@bitbucket.org 24 Jan '14
by commits-noreply@bitbucket.org 24 Jan '14
24 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/9414cc43797a/
Changeset: 9414cc43797a
User: greg
Date: 2014-01-24 18:31:29
Summary: Add the ability for a tool shed repository owner to grant administrative privileges on a repository to other users or groups. This feature incorporates the tool shed's role based authorization framework. Each repository and repository owner are associated with a repository administrative role which can then be associated with others.
Affected #: 13 files
diff -r e2eb861e6c0b0cbaf8a1a1e091d3792724495b69 -r 9414cc43797afb77190abcbda0fdf173a6a100f3 lib/galaxy/web/base/controllers/admin.py
--- a/lib/galaxy/web/base/controllers/admin.py
+++ b/lib/galaxy/web/base/controllers/admin.py
@@ -94,6 +94,9 @@
return self.purge_role( trans, **kwargs )
if operation == "manage users and groups":
return self.manage_users_and_groups_for_role( trans, **kwargs )
+ if operation == "manage role associations":
+ # This is currently used only in the Tool Shed.
+ return self.manage_role_associations( trans, **kwargs )
if operation == "rename":
return self.rename_role( trans, **kwargs )
# Render the list view
diff -r e2eb861e6c0b0cbaf8a1a1e091d3792724495b69 -r 9414cc43797afb77190abcbda0fdf173a6a100f3 lib/galaxy/webapps/tool_shed/controllers/admin.py
--- a/lib/galaxy/webapps/tool_shed/controllers/admin.py
+++ b/lib/galaxy/webapps/tool_shed/controllers/admin.py
@@ -1,17 +1,14 @@
+import logging
from galaxy.web.base.controller import BaseUIController
-from galaxy import web, util
from galaxy.web.base.controllers.admin import Admin
+from galaxy import util
+from galaxy import web
from galaxy.util import inflector
import tool_shed.util.shed_util_common as suc
import tool_shed.util.metadata_util as metadata_util
+from tool_shed.util import repository_maintenance_util
import tool_shed.grids.admin_grids as admin_grids
-from galaxy import eggs
-eggs.require( 'mercurial' )
-from mercurial import hg
-
-import logging
-
log = logging.getLogger( __name__ )
@@ -27,7 +24,7 @@
@web.expose
@web.require_admin
def browse_repositories( self, trans, **kwd ):
- # We add params to the keyword dict in this method in order to rename the param
+ # We add parameters to the keyword dict in this method in order to rename the param
# with an "f-" prefix, simulating filtering by clicking a search link. We have
# to take this approach because the "-" character is illegal in HTTP requests.
if 'operation' in kwd:
@@ -166,6 +163,11 @@
for repository_metadata in repository.downloadable_revisions:
repository_metadata.downloadable = False
trans.sa_session.add( repository_metadata )
+ # Mark the repository admin role as deleted.
+ repository_admin_role = repository.admin_role
+ if repository_admin_role is not None:
+ repository_admin_role.deleted = True
+ trans.sa_session.add( repository_admin_role )
repository.deleted = True
trans.sa_session.add( repository )
trans.sa_session.flush()
@@ -295,6 +297,33 @@
@web.expose
@web.require_admin
+ def manage_role_associations( self, trans, **kwd ):
+ """Manage users, groups and repositories associated with a role."""
+ role_id = kwd.get( 'id', None )
+ role = repository_maintenance_util.get_role_by_id( trans, role_id )
+ # We currently only have a single role associated with a repository, the repository admin role.
+ repository_role_association = role.repositories[ 0 ]
+ repository = repository_role_association.repository
+ associations_dict = repository_maintenance_util.handle_role_associations( trans, role, repository, **kwd )
+ in_users = associations_dict.get( 'in_users', [] )
+ out_users = associations_dict.get( 'out_users', [] )
+ in_groups = associations_dict.get( 'in_groups', [] )
+ out_groups = associations_dict.get( 'out_groups', [] )
+ message = associations_dict.get( 'message', '' )
+ status = associations_dict.get( 'status', 'done' )
+ return trans.fill_template( '/webapps/tool_shed/role/role.mako',
+ in_admin_controller=True,
+ repository=repository,
+ role=role,
+ in_users=in_users,
+ out_users=out_users,
+ in_groups=in_groups,
+ out_groups=out_groups,
+ message=message,
+ status=status )
+
+ @web.expose
+ @web.require_admin
def reset_metadata_on_selected_repositories_in_tool_shed( self, trans, **kwd ):
if 'reset_metadata_on_selected_repositories_button' in kwd:
message, status = metadata_util.reset_metadata_on_selected_repositories( trans, **kwd )
@@ -322,13 +351,19 @@
repository = suc.get_repository_in_tool_shed( trans, repository_id )
if repository:
if repository.deleted:
- # Inspect all repository_metadata records to determine those that are installable, and mark them accordingly.
+ # Inspect all repository_metadata records to determine those that are installable, and mark
+ # them accordingly.
for repository_metadata in repository.metadata_revisions:
metadata = repository_metadata.metadata
if metadata:
if metadata_util.is_downloadable( metadata ):
repository_metadata.downloadable = True
trans.sa_session.add( repository_metadata )
+ # Mark the repository admin role as not deleted.
+ repository_admin_role = repository.admin_role
+ if repository_admin_role is not None:
+ repository_admin_role.deleted = False
+ trans.sa_session.add( repository_admin_role )
repository.deleted = False
trans.sa_session.add( repository )
trans.sa_session.flush()
diff -r e2eb861e6c0b0cbaf8a1a1e091d3792724495b69 -r 9414cc43797afb77190abcbda0fdf173a6a100f3 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
@@ -68,6 +68,7 @@
my_writable_repositories_with_test_install_errors_grid = repository_grids.MyWritableRepositoriesWithTestInstallErrorsGrid()
repositories_by_user_grid = repository_grids.RepositoriesByUserGrid()
repositories_i_own_grid = repository_grids.RepositoriesIOwnGrid()
+ repositories_i_can_administer_grid = repository_grids.RepositoriesICanAdministerGrid()
repositories_in_category_grid = repository_grids.RepositoriesInCategoryGrid()
repositories_missing_tool_test_components_grid = repository_grids.RepositoriesMissingToolTestComponentsGrid()
repositories_with_failing_tool_tests_grid = repository_grids.RepositoriesWithFailingToolTestsGrid()
@@ -351,8 +352,9 @@
@web.expose
def browse_repositories( self, trans, **kwd ):
- # We add params to the keyword dict in this method in order to rename the param with an "f-" prefix, simulating filtering by clicking a search
- # link. We have to take this approach because the "-" character is illegal in HTTP requests.
+ # We add params to the keyword dict in this method in order to rename the param with an "f-" prefix,
+ # simulating filtering by clicking a search link. We have to take this approach because the "-"
+ # character is illegal in HTTP requests.
if 'operation' in kwd:
operation = kwd[ 'operation' ].lower()
if operation == "view_or_manage_repository":
@@ -434,6 +436,32 @@
return self.repositories_by_user_grid( trans, **kwd )
@web.expose
+ def browse_repositories_i_can_administer( self, trans, **kwd ):
+ if 'operation' in kwd:
+ operation = kwd[ 'operation' ].lower()
+ if operation == "view_or_manage_repository":
+ return trans.response.send_redirect( web.url_for( controller='repository',
+ action='view_or_manage_repository',
+ **kwd ) )
+ elif operation == "repositories_by_user":
+ return trans.response.send_redirect( web.url_for( controller='repository',
+ action='browse_repositories_by_user',
+ **kwd ) )
+ elif operation in [ 'mark as deprecated', 'mark as not deprecated' ]:
+ kwd[ 'mark_deprecated' ] = operation == 'mark as deprecated'
+ return trans.response.send_redirect( web.url_for( controller='repository',
+ action='deprecate',
+ **kwd ) )
+ selected_changeset_revision, repository = suc.get_repository_from_refresh_on_change( trans, **kwd )
+ if repository:
+ return trans.response.send_redirect( web.url_for( controller='repository',
+ action='browse_repositories',
+ operation='view_or_manage_repository',
+ id=trans.security.encode_id( repository.id ),
+ changeset_revision=selected_changeset_revision ) )
+ return self.repositories_i_can_administer_grid( trans, **kwd )
+
+ @web.expose
def browse_repositories_i_own( self, trans, **kwd ):
if 'operation' in kwd:
operation = kwd[ 'operation' ].lower()
@@ -921,8 +949,8 @@
status = kwd.get( 'status', 'done' )
categories = suc.get_categories( trans )
if not categories:
- message = 'No categories have been configured in this instance of the Galaxy Tool Shed. ' + \
- 'An administrator needs to create some via the Administrator control panel before creating repositories.',
+ message = 'No categories have been configured in this instance of the Galaxy Tool Shed. '
+ message += 'An administrator needs to create some via the Administrator control panel before creating repositories.',
status = 'error'
return trans.response.send_redirect( web.url_for( controller='repository',
action='browse_repositories',
@@ -1741,8 +1769,9 @@
owner = kwd.get( 'owner', None )
changeset_revision = kwd.get( 'changeset_revision', None )
repository = suc.get_repository_by_name_and_owner( trans.app, name, owner )
- # TODO: We're currently returning the tool_dependencies.xml file that is available on disk. We need to enhance this process
- # to retrieve older versions of the tool-dependencies.xml file from the repository manafest.
+ # TODO: We're currently returning the tool_dependencies.xml file that is available on disk. We need
+ # to enhance this process to retrieve older versions of the tool-dependencies.xml file from the repository
+ #manafest.
repo_dir = repository.repo_path( trans.app )
# Get the tool_dependencies.xml file from disk.
tool_dependencies_config = suc.get_config_from_disk( suc.TOOL_DEPENDENCY_DEFINITION_FILENAME, repo_dir )
@@ -1951,6 +1980,9 @@
# See if there are any RepositoryMetadata records since menu items require them.
repository_metadata = trans.sa_session.query( trans.model.RepositoryMetadata ).first()
current_user = trans.user
+ # TODO: move the following to some in-memory register so these queries can be done once
+ # at startup. The in-memory registe can then be managed during the current session.
+ can_administer_repositories = False
has_reviewed_repositories = False
has_deprecated_repositories = False
if current_user:
@@ -1964,6 +1996,16 @@
if repository.deprecated:
has_deprecated_repositories = True
break
+ # See if the current user can administer any repositories, but only if not an admin user.
+ if not trans.user_is_admin():
+ if current_user.active_repositories:
+ can_administer_repositories = True
+ else:
+ for repository in trans.sa_session.query( trans.model.Repository ) \
+ .filter( trans.model.Repository.table.c.deleted == False ):
+ if trans.app.security_agent.user_can_administer_repository( current_user, repository ):
+ can_administer_repositories = True
+ break
# Route in may have been from a sharable URL, in whcih case we'll have a user_id and possibly a name
# The received user_id will be the id of the repository owner.
user_id = kwd.get( 'user_id', None )
@@ -1971,6 +2013,7 @@
changeset_revision = kwd.get( 'changeset_revision', None )
return trans.fill_template( '/webapps/tool_shed/index.mako',
repository_metadata=repository_metadata,
+ can_administer_repositories=can_administer_repositories,
has_reviewed_repositories=has_reviewed_repositories,
has_deprecated_repositories=has_deprecated_repositories,
user_id=user_id,
@@ -2116,9 +2159,8 @@
user = trans.user
if kwd.get( 'edit_repository_button', False ):
flush_needed = False
- # TODO: add a can_manage in the security agent.
- if not ( user.email == repository.user.email or trans.user_is_admin() ):
- message = "You are not the owner of this repository, so you cannot manage it."
+ if not ( trans.user_is_admin() or trans.app.security_agent.user_can_administer_repository( user, repository ) ):
+ message = "You are not the owner of this repository, so you cannot administer it."
return trans.response.send_redirect( web.url_for( controller='repository',
action='view_repository',
id=id,
@@ -2145,6 +2187,12 @@
# Change the entry in the repository's hgrc file.
hgrc_file = os.path.join( repo_dir, '.hg', 'hgrc' )
repository_maintenance_util.change_repository_name_in_hgrc_file( hgrc_file, repo_name )
+ # Rename the repository's admin role to match the new repository name.
+ repository_admin_role = repository.admin_role
+ repository_admin_role.name = \
+ repository_maintenance_util.get_repository_admin_role_name( str( repo_name ),
+ str( repository.user.username ) )
+ trans.sa_session.add( repository_admin_role )
repository.name = repo_name
flush_needed = True
elif repository.times_downloaded != 0 and repo_name != repository.name:
@@ -2345,6 +2393,55 @@
status=status )
@web.expose
+ @web.require_login( "manage repository administrators" )
+ def manage_repository_admins( self, trans, id, **kwd ):
+ message = kwd.get( 'message', '' )
+ status = kwd.get( 'status', 'done' )
+ repository = suc.get_repository_in_tool_shed( trans, id )
+ changeset_revision = kwd.get( 'changeset_revision', repository.tip( trans.app ) )
+ metadata = None
+ if changeset_revision != suc.INITIAL_CHANGELOG_HASH:
+ repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans, id, changeset_revision )
+ if repository_metadata:
+ metadata = repository_metadata.metadata
+ else:
+ # There is no repository_metadata defined for the changeset_revision, so see if it was defined
+ # in a previous changeset in the changelog.
+ repo_dir = repository.repo_path( trans.app )
+ repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ previous_changeset_revision = \
+ suc.get_previous_metadata_changeset_revision( repository,
+ repo,
+ changeset_revision,
+ downloadable=False )
+ if previous_changeset_revision != suc.INITIAL_CHANGELOG_HASH:
+ repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans,
+ id,
+ previous_changeset_revision )
+ if repository_metadata:
+ metadata = repository_metadata.metadata
+ role = repository.admin_role
+ associations_dict = repository_maintenance_util.handle_role_associations( trans, role, repository, **kwd )
+ in_users = associations_dict.get( 'in_users', [] )
+ out_users = associations_dict.get( 'out_users', [] )
+ in_groups = associations_dict.get( 'in_groups', [] )
+ out_groups = associations_dict.get( 'out_groups', [] )
+ message = associations_dict.get( 'message', '' )
+ status = associations_dict.get( 'status', 'done' )
+ return trans.fill_template( '/webapps/tool_shed/role/role.mako',
+ in_admin_controller=False,
+ repository=repository,
+ metadata=metadata,
+ changeset_revision=changeset_revision,
+ role=role,
+ in_users=in_users,
+ out_users=out_users,
+ in_groups=in_groups,
+ out_groups=out_groups,
+ message=message,
+ status=status )
+
+ @web.expose
@web.require_login( "review repository revision" )
def manage_repository_reviews_of_revision( self, trans, **kwd ):
return trans.response.send_redirect( web.url_for( controller='repository_review',
@@ -3025,8 +3122,10 @@
repository_id = kwd.get( 'id', None )
if repository_id:
repository = suc.get_repository_in_tool_shed( trans, repository_id )
+ user = trans.user
if repository:
- if trans.user_is_admin() or repository.user == trans.user:
+ if user is not None and ( trans.user_is_admin() or \
+ trans.app.security_agent.user_can_administer_repository( user, repository ) ):
return trans.response.send_redirect( web.url_for( controller='repository',
action='manage_repository',
**kwd ) )
diff -r e2eb861e6c0b0cbaf8a1a1e091d3792724495b69 -r 9414cc43797afb77190abcbda0fdf173a6a100f3 lib/galaxy/webapps/tool_shed/model/__init__.py
--- a/lib/galaxy/webapps/tool_shed/model/__init__.py
+++ b/lib/galaxy/webapps/tool_shed/model/__init__.py
@@ -40,10 +40,6 @@
roles.append( role )
return roles
- def set_password_cleartext( self, cleartext ):
- """Set 'self.password' to the digest of 'cleartext'."""
- self.password = new_secure_hash( text_type=cleartext )
-
def check_password( self, cleartext ):
"""Check if 'cleartext' matches 'self.password' when hashed."""
return self.password == new_secure_hash( text_type=cleartext )
@@ -51,14 +47,18 @@
def get_disk_usage( self, nice_size=False ):
return 0
+ @property
+ def nice_total_disk_usage( self ):
+ return 0
+
def set_disk_usage( self, bytes ):
pass
total_disk_usage = property( get_disk_usage, set_disk_usage )
- @property
- def nice_total_disk_usage( self ):
- return 0
+ def set_password_cleartext( self, cleartext ):
+ """Set 'self.password' to the digest of 'cleartext'."""
+ self.password = new_secure_hash( text_type=cleartext )
class Group( object, Dictifiable ):
@@ -74,19 +74,26 @@
dict_collection_visible_keys = ( 'id', 'name' )
dict_element_visible_keys = ( 'id', 'name', 'description', 'type' )
private_id = None
- types = Bunch(
- PRIVATE = 'private',
- SYSTEM = 'system',
- USER = 'user',
- ADMIN = 'admin',
- SHARING = 'sharing'
- )
+ types = Bunch( PRIVATE = 'private',
+ SYSTEM = 'system',
+ USER = 'user',
+ ADMIN = 'admin',
+ SHARING = 'sharing' )
def __init__( self, name="", description="", type="system", deleted=False ):
self.name = name
self.description = description
self.type = type
self.deleted = deleted
+
+ @property
+ def is_repository_admin_role( self ):
+ # A repository admin role must always be associated with a repository. The mapper returns an
+ # empty list for those roles that have no repositories. This method will require changes if
+ # new features are introduced that results in more than one role per repository.
+ if self.repositories:
+ return True
+ return False
class UserGroupAssociation( object ):
@@ -107,6 +114,12 @@
self.role = role
+class RepositoryRoleAssociation( object ):
+ def __init__( self, repository, role ):
+ self.repository = repository
+ self.role = role
+
+
class GalaxySession( object ):
def __init__( self,
@@ -131,17 +144,18 @@
class Repository( object, Dictifiable ):
- dict_collection_visible_keys = ( 'id', 'name', 'type', 'description', 'user_id', 'private', 'deleted', 'times_downloaded', 'deprecated' )
- dict_element_visible_keys = ( 'id', 'name', 'type', 'description', 'long_description', 'user_id', 'private', 'deleted', 'times_downloaded',
- 'deprecated' )
+ dict_collection_visible_keys = ( 'id', 'name', 'type', 'description', 'user_id', 'private', 'deleted',
+ 'times_downloaded', 'deprecated' )
+ dict_element_visible_keys = ( 'id', 'name', 'type', 'description', 'long_description', 'user_id', 'private',
+ 'deleted', 'times_downloaded', 'deprecated' )
file_states = Bunch( NORMAL = 'n',
NEEDS_MERGING = 'm',
MARKED_FOR_REMOVAL = 'r',
MARKED_FOR_ADDITION = 'a',
NOT_TRACKED = '?' )
- def __init__( self, id=None, name=None, type=None, description=None, long_description=None, user_id=None, private=False, deleted=None,
- email_alerts=None, times_downloaded=0, deprecated=False ):
+ def __init__( self, id=None, name=None, type=None, description=None, long_description=None, user_id=None, private=False,
+ deleted=None, email_alerts=None, times_downloaded=0, deprecated=False ):
self.id = id
self.name = name or "Unnamed repository"
self.type = type
@@ -154,13 +168,23 @@
self.times_downloaded = times_downloaded
self.deprecated = deprecated
+ @property
+ def admin_role( self ):
+ admin_role_name = '%s_%s_admin' % ( str( self.name ), str( self.user.username ) )
+ for rra in self.roles:
+ role = rra.role
+ if str( role.name ) == admin_role_name:
+ return role
+ raise Exception( 'Repository %s owned by %s is not associated with a required administrative role.' % \
+ ( str( self.name ), str( self.user.username ) ) )
+
def allow_push( self, app ):
repo = hg.repository( ui.ui(), self.repo_path( app ) )
return repo.ui.config( 'web', 'allow_push' )
def can_change_type( self, app ):
- # Allow changing the type only if the repository has no contents, has never been installed, or has never been changed from
- # the default type.
+ # Allow changing the type only if the repository has no contents, has never been installed, or has
+ # never been changed from the default type.
if self.is_new( app ):
return True
if self.times_downloaded == 0:
diff -r e2eb861e6c0b0cbaf8a1a1e091d3792724495b69 -r 9414cc43797afb77190abcbda0fdf173a6a100f3 lib/galaxy/webapps/tool_shed/model/mapping.py
--- a/lib/galaxy/webapps/tool_shed/model/mapping.py
+++ b/lib/galaxy/webapps/tool_shed/model/mapping.py
@@ -74,6 +74,13 @@
Column( "create_time", DateTime, default=now ),
Column( "update_time", DateTime, default=now, onupdate=now ) )
+RepositoryRoleAssociation.table = Table( "repository_role_association", metadata,
+ Column( "id", Integer, primary_key=True ),
+ Column( "repository_id", Integer, ForeignKey( "repository.id" ), index=True ),
+ Column( "role_id", Integer, ForeignKey( "role.id" ), index=True ),
+ Column( "create_time", DateTime, default=now ),
+ Column( "update_time", DateTime, default=now, onupdate=now ) )
+
GalaxySession.table = Table( "galaxy_session", metadata,
Column( "id", Integer, primary_key=True ),
Column( "create_time", DateTime, default=now ),
@@ -203,8 +210,17 @@
mapper( Role, Role.table,
properties=dict(
- users=relation( UserRoleAssociation ),
- groups=relation( GroupRoleAssociation ) ) )
+ repositories=relation( RepositoryRoleAssociation,
+ primaryjoin=( ( Role.table.c.id == RepositoryRoleAssociation.table.c.role_id ) & ( RepositoryRoleAssociation.table.c.repository_id == Repository.table.c.id ) ) ),
+ users=relation( UserRoleAssociation,
+ primaryjoin=( ( Role.table.c.id == UserRoleAssociation.table.c.role_id ) & ( UserRoleAssociation.table.c.user_id == User.table.c.id ) ) ),
+ groups=relation( GroupRoleAssociation,
+ primaryjoin=( ( Role.table.c.id == GroupRoleAssociation.table.c.role_id ) & ( GroupRoleAssociation.table.c.group_id == Group.table.c.id ) ) ) ) )
+
+mapper( RepositoryRoleAssociation, RepositoryRoleAssociation.table,
+ properties=dict(
+ repository=relation( Repository ),
+ role=relation( Role ) ) )
mapper( UserGroupAssociation, UserGroupAssociation.table,
properties=dict( user=relation( User, backref = "groups" ),
@@ -245,6 +261,7 @@
order_by=desc( RepositoryMetadata.table.c.update_time ) ),
metadata_revisions=relation( RepositoryMetadata,
order_by=desc( RepositoryMetadata.table.c.update_time ) ),
+ roles=relation( RepositoryRoleAssociation ),
reviews=relation( RepositoryReview,
primaryjoin=( ( Repository.table.c.id == RepositoryReview.table.c.repository_id ) ) ),
reviewers=relation( User,
diff -r e2eb861e6c0b0cbaf8a1a1e091d3792724495b69 -r 9414cc43797afb77190abcbda0fdf173a6a100f3 lib/galaxy/webapps/tool_shed/model/migrate/versions/0022_add_repository_admin_roles.py
--- /dev/null
+++ b/lib/galaxy/webapps/tool_shed/model/migrate/versions/0022_add_repository_admin_roles.py
@@ -0,0 +1,159 @@
+"""
+Migration script to create the repository_role_association table, insert name-spaced
+repository administrative roles into the role table and associate each repository and
+owner with the appropriate name-spaced role.
+"""
+import datetime, logging, sys
+from sqlalchemy import *
+from sqlalchemy.orm import *
+from migrate import *
+from migrate.changeset import *
+# Need our custom types, but don't import anything else from model
+from galaxy.model.custom_types import *
+
+log = logging.getLogger( __name__ )
+log.setLevel(logging.DEBUG)
+handler = logging.StreamHandler( sys.stdout )
+format = "%(name)s %(levelname)s %(asctime)s %(message)s"
+formatter = logging.Formatter( format )
+handler.setFormatter( formatter )
+log.addHandler( handler )
+
+metadata = MetaData()
+
+NOW = datetime.datetime.utcnow
+ROLE_TYPE = 'system'
+
+RepositoryRoleAssociation_table = Table( "repository_role_association", metadata,
+ Column( "id", Integer, primary_key=True ),
+ Column( "repository_id", Integer, ForeignKey( "repository.id" ), index=True ),
+ Column( "role_id", Integer, ForeignKey( "role.id" ), index=True ),
+ Column( "create_time", DateTime, default=NOW ),
+ Column( "update_time", DateTime, default=NOW, onupdate=NOW ) )
+
+def nextval( migrate_engine, table, col='id' ):
+ if migrate_engine.name in [ 'postgresql', 'postgres' ]:
+ return "nextval('%s_%s_seq')" % ( table, col )
+ elif migrate_engine.name in [ 'mysql', 'sqlite' ]:
+ return "null"
+ else:
+ raise Exception( 'Unable to convert data for unknown database type: %s' % migrate_engine.name )
+
+def localtimestamp( migrate_engine ):
+ if migrate_engine.name in [ 'postgresql', 'postgres', 'mysql' ]:
+ return "LOCALTIMESTAMP"
+ elif migrate_engine.name == 'sqlite':
+ return "current_date || ' ' || current_time"
+ else:
+ raise Exception( 'Unable to convert data for unknown database type: %s' % db )
+
+def boolean_false( migrate_engine ):
+ if migrate_engine.name in [ 'postgresql', 'postgres', 'mysql' ]:
+ return False
+ elif migrate_engine.name == 'sqlite':
+ return 0
+ else:
+ raise Exception( 'Unable to convert data for unknown database type: %s' % db )
+
+def upgrade( migrate_engine ):
+ print __doc__
+ metadata.bind = migrate_engine
+ metadata.reflect()
+ # Create the new repository_role_association table.
+ try:
+ RepositoryRoleAssociation_table.create()
+ except Exception, e:
+ print str(e)
+ log.debug( "Creating repository_role_association table failed: %s" % str( e ) )
+ # Select the list of repositories and associated public user names for their owners.
+ user_ids = []
+ repository_ids = []
+ role_names = []
+ cmd = 'SELECT repository.id, repository.name, repository.user_id, galaxy_user.username FROM repository, galaxy_user WHERE repository.user_id = galaxy_user.id;'
+ for row in migrate_engine.execute( cmd ):
+ repository_id = row[ 0 ]
+ name = row[ 1 ]
+ user_id = row[ 2 ]
+ username = row[ 3 ]
+ repository_ids.append( int( repository_id ) )
+ role_names.append( '%s_%s_admin' % ( str( name ), str( username ) ) )
+ user_ids.append( int( user_id ) )
+ # Insert a new record into the role table for each new role.
+ for tup in zip( repository_ids, user_ids, role_names ):
+ repository_id, user_id, role_name = tup
+ cmd = "INSERT INTO role VALUES ("
+ cmd += "%s, " % nextval( migrate_engine, 'role' )
+ cmd += "%s, " % localtimestamp( migrate_engine )
+ cmd += "%s, " % localtimestamp( migrate_engine )
+ cmd += "'%s', " % role_name
+ cmd += "'A user or group member with this role can administer this repository.', "
+ cmd += "'%s', " % ROLE_TYPE
+ cmd += "%s" % boolean_false( migrate_engine )
+ cmd += ");"
+ migrate_engine.execute( cmd )
+ # Get the id of the new role.
+ cmd = "SELECT id FROM role WHERE name = '%s' and type = '%s';" % ( role_name, ROLE_TYPE )
+ row = migrate_engine.execute( cmd ).fetchone()
+ if row:
+ role_id = row[ 0 ]
+ else:
+ role_id = None
+ if role_id:
+ # Create a repository_role_association record to associate the repository with the new role.
+ cmd = "INSERT INTO repository_role_association VALUES ("
+ cmd += "%s, " % nextval( migrate_engine, 'repository_role_association' )
+ cmd += "%d, " % int( repository_id )
+ cmd += "%d, " % int( role_id )
+ cmd += "%s, " % localtimestamp( migrate_engine )
+ cmd += "%s " % localtimestamp( migrate_engine )
+ cmd += ");"
+ migrate_engine.execute( cmd )
+ # Create a user_role_association record to associate the repository owner with the new role.
+ cmd = "INSERT INTO user_role_association VALUES ("
+ cmd += "%s, " % nextval( migrate_engine, 'user_role_association' )
+ cmd += "%d, " % int( user_id )
+ cmd += "%d, " % int( role_id )
+ cmd += "%s, " % localtimestamp( migrate_engine )
+ cmd += "%s " % localtimestamp( migrate_engine )
+ cmd += ");"
+ migrate_engine.execute( cmd )
+
+def downgrade( migrate_engine ):
+ metadata.bind = migrate_engine
+ metadata.reflect()
+ # Determine the list of roles to delete by first selecting the list of repositories and associated
+ # public user names for their owners.
+ role_names = []
+ cmd = 'SELECT name, username FROM repository, galaxy_user WHERE repository.user_id = galaxy_user.id;'
+ for row in migrate_engine.execute( cmd ):
+ name = row[ 0 ]
+ username = row[ 1 ]
+ role_names.append( '%s_%s_admin' % ( str( name ), str( username ) ) )
+ # Delete each role as well as all users associated with each role.
+ for role_name in role_names:
+ # Select the id of the record associated with the current role_name from the role table.
+ cmd = "SELECT id, name FROM role WHERE name = '%s';" % role_name
+ row = migrate_engine.execute( cmd ).fetchone()
+ if row:
+ role_id = row[ 0 ]
+ else:
+ role_id = None
+ if role_id:
+ # Delete all user_role_association records for the current role.
+ cmd = "DELETE FROM user_role_association WHERE role_id = %d;" % int( role_id )
+ migrate_engine.execute( cmd )
+ # Delete all repository_role_association records for the current role.
+ cmd = "DELETE FROM repository_role_association WHERE role_id = %d;" % int( role_id )
+ migrate_engine.execute( cmd )
+ # Delete the role from the role table.
+ cmd = "DELETE FROM role WHERE id = %d;" % int( role_id )
+ migrate_engine.execute( cmd )
+ # Drop the repository_role_association table.
+ try:
+ RepositoryRoleAssociation_table = Table( "repository_role_association", metadata, autoload=True )
+ except NoSuchTableError:
+ log.debug( "Failed loading table repository_role_association" )
+ try:
+ RepositoryRoleAssociation_table.drop()
+ except Exception, e:
+ log.debug( "Dropping repository_role_association table failed: %s" % str( e ) )
diff -r e2eb861e6c0b0cbaf8a1a1e091d3792724495b69 -r 9414cc43797afb77190abcbda0fdf173a6a100f3 lib/galaxy/webapps/tool_shed/security/__init__.py
--- a/lib/galaxy/webapps/tool_shed/security/__init__.py
+++ b/lib/galaxy/webapps/tool_shed/security/__init__.py
@@ -152,7 +152,13 @@
self.model.Role.table.c.type == self.model.Role.types.SYSTEM ) ) \
.first()
- def set_entity_group_associations( self, groups=[], users=[], roles=[], delete_existing_assocs=True ):
+ def set_entity_group_associations( self, groups=None, users=None, roles=None, delete_existing_assocs=True ):
+ if groups is None:
+ groups = []
+ if users is None:
+ users = []
+ if roles is None:
+ roles = []
for group in groups:
if delete_existing_assocs:
for a in group.roles + group.users:
@@ -163,7 +169,15 @@
for user in users:
self.associate_components( group=group, user=user )
- def set_entity_role_associations( self, roles=[], users=[], groups=[], delete_existing_assocs=True ):
+ def set_entity_role_associations( self, roles=None, users=None, groups=None, repositories=None, delete_existing_assocs=True ):
+ if roles is None:
+ roles = []
+ if users is None:
+ users = []
+ if groups is None:
+ groups = []
+ if repositories is None:
+ repositories = []
for role in roles:
if delete_existing_assocs:
for a in role.users + role.groups:
@@ -174,7 +188,13 @@
for group in groups:
self.associate_components( group=group, role=role )
- def set_entity_user_associations( self, users=[], roles=[], groups=[], delete_existing_assocs=True ):
+ def set_entity_user_associations( self, users=None, roles=None, groups=None, delete_existing_assocs=True ):
+ if users is None:
+ users = []
+ if roles is None:
+ roles = []
+ if groups is None:
+ groups = []
for user in users:
if delete_existing_assocs:
for a in user.non_private_roles + user.groups:
@@ -193,6 +213,29 @@
return user.username in listify( repository.allow_push( app ) )
return False
+ def user_can_administer_repository( self, user, repository ):
+ """Return True if the received user can administer the received repository."""
+ if user:
+ if repository:
+ repository_admin_role = repository.admin_role
+ for rra in repository.roles:
+ role = rra.role
+ if role.id == repository_admin_role.id:
+ # We have the repository's admin role, so see if the user is associated with it.
+ for ura in role.users:
+ role_member = ura.user
+ if role_member.id == user.id:
+ return True
+ # The user is not directly associated with the role, so see if they are a member
+ # of a group that is associated with the role.
+ for gra in role.groups:
+ group = gra.group
+ for uga in group.members:
+ member = uga.user
+ if member.id == user.id:
+ return True
+ return False
+
def user_can_import_repository_archive( self, user, archive_owner ):
# This method should be called only if the current user is not an admin.
if user.username == archive_owner:
diff -r e2eb861e6c0b0cbaf8a1a1e091d3792724495b69 -r 9414cc43797afb77190abcbda0fdf173a6a100f3 lib/tool_shed/grids/admin_grids.py
--- a/lib/tool_shed/grids/admin_grids.py
+++ b/lib/tool_shed/grids/admin_grids.py
@@ -149,20 +149,20 @@
class NameColumn( grids.TextColumn ):
def get_value( self, trans, grid, role ):
- return role.name
+ return str( role.name )
class DescriptionColumn( grids.TextColumn ):
def get_value( self, trans, grid, role ):
if role.description:
- return role.description
+ return str( role.description )
return ''
class TypeColumn( grids.TextColumn ):
def get_value( self, trans, grid, role ):
- return role.type
+ return str( role.type )
class StatusColumn( grids.GridColumn ):
@@ -181,6 +181,14 @@
return 0
+ class RepositoriesColumn( grids.GridColumn ):
+
+ def get_value( self, trans, grid, role ):
+ if role.repositories:
+ return len( role.repositories )
+ return 0
+
+
class UsersColumn( grids.GridColumn ):
def get_value( self, trans, grid, role ):
@@ -195,20 +203,16 @@
columns = [
NameColumn( "Name",
key="name",
- link=( lambda item: dict( operation="Manage users and groups", id=item.id ) ),
+ link=( lambda item: dict( operation="Manage role associations", id=item.id ) ),
attach_popup=True,
filterable="advanced" ),
DescriptionColumn( "Description",
key='description',
attach_popup=False,
filterable="advanced" ),
- TypeColumn( "Type",
- key='type',
- attach_popup=False,
- filterable="advanced" ),
GroupsColumn( "Groups", attach_popup=False ),
+ RepositoriesColumn( "Repositories", attach_popup=False ),
UsersColumn( "Users", attach_popup=False ),
- StatusColumn( "Status", attach_popup=False ),
# Columns that are valid for filtering but are not visible.
grids.DeletedColumn( "Deleted",
key="deleted",
@@ -224,20 +228,23 @@
grids.GridAction( "Add new role",
dict( controller='admin', action='roles', operation='create' ) )
]
+ # Repository admin roles currently do not have any operations since they are managed automatically based
+ # on other events. For example, if a repository is renamed, its associated admin role is automatically
+ # renamed accordingly and if a repository is deleted its associated admin role is automatically deleted.
operations = [ grids.GridOperation( "Rename",
- condition=( lambda item: not item.deleted ),
+ condition=( lambda item: not item.deleted and not item.is_repository_admin_role ),
allow_multiple=False,
url_args=dict( action="rename_role" ) ),
grids.GridOperation( "Delete",
- condition=( lambda item: not item.deleted ),
+ condition=( lambda item: not item.deleted and not item.is_repository_admin_role ),
allow_multiple=True,
url_args=dict( action="mark_role_deleted" ) ),
grids.GridOperation( "Undelete",
- condition=( lambda item: item.deleted ),
+ condition=( lambda item: item.deleted and not item.is_repository_admin_role ),
allow_multiple=True,
url_args=dict( action="undelete_role" ) ),
grids.GridOperation( "Purge",
- condition=( lambda item: item.deleted ),
+ condition=( lambda item: item.deleted and not item.is_repository_admin_role ),
allow_multiple=True,
url_args=dict( action="purge_role" ) ) ]
standard_filters = [
diff -r e2eb861e6c0b0cbaf8a1a1e091d3792724495b69 -r 9414cc43797afb77190abcbda0fdf173a6a100f3 lib/tool_shed/grids/repository_grids.py
--- a/lib/tool_shed/grids/repository_grids.py
+++ b/lib/tool_shed/grids/repository_grids.py
@@ -555,6 +555,52 @@
.outerjoin( model.RepositoryCategoryAssociation.table ) \
.outerjoin( model.Category.table )
+class RepositoriesICanAdministerGrid( RepositoryGrid ):
+ title = "Repositories I can administer"
+ columns = [
+ RepositoryGrid.NameColumn( "Name",
+ key="name",
+ link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
+ attach_popup=False ),
+ RepositoryGrid.UserColumn( "Owner" ),
+ RepositoryGrid.MetadataRevisionColumn( "Metadata<br/>Revisions" ),
+ RepositoryGrid.ToolsFunctionallyCorrectColumn( "Tools<br/>Verified" ),
+ RepositoryGrid.DeprecatedColumn( "Deprecated" )
+ ]
+ columns.append( grids.MulticolFilterColumn( "Search repository name",
+ cols_to_filter=[ columns[0] ],
+ key="free-text-search",
+ visible=False,
+ filterable="standard" ) )
+ operations = []
+ use_paging = False
+
+ def build_initial_query( self, trans, **kwd ):
+ """
+ Retrieve all repositories for which the current user has been granted administrative privileges.
+ """
+ current_user = trans.user
+ # Build up an or-based clause list containing role table records.
+ clause_list = []
+ # Include each of the user's roles.
+ for ura in current_user.roles:
+ clause_list.append( model.Role.table.c.id == ura.role_id )
+ # Include each role associated with each group of which the user is a member.
+ for uga in current_user.groups:
+ group = uga.group
+ for gra in group.roles:
+ clause_list.append( model.Role.table.c.id == gra.role_id )
+ # Filter out repositories for which the user does not have the administrative role either directly
+ # via a role association or indirectly via a group -> role association.
+ return trans.sa_session.query( model.Repository ) \
+ .filter( model.Repository.table.c.deleted == False ) \
+ .outerjoin( model.RepositoryRoleAssociation.table ) \
+ .outerjoin( model.Role.table ) \
+ .filter( or_( *clause_list ) ) \
+ .join( model.User.table ) \
+ .outerjoin( model.RepositoryCategoryAssociation.table ) \
+ .outerjoin( model.Category.table )
+
class RepositoriesMissingToolTestComponentsGrid( RepositoryGrid ):
# This grid displays only the latest installable revision of each repository.
diff -r e2eb861e6c0b0cbaf8a1a1e091d3792724495b69 -r 9414cc43797afb77190abcbda0fdf173a6a100f3 lib/tool_shed/util/repository_maintenance_util.py
--- a/lib/tool_shed/util/repository_maintenance_util.py
+++ b/lib/tool_shed/util/repository_maintenance_util.py
@@ -4,6 +4,7 @@
import re
import tool_shed.util.shed_util_common as suc
from tool_shed.util import import_util
+from galaxy import util
from galaxy.web.form_builder import build_select_field
from galaxy.webapps.tool_shed.model import directory_hash_id
@@ -69,6 +70,8 @@
# Flush to get the id.
trans.sa_session.add( repository )
trans.sa_session.flush()
+ # Create an admin role for the repository.
+ repository_admin_role = create_repository_admin_role( trans, repository )
# Determine the repository's repo_path on disk.
dir = os.path.join( trans.app.config.file_path, *directory_hash_id( repository.id ) )
# Create directory if it does not exist.
@@ -100,10 +103,28 @@
message = "Repository <b>%s</b> has been created." % str( repository.name )
return repository, message
+def create_repository_admin_role( trans, repository ):
+ """
+ Create a new role with name-spaced name based on the repository name and its owner's public user
+ name. This will ensure that the tole name is unique.
+ """
+ name = get_repository_admin_role_name( str( repository.name ), str( repository.user.username ) )
+ description = 'A user or group member with this role can administer this repository.'
+ role = trans.app.model.Role( name=name, description=description, type=trans.app.model.Role.types.SYSTEM )
+ trans.sa_session.add( role )
+ trans.sa_session.flush()
+ # Associate the role with the repository owner.
+ ura = trans.model.UserRoleAssociation( repository.user, role )
+ # Associate the role with the repository.
+ rra = trans.model.RepositoryRoleAssociation( repository, role )
+ trans.sa_session.add( rra )
+ trans.sa_session.flush()
+ return role
+
def create_repository_and_import_archive( trans, repository_archive_dict, import_results_tups ):
"""
- Create a new repository in the tool shed and populate it with the contents of a gzip compressed tar archive
- that was exported as part or all of the contents of a capsule.
+ Create a new repository in the tool shed and populate it with the contents of a gzip compressed
+ tar archive that was exported as part or all of the contents of a capsule.
"""
results_message = ''
name = repository_archive_dict.get( 'name', None )
@@ -166,6 +187,66 @@
import_results_tups.append( ( ok, ( str( name ), str( username ) ), results_message ) )
return import_results_tups
+def get_repository_admin_role_name( repository_name, repository_owner ):
+ return '%s_%s_admin' % ( str( repository_name ), str( repository_owner ) )
+
+def get_role_by_id( trans, role_id ):
+ """Get a Role from the database by id."""
+ return trans.sa_session.query( trans.model.Role ).get( trans.security.decode_id( role_id ) )
+
+def handle_role_associations( trans, role, repository, **kwd ):
+ message = kwd.get( 'message', '' )
+ status = kwd.get( 'status', 'done' )
+ repository_owner = repository.user
+ if kwd.get( 'manage_role_associations_button', False ):
+ in_users_list = util.listify( kwd.get( 'in_users', [] ) )
+ in_users = [ trans.sa_session.query( trans.app.model.User ).get( x ) for x in in_users_list ]
+ # Make sure the repository owner is always associated with the repostory's admin role.
+ owner_associated = False
+ for user in in_users:
+ if user.id == repository_owner.id:
+ owner_associated = True
+ break
+ if not owner_associated:
+ in_users.append( repository_owner )
+ message += "The repository owner must always be associated with the repository's administrator role. "
+ status = 'error'
+ in_groups_list = util.listify( kwd.get( 'in_groups', [] ) )
+ in_groups = [ trans.sa_session.query( trans.app.model.Group ).get( x ) for x in in_groups_list ]
+ in_repositories = [ repository ]
+ trans.app.security_agent.set_entity_role_associations( roles=[ role ],
+ users=in_users,
+ groups=in_groups,
+ repositories=in_repositories )
+ trans.sa_session.refresh( role )
+ message += "Role <b>%s</b> has been associated with %d users, %d groups and %d repositories. " % \
+ ( str( role.name ), len( in_users ), len( in_groups ), len( in_repositories ) )
+ in_users = []
+ out_users = []
+ in_groups = []
+ out_groups = []
+ for user in trans.sa_session.query( trans.app.model.User ) \
+ .filter( trans.app.model.User.table.c.deleted==False ) \
+ .order_by( trans.app.model.User.table.c.email ):
+ if user in [ x.user for x in role.users ]:
+ in_users.append( ( user.id, user.email ) )
+ else:
+ out_users.append( ( user.id, user.email ) )
+ for group in trans.sa_session.query( trans.app.model.Group ) \
+ .filter( trans.app.model.Group.table.c.deleted==False ) \
+ .order_by( trans.app.model.Group.table.c.name ):
+ if group in [ x.group for x in role.groups ]:
+ in_groups.append( ( group.id, group.name ) )
+ else:
+ out_groups.append( ( group.id, group.name ) )
+ associations_dict = dict( in_users=in_users,
+ out_users=out_users,
+ in_groups=in_groups,
+ out_groups=out_groups,
+ message=message,
+ status=status )
+ return associations_dict
+
def validate_repository_name( app, name, user ):
# Repository names must be unique for each user, must be at least four characters
# in length and must contain only lower-case letters, numbers, and the '_' character.
diff -r e2eb861e6c0b0cbaf8a1a1e091d3792724495b69 -r 9414cc43797afb77190abcbda0fdf173a6a100f3 templates/webapps/tool_shed/common/repository_actions_menu.mako
--- a/templates/webapps/tool_shed/common/repository_actions_menu.mako
+++ b/templates/webapps/tool_shed/common/repository_actions_menu.mako
@@ -12,6 +12,11 @@
is_admin = trans.user_is_admin()
+ if is_admin or trans.app.security_agent.user_can_administer_repository( trans.user, repository ):
+ can_administer = True
+ else:
+ can_administer = False
+
if repository.deprecated:
is_deprecated = True
else:
@@ -54,7 +59,7 @@
else:
can_download = False
- if ( is_admin or can_push ) and not repository.deleted and not repository.deprecated and not is_new:
+ if ( can_administer or can_push ) and not repository.deleted and not repository.deprecated and not is_new:
can_reset_all_metadata = True
else:
can_reset_all_metadata = False
@@ -109,11 +114,6 @@
else:
can_undeprecate = False
- if is_admin or repository.user == trans.user:
- can_manage = True
- else:
- can_manage = False
-
can_view_change_log = not is_new
if can_push:
@@ -147,7 +147,7 @@
%if can_upload:
<a class="action-button" target="galaxy_main" href="${h.url_for( controller='upload', action='upload', repository_id=trans.security.encode_id( repository.id ) )}">Upload files to repository</a>
%endif
- %if can_manage:
+ %if can_administer:
<a class="action-button" target="galaxy_main" href="${h.url_for( controller='repository', action='manage_repository', id=trans.app.security.encode_id( repository.id ), changeset_revision=repository.tip( trans.app ) )}">Manage repository</a>
%else:
<a class="action-button" target="galaxy_main" href="${h.url_for( controller='repository', action='view_repository', id=trans.app.security.encode_id( repository.id ), changeset_revision=repository.tip( trans.app ) )}">View repository</a>
@@ -173,6 +173,9 @@
%if can_undeprecate:
<a class="action-button" target="galaxy_main" href="${h.url_for( controller='repository', action='deprecate', id=trans.security.encode_id( repository.id ), mark_deprecated=False )}">Mark repository as not deprecated</a>
%endif
+ %if can_administer:
+ <a class="action-button" target="galaxy_main" href="${h.url_for( controller='repository', action='manage_repository_admins', id=trans.security.encode_id( repository.id ) )}">Manage repository administrators</a>
+ %endif
%if can_download:
%if changeset_revision is not None:
<a class="action-button" href="${h.url_for( controller='repository', action='export', repository_id=trans.app.security.encode_id( repository.id ), changeset_revision=changeset_revision )}">Export this revision</a>
diff -r e2eb861e6c0b0cbaf8a1a1e091d3792724495b69 -r 9414cc43797afb77190abcbda0fdf173a6a100f3 templates/webapps/tool_shed/index.mako
--- a/templates/webapps/tool_shed/index.mako
+++ b/templates/webapps/tool_shed/index.mako
@@ -97,7 +97,7 @@
<a target="galaxy_main" href="${h.url_for( controller='repository', action='browse_categories' )}">Browse by category</a></div>
%if trans.user:
- %if trans.user.active_repositories:
+ %if trans.user.active_repositories or can_administer_repositories:
<div class="toolSectionPad"></div><div class="toolSectionTitle">
Repositories I Can Change
@@ -105,6 +105,11 @@
<div class="toolTitle"><a target="galaxy_main" href="${h.url_for( controller='repository', action='browse_repositories_i_own' )}">Repositories I own</a></div>
+ %if can_administer_repositories:
+ <div class="toolTitle">
+ <a target="galaxy_main" href="${h.url_for( controller='repository', action='browse_repositories_i_can_administer' )}">Repositories I can administer</a>
+ </div>
+ %endif
%if has_reviewed_repositories:
<div class="toolTitle"><a target="galaxy_main" href="${h.url_for( controller='repository', action='browse_repositories', operation='reviewed_repositories_i_own' )}">Reviewed repositories I own</a>
diff -r e2eb861e6c0b0cbaf8a1a1e091d3792724495b69 -r 9414cc43797afb77190abcbda0fdf173a6a100f3 templates/webapps/tool_shed/role/role.mako
--- /dev/null
+++ b/templates/webapps/tool_shed/role/role.mako
@@ -0,0 +1,136 @@
+<%inherit file="/base.mako"/>
+<%namespace file="/message.mako" import="render_msg" />
+<%namespace file="/webapps/tool_shed/common/repository_actions_menu.mako" import="render_tool_shed_repository_actions" />
+
+<%def name="javascripts()">
+ ${parent.javascripts()}
+ <script type="text/javascript">
+ $(function(){
+ $("input:text:first").focus();
+ })
+ </script>
+</%def>
+
+<%def name="render_select( name, options )">
+ <select name="${name}" id="${name}" style="min-width: 250px; height: 150px;" multiple>
+ %for option in options:
+ <option value="${option[0]}">${option[1]}</option>
+ %endfor
+ </select>
+</%def>
+
+<script type="text/javascript">
+$().ready(function() {
+ $('#repositories_add_button').click(function() {
+ return !$('#out_repositories option:selected').remove().appendTo('#in_repositories');
+ });
+ $('#repositories_remove_button').click(function() {
+ return !$('#in_repositories option:selected').remove().appendTo('#out_repositories');
+ });
+ $('#users_add_button').click(function() {
+ return !$('#out_users option:selected').remove().appendTo('#in_users');
+ });
+ $('#users_remove_button').click(function() {
+ return !$('#in_users option:selected').remove().appendTo('#out_users');
+ });
+ $('#groups_add_button').click(function() {
+ return !$('#out_groups option:selected').remove().appendTo('#in_groups');
+ });
+ $('#groups_remove_button').click(function() {
+ return !$('#in_groups option:selected').remove().appendTo('#out_groups');
+ });
+ $('form#manage_role_associations').submit(function() {
+ $('#in_repositories option').each(function(i) {
+ $(this).attr("selected", "selected");
+ });
+ $('#in_users option').each(function(i) {
+ $(this).attr("selected", "selected");
+ });
+ $('#in_groups option').each(function(i) {
+ $(this).attr("selected", "selected");
+ });
+ });
+});
+</script>
+
+<%
+ if trans.user_is_admin() and in_admin_controller:
+ render_for_admin = True
+ else:
+ render_for_admin = False
+%>
+
+%if not render_for_admin:
+ ${render_tool_shed_repository_actions( repository, metadata=metadata, changeset_revision=changeset_revision )}
+%endif
+
+%if message:
+ ${render_msg( message, status )}
+%endif
+
+<div class="warningmessage">
+ <b>${role.name}</b> is the administrator role for the repository <b>${repository.name}</b> owned by
+ <b>${repository.user.username}</b>. ${role.description}
+</div>
+
+<div class="toolForm">
+ <div class="toolFormTitle">Manage users and groups associated with role <b>${role.name}</b></div>
+ <div class="toolFormBody">
+ % if not render_for_admin:
+ <div class="form-row">
+ <label>Repository name:</label>
+ ${repository.name}
+ <div style="clear: both"></div>
+ </div>
+ <div class="form-row">
+ <label>Repository owner:</label>
+ ${repository.user.username}
+ <div style="clear: both"></div>
+ </div>
+ %endif
+ <%
+ if render_for_admin:
+ controller_module = 'admin'
+ controller_method = 'manage_role_associations'
+ id_param = trans.security.encode_id( role.id )
+ else:
+ controller_module = 'repository'
+ controller_method = 'manage_repository_admins'
+ id_param = trans.security.encode_id( repository.id )
+ %>
+ <form name="manage_role_associations" id="manage_role_associations" action="${h.url_for( controller=controller_module, action=controller_method, id=id_param )}" method="post" >
+ <div class="form-row">
+ <div style="float: left; margin-right: 10px;">
+ <label>Users associated with '${role.name}'</label>
+ ${render_select( "in_users", in_users )}<br/>
+ <input type="submit" id="users_remove_button" value=">>"/>
+ <div style="clear: both"></div>
+ </div>
+ <div>
+ <label>Users not associated with '${role.name}'</label>
+ ${render_select( "out_users", out_users )}<br/>
+ <input type="submit" id="users_add_button" value="<<"/>
+ <div style="clear: both"></div>
+ </div>
+ </div>
+ <div class="form-row">
+ <div style="float: left; margin-right: 10px;">
+ <label>Groups associated with '${role.name}'</label>
+ ${render_select( "in_groups", in_groups )}<br/>
+ <input type="submit" id="groups_remove_button" value=">>"/>
+ <div style="clear: both"></div>
+ </div>
+ <div>
+ <label>Groups not associated with '${role.name}'</label>
+ ${render_select( "out_groups", out_groups )}<br/>
+ <input type="submit" id="groups_add_button" value="<<"/>
+ <div style="clear: both"></div>
+ </div>
+ </div>
+ <div style="clear: both"></div>
+ <div class="form-row">
+ <input type="submit" name="manage_role_associations_button" value="Save"/>
+ </div>
+ </form>
+ </div>
+</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
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/e2eb861e6c0b/
Changeset: e2eb861e6c0b
User: guerler
Date: 2014-01-24 18:19:57
Summary: Packscripts
Affected #: 2 files
diff -r 96d7f3af0b618c195ba4a00e47be26102e59a368 -r e2eb861e6c0b0cbaf8a1a1e091d3792724495b69 static/scripts/galaxy.base.js
--- a/static/scripts/galaxy.base.js
+++ b/static/scripts/galaxy.base.js
@@ -185,7 +185,6 @@
link.click();
}
}
- //return false;
}
};
}
diff -r 96d7f3af0b618c195ba4a00e47be26102e59a368 -r e2eb861e6c0b0cbaf8a1a1e091d3792724495b69 static/scripts/packed/galaxy.base.js
--- a/static/scripts/packed/galaxy.base.js
+++ b/static/scripts/packed/galaxy.base.js
@@ -1,1 +1,1 @@
-(function(){var b=0;var c=["ms","moz","webkit","o"];for(var a=0;a<c.length&&!window.requestAnimationFrame;++a){window.requestAnimationFrame=window[c[a]+"RequestAnimationFrame"];window.cancelRequestAnimationFrame=window[c[a]+"CancelRequestAnimationFrame"]}if(!window.requestAnimationFrame){window.requestAnimationFrame=function(h,e){var d=new Date().getTime();var f=Math.max(0,16-(d-b));var g=window.setTimeout(function(){h(d+f)},f);b=d+f;return g}}if(!window.cancelAnimationFrame){window.cancelAnimationFrame=function(d){clearTimeout(d)}}}());if(!Array.indexOf){Array.prototype.indexOf=function(c){for(var b=0,a=this.length;b<a;b++){if(this[b]==c){return b}}return -1}}function obj_length(c){if(c.length!==undefined){return c.length}var b=0;for(var a in c){b++}return b}$.fn.makeAbsolute=function(a){return this.each(function(){var b=$(this);var c=b.position();b.css({position:"absolute",marginLeft:0,marginTop:0,top:c.top,left:c.left,right:$(window).width()-(c.left+b.width())});if(a){b.remove().appendTo("body")}})};function make_popupmenu(b,c){var a=(b.data("menu_options"));b.data("menu_options",c);if(a){return}b.bind("click.show_popup",function(d){$(".popmenu-wrapper").remove();setTimeout(function(){var g=$("<ul class='dropdown-menu' id='"+b.attr("id")+"-menu'></ul>");var f=b.data("menu_options");if(obj_length(f)<=0){$("<li>No Options.</li>").appendTo(g)}$.each(f,function(j,i){if(i){var l=i.action||i;g.append($("<li></li>").append($("<a>").attr("href",i.url).html(j).click(l)))}else{g.append($("<li></li>").addClass("head").append($("<a href='#'></a>").html(j)))}});var h=$("<div class='popmenu-wrapper' style='position: absolute;left: 0; top: -1000;'></div>").append(g).appendTo("body");var e=d.pageX-h.width()/2;e=Math.min(e,$(document).scrollLeft()+$(window).width()-$(h).width()-5);e=Math.max(e,$(document).scrollLeft()+5);h.css({top:d.pageY,left:e})},10);setTimeout(function(){var f=function(h){$(h).bind("click.close_popup",function(){$(".popmenu-wrapper").remove();h.unbind("click.close_popup")})};f($(window.document));f($(window.top.document));for(var e=window.top.frames.length;e--;){var g=$(window.top.frames[e].document);f(g)}},50);return false})}function make_popup_menus(a){a=a||document;$(a).find("div[popupmenu]").each(function(){var b={};var d=$(this);d.find("a").each(function(){var g=$(this),i=g.get(0),e=i.getAttribute("confirm"),f=i.getAttribute("href"),h=i.getAttribute("target");if(!f){b[g.text()]=null}else{b[g.text()]={url:f,action:function(){if(!e||confirm(e)){if(h){window.open(f,h)}else{g.click()}}return false}}}});var c=$(a).find("#"+d.attr("popupmenu"));c.find("a").bind("click",function(f){f.stopPropagation();return true});make_popupmenu(c,b);c.addClass("popup");d.remove()})}function naturalSort(j,h){var p=/(-?[0-9\.]+)/g,k=j.toString().toLowerCase()||"",g=h.toString().toLowerCase()||"",l=String.fromCharCode(0),n=k.replace(p,l+"$1"+l).split(l),e=g.replace(p,l+"$1"+l).split(l),d=(new Date(k)).getTime(),o=d?(new Date(g)).getTime():null;if(o){if(d<o){return -1}else{if(d>o){return 1}}}var m,f;for(var i=0,c=Math.max(n.length,e.length);i<c;i++){m=parseFloat(n[i])||n[i];f=parseFloat(e[i])||e[i];if(m<f){return -1}else{if(m>f){return 1}}}return 0}$.fn.refresh_select2=function(){var b=$(this);var a={width:"resolve",closeOnSelect:!b.is("[MULTIPLE]")};return b.select2(a)};function replace_big_select_inputs(a,c,b){if(!jQuery.fn.select2){return}if(a===undefined){a=20}if(c===undefined){c=3000}b=b||$("select");b.each(function(){var e=$(this);var d=e.find("option").length;if((d<a)||(d>c)){return}if(e.hasClass("no-autocomplete")){return}e.refresh_select2()})}$.fn.make_text_editable=function(g){var d=("num_cols" in g?g.num_cols:30),c=("num_rows" in g?g.num_rows:4),e=("use_textarea" in g?g.use_textarea:false),b=("on_finish" in g?g.on_finish:null),f=("help_text" in g?g.help_text:null);var a=$(this);a.addClass("editable-text").click(function(l){if($(this).children(":input").length>0){return}a.removeClass("editable-text");var i=function(m){a.find(":input").remove();if(m!==""){a.text(m)}else{a.html("<br>")}a.addClass("editable-text");if(b){b(m)}};var h=("cur_text" in g?g.cur_text:a.text()),k,j;if(e){k=$("<textarea/>").attr({rows:c,cols:d}).text($.trim(h)).keyup(function(m){if(m.keyCode===27){i(h)}});j=$("<button/>").text("Done").click(function(){i(k.val());return false})}else{k=$("<input type='text'/>").attr({value:$.trim(h),size:d}).blur(function(){i(h)}).keyup(function(m){if(m.keyCode===27){$(this).trigger("blur")}else{if(m.keyCode===13){i($(this).val())}}})}a.text("");a.append(k);if(j){a.append(j)}k.focus();k.select();l.stopPropagation()});if(f){a.attr("title",f).tooltip()}return a};function async_save_text(d,f,e,a,c,h,i,g,b){if(c===undefined){c=30}if(i===undefined){i=4}$("#"+d).click(function(){if($("#renaming-active").length>0){return}var l=$("#"+f),k=l.text(),j;if(h){j=$("<textarea></textarea>").attr({rows:i,cols:c}).text($.trim(k))}else{j=$("<input type='text'></input>").attr({value:$.trim(k),size:c})}j.attr("id","renaming-active");j.blur(function(){$(this).remove();l.show();if(b){b(j)}});j.keyup(function(n){if(n.keyCode===27){$(this).trigger("blur")}else{if(n.keyCode===13){var m={};m[a]=$(this).val();$(this).trigger("blur");$.ajax({url:e,data:m,error:function(){alert("Text editing for elt "+f+" failed")},success:function(o){if(o!==""){l.text(o)}else{l.html("<em>None</em>")}if(b){b(j)}}})}}});if(g){g(j)}l.hide();j.insertAfter(l);j.focus();j.select();return})}function init_history_items(d,a,c){var b=function(){try{var e=$.jStorage.get("history_expand_state");if(e){for(var g in e){$("#"+g+" div.historyItemBody").show()}}}catch(f){$.jStorage.deleteKey("history_expand_state")}if($.browser.mozilla){$("div.historyItemBody").each(function(){if(!$(this).is(":visible")){$(this).find("pre.peek").css("overflow","hidden")}})}d.each(function(){var j=this.id,h=$(this).children("div.historyItemBody"),i=h.find("pre.peek");$(this).find(".historyItemTitleBar > .historyItemTitle").wrap("<a href='javascript:void(0);'></a>").click(function(){var k;if(h.is(":visible")){if($.browser.mozilla){i.css("overflow","hidden")}h.slideUp("fast");if(!c){k=$.jStorage.get("history_expand_state");if(k){delete k[j];$.jStorage.set("history_expand_state",k)}}}else{h.slideDown("fast",function(){if($.browser.mozilla){i.css("overflow","auto")}});if(!c){k=$.jStorage.get("history_expand_state");if(!k){k={}}k[j]=true;$.jStorage.set("history_expand_state",k)}}return false})});$("#top-links > a.toggle").click(function(){var h=$.jStorage.get("history_expand_state");if(!h){h={}}$("div.historyItemBody:visible").each(function(){if($.browser.mozilla){$(this).find("pre.peek").css("overflow","hidden")}$(this).slideUp("fast");if(h){delete h[$(this).parent().attr("id")]}});$.jStorage.set("history_expand_state",h)}).show()};b()}function commatize(b){b+="";var a=/(\d+)(\d{3})/;while(a.test(b)){b=b.replace(a,"$1,$2")}return b}function reset_tool_search(a){var c=$("#galaxy_tools").contents();if(c.length===0){c=$(document)}$(this).removeClass("search_active");c.find(".toolTitle").removeClass("search_match");c.find(".toolSectionBody").hide();c.find(".toolTitle").show();c.find(".toolPanelLabel").show();c.find(".toolSectionWrapper").each(function(){if($(this).attr("id")!=="recently_used_wrapper"){$(this).show()}else{if($(this).hasClass("user_pref_visible")){$(this).show()}}});c.find("#search-no-results").hide();c.find("#search-spinner").hide();if(a){var b=c.find("#tool-search-query");b.val("search tools")}}var GalaxyAsync=function(a){this.url_dict={};this.log_action=(a===undefined?false:a)};GalaxyAsync.prototype.set_func_url=function(a,b){this.url_dict[a]=b};GalaxyAsync.prototype.set_user_pref=function(a,b){var c=this.url_dict[arguments.callee];if(c===undefined){return false}$.ajax({url:c,data:{pref_name:a,pref_value:b},error:function(){return false},success:function(){return true}})};GalaxyAsync.prototype.log_user_action=function(c,b,d){if(!this.log_action){return}var a=this.url_dict[arguments.callee];if(a===undefined){return false}$.ajax({url:a,data:{action:c,context:b,params:d},error:function(){return false},success:function(){return true}})};function init_refresh_on_change(){$("select[refresh_on_change='true']").off("change").change(function(){var a=$(this),e=a.val(),d=false,c=a.attr("refresh_on_change_values");if(c){c=c.split(",");var b=a.attr("last_selected_value");if($.inArray(e,c)===-1&&$.inArray(b,c)===-1){return}}$(window).trigger("refresh_on_change");$(document).trigger("convert_to_values");a.get(0).form.submit()});$(":checkbox[refresh_on_change='true']").off("click").click(function(){var a=$(this),e=a.val(),d=false,c=a.attr("refresh_on_change_values");if(c){c=c.split(",");var b=a.attr("last_selected_value");if($.inArray(e,c)===-1&&$.inArray(b,c)===-1){return}}$(window).trigger("refresh_on_change");a.get(0).form.submit()});$("a[confirm]").off("click").click(function(){return confirm($(this).attr("confirm"))})}$(document).ready(function(){init_refresh_on_change();if($.fn.tooltip){$(".unified-panel-header [title]").tooltip({placement:"bottom"});$("[title]").tooltip({placement:"top"})}make_popup_menus();replace_big_select_inputs(20,1500);$("a").click(function(){var b=$(this);var c=(parent.frames&&parent.frames.galaxy_main);if((b.attr("target")=="galaxy_main")&&(!c)){var a=b.attr("href");if(a.indexOf("?")==-1){a+="?"}else{a+="&"}a+="use_panels=True";b.attr("href",a);b.attr("target","_self")}return b})});
\ No newline at end of file
+(function(){var b=0;var c=["ms","moz","webkit","o"];for(var a=0;a<c.length&&!window.requestAnimationFrame;++a){window.requestAnimationFrame=window[c[a]+"RequestAnimationFrame"];window.cancelRequestAnimationFrame=window[c[a]+"CancelRequestAnimationFrame"]}if(!window.requestAnimationFrame){window.requestAnimationFrame=function(h,e){var d=new Date().getTime();var f=Math.max(0,16-(d-b));var g=window.setTimeout(function(){h(d+f)},f);b=d+f;return g}}if(!window.cancelAnimationFrame){window.cancelAnimationFrame=function(d){clearTimeout(d)}}}());if(!Array.indexOf){Array.prototype.indexOf=function(c){for(var b=0,a=this.length;b<a;b++){if(this[b]==c){return b}}return -1}}function obj_length(c){if(c.length!==undefined){return c.length}var b=0;for(var a in c){b++}return b}$.fn.makeAbsolute=function(a){return this.each(function(){var b=$(this);var c=b.position();b.css({position:"absolute",marginLeft:0,marginTop:0,top:c.top,left:c.left,right:$(window).width()-(c.left+b.width())});if(a){b.remove().appendTo("body")}})};function make_popupmenu(b,c){var a=(b.data("menu_options"));b.data("menu_options",c);if(a){return}b.bind("click.show_popup",function(d){$(".popmenu-wrapper").remove();setTimeout(function(){var g=$("<ul class='dropdown-menu' id='"+b.attr("id")+"-menu'></ul>");var f=b.data("menu_options");if(obj_length(f)<=0){$("<li>No Options.</li>").appendTo(g)}$.each(f,function(j,i){if(i){var l=i.action||i;g.append($("<li></li>").append($("<a>").attr("href",i.url).html(j).click(l)))}else{g.append($("<li></li>").addClass("head").append($("<a href='#'></a>").html(j)))}});var h=$("<div class='popmenu-wrapper' style='position: absolute;left: 0; top: -1000;'></div>").append(g).appendTo("body");var e=d.pageX-h.width()/2;e=Math.min(e,$(document).scrollLeft()+$(window).width()-$(h).width()-5);e=Math.max(e,$(document).scrollLeft()+5);h.css({top:d.pageY,left:e})},10);setTimeout(function(){var f=function(h){$(h).bind("click.close_popup",function(){$(".popmenu-wrapper").remove();h.unbind("click.close_popup")})};f($(window.document));f($(window.top.document));for(var e=window.top.frames.length;e--;){var g=$(window.top.frames[e].document);f(g)}},50);return false})}function make_popup_menus(a){a=a||document;$(a).find("div[popupmenu]").each(function(){var b={};var d=$(this);d.find("a").each(function(){var g=$(this),i=g.get(0),e=i.getAttribute("confirm"),f=i.getAttribute("href"),h=i.getAttribute("target");if(!f){b[g.text()]=null}else{b[g.text()]={url:f,action:function(){if(!e||confirm(e)){if(h){window.open(f,h)}else{g.click()}}}}}});var c=$(a).find("#"+d.attr("popupmenu"));c.find("a").bind("click",function(f){f.stopPropagation();return true});make_popupmenu(c,b);c.addClass("popup");d.remove()})}function naturalSort(j,h){var p=/(-?[0-9\.]+)/g,k=j.toString().toLowerCase()||"",g=h.toString().toLowerCase()||"",l=String.fromCharCode(0),n=k.replace(p,l+"$1"+l).split(l),e=g.replace(p,l+"$1"+l).split(l),d=(new Date(k)).getTime(),o=d?(new Date(g)).getTime():null;if(o){if(d<o){return -1}else{if(d>o){return 1}}}var m,f;for(var i=0,c=Math.max(n.length,e.length);i<c;i++){m=parseFloat(n[i])||n[i];f=parseFloat(e[i])||e[i];if(m<f){return -1}else{if(m>f){return 1}}}return 0}$.fn.refresh_select2=function(){var b=$(this);var a={width:"resolve",closeOnSelect:!b.is("[MULTIPLE]")};return b.select2(a)};function replace_big_select_inputs(a,c,b){if(!jQuery.fn.select2){return}if(a===undefined){a=20}if(c===undefined){c=3000}b=b||$("select");b.each(function(){var e=$(this);var d=e.find("option").length;if((d<a)||(d>c)){return}if(e.hasClass("no-autocomplete")){return}e.refresh_select2()})}$.fn.make_text_editable=function(g){var d=("num_cols" in g?g.num_cols:30),c=("num_rows" in g?g.num_rows:4),e=("use_textarea" in g?g.use_textarea:false),b=("on_finish" in g?g.on_finish:null),f=("help_text" in g?g.help_text:null);var a=$(this);a.addClass("editable-text").click(function(l){if($(this).children(":input").length>0){return}a.removeClass("editable-text");var i=function(m){a.find(":input").remove();if(m!==""){a.text(m)}else{a.html("<br>")}a.addClass("editable-text");if(b){b(m)}};var h=("cur_text" in g?g.cur_text:a.text()),k,j;if(e){k=$("<textarea/>").attr({rows:c,cols:d}).text($.trim(h)).keyup(function(m){if(m.keyCode===27){i(h)}});j=$("<button/>").text("Done").click(function(){i(k.val());return false})}else{k=$("<input type='text'/>").attr({value:$.trim(h),size:d}).blur(function(){i(h)}).keyup(function(m){if(m.keyCode===27){$(this).trigger("blur")}else{if(m.keyCode===13){i($(this).val())}}})}a.text("");a.append(k);if(j){a.append(j)}k.focus();k.select();l.stopPropagation()});if(f){a.attr("title",f).tooltip()}return a};function async_save_text(d,f,e,a,c,h,i,g,b){if(c===undefined){c=30}if(i===undefined){i=4}$("#"+d).click(function(){if($("#renaming-active").length>0){return}var l=$("#"+f),k=l.text(),j;if(h){j=$("<textarea></textarea>").attr({rows:i,cols:c}).text($.trim(k))}else{j=$("<input type='text'></input>").attr({value:$.trim(k),size:c})}j.attr("id","renaming-active");j.blur(function(){$(this).remove();l.show();if(b){b(j)}});j.keyup(function(n){if(n.keyCode===27){$(this).trigger("blur")}else{if(n.keyCode===13){var m={};m[a]=$(this).val();$(this).trigger("blur");$.ajax({url:e,data:m,error:function(){alert("Text editing for elt "+f+" failed")},success:function(o){if(o!==""){l.text(o)}else{l.html("<em>None</em>")}if(b){b(j)}}})}}});if(g){g(j)}l.hide();j.insertAfter(l);j.focus();j.select();return})}function init_history_items(d,a,c){var b=function(){try{var e=$.jStorage.get("history_expand_state");if(e){for(var g in e){$("#"+g+" div.historyItemBody").show()}}}catch(f){$.jStorage.deleteKey("history_expand_state")}if($.browser.mozilla){$("div.historyItemBody").each(function(){if(!$(this).is(":visible")){$(this).find("pre.peek").css("overflow","hidden")}})}d.each(function(){var j=this.id,h=$(this).children("div.historyItemBody"),i=h.find("pre.peek");$(this).find(".historyItemTitleBar > .historyItemTitle").wrap("<a href='javascript:void(0);'></a>").click(function(){var k;if(h.is(":visible")){if($.browser.mozilla){i.css("overflow","hidden")}h.slideUp("fast");if(!c){k=$.jStorage.get("history_expand_state");if(k){delete k[j];$.jStorage.set("history_expand_state",k)}}}else{h.slideDown("fast",function(){if($.browser.mozilla){i.css("overflow","auto")}});if(!c){k=$.jStorage.get("history_expand_state");if(!k){k={}}k[j]=true;$.jStorage.set("history_expand_state",k)}}return false})});$("#top-links > a.toggle").click(function(){var h=$.jStorage.get("history_expand_state");if(!h){h={}}$("div.historyItemBody:visible").each(function(){if($.browser.mozilla){$(this).find("pre.peek").css("overflow","hidden")}$(this).slideUp("fast");if(h){delete h[$(this).parent().attr("id")]}});$.jStorage.set("history_expand_state",h)}).show()};b()}function commatize(b){b+="";var a=/(\d+)(\d{3})/;while(a.test(b)){b=b.replace(a,"$1,$2")}return b}function reset_tool_search(a){var c=$("#galaxy_tools").contents();if(c.length===0){c=$(document)}$(this).removeClass("search_active");c.find(".toolTitle").removeClass("search_match");c.find(".toolSectionBody").hide();c.find(".toolTitle").show();c.find(".toolPanelLabel").show();c.find(".toolSectionWrapper").each(function(){if($(this).attr("id")!=="recently_used_wrapper"){$(this).show()}else{if($(this).hasClass("user_pref_visible")){$(this).show()}}});c.find("#search-no-results").hide();c.find("#search-spinner").hide();if(a){var b=c.find("#tool-search-query");b.val("search tools")}}var GalaxyAsync=function(a){this.url_dict={};this.log_action=(a===undefined?false:a)};GalaxyAsync.prototype.set_func_url=function(a,b){this.url_dict[a]=b};GalaxyAsync.prototype.set_user_pref=function(a,b){var c=this.url_dict[arguments.callee];if(c===undefined){return false}$.ajax({url:c,data:{pref_name:a,pref_value:b},error:function(){return false},success:function(){return true}})};GalaxyAsync.prototype.log_user_action=function(c,b,d){if(!this.log_action){return}var a=this.url_dict[arguments.callee];if(a===undefined){return false}$.ajax({url:a,data:{action:c,context:b,params:d},error:function(){return false},success:function(){return true}})};function init_refresh_on_change(){$("select[refresh_on_change='true']").off("change").change(function(){var a=$(this),e=a.val(),d=false,c=a.attr("refresh_on_change_values");if(c){c=c.split(",");var b=a.attr("last_selected_value");if($.inArray(e,c)===-1&&$.inArray(b,c)===-1){return}}$(window).trigger("refresh_on_change");$(document).trigger("convert_to_values");a.get(0).form.submit()});$(":checkbox[refresh_on_change='true']").off("click").click(function(){var a=$(this),e=a.val(),d=false,c=a.attr("refresh_on_change_values");if(c){c=c.split(",");var b=a.attr("last_selected_value");if($.inArray(e,c)===-1&&$.inArray(b,c)===-1){return}}$(window).trigger("refresh_on_change");a.get(0).form.submit()});$("a[confirm]").off("click").click(function(){return confirm($(this).attr("confirm"))})}$(document).ready(function(){init_refresh_on_change();if($.fn.tooltip){$(".unified-panel-header [title]").tooltip({placement:"bottom"});$("[title]").tooltip({placement:"top"})}make_popup_menus();replace_big_select_inputs(20,1500);$("a").click(function(){var b=$(this);var c=(parent.frames&&parent.frames.galaxy_main);if((b.attr("target")=="galaxy_main")&&(!c)){var a=b.attr("href");if(a.indexOf("?")==-1){a+="?"}else{a+="&"}a+="use_panels=True";b.attr("href",a);b.attr("target","_self")}return b})});
\ No newline at end of file
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: guerler: Undo fix for popup menus
by commits-noreply@bitbucket.org 24 Jan '14
by commits-noreply@bitbucket.org 24 Jan '14
24 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/96d7f3af0b61/
Changeset: 96d7f3af0b61
User: guerler
Date: 2014-01-24 18:07:44
Summary: Undo fix for popup menus
Affected #: 1 file
diff -r ef31ebe84aaef0998f2c2d828c8b10352d33de85 -r 96d7f3af0b618c195ba4a00e47be26102e59a368 static/scripts/galaxy.base.js
--- a/static/scripts/galaxy.base.js
+++ b/static/scripts/galaxy.base.js
@@ -185,7 +185,7 @@
link.click();
}
}
- return false;
+ //return false;
}
};
}
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: dan: Fix for automatic population of history name when running a workflow and sending results to a new history.
by commits-noreply@bitbucket.org 24 Jan '14
by commits-noreply@bitbucket.org 24 Jan '14
24 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/ef31ebe84aae/
Changeset: ef31ebe84aae
User: dan
Date: 2014-01-24 18:05:11
Summary: Fix for automatic population of history name when running a workflow and sending results to a new history.
Affected #: 1 file
diff -r 5b85de149657c2d9bbb3163db6ced3bb23fbfbc0 -r ef31ebe84aaef0998f2c2d828c8b10352d33de85 templates/webapps/galaxy/workflow/run.mako
--- a/templates/webapps/galaxy/workflow/run.mako
+++ b/templates/webapps/galaxy/workflow/run.mako
@@ -603,7 +603,7 @@
%if history_id is None:
<p id='new_history_p'><input type="checkbox" name='new_history' value="true" id='new_history_cbx'/><label for='new_history_cbx'>Send results to a new history </label>
- <span id="new_history_input">named: <input type='text' name='new_history_name' value='${h.to_unicode( workflow.name )}'/></span>
+ <span id="new_history_input">named: <input type='text' name='new_history_name' value='${ h.to_unicode( workflow.name ) | h }'/></span></p>
%endif
<input type="submit" class="btn btn-primary" name="run_workflow" value="Run workflow" />
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
24 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/5b85de149657/
Changeset: 5b85de149657
User: guerler
Date: 2014-01-24 18:01:30
Summary: Fix for popup menus
Affected #: 3 files
diff -r 210a768c98bc394eeabd231aac1056733bec9b11 -r 5b85de149657c2d9bbb3163db6ced3bb23fbfbc0 static/scripts/galaxy.base.js
--- a/static/scripts/galaxy.base.js
+++ b/static/scripts/galaxy.base.js
@@ -185,6 +185,7 @@
link.click();
}
}
+ return false;
}
};
}
@@ -625,44 +626,50 @@
// Initialize refresh events.
function init_refresh_on_change () {
- $("select[refresh_on_change='true']").change( function() {
- var select_field = $(this),
- select_val = select_field.val(),
- refresh = false,
- ref_on_change_vals = select_field.attr("refresh_on_change_values");
- if (ref_on_change_vals) {
- ref_on_change_vals = ref_on_change_vals.split(',');
- var last_selected_value = select_field.attr("last_selected_value");
- if ($.inArray(select_val, ref_on_change_vals) === -1 && $.inArray(last_selected_value, ref_on_change_vals) === -1) {
- return;
+ $("select[refresh_on_change='true']")
+ .off('change')
+ .change(function() {
+ var select_field = $(this),
+ select_val = select_field.val(),
+ refresh = false,
+ ref_on_change_vals = select_field.attr("refresh_on_change_values");
+ if (ref_on_change_vals) {
+ ref_on_change_vals = ref_on_change_vals.split(',');
+ var last_selected_value = select_field.attr("last_selected_value");
+ if ($.inArray(select_val, ref_on_change_vals) === -1 && $.inArray(last_selected_value, ref_on_change_vals) === -1) {
+ return;
+ }
}
- }
- $(window).trigger("refresh_on_change");
- $(document).trigger("convert_to_values"); // Convert autocomplete text to values
- select_field.get(0).form.submit();
- });
+ $(window).trigger("refresh_on_change");
+ $(document).trigger("convert_to_values"); // Convert autocomplete text to values
+ select_field.get(0).form.submit();
+ });
// checkboxes refresh on change
- $(":checkbox[refresh_on_change='true']").click( function() {
- var select_field = $(this),
- select_val = select_field.val(),
- refresh = false,
- ref_on_change_vals = select_field.attr("refresh_on_change_values");
- if (ref_on_change_vals) {
- ref_on_change_vals = ref_on_change_vals.split(',');
- var last_selected_value = select_field.attr("last_selected_value");
- if ($.inArray(select_val, ref_on_change_vals) === -1 && $.inArray(last_selected_value, ref_on_change_vals) === -1) {
- return;
+ $(":checkbox[refresh_on_change='true']")
+ .off('click')
+ .click( function() {
+ var select_field = $(this),
+ select_val = select_field.val(),
+ refresh = false,
+ ref_on_change_vals = select_field.attr("refresh_on_change_values");
+ if (ref_on_change_vals) {
+ ref_on_change_vals = ref_on_change_vals.split(',');
+ var last_selected_value = select_field.attr("last_selected_value");
+ if ($.inArray(select_val, ref_on_change_vals) === -1 && $.inArray(last_selected_value, ref_on_change_vals) === -1) {
+ return;
+ }
}
- }
- $(window).trigger("refresh_on_change");
- select_field.get(0).form.submit();
- });
+ $(window).trigger("refresh_on_change");
+ select_field.get(0).form.submit();
+ });
// Links with confirmation
- $( "a[confirm]" ).click( function() {
- return confirm( $(this).attr("confirm") );
- });
+ $( "a[confirm]" )
+ .off('click')
+ .click( function() {
+ return confirm( $(this).attr("confirm") );
+ });
};
$(document).ready( function() {
diff -r 210a768c98bc394eeabd231aac1056733bec9b11 -r 5b85de149657c2d9bbb3163db6ced3bb23fbfbc0 static/scripts/packed/galaxy.base.js
--- a/static/scripts/packed/galaxy.base.js
+++ b/static/scripts/packed/galaxy.base.js
@@ -1,1 +1,1 @@
-(function(){var b=0;var c=["ms","moz","webkit","o"];for(var a=0;a<c.length&&!window.requestAnimationFrame;++a){window.requestAnimationFrame=window[c[a]+"RequestAnimationFrame"];window.cancelRequestAnimationFrame=window[c[a]+"CancelRequestAnimationFrame"]}if(!window.requestAnimationFrame){window.requestAnimationFrame=function(h,e){var d=new Date().getTime();var f=Math.max(0,16-(d-b));var g=window.setTimeout(function(){h(d+f)},f);b=d+f;return g}}if(!window.cancelAnimationFrame){window.cancelAnimationFrame=function(d){clearTimeout(d)}}}());if(!Array.indexOf){Array.prototype.indexOf=function(c){for(var b=0,a=this.length;b<a;b++){if(this[b]==c){return b}}return -1}}function obj_length(c){if(c.length!==undefined){return c.length}var b=0;for(var a in c){b++}return b}$.fn.makeAbsolute=function(a){return this.each(function(){var b=$(this);var c=b.position();b.css({position:"absolute",marginLeft:0,marginTop:0,top:c.top,left:c.left,right:$(window).width()-(c.left+b.width())});if(a){b.remove().appendTo("body")}})};function make_popupmenu(b,c){var a=(b.data("menu_options"));b.data("menu_options",c);if(a){return}b.bind("click.show_popup",function(d){$(".popmenu-wrapper").remove();setTimeout(function(){var g=$("<ul class='dropdown-menu' id='"+b.attr("id")+"-menu'></ul>");var f=b.data("menu_options");if(obj_length(f)<=0){$("<li>No Options.</li>").appendTo(g)}$.each(f,function(j,i){if(i){var l=i.action||i;g.append($("<li></li>").append($("<a>").attr("href",i.url).html(j).click(l)))}else{g.append($("<li></li>").addClass("head").append($("<a href='#'></a>").html(j)))}});var h=$("<div class='popmenu-wrapper' style='position: absolute;left: 0; top: -1000;'></div>").append(g).appendTo("body");var e=d.pageX-h.width()/2;e=Math.min(e,$(document).scrollLeft()+$(window).width()-$(h).width()-5);e=Math.max(e,$(document).scrollLeft()+5);h.css({top:d.pageY,left:e})},10);setTimeout(function(){var f=function(h){$(h).bind("click.close_popup",function(){$(".popmenu-wrapper").remove();h.unbind("click.close_popup")})};f($(window.document));f($(window.top.document));for(var e=window.top.frames.length;e--;){var g=$(window.top.frames[e].document);f(g)}},50);return false})}function make_popup_menus(a){a=a||document;$(a).find("div[popupmenu]").each(function(){var b={};var d=$(this);d.find("a").each(function(){var g=$(this),i=g.get(0),e=i.getAttribute("confirm"),f=i.getAttribute("href"),h=i.getAttribute("target");if(!f){b[g.text()]=null}else{b[g.text()]={url:f,action:function(){if(!e||confirm(e)){if(h){window.open(f,h)}else{g.click()}}}}}});var c=$(a).find("#"+d.attr("popupmenu"));c.find("a").bind("click",function(f){f.stopPropagation();return true});make_popupmenu(c,b);c.addClass("popup");d.remove()})}function naturalSort(j,h){var p=/(-?[0-9\.]+)/g,k=j.toString().toLowerCase()||"",g=h.toString().toLowerCase()||"",l=String.fromCharCode(0),n=k.replace(p,l+"$1"+l).split(l),e=g.replace(p,l+"$1"+l).split(l),d=(new Date(k)).getTime(),o=d?(new Date(g)).getTime():null;if(o){if(d<o){return -1}else{if(d>o){return 1}}}var m,f;for(var i=0,c=Math.max(n.length,e.length);i<c;i++){m=parseFloat(n[i])||n[i];f=parseFloat(e[i])||e[i];if(m<f){return -1}else{if(m>f){return 1}}}return 0}$.fn.refresh_select2=function(){var b=$(this);var a={width:"resolve",closeOnSelect:!b.is("[MULTIPLE]")};return b.select2(a)};function replace_big_select_inputs(a,c,b){if(!jQuery.fn.select2){return}if(a===undefined){a=20}if(c===undefined){c=3000}b=b||$("select");b.each(function(){var e=$(this);var d=e.find("option").length;if((d<a)||(d>c)){return}if(e.hasClass("no-autocomplete")){return}e.refresh_select2()})}$.fn.make_text_editable=function(g){var d=("num_cols" in g?g.num_cols:30),c=("num_rows" in g?g.num_rows:4),e=("use_textarea" in g?g.use_textarea:false),b=("on_finish" in g?g.on_finish:null),f=("help_text" in g?g.help_text:null);var a=$(this);a.addClass("editable-text").click(function(l){if($(this).children(":input").length>0){return}a.removeClass("editable-text");var i=function(m){a.find(":input").remove();if(m!==""){a.text(m)}else{a.html("<br>")}a.addClass("editable-text");if(b){b(m)}};var h=("cur_text" in g?g.cur_text:a.text()),k,j;if(e){k=$("<textarea/>").attr({rows:c,cols:d}).text($.trim(h)).keyup(function(m){if(m.keyCode===27){i(h)}});j=$("<button/>").text("Done").click(function(){i(k.val());return false})}else{k=$("<input type='text'/>").attr({value:$.trim(h),size:d}).blur(function(){i(h)}).keyup(function(m){if(m.keyCode===27){$(this).trigger("blur")}else{if(m.keyCode===13){i($(this).val())}}})}a.text("");a.append(k);if(j){a.append(j)}k.focus();k.select();l.stopPropagation()});if(f){a.attr("title",f).tooltip()}return a};function async_save_text(d,f,e,a,c,h,i,g,b){if(c===undefined){c=30}if(i===undefined){i=4}$("#"+d).click(function(){if($("#renaming-active").length>0){return}var l=$("#"+f),k=l.text(),j;if(h){j=$("<textarea></textarea>").attr({rows:i,cols:c}).text($.trim(k))}else{j=$("<input type='text'></input>").attr({value:$.trim(k),size:c})}j.attr("id","renaming-active");j.blur(function(){$(this).remove();l.show();if(b){b(j)}});j.keyup(function(n){if(n.keyCode===27){$(this).trigger("blur")}else{if(n.keyCode===13){var m={};m[a]=$(this).val();$(this).trigger("blur");$.ajax({url:e,data:m,error:function(){alert("Text editing for elt "+f+" failed")},success:function(o){if(o!==""){l.text(o)}else{l.html("<em>None</em>")}if(b){b(j)}}})}}});if(g){g(j)}l.hide();j.insertAfter(l);j.focus();j.select();return})}function init_history_items(d,a,c){var b=function(){try{var e=$.jStorage.get("history_expand_state");if(e){for(var g in e){$("#"+g+" div.historyItemBody").show()}}}catch(f){$.jStorage.deleteKey("history_expand_state")}if($.browser.mozilla){$("div.historyItemBody").each(function(){if(!$(this).is(":visible")){$(this).find("pre.peek").css("overflow","hidden")}})}d.each(function(){var j=this.id,h=$(this).children("div.historyItemBody"),i=h.find("pre.peek");$(this).find(".historyItemTitleBar > .historyItemTitle").wrap("<a href='javascript:void(0);'></a>").click(function(){var k;if(h.is(":visible")){if($.browser.mozilla){i.css("overflow","hidden")}h.slideUp("fast");if(!c){k=$.jStorage.get("history_expand_state");if(k){delete k[j];$.jStorage.set("history_expand_state",k)}}}else{h.slideDown("fast",function(){if($.browser.mozilla){i.css("overflow","auto")}});if(!c){k=$.jStorage.get("history_expand_state");if(!k){k={}}k[j]=true;$.jStorage.set("history_expand_state",k)}}return false})});$("#top-links > a.toggle").click(function(){var h=$.jStorage.get("history_expand_state");if(!h){h={}}$("div.historyItemBody:visible").each(function(){if($.browser.mozilla){$(this).find("pre.peek").css("overflow","hidden")}$(this).slideUp("fast");if(h){delete h[$(this).parent().attr("id")]}});$.jStorage.set("history_expand_state",h)}).show()};b()}function commatize(b){b+="";var a=/(\d+)(\d{3})/;while(a.test(b)){b=b.replace(a,"$1,$2")}return b}function reset_tool_search(a){var c=$("#galaxy_tools").contents();if(c.length===0){c=$(document)}$(this).removeClass("search_active");c.find(".toolTitle").removeClass("search_match");c.find(".toolSectionBody").hide();c.find(".toolTitle").show();c.find(".toolPanelLabel").show();c.find(".toolSectionWrapper").each(function(){if($(this).attr("id")!=="recently_used_wrapper"){$(this).show()}else{if($(this).hasClass("user_pref_visible")){$(this).show()}}});c.find("#search-no-results").hide();c.find("#search-spinner").hide();if(a){var b=c.find("#tool-search-query");b.val("search tools")}}var GalaxyAsync=function(a){this.url_dict={};this.log_action=(a===undefined?false:a)};GalaxyAsync.prototype.set_func_url=function(a,b){this.url_dict[a]=b};GalaxyAsync.prototype.set_user_pref=function(a,b){var c=this.url_dict[arguments.callee];if(c===undefined){return false}$.ajax({url:c,data:{pref_name:a,pref_value:b},error:function(){return false},success:function(){return true}})};GalaxyAsync.prototype.log_user_action=function(c,b,d){if(!this.log_action){return}var a=this.url_dict[arguments.callee];if(a===undefined){return false}$.ajax({url:a,data:{action:c,context:b,params:d},error:function(){return false},success:function(){return true}})};function init_refresh_on_change(){$("select[refresh_on_change='true']").change(function(){var a=$(this),e=a.val(),d=false,c=a.attr("refresh_on_change_values");if(c){c=c.split(",");var b=a.attr("last_selected_value");if($.inArray(e,c)===-1&&$.inArray(b,c)===-1){return}}$(window).trigger("refresh_on_change");$(document).trigger("convert_to_values");a.get(0).form.submit()});$(":checkbox[refresh_on_change='true']").click(function(){var a=$(this),e=a.val(),d=false,c=a.attr("refresh_on_change_values");if(c){c=c.split(",");var b=a.attr("last_selected_value");if($.inArray(e,c)===-1&&$.inArray(b,c)===-1){return}}$(window).trigger("refresh_on_change");a.get(0).form.submit()});$("a[confirm]").click(function(){return confirm($(this).attr("confirm"))})}$(document).ready(function(){init_refresh_on_change();if($.fn.tooltip){$(".unified-panel-header [title]").tooltip({placement:"bottom"});$("[title]").tooltip({placement:"top"})}make_popup_menus();replace_big_select_inputs(20,1500);$("a").click(function(){var b=$(this);var c=(parent.frames&&parent.frames.galaxy_main);if((b.attr("target")=="galaxy_main")&&(!c)){var a=b.attr("href");if(a.indexOf("?")==-1){a+="?"}else{a+="&"}a+="use_panels=True";b.attr("href",a);b.attr("target","_self")}return b})});
\ No newline at end of file
+(function(){var b=0;var c=["ms","moz","webkit","o"];for(var a=0;a<c.length&&!window.requestAnimationFrame;++a){window.requestAnimationFrame=window[c[a]+"RequestAnimationFrame"];window.cancelRequestAnimationFrame=window[c[a]+"CancelRequestAnimationFrame"]}if(!window.requestAnimationFrame){window.requestAnimationFrame=function(h,e){var d=new Date().getTime();var f=Math.max(0,16-(d-b));var g=window.setTimeout(function(){h(d+f)},f);b=d+f;return g}}if(!window.cancelAnimationFrame){window.cancelAnimationFrame=function(d){clearTimeout(d)}}}());if(!Array.indexOf){Array.prototype.indexOf=function(c){for(var b=0,a=this.length;b<a;b++){if(this[b]==c){return b}}return -1}}function obj_length(c){if(c.length!==undefined){return c.length}var b=0;for(var a in c){b++}return b}$.fn.makeAbsolute=function(a){return this.each(function(){var b=$(this);var c=b.position();b.css({position:"absolute",marginLeft:0,marginTop:0,top:c.top,left:c.left,right:$(window).width()-(c.left+b.width())});if(a){b.remove().appendTo("body")}})};function make_popupmenu(b,c){var a=(b.data("menu_options"));b.data("menu_options",c);if(a){return}b.bind("click.show_popup",function(d){$(".popmenu-wrapper").remove();setTimeout(function(){var g=$("<ul class='dropdown-menu' id='"+b.attr("id")+"-menu'></ul>");var f=b.data("menu_options");if(obj_length(f)<=0){$("<li>No Options.</li>").appendTo(g)}$.each(f,function(j,i){if(i){var l=i.action||i;g.append($("<li></li>").append($("<a>").attr("href",i.url).html(j).click(l)))}else{g.append($("<li></li>").addClass("head").append($("<a href='#'></a>").html(j)))}});var h=$("<div class='popmenu-wrapper' style='position: absolute;left: 0; top: -1000;'></div>").append(g).appendTo("body");var e=d.pageX-h.width()/2;e=Math.min(e,$(document).scrollLeft()+$(window).width()-$(h).width()-5);e=Math.max(e,$(document).scrollLeft()+5);h.css({top:d.pageY,left:e})},10);setTimeout(function(){var f=function(h){$(h).bind("click.close_popup",function(){$(".popmenu-wrapper").remove();h.unbind("click.close_popup")})};f($(window.document));f($(window.top.document));for(var e=window.top.frames.length;e--;){var g=$(window.top.frames[e].document);f(g)}},50);return false})}function make_popup_menus(a){a=a||document;$(a).find("div[popupmenu]").each(function(){var b={};var d=$(this);d.find("a").each(function(){var g=$(this),i=g.get(0),e=i.getAttribute("confirm"),f=i.getAttribute("href"),h=i.getAttribute("target");if(!f){b[g.text()]=null}else{b[g.text()]={url:f,action:function(){if(!e||confirm(e)){if(h){window.open(f,h)}else{g.click()}}return false}}}});var c=$(a).find("#"+d.attr("popupmenu"));c.find("a").bind("click",function(f){f.stopPropagation();return true});make_popupmenu(c,b);c.addClass("popup");d.remove()})}function naturalSort(j,h){var p=/(-?[0-9\.]+)/g,k=j.toString().toLowerCase()||"",g=h.toString().toLowerCase()||"",l=String.fromCharCode(0),n=k.replace(p,l+"$1"+l).split(l),e=g.replace(p,l+"$1"+l).split(l),d=(new Date(k)).getTime(),o=d?(new Date(g)).getTime():null;if(o){if(d<o){return -1}else{if(d>o){return 1}}}var m,f;for(var i=0,c=Math.max(n.length,e.length);i<c;i++){m=parseFloat(n[i])||n[i];f=parseFloat(e[i])||e[i];if(m<f){return -1}else{if(m>f){return 1}}}return 0}$.fn.refresh_select2=function(){var b=$(this);var a={width:"resolve",closeOnSelect:!b.is("[MULTIPLE]")};return b.select2(a)};function replace_big_select_inputs(a,c,b){if(!jQuery.fn.select2){return}if(a===undefined){a=20}if(c===undefined){c=3000}b=b||$("select");b.each(function(){var e=$(this);var d=e.find("option").length;if((d<a)||(d>c)){return}if(e.hasClass("no-autocomplete")){return}e.refresh_select2()})}$.fn.make_text_editable=function(g){var d=("num_cols" in g?g.num_cols:30),c=("num_rows" in g?g.num_rows:4),e=("use_textarea" in g?g.use_textarea:false),b=("on_finish" in g?g.on_finish:null),f=("help_text" in g?g.help_text:null);var a=$(this);a.addClass("editable-text").click(function(l){if($(this).children(":input").length>0){return}a.removeClass("editable-text");var i=function(m){a.find(":input").remove();if(m!==""){a.text(m)}else{a.html("<br>")}a.addClass("editable-text");if(b){b(m)}};var h=("cur_text" in g?g.cur_text:a.text()),k,j;if(e){k=$("<textarea/>").attr({rows:c,cols:d}).text($.trim(h)).keyup(function(m){if(m.keyCode===27){i(h)}});j=$("<button/>").text("Done").click(function(){i(k.val());return false})}else{k=$("<input type='text'/>").attr({value:$.trim(h),size:d}).blur(function(){i(h)}).keyup(function(m){if(m.keyCode===27){$(this).trigger("blur")}else{if(m.keyCode===13){i($(this).val())}}})}a.text("");a.append(k);if(j){a.append(j)}k.focus();k.select();l.stopPropagation()});if(f){a.attr("title",f).tooltip()}return a};function async_save_text(d,f,e,a,c,h,i,g,b){if(c===undefined){c=30}if(i===undefined){i=4}$("#"+d).click(function(){if($("#renaming-active").length>0){return}var l=$("#"+f),k=l.text(),j;if(h){j=$("<textarea></textarea>").attr({rows:i,cols:c}).text($.trim(k))}else{j=$("<input type='text'></input>").attr({value:$.trim(k),size:c})}j.attr("id","renaming-active");j.blur(function(){$(this).remove();l.show();if(b){b(j)}});j.keyup(function(n){if(n.keyCode===27){$(this).trigger("blur")}else{if(n.keyCode===13){var m={};m[a]=$(this).val();$(this).trigger("blur");$.ajax({url:e,data:m,error:function(){alert("Text editing for elt "+f+" failed")},success:function(o){if(o!==""){l.text(o)}else{l.html("<em>None</em>")}if(b){b(j)}}})}}});if(g){g(j)}l.hide();j.insertAfter(l);j.focus();j.select();return})}function init_history_items(d,a,c){var b=function(){try{var e=$.jStorage.get("history_expand_state");if(e){for(var g in e){$("#"+g+" div.historyItemBody").show()}}}catch(f){$.jStorage.deleteKey("history_expand_state")}if($.browser.mozilla){$("div.historyItemBody").each(function(){if(!$(this).is(":visible")){$(this).find("pre.peek").css("overflow","hidden")}})}d.each(function(){var j=this.id,h=$(this).children("div.historyItemBody"),i=h.find("pre.peek");$(this).find(".historyItemTitleBar > .historyItemTitle").wrap("<a href='javascript:void(0);'></a>").click(function(){var k;if(h.is(":visible")){if($.browser.mozilla){i.css("overflow","hidden")}h.slideUp("fast");if(!c){k=$.jStorage.get("history_expand_state");if(k){delete k[j];$.jStorage.set("history_expand_state",k)}}}else{h.slideDown("fast",function(){if($.browser.mozilla){i.css("overflow","auto")}});if(!c){k=$.jStorage.get("history_expand_state");if(!k){k={}}k[j]=true;$.jStorage.set("history_expand_state",k)}}return false})});$("#top-links > a.toggle").click(function(){var h=$.jStorage.get("history_expand_state");if(!h){h={}}$("div.historyItemBody:visible").each(function(){if($.browser.mozilla){$(this).find("pre.peek").css("overflow","hidden")}$(this).slideUp("fast");if(h){delete h[$(this).parent().attr("id")]}});$.jStorage.set("history_expand_state",h)}).show()};b()}function commatize(b){b+="";var a=/(\d+)(\d{3})/;while(a.test(b)){b=b.replace(a,"$1,$2")}return b}function reset_tool_search(a){var c=$("#galaxy_tools").contents();if(c.length===0){c=$(document)}$(this).removeClass("search_active");c.find(".toolTitle").removeClass("search_match");c.find(".toolSectionBody").hide();c.find(".toolTitle").show();c.find(".toolPanelLabel").show();c.find(".toolSectionWrapper").each(function(){if($(this).attr("id")!=="recently_used_wrapper"){$(this).show()}else{if($(this).hasClass("user_pref_visible")){$(this).show()}}});c.find("#search-no-results").hide();c.find("#search-spinner").hide();if(a){var b=c.find("#tool-search-query");b.val("search tools")}}var GalaxyAsync=function(a){this.url_dict={};this.log_action=(a===undefined?false:a)};GalaxyAsync.prototype.set_func_url=function(a,b){this.url_dict[a]=b};GalaxyAsync.prototype.set_user_pref=function(a,b){var c=this.url_dict[arguments.callee];if(c===undefined){return false}$.ajax({url:c,data:{pref_name:a,pref_value:b},error:function(){return false},success:function(){return true}})};GalaxyAsync.prototype.log_user_action=function(c,b,d){if(!this.log_action){return}var a=this.url_dict[arguments.callee];if(a===undefined){return false}$.ajax({url:a,data:{action:c,context:b,params:d},error:function(){return false},success:function(){return true}})};function init_refresh_on_change(){$("select[refresh_on_change='true']").off("change").change(function(){var a=$(this),e=a.val(),d=false,c=a.attr("refresh_on_change_values");if(c){c=c.split(",");var b=a.attr("last_selected_value");if($.inArray(e,c)===-1&&$.inArray(b,c)===-1){return}}$(window).trigger("refresh_on_change");$(document).trigger("convert_to_values");a.get(0).form.submit()});$(":checkbox[refresh_on_change='true']").off("click").click(function(){var a=$(this),e=a.val(),d=false,c=a.attr("refresh_on_change_values");if(c){c=c.split(",");var b=a.attr("last_selected_value");if($.inArray(e,c)===-1&&$.inArray(b,c)===-1){return}}$(window).trigger("refresh_on_change");a.get(0).form.submit()});$("a[confirm]").off("click").click(function(){return confirm($(this).attr("confirm"))})}$(document).ready(function(){init_refresh_on_change();if($.fn.tooltip){$(".unified-panel-header [title]").tooltip({placement:"bottom"});$("[title]").tooltip({placement:"top"})}make_popup_menus();replace_big_select_inputs(20,1500);$("a").click(function(){var b=$(this);var c=(parent.frames&&parent.frames.galaxy_main);if((b.attr("target")=="galaxy_main")&&(!c)){var a=b.attr("href");if(a.indexOf("?")==-1){a+="?"}else{a+="&"}a+="use_panels=True";b.attr("href",a);b.attr("target","_self")}return b})});
\ No newline at end of file
diff -r 210a768c98bc394eeabd231aac1056733bec9b11 -r 5b85de149657c2d9bbb3163db6ced3bb23fbfbc0 static/scripts/packed/viz/trackster/painters.js
--- a/static/scripts/packed/viz/trackster/painters.js
+++ b/static/scripts/packed/viz/trackster/painters.js
@@ -1,1 +1,1 @@
-define(["libs/underscore"],function(_){var extend=_.extend;var BEFORE=1001,CONTAINS=1002,OVERLAP_START=1003,OVERLAP_END=1004,CONTAINED_BY=1005,AFTER=1006;var compute_overlap=function(first_region,second_region){var first_start=first_region[0],first_end=first_region[1],second_start=second_region[0],second_end=second_region[1],overlap;if(first_start<second_start){if(first_end<=second_start){overlap=BEFORE}else{if(first_end<=second_end){overlap=OVERLAP_START}else{overlap=CONTAINS}}}else{if(first_start>second_end){overlap=AFTER}else{if(first_end<=second_end){overlap=CONTAINED_BY}else{overlap=OVERLAP_END}}}return overlap};var is_overlap=function(first_region,second_region){var overlap=compute_overlap(first_region,second_region);return(overlap!==BEFORE&&overlap!==AFTER)};var dashedLine=function(ctx,x1,y1,x2,y2,dashLen){if(dashLen===undefined){dashLen=4}var dX=x2-x1;var dY=y2-y1;var dashes=Math.floor(Math.sqrt(dX*dX+dY*dY)/dashLen);var dashX=dX/dashes;var dashY=dY/dashes;var q;for(q=0;q<dashes;q++,x1+=dashX,y1+=dashY){if(q%2!==0){continue}ctx.fillRect(x1,y1,dashLen,1)}};var drawDownwardEquilateralTriangle=function(ctx,down_vertex_x,down_vertex_y,side_len){var x1=down_vertex_x-side_len/2,x2=down_vertex_x+side_len/2,y=down_vertex_y-Math.sqrt(side_len*3/2);ctx.beginPath();ctx.moveTo(x1,y);ctx.lineTo(x2,y);ctx.lineTo(down_vertex_x,down_vertex_y);ctx.lineTo(x1,y);ctx.strokeStyle=this.fillStyle;ctx.fill();ctx.stroke();ctx.closePath()};var Scaler=function(default_val){this.default_val=(default_val?default_val:1)};Scaler.prototype.gen_val=function(input){return this.default_val};var Painter=function(data,view_start,view_end,prefs,mode){this.data=data;this.view_start=view_start;this.view_end=view_end;this.prefs=extend({},this.default_prefs,prefs);this.mode=mode};Painter.prototype.default_prefs={};Painter.prototype.draw=function(ctx,width,height,w_scale){};var LinePainter=function(data,view_start,view_end,prefs,mode){Painter.call(this,data,view_start,view_end,prefs,mode);if(this.prefs.min_value===undefined){this.prefs.min_value=_.min(_.map(this.data,function(d){return d[1]}))||0}if(this.prefs.max_value===undefined){this.prefs.max_value=_.max(_.map(this.data,function(d){return d[1]}))||0}};LinePainter.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Histogram",color:"#000",overflow_color:"#F66"};LinePainter.prototype.draw=function(ctx,width,height,w_scale){var in_path=false,min_value=this.prefs.min_value,max_value=this.prefs.max_value,vertical_range=max_value-min_value,height_px=height,view_start=this.view_start,mode=this.mode,data=this.data;ctx.save();var y_zero=Math.round(height+min_value/vertical_range*height);if(mode!=="Intensity"){ctx.fillStyle="#aaa";ctx.fillRect(0,y_zero,width,1)}ctx.beginPath();var x_scaled,y,delta_x_px;if(data.length>1){delta_x_px=Math.ceil((data[1][0]-data[0][0])*w_scale)}else{delta_x_px=10}var painter_color=this.prefs.block_color||this.prefs.color,pref_color=parseInt(painter_color.slice(1),16),pref_r=(pref_color&16711680)>>16,pref_g=(pref_color&65280)>>8,pref_b=pref_color&255,top_overflow=false,bot_overflow=false;for(var i=0,len=data.length;i<len;i++){ctx.fillStyle=ctx.strokeStyle=painter_color;top_overflow=bot_overflow=false;x_scaled=Math.round((data[i][0]-view_start)*w_scale);y=data[i][1];if(y===null){if(in_path&&mode==="Filled"){ctx.lineTo(x_scaled,height_px)}in_path=false;continue}if(y<min_value){bot_overflow=true;y=min_value}else{if(y>max_value){top_overflow=true;y=max_value}}if(mode==="Histogram"){y=Math.round(y/vertical_range*height_px);ctx.fillRect(x_scaled,y_zero,delta_x_px,-y)}else{if(mode==="Intensity"){var saturation=(y-min_value)/vertical_range,new_r=Math.round(pref_r+(255-pref_r)*(1-saturation)),new_g=Math.round(pref_g+(255-pref_g)*(1-saturation)),new_b=Math.round(pref_b+(255-pref_b)*(1-saturation));ctx.fillStyle="rgb("+new_r+","+new_g+","+new_b+")";ctx.fillRect(x_scaled,0,delta_x_px,height_px)}else{y=Math.round(height_px-(y-min_value)/vertical_range*height_px);if(in_path){ctx.lineTo(x_scaled,y)}else{in_path=true;if(mode==="Filled"){ctx.moveTo(x_scaled,height_px);ctx.lineTo(x_scaled,y)}else{ctx.moveTo(x_scaled,y)}}}}ctx.fillStyle=this.prefs.overflow_color;if(top_overflow||bot_overflow){var overflow_x;if(mode==="Histogram"||mode==="Intensity"){overflow_x=delta_x_px}else{x_scaled-=2;overflow_x=4}if(top_overflow){ctx.fillRect(x_scaled,0,overflow_x,3)}if(bot_overflow){ctx.fillRect(x_scaled,height_px-3,overflow_x,3)}}ctx.fillStyle=painter_color}if(mode==="Filled"){if(in_path){ctx.lineTo(x_scaled,y_zero);ctx.lineTo(0,y_zero)}ctx.fill()}else{ctx.stroke()}ctx.restore()};var FeaturePositionMapper=function(slot_height){this.feature_positions={};this.slot_height=slot_height;this.translation=0;this.y_translation=0};FeaturePositionMapper.prototype.map_feature_data=function(feature_data,slot,x_start,x_end){if(!this.feature_positions[slot]){this.feature_positions[slot]=[]}this.feature_positions[slot].push({data:feature_data,x_start:x_start,x_end:x_end})};FeaturePositionMapper.prototype.get_feature_data=function(x,y){var slot=Math.floor((y-this.y_translation)/this.slot_height),feature_dict;if(!this.feature_positions[slot]){return null}x+=this.translation;for(var i=0;i<this.feature_positions[slot].length;i++){feature_dict=this.feature_positions[slot][i];if(x>=feature_dict.x_start&&x<=feature_dict.x_end){return feature_dict.data}}};var FeaturePainter=function(data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler){Painter.call(this,data,view_start,view_end,prefs,mode);this.alpha_scaler=(alpha_scaler?alpha_scaler:new Scaler());this.height_scaler=(height_scaler?height_scaler:new Scaler())};FeaturePainter.prototype.default_prefs={block_color:"#FFF",connector_color:"#FFF"};extend(FeaturePainter.prototype,{get_required_height:function(rows_required,width){var required_height=this.get_row_height(),y_scale=required_height,mode=this.mode;if(mode==="no_detail"||mode==="Squish"||mode==="Pack"){required_height=rows_required*y_scale}return required_height+this.get_top_padding(width)},get_top_padding:function(width){return 0},draw:function(ctx,width,height,w_scale,slots){var data=this.data,view_start=this.view_start,view_end=this.view_end;ctx.save();ctx.fillStyle=this.prefs.block_color;ctx.textAlign="right";var y_scale=this.get_row_height(),feature_mapper=new FeaturePositionMapper(y_scale),x_draw_coords;for(var i=0,len=data.length;i<len;i++){var feature=data[i],feature_uid=feature[0],feature_start=feature[1],feature_end=feature[2],slot=(slots&&slots[feature_uid]!==undefined?slots[feature_uid]:null);if((feature_start<view_end&&feature_end>view_start)&&(this.mode==="Dense"||slot!==null)){x_draw_coords=this.draw_element(ctx,this.mode,feature,slot,view_start,view_end,w_scale,y_scale,width);feature_mapper.map_feature_data(feature,slot,x_draw_coords[0],x_draw_coords[1])}}ctx.restore();feature_mapper.y_translation=this.get_top_padding(width);return feature_mapper},draw_element:function(ctx,mode,feature,slot,tile_low,tile_high,w_scale,y_scale,width){return[0,0]}});var DENSE_TRACK_HEIGHT=10,NO_DETAIL_TRACK_HEIGHT=3,SQUISH_TRACK_HEIGHT=5,PACK_TRACK_HEIGHT=10,NO_DETAIL_FEATURE_HEIGHT=1,DENSE_FEATURE_HEIGHT=9,SQUISH_FEATURE_HEIGHT=3,PACK_FEATURE_HEIGHT=9,LABEL_SPACING=2,CONNECTOR_COLOR="#ccc";var LinkedFeaturePainter=function(data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler){FeaturePainter.call(this,data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler);this.draw_background_connector=true;this.draw_individual_connectors=false};extend(LinkedFeaturePainter.prototype,FeaturePainter.prototype,{get_row_height:function(){var mode=this.mode,height;if(mode==="Dense"){height=DENSE_TRACK_HEIGHT}else{if(mode==="no_detail"){height=NO_DETAIL_TRACK_HEIGHT}else{if(mode==="Squish"){height=SQUISH_TRACK_HEIGHT}else{height=PACK_TRACK_HEIGHT}}}return height},draw_element:function(ctx,mode,feature,slot,tile_low,tile_high,w_scale,y_scale,width){var feature_uid=feature[0],feature_start=feature[1],feature_end=feature[2],feature_name=feature[3],feature_strand=feature[4],f_start=Math.floor(Math.max(0,(feature_start-tile_low-0.5)*w_scale)),f_end=Math.ceil(Math.min(width,Math.max(0,(feature_end-tile_low-0.5)*w_scale))),draw_start=f_start,draw_end=f_end,y_start=(mode==="Dense"?0:(0+slot))*y_scale+this.get_top_padding(width),thickness,y_start,thick_start=null,thick_end=null,block_color=(!feature_strand||feature_strand==="+"||feature_strand==="."?this.prefs.block_color:this.prefs.reverse_strand_color);label_color=this.prefs.label_color;ctx.globalAlpha=this.alpha_scaler.gen_val(feature);if(mode==="Dense"){slot=1}if(mode==="no_detail"){ctx.fillStyle=block_color;ctx.fillRect(f_start,y_start+5,f_end-f_start,NO_DETAIL_FEATURE_HEIGHT)}else{var feature_ts=feature[5],feature_te=feature[6],feature_blocks=feature[7],full_height=true;if(feature_ts&&feature_te){thick_start=Math.floor(Math.max(0,(feature_ts-tile_low)*w_scale));thick_end=Math.ceil(Math.min(width,Math.max(0,(feature_te-tile_low)*w_scale)))}var thin_height,thick_height;if(mode==="Squish"){thin_height=1;thick_height=SQUISH_FEATURE_HEIGHT;full_height=false}else{if(mode==="Dense"){thin_height=5;thick_height=DENSE_FEATURE_HEIGHT}else{thin_height=5;thick_height=PACK_FEATURE_HEIGHT}}if(!feature_blocks){ctx.fillStyle=block_color;ctx.fillRect(f_start,y_start+1,f_end-f_start,thick_height);if(feature_strand&&full_height){if(feature_strand==="+"){ctx.fillStyle=ctx.canvas.manager.get_pattern("right_strand_inv")}else{if(feature_strand==="-"){ctx.fillStyle=ctx.canvas.manager.get_pattern("left_strand_inv")}}ctx.fillRect(f_start,y_start+1,f_end-f_start,thick_height)}}else{var cur_y_start,cur_height;if(mode==="Squish"||mode==="Dense"){cur_y_start=y_start+Math.floor(SQUISH_FEATURE_HEIGHT/2)+1;cur_height=1}else{if(feature_strand){cur_y_start=y_start;cur_height=thick_height}else{cur_y_start+=(SQUISH_FEATURE_HEIGHT/2)+1;cur_height=1}}if(this.draw_background_connector){if(mode==="Squish"||mode==="Dense"){ctx.fillStyle=CONNECTOR_COLOR}else{if(feature_strand){if(feature_strand==="+"){ctx.fillStyle=ctx.canvas.manager.get_pattern("right_strand")}else{if(feature_strand==="-"){ctx.fillStyle=ctx.canvas.manager.get_pattern("left_strand")}}}else{ctx.fillStyle=CONNECTOR_COLOR}}ctx.fillRect(f_start,cur_y_start,f_end-f_start,cur_height)}var start_and_height;for(var k=0,k_len=feature_blocks.length;k<k_len;k++){var block=feature_blocks[k],block_start=Math.floor(Math.max(0,(block[0]-tile_low-0.5)*w_scale)),block_end=Math.ceil(Math.min(width,Math.max((block[1]-tile_low-0.5)*w_scale))),last_block_start,last_block_end;if(block_start>block_end){continue}ctx.fillStyle=block_color;ctx.fillRect(block_start,y_start+(thick_height-thin_height)/2+1,block_end-block_start,thin_height);if(thick_start!==undefined&&feature_te>feature_ts&&!(block_start>thick_end||block_end<thick_start)){var block_thick_start=Math.max(block_start,thick_start),block_thick_end=Math.min(block_end,thick_end);ctx.fillRect(block_thick_start,y_start+1,block_thick_end-block_thick_start,thick_height);if(feature_blocks.length===1&&mode==="Pack"){if(feature_strand==="+"){ctx.fillStyle=ctx.canvas.manager.get_pattern("right_strand_inv")}else{if(feature_strand==="-"){ctx.fillStyle=ctx.canvas.manager.get_pattern("left_strand_inv")}}if(block_thick_start+14<block_thick_end){block_thick_start+=2;block_thick_end-=2}ctx.fillRect(block_thick_start,y_start+1,block_thick_end-block_thick_start,thick_height)}}if(this.draw_individual_connectors&&last_block_start){this.draw_connector(ctx,last_block_start,last_block_end,block_start,block_end,y_start)}last_block_start=block_start;last_block_end=block_end}if(mode==="Pack"){ctx.globalAlpha=1;ctx.fillStyle="white";var hscale_factor=this.height_scaler.gen_val(feature),new_height=Math.ceil(thick_height*hscale_factor),ws_height=Math.round((thick_height-new_height)/2);if(hscale_factor!==1){ctx.fillRect(f_start,cur_y_start+1,f_end-f_start,ws_height);ctx.fillRect(f_start,cur_y_start+thick_height-ws_height+1,f_end-f_start,ws_height)}}}ctx.globalAlpha=1;if(feature_name&&mode==="Pack"&&feature_start>tile_low){ctx.fillStyle=label_color;if(tile_low===0&&f_start-ctx.measureText(feature_name).width<0){ctx.textAlign="left";ctx.fillText(feature_name,f_end+LABEL_SPACING,y_start+8);draw_end+=ctx.measureText(feature_name).width+LABEL_SPACING}else{ctx.textAlign="right";ctx.fillText(feature_name,f_start-LABEL_SPACING,y_start+8);draw_start-=ctx.measureText(feature_name).width+LABEL_SPACING}}}ctx.globalAlpha=1;return[draw_start,draw_end]}});var ReadPainter=function(data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler,ref_seq,base_color_fn){FeaturePainter.call(this,data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler);this.ref_seq=(ref_seq?ref_seq.data:null);this.base_color_fn=base_color_fn};extend(ReadPainter.prototype,FeaturePainter.prototype,{get_row_height:function(){var height,mode=this.mode;if(mode==="Dense"){height=DENSE_TRACK_HEIGHT}else{if(mode==="Squish"){height=SQUISH_TRACK_HEIGHT}else{height=PACK_TRACK_HEIGHT;if(this.prefs.show_insertions){height*=2}}}return height},_parse_cigar:function(cigar_str){var cigar_ops="MIDNSHP=X";var blocks=[[0,0]],cur_block=blocks[0],base_pos=0,parsed_cigar=_.map(cigar_str.match(/[0-9]+[MIDNSHP=X]/g),function(op){var op_len=parseInt(op.slice(0,-1),10),op_char=op.slice(-1);if(op_char==="N"){if(cur_block[1]!==0){cur_block=[base_pos+op_len,base_pos+op_len];blocks.push(cur_block)}}else{if("ISHP".indexOf(op_char)===-1){cur_block[1]+=op_len;base_pos+=op_len}}return[cigar_ops.indexOf(op_char),op_len]});return{blocks:blocks,cigar:parsed_cigar}},draw_read:function(ctx,mode,w_scale,y_start,tile_low,tile_high,feature_start,cigar,strand,read_seq){ctx.textAlign="center";var tile_region=[tile_low,tile_high],base_offset=0,seq_offset=0,gap=Math.round(w_scale/2),char_width_px=ctx.canvas.manager.char_width_px,block_color=(strand==="+"?this.prefs.block_color:this.prefs.reverse_strand_color),pack_mode=(mode==="Pack"),paint_utils=new ReadPainterUtils(ctx,(pack_mode?PACK_FEATURE_HEIGHT:SQUISH_FEATURE_HEIGHT),w_scale,mode);var draw_last=[];if(!cigar){cigar=[[0,read_seq.length]]}for(var cig_id=0,len=cigar.length;cig_id<len;cig_id++){var cig=cigar[cig_id],cig_op="MIDNSHP=X"[cig[0]],cig_len=cig[1];var seq_start=feature_start+base_offset,s_start=Math.floor(Math.max(-0.5*w_scale,(seq_start-tile_low-0.5)*w_scale)),s_end=Math.floor(Math.max(0,(seq_start+cig_len-tile_low-0.5)*w_scale));if(!is_overlap([seq_start,seq_start+cig_len],tile_region)){continue}if(s_start===s_end){s_end+=1}switch(cig_op){case"H":break;case"S":seq_offset+=cig_len;break;case"M":case"=":case"X":ctx.fillStyle=block_color;ctx.fillRect(s_start,y_start+(pack_mode?1:4),s_end-s_start,(pack_mode?PACK_FEATURE_HEIGHT:SQUISH_FEATURE_HEIGHT));var seq=read_seq.slice(seq_offset,seq_offset+cig_len),ref_char,read_char;for(var c=0,str_len=seq.length;c<str_len;c++){if(seq_start+c>=tile_low&&seq_start+c<=tile_high){ref_char=(this.ref_seq?this.ref_seq[seq_start-tile_low+c]:null);read_char=seq[c];if((ref_char&&(!this.prefs.show_differences||(read_char.toLowerCase!=="n"&&(ref_char.toLowerCase()!==read_char.toLowerCase()))))||(!ref_char&&!this.prefs.show_differences)){var c_start=Math.floor(Math.max(0,(seq_start+c-tile_low)*w_scale));ctx.fillStyle=this.base_color_fn(seq[c]);if(pack_mode&&w_scale>char_width_px){ctx.fillText(seq[c],c_start,y_start+9)}else{if(w_scale>0.05){ctx.fillRect(c_start-gap,y_start+(pack_mode?1:4),Math.max(1,Math.round(w_scale)),(pack_mode?PACK_FEATURE_HEIGHT:SQUISH_FEATURE_HEIGHT))}}}}}seq_offset+=cig_len;base_offset+=cig_len;break;case"N":ctx.fillStyle=CONNECTOR_COLOR;ctx.fillRect(s_start,y_start+5,s_end-s_start,1);base_offset+=cig_len;break;case"D":paint_utils.draw_deletion(s_start,y_start,1);base_offset+=cig_len;break;case"P":break;case"I":var insert_x_coord=s_start-gap;if(is_overlap([seq_start,seq_start+cig_len],tile_region)){var seq=read_seq.slice(seq_offset,seq_offset+cig_len);if(this.prefs.show_insertions){var x_center=s_start-(s_end-s_start)/2;if((mode==="Pack"||this.mode==="Auto")&&read_seq!==undefined&&w_scale>char_width_px){ctx.fillStyle="yellow";ctx.fillRect(x_center-gap,y_start-9,s_end-s_start,9);draw_last[draw_last.length]={type:"triangle",data:[insert_x_coord,y_start+4,5]};ctx.fillStyle=CONNECTOR_COLOR;switch(compute_overlap([seq_start,seq_start+cig_len],tile_region)){case (OVERLAP_START):seq=seq.slice(tile_low-seq_start);break;case (OVERLAP_END):seq=seq.slice(0,seq_start-tile_high);break;case (CONTAINED_BY):break;case (CONTAINS):seq=seq.slice(tile_low-seq_start,seq_start-tile_high);break}for(var c=0,str_len=seq.length;c<str_len;c++){var c_start=Math.floor(Math.max(0,(seq_start+c-tile_low)*w_scale));ctx.fillText(seq[c],c_start-(s_end-s_start)/2,y_start)}}else{ctx.fillStyle="yellow";ctx.fillRect(x_center,y_start+(this.mode!=="Dense"?2:5),s_end-s_start,(mode!=="Dense"?SQUISH_FEATURE_HEIGHT:DENSE_FEATURE_HEIGHT))}}else{if((mode==="Pack"||this.mode==="Auto")&&read_seq!==undefined&&w_scale>char_width_px){draw_last.push({type:"text",data:[seq.length,insert_x_coord,y_start+9]})}else{}}}seq_offset+=cig_len;break}}ctx.fillStyle="yellow";var item,type,data;for(var i=0;i<draw_last.length;i++){item=draw_last[i];type=item.type;data=item.data;if(type==="text"){ctx.save();ctx.font="bold "+ctx.font;ctx.fillText(data[0],data[1],data[2]);ctx.restore()}else{if(type==="triangle"){drawDownwardEquilateralTriangle(ctx,data[0],data[1],data[2])}}}},draw_element:function(ctx,mode,feature,slot,tile_low,tile_high,w_scale,y_scale,width){var feature_uid=feature[0],feature_start=feature[1],feature_end=feature[2],feature_name=feature[3],f_start=Math.floor(Math.max(-0.5*w_scale,(feature_start-tile_low-0.5)*w_scale)),f_end=Math.ceil(Math.min(width,Math.max(0,(feature_end-tile_low-0.5)*w_scale))),y_start=(mode==="Dense"?0:(0+slot))*y_scale,label_color=this.prefs.label_color;if(feature[5] instanceof Array){var connector=true;if(feature[4][1]>=tile_low&&feature[4][0]<=tile_high&&feature[4][2]){this.draw_read(ctx,mode,w_scale,y_start,tile_low,tile_high,feature[4][0],feature[4][2],feature[4][3],feature[4][4])}else{connector=false}if(feature[5][1]>=tile_low&&feature[5][0]<=tile_high&&feature[5][2]){this.draw_read(ctx,mode,w_scale,y_start,tile_low,tile_high,feature[5][0],feature[5][2],feature[5][3],feature[5][4])}else{connector=false}var b1_end=Math.ceil(Math.min(width,Math.max(-0.5*w_scale,(feature[4][1]-tile_low-0.5)*w_scale))),b2_start=Math.floor(Math.max(-0.5*w_scale,(feature[5][0]-tile_low-0.5)*w_scale));if(connector&&b2_start>b1_end){ctx.fillStyle=CONNECTOR_COLOR;dashedLine(ctx,b1_end,y_start+5,b2_start,y_start+5)}}else{this.draw_read(ctx,mode,w_scale,y_start,tile_low,tile_high,feature_start,feature[4],feature[5],feature[6])}if(mode==="Pack"&&feature_start>=tile_low&&feature_name!=="."){ctx.fillStyle=this.prefs.label_color;if(tile_low===0&&f_start-ctx.measureText(feature_name).width<0){ctx.textAlign="left";ctx.fillText(feature_name,f_end+LABEL_SPACING,y_start+8)}else{ctx.textAlign="right";ctx.fillText(feature_name,f_start-LABEL_SPACING,y_start+8)}}return[0,0]}});var RefBasedReadPainter=function(data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler,ref_seq,base_color_fn){ReadPainter.call(this,data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler,ref_seq,base_color_fn)};extend(RefBasedReadPainter.prototype,ReadPainter.prototype,FeaturePainter,{draw_read:function(ctx,mode,w_scale,y_start,tile_low,tile_high,feature_start,cigar,strand,read_seq){ctx.textAlign="center";var tile_region=[tile_low,tile_high],base_offset=0,seq_offset=0,gap=Math.round(w_scale/2),char_width_px=ctx.canvas.manager.char_width_px,block_color=(strand==="+"?this.prefs.block_color:this.prefs.reverse_strand_color),pack_mode=(mode==="Pack"),paint_utils=new ReadPainterUtils(ctx,(pack_mode?PACK_FEATURE_HEIGHT:SQUISH_FEATURE_HEIGHT),w_scale,mode),drawing_blocks=[];var draw_last=[];var t=this._parse_cigar(cigar);cigar=t.cigar;drawing_blocks=t.blocks;for(var i=0;i<drawing_blocks.length;i++){var block=drawing_blocks[i];if(is_overlap([feature_start+block[0],feature_start+block[1]],tile_region)){var s_start=Math.floor(Math.max(-0.5*w_scale,(feature_start+block[0]-tile_low-0.5)*w_scale)),s_end=Math.floor(Math.max(0,(feature_start+block[1]-tile_low-0.5)*w_scale));if(s_start===s_end){s_end+=1}ctx.fillStyle=block_color;ctx.fillRect(s_start,y_start+(pack_mode?1:4),s_end-s_start,(pack_mode?PACK_FEATURE_HEIGHT:SQUISH_FEATURE_HEIGHT))}}for(var cig_id=0,len=cigar.length;cig_id<len;cig_id++){var cig=cigar[cig_id],cig_op="MIDNSHP=X"[cig[0]],cig_len=cig[1];var seq_start=feature_start+base_offset,s_start=Math.floor(Math.max(0,-0.5*w_scale,(seq_start-tile_low-0.5)*w_scale)),s_end=Math.floor(Math.max(0,(seq_start+cig_len-tile_low-0.5)*w_scale));if(!is_overlap([seq_start,seq_start+cig_len],tile_region)){continue}if(s_start===s_end){s_end+=1}switch(cig_op){case"H":case"S":case"P":break;case"M":base_offset+=cig_len;break;case"=":case"X":var cur_seq="";if(cig_op==="X"){cur_seq=read_seq.slice(seq_offset,seq_offset+cig_len)}else{if(this.ref_seq){cur_seq=this.ref_seq.slice(Math.max(0,seq_start-tile_low),Math.min(seq_start-tile_low+cig_len,tile_high-tile_low))}}var start_pos=Math.max(seq_start,tile_low);for(var c=0;c<cur_seq.length;c++){if(cur_seq&&!this.prefs.show_differences||cig_op==="X"){var c_start=Math.floor(Math.max(0,(start_pos+c-tile_low)*w_scale));ctx.fillStyle=this.base_color_fn(cur_seq[c]);if(pack_mode&&w_scale>char_width_px){ctx.fillText(cur_seq[c],c_start,y_start+9)}else{if(w_scale>0.05){ctx.fillRect(c_start-gap,y_start+(pack_mode?1:4),Math.max(1,Math.round(w_scale)),(pack_mode?PACK_FEATURE_HEIGHT:SQUISH_FEATURE_HEIGHT))}}}}if(cig_op==="X"){seq_offset+=cig_len}base_offset+=cig_len;break;case"N":ctx.fillStyle=CONNECTOR_COLOR;ctx.fillRect(s_start,y_start+5,s_end-s_start,1);base_offset+=cig_len;break;case"D":paint_utils.draw_deletion(s_start,y_start+(pack_mode?1:4),cig_len);base_offset+=cig_len;break;case"I":var insert_x_coord=s_start-gap;if(is_overlap([seq_start,seq_start+cig_len],tile_region)){var seq=read_seq.slice(seq_offset,seq_offset+cig_len);if(this.prefs.show_insertions){var x_center=s_start-(s_end-s_start)/2;if((mode==="Pack"||this.mode==="Auto")&&read_seq!==undefined&&w_scale>char_width_px){ctx.fillStyle="yellow";ctx.fillRect(x_center-gap,y_start-9,s_end-s_start,9);draw_last[draw_last.length]={type:"triangle",data:[insert_x_coord,y_start+4,5]};ctx.fillStyle=CONNECTOR_COLOR;switch(compute_overlap([seq_start,seq_start+cig_len],tile_region)){case (OVERLAP_START):seq=seq.slice(tile_low-seq_start);break;case (OVERLAP_END):seq=seq.slice(0,seq_start-tile_high);break;case (CONTAINED_BY):break;case (CONTAINS):seq=seq.slice(tile_low-seq_start,seq_start-tile_high);break}for(var c=0,str_len=seq.length;c<str_len;c++){var c_start=Math.floor(Math.max(0,(seq_start+c-tile_low)*w_scale));ctx.fillText(seq[c],c_start-(s_end-s_start)/2,y_start)}}else{ctx.fillStyle="yellow";ctx.fillRect(x_center,y_start+(this.mode!=="Dense"?2:5),s_end-s_start,(mode!=="Dense"?SQUISH_FEATURE_HEIGHT:DENSE_FEATURE_HEIGHT))}}else{if((mode==="Pack"||this.mode==="Auto")&&read_seq!==undefined&&w_scale>char_width_px){draw_last.push({type:"text",data:[seq.length,insert_x_coord,y_start+9]})}else{}}}seq_offset+=cig_len;break}}ctx.fillStyle="yellow";var item,type,data;for(var i=0;i<draw_last.length;i++){item=draw_last[i];type=item.type;data=item.data;if(type==="text"){ctx.save();ctx.font="bold "+ctx.font;ctx.fillText(data[0],data[1],data[2]);ctx.restore()}else{if(type==="triangle"){drawDownwardEquilateralTriangle(ctx,data[0],data[1],data[2])}}}}});var ArcLinkedFeaturePainter=function(data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler){LinkedFeaturePainter.call(this,data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler);this.longest_feature_length=this.calculate_longest_feature_length();this.draw_background_connector=false;this.draw_individual_connectors=true};extend(ArcLinkedFeaturePainter.prototype,FeaturePainter.prototype,LinkedFeaturePainter.prototype,{calculate_longest_feature_length:function(){var longest_feature_length=0;for(var i=0,len=this.data.length;i<len;i++){var feature=this.data[i],feature_start=feature[1],feature_end=feature[2];longest_feature_length=Math.max(longest_feature_length,feature_end-feature_start)}return longest_feature_length},get_top_padding:function(width){var view_range=this.view_end-this.view_start,w_scale=width/view_range;return Math.min(128,Math.ceil((this.longest_feature_length/2)*w_scale))},draw_connector:function(ctx,block1_start,block1_end,block2_start,block2_end,y_start){var x_center=(block1_end+block2_start)/2,radius=block2_start-x_center;var angle1=Math.PI,angle2=0;if(radius>0){ctx.beginPath();ctx.arc(x_center,y_start,block2_start-x_center,Math.PI,0);ctx.stroke()}}});var Color=function(rgb,a){if(Array.isArray(rgb)){this.rgb=rgb}else{if(rgb.length==6){this.rgb=rgb.match(/.{2}/g).map(function(c){return parseInt(c,16)})}else{if(rgb.length==7){this.rgb=rgb.substring(1,7).match(/.{2}/g).map(function(c){return parseInt(c,16)})}else{this.rgb=rgb.split("").map(function(c){return parseInt(c+c,16)})}}}this.alpha=typeof(a)==="number"?a:1};Color.prototype={eval:function(){return this},toCSS:function(){if(this.alpha<1){return"rgba("+this.rgb.map(function(c){return Math.round(c)}).concat(this.alpha).join(", ")+")"}else{return"#"+this.rgb.map(function(i){i=Math.round(i);i=(i>255?255:(i<0?0:i)).toString(16);return i.length===1?"0"+i:i}).join("")}},toHSL:function(){var r=this.rgb[0]/255,g=this.rgb[1]/255,b=this.rgb[2]/255,a=this.alpha;var max=Math.max(r,g,b),min=Math.min(r,g,b);var h,s,l=(max+min)/2,d=max-min;if(max===min){h=s=0}else{s=l>0.5?d/(2-max-min):d/(max+min);switch(max){case r:h=(g-b)/d+(g<b?6:0);break;case g:h=(b-r)/d+2;break;case b:h=(r-g)/d+4;break}h/=6}return{h:h*360,s:s,l:l,a:a}},toARGB:function(){var argb=[Math.round(this.alpha*255)].concat(this.rgb);return"#"+argb.map(function(i){i=Math.round(i);i=(i>255?255:(i<0?0:i)).toString(16);return i.length===1?"0"+i:i}).join("")},mix:function(color2,weight){color1=this;var p=weight;var w=p*2-1;var a=color1.toHSL().a-color2.toHSL().a;var w1=(((w*a==-1)?w:(w+a)/(1+w*a))+1)/2;var w2=1-w1;var rgb=[color1.rgb[0]*w1+color2.rgb[0]*w2,color1.rgb[1]*w1+color2.rgb[1]*w2,color1.rgb[2]*w1+color2.rgb[2]*w2];var alpha=color1.alpha*p+color2.alpha*(1-p);return new Color(rgb,alpha)}};var LinearRamp=function(start_color,end_color,start_value,end_value){this.start_color=new Color(start_color);this.end_color=new Color(end_color);this.start_value=start_value;this.end_value=end_value;this.value_range=end_value-start_value};LinearRamp.prototype.map_value=function(value){value=Math.max(value,this.start_value);value=Math.min(value,this.end_value);value=(value-this.start_value)/this.value_range;return this.start_color.mix(this.end_color,1-value).toCSS()};var SplitRamp=function(start_color,middle_color,end_color,start_value,end_value){this.positive_ramp=new LinearRamp(middle_color,end_color,0,end_value);this.negative_ramp=new LinearRamp(middle_color,start_color,0,-start_value);this.start_value=start_value;this.end_value=end_value};SplitRamp.prototype.map_value=function(value){value=Math.max(value,this.start_value);value=Math.min(value,this.end_value);if(value>=0){return this.positive_ramp.map_value(value)}else{return this.negative_ramp.map_value(-value)}};var DiagonalHeatmapPainter=function(data,view_start,view_end,prefs,mode){Painter.call(this,data,view_start,view_end,prefs,mode);var i,len;if(this.prefs.min_value===undefined){var min_value=Infinity;for(i=0,len=this.data.length;i<len;i++){min_value=Math.min(min_value,this.data[i][5])}this.prefs.min_value=min_value}if(this.prefs.max_value===undefined){var max_value=-Infinity;for(i=0,len=this.data.length;i<len;i++){max_value=Math.max(max_value,this.data[i][5])}this.prefs.max_value=max_value}};DiagonalHeatmapPainter.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Heatmap",pos_color:"#FF8C00",neg_color:"#4169E1"};DiagonalHeatmapPainter.prototype.draw=function(ctx,width,height,w_scale){var min_value=this.prefs.min_value,max_value=this.prefs.max_value,value_range=max_value-min_value,height_px=height,view_start=this.view_start,mode=this.mode,data=this.data,invsqrt2=1/Math.sqrt(2);var ramp=(new SplitRamp(this.prefs.neg_color,"#FFFFFF",this.prefs.pos_color,min_value,max_value));var d,s1,e1,s2,e2,value;var scale=function(p){return(p-view_start)*w_scale};ctx.save();ctx.rotate(-45*Math.PI/180);ctx.scale(invsqrt2,invsqrt2);for(var i=0,len=data.length;i<len;i++){d=data[i];s1=scale(d[1]);e1=scale(d[2]);s2=scale(d[4]);e2=scale(d[5]);value=d[6];ctx.fillStyle=(ramp.map_value(value));ctx.fillRect(s1,s2,(e1-s1),(e2-s2))}ctx.restore()};var ReadPainterUtils=function(ctx,row_height,px_per_base,mode){this.ctx=ctx;this.row_height=row_height;this.px_per_base=px_per_base;this.draw_details=(mode==="Pack"||mode==="Auto")&&(px_per_base>=ctx.canvas.manager.char_width_px);this.delete_details_thickness=0.2};extend(ReadPainterUtils.prototype,{draw_deletion:function(x,y,len){this.ctx.fillStyle="black";var thickness=(this.draw_details?this.delete_details_thickness:1)*this.row_height;y+=0.5*(this.row_height-thickness);this.ctx.fillRect(x,y,len*this.px_per_base,thickness)}});var VariantPainter=function(data,view_start,view_end,prefs,mode,base_color_fn){Painter.call(this,data,view_start,view_end,prefs,mode);this.base_color_fn=base_color_fn;this.divider_height=1};extend(VariantPainter.prototype,Painter.prototype,{get_row_height:function(){var mode=this.mode,height;if(mode==="Dense"){height=DENSE_TRACK_HEIGHT}else{if(mode==="Squish"){height=SQUISH_TRACK_HEIGHT}else{height=PACK_TRACK_HEIGHT}}return height},get_required_height:function(num_samples){var height=this.prefs.summary_height;if(num_samples>1&&this.prefs.show_sample_data){height+=this.divider_height+num_samples*this.get_row_height()}return height},draw:function(ctx,width,height,w_scale){ctx.save();var get_deletion_info=function(ref,alt){var ref_len=ref.length,alt_len=alt.length,start=0,len=1,is_delete=false;if(alt==="-"){is_delete=true;len=ref.length}else{if(ref.indexOf(alt)===0&&ref_len>alt_len){is_delete=true;len=ref_len=alt_len;start+=alt_len}}return(is_delete?{start:start,len:len}:null)};var locus_data,pos,id,ref,alt,qual,filter,sample_gts,allele_counts,variant,draw_x_start,char_x_start,draw_y_start,genotype,base_px=Math.max(1,Math.floor(w_scale)),num_samples=(this.data.length?this.data[0][7].split(",").length:0),row_height=(this.mode==="Squish"?SQUISH_TRACK_HEIGHT:PACK_TRACK_HEIGHT),feature_height=(w_scale<0.1?row_height:(this.mode==="Squish"?SQUISH_FEATURE_HEIGHT:PACK_FEATURE_HEIGHT)),draw_summary=true,paint_utils=new ReadPainterUtils(ctx,row_height,w_scale,this.mode),j;if(num_samples===1){row_height=feature_height=(w_scale<ctx.canvas.manager.char_width_px?this.prefs.summary_height:row_height);draw_summary=false}if(this.prefs.show_sample_data&&draw_summary){ctx.fillStyle="#F3F3F3";ctx.globalAlpha=1;ctx.fillRect(0,this.prefs.summary_height-this.divider_height,width,this.divider_height)}ctx.textAlign="center";for(var i=0;i<this.data.length;i++){locus_data=this.data[i];pos=locus_data[1];ref=locus_data[3];alt=[locus_data[4].split(",")];sample_gts=locus_data[7].split(",");allele_counts=locus_data.slice(8);alt=_.map(_.flatten(alt),function(a){var type,alt_info={},delete_info=get_deletion_info(ref,a);if(delete_info){type="deletion";_.extend(alt_info,delete_info)}else{type="snp"}return _.extend(alt_info,{type:type,value:a,})});if(pos<this.view_start||pos>this.view_end){continue}draw_x_start=Math.floor(Math.max(-0.5*w_scale,(pos-this.view_start-0.5)*w_scale));char_x_start=Math.floor(Math.max(0,(pos-this.view_start)*w_scale));if(draw_summary){ctx.fillStyle="#999999";ctx.globalAlpha=1;ctx.fillRect(draw_x_start,0,base_px,this.prefs.summary_height);draw_y_start=this.prefs.summary_height;for(j=0;j<alt.length;j++){ctx.fillStyle=(alt[j].type==="deletion"?"black":this.base_color_fn(alt[j].value));allele_frac=allele_counts/sample_gts.length;draw_height=Math.ceil(this.prefs.summary_height*allele_frac);ctx.fillRect(draw_x_start,draw_y_start-draw_height,base_px,draw_height);draw_y_start-=draw_height}}if(!this.prefs.show_sample_data){continue}draw_y_start=(draw_summary?this.prefs.summary_height+this.divider_height:0);for(j=0;j<sample_gts.length;j++,draw_y_start+=row_height){genotype=(sample_gts[j]?sample_gts[j].split(/\/|\|/):["0","0"]);variant=null;if(genotype[0]===genotype[1]){if(genotype[0]==="."){}else{if(genotype[0]!=="0"){variant=alt[parseInt(genotype[0],10)-1];ctx.globalAlpha=1}}}else{variant=(genotype[0]!=="0"?genotype[0]:genotype[1]);variant=alt[parseInt(variant,10)-1];ctx.globalAlpha=0.5}if(variant){if(variant.type==="snp"){var snp=variant.value;ctx.fillStyle=this.base_color_fn(snp);if(paint_utils.draw_details){ctx.fillText(snp,char_x_start,draw_y_start+row_height)}else{ctx.fillRect(draw_x_start,draw_y_start+1,base_px,feature_height)}}else{if(variant.type==="deletion"){paint_utils.draw_deletion(draw_x_start+base_px*variant.start,draw_y_start+1,variant.len)}else{}}}}}ctx.restore()}});return{Scaler:Scaler,LinePainter:LinePainter,LinkedFeaturePainter:LinkedFeaturePainter,ReadPainter:ReadPainter,RefBasedReadPainter:RefBasedReadPainter,ArcLinkedFeaturePainter:ArcLinkedFeaturePainter,DiagonalHeatmapPainter:DiagonalHeatmapPainter,VariantPainter:VariantPainter}});
\ No newline at end of file
+define(["libs/underscore"],function(_){var extend=_.extend;var BEFORE=1001,CONTAINS=1002,OVERLAP_START=1003,OVERLAP_END=1004,CONTAINED_BY=1005,AFTER=1006;var compute_overlap=function(first_region,second_region){var first_start=first_region[0],first_end=first_region[1],second_start=second_region[0],second_end=second_region[1],overlap;if(first_start<second_start){if(first_end<=second_start){overlap=BEFORE}else{if(first_end<=second_end){overlap=OVERLAP_START}else{overlap=CONTAINS}}}else{if(first_start>second_end){overlap=AFTER}else{if(first_end<=second_end){overlap=CONTAINED_BY}else{overlap=OVERLAP_END}}}return overlap};var is_overlap=function(first_region,second_region){var overlap=compute_overlap(first_region,second_region);return(overlap!==BEFORE&&overlap!==AFTER)};var dashedLine=function(ctx,x1,y1,x2,y2,dashLen){if(dashLen===undefined){dashLen=4}var dX=x2-x1;var dY=y2-y1;var dashes=Math.floor(Math.sqrt(dX*dX+dY*dY)/dashLen);var dashX=dX/dashes;var dashY=dY/dashes;var q;for(q=0;q<dashes;q++,x1+=dashX,y1+=dashY){if(q%2!==0){continue}ctx.fillRect(x1,y1,dashLen,1)}};var drawDownwardEquilateralTriangle=function(ctx,down_vertex_x,down_vertex_y,side_len){var x1=down_vertex_x-side_len/2,x2=down_vertex_x+side_len/2,y=down_vertex_y-Math.sqrt(side_len*3/2);ctx.beginPath();ctx.moveTo(x1,y);ctx.lineTo(x2,y);ctx.lineTo(down_vertex_x,down_vertex_y);ctx.lineTo(x1,y);ctx.strokeStyle=this.fillStyle;ctx.fill();ctx.stroke();ctx.closePath()};var Scaler=function(default_val){this.default_val=(default_val?default_val:1)};Scaler.prototype.gen_val=function(input){return this.default_val};var Painter=function(data,view_start,view_end,prefs,mode){this.data=data;this.view_start=view_start;this.view_end=view_end;this.prefs=extend({},this.default_prefs,prefs);this.mode=mode};Painter.prototype.default_prefs={};Painter.prototype.draw=function(ctx,width,height,w_scale){};var LinePainter=function(data,view_start,view_end,prefs,mode){Painter.call(this,data,view_start,view_end,prefs,mode);if(this.prefs.min_value===undefined){this.prefs.min_value=_.min(_.map(this.data,function(d){return d[1]}))||0}if(this.prefs.max_value===undefined){this.prefs.max_value=_.max(_.map(this.data,function(d){return d[1]}))||0}};LinePainter.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Histogram",color:"#000",overflow_color:"#F66"};LinePainter.prototype.draw=function(ctx,width,height,w_scale){var in_path=false,min_value=this.prefs.min_value,max_value=this.prefs.max_value,vertical_range=max_value-min_value,height_px=height,view_start=this.view_start,mode=this.mode,data=this.data;ctx.save();var y_zero=Math.round(height+min_value/vertical_range*height);if(mode!=="Intensity"){ctx.fillStyle="#aaa";ctx.fillRect(0,y_zero,width,1)}ctx.beginPath();var x_scaled,y,delta_x_px;if(data.length>1){delta_x_px=Math.ceil((data[1][0]-data[0][0])*w_scale)}else{delta_x_px=10}var painter_color=this.prefs.block_color||this.prefs.color,pref_color=parseInt(painter_color.slice(1),16),pref_r=(pref_color&16711680)>>16,pref_g=(pref_color&65280)>>8,pref_b=pref_color&255,top_overflow=false,bot_overflow=false;for(var i=0,len=data.length;i<len;i++){ctx.fillStyle=ctx.strokeStyle=painter_color;top_overflow=bot_overflow=false;x_scaled=Math.round((data[i][0]-view_start)*w_scale);y=data[i][1];if(y===null){if(in_path&&mode==="Filled"){ctx.lineTo(x_scaled,height_px)}in_path=false;continue}if(y<min_value){bot_overflow=true;y=min_value}else{if(y>max_value){top_overflow=true;y=max_value}}if(mode==="Histogram"){y=Math.round(y/vertical_range*height_px);ctx.fillRect(x_scaled,y_zero,delta_x_px,-y)}else{if(mode==="Intensity"){var saturation=(y-min_value)/vertical_range,new_r=Math.round(pref_r+(255-pref_r)*(1-saturation)),new_g=Math.round(pref_g+(255-pref_g)*(1-saturation)),new_b=Math.round(pref_b+(255-pref_b)*(1-saturation));ctx.fillStyle="rgb("+new_r+","+new_g+","+new_b+")";ctx.fillRect(x_scaled,0,delta_x_px,height_px)}else{y=Math.round(height_px-(y-min_value)/vertical_range*height_px);if(in_path){ctx.lineTo(x_scaled,y)}else{in_path=true;if(mode==="Filled"){ctx.moveTo(x_scaled,height_px);ctx.lineTo(x_scaled,y)}else{ctx.moveTo(x_scaled,y)}}}}ctx.fillStyle=this.prefs.overflow_color;if(top_overflow||bot_overflow){var overflow_x;if(mode==="Histogram"||mode==="Intensity"){overflow_x=delta_x_px}else{x_scaled-=2;overflow_x=4}if(top_overflow){ctx.fillRect(x_scaled,0,overflow_x,3)}if(bot_overflow){ctx.fillRect(x_scaled,height_px-3,overflow_x,3)}}ctx.fillStyle=painter_color}if(mode==="Filled"){if(in_path){ctx.lineTo(x_scaled,y_zero);ctx.lineTo(0,y_zero)}ctx.fill()}else{ctx.stroke()}ctx.restore()};var FeaturePositionMapper=function(slot_height){this.feature_positions={};this.slot_height=slot_height;this.translation=0;this.y_translation=0};FeaturePositionMapper.prototype.map_feature_data=function(feature_data,slot,x_start,x_end){if(!this.feature_positions[slot]){this.feature_positions[slot]=[]}this.feature_positions[slot].push({data:feature_data,x_start:x_start,x_end:x_end})};FeaturePositionMapper.prototype.get_feature_data=function(x,y){var slot=Math.floor((y-this.y_translation)/this.slot_height),feature_dict;if(!this.feature_positions[slot]){return null}x+=this.translation;for(var i=0;i<this.feature_positions[slot].length;i++){feature_dict=this.feature_positions[slot][i];if(x>=feature_dict.x_start&&x<=feature_dict.x_end){return feature_dict.data}}};var FeaturePainter=function(data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler){Painter.call(this,data,view_start,view_end,prefs,mode);this.alpha_scaler=(alpha_scaler?alpha_scaler:new Scaler());this.height_scaler=(height_scaler?height_scaler:new Scaler())};FeaturePainter.prototype.default_prefs={block_color:"#FFF",connector_color:"#FFF"};extend(FeaturePainter.prototype,{get_required_height:function(rows_required,width){var required_height=this.get_row_height(),y_scale=required_height,mode=this.mode;if(mode==="no_detail"||mode==="Squish"||mode==="Pack"){required_height=rows_required*y_scale}return required_height+this.get_top_padding(width)},get_top_padding:function(width){return 0},draw:function(ctx,width,height,w_scale,slots){var data=this.data,view_start=this.view_start,view_end=this.view_end;ctx.save();ctx.fillStyle=this.prefs.block_color;ctx.textAlign="right";var y_scale=this.get_row_height(),feature_mapper=new FeaturePositionMapper(y_scale),x_draw_coords;for(var i=0,len=data.length;i<len;i++){var feature=data[i],feature_uid=feature[0],feature_start=feature[1],feature_end=feature[2],slot=(slots&&slots[feature_uid]!==undefined?slots[feature_uid]:null);if((feature_start<view_end&&feature_end>view_start)&&(this.mode==="Dense"||slot!==null)){x_draw_coords=this.draw_element(ctx,this.mode,feature,slot,view_start,view_end,w_scale,y_scale,width);feature_mapper.map_feature_data(feature,slot,x_draw_coords[0],x_draw_coords[1])}}ctx.restore();feature_mapper.y_translation=this.get_top_padding(width);return feature_mapper},draw_element:function(ctx,mode,feature,slot,tile_low,tile_high,w_scale,y_scale,width){return[0,0]}});var DENSE_TRACK_HEIGHT=10,NO_DETAIL_TRACK_HEIGHT=3,SQUISH_TRACK_HEIGHT=5,PACK_TRACK_HEIGHT=10,NO_DETAIL_FEATURE_HEIGHT=1,DENSE_FEATURE_HEIGHT=9,SQUISH_FEATURE_HEIGHT=3,PACK_FEATURE_HEIGHT=9,LABEL_SPACING=2,CONNECTOR_COLOR="#ccc";var LinkedFeaturePainter=function(data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler){FeaturePainter.call(this,data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler);this.draw_background_connector=true;this.draw_individual_connectors=false};extend(LinkedFeaturePainter.prototype,FeaturePainter.prototype,{get_row_height:function(){var mode=this.mode,height;if(mode==="Dense"){height=DENSE_TRACK_HEIGHT}else{if(mode==="no_detail"){height=NO_DETAIL_TRACK_HEIGHT}else{if(mode==="Squish"){height=SQUISH_TRACK_HEIGHT}else{height=PACK_TRACK_HEIGHT}}}return height},draw_element:function(ctx,mode,feature,slot,tile_low,tile_high,w_scale,y_scale,width){var feature_uid=feature[0],feature_start=feature[1],feature_end=feature[2],feature_name=feature[3],feature_strand=feature[4],f_start=Math.floor(Math.max(0,(feature_start-tile_low-0.5)*w_scale)),f_end=Math.ceil(Math.min(width,Math.max(0,(feature_end-tile_low-0.5)*w_scale))),draw_start=f_start,draw_end=f_end,y_start=(mode==="Dense"?0:(0+slot))*y_scale+this.get_top_padding(width),thickness,y_start,thick_start=null,thick_end=null,block_color=(!feature_strand||feature_strand==="+"||feature_strand==="."?this.prefs.block_color:this.prefs.reverse_strand_color);label_color=this.prefs.label_color;ctx.globalAlpha=this.alpha_scaler.gen_val(feature);if(mode==="Dense"){slot=1}if(mode==="no_detail"){ctx.fillStyle=block_color;ctx.fillRect(f_start,y_start+5,f_end-f_start,NO_DETAIL_FEATURE_HEIGHT)}else{var feature_ts=feature[5],feature_te=feature[6],feature_blocks=feature[7],full_height=true;if(feature_ts&&feature_te){thick_start=Math.floor(Math.max(0,(feature_ts-tile_low)*w_scale));thick_end=Math.ceil(Math.min(width,Math.max(0,(feature_te-tile_low)*w_scale)))}var thin_height,thick_height;if(mode==="Squish"){thin_height=1;thick_height=SQUISH_FEATURE_HEIGHT;full_height=false}else{if(mode==="Dense"){thin_height=5;thick_height=DENSE_FEATURE_HEIGHT}else{thin_height=5;thick_height=PACK_FEATURE_HEIGHT}}if(!feature_blocks){ctx.fillStyle=block_color;ctx.fillRect(f_start,y_start+1,f_end-f_start,thick_height);if(feature_strand&&full_height){if(feature_strand==="+"){ctx.fillStyle=ctx.canvas.manager.get_pattern("right_strand_inv")}else{if(feature_strand==="-"){ctx.fillStyle=ctx.canvas.manager.get_pattern("left_strand_inv")}}ctx.fillRect(f_start,y_start+1,f_end-f_start,thick_height)}}else{var cur_y_start,cur_height;if(mode==="Squish"||mode==="Dense"){cur_y_start=y_start+Math.floor(SQUISH_FEATURE_HEIGHT/2)+1;cur_height=1}else{if(feature_strand){cur_y_start=y_start;cur_height=thick_height}else{cur_y_start+=(SQUISH_FEATURE_HEIGHT/2)+1;cur_height=1}}if(this.draw_background_connector){if(mode==="Squish"||mode==="Dense"){ctx.fillStyle=CONNECTOR_COLOR}else{if(feature_strand){if(feature_strand==="+"){ctx.fillStyle=ctx.canvas.manager.get_pattern("right_strand")}else{if(feature_strand==="-"){ctx.fillStyle=ctx.canvas.manager.get_pattern("left_strand")}}}else{ctx.fillStyle=CONNECTOR_COLOR}}ctx.fillRect(f_start,cur_y_start,f_end-f_start,cur_height)}var start_and_height;for(var k=0,k_len=feature_blocks.length;k<k_len;k++){var block=feature_blocks[k],block_start=Math.floor(Math.max(0,(block[0]-tile_low-0.5)*w_scale)),block_end=Math.ceil(Math.min(width,Math.max((block[1]-tile_low-0.5)*w_scale))),last_block_start,last_block_end;if(block_start>block_end){continue}ctx.fillStyle=block_color;ctx.fillRect(block_start,y_start+(thick_height-thin_height)/2+1,block_end-block_start,thin_height);if(thick_start!==undefined&&feature_te>feature_ts&&!(block_start>thick_end||block_end<thick_start)){var block_thick_start=Math.max(block_start,thick_start),block_thick_end=Math.min(block_end,thick_end);ctx.fillRect(block_thick_start,y_start+1,block_thick_end-block_thick_start,thick_height);if(feature_blocks.length===1&&mode==="Pack"){if(feature_strand==="+"){ctx.fillStyle=ctx.canvas.manager.get_pattern("right_strand_inv")}else{if(feature_strand==="-"){ctx.fillStyle=ctx.canvas.manager.get_pattern("left_strand_inv")}}if(block_thick_start+14<block_thick_end){block_thick_start+=2;block_thick_end-=2}ctx.fillRect(block_thick_start,y_start+1,block_thick_end-block_thick_start,thick_height)}}if(this.draw_individual_connectors&&last_block_start){this.draw_connector(ctx,last_block_start,last_block_end,block_start,block_end,y_start)}last_block_start=block_start;last_block_end=block_end}if(mode==="Pack"){ctx.globalAlpha=1;ctx.fillStyle="white";var hscale_factor=this.height_scaler.gen_val(feature),new_height=Math.ceil(thick_height*hscale_factor),ws_height=Math.round((thick_height-new_height)/2);if(hscale_factor!==1){ctx.fillRect(f_start,cur_y_start+1,f_end-f_start,ws_height);ctx.fillRect(f_start,cur_y_start+thick_height-ws_height+1,f_end-f_start,ws_height)}}}ctx.globalAlpha=1;if(feature_name&&mode==="Pack"&&feature_start>tile_low){ctx.fillStyle=label_color;if(tile_low===0&&f_start-ctx.measureText(feature_name).width<0){ctx.textAlign="left";ctx.fillText(feature_name,f_end+LABEL_SPACING,y_start+8);draw_end+=ctx.measureText(feature_name).width+LABEL_SPACING}else{ctx.textAlign="right";ctx.fillText(feature_name,f_start-LABEL_SPACING,y_start+8);draw_start-=ctx.measureText(feature_name).width+LABEL_SPACING}}}ctx.globalAlpha=1;return[draw_start,draw_end]}});var ReadPainter=function(data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler,ref_seq,base_color_fn){FeaturePainter.call(this,data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler);this.ref_seq=(ref_seq?ref_seq.data:null);this.base_color_fn=base_color_fn};extend(ReadPainter.prototype,FeaturePainter.prototype,{get_row_height:function(){var height,mode=this.mode;if(mode==="Dense"){height=DENSE_TRACK_HEIGHT}else{if(mode==="Squish"){height=SQUISH_TRACK_HEIGHT}else{height=PACK_TRACK_HEIGHT;if(this.prefs.show_insertions){height*=2}}}return height},_parse_cigar:function(cigar_str){var cigar_ops="MIDNSHP=X";var blocks=[[0,0]],cur_block=blocks[0],base_pos=0,parsed_cigar=_.map(cigar_str.match(/[0-9]+[MIDNSHP=X]/g),function(op){var op_len=parseInt(op.slice(0,-1),10),op_char=op.slice(-1);if(op_char==="N"){if(cur_block[1]!==0){cur_block=[base_pos+op_len,base_pos+op_len];blocks.push(cur_block)}}else{if("ISHP".indexOf(op_char)===-1){cur_block[1]+=op_len;base_pos+=op_len}}return[cigar_ops.indexOf(op_char),op_len]});return{blocks:blocks,cigar:parsed_cigar}},draw_read:function(ctx,mode,w_scale,y_start,tile_low,tile_high,feature_start,cigar,strand,read_seq){ctx.textAlign="center";var tile_region=[tile_low,tile_high],base_offset=0,seq_offset=0,gap=Math.round(w_scale/2),char_width_px=ctx.canvas.manager.char_width_px,block_color=(strand==="+"?this.prefs.block_color:this.prefs.reverse_strand_color),pack_mode=(mode==="Pack"),paint_utils=new ReadPainterUtils(ctx,(pack_mode?PACK_FEATURE_HEIGHT:SQUISH_FEATURE_HEIGHT),w_scale,mode);var draw_last=[];if(!cigar){cigar=[[0,read_seq.length]]}for(var cig_id=0,len=cigar.length;cig_id<len;cig_id++){var cig=cigar[cig_id],cig_op="MIDNSHP=X"[cig[0]],cig_len=cig[1];var seq_start=feature_start+base_offset,s_start=Math.floor(Math.max(-0.5*w_scale,(seq_start-tile_low-0.5)*w_scale)),s_end=Math.floor(Math.max(0,(seq_start+cig_len-tile_low-0.5)*w_scale));if(!is_overlap([seq_start,seq_start+cig_len],tile_region)){if("MDN=X".indexOf(cig_op)!==-1){base_offset+=cig_len}continue}if(s_start===s_end){s_end+=1}switch(cig_op){case"H":break;case"S":seq_offset+=cig_len;break;case"M":case"=":case"X":ctx.fillStyle=block_color;ctx.fillRect(s_start,y_start+(pack_mode?1:4),s_end-s_start,(pack_mode?PACK_FEATURE_HEIGHT:SQUISH_FEATURE_HEIGHT));var seq=read_seq.slice(seq_offset,seq_offset+cig_len),ref_char,read_char;for(var c=0,str_len=seq.length;c<str_len;c++){if(seq_start+c>=tile_low&&seq_start+c<=tile_high){ref_char=(this.ref_seq?this.ref_seq[seq_start-tile_low+c]:null);read_char=seq[c];if((ref_char&&(!this.prefs.show_differences||(read_char.toLowerCase!=="n"&&(ref_char.toLowerCase()!==read_char.toLowerCase()))))||(!ref_char&&!this.prefs.show_differences)){var c_start=Math.floor(Math.max(0,(seq_start+c-tile_low)*w_scale));ctx.fillStyle=this.base_color_fn(seq[c]);if(pack_mode&&w_scale>char_width_px){ctx.fillText(seq[c],c_start,y_start+9)}else{if(w_scale>0.05){ctx.fillRect(c_start-gap,y_start+(pack_mode?1:4),Math.max(1,Math.round(w_scale)),(pack_mode?PACK_FEATURE_HEIGHT:SQUISH_FEATURE_HEIGHT))}}}}}seq_offset+=cig_len;base_offset+=cig_len;break;case"N":ctx.fillStyle=CONNECTOR_COLOR;ctx.fillRect(s_start,y_start+5,s_end-s_start,1);base_offset+=cig_len;break;case"D":paint_utils.draw_deletion(s_start,y_start,1);base_offset+=cig_len;break;case"P":break;case"I":var insert_x_coord=s_start-gap;if(is_overlap([seq_start,seq_start+cig_len],tile_region)){var seq=read_seq.slice(seq_offset,seq_offset+cig_len);if(this.prefs.show_insertions){var x_center=s_start-(s_end-s_start)/2;if((mode==="Pack"||this.mode==="Auto")&&read_seq!==undefined&&w_scale>char_width_px){ctx.fillStyle="yellow";ctx.fillRect(x_center-gap,y_start-9,s_end-s_start,9);draw_last[draw_last.length]={type:"triangle",data:[insert_x_coord,y_start+4,5]};ctx.fillStyle=CONNECTOR_COLOR;switch(compute_overlap([seq_start,seq_start+cig_len],tile_region)){case (OVERLAP_START):seq=seq.slice(tile_low-seq_start);break;case (OVERLAP_END):seq=seq.slice(0,seq_start-tile_high);break;case (CONTAINED_BY):break;case (CONTAINS):seq=seq.slice(tile_low-seq_start,seq_start-tile_high);break}for(var c=0,str_len=seq.length;c<str_len;c++){var c_start=Math.floor(Math.max(0,(seq_start+c-tile_low)*w_scale));ctx.fillText(seq[c],c_start-(s_end-s_start)/2,y_start)}}else{ctx.fillStyle="yellow";ctx.fillRect(x_center,y_start+(this.mode!=="Dense"?2:5),s_end-s_start,(mode!=="Dense"?SQUISH_FEATURE_HEIGHT:DENSE_FEATURE_HEIGHT))}}else{if((mode==="Pack"||this.mode==="Auto")&&read_seq!==undefined&&w_scale>char_width_px){draw_last.push({type:"text",data:[seq.length,insert_x_coord,y_start+9]})}else{}}}seq_offset+=cig_len;break}}ctx.fillStyle="yellow";var item,type,data;for(var i=0;i<draw_last.length;i++){item=draw_last[i];type=item.type;data=item.data;if(type==="text"){ctx.save();ctx.font="bold "+ctx.font;ctx.fillText(data[0],data[1],data[2]);ctx.restore()}else{if(type==="triangle"){drawDownwardEquilateralTriangle(ctx,data[0],data[1],data[2])}}}},draw_element:function(ctx,mode,feature,slot,tile_low,tile_high,w_scale,y_scale,width){var feature_uid=feature[0],feature_start=feature[1],feature_end=feature[2],feature_name=feature[3],f_start=Math.floor(Math.max(-0.5*w_scale,(feature_start-tile_low-0.5)*w_scale)),f_end=Math.ceil(Math.min(width,Math.max(0,(feature_end-tile_low-0.5)*w_scale))),y_start=(mode==="Dense"?0:(0+slot))*y_scale,label_color=this.prefs.label_color;if(feature[5] instanceof Array){var connector=true;if(feature[4][1]>=tile_low&&feature[4][0]<=tile_high&&feature[4][2]){this.draw_read(ctx,mode,w_scale,y_start,tile_low,tile_high,feature[4][0],feature[4][2],feature[4][3],feature[4][4])}else{connector=false}if(feature[5][1]>=tile_low&&feature[5][0]<=tile_high&&feature[5][2]){this.draw_read(ctx,mode,w_scale,y_start,tile_low,tile_high,feature[5][0],feature[5][2],feature[5][3],feature[5][4])}else{connector=false}var b1_end=Math.ceil(Math.min(width,Math.max(-0.5*w_scale,(feature[4][1]-tile_low-0.5)*w_scale))),b2_start=Math.floor(Math.max(-0.5*w_scale,(feature[5][0]-tile_low-0.5)*w_scale));if(connector&&b2_start>b1_end){ctx.fillStyle=CONNECTOR_COLOR;dashedLine(ctx,b1_end,y_start+5,b2_start,y_start+5)}}else{this.draw_read(ctx,mode,w_scale,y_start,tile_low,tile_high,feature_start,feature[4],feature[5],feature[6])}if(mode==="Pack"&&feature_start>=tile_low&&feature_name!=="."){ctx.fillStyle=this.prefs.label_color;if(tile_low===0&&f_start-ctx.measureText(feature_name).width<0){ctx.textAlign="left";ctx.fillText(feature_name,f_end+LABEL_SPACING,y_start+8)}else{ctx.textAlign="right";ctx.fillText(feature_name,f_start-LABEL_SPACING,y_start+8)}}return[0,0]}});var RefBasedReadPainter=function(data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler,ref_seq,base_color_fn){ReadPainter.call(this,data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler,ref_seq,base_color_fn)};extend(RefBasedReadPainter.prototype,ReadPainter.prototype,FeaturePainter,{draw_read:function(ctx,mode,w_scale,y_start,tile_low,tile_high,feature_start,cigar,strand,read_seq){ctx.textAlign="center";var tile_region=[tile_low,tile_high],base_offset=0,seq_offset=0,gap=Math.round(w_scale/2),char_width_px=ctx.canvas.manager.char_width_px,block_color=(strand==="+"?this.prefs.block_color:this.prefs.reverse_strand_color),pack_mode=(mode==="Pack"),paint_utils=new ReadPainterUtils(ctx,(pack_mode?PACK_FEATURE_HEIGHT:SQUISH_FEATURE_HEIGHT),w_scale,mode),drawing_blocks=[];var draw_last=[];var t=this._parse_cigar(cigar);cigar=t.cigar;drawing_blocks=t.blocks;for(var i=0;i<drawing_blocks.length;i++){var block=drawing_blocks[i];if(is_overlap([feature_start+block[0],feature_start+block[1]],tile_region)){var s_start=Math.floor(Math.max(-0.5*w_scale,(feature_start+block[0]-tile_low-0.5)*w_scale)),s_end=Math.floor(Math.max(0,(feature_start+block[1]-tile_low-0.5)*w_scale));if(s_start===s_end){s_end+=1}ctx.fillStyle=block_color;ctx.fillRect(s_start,y_start+(pack_mode?1:4),s_end-s_start,(pack_mode?PACK_FEATURE_HEIGHT:SQUISH_FEATURE_HEIGHT))}}for(var cig_id=0,len=cigar.length;cig_id<len;cig_id++){var cig=cigar[cig_id],cig_op="MIDNSHP=X"[cig[0]],cig_len=cig[1];var seq_start=feature_start+base_offset,s_start=Math.floor(Math.max(0,-0.5*w_scale,(seq_start-tile_low-0.5)*w_scale)),s_end=Math.floor(Math.max(0,(seq_start+cig_len-tile_low-0.5)*w_scale));if(!is_overlap([seq_start,seq_start+cig_len],tile_region)){continue}if(s_start===s_end){s_end+=1}switch(cig_op){case"H":case"S":case"P":break;case"M":base_offset+=cig_len;break;case"=":case"X":var cur_seq="";if(cig_op==="X"){cur_seq=read_seq.slice(seq_offset,seq_offset+cig_len)}else{if(this.ref_seq){cur_seq=this.ref_seq.slice(Math.max(0,seq_start-tile_low),Math.min(seq_start-tile_low+cig_len,tile_high-tile_low))}}var start_pos=Math.max(seq_start,tile_low);for(var c=0;c<cur_seq.length;c++){if(cur_seq&&!this.prefs.show_differences||cig_op==="X"){var c_start=Math.floor(Math.max(0,(start_pos+c-tile_low)*w_scale));ctx.fillStyle=this.base_color_fn(cur_seq[c]);if(pack_mode&&w_scale>char_width_px){ctx.fillText(cur_seq[c],c_start,y_start+9)}else{if(w_scale>0.05){ctx.fillRect(c_start-gap,y_start+(pack_mode?1:4),Math.max(1,Math.round(w_scale)),(pack_mode?PACK_FEATURE_HEIGHT:SQUISH_FEATURE_HEIGHT))}}}}if(cig_op==="X"){seq_offset+=cig_len}base_offset+=cig_len;break;case"N":ctx.fillStyle=CONNECTOR_COLOR;ctx.fillRect(s_start,y_start+5,s_end-s_start,1);base_offset+=cig_len;break;case"D":paint_utils.draw_deletion(s_start,y_start+(pack_mode?1:4),cig_len);base_offset+=cig_len;break;case"I":var insert_x_coord=s_start-gap;if(is_overlap([seq_start,seq_start+cig_len],tile_region)){var seq=read_seq.slice(seq_offset,seq_offset+cig_len);if(this.prefs.show_insertions){var x_center=s_start-(s_end-s_start)/2;if((mode==="Pack"||this.mode==="Auto")&&read_seq!==undefined&&w_scale>char_width_px){ctx.fillStyle="yellow";ctx.fillRect(x_center-gap,y_start-9,s_end-s_start,9);draw_last[draw_last.length]={type:"triangle",data:[insert_x_coord,y_start+4,5]};ctx.fillStyle=CONNECTOR_COLOR;switch(compute_overlap([seq_start,seq_start+cig_len],tile_region)){case (OVERLAP_START):seq=seq.slice(tile_low-seq_start);break;case (OVERLAP_END):seq=seq.slice(0,seq_start-tile_high);break;case (CONTAINED_BY):break;case (CONTAINS):seq=seq.slice(tile_low-seq_start,seq_start-tile_high);break}for(var c=0,str_len=seq.length;c<str_len;c++){var c_start=Math.floor(Math.max(0,(seq_start+c-tile_low)*w_scale));ctx.fillText(seq[c],c_start-(s_end-s_start)/2,y_start)}}else{ctx.fillStyle="yellow";ctx.fillRect(x_center,y_start+(this.mode!=="Dense"?2:5),s_end-s_start,(mode!=="Dense"?SQUISH_FEATURE_HEIGHT:DENSE_FEATURE_HEIGHT))}}else{if((mode==="Pack"||this.mode==="Auto")&&read_seq!==undefined&&w_scale>char_width_px){draw_last.push({type:"text",data:[seq.length,insert_x_coord,y_start+9]})}else{}}}seq_offset+=cig_len;break}}ctx.fillStyle="yellow";var item,type,data;for(var i=0;i<draw_last.length;i++){item=draw_last[i];type=item.type;data=item.data;if(type==="text"){ctx.save();ctx.font="bold "+ctx.font;ctx.fillText(data[0],data[1],data[2]);ctx.restore()}else{if(type==="triangle"){drawDownwardEquilateralTriangle(ctx,data[0],data[1],data[2])}}}}});var ArcLinkedFeaturePainter=function(data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler){LinkedFeaturePainter.call(this,data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler);this.longest_feature_length=this.calculate_longest_feature_length();this.draw_background_connector=false;this.draw_individual_connectors=true};extend(ArcLinkedFeaturePainter.prototype,FeaturePainter.prototype,LinkedFeaturePainter.prototype,{calculate_longest_feature_length:function(){var longest_feature_length=0;for(var i=0,len=this.data.length;i<len;i++){var feature=this.data[i],feature_start=feature[1],feature_end=feature[2];longest_feature_length=Math.max(longest_feature_length,feature_end-feature_start)}return longest_feature_length},get_top_padding:function(width){var view_range=this.view_end-this.view_start,w_scale=width/view_range;return Math.min(128,Math.ceil((this.longest_feature_length/2)*w_scale))},draw_connector:function(ctx,block1_start,block1_end,block2_start,block2_end,y_start){var x_center=(block1_end+block2_start)/2,radius=block2_start-x_center;var angle1=Math.PI,angle2=0;if(radius>0){ctx.beginPath();ctx.arc(x_center,y_start,block2_start-x_center,Math.PI,0);ctx.stroke()}}});var Color=function(rgb,a){if(Array.isArray(rgb)){this.rgb=rgb}else{if(rgb.length==6){this.rgb=rgb.match(/.{2}/g).map(function(c){return parseInt(c,16)})}else{if(rgb.length==7){this.rgb=rgb.substring(1,7).match(/.{2}/g).map(function(c){return parseInt(c,16)})}else{this.rgb=rgb.split("").map(function(c){return parseInt(c+c,16)})}}}this.alpha=typeof(a)==="number"?a:1};Color.prototype={eval:function(){return this},toCSS:function(){if(this.alpha<1){return"rgba("+this.rgb.map(function(c){return Math.round(c)}).concat(this.alpha).join(", ")+")"}else{return"#"+this.rgb.map(function(i){i=Math.round(i);i=(i>255?255:(i<0?0:i)).toString(16);return i.length===1?"0"+i:i}).join("")}},toHSL:function(){var r=this.rgb[0]/255,g=this.rgb[1]/255,b=this.rgb[2]/255,a=this.alpha;var max=Math.max(r,g,b),min=Math.min(r,g,b);var h,s,l=(max+min)/2,d=max-min;if(max===min){h=s=0}else{s=l>0.5?d/(2-max-min):d/(max+min);switch(max){case r:h=(g-b)/d+(g<b?6:0);break;case g:h=(b-r)/d+2;break;case b:h=(r-g)/d+4;break}h/=6}return{h:h*360,s:s,l:l,a:a}},toARGB:function(){var argb=[Math.round(this.alpha*255)].concat(this.rgb);return"#"+argb.map(function(i){i=Math.round(i);i=(i>255?255:(i<0?0:i)).toString(16);return i.length===1?"0"+i:i}).join("")},mix:function(color2,weight){color1=this;var p=weight;var w=p*2-1;var a=color1.toHSL().a-color2.toHSL().a;var w1=(((w*a==-1)?w:(w+a)/(1+w*a))+1)/2;var w2=1-w1;var rgb=[color1.rgb[0]*w1+color2.rgb[0]*w2,color1.rgb[1]*w1+color2.rgb[1]*w2,color1.rgb[2]*w1+color2.rgb[2]*w2];var alpha=color1.alpha*p+color2.alpha*(1-p);return new Color(rgb,alpha)}};var LinearRamp=function(start_color,end_color,start_value,end_value){this.start_color=new Color(start_color);this.end_color=new Color(end_color);this.start_value=start_value;this.end_value=end_value;this.value_range=end_value-start_value};LinearRamp.prototype.map_value=function(value){value=Math.max(value,this.start_value);value=Math.min(value,this.end_value);value=(value-this.start_value)/this.value_range;return this.start_color.mix(this.end_color,1-value).toCSS()};var SplitRamp=function(start_color,middle_color,end_color,start_value,end_value){this.positive_ramp=new LinearRamp(middle_color,end_color,0,end_value);this.negative_ramp=new LinearRamp(middle_color,start_color,0,-start_value);this.start_value=start_value;this.end_value=end_value};SplitRamp.prototype.map_value=function(value){value=Math.max(value,this.start_value);value=Math.min(value,this.end_value);if(value>=0){return this.positive_ramp.map_value(value)}else{return this.negative_ramp.map_value(-value)}};var DiagonalHeatmapPainter=function(data,view_start,view_end,prefs,mode){Painter.call(this,data,view_start,view_end,prefs,mode);var i,len;if(this.prefs.min_value===undefined){var min_value=Infinity;for(i=0,len=this.data.length;i<len;i++){min_value=Math.min(min_value,this.data[i][5])}this.prefs.min_value=min_value}if(this.prefs.max_value===undefined){var max_value=-Infinity;for(i=0,len=this.data.length;i<len;i++){max_value=Math.max(max_value,this.data[i][5])}this.prefs.max_value=max_value}};DiagonalHeatmapPainter.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Heatmap",pos_color:"#FF8C00",neg_color:"#4169E1"};DiagonalHeatmapPainter.prototype.draw=function(ctx,width,height,w_scale){var min_value=this.prefs.min_value,max_value=this.prefs.max_value,value_range=max_value-min_value,height_px=height,view_start=this.view_start,mode=this.mode,data=this.data,invsqrt2=1/Math.sqrt(2);var ramp=(new SplitRamp(this.prefs.neg_color,"#FFFFFF",this.prefs.pos_color,min_value,max_value));var d,s1,e1,s2,e2,value;var scale=function(p){return(p-view_start)*w_scale};ctx.save();ctx.rotate(-45*Math.PI/180);ctx.scale(invsqrt2,invsqrt2);for(var i=0,len=data.length;i<len;i++){d=data[i];s1=scale(d[1]);e1=scale(d[2]);s2=scale(d[4]);e2=scale(d[5]);value=d[6];ctx.fillStyle=(ramp.map_value(value));ctx.fillRect(s1,s2,(e1-s1),(e2-s2))}ctx.restore()};var ReadPainterUtils=function(ctx,row_height,px_per_base,mode){this.ctx=ctx;this.row_height=row_height;this.px_per_base=px_per_base;this.draw_details=(mode==="Pack"||mode==="Auto")&&(px_per_base>=ctx.canvas.manager.char_width_px);this.delete_details_thickness=0.2};extend(ReadPainterUtils.prototype,{draw_deletion:function(x,y,len){this.ctx.fillStyle="black";var thickness=(this.draw_details?this.delete_details_thickness:1)*this.row_height;y+=0.5*(this.row_height-thickness);this.ctx.fillRect(x,y,len*this.px_per_base,thickness)}});var VariantPainter=function(data,view_start,view_end,prefs,mode,base_color_fn){Painter.call(this,data,view_start,view_end,prefs,mode);this.base_color_fn=base_color_fn;this.divider_height=1};extend(VariantPainter.prototype,Painter.prototype,{get_row_height:function(){var mode=this.mode,height;if(mode==="Dense"){height=DENSE_TRACK_HEIGHT}else{if(mode==="Squish"){height=SQUISH_TRACK_HEIGHT}else{height=PACK_TRACK_HEIGHT}}return height},get_required_height:function(num_samples){var height=this.prefs.summary_height;if(num_samples>1&&this.prefs.show_sample_data){height+=this.divider_height+num_samples*this.get_row_height()}return height},draw:function(ctx,width,height,w_scale){ctx.save();var get_deletion_info=function(ref,alt){var ref_len=ref.length,alt_len=alt.length,start=0,len=1,is_delete=false;if(alt==="-"){is_delete=true;len=ref.length}else{if(ref.indexOf(alt)===0&&ref_len>alt_len){is_delete=true;len=ref_len=alt_len;start+=alt_len}}return(is_delete?{start:start,len:len}:null)};var locus_data,pos,id,ref,alt,qual,filter,sample_gts,allele_counts,variant,draw_x_start,char_x_start,draw_y_start,genotype,base_px=Math.max(1,Math.floor(w_scale)),num_samples=(this.data.length?this.data[0][7].split(",").length:0),row_height=(this.mode==="Squish"?SQUISH_TRACK_HEIGHT:PACK_TRACK_HEIGHT),feature_height=(w_scale<0.1?row_height:(this.mode==="Squish"?SQUISH_FEATURE_HEIGHT:PACK_FEATURE_HEIGHT)),draw_summary=true,paint_utils=new ReadPainterUtils(ctx,row_height,w_scale,this.mode),j;if(num_samples===1){row_height=feature_height=(w_scale<ctx.canvas.manager.char_width_px?this.prefs.summary_height:row_height);draw_summary=false}if(this.prefs.show_sample_data&&draw_summary){ctx.fillStyle="#F3F3F3";ctx.globalAlpha=1;ctx.fillRect(0,this.prefs.summary_height-this.divider_height,width,this.divider_height)}ctx.textAlign="center";for(var i=0;i<this.data.length;i++){locus_data=this.data[i];pos=locus_data[1];ref=locus_data[3];alt=[locus_data[4].split(",")];sample_gts=locus_data[7].split(",");allele_counts=locus_data.slice(8);alt=_.map(_.flatten(alt),function(a){var type,alt_info={},delete_info=get_deletion_info(ref,a);if(delete_info){type="deletion";_.extend(alt_info,delete_info)}else{type="snp"}return _.extend(alt_info,{type:type,value:a,})});if(pos<this.view_start||pos>this.view_end){continue}draw_x_start=Math.floor(Math.max(-0.5*w_scale,(pos-this.view_start-0.5)*w_scale));char_x_start=Math.floor(Math.max(0,(pos-this.view_start)*w_scale));if(draw_summary){ctx.fillStyle="#999999";ctx.globalAlpha=1;ctx.fillRect(draw_x_start,0,base_px,this.prefs.summary_height);draw_y_start=this.prefs.summary_height;for(j=0;j<alt.length;j++){ctx.fillStyle=(alt[j].type==="deletion"?"black":this.base_color_fn(alt[j].value));allele_frac=allele_counts/sample_gts.length;draw_height=Math.ceil(this.prefs.summary_height*allele_frac);ctx.fillRect(draw_x_start,draw_y_start-draw_height,base_px,draw_height);draw_y_start-=draw_height}}if(!this.prefs.show_sample_data){continue}draw_y_start=(draw_summary?this.prefs.summary_height+this.divider_height:0);for(j=0;j<sample_gts.length;j++,draw_y_start+=row_height){genotype=(sample_gts[j]?sample_gts[j].split(/\/|\|/):["0","0"]);variant=null;if(genotype[0]===genotype[1]){if(genotype[0]==="."){}else{if(genotype[0]!=="0"){variant=alt[parseInt(genotype[0],10)-1];ctx.globalAlpha=1}}}else{variant=(genotype[0]!=="0"?genotype[0]:genotype[1]);variant=alt[parseInt(variant,10)-1];ctx.globalAlpha=0.5}if(variant){if(variant.type==="snp"){var snp=variant.value;ctx.fillStyle=this.base_color_fn(snp);if(paint_utils.draw_details){ctx.fillText(snp,char_x_start,draw_y_start+row_height)}else{ctx.fillRect(draw_x_start,draw_y_start+1,base_px,feature_height)}}else{if(variant.type==="deletion"){paint_utils.draw_deletion(draw_x_start+base_px*variant.start,draw_y_start+1,variant.len)}else{}}}}}ctx.restore()}});return{Scaler:Scaler,LinePainter:LinePainter,LinkedFeaturePainter:LinkedFeaturePainter,ReadPainter:ReadPainter,RefBasedReadPainter:RefBasedReadPainter,ArcLinkedFeaturePainter:ArcLinkedFeaturePainter,DiagonalHeatmapPainter:DiagonalHeatmapPainter,VariantPainter:VariantPainter}});
\ 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
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/fcf498d29780/
Changeset: fcf498d29780
User: guerler
Date: 2014-01-24 05:40:40
Summary: Frame: Add widget option to frames
Affected #: 2 files
diff -r ce250b678c13cabd72f13e3ed118976b7fcb4fe8 -r fcf498d297805f3ba634582de24991b99e510d6e lib/galaxy/datatypes/tabular.py
--- a/lib/galaxy/datatypes/tabular.py
+++ b/lib/galaxy/datatypes/tabular.py
@@ -275,7 +275,7 @@
cursor = f.read(1)
return to_json_string( { 'ck_data': util.unicodify( ck_data ), 'ck_index': ck_index + 1 } )
- def display_data(self, trans, dataset, preview=False, filename=None, to_ext=None, chunk=None):
+ def display_data(self, trans, dataset, preview=False, filename=None, to_ext=None, chunk=None, **kwd):
preview = util.string_as_bool( preview )
if chunk:
return self.get_chunk(trans, dataset, chunk)
diff -r ce250b678c13cabd72f13e3ed118976b7fcb4fe8 -r fcf498d297805f3ba634582de24991b99e510d6e static/scripts/galaxy.frame.js
--- a/static/scripts/galaxy.frame.js
+++ b/static/scripts/galaxy.frame.js
@@ -1096,6 +1096,11 @@
// identify content type
if (type == 'url') {
+ if (content.indexOf('?') == -1)
+ content += '?';
+ else
+ content += '&';
+ content += 'widget=True';
content = '<iframe scrolling="auto" class="f-iframe" src="' + content + '"></iframe>';
}
https://bitbucket.org/galaxy/galaxy-central/commits/210a768c98bc/
Changeset: 210a768c98bc
User: guerler
Date: 2014-01-24 05:41:17
Summary: merge
Affected #: 2 files
diff -r fcf498d297805f3ba634582de24991b99e510d6e -r 210a768c98bc394eeabd231aac1056733bec9b11 lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -35,7 +35,9 @@
PasswordField, SelectField, TextArea, TextField, WorkflowField,
WorkflowMappingField)
from sqlalchemy.orm import object_session
+from sqlalchemy.orm import joinedload
from sqlalchemy.sql.expression import func
+from sqlalchemy import not_
log = logging.getLogger( __name__ )
@@ -897,6 +899,22 @@
rval = galaxy.datatypes.data.nice_size( rval )
return rval
+ @property
+ def active_datasets_children_and_roles( self ):
+ if not hasattr(self, '_active_datasets_children_and_roles'):
+ db_session = object_session( self )
+ query = db_session.query( HistoryDatasetAssociation ).filter( HistoryDatasetAssociation.table.c.history_id == self.id ). \
+ filter( not_( HistoryDatasetAssociation.deleted ) ). \
+ order_by( HistoryDatasetAssociation.table.c.hid.asc() ). \
+ options(
+ joinedload("children"),
+ joinedload("dataset"),
+ joinedload("dataset.actions"),
+ joinedload("dataset.actions.role"),
+ )
+ self._active_datasets_children_and_roles = query.all()
+ return self._active_datasets_children_and_roles
+
def contents_iter( self, **kwds ):
"""
Fetch filtered list of contents of history.
diff -r fcf498d297805f3ba634582de24991b99e510d6e -r 210a768c98bc394eeabd231aac1056733bec9b11 lib/galaxy/tools/parameters/basic.py
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -1653,7 +1653,7 @@
field.add_option( "%s: (as %s) %s" % ( hid, target_ext, hda_name ), hda.id, selected )
# Also collect children via association object
dataset_collector( hda.children, hid )
- dataset_collector( history.active_datasets, None )
+ dataset_collector( history.active_datasets_children_and_roles, None )
some_data = bool( field.options )
if some_data:
if value is None or len( field.options ) == 1:
@@ -1709,7 +1709,7 @@
most_recent_dataset.append(data)
# Also collect children via association object
dataset_collector( data.children )
- dataset_collector( history.datasets )
+ dataset_collector( history.active_datasets_children_and_roles )
most_recent_dataset.reverse()
if already_used is not None:
for val in most_recent_dataset:
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/e950fc8b720a/
Changeset: e950fc8b720a
User: jmchilton
Date: 2014-01-15 21:42:24
Summary: Bug fix related to tool dataset collection of HDA children.
If the parent dataset is deleted don't allow it child to be selected as the initial value for a param when generating state - it won't work anyway because these don't appear in the final selection box.
Affected #: 1 file
diff -r 9fe1a6fc375b3fad14dac271ed8f85e02fc6ef6d -r e950fc8b720ad9db8b27c4599ab947ebfb0bcb7e lib/galaxy/tools/parameters/basic.py
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -1719,7 +1719,7 @@
most_recent_dataset.append(data)
# Also collect children via association object
dataset_collector( data.children )
- dataset_collector( history.datasets )
+ dataset_collector( history.active_datasets )
most_recent_dataset.reverse()
if already_used is not None:
for val in most_recent_dataset:
https://bitbucket.org/galaxy/galaxy-central/commits/0951e07b7486/
Changeset: 0951e07b7486
User: jmchilton
Date: 2014-01-15 21:42:24
Summary: Optimize database access during tool rendering.
Prefetch all children, permission, and role data that will be needed for calculation in first database call. Number of database calls no longer proporational to size of history. 17x speed up on my laptop with ~400 history items - typical tool form update times drop from over 5 seconds to under a third of a second. That is with sqlite database on local SSD, I imagine with remote databases and/or larger histories this speed improvement could be even more significant.
Affected #: 2 files
diff -r e950fc8b720ad9db8b27c4599ab947ebfb0bcb7e -r 0951e07b74866c1539a7df46b051bb431f67acf4 lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -35,7 +35,9 @@
PasswordField, SelectField, TextArea, TextField, WorkflowField,
WorkflowMappingField)
from sqlalchemy.orm import object_session
+from sqlalchemy.orm import joinedload
from sqlalchemy.sql.expression import func
+from sqlalchemy import not_
log = logging.getLogger( __name__ )
@@ -898,6 +900,22 @@
rval = galaxy.datatypes.data.nice_size( rval )
return rval
+ @property
+ def active_datasets_children_and_roles( self ):
+ if not hasattr(self, '_active_datasets_children_and_roles'):
+ db_session = object_session( self )
+ query = db_session.query( HistoryDatasetAssociation ).filter( HistoryDatasetAssociation.table.c.history_id == self.id ). \
+ filter( not_( HistoryDatasetAssociation.deleted ) ). \
+ order_by( HistoryDatasetAssociation.table.c.hid.asc() ). \
+ options(
+ joinedload("children"),
+ joinedload("dataset"),
+ joinedload("dataset.actions"),
+ joinedload("dataset.actions.role"),
+ )
+ self._active_datasets_children_and_roles = query.all()
+ return self._active_datasets_children_and_roles
+
def contents_iter( self, **kwds ):
"""
Fetch filtered list of contents of history.
diff -r e950fc8b720ad9db8b27c4599ab947ebfb0bcb7e -r 0951e07b74866c1539a7df46b051bb431f67acf4 lib/galaxy/tools/parameters/basic.py
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -1655,7 +1655,7 @@
field.add_option( "%s: (as %s) %s" % ( hid, target_ext, hda_name ), hda.id, selected )
# Also collect children via association object
dataset_collector( hda.children, hid )
- dataset_collector( history.active_datasets, None )
+ dataset_collector( history.active_datasets_children_and_roles, None )
some_data = bool( field.options )
if some_data:
if value is None or len( field.options ) == 1:
@@ -1719,7 +1719,7 @@
most_recent_dataset.append(data)
# Also collect children via association object
dataset_collector( data.children )
- dataset_collector( history.active_datasets )
+ dataset_collector( history.active_datasets_children_and_roles )
most_recent_dataset.reverse()
if already_used is not None:
for val in most_recent_dataset:
https://bitbucket.org/galaxy/galaxy-central/commits/581b149358aa/
Changeset: 581b149358aa
User: jmchilton
Date: 2014-01-24 05:40:41
Summary: Merged in jmchilton/galaxy-central-fork-1 (pull request #297)
Optimize database access during tool rendering.
Affected #: 2 files
diff -r ce250b678c13cabd72f13e3ed118976b7fcb4fe8 -r 581b149358aa655dd7c25a460f1ec48093268e93 lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -35,7 +35,9 @@
PasswordField, SelectField, TextArea, TextField, WorkflowField,
WorkflowMappingField)
from sqlalchemy.orm import object_session
+from sqlalchemy.orm import joinedload
from sqlalchemy.sql.expression import func
+from sqlalchemy import not_
log = logging.getLogger( __name__ )
@@ -897,6 +899,22 @@
rval = galaxy.datatypes.data.nice_size( rval )
return rval
+ @property
+ def active_datasets_children_and_roles( self ):
+ if not hasattr(self, '_active_datasets_children_and_roles'):
+ db_session = object_session( self )
+ query = db_session.query( HistoryDatasetAssociation ).filter( HistoryDatasetAssociation.table.c.history_id == self.id ). \
+ filter( not_( HistoryDatasetAssociation.deleted ) ). \
+ order_by( HistoryDatasetAssociation.table.c.hid.asc() ). \
+ options(
+ joinedload("children"),
+ joinedload("dataset"),
+ joinedload("dataset.actions"),
+ joinedload("dataset.actions.role"),
+ )
+ self._active_datasets_children_and_roles = query.all()
+ return self._active_datasets_children_and_roles
+
def contents_iter( self, **kwds ):
"""
Fetch filtered list of contents of history.
diff -r ce250b678c13cabd72f13e3ed118976b7fcb4fe8 -r 581b149358aa655dd7c25a460f1ec48093268e93 lib/galaxy/tools/parameters/basic.py
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -1653,7 +1653,7 @@
field.add_option( "%s: (as %s) %s" % ( hid, target_ext, hda_name ), hda.id, selected )
# Also collect children via association object
dataset_collector( hda.children, hid )
- dataset_collector( history.active_datasets, None )
+ dataset_collector( history.active_datasets_children_and_roles, None )
some_data = bool( field.options )
if some_data:
if value is None or len( field.options ) == 1:
@@ -1709,7 +1709,7 @@
most_recent_dataset.append(data)
# Also collect children via association object
dataset_collector( data.children )
- dataset_collector( history.datasets )
+ dataset_collector( history.active_datasets_children_and_roles )
most_recent_dataset.reverse()
if already_used is not None:
for val in most_recent_dataset:
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: guerler: Frame: Fix widget parameter
by commits-noreply@bitbucket.org 24 Jan '14
by commits-noreply@bitbucket.org 24 Jan '14
24 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/ce250b678c13/
Changeset: ce250b678c13
User: guerler
Date: 2014-01-24 05:30:47
Summary: Frame: Fix widget parameter
Affected #: 1 file
diff -r b883d2f753824cf615fd4b3acb04d815f919bba9 -r ce250b678c13cabd72f13e3ed118976b7fcb4fe8 static/scripts/galaxy.frame.js
--- a/static/scripts/galaxy.frame.js
+++ b/static/scripts/galaxy.frame.js
@@ -1096,11 +1096,6 @@
// identify content type
if (type == 'url') {
- if (content.indexOf('?') == -1)
- content += '?';
- else
- content += '&';
- content += 'widget=True';
content = '<iframe scrolling="auto" class="f-iframe" src="' + content + '"></iframe>';
}
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: Get rid of unused is_convertable nested function.
by commits-noreply@bitbucket.org 24 Jan '14
by commits-noreply@bitbucket.org 24 Jan '14
24 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/b883d2f75382/
Changeset: b883d2f75382
User: jmchilton
Date: 2014-01-24 05:21:27
Summary: Get rid of unused is_convertable nested function.
Affected #: 1 file
diff -r f443913ea49987da0bb651621743fefd03328cea -r b883d2f753824cf615fd4b3acb04d815f919bba9 lib/galaxy/tools/parameters/basic.py
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -1693,11 +1693,6 @@
pass # no valid options
def dataset_collector( datasets ):
- def is_convertable( dataset ):
- target_ext, converted_dataset = dataset.find_conversion_destination( self.formats )
- if target_ext is not None:
- return True
- return False
for i, data in enumerate( datasets ):
if data.visible and not data.deleted and data.state not in [data.states.ERROR, data.states.DISCARDED]:
is_valid = False
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
3 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/15e54243fcc3/
Changeset: 15e54243fcc3
User: jmchilton
Date: 2014-01-24 05:11:06
Summary: Slight improvement to test_execution.py
Affected #: 1 file
diff -r b4abf0b73f7c7a89444fd5ec01d9d4e6d2fc8c7d -r 15e54243fcc3b11055aa418aab7cf01bf412646b test/unit/tools/test_execution.py
--- a/test/unit/tools/test_execution.py
+++ b/test/unit/tools/test_execution.py
@@ -92,7 +92,7 @@
param1="moo",
runtool_btn="dummy",
)
- assert template == "tool_executed.mako"
+ self.__assert_exeuted( template, template_vars )
# Didn't specify a rerun_remap_id so this should be None
assert self.tool_action.execution_call_args[ 0 ][ "rerun_remap_job_id" ] is None
@@ -138,7 +138,7 @@
rerun_remap_job_id=self.app.security.encode_id(123),
runtool_btn="dummy",
)
- assert template == "tool_executed.mako"
+ self.__assert_exeuted( template, template_vars )
assert self.tool_action.execution_call_args[ 0 ][ "rerun_remap_job_id" ] == 123
def test_invalid_remap_job( self ):
@@ -189,7 +189,7 @@
param1=1,
runtool_btn="dummy",
)
- assert template == "tool_executed.mako"
+ self.__assert_exeuted( template, template_vars )
# Tool 'executed' once, with hda as param1
assert len( self.tool_action.execution_call_args ) == 1
assert self.tool_action.execution_call_args[ 0 ][ "incoming" ][ "param1" ] == hda
@@ -236,10 +236,20 @@
def __assert_rerenders_tool_without_errors( self, template, template_vars ):
assert template == "tool_form.mako"
- assert not template_vars[ "errors" ]
+ self.__assert_no_errors( template_vars )
state = template_vars[ "tool_state" ]
return state
+ def __assert_exeuted( self, template, template_vars ):
+ if template == "tool_form.mako":
+ self.__assert_no_errors( template_vars )
+ self.assertEquals(template, "tool_executed.mako")
+
+ def __assert_no_errors( self, template_vars ):
+ assert "errors" in template_vars, "tool_form.mako rendered without errors defintion."
+ errors = template_vars[ "errors" ]
+ assert not errors, "Template rendered unexpected errors - %s" % errors
+
def __init_tool( self, tool_contents ):
self.__write_tool( tool_contents )
self.__setup_tool( )
https://bitbucket.org/galaxy/galaxy-central/commits/1277dd1aa267/
Changeset: 1277dd1aa267
User: jmchilton
Date: 2014-01-24 05:11:06
Summary: Refactor logic related to creating tools for unit tests.
So it can be reused by tool actions unit test.
Affected #: 2 files
diff -r 15e54243fcc3b11055aa418aab7cf01bf412646b -r 1277dd1aa2671c9a738b38f88507c8c14b2fb1a6 test/unit/tools/test_execution.py
--- a/test/unit/tools/test_execution.py
+++ b/test/unit/tools/test_execution.py
@@ -5,15 +5,13 @@
from unittest import TestCase
import galaxy.model
-from galaxy.tools import Tool
from galaxy.tools import DefaultToolState
from galaxy.tools.parameters import params_to_incoming
-from galaxy.util import parse_xml
from galaxy.util.bunch import Bunch
from galaxy.util import string_to_object
from galaxy.util import object_to_string
from galaxy.util.odict import odict
-from tools_support import UsesApp
+import tools_support
from galaxy import eggs
eggs.require( "Paste" )
@@ -61,7 +59,7 @@
'''
-class ToolExecutionTestCase( TestCase, UsesApp ):
+class ToolExecutionTestCase( TestCase, tools_support.UsesApp, tools_support.UsesTools ):
def setUp(self):
self.setup_app()
@@ -77,7 +75,7 @@
self.tear_down_app()
def test_state_new( self ):
- self.__init_tool( SIMPLE_TOOL_CONTENTS )
+ self._init_tool( SIMPLE_TOOL_CONTENTS )
template, template_vars = self.__handle_with_incoming(
param1="moo",
# no runtool_btn, just rerenders the form mako with tool
@@ -87,7 +85,7 @@
assert state.inputs[ "param1" ] == "moo"
def test_execute( self ):
- self.__init_tool( SIMPLE_TOOL_CONTENTS )
+ self._init_tool( SIMPLE_TOOL_CONTENTS )
template, template_vars = self.__handle_with_incoming(
param1="moo",
runtool_btn="dummy",
@@ -97,7 +95,7 @@
assert self.tool_action.execution_call_args[ 0 ][ "rerun_remap_job_id" ] is None
def test_execute_exception( self ):
- self.__init_tool( SIMPLE_TOOL_CONTENTS )
+ self._init_tool( SIMPLE_TOOL_CONTENTS )
self.tool_action.raise_exception( )
template, template_vars = self.__handle_with_incoming(
param1="moo",
@@ -108,7 +106,7 @@
assert "Error executing tool" in template_vars[ "message" ]
def test_execute_errors( self ):
- self.__init_tool( SIMPLE_TOOL_CONTENTS )
+ self._init_tool( SIMPLE_TOOL_CONTENTS )
self.tool_action.return_error( )
template, template_vars = self.__handle_with_incoming(
param1="moo",
@@ -119,7 +117,7 @@
assert "Test Error Message" in template_vars[ "message" ], template_vars
def test_redirect( self ):
- self.__init_tool( SIMPLE_TOOL_CONTENTS )
+ self._init_tool( SIMPLE_TOOL_CONTENTS )
self.tool_action.expect_redirect = True
redirect_raised = False
try:
@@ -132,7 +130,7 @@
assert redirect_raised
def test_remap_job( self ):
- self.__init_tool( SIMPLE_TOOL_CONTENTS )
+ self._init_tool( SIMPLE_TOOL_CONTENTS )
template, template_vars = self.__handle_with_incoming(
param1="moo",
rerun_remap_job_id=self.app.security.encode_id(123),
@@ -142,7 +140,7 @@
assert self.tool_action.execution_call_args[ 0 ][ "rerun_remap_job_id" ] == 123
def test_invalid_remap_job( self ):
- self.__init_tool( SIMPLE_TOOL_CONTENTS )
+ self._init_tool( SIMPLE_TOOL_CONTENTS )
template, template_vars = self.__handle_with_incoming(
param1="moo",
rerun_remap_job_id='123', # Not encoded
@@ -153,7 +151,7 @@
assert "invalid job" in template_vars[ "message" ]
def test_repeat_state_updates( self ):
- self.__init_tool( REPEAT_TOOL_CONTENTS )
+ self._init_tool( REPEAT_TOOL_CONTENTS )
# Fresh state contains no repeat elements
template, template_vars = self.__handle_with_incoming()
@@ -182,7 +180,7 @@
assert len( state.inputs[ "repeat1" ] ) == 1
def test_data_param_execute( self ):
- self.__init_tool( SIMPLE_CAT_TOOL_CONTENTS )
+ self._init_tool( SIMPLE_CAT_TOOL_CONTENTS )
hda = self.__add_dataset(1)
# Execute tool action
template, template_vars = self.__handle_with_incoming(
@@ -195,7 +193,7 @@
assert self.tool_action.execution_call_args[ 0 ][ "incoming" ][ "param1" ] == hda
def test_data_param_state_update( self ):
- self.__init_tool( SIMPLE_CAT_TOOL_CONTENTS )
+ self._init_tool( SIMPLE_CAT_TOOL_CONTENTS )
hda = self.__add_dataset( 1 )
# Update state
template, template_vars = self.__handle_with_incoming(
@@ -250,18 +248,6 @@
errors = template_vars[ "errors" ]
assert not errors, "Template rendered unexpected errors - %s" % errors
- def __init_tool( self, tool_contents ):
- self.__write_tool( tool_contents )
- self.__setup_tool( )
-
- def __setup_tool( self ):
- tree = parse_xml( self.tool_file )
- self.tool = Tool( self.tool_file, tree.getroot(), self.app )
- self.tool.tool_action = self.tool_action
-
- def __write_tool( self, contents ):
- open( self.tool_file, "w" ).write( contents )
-
def __string_to_state( self, state_string ):
encoded_state = string_to_object( state_string )
state = DefaultToolState()
diff -r 15e54243fcc3b11055aa418aab7cf01bf412646b -r 1277dd1aa2671c9a738b38f88507c8c14b2fb1a6 test/unit/tools_support.py
--- a/test/unit/tools_support.py
+++ b/test/unit/tools_support.py
@@ -12,6 +12,8 @@
from galaxy.web.security import SecurityHelper
import galaxy.model
from galaxy.model import mapping
+from galaxy.tools import Tool
+from galaxy.util import parse_xml
class UsesApp( object ):
@@ -28,6 +30,21 @@
shutil.rmtree( self.test_directory )
+class UsesTools( object ):
+
+ def _init_tool( self, tool_contents ):
+ self.__write_tool( tool_contents )
+ self.__setup_tool( )
+
+ def __setup_tool( self ):
+ tree = parse_xml( self.tool_file )
+ self.tool = Tool( self.tool_file, tree.getroot(), self.app )
+ self.tool.tool_action = self.tool_action
+
+ def __write_tool( self, contents ):
+ open( self.tool_file, "w" ).write( contents )
+
+
class MockApp( object ):
def __init__( self, test_directory ):
https://bitbucket.org/galaxy/galaxy-central/commits/f443913ea499/
Changeset: f443913ea499
User: jmchilton
Date: 2014-01-24 05:11:07
Summary: Create unit test for some simple DefaultToolAction functionality.
Want to refactor some stuff around in DefaultToolAction so can be reused when dealing with dataset collections downstream in https://github.com/jmchilton/galaxy-central/tree/collections_1 - so creating unit tests to ensure functionality is not changing.
This changeset also reworks test_execution.py moving more stuff to test/unit/tools_support.py to share between test files.
Affected #: 3 files
diff -r 1277dd1aa2671c9a738b38f88507c8c14b2fb1a6 -r f443913ea49987da0bb651621743fefd03328cea test/unit/tools/test_actions.py
--- /dev/null
+++ b/test/unit/tools/test_actions.py
@@ -0,0 +1,133 @@
+import unittest
+
+from galaxy import model
+from galaxy.tools.actions import DefaultToolAction
+
+import tools_support
+
+TEST_HANDLER_NAME = "test_handler_1"
+
+
+# I cannot think of a saner way to test if data is being wrapped than use a
+# data param in the output label - though you would probably never want to do
+# this.
+DATA_IN_LABEL_TOOL_CONTENTS = '''<tool id="test_tool" name="Test Tool">
+ <command>echo "$param1" < $out1</command>
+ <inputs>
+ <repeat name="repeat1" label="The Repeat">
+ <param type="data" name="param1" value="" />
+ </repeat>
+ </inputs>
+ <outputs>
+ <data name="out1" format="data" label="Output (${repeat1[0].param1})" />
+ </outputs>
+</tool>
+'''
+
+
+class DefaultToolActionTestCase( unittest.TestCase, tools_support.UsesApp, tools_support.UsesTools ):
+
+ def setUp( self ):
+ self.setup_app( mock_model=False )
+ history = model.History()
+ self.history = history
+ self.trans = MockTrans(
+ self.app,
+ self.history
+ )
+ self.app.model.context.add( history )
+ self.app.model.context.flush()
+ self.action = DefaultToolAction()
+ self.app.config.len_file_path = "moocow"
+ self.app.job_config[ "get_handler" ] = lambda h: TEST_HANDLER_NAME
+ self.app.object_store = MockObjectStore()
+
+ def test_output_created( self ):
+ _, output = self._simple_execute()
+ assert len( output ) == 1
+ assert "out1" in output
+
+ def test_output_label( self ):
+ _, output = self._simple_execute()
+ self.assertEquals( output[ "out1" ].name, "Output (moo)" )
+
+ def test_output_label_data( self ):
+ hda1 = self.__add_dataset()
+ hda2 = self.__add_dataset()
+ incoming = {
+ "param1": hda1,
+ "repeat1": [
+ {"param2": hda2},
+ ]
+ }
+ job, output = self._simple_execute(
+ tools_support.SIMPLE_CAT_TOOL_CONTENTS,
+ incoming,
+ )
+ self.assertEquals( output[ "out1" ].name, "Test Tool on data 2 and data 1" )
+
+ def test_params_wrapped( self ):
+ hda1 = self.__add_dataset()
+ _, output = self._simple_execute(
+ contents=DATA_IN_LABEL_TOOL_CONTENTS,
+ incoming=dict( repeat1=[ dict( param1=hda1 ) ] ),
+ )
+ # Again this is a stupid way to ensure data parameters are wrapped.
+ self.assertEquals( output[ "out1" ].name, "Output (%s)" % hda1.dataset.get_file_name() )
+
+ def test_handler_set( self ):
+ job, _ = self._simple_execute()
+ assert job.handler == TEST_HANDLER_NAME
+
+ def __add_dataset( self, state='ok' ):
+ hda = model.HistoryDatasetAssociation()
+ hda.dataset = model.Dataset()
+ hda.dataset.state = 'ok'
+ hda.dataset.external_filename = "/tmp/datasets/dataset_001.dat"
+ self.history.add_dataset( hda )
+ self.app.model.context.flush()
+ return hda
+
+ def _simple_execute( self, contents=None, incoming=None ):
+ if contents is None:
+ contents = tools_support.SIMPLE_TOOL_CONTENTS
+ if incoming is None:
+ incoming = dict(param1="moo")
+ self._init_tool( contents )
+ return self.action.execute(
+ tool=self.tool,
+ trans=self.trans,
+ history=self.history,
+ incoming=incoming,
+ )
+
+
+class MockTrans( object ):
+
+ def __init__( self, app, history, user=None ):
+ self.app = app
+ self.history = history
+ self.user = user
+ self.sa_session = self.app.model.context
+ self.model = app.model
+
+ def db_dataset_for( self, input_db_key ):
+ return None
+
+ def get_galaxy_session( self ):
+ return model.GalaxySession()
+
+ def get_current_user_roles( self ):
+ return []
+
+ def log_event( self, *args, **kwargs ):
+ pass
+
+
+class MockObjectStore( object ):
+
+ def __init__( self ):
+ self.created_datasets = []
+
+ def create( self, dataset ):
+ self.created_datasets.append( dataset )
diff -r 1277dd1aa2671c9a738b38f88507c8c14b2fb1a6 -r f443913ea49987da0bb651621743fefd03328cea test/unit/tools/test_execution.py
--- a/test/unit/tools/test_execution.py
+++ b/test/unit/tools/test_execution.py
@@ -1,6 +1,5 @@
""" Test Tool execution and state handling logic.
"""
-import os
from unittest import TestCase
@@ -17,17 +16,6 @@
eggs.require( "Paste" )
from paste import httpexceptions
-# Simple tool with just one text parameter and output.
-SIMPLE_TOOL_CONTENTS = '''<tool id="test_tool" name="Test Tool">
- <command>echo "$param1" < $out1</command>
- <inputs>
- <param type="text" name="param1" value="" />
- </inputs>
- <outputs>
- <output name="out1" format="data" />
- </outputs>
-</tool>'''
-
# Tool with a repeat parameter, to test state update.
REPEAT_TOOL_CONTENTS = '''<tool id="test_tool" name="Test Tool"><command>echo "$param1" #for $r in $repeat# "$r.param2" #end for# < $out1</command>
@@ -38,22 +26,7 @@
</repeat></inputs><outputs>
- <output name="out1" format="data" />
- </outputs>
-</tool>
-'''
-
-# A tool with data parameters (kind of like cat1) my favorite test tool :)
-SIMPLE_CAT_TOOL_CONTENTS = '''<tool id="test_tool" name="Test Tool">
- <command>cat "$param1" #for $r in $repeat# "$r.param2" #end for# < $out1</command>
- <inputs>
- <param type="data" format="tabular" name="param1" value="" />
- <repeat name="repeat1" label="Repeat 1">
- <param type="data" format="tabular" name="param2" value="" />
- </repeat>
- </inputs>
- <outputs>
- <output name="out1" format="data" />
+ <data name="out1" format="data" /></outputs></tool>
'''
@@ -64,18 +37,14 @@
def setUp(self):
self.setup_app()
self.history = galaxy.model.History()
- self.app.job_config["get_job_tool_configurations"] = lambda ids: None
- self.app.config.drmaa_external_runjob_script = ""
- self.app.config.tool_secret = "testsecret"
self.trans = MockTrans( self.app, self.history )
self.tool_action = MockAction( self.trans )
- self.tool_file = os.path.join( self.test_directory, "tool.xml" )
def tearDown(self):
self.tear_down_app()
def test_state_new( self ):
- self._init_tool( SIMPLE_TOOL_CONTENTS )
+ self._init_tool( tools_support.SIMPLE_TOOL_CONTENTS )
template, template_vars = self.__handle_with_incoming(
param1="moo",
# no runtool_btn, just rerenders the form mako with tool
@@ -85,7 +54,7 @@
assert state.inputs[ "param1" ] == "moo"
def test_execute( self ):
- self._init_tool( SIMPLE_TOOL_CONTENTS )
+ self._init_tool( tools_support.SIMPLE_TOOL_CONTENTS )
template, template_vars = self.__handle_with_incoming(
param1="moo",
runtool_btn="dummy",
@@ -95,7 +64,7 @@
assert self.tool_action.execution_call_args[ 0 ][ "rerun_remap_job_id" ] is None
def test_execute_exception( self ):
- self._init_tool( SIMPLE_TOOL_CONTENTS )
+ self._init_tool( tools_support.SIMPLE_TOOL_CONTENTS )
self.tool_action.raise_exception( )
template, template_vars = self.__handle_with_incoming(
param1="moo",
@@ -106,7 +75,7 @@
assert "Error executing tool" in template_vars[ "message" ]
def test_execute_errors( self ):
- self._init_tool( SIMPLE_TOOL_CONTENTS )
+ self._init_tool( tools_support.SIMPLE_TOOL_CONTENTS )
self.tool_action.return_error( )
template, template_vars = self.__handle_with_incoming(
param1="moo",
@@ -117,7 +86,7 @@
assert "Test Error Message" in template_vars[ "message" ], template_vars
def test_redirect( self ):
- self._init_tool( SIMPLE_TOOL_CONTENTS )
+ self._init_tool( tools_support.SIMPLE_TOOL_CONTENTS )
self.tool_action.expect_redirect = True
redirect_raised = False
try:
@@ -130,7 +99,7 @@
assert redirect_raised
def test_remap_job( self ):
- self._init_tool( SIMPLE_TOOL_CONTENTS )
+ self._init_tool( tools_support.SIMPLE_TOOL_CONTENTS )
template, template_vars = self.__handle_with_incoming(
param1="moo",
rerun_remap_job_id=self.app.security.encode_id(123),
@@ -140,7 +109,7 @@
assert self.tool_action.execution_call_args[ 0 ][ "rerun_remap_job_id" ] == 123
def test_invalid_remap_job( self ):
- self._init_tool( SIMPLE_TOOL_CONTENTS )
+ self._init_tool( tools_support.SIMPLE_TOOL_CONTENTS )
template, template_vars = self.__handle_with_incoming(
param1="moo",
rerun_remap_job_id='123', # Not encoded
@@ -180,7 +149,7 @@
assert len( state.inputs[ "repeat1" ] ) == 1
def test_data_param_execute( self ):
- self._init_tool( SIMPLE_CAT_TOOL_CONTENTS )
+ self._init_tool( tools_support.SIMPLE_CAT_TOOL_CONTENTS )
hda = self.__add_dataset(1)
# Execute tool action
template, template_vars = self.__handle_with_incoming(
@@ -193,7 +162,7 @@
assert self.tool_action.execution_call_args[ 0 ][ "incoming" ][ "param1" ] == hda
def test_data_param_state_update( self ):
- self._init_tool( SIMPLE_CAT_TOOL_CONTENTS )
+ self._init_tool( tools_support.SIMPLE_CAT_TOOL_CONTENTS )
hda = self.__add_dataset( 1 )
# Update state
template, template_vars = self.__handle_with_incoming(
diff -r 1277dd1aa2671c9a738b38f88507c8c14b2fb1a6 -r f443913ea49987da0bb651621743fefd03328cea test/unit/tools_support.py
--- a/test/unit/tools_support.py
+++ b/test/unit/tools_support.py
@@ -14,32 +14,64 @@
from galaxy.model import mapping
from galaxy.tools import Tool
from galaxy.util import parse_xml
+from galaxy.jobs import NoopQueue
class UsesApp( object ):
- def setup_app( self ):
- # The following line is needed in order to create
- # HistoryDatasetAssociations - ideally the model classes would be
- # usable without the ORM infrastructure in place.
- mapping.init( "/tmp", "sqlite:///:memory:", create_tables=True )
+ def setup_app( self, mock_model=True ):
self.test_directory = tempfile.mkdtemp()
- self.app = MockApp(self.test_directory)
+ self.app = MockApp( self.test_directory, mock_model=mock_model )
def tear_down_app( self ):
shutil.rmtree( self.test_directory )
+# Simple tool with just one text parameter and output.
+SIMPLE_TOOL_CONTENTS = '''<tool id="test_tool" name="Test Tool">
+ <command>echo "$param1" < $out1</command>
+ <inputs>
+ <param type="text" name="param1" value="" />
+ </inputs>
+ <outputs>
+ <data name="out1" format="data" label="Output ($param1)" />
+ </outputs>
+</tool>
+'''
+
+
+# A tool with data parameters (kind of like cat1) my favorite test tool :)
+SIMPLE_CAT_TOOL_CONTENTS = '''<tool id="test_tool" name="Test Tool">
+ <command>cat "$param1" #for $r in $repeat# "$r.param2" #end for# < $out1</command>
+ <inputs>
+ <param type="data" format="tabular" name="param1" value="" />
+ <repeat name="repeat1" label="Repeat 1">
+ <param type="data" format="tabular" name="param2" value="" />
+ </repeat>
+ </inputs>
+ <outputs>
+ <data name="out1" format="data" />
+ </outputs>
+</tool>
+'''
+
+
class UsesTools( object ):
def _init_tool( self, tool_contents ):
+ self.tool_file = os.path.join( self.test_directory, "tool.xml" )
+ self.app.config.drmaa_external_runjob_script = ""
+ self.app.config.tool_secret = "testsecret"
+ self.app.config.track_jobs_in_database = False
+ self.app.job_config["get_job_tool_configurations"] = lambda ids: [Bunch(handler=Bunch())]
self.__write_tool( tool_contents )
self.__setup_tool( )
def __setup_tool( self ):
tree = parse_xml( self.tool_file )
self.tool = Tool( self.tool_file, tree.getroot(), self.app )
- self.tool.tool_action = self.tool_action
+ if getattr( self, "tool_action", None ):
+ self.tool.tool_action = self.tool_action
def __write_tool( self, contents ):
open( self.tool_file, "w" ).write( contents )
@@ -47,7 +79,11 @@
class MockApp( object ):
- def __init__( self, test_directory ):
+ def __init__( self, test_directory, mock_model=True ):
+ # The following line is needed in order to create
+ # HistoryDatasetAssociations - ideally the model classes would be
+ # usable without the ORM infrastructure in place.
+ in_memomry_model = mapping.init( "/tmp", "sqlite:///:memory:", create_tables=True )
self.datatypes_registry = Bunch(
integrated_datatypes_configs='/galaxy/integrated_datatypes_configs.xml',
@@ -64,15 +100,27 @@
# Setup some attributes for downstream extension by specific tests.
self.job_config = Bunch()
- # Create self.model to mimic app.model.
- self.model = Bunch( context=MockContext() )
- for module_member_name in dir( galaxy.model ):
- module_member = getattr(galaxy.model, module_member_name)
- if type( module_member ) == type:
- self.model[ module_member_name ] = module_member
+
+ # Two ways to handle model layer, one is to stub out some objects that
+ # have an interface similar to real model (mock_model) and can keep
+ # track of 'persisted' objects in a map. The other is to use a real
+ # sqlalchemy layer but target an in memory database. Depending on what
+ # is being tested.
+ if mock_model:
+ # Create self.model to mimic app.model.
+ self.model = Bunch( context=MockContext() )
+ for module_member_name in dir( galaxy.model ):
+ module_member = getattr(galaxy.model, module_member_name)
+ if type( module_member ) == type:
+ self.model[ module_member_name ] = module_member
+ else:
+ self.model = in_memomry_model
self.toolbox = None
self.object_store = None
self.security = SecurityHelper(id_secret="testing")
+ from galaxy.security import GalaxyRBACAgent
+ self.job_queue = NoopQueue()
+ self.security_agent = GalaxyRBACAgent( self.model )
class MockContext(object):
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: jeremy goecks: Fix bug in read painter.
by commits-noreply@bitbucket.org 23 Jan '14
by commits-noreply@bitbucket.org 23 Jan '14
23 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/b4abf0b73f7c/
Changeset: b4abf0b73f7c
User: jeremy goecks
Date: 2014-01-23 23:43:21
Summary: Fix bug in read painter.
Affected #: 1 file
diff -r 117fef56513fc563dd231516196cfd601c1635e2 -r b4abf0b73f7c7a89444fd5ec01d9d4e6d2fc8c7d static/scripts/viz/trackster/painters.js
--- a/static/scripts/viz/trackster/painters.js
+++ b/static/scripts/viz/trackster/painters.js
@@ -772,6 +772,10 @@
s_end = Math.floor( Math.max(0, (seq_start + cig_len - tile_low - 0.5) * w_scale) );
if (!is_overlap([seq_start, seq_start + cig_len], tile_region)) {
+ // Increment base offset only for certain operations.
+ if ("MDN=X".indexOf(cig_op) !== -1) {
+ base_offset += cig_len;
+ }
continue;
}
@@ -960,7 +964,6 @@
f_end = Math.ceil( Math.min(width, Math.max(0, (feature_end - tile_low - 0.5) * w_scale)) ),
y_start = (mode === "Dense" ? 0 : (0 + slot)) * y_scale,
label_color = this.prefs.label_color;
-
// Draw read.
if (feature[5] instanceof Array) {
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: jeremy goecks: Update tool template's chrom_info to correctly point to len file for custom builds defined by len files. This was broken was len files were moved from the len_file directory to HDAs.
by commits-noreply@bitbucket.org 23 Jan '14
by commits-noreply@bitbucket.org 23 Jan '14
23 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/117fef56513f/
Changeset: 117fef56513f
User: jeremy goecks
Date: 2014-01-23 21:29:14
Summary: Update tool template's chrom_info to correctly point to len file for custom builds defined by len files. This was broken was len files were moved from the len_file directory to HDAs.
Affected #: 1 file
diff -r 7fd2f3f098840a5a1b9d7041330100c4f2af70df -r 117fef56513fc563dd231516196cfd601c1635e2 lib/galaxy/tools/actions/__init__.py
--- a/lib/galaxy/tools/actions/__init__.py
+++ b/lib/galaxy/tools/actions/__init__.py
@@ -213,7 +213,7 @@
db_datasets[ "chromInfo" ] = db_dataset
incoming[ "chromInfo" ] = db_dataset.file_name
else:
- # -- Get chrom_info from either a custom or built-in build. --
+ # -- Get chrom_info (len file) from either a custom or built-in build. --
chrom_info = None
if trans.user and ( 'dbkeys' in trans.user.preferences ) and ( input_dbkey in from_json_string( trans.user.preferences[ 'dbkeys' ] ) ):
@@ -226,9 +226,13 @@
# condition below to avoid getting chrom_info when running the
# fasta-to-len converter.
if 'fasta' in custom_build_dict and tool.id != 'CONVERTER_fasta_to_len':
+ # Build is defined by fasta; get len file, which is obtained from converting fasta.
build_fasta_dataset = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( custom_build_dict[ 'fasta' ] )
chrom_info = build_fasta_dataset.get_converted_dataset( trans, 'len' ).file_name
-
+ elif 'len' in custom_build_dict:
+ # Build is defined by len file, so use it.
+ chrom_info = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( custom_build_dict[ 'len' ] ).file_name
+
if not chrom_info:
# Default to built-in build.
chrom_info = os.path.join( trans.app.config.len_file_path, "%s.len" % input_dbkey )
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: packed js that was missing
by commits-noreply@bitbucket.org 23 Jan '14
by commits-noreply@bitbucket.org 23 Jan '14
23 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/7fd2f3f09884/
Changeset: 7fd2f3f09884
User: martenson
Date: 2014-01-23 19:20:41
Summary: packed js that was missing
Affected #: 2 files
diff -r aaabd336009044d2d6f748eaca483ccab0950435 -r 7fd2f3f098840a5a1b9d7041330100c4f2af70df static/scripts/packed/viz/circster.js
--- a/static/scripts/packed/viz/circster.js
+++ b/static/scripts/packed/viz/circster.js
@@ -1,1 +1,1 @@
-define(["libs/underscore","libs/d3","viz/visualization"],function(g,l,i){var m=Backbone.Model.extend({is_visible:function(q,n){var o=q.getBoundingClientRect(),p=$("svg")[0].getBoundingClientRect();if(o.right<0||o.left>p.right||o.bottom<0||o.top>p.bottom){return false}return true}});var h={drawTicks:function(r,q,v,p,n){var u=r.append("g").selectAll("g").data(q).enter().append("g").selectAll("g").data(v).enter().append("g").attr("class","tick").attr("transform",function(w){return"rotate("+(w.angle*180/Math.PI-90)+")translate("+w.radius+",0)"});var t=[],s=[],o=function(w){return w.angle>Math.PI?"end":null};if(n){t=[0,0,0,-4];s=[4,0,"",".35em"];o=null}else{t=[1,0,4,0];s=[0,4,".35em",""]}u.append("line").attr("x1",t[0]).attr("y1",t[1]).attr("x2",t[2]).attr("y1",t[3]).style("stroke","#000");u.append("text").attr("x",s[0]).attr("y",s[1]).attr("dx",s[2]).attr("dy",s[3]).attr("text-anchor",o).attr("transform",p).text(function(w){return w.label})},formatNum:function(o,n){if(n===undefined){n=2}if(o===null){return null}var q=null;if(o<1){q=o.toPrecision(n)}else{var p=Math.round(o.toPrecision(n));if(o<1000){q=p}else{if(o<1000000){q=Math.round((p/1000).toPrecision(3)).toFixed(0)+"K"}else{if(o<1000000000){q=Math.round((p/1000000).toPrecision(3)).toFixed(0)+"M"}}}}return q}};var c=Backbone.Model.extend({});var a=Backbone.View.extend({className:"circster",initialize:function(n){this.total_gap=n.total_gap;this.genome=n.genome;this.dataset_arc_height=n.dataset_arc_height;this.track_gap=10;this.label_arc_height=50;this.scale=1;this.circular_views=null;this.chords_views=null;this.model.get("tracks").on("add",this.add_track,this);this.model.get("tracks").on("remove",this.remove_track,this);this.get_circular_tracks()},get_circular_tracks:function(){return this.model.get("tracks").filter(function(n){return n.get("track_type")!=="DiagonalHeatmapTrack"})},get_chord_tracks:function(){return this.model.get("tracks").filter(function(n){return n.get("track_type")==="DiagonalHeatmapTrack"})},get_tracks_bounds:function(){var o=this.get_circular_tracks();dataset_arc_height=this.dataset_arc_height,min_dimension=Math.min(this.$el.width(),this.$el.height()),radius_start=min_dimension/2-o.length*(this.dataset_arc_height+this.track_gap)-(this.label_arc_height+this.track_gap),tracks_start_radii=l.range(radius_start,min_dimension/2,this.dataset_arc_height+this.track_gap);var n=this;return g.map(tracks_start_radii,function(p){return[p,p+n.dataset_arc_height]})},render:function(){var w=this,q=this.dataset_arc_height,n=w.$el.width(),v=w.$el.height(),s=this.get_circular_tracks(),p=this.get_chord_tracks(),r=this.get_tracks_bounds(),o=l.select(w.$el[0]).append("svg").attr("width",n).attr("height",v).attr("pointer-events","all").append("svg:g").call(l.behavior.zoom().on("zoom",function(){var x=l.event.scale;o.attr("transform","translate("+l.event.translate+") scale("+x+")");if(w.scale!==x){if(w.zoom_drag_timeout){clearTimeout(w.zoom_drag_timeout)}w.zoom_drag_timeout=setTimeout(function(){},400)}})).attr("transform","translate("+n/2+","+v/2+")").append("svg:g").attr("class","tracks");this.circular_views=s.map(function(y,z){var x=new d({el:o.append("g")[0],track:y,radius_bounds:r[z],genome:w.genome,total_gap:w.total_gap});x.render();return x});this.chords_views=p.map(function(y){var x=new j({el:o.append("g")[0],track:y,radius_bounds:r[0],genome:w.genome,total_gap:w.total_gap});x.render();return x});var u=this.circular_views[this.circular_views.length-1].radius_bounds[1],t=[u,u+this.label_arc_height];this.label_track_view=new b({el:o.append("g")[0],track:new c(),radius_bounds:t,genome:w.genome,total_gap:w.total_gap});this.label_track_view.render()},add_track:function(t){if(t.get("track_type")==="DiagonalHeatmapTrack"){var p=this.circular_views[0].radius_bounds,s=new j({el:l.select("g.tracks").append("g")[0],track:t,radius_bounds:p,genome:this.genome,total_gap:this.total_gap});s.render();this.chords_views.push(s)}else{var r=this.get_tracks_bounds();g.each(this.circular_views,function(u,v){u.update_radius_bounds(r[v])});g.each(this.chords_views,function(u){u.update_radius_bounds(r[0])});var q=this.circular_views.length,n=new d({el:l.select("g.tracks").append("g")[0],track:t,radius_bounds:r[q],genome:this.genome,total_gap:this.total_gap});n.render();this.circular_views.push(n);var o=r[r.length-1];o[1]=o[0];this.label_track_view.update_radius_bounds(o)}},remove_track:function(o,q,p){var n=this.circular_views[p.index];this.circular_views.splice(p.index,1);n.$el.remove();var r=this.get_tracks_bounds();g.each(this.circular_views,function(s,t){s.update_radius_bounds(r[t])})}});var k=Backbone.View.extend({tagName:"g",initialize:function(n){this.bg_stroke="ccc";this.loading_bg_fill="000";this.bg_fill="ccc";this.total_gap=n.total_gap;this.track=n.track;this.radius_bounds=n.radius_bounds;this.genome=n.genome;this.chroms_layout=this._chroms_layout();this.data_bounds=[];this.scale=1;this.parent_elt=l.select(this.$el[0])},get_fill_color:function(){var n=this.track.get("config").get_value("block_color");if(!n){n=this.track.get("config").get_value("color")}return n},render:function(){var r=this.parent_elt;if(!r){console.log("no parent elt")}var q=this.chroms_layout,t=l.svg.arc().innerRadius(this.radius_bounds[0]).outerRadius(this.radius_bounds[1]),n=r.selectAll("g").data(q).enter().append("svg:g"),p=n.append("path").attr("d",t).attr("class","chrom-background").style("stroke",this.bg_stroke).style("fill",this.loading_bg_fill);p.append("title").text(function(v){return v.data.chrom});var o=this,s=o.track.get("data_manager"),u=(s?s.data_is_ready():true);$.when(u).then(function(){$.when(o._render_data(r)).then(function(){p.style("fill",o.bg_fill);o.render_labels()})})},render_labels:function(){},update_radius_bounds:function(o){this.radius_bounds=o;var n=l.svg.arc().innerRadius(this.radius_bounds[0]).outerRadius(this.radius_bounds[1]);this.parent_elt.selectAll("g>path.chrom-background").transition().duration(1000).attr("d",n);this._transition_chrom_data();this._transition_labels()},update_scale:function(q){var p=this.scale;this.scale=q;if(q<=p){return}var o=this,n=new m();this.parent_elt.selectAll("path.chrom-data").filter(function(s,r){return n.is_visible(this)}).each(function(x,t){var w=l.select(this),s=w.attr("chrom"),v=o.genome.get_chrom_region(s),u=o.track.get("data_manager"),r;if(!u.can_get_more_detailed_data(v)){return}r=o.track.get("data_manager").get_more_detailed_data(v,"Coverage",0,q);$.when(r).then(function(A){w.remove();o._update_data_bounds();var z=g.find(o.chroms_layout,function(B){return B.data.chrom===s});var y=o.get_fill_color();o._render_chrom_data(o.parent_elt,z,A).style("stroke",y).style("fill",y)})});return o},_transition_chrom_data:function(){var o=this.track,q=this.chroms_layout,n=this.parent_elt.selectAll("g>path.chrom-data"),r=n[0].length;if(r>0){var p=this;$.when(o.get("data_manager").get_genome_wide_data(this.genome)).then(function(t){var s=g.reject(g.map(t,function(u,v){var w=null,x=p._get_path_function(q[v],u);if(x){w=x(u.data)}return w}),function(u){return u===null});n.each(function(v,u){l.select(this).transition().duration(1000).attr("d",s[u])})})}},_transition_labels:function(){},_update_data_bounds:function(){var n=this.data_bounds;this.data_bounds=this.get_data_bounds(this.track.get("data_manager").get_genome_wide_data(this.genome));if(this.data_bounds[0]<n[0]||this.data_bounds[1]>n[1]){this._transition_chrom_data()}},_render_data:function(q){var p=this,o=this.chroms_layout,n=this.track,r=$.Deferred();$.when(n.get("data_manager").get_genome_wide_data(this.genome)).then(function(t){p.data_bounds=p.get_data_bounds(t);layout_and_data=g.zip(o,t),chroms_data_layout=g.map(layout_and_data,function(u){var v=u[0],w=u[1];return p._render_chrom_data(q,v,w)});var s=p.get_fill_color();p.parent_elt.selectAll("path.chrom-data").style("stroke",s).style("fill",s);r.resolve(q)});return r},_render_chrom_data:function(n,o,p){},_get_path_function:function(o,n){},_chroms_layout:function(){var o=this.genome.get_chroms_info(),q=l.layout.pie().value(function(s){return s.len}).sort(null),r=q(o),n=this.total_gap/o.length,p=g.map(r,function(u,t){var s=u.endAngle-n;u.endAngle=(s>u.startAngle?s:u.startAngle);return u});return p}});var b=k.extend({initialize:function(n){k.prototype.initialize.call(this,n);this.innerRadius=this.radius_bounds[0];this.radius_bounds[0]=this.radius_bounds[1];this.bg_stroke="fff";this.bg_fill="fff";this.min_arc_len=0.08},_render_data:function(p){var o=this,n=p.selectAll("g");n.selectAll("path").attr("id",function(t){return"label-"+t.data.chrom});n.append("svg:text").filter(function(t){return t.endAngle-t.startAngle>o.min_arc_len}).attr("text-anchor","middle").append("svg:textPath").attr("xlink:href",function(t){return"#label-"+t.data.chrom}).attr("startOffset","25%").attr("font-weight","bold").text(function(t){return t.data.chrom});var q=function(v){var t=(v.endAngle-v.startAngle)/v.value,u=l.range(0,v.value,25000000).map(function(w,x){return{radius:o.innerRadius,angle:w*t+v.startAngle,label:x===0?0:(x%3?null:o.formatNum(w))}});if(u.length<4){u[u.length-1].label=o.formatNum(Math.round((u[u.length-1].angle-v.startAngle)/t))}return u};var s=function(t){return t.angle>Math.PI?"rotate(180)translate(-16)":null};var r=g.filter(this.chroms_layout,function(t){return t.endAngle-t.startAngle>o.min_arc_len});this.drawTicks(this.parent_elt,r,q,s)}});g.extend(b.prototype,h);var f=k.extend({_quantile:function(o,n){o.sort(l.ascending);return l.quantile(o,n)},_render_chrom_data:function(n,q,o){var r=this._get_path_function(q,o);if(!r){return null}var p=n.datum(o.data),s=p.append("path").attr("class","chrom-data").attr("chrom",q.data.chrom).attr("d",r);return s},_get_path_function:function(q,p){if(typeof p==="string"||!p.data||p.data.length===0){return null}var n=l.scale.linear().domain(this.data_bounds).range(this.radius_bounds).clamp(true);var r=l.scale.linear().domain([0,p.data.length]).range([q.startAngle,q.endAngle]);var o=l.svg.line.radial().interpolate("linear").radius(function(s){return n(s[1])}).angle(function(t,s){return r(s)});return l.svg.area.radial().interpolate(o.interpolate()).innerRadius(n(0)).outerRadius(o.radius()).angle(o.angle())},render_labels:function(){var n=this,q=function(){return"rotate(90)"};var p=g.filter(this.chroms_layout,function(r){return r.endAngle-r.startAngle>0.08}),o=g.filter(p,function(s,r){return r%3===0});this.drawTicks(this.parent_elt,o,this._data_bounds_ticks_fn(),q,true)},_transition_labels:function(){if(this.data_bounds.length===0){return}var o=this,q=g.filter(this.chroms_layout,function(r){return r.endAngle-r.startAngle>0.08}),p=g.filter(q,function(s,r){return r%3===0}),n=g.flatten(g.map(p,function(r){return o._data_bounds_ticks_fn()(r)}));this.parent_elt.selectAll("g.tick").data(n).transition().attr("transform",function(r){return"rotate("+(r.angle*180/Math.PI-90)+")translate("+r.radius+",0)"})},_data_bounds_ticks_fn:function(){var n=this;visibleChroms=0;return function(o){return[{radius:n.radius_bounds[0],angle:o.startAngle,label:n.formatNum(n.data_bounds[0])},{radius:n.radius_bounds[1],angle:o.startAngle,label:n.formatNum(n.data_bounds[1])}]}},get_data_bounds:function(n){}});g.extend(f.prototype,h);var d=f.extend({get_data_bounds:function(o){var n=g.flatten(g.map(o,function(p){if(p){return g.map(p.data,function(q){return q[1]})}else{return 0}}));return[g.min(n),this._quantile(n,0.98)]}});var j=k.extend({render:function(){var n=this;$.when(n.track.get("data_manager").data_is_ready()).then(function(){$.when(n.track.get("data_manager").get_genome_wide_data(n.genome)).then(function(q){var p=[],o=n.genome.get_chroms_info();g.each(q,function(u,t){var r=o[t].chrom;var s=g.map(u.data,function(w){var v=n._get_region_angle(r,w[1]),x=n._get_region_angle(w[3],w[4]);return{source:{startAngle:v,endAngle:v+0.01},target:{startAngle:x,endAngle:x+0.01}}});p=p.concat(s)});n.parent_elt.append("g").attr("class","chord").selectAll("path").data(p).enter().append("path").style("fill",n.get_fill_color()).attr("d",l.svg.chord().radius(n.radius_bounds[0])).style("opacity",1)})})},update_radius_bounds:function(n){this.radius_bounds=n;this.parent_elt.selectAll("path").transition().attr("d",l.svg.chord().radius(this.radius_bounds[0]))},_get_region_angle:function(p,n){var o=g.find(this.chroms_layout,function(q){return q.data.chrom===p});return o.endAngle-((o.endAngle-o.startAngle)*(o.data.len-n)/o.data.len)}});var e=Backbone.View.extend({initialize:function(){var n=new i.Genome(galaxy_config.app.genome),o=new i.GenomeVisualization(galaxy_config.app.viz_config),q=new a({el:$("#center .unified-panel-body"),total_gap:2*Math.PI*0.1,genome:n,model:o,dataset_arc_height:25});q.render();$("#center .unified-panel-header-inner").append(galaxy_config.app.viz_config.title+" "+galaxy_config.app.viz_config.dbkey);var p=create_icon_buttons_menu([{icon_class:"plus-button",title:"Add tracks",on_click:function(){i.select_datasets(galaxy_config.root+"visualization/list_current_history_datasets",galaxy_config.root+"api/datasets",o.get("dbkey"),function(r){o.add_tracks(r)})}},{icon_class:"disk--arrow",title:"Save",on_click:function(){Galaxy.modal.show({title:"Saving...",body:"progress"});var r=galaxy_config.app.viz_config;$.ajax({url:galaxy_config.root+"visualization/save",type:"POST",dataType:"json",data:{id:r.vis_id,title:r.title,dbkey:r.dbkey,type:"trackster",vis_json:JSON.stringify(r)}}).success(function(s){Galaxy.modal.hide();r.vis_id=s.vis_id;r.has_changes=false;window.history.pushState({},"",s.url+window.location.hash)}).error(function(){Galaxy.modal.show({title:"Could Not Save",body:"Could not save visualization. Please try again later.",buttons:{Cancel:function(){Galaxy.modal.hide()}}})})}},{icon_class:"cross-circle",title:"Close",on_click:function(){window.location=galaxy_config.root+"visualization/list"}}],{tooltip_config:{placement:"bottom"}});p.$el.attr("style","float: right");$("#center .unified-panel-header-inner").append(p.$el);$(".menu-button").tooltip({placement:"bottom"})}});return{GalaxyApp:e}});
\ No newline at end of file
+define(["utils/utils","libs/underscore","libs/d3","viz/visualization"],function(g,h,m,j){g.cssLoadFile("static/style/circster.css");var n=Backbone.Model.extend({is_visible:function(r,o){var p=r.getBoundingClientRect(),q=$("svg")[0].getBoundingClientRect();if(p.right<0||p.left>q.right||p.bottom<0||p.top>q.bottom){return false}return true}});var i={drawTicks:function(s,r,w,q,o){var v=s.append("g").selectAll("g").data(r).enter().append("g").selectAll("g").data(w).enter().append("g").attr("class","tick").attr("transform",function(x){return"rotate("+(x.angle*180/Math.PI-90)+")translate("+x.radius+",0)"});var u=[],t=[],p=function(x){return x.angle>Math.PI?"end":null};if(o){u=[0,0,0,-4];t=[4,0,"",".35em"];p=null}else{u=[1,0,4,0];t=[0,4,".35em",""]}v.append("line").attr("x1",u[0]).attr("y1",u[1]).attr("x2",u[2]).attr("y1",u[3]).style("stroke","#000");v.append("text").attr("x",t[0]).attr("y",t[1]).attr("dx",t[2]).attr("dy",t[3]).attr("text-anchor",p).attr("transform",q).text(function(x){return x.label})},formatNum:function(p,o){if(o===undefined){o=2}if(p===null){return null}var r=null;if(p<1){r=p.toPrecision(o)}else{var q=Math.round(p.toPrecision(o));if(p<1000){r=q}else{if(p<1000000){r=Math.round((q/1000).toPrecision(3)).toFixed(0)+"K"}else{if(p<1000000000){r=Math.round((q/1000000).toPrecision(3)).toFixed(0)+"M"}}}}return r}};var c=Backbone.Model.extend({});var a=Backbone.View.extend({className:"circster",initialize:function(o){this.total_gap=o.total_gap;this.genome=o.genome;this.dataset_arc_height=o.dataset_arc_height;this.track_gap=10;this.label_arc_height=50;this.scale=1;this.circular_views=null;this.chords_views=null;this.model.get("tracks").on("add",this.add_track,this);this.model.get("tracks").on("remove",this.remove_track,this);this.get_circular_tracks()},get_circular_tracks:function(){return this.model.get("tracks").filter(function(o){return o.get("track_type")!=="DiagonalHeatmapTrack"})},get_chord_tracks:function(){return this.model.get("tracks").filter(function(o){return o.get("track_type")==="DiagonalHeatmapTrack"})},get_tracks_bounds:function(){var p=this.get_circular_tracks();dataset_arc_height=this.dataset_arc_height,min_dimension=Math.min(this.$el.width(),this.$el.height()),radius_start=min_dimension/2-p.length*(this.dataset_arc_height+this.track_gap)-(this.label_arc_height+this.track_gap),tracks_start_radii=m.range(radius_start,min_dimension/2,this.dataset_arc_height+this.track_gap);var o=this;return h.map(tracks_start_radii,function(q){return[q,q+o.dataset_arc_height]})},render:function(){var x=this,r=this.dataset_arc_height,o=x.$el.width(),w=x.$el.height(),t=this.get_circular_tracks(),q=this.get_chord_tracks(),s=this.get_tracks_bounds(),p=m.select(x.$el[0]).append("svg").attr("width",o).attr("height",w).attr("pointer-events","all").append("svg:g").call(m.behavior.zoom().on("zoom",function(){var y=m.event.scale;p.attr("transform","translate("+m.event.translate+") scale("+y+")");if(x.scale!==y){if(x.zoom_drag_timeout){clearTimeout(x.zoom_drag_timeout)}x.zoom_drag_timeout=setTimeout(function(){},400)}})).attr("transform","translate("+o/2+","+w/2+")").append("svg:g").attr("class","tracks");this.circular_views=t.map(function(z,A){var y=new d({el:p.append("g")[0],track:z,radius_bounds:s[A],genome:x.genome,total_gap:x.total_gap});y.render();return y});this.chords_views=q.map(function(z){var y=new k({el:p.append("g")[0],track:z,radius_bounds:s[0],genome:x.genome,total_gap:x.total_gap});y.render();return y});var v=this.circular_views[this.circular_views.length-1].radius_bounds[1],u=[v,v+this.label_arc_height];this.label_track_view=new b({el:p.append("g")[0],track:new c(),radius_bounds:u,genome:x.genome,total_gap:x.total_gap});this.label_track_view.render()},add_track:function(u){if(u.get("track_type")==="DiagonalHeatmapTrack"){var q=this.circular_views[0].radius_bounds,t=new k({el:m.select("g.tracks").append("g")[0],track:u,radius_bounds:q,genome:this.genome,total_gap:this.total_gap});t.render();this.chords_views.push(t)}else{var s=this.get_tracks_bounds();h.each(this.circular_views,function(v,w){v.update_radius_bounds(s[w])});h.each(this.chords_views,function(v){v.update_radius_bounds(s[0])});var r=this.circular_views.length,o=new d({el:m.select("g.tracks").append("g")[0],track:u,radius_bounds:s[r],genome:this.genome,total_gap:this.total_gap});o.render();this.circular_views.push(o);var p=s[s.length-1];p[1]=p[0];this.label_track_view.update_radius_bounds(p)}},remove_track:function(p,r,q){var o=this.circular_views[q.index];this.circular_views.splice(q.index,1);o.$el.remove();var s=this.get_tracks_bounds();h.each(this.circular_views,function(t,u){t.update_radius_bounds(s[u])})}});var l=Backbone.View.extend({tagName:"g",initialize:function(o){this.bg_stroke="ccc";this.loading_bg_fill="000";this.bg_fill="ccc";this.total_gap=o.total_gap;this.track=o.track;this.radius_bounds=o.radius_bounds;this.genome=o.genome;this.chroms_layout=this._chroms_layout();this.data_bounds=[];this.scale=1;this.parent_elt=m.select(this.$el[0])},get_fill_color:function(){var o=this.track.get("config").get_value("block_color");if(!o){o=this.track.get("config").get_value("color")}return o},render:function(){var s=this.parent_elt;if(!s){console.log("no parent elt")}var r=this.chroms_layout,u=m.svg.arc().innerRadius(this.radius_bounds[0]).outerRadius(this.radius_bounds[1]),o=s.selectAll("g").data(r).enter().append("svg:g"),q=o.append("path").attr("d",u).attr("class","chrom-background").style("stroke",this.bg_stroke).style("fill",this.loading_bg_fill);q.append("title").text(function(w){return w.data.chrom});var p=this,t=p.track.get("data_manager"),v=(t?t.data_is_ready():true);$.when(v).then(function(){$.when(p._render_data(s)).then(function(){q.style("fill",p.bg_fill);p.render_labels()})})},render_labels:function(){},update_radius_bounds:function(p){this.radius_bounds=p;var o=m.svg.arc().innerRadius(this.radius_bounds[0]).outerRadius(this.radius_bounds[1]);this.parent_elt.selectAll("g>path.chrom-background").transition().duration(1000).attr("d",o);this._transition_chrom_data();this._transition_labels()},update_scale:function(r){var q=this.scale;this.scale=r;if(r<=q){return}var p=this,o=new n();this.parent_elt.selectAll("path.chrom-data").filter(function(t,s){return o.is_visible(this)}).each(function(y,u){var x=m.select(this),t=x.attr("chrom"),w=p.genome.get_chrom_region(t),v=p.track.get("data_manager"),s;if(!v.can_get_more_detailed_data(w)){return}s=p.track.get("data_manager").get_more_detailed_data(w,"Coverage",0,r);$.when(s).then(function(B){x.remove();p._update_data_bounds();var A=h.find(p.chroms_layout,function(C){return C.data.chrom===t});var z=p.get_fill_color();p._render_chrom_data(p.parent_elt,A,B).style("stroke",z).style("fill",z)})});return p},_transition_chrom_data:function(){var p=this.track,r=this.chroms_layout,o=this.parent_elt.selectAll("g>path.chrom-data"),s=o[0].length;if(s>0){var q=this;$.when(p.get("data_manager").get_genome_wide_data(this.genome)).then(function(u){var t=h.reject(h.map(u,function(v,w){var x=null,y=q._get_path_function(r[w],v);if(y){x=y(v.data)}return x}),function(v){return v===null});o.each(function(w,v){m.select(this).transition().duration(1000).attr("d",t[v])})})}},_transition_labels:function(){},_update_data_bounds:function(){var o=this.data_bounds;this.data_bounds=this.get_data_bounds(this.track.get("data_manager").get_genome_wide_data(this.genome));if(this.data_bounds[0]<o[0]||this.data_bounds[1]>o[1]){this._transition_chrom_data()}},_render_data:function(r){var q=this,p=this.chroms_layout,o=this.track,s=$.Deferred();$.when(o.get("data_manager").get_genome_wide_data(this.genome)).then(function(u){q.data_bounds=q.get_data_bounds(u);layout_and_data=h.zip(p,u),chroms_data_layout=h.map(layout_and_data,function(v){var w=v[0],x=v[1];return q._render_chrom_data(r,w,x)});var t=q.get_fill_color();q.parent_elt.selectAll("path.chrom-data").style("stroke",t).style("fill",t);s.resolve(r)});return s},_render_chrom_data:function(o,p,q){},_get_path_function:function(p,o){},_chroms_layout:function(){var p=this.genome.get_chroms_info(),r=m.layout.pie().value(function(t){return t.len}).sort(null),s=r(p),o=this.total_gap/p.length,q=h.map(s,function(v,u){var t=v.endAngle-o;v.endAngle=(t>v.startAngle?t:v.startAngle);return v});return q}});var b=l.extend({initialize:function(o){l.prototype.initialize.call(this,o);this.innerRadius=this.radius_bounds[0];this.radius_bounds[0]=this.radius_bounds[1];this.bg_stroke="fff";this.bg_fill="fff";this.min_arc_len=0.05},_render_data:function(q){var p=this,o=q.selectAll("g");o.selectAll("path").attr("id",function(u){return"label-"+u.data.chrom});o.append("svg:text").filter(function(u){return u.endAngle-u.startAngle>p.min_arc_len}).attr("text-anchor","middle").append("svg:textPath").attr("class","chrom-label").attr("xlink:href",function(u){return"#label-"+u.data.chrom}).attr("startOffset","25%").text(function(u){return u.data.chrom});var r=function(w){var u=(w.endAngle-w.startAngle)/w.value,v=m.range(0,w.value,25000000).map(function(x,y){return{radius:p.innerRadius,angle:x*u+w.startAngle,label:y===0?0:(y%3?null:p.formatNum(x))}});if(v.length<4){v[v.length-1].label=p.formatNum(Math.round((v[v.length-1].angle-w.startAngle)/u))}return v};var t=function(u){return u.angle>Math.PI?"rotate(180)translate(-16)":null};var s=h.filter(this.chroms_layout,function(u){return u.endAngle-u.startAngle>p.min_arc_len});this.drawTicks(this.parent_elt,s,r,t)}});h.extend(b.prototype,i);var f=l.extend({_quantile:function(p,o){p.sort(m.ascending);return m.quantile(p,o)},_render_chrom_data:function(o,r,p){var s=this._get_path_function(r,p);if(!s){return null}var q=o.datum(p.data),t=q.append("path").attr("class","chrom-data").attr("chrom",r.data.chrom).attr("d",s);return t},_get_path_function:function(r,q){if(typeof q==="string"||!q.data||q.data.length===0){return null}var o=m.scale.linear().domain(this.data_bounds).range(this.radius_bounds).clamp(true);var s=m.scale.linear().domain([0,q.data.length]).range([r.startAngle,r.endAngle]);var p=m.svg.line.radial().interpolate("linear").radius(function(t){return o(t[1])}).angle(function(u,t){return s(t)});return m.svg.area.radial().interpolate(p.interpolate()).innerRadius(o(0)).outerRadius(p.radius()).angle(p.angle())},render_labels:function(){var o=this,p=function(){return"rotate(90)"};this.drawTicks(this.parent_elt,[this.chroms_layout[0]],this._data_bounds_ticks_fn(),p,true)},_transition_labels:function(){if(this.data_bounds.length===0){return}var p=this,r=h.filter(this.chroms_layout,function(s){return s.endAngle-s.startAngle>0.08}),q=h.filter(r,function(t,s){return s%3===0}),o=h.flatten(h.map(q,function(s){return p._data_bounds_ticks_fn()(s)}));this.parent_elt.selectAll("g.tick").data(o).transition().attr("transform",function(s){return"rotate("+(s.angle*180/Math.PI-90)+")translate("+s.radius+",0)"})},_data_bounds_ticks_fn:function(){var o=this;visibleChroms=0;return function(p){return[{radius:o.radius_bounds[0],angle:p.startAngle,label:o.formatNum(o.data_bounds[0])},{radius:o.radius_bounds[1],angle:p.startAngle,label:o.formatNum(o.data_bounds[1])}]}},get_data_bounds:function(o){}});h.extend(f.prototype,i);var d=f.extend({get_data_bounds:function(p){var o=h.flatten(h.map(p,function(q){if(q){return h.map(q.data,function(r){return parseInt(r[1],10)||0})}else{return 0}}));return[h.min(o),this._quantile(o,0.98)||h.max(o)]}});var k=l.extend({render:function(){var o=this;$.when(o.track.get("data_manager").data_is_ready()).then(function(){$.when(o.track.get("data_manager").get_genome_wide_data(o.genome)).then(function(r){var q=[],p=o.genome.get_chroms_info();h.each(r,function(v,u){var s=p[u].chrom;var t=h.map(v.data,function(x){var w=o._get_region_angle(s,x[1]),y=o._get_region_angle(x[3],x[4]);return{source:{startAngle:w,endAngle:w+0.01},target:{startAngle:y,endAngle:y+0.01}}});q=q.concat(t)});o.parent_elt.append("g").attr("class","chord").selectAll("path").data(q).enter().append("path").style("fill",o.get_fill_color()).attr("d",m.svg.chord().radius(o.radius_bounds[0])).style("opacity",1)})})},update_radius_bounds:function(o){this.radius_bounds=o;this.parent_elt.selectAll("path").transition().attr("d",m.svg.chord().radius(this.radius_bounds[0]))},_get_region_angle:function(q,o){var p=h.find(this.chroms_layout,function(r){return r.data.chrom===q});return p.endAngle-((p.endAngle-p.startAngle)*(p.data.len-o)/p.data.len)}});var e=Backbone.View.extend({initialize:function(){var o=new j.Genome(galaxy_config.app.genome),p=new j.GenomeVisualization(galaxy_config.app.viz_config),r=new a({el:$("#center .unified-panel-body"),total_gap:2*Math.PI*0.4,genome:o,model:p,dataset_arc_height:25});r.render();$("#center .unified-panel-header-inner").append(galaxy_config.app.viz_config.title+" "+galaxy_config.app.viz_config.dbkey);var q=create_icon_buttons_menu([{icon_class:"plus-button",title:"Add tracks",on_click:function(){j.select_datasets(galaxy_config.root+"visualization/list_current_history_datasets",galaxy_config.root+"api/datasets",p.get("dbkey"),function(s){p.add_tracks(s)})}},{icon_class:"disk--arrow",title:"Save",on_click:function(){Galaxy.modal.show({title:"Saving...",body:"progress"});var s=galaxy_config.app.viz_config;$.ajax({url:galaxy_config.root+"visualization/save",type:"POST",dataType:"json",data:{id:s.vis_id,title:s.title,dbkey:s.dbkey,type:"trackster",vis_json:JSON.stringify(s)}}).success(function(t){Galaxy.modal.hide();s.vis_id=t.vis_id;s.has_changes=false;window.history.pushState({},"",t.url+window.location.hash)}).error(function(){Galaxy.modal.show({title:"Could Not Save",body:"Could not save visualization. Please try again later.",buttons:{Cancel:function(){Galaxy.modal.hide()}}})})}},{icon_class:"cross-circle",title:"Close",on_click:function(){window.location=galaxy_config.root+"visualization/list"}}],{tooltip_config:{placement:"bottom"}});q.$el.attr("style","float: right");$("#center .unified-panel-header-inner").append(q.$el);$(".menu-button").tooltip({placement:"bottom"})}});return{GalaxyApp:e}});
\ No newline at end of file
diff -r aaabd336009044d2d6f748eaca483ccab0950435 -r 7fd2f3f098840a5a1b9d7041330100c4f2af70df static/scripts/packed/viz/visualization.js
--- a/static/scripts/packed/viz/visualization.js
+++ b/static/scripts/packed/viz/visualization.js
@@ -1,1 +1,1 @@
-define(["libs/underscore","mvc/data","viz/trackster/util","utils/config"],function(t,j,m,p){var a=function(v,y,x,w){$.ajax({url:v,data:x,error:function(){alert("Grid failed")},success:function(z){Galaxy.modal.show({title:"Select datasets for new tracks",body:z,buttons:{Cancel:function(){Galaxy.modal.hide()},Add:function(){var A=[];$("input[name=id]:checked,input[name=ldda_ids]:checked").each(function(){var B={data_type:"track_config",hda_ldda:"hda"},C=$(this).val();if($(this).attr("name")!=="id"){B.hda_ldda="ldda"}A[A.length]=$.ajax({url:y+"/"+C,data:B,dataType:"json"})});$.when.apply($,A).then(function(){var B=(arguments[0] instanceof Array?$.map(arguments,function(C){return C[0]}):[arguments[0]]);w(B)});Galaxy.modal.hide()}}})}})};var k=function(v){return("promise" in v)};var f=function(v){this.default_font=v!==undefined?v:"9px Monaco, Lucida Console, monospace";this.dummy_canvas=this.new_canvas();this.dummy_context=this.dummy_canvas.getContext("2d");this.dummy_context.font=this.default_font;this.char_width_px=this.dummy_context.measureText("A").width;this.patterns={};this.load_pattern("right_strand","/visualization/strand_right.png");this.load_pattern("left_strand","/visualization/strand_left.png");this.load_pattern("right_strand_inv","/visualization/strand_right_inv.png");this.load_pattern("left_strand_inv","/visualization/strand_left_inv.png")};t.extend(f.prototype,{load_pattern:function(v,z){var w=this.patterns,x=this.dummy_context,y=new Image();y.src=galaxy_config.root+"static/images"+z;y.onload=function(){w[v]=x.createPattern(y,"repeat")}},get_pattern:function(v){return this.patterns[v]},new_canvas:function(){var v=$("<canvas/>")[0];if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(v)}v.manager=this;return v}});var r=Backbone.Model.extend({defaults:{num_elements:20,obj_cache:null,key_ary:null},initialize:function(v){this.clear()},get_elt:function(x){var y=this.attributes.obj_cache,z=this.attributes.key_ary,w=x.toString(),v=t.indexOf(z,function(A){return A.toString()===w});if(v!==-1){if(y[w].stale){z.splice(v,1);delete y[w]}else{this.move_key_to_end(x,v)}}return y[w]},set_elt:function(x,z){var A=this.attributes.obj_cache,B=this.attributes.key_ary,w=x.toString(),y=this.attributes.num_elements;if(!A[w]){if(B.length>=y){var v=B.shift();delete A[v.toString()]}B.push(x)}A[w]=z;return z},move_key_to_end:function(w,v){this.attributes.key_ary.splice(v,1);this.attributes.key_ary.push(w)},clear:function(){this.attributes.obj_cache={};this.attributes.key_ary=[]},size:function(){return this.attributes.key_ary.length},most_recently_added:function(){return this.size()===0?null:this.attributes.key_ary[this.attributes.key_ary.length-1]}});var d=r.extend({defaults:t.extend({},r.prototype.defaults,{dataset:null,genome:null,init_data:null,min_region_size:200,filters_manager:null,data_type:"data",data_mode_compatible:function(v,w){return true},can_subset:function(v){return false}}),initialize:function(v){r.prototype.initialize.call(this);var w=this.get("init_data");if(w){this.add_data(w)}},add_data:function(v){if(this.get("num_elements")<v.length){this.set("num_elements",v.length)}var w=this;t.each(v,function(x){w.set_data(x.region,x)})},data_is_ready:function(){var y=this.get("dataset"),x=$.Deferred(),v=(this.get("data_type")==="raw_data"?"state":this.get("data_type")==="data"?"converted_datasets_state":"error"),w=new m.ServerStateDeferred({ajax_settings:{url:this.get("dataset").url(),data:{hda_ldda:y.get("hda_ldda"),data_type:v},dataType:"json"},interval:5000,success_fn:function(z){return z!=="pending"}});$.when(w.go()).then(function(z){x.resolve(z==="ok"||z==="data")});return x},search_features:function(v){var w=this.get("dataset"),x={query:v,hda_ldda:w.get("hda_ldda"),data_type:"features"};return $.getJSON(w.url(),x)},load_data:function(D,C,w,B){var z=this.get("dataset"),y={data_type:this.get("data_type"),chrom:D.get("chrom"),low:D.get("start"),high:D.get("end"),mode:C,resolution:w,hda_ldda:z.get("hda_ldda")};$.extend(y,B);var F=this.get("filters_manager");if(F){var G=[];var v=F.filters;for(var A=0;A<v.length;A++){G.push(v[A].name)}y.filter_cols=JSON.stringify(G)}var x=this,E=$.getJSON(z.url(),y,function(H){H.region=D;x.set_data(D,H)});this.set_data(D,E);return E},get_data:function(C,B,x,z){var D=this.get_elt(C);if(D&&(k(D)||this.get("data_mode_compatible")(D,B))){return D}var E=this.get("key_ary"),v=this.get("obj_cache"),w,A;for(var y=0;y<E.length;y++){w=E[y];if(w.contains(C)){A=true;D=v[w.toString()];if(k(D)||(this.get("data_mode_compatible")(D,B)&&this.get("can_subset")(D))){this.move_key_to_end(w,y);if(!k(D)){var G=this.subset_entry(D,C);this.set(C,G);D=G}return D}}}if(!A&&C.length()<this.attributes.min_region_size){C=C.copy();var F=this.most_recently_added();if(!F||(C.get("start")>F.get("start"))){C.set("end",C.get("start")+this.attributes.min_region_size)}else{C.set("start",C.get("end")-this.attributes.min_region_size)}C.set("genome",this.attributes.genome);C.trim()}return this.load_data(C,B,x,z)},set_data:function(w,v){this.set_elt(w,v)},DEEP_DATA_REQ:"deep",BROAD_DATA_REQ:"breadth",get_more_data:function(D,C,y,B,z){var F=this._mark_stale(D);if(!(F&&this.get("data_mode_compatible")(F,C))){console.log("ERROR: problem with getting more data: current data is not compatible");return}var x=D.get("start");if(z===this.DEEP_DATA_REQ){$.extend(B,{start_val:F.data.length+1})}else{if(z===this.BROAD_DATA_REQ){x=(F.max_high?F.max_high:F.data[F.data.length-1][2])+1}}var E=D.copy().set("start",x);var w=this,A=this.load_data(E,C,y,B),v=$.Deferred();this.set_data(D,v);$.when(A).then(function(G){if(G.data){G.data=F.data.concat(G.data);if(G.max_low){G.max_low=F.max_low}if(G.message){G.message=G.message.replace(/[0-9]+/,G.data.length)}}w.set_data(D,G);v.resolve(G)});return v},can_get_more_detailed_data:function(w){var v=this.get_elt(w);return(v.dataset_type==="bigwig"&&v.data.length<8000)},get_more_detailed_data:function(y,A,w,z,x){var v=this._mark_stale(y);if(!v){console.log("ERROR getting more detailed data: no current data");return}if(!x){x={}}if(v.dataset_type==="bigwig"){x.num_samples=1000*z}return this.load_data(y,A,w,x)},_mark_stale:function(w){var v=this.get_elt(w);if(!v){console.log("ERROR: no data to mark as stale: ",this.get("dataset"),w.toString())}v.stale=true;return v},get_genome_wide_data:function(v){var x=this,z=true,y=t.map(v.get("chroms_info").chrom_info,function(B){var A=x.get_elt(new g({chrom:B.chrom,start:0,end:B.len}));if(!A){z=false}return A});if(z){return y}var w=$.Deferred();$.getJSON(this.get("dataset").url(),{data_type:"genome_data"},function(A){x.add_data(A.data);w.resolve(A.data)});return w},subset_entry:function(x,y){var v={bigwig:function(z,A){return t.filter(z,function(B){return B[0]>=A.get("start")&&B[0]<=A.get("end")})},refseq:function(A,B){var C=B.get("start")-x.region.get("start"),z=x.data.length-(x.region.get("end")-B.get("end"));return x.data.slice(C,z)}};var w=x.data;if(!x.region.same(y)&&x.dataset_type in v){w=v[x.dataset_type](x.data,y)}return{region:y,data:w,dataset_type:x.dataset_type}}});var q=d.extend({initialize:function(v){var w=new Backbone.Model();w.urlRoot=v.data_url;this.set("dataset",w)},load_data:function(x,y,v,w){return(x.length()<=100000?d.prototype.load_data.call(this,x,y,v,w):{data:null,region:x})}});var c=Backbone.Model.extend({defaults:{name:null,key:null,chroms_info:null},initialize:function(v){this.id=v.dbkey},get_chroms_info:function(){return this.attributes.chroms_info.chrom_info},get_chrom_region:function(v){var w=t.find(this.get_chroms_info(),function(x){return x.chrom===v});return new g({chrom:w.chrom,end:w.len})},get_chrom_len:function(v){return t.find(this.get_chroms_info(),function(w){return w.chrom===v}).len}});var g=Backbone.Model.extend({defaults:{chrom:null,start:0,end:0,str_val:null,genome:null},same:function(v){return this.attributes.chrom===v.get("chrom")&&this.attributes.start===v.get("start")&&this.attributes.end===v.get("end")},initialize:function(w){if(w.from_str){var y=w.from_str.split(":"),x=y[0],v=y[1].split("-");this.set({chrom:x,start:parseInt(v[0],10),end:parseInt(v[1],10)})}this.attributes.str_val=this.get("chrom")+":"+this.get("start")+"-"+this.get("end");this.on("change",function(){this.attributes.str_val=this.get("chrom")+":"+this.get("start")+"-"+this.get("end")},this)},copy:function(){return new g({chrom:this.get("chrom"),start:this.get("start"),end:this.get("end")})},length:function(){return this.get("end")-this.get("start")},toString:function(){return this.attributes.str_val},toJSON:function(){return{chrom:this.get("chrom"),start:this.get("start"),end:this.get("end")}},compute_overlap:function(C){var w=this.get("chrom"),B=C.get("chrom"),A=this.get("start"),y=C.get("start"),z=this.get("end"),x=C.get("end"),v;if(w&&B&&w!==B){return g.overlap_results.DIF_CHROMS}if(A<y){if(z<y){v=g.overlap_results.BEFORE}else{if(z<x){v=g.overlap_results.OVERLAP_START}else{v=g.overlap_results.CONTAINS}}}else{if(A>y){if(A>x){v=g.overlap_results.AFTER}else{if(z<=x){v=g.overlap_results.CONTAINED_BY}else{v=g.overlap_results.OVERLAP_END}}}else{v=(z>=x?g.overlap_results.CONTAINS:g.overlap_results.CONTAINED_BY)}}return v},trim:function(v){if(this.attributes.start<0){this.attributes.start=0}if(this.attributes.genome){var w=this.attributes.genome.get_chrom_len(this.attributes.chrom);if(this.attributes.end>w){this.attributes.end=w-1}}return this},contains:function(v){return this.compute_overlap(v)===g.overlap_results.CONTAINS},overlaps:function(v){return t.intersection([this.compute_overlap(v)],[g.overlap_results.DIF_CHROMS,g.overlap_results.BEFORE,g.overlap_results.AFTER]).length===0}},{overlap_results:{DIF_CHROMS:1000,BEFORE:1001,CONTAINS:1002,OVERLAP_START:1003,OVERLAP_END:1004,CONTAINED_BY:1005,AFTER:1006}});var n=Backbone.Collection.extend({model:g});var e=Backbone.Model.extend({defaults:{region:null,note:""},initialize:function(v){this.set("region",new g(v.region))}});var s=Backbone.Collection.extend({model:e});var u=Backbone.Model.extend({initialize:function(v){this.set("dataset",new j.Dataset("dataset"));this.set("config",p.ConfigSettingCollection.from_config_dict(v.prefs));this.get("config").add([{key:"name",value:this.get("name")},{key:"color"}]);var w=this.get("preloaded_data");if(w){w=w.data}else{w=[]}this.set("data_manager",new d({dataset:this.get("dataset"),init_data:w}))}});var i=new Backbone.Collection.extend({model:u});var o=Backbone.Model.extend({defaults:{title:"",type:""},url:galaxy_config.root+"visualization/save",save:function(){return $.ajax({url:this.url(),type:"POST",dataType:"json",data:{vis_json:JSON.stringify(this)}})}});var l=o.extend({defaults:t.extend({},o.prototype.defaults,{dbkey:"",tracks:null,bookmarks:null,viewport:null}),initialize:function(v){this.set("tracks",new i(v.tracks))},add_tracks:function(v){this.get("tracks").add(v)}});var b=Backbone.Model.extend({});var h=Backbone.Router.extend({initialize:function(w){this.view=w.view;this.route(/([\w]+)$/,"change_location");this.route(/([\w]+\:[\d,]+-[\d,]+)$/,"change_location");var v=this;v.view.on("navigate",function(x){v.navigate(x)})},change_location:function(v){this.view.go_to(v)}});return{BackboneTrack:u,BrowserBookmark:e,BrowserBookmarkCollection:s,Cache:r,CanvasManager:f,Genome:c,GenomeDataManager:d,GenomeRegion:g,GenomeRegionCollection:n,GenomeVisualization:l,GenomeReferenceDataManager:q,TrackBrowserRouter:h,TrackConfig:b,Visualization:o,select_datasets:a}});
\ No newline at end of file
+define(["libs/underscore","mvc/data","viz/trackster/util","utils/config"],function(t,j,m,p){var a=function(v,y,x,w){$.ajax({url:v,data:x,error:function(){alert("Grid failed")},success:function(z){Galaxy.modal.show({title:"Select datasets for new tracks",body:z,buttons:{Cancel:function(){Galaxy.modal.hide()},Add:function(){var A=[];$("input[name=id]:checked,input[name=ldda_ids]:checked").each(function(){var B={data_type:"track_config",hda_ldda:"hda"},C=$(this).val();if($(this).attr("name")!=="id"){B.hda_ldda="ldda"}A[A.length]=$.ajax({url:y+"/"+C,data:B,dataType:"json"})});$.when.apply($,A).then(function(){var B=(arguments[0] instanceof Array?$.map(arguments,function(C){return C[0]}):[arguments[0]]);w(B)});Galaxy.modal.hide()}}})}})};var k=function(v){return("promise" in v)};var f=function(v){this.default_font=v!==undefined?v:"9px Monaco, Lucida Console, monospace";this.dummy_canvas=this.new_canvas();this.dummy_context=this.dummy_canvas.getContext("2d");this.dummy_context.font=this.default_font;this.char_width_px=this.dummy_context.measureText("A").width;this.patterns={};this.load_pattern("right_strand","/visualization/strand_right.png");this.load_pattern("left_strand","/visualization/strand_left.png");this.load_pattern("right_strand_inv","/visualization/strand_right_inv.png");this.load_pattern("left_strand_inv","/visualization/strand_left_inv.png")};t.extend(f.prototype,{load_pattern:function(v,z){var w=this.patterns,x=this.dummy_context,y=new Image();y.src=galaxy_config.root+"static/images"+z;y.onload=function(){w[v]=x.createPattern(y,"repeat")}},get_pattern:function(v){return this.patterns[v]},new_canvas:function(){var v=$("<canvas/>")[0];if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(v)}v.manager=this;return v}});var r=Backbone.Model.extend({defaults:{num_elements:20,obj_cache:null,key_ary:null},initialize:function(v){this.clear()},get_elt:function(x){var y=this.attributes.obj_cache,z=this.attributes.key_ary,w=x.toString(),v=t.indexOf(z,function(A){return A.toString()===w});if(v!==-1){if(y[w].stale){z.splice(v,1);delete y[w]}else{this.move_key_to_end(x,v)}}return y[w]},set_elt:function(x,z){var A=this.attributes.obj_cache,B=this.attributes.key_ary,w=x.toString(),y=this.attributes.num_elements;if(!A[w]){if(B.length>=y){var v=B.shift();delete A[v.toString()]}B.push(x)}A[w]=z;return z},move_key_to_end:function(w,v){this.attributes.key_ary.splice(v,1);this.attributes.key_ary.push(w)},clear:function(){this.attributes.obj_cache={};this.attributes.key_ary=[]},size:function(){return this.attributes.key_ary.length},most_recently_added:function(){return this.size()===0?null:this.attributes.key_ary[this.attributes.key_ary.length-1]}});var d=r.extend({defaults:t.extend({},r.prototype.defaults,{dataset:null,genome:null,init_data:null,min_region_size:200,filters_manager:null,data_type:"data",data_mode_compatible:function(v,w){return true},can_subset:function(v){return false}}),initialize:function(v){r.prototype.initialize.call(this);var w=this.get("init_data");if(w){this.add_data(w)}},add_data:function(v){if(this.get("num_elements")<v.length){this.set("num_elements",v.length)}var w=this;t.each(v,function(x){w.set_data(x.region,x)})},data_is_ready:function(){var y=this.get("dataset"),x=$.Deferred(),v=(this.get("data_type")==="raw_data"?"state":this.get("data_type")==="data"?"converted_datasets_state":"error"),w=new m.ServerStateDeferred({ajax_settings:{url:this.get("dataset").url(),data:{hda_ldda:y.get("hda_ldda"),data_type:v},dataType:"json"},interval:5000,success_fn:function(z){return z!=="pending"}});$.when(w.go()).then(function(z){x.resolve(z==="ok"||z==="data")});return x},search_features:function(v){var w=this.get("dataset"),x={query:v,hda_ldda:w.get("hda_ldda"),data_type:"features"};return $.getJSON(w.url(),x)},load_data:function(D,C,w,B){var z=this.get("dataset"),y={data_type:this.get("data_type"),chrom:D.get("chrom"),low:D.get("start"),high:D.get("end"),mode:C,resolution:w,hda_ldda:z.get("hda_ldda")};$.extend(y,B);var F=this.get("filters_manager");if(F){var G=[];var v=F.filters;for(var A=0;A<v.length;A++){G.push(v[A].name)}y.filter_cols=JSON.stringify(G)}var x=this,E=$.getJSON(z.url(),y,function(H){H.region=D;x.set_data(D,H)});this.set_data(D,E);return E},get_data:function(C,B,x,z){var D=this.get_elt(C);if(D&&(k(D)||this.get("data_mode_compatible")(D,B))){return D}var E=this.get("key_ary"),v=this.get("obj_cache"),w,A;for(var y=0;y<E.length;y++){w=E[y];if(w.contains(C)){A=true;D=v[w.toString()];if(k(D)||(this.get("data_mode_compatible")(D,B)&&this.get("can_subset")(D))){this.move_key_to_end(w,y);if(!k(D)){var G=this.subset_entry(D,C);this.set(C,G);D=G}return D}}}if(!A&&C.length()<this.attributes.min_region_size){C=C.copy();var F=this.most_recently_added();if(!F||(C.get("start")>F.get("start"))){C.set("end",C.get("start")+this.attributes.min_region_size)}else{C.set("start",C.get("end")-this.attributes.min_region_size)}C.set("genome",this.attributes.genome);C.trim()}return this.load_data(C,B,x,z)},set_data:function(w,v){this.set_elt(w,v)},DEEP_DATA_REQ:"deep",BROAD_DATA_REQ:"breadth",get_more_data:function(D,C,y,B,z){var F=this._mark_stale(D);if(!(F&&this.get("data_mode_compatible")(F,C))){console.log("ERROR: problem with getting more data: current data is not compatible");return}var x=D.get("start");if(z===this.DEEP_DATA_REQ){$.extend(B,{start_val:F.data.length+1})}else{if(z===this.BROAD_DATA_REQ){x=(F.max_high?F.max_high:F.data[F.data.length-1][2])+1}}var E=D.copy().set("start",x);var w=this,A=this.load_data(E,C,y,B),v=$.Deferred();this.set_data(D,v);$.when(A).then(function(G){if(G.data){G.data=F.data.concat(G.data);if(G.max_low){G.max_low=F.max_low}if(G.message){G.message=G.message.replace(/[0-9]+/,G.data.length)}}w.set_data(D,G);v.resolve(G)});return v},can_get_more_detailed_data:function(w){var v=this.get_elt(w);return(v.dataset_type==="bigwig"&&v.data.length<8000)},get_more_detailed_data:function(y,A,w,z,x){var v=this._mark_stale(y);if(!v){console.log("ERROR getting more detailed data: no current data");return}if(!x){x={}}if(v.dataset_type==="bigwig"){x.num_samples=1000*z}return this.load_data(y,A,w,x)},_mark_stale:function(w){var v=this.get_elt(w);if(!v){console.log("ERROR: no data to mark as stale: ",this.get("dataset"),w.toString())}v.stale=true;return v},get_genome_wide_data:function(v){var x=this,z=true,y=t.map(v.get("chroms_info").chrom_info,function(B){var A=x.get_elt(new g({chrom:B.chrom,start:0,end:B.len}));if(!A){z=false}return A});if(z){return y}var w=$.Deferred();$.getJSON(this.get("dataset").url(),{data_type:"genome_data"},function(A){x.add_data(A.data);w.resolve(A.data)});return w},subset_entry:function(x,y){var v={bigwig:function(z,A){return t.filter(z,function(B){return B[0]>=A.get("start")&&B[0]<=A.get("end")})},refseq:function(A,B){var C=B.get("start")-x.region.get("start"),z=x.data.length-(x.region.get("end")-B.get("end"));return x.data.slice(C,z)}};var w=x.data;if(!x.region.same(y)&&x.dataset_type in v){w=v[x.dataset_type](x.data,y)}return{region:y,data:w,dataset_type:x.dataset_type}}});var q=d.extend({initialize:function(v){var w=new Backbone.Model();w.urlRoot=v.data_url;this.set("dataset",w)},load_data:function(x,y,v,w){return(x.length()<=100000?d.prototype.load_data.call(this,x,y,v,w):{data:null,region:x})}});var c=Backbone.Model.extend({defaults:{name:null,key:null,chroms_info:null},initialize:function(v){this.id=v.dbkey},get_chroms_info:function(){return this.attributes.chroms_info.chrom_info},get_chrom_region:function(v){var w=t.find(this.get_chroms_info(),function(x){return x.chrom===v});return new g({chrom:w.chrom,end:w.len})},get_chrom_len:function(v){return t.find(this.get_chroms_info(),function(w){return w.chrom===v}).len}});var g=Backbone.Model.extend({defaults:{chrom:null,start:0,end:0,str_val:null,genome:null},same:function(v){return this.attributes.chrom===v.get("chrom")&&this.attributes.start===v.get("start")&&this.attributes.end===v.get("end")},initialize:function(w){if(w.from_str){var y=w.from_str.split(":"),x=y[0],v=y[1].split("-");this.set({chrom:x,start:parseInt(v[0],10),end:parseInt(v[1],10)})}this.attributes.str_val=this.get("chrom")+":"+this.get("start")+"-"+this.get("end");this.on("change",function(){this.attributes.str_val=this.get("chrom")+":"+this.get("start")+"-"+this.get("end")},this)},copy:function(){return new g({chrom:this.get("chrom"),start:this.get("start"),end:this.get("end")})},length:function(){return this.get("end")-this.get("start")},toString:function(){return this.attributes.str_val},toJSON:function(){return{chrom:this.get("chrom"),start:this.get("start"),end:this.get("end")}},compute_overlap:function(C){var w=this.get("chrom"),B=C.get("chrom"),A=this.get("start"),y=C.get("start"),z=this.get("end"),x=C.get("end"),v;if(w&&B&&w!==B){return g.overlap_results.DIF_CHROMS}if(A<y){if(z<y){v=g.overlap_results.BEFORE}else{if(z<x){v=g.overlap_results.OVERLAP_START}else{v=g.overlap_results.CONTAINS}}}else{if(A>y){if(A>x){v=g.overlap_results.AFTER}else{if(z<=x){v=g.overlap_results.CONTAINED_BY}else{v=g.overlap_results.OVERLAP_END}}}else{v=(z>=x?g.overlap_results.CONTAINS:g.overlap_results.CONTAINED_BY)}}return v},trim:function(v){if(this.attributes.start<0){this.attributes.start=0}if(this.attributes.genome){var w=this.attributes.genome.get_chrom_len(this.attributes.chrom);if(this.attributes.end>w){this.attributes.end=w-1}}return this},contains:function(v){return this.compute_overlap(v)===g.overlap_results.CONTAINS},overlaps:function(v){return t.intersection([this.compute_overlap(v)],[g.overlap_results.DIF_CHROMS,g.overlap_results.BEFORE,g.overlap_results.AFTER]).length===0}},{overlap_results:{DIF_CHROMS:1000,BEFORE:1001,CONTAINS:1002,OVERLAP_START:1003,OVERLAP_END:1004,CONTAINED_BY:1005,AFTER:1006}});var n=Backbone.Collection.extend({model:g});var e=Backbone.Model.extend({defaults:{region:null,note:""},initialize:function(v){this.set("region",new g(v.region))}});var s=Backbone.Collection.extend({model:e});var u=Backbone.Model.extend({initialize:function(v){this.set("dataset",new j.Dataset(v.dataset));this.set("config",p.ConfigSettingCollection.from_config_dict(v.prefs));this.get("config").add([{key:"name",value:this.get("name")},{key:"color"}]);var w=this.get("preloaded_data");if(w){w=w.data}else{w=[]}this.set("data_manager",new d({dataset:this.get("dataset"),init_data:w}))}});var i=Backbone.Collection.extend({model:u});var o=Backbone.Model.extend({defaults:{title:"",type:""},url:galaxy_config.root+"visualization/save",save:function(){return $.ajax({url:this.url(),type:"POST",dataType:"json",data:{vis_json:JSON.stringify(this)}})}});var l=o.extend({defaults:t.extend({},o.prototype.defaults,{dbkey:"",tracks:null,bookmarks:null,viewport:null}),initialize:function(v){this.set("tracks",new i(v.tracks))},add_tracks:function(v){this.get("tracks").add(v)}});var b=Backbone.Model.extend({});var h=Backbone.Router.extend({initialize:function(w){this.view=w.view;this.route(/([\w]+)$/,"change_location");this.route(/([\w]+\:[\d,]+-[\d,]+)$/,"change_location");var v=this;v.view.on("navigate",function(x){v.navigate(x)})},change_location:function(v){this.view.go_to(v)}});return{BackboneTrack:u,BrowserBookmark:e,BrowserBookmarkCollection:s,Cache:r,CanvasManager:f,Genome:c,GenomeDataManager:d,GenomeRegion:g,GenomeRegionCollection:n,GenomeVisualization:l,GenomeReferenceDataManager:q,TrackBrowserRouter:h,TrackConfig:b,Visualization:o,select_datasets: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: martenson: bind click-to-close on upload modal
by commits-noreply@bitbucket.org 23 Jan '14
by commits-noreply@bitbucket.org 23 Jan '14
23 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/aaabd3360090/
Changeset: aaabd3360090
User: martenson
Date: 2014-01-23 19:18:39
Summary: bind click-to-close on upload modal
Affected #: 4 files
diff -r 658d07c0f8442657229062cfdc5f3fe6b6bd00e8 -r aaabd336009044d2d6f748eaca483ccab0950435 static/scripts/galaxy.modal.js
--- a/static/scripts/galaxy.modal.js
+++ b/static/scripts/galaxy.modal.js
@@ -152,11 +152,13 @@
// bind additional closing events
if (this.options.closing_events) {
// bind the ESC key to hide() function
- $(document).on('keyup', function(e) {
- if (e.keyCode == 27) {
- self.hide();
- }
- });
+ if (!this.options.buttons.Pause){ // don't bind for the upload modal because of the side effects with system modal for file choosing
+ $(document).on('keyup', function(e) {
+ if (e.keyCode == 27) {
+ self.hide();
+ }
+ });
+ }
// hide modal if background is clicked
this.$el.find('.modal-backdrop').on('click', function() { self.hide(); });
diff -r 658d07c0f8442657229062cfdc5f3fe6b6bd00e8 -r aaabd336009044d2d6f748eaca483ccab0950435 static/scripts/mvc/upload/upload-view.js
--- a/static/scripts/mvc/upload/upload-view.js
+++ b/static/scripts/mvc/upload/upload-view.js
@@ -262,8 +262,7 @@
},
height : '400',
width : '900',
- bindClosingEvents : true,
- bindEscKey : false
+ closing_events : true
});
// set element
diff -r 658d07c0f8442657229062cfdc5f3fe6b6bd00e8 -r aaabd336009044d2d6f748eaca483ccab0950435 static/scripts/packed/galaxy.modal.js
--- a/static/scripts/packed/galaxy.modal.js
+++ b/static/scripts/packed/galaxy.modal.js
@@ -1,1 +1,1 @@
-define([],function(){var a=Backbone.View.extend({elMain:"#everything",optionsDefault:{title:"galaxy-modal",body:"",backdrop:true,height:null,width:null,closing_events:false},buttonList:{},initialize:function(b){if(b){this._create(b)}},show:function(b){this.initialize(b);if(this.options.height){this.$body.css("height",this.options.height);this.$body.css("overflow","hidden")}else{this.$body.css("max-height",$(window).height()/2)}if(this.options.width){this.$dialog.css("width",this.options.width)}if(this.visible){this.$el.show()}else{this.$el.fadeIn("fast")}this.visible=true},hide:function(){this.visible=false;this.$el.fadeOut("fast")},enableButton:function(b){var c=this.buttonList[b];this.$buttons.find("#"+c).prop("disabled",false)},disableButton:function(b){var c=this.buttonList[b];this.$buttons.find("#"+c).prop("disabled",true)},showButton:function(b){var c=this.buttonList[b];this.$buttons.find("#"+c).show()},hideButton:function(b){var c=this.buttonList[b];this.$buttons.find("#"+c).hide()},scrollTop:function(){return this.$body.scrollTop()},_create:function(d){var c=this;this.options=_.defaults(d,this.optionsDefault);if(this.options.body=="progress"){this.options.body=$('<div class="progress progress-striped active"><div class="progress-bar progress-bar-info" style="width:100%"></div></div>')}if(this.$el){this.$el.remove();$(document).off("keyup")}this.setElement(this._template(this.options.title));this.$dialog=(this.$el).find(".modal-dialog");this.$body=(this.$el).find(".modal-body");this.$footer=(this.$el).find(".modal-footer");this.$buttons=(this.$el).find(".buttons");this.$backdrop=(this.$el).find(".modal-backdrop");this.$body.html(this.options.body);if(!this.options.backdrop){this.$backdrop.removeClass("in")}if(this.options.buttons){this.buttonList={};var b=0;$.each(this.options.buttons,function(e,g){var f="button-"+b++;c.$buttons.append($('<button id="'+f+'"></button>').text(e).click(g)).append(" ");c.buttonList[e]=f})}else{this.$footer.hide()}$(this.elMain).append($(this.el));if(this.options.closing_events){$(document).on("keyup",function(f){if(f.keyCode==27){c.hide()}});this.$el.find(".modal-backdrop").on("click",function(){c.hide()})}},_template:function(b){return'<div class="modal"><div class="modal-backdrop fade in" style="z-index: -1;"></div><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><button type="button" class="close" style="display: none;">×</button><h4 class="title">'+b+'</h4></div><div class="modal-body"></div><div class="modal-footer"><div class="buttons" style="float: right;"></div></div></div</div></div>'}});return{GalaxyModal:a}});
\ No newline at end of file
+define([],function(){var a=Backbone.View.extend({elMain:"#everything",optionsDefault:{title:"galaxy-modal",body:"",backdrop:true,height:null,width:null,closing_events:false},buttonList:{},initialize:function(b){if(b){this._create(b)}},show:function(b){this.initialize(b);if(this.options.height){this.$body.css("height",this.options.height);this.$body.css("overflow","hidden")}else{this.$body.css("max-height",$(window).height()/2)}if(this.options.width){this.$dialog.css("width",this.options.width)}if(this.visible){this.$el.show()}else{this.$el.fadeIn("fast")}this.visible=true},hide:function(){this.visible=false;this.$el.fadeOut("fast")},enableButton:function(b){var c=this.buttonList[b];this.$buttons.find("#"+c).prop("disabled",false)},disableButton:function(b){var c=this.buttonList[b];this.$buttons.find("#"+c).prop("disabled",true)},showButton:function(b){var c=this.buttonList[b];this.$buttons.find("#"+c).show()},hideButton:function(b){var c=this.buttonList[b];this.$buttons.find("#"+c).hide()},scrollTop:function(){return this.$body.scrollTop()},_create:function(d){var c=this;this.options=_.defaults(d,this.optionsDefault);if(this.options.body=="progress"){this.options.body=$('<div class="progress progress-striped active"><div class="progress-bar progress-bar-info" style="width:100%"></div></div>')}if(this.$el){this.$el.remove();$(document).off("keyup")}this.setElement(this._template(this.options.title));this.$dialog=(this.$el).find(".modal-dialog");this.$body=(this.$el).find(".modal-body");this.$footer=(this.$el).find(".modal-footer");this.$buttons=(this.$el).find(".buttons");this.$backdrop=(this.$el).find(".modal-backdrop");this.$body.html(this.options.body);if(!this.options.backdrop){this.$backdrop.removeClass("in")}if(this.options.buttons){this.buttonList={};var b=0;$.each(this.options.buttons,function(e,g){var f="button-"+b++;c.$buttons.append($('<button id="'+f+'"></button>').text(e).click(g)).append(" ");c.buttonList[e]=f})}else{this.$footer.hide()}$(this.elMain).append($(this.el));if(this.options.closing_events){if(!this.options.buttons.Pause){$(document).on("keyup",function(f){if(f.keyCode==27){c.hide()}})}this.$el.find(".modal-backdrop").on("click",function(){c.hide()})}},_template:function(b){return'<div class="modal"><div class="modal-backdrop fade in" style="z-index: -1;"></div><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><button type="button" class="close" style="display: none;">×</button><h4 class="title">'+b+'</h4></div><div class="modal-body"></div><div class="modal-footer"><div class="buttons" style="float: right;"></div></div></div</div></div>'}});return{GalaxyModal:a}});
\ No newline at end of file
diff -r 658d07c0f8442657229062cfdc5f3fe6b6bd00e8 -r aaabd336009044d2d6f748eaca483ccab0950435 static/scripts/packed/mvc/upload/upload-view.js
--- a/static/scripts/packed/mvc/upload/upload-view.js
+++ b/static/scripts/packed/mvc/upload/upload-view.js
@@ -1,1 +1,1 @@
-define(["galaxy.modal","utils/utils","mvc/upload/upload-model","mvc/upload/upload-row","mvc/ui","utils/uploadbox"],function(c,f,e,d){var b=Backbone.Model.extend({defaults:{percentage:0,icon:"fa-circle",label:"",status:""}});var a=Backbone.View.extend({model:null,initialize:function(h){var g=this;this.model=h;this.options=this.model.attributes;this.setElement(this._template(this.options));$(this.el).on("click",this.options.onclick);if(this.options.tooltip){$(this.el).tooltip({title:this.options.tooltip,placement:"bottom"})}this.model.on("change:percentage",function(){g._percentage(g.model.get("percentage"))});this.model.on("change:status",function(){g._status(g.model.get("status"))});var g=this;$(window).on("beforeunload",function(){var i="";if(g.options.onunload){i=g.options.onunload()}if(i!=""){return i}})},_status:function(h){var g=this.$el.find(".progress-bar");g.removeClass();g.addClass("progress-bar");g.addClass("progress-bar-notransition");if(h!=""){g.addClass("progress-bar-"+h)}},_percentage:function(h){var g=this.$el.find(".progress-bar");g.css({width:h+"%"})},_template:function(g){return'<div class="progress-button"><div class="progress"><div class="progress-bar"></div></div><div id="label" class="label" style="position: absolute; top: 0px; width: inherit; text-align: center;"><div class="fa '+g.icon+'"></div> '+g.label+"</div></div>"}});return Backbone.View.extend({modal:null,button_show:null,uploadbox:null,current_history:null,upload_size:0,select_extension:[["Auto-detect","auto"]],select_genome:[["Unspecified (?)","?"]],collection:new e.Collection(),counter:{announce:0,success:0,error:0,running:0,reset:function(){this.announce=this.success=this.error=this.running=0}},options:{nginx_upload_path:""},initialize:function(h){var g=this;if(!Galaxy.currHistoryPanel||!Galaxy.currHistoryPanel.model){window.setTimeout(function(){g.initialize()},500);return}if(!Galaxy.currUser.get("id")){return}this.button_show=new b({icon:"fa-upload",tooltip:"Download from URL or upload files from disk",label:"Load Data",onclick:function(i){if(i){g._eventShow(i)}},onunload:function(){if(g.counter.running>0){return"Several uploads are still processing."}}});$("#left .unified-panel-header-inner").append((new a(this.button_show)).$el);var g=this;f.jsonFromUrl(galaxy_config.root+"api/datatypes",function(i){for(key in i){g.select_extension.push([i[key],i[key]])}});f.jsonFromUrl(galaxy_config.root+"api/genomes",function(i){var j=g.select_genome[0];g.select_genome=[];for(key in i){if(i[key].length>1){if(i[key][1]!==j[1]){g.select_genome.push(i[key])}}}g.select_genome.sort(function(l,k){return l[0]>k[0]?1:l[0]<k[0]?-1:0});g.select_genome.unshift(j)});if(h){this.options=_.defaults(h,this.options)}this.collection.on("remove",function(i){g._eventRemove(i)});this.collection.on("change:genome",function(j){var i=j.get("genome");g.collection.each(function(k){if(k.get("status")=="init"&&k.get("genome")=="?"){k.set("genome",i)}})})},_eventShow:function(h){h.preventDefault();h.stopPropagation();if(!this.modal){var g=this;this.modal=new c.GalaxyModal({title:"Download data directly from web or upload files from your disk",body:this._template("upload-box","upload-info"),buttons:{"Choose files":function(){g.uploadbox.select()},"Create file":function(){g._eventCreate()},Start:function(){g._eventStart()},Pause:function(){g._eventStop()},Reset:function(){g._eventReset()},Close:function(){g.modal.hide()},},height:"400",width:"900",bindClosingEvents:true,bindEscKey:false});this.setElement("#upload-box");var g=this;this.uploadbox=this.$el.uploadbox({announce:function(i,j,k){g._eventAnnounce(i,j,k)},initialize:function(i,j,k){return g._eventInitialize(i,j,k)},progress:function(i,j,k){g._eventProgress(i,j,k)},success:function(i,j,k){g._eventSuccess(i,j,k)},error:function(i,j,k){g._eventError(i,j,k)},complete:function(){g._eventComplete()}});this._updateScreen()}this.modal.show()},_eventRemove:function(h){var g=h.get("status");if(g=="success"){this.counter.success--}else{if(g=="error"){this.counter.error--}else{this.counter.announce--}}this._updateScreen();this.uploadbox.remove(h.id)},_eventAnnounce:function(g,h,j){this.counter.announce++;this._updateScreen();var i=new d(this,{id:g,file_name:h.name,file_size:h.size});this.collection.add(i.model);$(this.el).find("tbody:last").append(i.$el);i.render()},_eventInitialize:function(k,g,o){var i=this.collection.get(k);i.set("status","running");var h=i.get("extension");var l=i.get("file_name");var n=i.get("genome");var m=i.get("url_paste");var j=i.get("space_to_tabs");if(!m&&!(g.size>0)){return null}this.uploadbox.configure({url:this.options.nginx_upload_path,paramname:"files_0|file_data"});tool_input={};tool_input.dbkey=n;tool_input.file_type=h;tool_input["files_0|NAME"]=l;tool_input["files_0|type"]="upload_dataset";tool_input["files_0|url_paste"]=m;tool_input.space_to_tabs=j;data={};data.history_id=this.current_history;data.tool_id="upload1";data.inputs=JSON.stringify(tool_input);return data},_eventProgress:function(h,i,g){var j=this.collection.get(h);j.set("percentage",g);this.button_show.set("percentage",this._upload_percentage(g,i.size))},_eventSuccess:function(h,i,k){var j=this.collection.get(h);j.set("status","success");var g=j.get("file_size");this.button_show.set("percentage",this._upload_percentage(100,g));this.upload_completed+=g*100;this.counter.announce--;this.counter.success++;this._updateScreen();Galaxy.currHistoryPanel.refreshHdas()},_eventError:function(g,h,j){var i=this.collection.get(g);i.set("status","error");i.set("info",j);this.button_show.set("percentage",this._upload_percentage(100,h.size));this.button_show.set("status","danger");this.upload_completed+=h.size*100;this.counter.announce--;this.counter.error++;this._updateScreen()},_eventComplete:function(){this.collection.each(function(g){if(g.get("status")=="queued"){g.set("status","init")}});this.counter.running=0;this._updateScreen()},_eventCreate:function(){this.uploadbox.add([{name:"New File",size:-1}])},_eventStart:function(){if(this.counter.announce==0||this.counter.running>0){return}var g=this;this.upload_size=0;this.upload_completed=0;this.collection.each(function(h){if(h.get("status")=="init"){h.set("status","queued");g.upload_size+=h.get("file_size")}});this.button_show.set("percentage",0);this.button_show.set("status","success");this.current_history=Galaxy.currHistoryPanel.model.get("id");this.counter.running=this.counter.announce;this._updateScreen();this.uploadbox.start()},_eventStop:function(){if(this.counter.running==0){return}this.button_show.set("status","info");this.uploadbox.stop();$("#upload-info").html("Queue will pause after completing the current file...")},_eventReset:function(){if(this.counter.running==0){this.collection.reset();this.counter.reset();this._updateScreen();this.uploadbox.reset();this.button_show.set("percentage",0)}},_updateScreen:function(){if(this.counter.announce==0){if(this.uploadbox.compatible()){message="You can Drag & Drop files into this box."}else{message="Unfortunately, your browser does not support multiple file uploads or drag&drop.<br>Some supported browsers are: Firefox 4+, Chrome 7+, IE 10+, Opera 12+ or Safari 6+."}}else{if(this.counter.running==0){message="You added "+this.counter.announce+" file(s) to the queue. Add more files or click 'Start' to proceed."}else{message="Please wait..."+this.counter.announce+" out of "+this.counter.running+" remaining."}}$("#upload-info").html(message);if(this.counter.running==0&&this.counter.announce+this.counter.success+this.counter.error>0){this.modal.enableButton("Reset")}else{this.modal.disableButton("Reset")}if(this.counter.running==0&&this.counter.announce>0){this.modal.enableButton("Start")}else{this.modal.disableButton("Start")}if(this.counter.running>0){this.modal.enableButton("Pause")}else{this.modal.disableButton("Pause")}if(this.counter.running==0){this.modal.enableButton("Choose files");this.modal.enableButton("Create file")}else{this.modal.disableButton("Choose files");this.modal.disableButton("Create file")}if(this.counter.announce+this.counter.success+this.counter.error>0){$(this.el).find("table").show()}else{$(this.el).find("table").hide()}},_upload_percentage:function(g,h){return(this.upload_completed+(g*h))/this.upload_size},_template:function(h,g){return'<div id="'+h+'" class="upload-box"><table class="table table-striped" style="display: none;"><thead><tr><th>Name</th><th>Size</th><th>Type</th><th>Genome</th><th>Space→Tab</th><th>Status</th><th></th></tr></thead><tbody></tbody></table></div><h6 id="'+g+'" class="upload-info"></h6>'}})});
\ No newline at end of file
+define(["galaxy.modal","utils/utils","mvc/upload/upload-model","mvc/upload/upload-row","mvc/ui","utils/uploadbox"],function(c,f,e,d){var b=Backbone.Model.extend({defaults:{percentage:0,icon:"fa-circle",label:"",status:""}});var a=Backbone.View.extend({model:null,initialize:function(h){var g=this;this.model=h;this.options=this.model.attributes;this.setElement(this._template(this.options));$(this.el).on("click",this.options.onclick);if(this.options.tooltip){$(this.el).tooltip({title:this.options.tooltip,placement:"bottom"})}this.model.on("change:percentage",function(){g._percentage(g.model.get("percentage"))});this.model.on("change:status",function(){g._status(g.model.get("status"))});var g=this;$(window).on("beforeunload",function(){var i="";if(g.options.onunload){i=g.options.onunload()}if(i!=""){return i}})},_status:function(h){var g=this.$el.find(".progress-bar");g.removeClass();g.addClass("progress-bar");g.addClass("progress-bar-notransition");if(h!=""){g.addClass("progress-bar-"+h)}},_percentage:function(h){var g=this.$el.find(".progress-bar");g.css({width:h+"%"})},_template:function(g){return'<div class="progress-button"><div class="progress"><div class="progress-bar"></div></div><div id="label" class="label" style="position: absolute; top: 0px; width: inherit; text-align: center;"><div class="fa '+g.icon+'"></div> '+g.label+"</div></div>"}});return Backbone.View.extend({modal:null,button_show:null,uploadbox:null,current_history:null,upload_size:0,select_extension:[["Auto-detect","auto"]],select_genome:[["Unspecified (?)","?"]],collection:new e.Collection(),counter:{announce:0,success:0,error:0,running:0,reset:function(){this.announce=this.success=this.error=this.running=0}},options:{nginx_upload_path:""},initialize:function(h){var g=this;if(!Galaxy.currHistoryPanel||!Galaxy.currHistoryPanel.model){window.setTimeout(function(){g.initialize()},500);return}if(!Galaxy.currUser.get("id")){return}this.button_show=new b({icon:"fa-upload",tooltip:"Download from URL or upload files from disk",label:"Load Data",onclick:function(i){if(i){g._eventShow(i)}},onunload:function(){if(g.counter.running>0){return"Several uploads are still processing."}}});$("#left .unified-panel-header-inner").append((new a(this.button_show)).$el);var g=this;f.jsonFromUrl(galaxy_config.root+"api/datatypes",function(i){for(key in i){g.select_extension.push([i[key],i[key]])}});f.jsonFromUrl(galaxy_config.root+"api/genomes",function(i){var j=g.select_genome[0];g.select_genome=[];for(key in i){if(i[key].length>1){if(i[key][1]!==j[1]){g.select_genome.push(i[key])}}}g.select_genome.sort(function(l,k){return l[0]>k[0]?1:l[0]<k[0]?-1:0});g.select_genome.unshift(j)});if(h){this.options=_.defaults(h,this.options)}this.collection.on("remove",function(i){g._eventRemove(i)});this.collection.on("change:genome",function(j){var i=j.get("genome");g.collection.each(function(k){if(k.get("status")=="init"&&k.get("genome")=="?"){k.set("genome",i)}})})},_eventShow:function(h){h.preventDefault();h.stopPropagation();if(!this.modal){var g=this;this.modal=new c.GalaxyModal({title:"Download data directly from web or upload files from your disk",body:this._template("upload-box","upload-info"),buttons:{"Choose files":function(){g.uploadbox.select()},"Create file":function(){g._eventCreate()},Start:function(){g._eventStart()},Pause:function(){g._eventStop()},Reset:function(){g._eventReset()},Close:function(){g.modal.hide()},},height:"400",width:"900",closing_events:true});this.setElement("#upload-box");var g=this;this.uploadbox=this.$el.uploadbox({announce:function(i,j,k){g._eventAnnounce(i,j,k)},initialize:function(i,j,k){return g._eventInitialize(i,j,k)},progress:function(i,j,k){g._eventProgress(i,j,k)},success:function(i,j,k){g._eventSuccess(i,j,k)},error:function(i,j,k){g._eventError(i,j,k)},complete:function(){g._eventComplete()}});this._updateScreen()}this.modal.show()},_eventRemove:function(h){var g=h.get("status");if(g=="success"){this.counter.success--}else{if(g=="error"){this.counter.error--}else{this.counter.announce--}}this._updateScreen();this.uploadbox.remove(h.id)},_eventAnnounce:function(g,h,j){this.counter.announce++;this._updateScreen();var i=new d(this,{id:g,file_name:h.name,file_size:h.size});this.collection.add(i.model);$(this.el).find("tbody:last").append(i.$el);i.render()},_eventInitialize:function(k,g,o){var i=this.collection.get(k);i.set("status","running");var h=i.get("extension");var l=i.get("file_name");var n=i.get("genome");var m=i.get("url_paste");var j=i.get("space_to_tabs");if(!m&&!(g.size>0)){return null}this.uploadbox.configure({url:this.options.nginx_upload_path,paramname:"files_0|file_data"});tool_input={};tool_input.dbkey=n;tool_input.file_type=h;tool_input["files_0|NAME"]=l;tool_input["files_0|type"]="upload_dataset";tool_input["files_0|url_paste"]=m;tool_input.space_to_tabs=j;data={};data.history_id=this.current_history;data.tool_id="upload1";data.inputs=JSON.stringify(tool_input);return data},_eventProgress:function(h,i,g){var j=this.collection.get(h);j.set("percentage",g);this.button_show.set("percentage",this._upload_percentage(g,i.size))},_eventSuccess:function(h,i,k){var j=this.collection.get(h);j.set("status","success");var g=j.get("file_size");this.button_show.set("percentage",this._upload_percentage(100,g));this.upload_completed+=g*100;this.counter.announce--;this.counter.success++;this._updateScreen();Galaxy.currHistoryPanel.refreshHdas()},_eventError:function(g,h,j){var i=this.collection.get(g);i.set("status","error");i.set("info",j);this.button_show.set("percentage",this._upload_percentage(100,h.size));this.button_show.set("status","danger");this.upload_completed+=h.size*100;this.counter.announce--;this.counter.error++;this._updateScreen()},_eventComplete:function(){this.collection.each(function(g){if(g.get("status")=="queued"){g.set("status","init")}});this.counter.running=0;this._updateScreen()},_eventCreate:function(){this.uploadbox.add([{name:"New File",size:-1}])},_eventStart:function(){if(this.counter.announce==0||this.counter.running>0){return}var g=this;this.upload_size=0;this.upload_completed=0;this.collection.each(function(h){if(h.get("status")=="init"){h.set("status","queued");g.upload_size+=h.get("file_size")}});this.button_show.set("percentage",0);this.button_show.set("status","success");this.current_history=Galaxy.currHistoryPanel.model.get("id");this.counter.running=this.counter.announce;this._updateScreen();this.uploadbox.start()},_eventStop:function(){if(this.counter.running==0){return}this.button_show.set("status","info");this.uploadbox.stop();$("#upload-info").html("Queue will pause after completing the current file...")},_eventReset:function(){if(this.counter.running==0){this.collection.reset();this.counter.reset();this._updateScreen();this.uploadbox.reset();this.button_show.set("percentage",0)}},_updateScreen:function(){if(this.counter.announce==0){if(this.uploadbox.compatible()){message="You can Drag & Drop files into this box."}else{message="Unfortunately, your browser does not support multiple file uploads or drag&drop.<br>Some supported browsers are: Firefox 4+, Chrome 7+, IE 10+, Opera 12+ or Safari 6+."}}else{if(this.counter.running==0){message="You added "+this.counter.announce+" file(s) to the queue. Add more files or click 'Start' to proceed."}else{message="Please wait..."+this.counter.announce+" out of "+this.counter.running+" remaining."}}$("#upload-info").html(message);if(this.counter.running==0&&this.counter.announce+this.counter.success+this.counter.error>0){this.modal.enableButton("Reset")}else{this.modal.disableButton("Reset")}if(this.counter.running==0&&this.counter.announce>0){this.modal.enableButton("Start")}else{this.modal.disableButton("Start")}if(this.counter.running>0){this.modal.enableButton("Pause")}else{this.modal.disableButton("Pause")}if(this.counter.running==0){this.modal.enableButton("Choose files");this.modal.enableButton("Create file")}else{this.modal.disableButton("Choose files");this.modal.disableButton("Create file")}if(this.counter.announce+this.counter.success+this.counter.error>0){$(this.el).find("table").show()}else{$(this.el).find("table").hide()}},_upload_percentage:function(g,h){return(this.upload_completed+(g*h))/this.upload_size},_template:function(h,g){return'<div id="'+h+'" class="upload-box"><table class="table table-striped" style="display: none;"><thead><tr><th>Name</th><th>Size</th><th>Type</th><th>Genome</th><th>Space→Tab</th><th>Status</th><th></th></tr></thead><tbody></tbody></table></div><h6 id="'+g+'" class="upload-info"></h6>'}})});
\ No newline at end of file
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: martenson: removed bug in libraries API (prepending ‘F’ to library id, should be only for folders)
by commits-noreply@bitbucket.org 23 Jan '14
by commits-noreply@bitbucket.org 23 Jan '14
23 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/658d07c0f844/
Changeset: 658d07c0f844
User: martenson
Date: 2014-01-23 16:05:09
Summary: removed bug in libraries API (prepending ‘F’ to library id, should be only for folders)
Affected #: 1 file
diff -r 7e9ef97e04496434313430ee71aff7033c50c390 -r 658d07c0f8442657229062cfdc5f3fe6b6bd00e8 lib/galaxy/webapps/galaxy/api/libraries.py
--- a/lib/galaxy/webapps/galaxy/api/libraries.py
+++ b/lib/galaxy/webapps/galaxy/api/libraries.py
@@ -50,7 +50,7 @@
for library in query:
item = library.to_dict( view='element' )
item['url'] = url_for( route, id=trans.security.encode_id( library.id ) )
- item['id'] = 'F' + trans.security.encode_id( item['id'] )
+ item['id'] = trans.security.encode_id( item['id'] )
item['root_folder_id'] = 'F' + trans.security.encode_id( item['root_folder_id'] )
libraries.append( item )
return libraries
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: Add workflow API tests.
by commits-noreply@bitbucket.org 23 Jan '14
by commits-noreply@bitbucket.org 23 Jan '14
23 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/7e9ef97e0449/
Changeset: 7e9ef97e0449
User: jmchilton
Date: 2014-01-23 09:04:52
Summary: Add workflow API tests.
Test import, export, index, show, run workflows, and post job actions.
Affected #: 4 files
diff -r f86086c92a2291e11bd1d76afa67b9166a8dc0ee -r 7e9ef97e04496434313430ee71aff7033c50c390 test/functional/api/helpers.py
--- /dev/null
+++ b/test/functional/api/helpers.py
@@ -0,0 +1,58 @@
+import time
+from json import dumps
+
+
+class TestsDatasets:
+
+ def _new_dataset( self, history_id, content='TestData123', **kwds ):
+ payload = self._upload_payload( history_id, content, **kwds )
+ run_response = self._post( "tools", data=payload )
+ self._assert_status_code_is( run_response, 200 )
+ return run_response.json()["outputs"][0]
+
+ def _wait_for_history( self, history_id, assert_ok=False ):
+ while True:
+ history_details_response = self._get( "histories/%s" % history_id )
+ self._assert_status_code_is( history_details_response, 200 )
+ history_state = history_details_response.json()[ "state" ]
+ if history_state not in [ "running", "queued" ]:
+ break
+ time.sleep( .1 )
+ if assert_ok:
+ self.assertEquals( history_state, 'ok' )
+
+ def _new_history( self, **kwds ):
+ name = kwds.get( "name", "API Test History" )
+ create_history_response = self._post( "histories", data=dict( name=name ) )
+ self._assert_status_code_is( create_history_response, 200 )
+ history_id = create_history_response.json()[ "id" ]
+ return history_id
+
+ def _upload_payload( self, history_id, content, **kwds ):
+ name = kwds.get( "name", "Test Dataset" )
+ dbkey = kwds.get( "dbkey", "?" )
+ file_type = kwds.get( "file_type", 'txt' )
+ upload_params = {
+ 'files_0|NAME': name,
+ 'files_0|url_paste': content,
+ 'dbkey': dbkey,
+ 'file_type': file_type,
+ }
+ if "to_posix_lines" in kwds:
+ upload_params[ "files_0|to_posix_lines"] = kwds[ "to_posix_lines" ]
+ if "space_to_tab" in kwds:
+ upload_params[ "files_0|space_to_tab" ] = kwds[ "space_to_tab" ]
+ return self._run_tool_payload(
+ tool_id='upload1',
+ inputs=upload_params,
+ history_id=history_id,
+ upload_type='upload_dataset'
+ )
+
+ def _run_tool_payload( self, tool_id, inputs, history_id, **kwds ):
+ return dict(
+ tool_id=tool_id,
+ inputs=dumps(inputs),
+ history_id=history_id,
+ **kwds
+ )
diff -r f86086c92a2291e11bd1d76afa67b9166a8dc0ee -r 7e9ef97e04496434313430ee71aff7033c50c390 test/functional/api/test_tools.py
--- a/test/functional/api/test_tools.py
+++ b/test/functional/api/test_tools.py
@@ -1,13 +1,12 @@
# Test tools API.
from itertools import chain
-from json import dumps
-import time
from base import api
from operator import itemgetter
+from .helpers import TestsDatasets
-class ToolsTestCase( api.ApiTestCase ):
+class ToolsTestCase( api.ApiTestCase, TestsDatasets ):
def test_index( self ):
index = self._get( "tools" )
@@ -80,56 +79,3 @@
display_response = self._get( "histories/%s/contents/%s/display" % ( history_id, new_dataset[ "id" ] ) )
self._assert_status_code_is( display_response, 200 )
return display_response.content
-
- def _new_dataset( self, history_id, content='TestData123', **kwds ):
- payload = self._upload_payload( history_id, content, **kwds )
- run_response = self._post( "tools", data=payload )
- self._assert_status_code_is( run_response, 200 )
- return run_response.json()["outputs"][0]
-
- def _wait_for_history( self, history_id, assert_ok=False ):
- while True:
- history_details_response = self._get( "histories/%s" % history_id )
- self._assert_status_code_is( history_details_response, 200 )
- history_state = history_details_response.json()[ "state" ]
- if history_state not in [ "running", "queued" ]:
- break
- time.sleep( .1 )
- if assert_ok:
- self.assertEquals( history_state, 'ok' )
-
- def _new_history( self, **kwds ):
- name = kwds.get( "name", "API Test History" )
- create_history_response = self._post( "histories", data=dict( name=name ) )
- self._assert_status_code_is( create_history_response, 200 )
- history_id = create_history_response.json()[ "id" ]
- return history_id
-
- def _upload_payload( self, history_id, content, **kwds ):
- name = kwds.get( "name", "Test Dataset" )
- dbkey = kwds.get( "dbkey", "?" )
- file_type = kwds.get( "file_type", 'txt' )
- upload_params = {
- 'files_0|NAME': name,
- 'files_0|url_paste': content,
- 'dbkey': dbkey,
- 'file_type': file_type,
- }
- if "to_posix_lines" in kwds:
- upload_params[ "files_0|to_posix_lines"] = kwds[ "to_posix_lines" ]
- if "space_to_tab" in kwds:
- upload_params[ "files_0|space_to_tab" ] = kwds[ "space_to_tab" ]
- return self._run_tool_payload(
- tool_id='upload1',
- inputs=upload_params,
- history_id=history_id,
- upload_type='upload_dataset'
- )
-
- def _run_tool_payload( self, tool_id, inputs, history_id, **kwds ):
- return dict(
- tool_id=tool_id,
- inputs=dumps(inputs),
- history_id=history_id,
- **kwds
- )
diff -r f86086c92a2291e11bd1d76afa67b9166a8dc0ee -r 7e9ef97e04496434313430ee71aff7033c50c390 test/functional/api/test_workflow_1.ga
--- /dev/null
+++ b/test/functional/api/test_workflow_1.ga
@@ -0,0 +1,87 @@
+{
+ "a_galaxy_workflow": "true",
+ "annotation": "",
+ "format-version": "0.1",
+ "name": "TestWorkflow1",
+ "steps": {
+ "0": {
+ "annotation": "",
+ "id": 0,
+ "input_connections": {},
+ "inputs": [
+ {
+ "description": "",
+ "name": "WorkflowInput1"
+ }
+ ],
+ "name": "Input dataset",
+ "outputs": [],
+ "position": {
+ "left": 199.55555772781372,
+ "top": 200.66666460037231
+ },
+ "tool_errors": null,
+ "tool_id": null,
+ "tool_state": "{\"name\": \"WorkflowInput1\"}",
+ "tool_version": null,
+ "type": "data_input",
+ "user_outputs": []
+ },
+ "1": {
+ "annotation": "",
+ "id": 1,
+ "input_connections": {},
+ "inputs": [
+ {
+ "description": "",
+ "name": "WorkflowInput2"
+ }
+ ],
+ "name": "Input dataset",
+ "outputs": [],
+ "position": {
+ "left": 206.22221422195435,
+ "top": 327.33335161209106
+ },
+ "tool_errors": null,
+ "tool_id": null,
+ "tool_state": "{\"name\": \"WorkflowInput2\"}",
+ "tool_version": null,
+ "type": "data_input",
+ "user_outputs": []
+ },
+ "2": {
+ "annotation": "",
+ "id": 2,
+ "input_connections": {
+ "input1": {
+ "id": 0,
+ "output_name": "output"
+ },
+ "queries_0|input2": {
+ "id": 1,
+ "output_name": "output"
+ }
+ },
+ "inputs": [],
+ "name": "Concatenate datasets",
+ "outputs": [
+ {
+ "name": "out_file1",
+ "type": "input"
+ }
+ ],
+ "position": {
+ "left": 419.33335876464844,
+ "top": 200.44446563720703
+ },
+ "post_job_actions": {},
+ "tool_errors": null,
+ "tool_id": "cat1",
+ "tool_state": "{\"__page__\": 0, \"__rerun_remap_job_id__\": null, \"input1\": \"null\", \"chromInfo\": \"\\\"/home/john/workspace/galaxy-central/tool-data/shared/ucsc/chrom/?.len\\\"\", \"queries\": \"[{\\\"input2\\\": null, \\\"__index__\\\": 0}]\"}",
+ "tool_version": "1.0.0",
+ "type": "tool",
+ "user_outputs": []
+ }
+ }
+}
\ No newline at end of file
diff -r f86086c92a2291e11bd1d76afa67b9166a8dc0ee -r 7e9ef97e04496434313430ee71aff7033c50c390 test/functional/api/test_workflows.py
--- /dev/null
+++ b/test/functional/api/test_workflows.py
@@ -0,0 +1,128 @@
+from base import api
+from json import loads
+from json import dumps
+from pkg_resources import resource_string
+import time
+from .helpers import TestsDatasets
+
+workflow_str = resource_string( __name__, "test_workflow_1.ga" )
+
+
+# Workflow API TODO:
+# - Allow history_id as param to workflow run action. (hist_id)
+# - Allow post to workflows/<workflow_id>/run in addition to posting to
+# /workflows with id in payload.
+# - Much more testing obviously, always more testing.
+class WorkflowsApiTestCase( api.ApiTestCase, TestsDatasets ):
+
+ def test_index( self ):
+ index_response = self._get( "workflows" )
+ self._assert_status_code_is( index_response, 200 )
+ assert isinstance( index_response.json(), list )
+
+ def test_import( self ):
+ data = dict(
+ workflow=dumps( self._load_workflow( name="test_import" ) ),
+ )
+ upload_response = self._post( "workflows/upload", data=data )
+ self._assert_status_code_is( upload_response, 200 )
+ self._assert_user_has_workflow_with_name( "test_import (imported from API)" )
+
+ def test_export( self ):
+ uploaded_workflow_id = self._create_workflow( self._load_workflow( name="test_for_export" ) )
+ download_response = self._get( "workflows/%s/download" % uploaded_workflow_id )
+ self._assert_status_code_is( download_response, 200 )
+ downloaded_workflow = download_response.json()
+ assert downloaded_workflow[ "name" ] == "test_for_export (imported from API)"
+ assert len( downloaded_workflow[ "steps" ] ) == 3
+ first_input = downloaded_workflow[ "steps" ][ "0" ][ "inputs" ][ 0 ]
+ assert first_input[ "name" ] == "WorkflowInput1"
+
+ def test_run_workflow( self ):
+ workflow = self._load_workflow( name="test_for_run" )
+ workflow_request, history_id = self._setup_workflow_run( workflow )
+ # TODO: This should really be a post to workflows/<workflow_id>/run or
+ # something like that.
+ run_workflow_response = self._post( "workflows", data=workflow_request )
+ self._assert_status_code_is( run_workflow_response, 200 )
+ self._wait_for_history( history_id, assert_ok=True )
+
+ def test_pja_import_export( self ):
+ workflow = self._load_workflow( name="test_for_pja_import", add_pja=True )
+ uploaded_workflow_id = self._create_workflow( workflow )
+ download_response = self._get( "workflows/%s/download" % uploaded_workflow_id )
+ downloaded_workflow = download_response.json()
+ self._assert_has_keys( downloaded_workflow[ "steps" ], "0", "1", "2" )
+ pjas = downloaded_workflow[ "steps" ][ "2" ][ "post_job_actions" ].values()
+ assert len( pjas ) == 1, len( pjas )
+ pja = pjas[ 0 ]
+ self._assert_has_keys( pja, "action_type", "output_name", "action_arguments" )
+
+ def test_post_job_action( self ):
+ """ Tests both import and execution of post job actions.
+ """
+ workflow = self._load_workflow( name="test_for_pja_run", add_pja=True )
+ workflow_request, history_id = self._setup_workflow_run( workflow )
+ run_workflow_response = self._post( "workflows", data=workflow_request )
+ self._assert_status_code_is( run_workflow_response, 200 )
+ self._wait_for_history( history_id, assert_ok=True )
+ time.sleep(.1) # Give another little bit of time for rename (needed?)
+ contents = self._get( "histories/%s/contents" % history_id ).json()
+ # loading workflow with add_pja=True causes workflow output to be
+ # renamed to 'the_new_name'.
+ assert "the_new_name" in map( lambda hda: hda[ "name" ], contents )
+
+ def _setup_workflow_run( self, workflow ):
+ uploaded_workflow_id = self._create_workflow( workflow )
+ workflow_show_resposne = self._get( "workflows/%s" % uploaded_workflow_id )
+ self._assert_status_code_is( workflow_show_resposne, 200 )
+ workflow_inputs = workflow_show_resposne.json()[ "inputs" ]
+ step_1 = step_2 = None
+ for key, value in workflow_inputs.iteritems():
+ label = value[ "label" ]
+ if label == "WorkflowInput1":
+ step_1 = key
+ if label == "WorkflowInput2":
+ step_2 = key
+ history_id = self._new_history()
+ hda1 = self._new_dataset( history_id, content="1 2 3" )
+ hda2 = self._new_dataset( history_id, content="4 5 6" )
+ workflow_request = dict(
+ history="hist_id=%s" % history_id,
+ workflow_id=uploaded_workflow_id,
+ ds_map=dumps( {
+ step_1: self._ds_entry(hda1),
+ step_2: self._ds_entry(hda2),
+ } ),
+ )
+ return workflow_request, history_id
+
+ def _ds_entry( self, hda ):
+ return dict( src="hda", id=hda[ "id" ] )
+
+ def _create_workflow( self, workflow ):
+ data = dict(
+ workflow=dumps( workflow ),
+ )
+ upload_response = self._post( "workflows/upload", data=data )
+ self._assert_status_code_is( upload_response, 200 )
+ uploaded_workflow_id = upload_response.json()[ "id" ]
+ return uploaded_workflow_id
+
+ def _assert_user_has_workflow_with_name( self, name ):
+ index_response = self._get( "workflows" )
+ self._assert_status_code_is( index_response, 200 )
+ names = map( lambda w: w[ "name" ], index_response.json() )
+ assert name in names, "No workflows with name %s in users workflows <%s>" % ( name, names )
+
+ def _load_workflow( self, name, add_pja=False ):
+ workflow = loads( workflow_str )
+ workflow[ "name" ] = name
+ if add_pja:
+ tool_step = workflow[ "steps" ][ "2" ]
+ tool_step[ "post_job_actions" ][ "RenameDatasetActionout_file1" ] = dict(
+ action_type="RenameDatasetAction",
+ output_name="out_file1",
+ action_arguments=dict( newname="the_new_name" ),
+ )
+ return workflow
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: guerler: Charts: Fix configure button in viewport
by commits-noreply@bitbucket.org 23 Jan '14
by commits-noreply@bitbucket.org 23 Jan '14
23 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/f86086c92a22/
Changeset: f86086c92a22
User: guerler
Date: 2014-01-23 04:21:14
Summary: Charts: Fix configure button in viewport
Affected #: 1 file
diff -r fd6cd92888edf53c86378e3ec36dae1e0cf54884 -r f86086c92a2291e11bd1d76afa67b9166a8dc0ee config/plugins/visualizations/charts/static/views/viewport.js
--- a/config/plugins/visualizations/charts/static/views/viewport.js
+++ b/config/plugins/visualizations/charts/static/views/viewport.js
@@ -61,15 +61,30 @@
},
// show
- show: function(id) {
+ show: function(chart_id) {
// hide all
this.$el.find('svg').hide();
- var item = this.list[id];
+ // identify selected item from list
+ var item = this.list[chart_id];
if (item) {
// show selected chart
this.$el.find(item.svg_id).show();
+ // get chart
+ var chart = self.app.charts.get(chart_id);
+
+ // update portlet
+ this.portlet.label(chart.get('title'));
+ this.portlet.setOperation('edit', function() {
+ // get chart
+ self.app.chart.copy(chart);
+
+ // show edit
+ self.app.charts_view.$el.hide();
+ self.app.chart_view.$el.show();
+ });
+
// this trigger d3 update events
$(window).trigger('resize');
}
@@ -83,23 +98,11 @@
// backup chart details
var chart_id = chart.id;
- // update portlet
- this.portlet.label(chart.get('title'));
- this.portlet.setOperation('edit', function() {
- // get chart
- var chart = self.app.charts.get(chart_id);
- self.app.chart.copy(chart);
-
- // show edit
- self.app.charts_view.$el.hide();
- self.app.chart_view.$el.show();
- });
-
// make sure that svg does not exist already
- this._removeChart(chart.id);
+ this._removeChart(chart_id);
// create id
- var svg_id = '#svg_' + chart.id;
+ var svg_id = '#svg_' + chart_id;
// create element
var chart_el = $(this._template({id: svg_id, height : this.options.height}));
@@ -108,7 +111,7 @@
this.portlet.append(chart_el);
// backup id
- this.list[chart.id] = {
+ this.list[chart_id] = {
svg_id : svg_id
}
@@ -155,8 +158,8 @@
chart_index++;
});
- // add view
- self.list[chart.id].view = view;
+ // show
+ self.show(chart_id);
});
},
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0