galaxy-commits
Threads by month
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
December 2013
- 1 participants
- 207 discussions
commit/galaxy-central: guerler: Grids: Pack scripts, remove grid_body from mako
by commits-noreply@bitbucket.org 18 Dec '13
by commits-noreply@bitbucket.org 18 Dec '13
18 Dec '13
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/9fa754a203b7/
Changeset: 9fa754a203b7
User: guerler
Date: 2013-12-18 23:28:16
Summary: Grids: Pack scripts, remove grid_body from mako
Affected #: 6 files
diff -r a3e2c3464298ebea3fd2ab93a43aac479ba9665a -r 9fa754a203b7312d58211b5e1e7140bf36aec76a static/scripts/packed/galaxy.grids.js
--- a/static/scripts/packed/galaxy.grids.js
+++ b/static/scripts/packed/galaxy.grids.js
@@ -1,1 +1,1 @@
-jQuery.ajaxSettings.traditional=true;define(["mvc/ui"],function(){var a=Backbone.Model.extend({defaults:{url_base:"",async:false,async_ops:[],categorical_filters:[],filters:{},sort_key:null,show_item_checkboxes:false,advanced_search:false,cur_page:1,num_pages:1,operation:undefined,item_ids:undefined},can_async_op:function(c){return _.indexOf(this.attributes.async_ops,c)!==-1},add_filter:function(g,h,d){if(d){var e=this.attributes.filters[g],c;if(e===null||e===undefined){c=h}else{if(typeof(e)=="string"){if(e=="All"){c=h}else{var f=[];f[0]=e;f[1]=h;c=f}}else{c=e;c.push(h)}}this.attributes.filters[g]=c}else{this.attributes.filters[g]=h}},remove_filter:function(d,g){var c=this.attributes.filters[d];if(c===null||c===undefined){return false}var f=true;if(typeof(c)==="string"){if(c=="All"){f=false}else{delete this.attributes.filters[d]}}else{var e=_.indexOf(c,g);if(e!==-1){c.splice(e,1)}else{f=false}}return f},get_url_data:function(){var c={async:this.attributes.async,sort:this.attributes.sort_key,page:this.attributes.cur_page,show_item_checkboxes:this.attributes.show_item_checkboxes,advanced_search:this.attributes.advanced_search};if(this.attributes.operation){c.operation=this.attributes.operation}if(this.attributes.item_ids){c.id=this.attributes.item_ids}var d=this;_.each(_.pairs(d.attributes.filters),function(e){c["f-"+e[0]]=e[1]});return c}});var b=Backbone.View.extend({grid:null,initialize:function(c){this.init_grid(c);this.init_grid_controls();$("input[type=text]").each(function(){$(this).click(function(){$(this).select()}).keyup(function(){$(this).css("font-style","normal")})})},init_grid:function(c){this.grid=c;this.init_grid_elements()},init_grid_controls:function(){$(".submit-image").each(function(){$(this).mousedown(function(){$(this).addClass("gray-background")});$(this).mouseup(function(){$(this).removeClass("gray-background")})});var c=this;$(".sort-link").each(function(){$(this).click(function(){c.set_sort_condition($(this).attr("sort_key"));return false})});$(".categorical-filter > a").each(function(){$(this).click(function(){c.set_categorical_filter($(this).attr("filter_key"),$(this).attr("filter_val"));return false})});$(".text-filter-form").each(function(){$(this).submit(function(){var g=$(this).attr("column_key");var f=$("#input-"+g+"-filter");var h=f.val();f.val("");c.add_filter_condition(g,h);return false})});var d=$("#input-tags-filter");if(d.length){d.autocomplete(this.grid.history_tag_autocomplete_url,{selectFirst:false,autoFill:false,highlight:false,mustMatch:false})}var e=$("#input-name-filter");if(e.length){e.autocomplete(this.grid.history_name_autocomplete_url,{selectFirst:false,autoFill:false,highlight:false,mustMatch:false})}$(".advanced-search-toggle").each(function(){$(this).click(function(){$("#standard-search").slideToggle("fast");$("#advanced-search").slideToggle("fast");return false})})},init_grid_elements:function(){$(".grid").each(function(){var j=$(this).find("input.grid-row-select-checkbox");var i=$(this).find("span.grid-selected-count");var q=function(){i.text($(j).filter(":checked").length)};$(j).each(function(){$(this).change(q)});q()});if($(".community_rating_star").length!==0){$(".community_rating_star").rating({})}var p=this.grid.attributes;var o=this;$(".page-link > a").each(function(){$(this).click(function(){o.set_page($(this).attr("page_num"));return false})});$(".use-inbound").each(function(){$(this).click(function(i){o.execute({href:$(this).attr("href"),inbound:true});return false})});$(".use-outbound").each(function(){$(this).click(function(i){o.execute({href:$(this).attr("href")});return false})});for(var h in p.items){var k=$("#grid-"+h+"-popup");k.off();var d=new PopupMenu(k);var n=p.items[h];for(var g in p.operations){var e=p.operations[g];var l=e.label;var c=n.operation_config[l];var f=n.encode_id;if(c.allowed&&e.allow_popup){var m={html:e.label,href:c.url_args,target:c.target,confirmation_text:e.confirm,inbound:e.inbound};m.func=function(q){q.preventDefault();var j=$(q.target).html();var i=this.findItemByHtml(j);o.execute(i)};d.addItem(m)}}}},add_filter_condition:function(e,g){if(g===""){return false}this.grid.add_filter(e,g,true);var f=$("<span>"+g+"<a href='javascript:void(0);'><span class='delete-search-icon' /></span></a>");f.addClass("text-filter-val");var d=this;f.click(function(){d.grid.remove_filter(e,g);$(this).remove();d.go_page_one();d.execute()});var c=$("#"+e+"-filtering-criteria");c.append(f);this.go_page_one();this.execute()},set_sort_condition:function(h){var g=this.grid.get("sort_key");var f=h;if(g.indexOf(h)!==-1){if(g.substring(0,1)!=="-"){f="-"+h}else{}}$(".sort-arrow").remove();var e=(f.substring(0,1)=="-")?"↑":"↓";var c=$("<span>"+e+"</span>").addClass("sort-arrow");var d=$("#"+h+"-header");d.append(c);this.grid.set("sort_key",f);this.go_page_one();this.execute()},set_categorical_filter:function(e,g){var d=this.grid.get("categorical_filters")[e],f=this.grid.get("filters")[e];var c=this;$("."+e+"-filter").each(function(){var k=$.trim($(this).text());var i=d[k];var j=i[e];if(j==g){$(this).empty();$(this).addClass("current-filter");$(this).append(k)}else{if(j==f){$(this).empty();var h=$("<a href='#'>"+k+"</a>");h.click(function(){c.set_categorical_filter(e,j)});$(this).removeClass("current-filter");$(this).append(h)}}});this.grid.add_filter(e,g);this.go_page_one();this.execute()},set_page:function(c){var d=this;$(".page-link").each(function(){var i=$(this).attr("id"),g=parseInt(i.split("-")[2],10),e=d.grid.get("cur_page"),h;if(g===c){h=$(this).children().text();$(this).empty();$(this).addClass("inactive-link");$(this).text(h)}else{if(g===e){h=$(this).text();$(this).empty();$(this).removeClass("inactive-link");var f=$("<a href='#'>"+h+"</a>");f.click(function(){d.set_page(g)});$(this).append(f)}}});if(c==="all"){this.grid.set("cur_page",c)}else{this.grid.set("cur_page",parseInt(c,10))}this.execute()},submit_operation:function(f,g){var e=$('input[name="id"]:checked').length;if(!e>0){return false}var d=$(f).val();var c=[];$("input[name=id]:checked").each(function(){c.push($(this).val())});this.execute({operation:d,id:c,confirmation_text:g});return true},execute:function(l){var f=null;var e=null;var g=null;var c=null;var k=null;if(l){e=l.href;g=l.operation;f=l.id;c=l.confirmation_text;k=l.inbound;if(e!==undefined&&e.indexOf("operation=")!=-1){var j=e.split("?");if(j.length>1){var i=j[1];var d=i.split("&");for(var h=0;h<d.length;h++){if(d[h].indexOf("operation")!=-1){g=d[h].split("=")[1];g=g.replace(/\+/g," ")}else{if(d[h].indexOf("id")!=-1){f=d[h].split("=")[1]}}}}}}if(g&&f){if(c&&c!=""&&c!="None"){if(!confirm(c)){return false}}g=g.toLowerCase();this.grid.set({operation:g,item_ids:f});if(this.grid.can_async_op(g)){this.update_grid()}else{this.go_to(k,"")}return false}if(e){this.go_to(k,e);return false}if(this.grid.get("async")){this.update_grid()}else{this.go_to(k,"")}return false},go_to:function(f,d){var e=this.grid.get("async");this.grid.set("async",false);advanced_search=$("#advanced-search").is(":visible");this.grid.set("advanced_search",advanced_search);if(!d){d=this.grid.get("url_base")+"?"+$.param(this.grid.get_url_data())}this.grid.set({operation:undefined,item_ids:undefined,async:e});if(f){var c=$(".grid-header").closest(".inbound");if(c.length!==0){c.load(d);return}}window.location=d},update_grid:function(){var d=(this.grid.get("operation")?"POST":"GET");$(".loading-elt-overlay").show();var c=this;$.ajax({type:d,url:c.grid.get("url_base"),data:c.grid.get_url_data(),error:function(e){alert("Grid refresh failed")},success:function(f){var e=f.split("*****");$("#grid-table-body").html(e[0]);$("#grid-table-footer").html(e[1]);$("#grid-table-body").trigger("update");$(".loading-elt-overlay").hide();var g=$.trim(e[2]);if(g!==""){$("#grid-message").html(g).show();setTimeout(function(){$("#grid-message").hide()},5000)}},complete:function(){c.grid.set({operation:undefined,item_ids:undefined})}})},check_all_items:function(){var c=document.getElementById("check_all"),d=document.getElementsByTagName("input"),f=0,e;if(c.checked===true){for(e=0;e<d.length;e++){if(d[e].name.indexOf("id")!==-1){d[e].checked=true;f++}}}else{for(e=0;e<d.length;e++){if(d[e].name.indexOf("id")!==-1){d[e].checked=false}}}this.init_grid_elements()},go_page_one:function(){var c=this.grid.get("cur_page");if(c!==null&&c!==undefined&&c!=="all"){this.grid.set("cur_page",1)}}});return{Grid:a,GridView:b}});
\ No newline at end of file
+jQuery.ajaxSettings.traditional=true;define(["mvc/ui"],function(){var a=Backbone.Model.extend({defaults:{url_base:"",async:false,async_ops:[],categorical_filters:[],filters:{},sort_key:null,show_item_checkboxes:false,advanced_search:false,cur_page:1,num_pages:1,operation:undefined,item_ids:undefined},can_async_op:function(c){return _.indexOf(this.attributes.async_ops,c)!==-1},add_filter:function(g,h,d){if(d){var e=this.attributes.filters[g],c;if(e===null||e===undefined){c=h}else{if(typeof(e)=="string"){if(e=="All"){c=h}else{var f=[];f[0]=e;f[1]=h;c=f}}else{c=e;c.push(h)}}this.attributes.filters[g]=c}else{this.attributes.filters[g]=h}},remove_filter:function(d,g){var c=this.attributes.filters[d];if(c===null||c===undefined){return false}var f=true;if(typeof(c)==="string"){if(c=="All"){f=false}else{delete this.attributes.filters[d]}}else{var e=_.indexOf(c,g);if(e!==-1){c.splice(e,1)}else{f=false}}return f},get_url_data:function(){var c={async:this.attributes.async,sort:this.attributes.sort_key,page:this.attributes.cur_page,show_item_checkboxes:this.attributes.show_item_checkboxes,advanced_search:this.attributes.advanced_search};if(this.attributes.operation){c.operation=this.attributes.operation}if(this.attributes.item_ids){c.id=this.attributes.item_ids}var d=this;_.each(_.pairs(d.attributes.filters),function(e){c["f-"+e[0]]=e[1]});return c},get_url:function(c){return this.get("url_base")+"?"+$.param(this.get_url_data())+"&"+$.param(c)}});var b=Backbone.View.extend({grid:null,initialize:function(c){this.init_grid(c);this.init_grid_controls();$("input[type=text]").each(function(){$(this).click(function(){$(this).select()}).keyup(function(){$(this).css("font-style","normal")})})},init_grid:function(e){this.grid=new a(e);var d=this.grid.attributes;var c=this.grid.get("url_base");c=c.replace(/^.*\/\/[^\/]+/,"");this.grid.set("url_base",c);$("#grid-table-body").html(this.template_body(d));$("#grid-table-footer").html(this.template_footer(d));if(d.message){$("#grid-message").html(this.template_message(d));setTimeout(function(){$("#grid-message").html("")},5000)}this.init_grid_elements()},init_grid_controls:function(){$(".submit-image").each(function(){$(this).mousedown(function(){$(this).addClass("gray-background")});$(this).mouseup(function(){$(this).removeClass("gray-background")})});var c=this;$(".sort-link").each(function(){$(this).click(function(){c.set_sort_condition($(this).attr("sort_key"));return false})});$(".categorical-filter > a").each(function(){$(this).click(function(){c.set_categorical_filter($(this).attr("filter_key"),$(this).attr("filter_val"));return false})});$(".text-filter-form").each(function(){$(this).submit(function(){var g=$(this).attr("column_key");var f=$("#input-"+g+"-filter");var h=f.val();f.val("");c.add_filter_condition(g,h);return false})});var d=$("#input-tags-filter");if(d.length){d.autocomplete(this.grid.history_tag_autocomplete_url,{selectFirst:false,autoFill:false,highlight:false,mustMatch:false})}var e=$("#input-name-filter");if(e.length){e.autocomplete(this.grid.history_name_autocomplete_url,{selectFirst:false,autoFill:false,highlight:false,mustMatch:false})}$(".advanced-search-toggle").each(function(){$(this).click(function(){$("#standard-search").slideToggle("fast");$("#advanced-search").slideToggle("fast");return false})})},init_grid_elements:function(){$(".grid").each(function(){var r=$(this).find("input.grid-row-select-checkbox");var q=$(this).find("span.grid-selected-count");var s=function(){q.text($(r).filter(":checked").length)};$(r).each(function(){$(this).change(s)});s()});if($(".community_rating_star").length!==0){$(".community_rating_star").rating({})}var p=this.grid.attributes;var o=this;$(".page-link > a").each(function(){$(this).click(function(){o.set_page($(this).attr("page_num"));return false})});$(".use-inbound").each(function(){$(this).click(function(q){o.execute({href:$(this).attr("href"),inbound:true});return false})});$(".use-outbound").each(function(){$(this).click(function(q){o.execute({href:$(this).attr("href")});return false})});for(var h in p.items){var k=$("#grid-"+h+"-popup");k.off();var d=new PopupMenu(k);var n=p.items[h];for(var g in p.operations){var e=p.operations[g];var l=e.label;var c=n.operation_config[l];var f=n.encode_id;if(c.allowed&&e.allow_popup){var m={html:e.label,href:c.url_args,target:c.target,confirmation_text:e.confirm,inbound:e.inbound};m.func=function(s){s.preventDefault();var r=$(s.target).html();var q=this.findItemByHtml(r);o.execute(q)};d.addItem(m)}}}},add_filter_condition:function(e,g){if(g===""){return false}this.grid.add_filter(e,g,true);var f=$("<span>"+g+"<a href='javascript:void(0);'><span class='delete-search-icon' /></span></a>");f.addClass("text-filter-val");var d=this;f.click(function(){d.grid.remove_filter(e,g);$(this).remove();d.go_page_one();d.execute()});var c=$("#"+e+"-filtering-criteria");c.append(f);this.go_page_one();this.execute()},set_sort_condition:function(h){var g=this.grid.get("sort_key");var f=h;if(g.indexOf(h)!==-1){if(g.substring(0,1)!=="-"){f="-"+h}else{}}$(".sort-arrow").remove();var e=(f.substring(0,1)=="-")?"↑":"↓";var c=$("<span>"+e+"</span>").addClass("sort-arrow");var d=$("#"+h+"-header");d.append(c);this.grid.set("sort_key",f);this.go_page_one();this.execute()},set_categorical_filter:function(e,g){var d=this.grid.get("categorical_filters")[e],f=this.grid.get("filters")[e];var c=this;$("."+e+"-filter").each(function(){var m=$.trim($(this).text());var k=d[m];var l=k[e];if(l==g){$(this).empty();$(this).addClass("current-filter");$(this).append(m)}else{if(l==f){$(this).empty();var h=$("<a href='#'>"+m+"</a>");h.click(function(){c.set_categorical_filter(e,l)});$(this).removeClass("current-filter");$(this).append(h)}}});this.grid.add_filter(e,g);this.go_page_one();this.execute()},set_page:function(c){var d=this;$(".page-link").each(function(){var k=$(this).attr("id"),g=parseInt(k.split("-")[2],10),e=d.grid.get("cur_page"),h;if(g===c){h=$(this).children().text();$(this).empty();$(this).addClass("inactive-link");$(this).text(h)}else{if(g===e){h=$(this).text();$(this).empty();$(this).removeClass("inactive-link");var f=$("<a href='#'>"+h+"</a>");f.click(function(){d.set_page(g)});$(this).append(f)}}});if(c==="all"){this.grid.set("cur_page",c)}else{this.grid.set("cur_page",parseInt(c,10))}this.execute()},submit_operation:function(f,g){var e=$('input[name="id"]:checked').length;if(!e>0){return false}var d=$(f).val();var c=[];$("input[name=id]:checked").each(function(){c.push($(this).val())});this.execute({operation:d,id:c,confirmation_text:g});return true},execute:function(n){var f=null;var e=null;var g=null;var c=null;var m=null;if(n){e=n.href;g=n.operation;f=n.id;c=n.confirmation_text;m=n.inbound;if(e!==undefined&&e.indexOf("operation=")!=-1){var l=e.split("?");if(l.length>1){var k=l[1];var d=k.split("&");for(var h=0;h<d.length;h++){if(d[h].indexOf("operation")!=-1){g=d[h].split("=")[1];g=g.replace(/\+/g," ")}else{if(d[h].indexOf("id")!=-1){f=d[h].split("=")[1]}}}}}}if(g&&f){if(c&&c!=""&&c!="None"&&c!="null"){if(!confirm(c)){return false}}g=g.toLowerCase();this.grid.set({operation:g,item_ids:f});if(this.grid.can_async_op(g)){this.update_grid()}else{this.go_to(m,"")}return false}if(e){this.go_to(m,e);return false}if(this.grid.get("async")){this.update_grid()}else{this.go_to(m,"")}return false},go_to:function(f,d){var e=this.grid.get("async");this.grid.set("async",false);advanced_search=$("#advanced-search").is(":visible");this.grid.set("advanced_search",advanced_search);if(!d){d=this.grid.get("url_base")+"?"+$.param(this.grid.get_url_data())}this.grid.set({operation:undefined,item_ids:undefined,async:e});if(f){var c=$(".grid-header").closest(".inbound");if(c.length!==0){c.load(d);return}}window.location=d},update_grid:function(){var d=(this.grid.get("operation")?"POST":"GET");$(".loading-elt-overlay").show();var c=this;$.ajax({type:d,url:c.grid.get("url_base"),data:c.grid.get_url_data(),error:function(e){alert("Grid refresh failed")},success:function(e){c.init_grid($.parseJSON(e));$("#grid-table-body").trigger("update");$(".loading-elt-overlay").hide()},complete:function(){c.grid.set({operation:undefined,item_ids:undefined})}})},check_all_items:function(){var c=document.getElementById("check_all"),d=document.getElementsByTagName("input"),f=0,e;if(c.checked===true){for(e=0;e<d.length;e++){if(d[e].name.indexOf("id")!==-1){d[e].checked=true;f++}}}else{for(e=0;e<d.length;e++){if(d[e].name.indexOf("id")!==-1){d[e].checked=false}}}this.init_grid_elements()},go_page_one:function(){var c=this.grid.get("cur_page");if(c!==null&&c!==undefined&&c!=="all"){this.grid.set("cur_page",1)}},template_body:function(s){var l="";var t=0;var g=s.items.length;if(g==0){l+='<tr><td colspan="100"><em>No Items</em></td></tr>';t=1}for(i in s.items){var q=s.items[i];var c=q.encode_id;var h="grid-"+i+"-popup";l+="<tr ";if(s.current_item_id==q.id){l+='class="current"'}l+=">";if(s.show_item_checkboxes){l+='<td style="width: 1.5em;"><input type="checkbox" name="id" value="'+c+'" id="'+c+'" class="grid-row-select-checkbox" /></td>'}for(j in s.columns){var f=s.columns[j];if(f.visible){var e="";if(f.nowrap){e='style="white-space:nowrap;"'}var r=q.column_config[f.label];var k=r.link;var m=r.value;var p=r.inbound;if(jQuery.type(m)==="string"){m=m.replace(/\/\//g,"/")}var d="";var o="";if(f.attach_popup){d="grid-"+i+"-popup";o="menubutton";if(k!=""){o+=" split"}o+=" popup"}l+="<td "+e+">";if(k){if(s.operations.length!=0){l+='<div id="'+d+'" class="'+o+'" style="float: left;">'}var n="";if(p){n="use-inbound"}else{n="use-outbound"}l+='<a class="label '+n+'" href="'+k+'" onclick="return false;">'+m+"</a>";if(s.operations.length!=0){l+="</div>"}}else{l+='<div id="'+d+'" class="'+o+'"><label id="'+f.label_id_prefix+c+'" for="'+c+'">'+m+"</label></div>"}l+="</td>"}}l+="</tr>";t++}return l},template_footer:function(q){var m="";if(q.use_paging&&q.num_pages>1){var o=q.num_page_links;var c=q.cur_page_num;var p=q.num_pages;var l=o/2;var k=c-l;var g=0;if(k==0){k=1;g=l-(c-k)}var f=l+g;var e=c+f;if(e<=p){max_offset=0}else{e=p;max_offset=f-(e+1-c)}if(max_offset!=0){k-=max_offset;if(k<1){k=1}}m+='<tr id="page-links-row">';if(q.show_item_checkboxes){m+="<td></td>"}m+='<td colspan="100"><span id="page-link-container">Page:';if(k>1){m+='<span class="page-link" id="page-link-1"><a href="'+this.grid.get_url({page:n})+'" page_num="1" onclick="return false;">1</a></span> ...'}for(var n=k;n<e+1;n++){if(n==q.cur_page_num){m+='<span class="page-link inactive-link" id="page-link-'+n+'">'+n+"</span>"}else{m+='<span class="page-link" id="page-link-'+n+'"><a href="'+this.grid.get_url({page:n})+'" onclick="return false;" page_num="'+n+'">'+n+"</a></span>"}}if(e<p){m+='...<span class="page-link" id="page-link-'+p+'"><a href="'+this.grid.get_url({page:p})+'" onclick="return false;" page_num="'+p+'">'+p+"</a></span>"}m+="</span>";m+='<span class="page-link" id="show-all-link-span"> | <a href="'+this.grid.get_url({page:"all"})+'" onclick="return false;" page_num="all">Show All</a></span></td></tr>'}if(q.show_item_checkboxes){m+='<tr><input type="hidden" id="operation" name="operation" value=""><td></td><td colspan="100">For <span class="grid-selected-count"></span> selected '+q.get_class_plural+": ";for(i in q.operations){var d=q.operations[i];if(d.allow_multiple){m+='<input type="button" value="'+d.label+'" class="action-button" onclick="gridView.submit_operation(this, \''+d.confirm+"')\"> "}}m+="</td></tr>"}var h=false;for(i in q.operations){if(q.operations[i].global_operation){h=true;break}}if(h){m+='<tr><td colspan="100">';for(i in q.operations){var d=q.operations[i];if(d.global_operation){m+='<a class="action-button" href="'+d.global_operation+'">'+d.label+"</a>"}}m+="</td></tr>"}if(q.legend){m+='<tr><td colspan="100">'+q.legend+"</td></tr>"}return m},template_message:function(c){return'<p><div class="'+c.status+'message transient-message">'+c.message+'</div><div style="clear: both"></div></p>'}});return{Grid:a,GridView:b}});
\ No newline at end of file
diff -r a3e2c3464298ebea3fd2ab93a43aac479ba9665a -r 9fa754a203b7312d58211b5e1e7140bf36aec76a static/scripts/packed/galaxy.workflow_editor.canvas.js
--- a/static/scripts/packed/galaxy.workflow_editor.canvas.js
+++ b/static/scripts/packed/galaxy.workflow_editor.canvas.js
@@ -1,1 +1,1 @@
-function Terminal(a){this.element=a;this.connectors=[]}$.extend(Terminal.prototype,{connect:function(a){this.connectors.push(a);if(this.node){this.node.changed()}},disconnect:function(a){this.connectors.splice($.inArray(a,this.connectors),1);if(this.node){this.node.changed()}},redraw:function(){$.each(this.connectors,function(a,b){b.redraw()})},destroy:function(){$.each(this.connectors.slice(),function(a,b){b.destroy()})}});function OutputTerminal(a,b){Terminal.call(this,a);this.datatypes=b}OutputTerminal.prototype=new Terminal();function InputTerminal(b,c,a){Terminal.call(this,b);this.datatypes=c;this.multiple=a}InputTerminal.prototype=new Terminal();$.extend(InputTerminal.prototype,{can_accept:function(a){if(this.connectors.length<1||this.multiple){for(var c in this.datatypes){var f=new Array();f=f.concat(a.datatypes);if(a.node.post_job_actions){for(var d in a.node.post_job_actions){var g=a.node.post_job_actions[d];if(g.action_type=="ChangeDatatypeAction"&&(g.output_name==""||g.output_name==a.name)&&g.action_arguments){f.push(g.action_arguments.newtype)}}}for(var b in f){if(f[b]=="input"||issubtype(f[b],this.datatypes[c])){return true}}}}return false}});function Connector(b,a){this.canvas=null;this.dragging=false;this.inner_color="#FFFFFF";this.outer_color="#D8B365";if(b&&a){this.connect(b,a)}}$.extend(Connector.prototype,{connect:function(b,a){this.handle1=b;if(this.handle1){this.handle1.connect(this)}this.handle2=a;if(this.handle2){this.handle2.connect(this)}},destroy:function(){if(this.handle1){this.handle1.disconnect(this)}if(this.handle2){this.handle2.disconnect(this)}$(this.canvas).remove()},redraw:function(){var d=$("#canvas-container");if(!this.canvas){this.canvas=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(this.canvas)}d.append($(this.canvas));if(this.dragging){this.canvas.style.zIndex="300"}}var n=function(c){return $(c).offset().left-d.offset().left};var i=function(c){return $(c).offset().top-d.offset().top};if(!this.handle1||!this.handle2){return}var h=n(this.handle1.element)+5;var g=i(this.handle1.element)+5;var p=n(this.handle2.element)+5;var m=i(this.handle2.element)+5;var f=100;var k=Math.min(h,p);var a=Math.max(h,p);var j=Math.min(g,m);var t=Math.max(g,m);var b=Math.min(Math.max(Math.abs(t-j)/2,100),300);var o=k-f;var s=j-f;var q=a-k+2*f;var l=t-j+2*f;this.canvas.style.left=o+"px";this.canvas.style.top=s+"px";this.canvas.setAttribute("width",q);this.canvas.setAttribute("height",l);h-=o;g-=s;p-=o;m-=s;var r=this.canvas.getContext("2d");r.lineCap="round";r.strokeStyle=this.outer_color;r.lineWidth=7;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke();r.strokeStyle=this.inner_color;r.lineWidth=5;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke()}});function Node(a){this.element=a;this.input_terminals={};this.output_terminals={};this.tool_errors={}}$.extend(Node.prototype,{enable_input_terminal:function(f,b,c,a){var d=this;$(f).each(function(){var g=this.terminal=new InputTerminal(this,c,a);g.node=d;g.name=b;$(this).bind("dropinit",function(h,i){return $(i.drag).hasClass("output-terminal")&&g.can_accept(i.drag.terminal)}).bind("dropstart",function(h,i){if(i.proxy.terminal){i.proxy.terminal.connectors[0].inner_color="#BBFFBB"}}).bind("dropend",function(h,i){if(i.proxy.terminal){i.proxy.terminal.connectors[0].inner_color="#FFFFFF"}}).bind("drop",function(h,i){(new Connector(i.drag.terminal,g)).redraw()}).bind("hover",function(){if(g.connectors.length>0){var h=$("<div class='callout'></div>").css({display:"none"}).appendTo("body").append($("<div class='button'></div>").append($("<div/>").addClass("fa-icon-button fa fa-times").click(function(){$.each(g.connectors,function(j,i){if(i){i.destroy()}});h.remove()}))).bind("mouseleave",function(){$(this).remove()});h.css({top:$(this).offset().top-2,left:$(this).offset().left-h.width(),"padding-right":$(this).width()}).show()}});d.input_terminals[b]=g})},enable_output_terminal:function(d,a,b){var c=this;$(d).each(function(){var g=this;var f=this.terminal=new OutputTerminal(this,b);f.node=c;f.name=a;$(this).bind("dragstart",function(j,k){$(k.available).addClass("input-terminal-active");workflow.check_changes_in_active_form();var i=$('<div class="drag-terminal" style="position: absolute;"></div>').appendTo("#canvas-container").get(0);i.terminal=new OutputTerminal(i);var l=new Connector();l.dragging=true;l.connect(this.terminal,i.terminal);return i}).bind("drag",function(i,j){var h=function(){var l=$(j.proxy).offsetParent().offset(),k=j.offsetX-l.left,m=j.offsetY-l.top;$(j.proxy).css({left:k,top:m});j.proxy.terminal.redraw();canvas_manager.update_viewport_overlay()};h();$("#canvas-container").get(0).scroll_panel.test(i,h)}).bind("dragend",function(h,i){i.proxy.terminal.connectors[0].destroy();$(i.proxy).remove();$(i.available).removeClass("input-terminal-active");$("#canvas-container").get(0).scroll_panel.stop()});c.output_terminals[a]=f})},redraw:function(){$.each(this.input_terminals,function(a,b){b.redraw()});$.each(this.output_terminals,function(a,b){b.redraw()})},destroy:function(){$.each(this.input_terminals,function(a,b){b.destroy()});$.each(this.output_terminals,function(a,b){b.destroy()});workflow.remove_node(this);$(this.element).remove()},make_active:function(){$(this.element).addClass("toolForm-active")},make_inactive:function(){var a=this.element.get(0);(function(b){b.removeChild(a);b.appendChild(a)})(a.parentNode);$(a).removeClass("toolForm-active")},init_field_data:function(h){var g=this.element;if(h.type){this.type=h.type}this.name=h.name;this.form_html=h.form_html;this.tool_state=h.tool_state;this.tool_errors=h.tool_errors;this.tooltip=h.tooltip?h.tooltip:"";this.annotation=h.annotation;this.post_job_actions=h.post_job_actions?h.post_job_actions:{};this.workflow_outputs=h.workflow_outputs?h.workflow_outputs:[];if(this.tool_errors){g.addClass("tool-node-error")}else{g.removeClass("tool-node-error")}var d=this;var c=Math.max(150,g.width());var a=g.find(".toolFormBody");a.find("div").remove();var i=$("<div class='inputs'></div>").appendTo(a);$.each(h.data_inputs,function(k,f){var j=$("<div class='terminal input-terminal'></div>");d.enable_input_terminal(j,f.name,f.extensions,f.multiple);var b=$("<div class='form-row dataRow input-data-row' name='"+f.name+"'>"+f.label+"</div>");b.css({position:"absolute",left:-1000,top:-1000,display:"none"});$("body").append(b);c=Math.max(c,b.outerWidth());b.css({position:"",left:"",top:"",display:""});b.remove();i.append(b.prepend(j))});if((h.data_inputs.length>0)&&(h.data_outputs.length>0)){a.append($("<div class='rule'></div>"))}$.each(h.data_outputs,function(k,b){var j=$("<div class='terminal output-terminal'></div>");d.enable_output_terminal(j,b.name,b.extensions);var f=b.name;if(b.extensions.indexOf("input")<0){f=f+" ("+b.extensions.join(", ")+")"}var m=$("<div class='form-row dataRow'>"+f+"</div>");if(d.type=="tool"){var l=$("<div class='callout "+f+"'></div>").css({display:"none"}).append($("<div class='buttons'></div>").append($("<img/>").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png").click(function(){if($.inArray(b.name,d.workflow_outputs)!=-1){d.workflow_outputs.splice($.inArray(b.name,d.workflow_outputs),1);l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{d.workflow_outputs.push(b.name);l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}workflow.has_changes=true;canvas_manager.draw_overview()}))).tooltip({delay:500,title:"Flag this as a workflow output. All non-flagged outputs will be hidden."});l.css({top:"50%",margin:"-8px 0px 0px 0px",right:8});l.show();m.append(l);if($.inArray(b.name,d.workflow_outputs)===-1){l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}m.hover(function(){l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-yellow.png")},function(){if($.inArray(b.name,d.workflow_outputs)===-1){l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}})}m.css({position:"absolute",left:-1000,top:-1000,display:"none"});$("body").append(m);c=Math.max(c,m.outerWidth()+17);m.css({position:"",left:"",top:"",display:""});m.detach();a.append(m.append(j))});g.css("width",Math.min(250,Math.max(g.width(),c)));workflow.node_changed(this)},update_field_data:function(f){var c=$(this.element),d=this;this.tool_state=f.tool_state;this.form_html=f.form_html;this.tool_errors=f.tool_errors;this.annotation=f.annotation;var g=$.parseJSON(f.post_job_actions);this.post_job_actions=g?g:{};if(this.tool_errors){c.addClass("tool-node-error")}else{c.removeClass("tool-node-error")}var h=c.find("div.inputs");var b=$("<div class='inputs'></div>");var a=h.find("div.input-data-row");$.each(f.data_inputs,function(l,j){var k=$("<div class='terminal input-terminal'></div>");d.enable_input_terminal(k,j.name,j.extensions,j.multiple);h.find("div[name='"+j.name+"']").each(function(){$(this).find(".input-terminal").each(function(){var i=this.terminal.connectors[0];if(i){k[0].terminal.connectors[0]=i;i.handle2=k[0].terminal}});$(this).remove()});b.append($("<div class='form-row dataRow input-data-row' name='"+j.name+"'>"+j.label+"</div>").prepend(k))});h.replaceWith(b);h.find("div.input-data-row > .terminal").each(function(){this.terminal.destroy()});this.changed();this.redraw()},error:function(d){var a=$(this.element).find(".toolFormBody");a.find("div").remove();var c="<div style='color: red; text-style: italic;'>"+d+"</div>";this.form_html=c;a.html(c);workflow.node_changed(this)},changed:function(){workflow.node_changed(this)}});function Workflow(a){this.canvas_container=a;this.id_counter=0;this.nodes={};this.name=null;this.has_changes=false;this.active_form_has_changes=false}$.extend(Workflow.prototype,{add_node:function(a){a.id=this.id_counter;a.element.attr("id","wf-node-step-"+a.id);this.id_counter++;this.nodes[a.id]=a;this.has_changes=true;a.workflow=this},remove_node:function(a){if(this.active_node==a){this.clear_active_node()}delete this.nodes[a.id];this.has_changes=true},remove_all:function(){wf=this;$.each(this.nodes,function(b,a){a.destroy();wf.remove_node(a)})},rectify_workflow_outputs:function(){var b=false;var a=false;$.each(this.nodes,function(c,d){if(d.workflow_outputs&&d.workflow_outputs.length>0){b=true}$.each(d.post_job_actions,function(g,f){if(f.action_type==="HideDatasetAction"){a=true}})});if(b!==false||a!==false){$.each(this.nodes,function(c,g){if(g.type==="tool"){var f=false;if(g.post_job_actions==null){g.post_job_actions={};f=true}var d=[];$.each(g.post_job_actions,function(i,h){if(h.action_type=="HideDatasetAction"){d.push(i)}});if(d.length>0){$.each(d,function(h,j){f=true;delete g.post_job_actions[j]})}if(b){$.each(g.output_terminals,function(i,j){var h=true;$.each(g.workflow_outputs,function(l,m){if(j.name===m){h=false}});if(h===true){f=true;var k={action_type:"HideDatasetAction",output_name:j.name,action_arguments:{}};g.post_job_actions["HideDatasetAction"+j.name]=null;g.post_job_actions["HideDatasetAction"+j.name]=k}})}if(workflow.active_node==g&&f===true){workflow.reload_active_node()}}})}},to_simple:function(){var a={};$.each(this.nodes,function(c,f){var g={};$.each(f.input_terminals,function(i,j){g[j.name]=null;var h=[];$.each(j.connectors,function(k,l){h[k]={id:l.handle1.node.id,output_name:l.handle1.name};g[j.name]=h})});var b={};if(f.post_job_actions){$.each(f.post_job_actions,function(j,h){var k={action_type:h.action_type,output_name:h.output_name,action_arguments:h.action_arguments};b[h.action_type+h.output_name]=null;b[h.action_type+h.output_name]=k})}if(!f.workflow_outputs){f.workflow_outputs=[]}var d={id:f.id,type:f.type,tool_id:f.tool_id,tool_state:f.tool_state,tool_errors:f.tool_errors,input_connections:g,position:$(f.element).position(),annotation:f.annotation,post_job_actions:f.post_job_actions,workflow_outputs:f.workflow_outputs};a[f.id]=d});return{steps:a}},from_simple:function(b){wf=this;var c=0;wf.name=b.name;var a=false;$.each(b.steps,function(g,f){var d=prebuild_node("tool",f.name,f.tool_id);d.init_field_data(f);if(f.position){d.element.css({top:f.position.top,left:f.position.left})}d.id=f.id;wf.nodes[d.id]=d;c=Math.max(c,parseInt(g));if(!a&&d.type==="tool"){if(d.workflow_outputs.length>0){a=true}else{$.each(d.post_job_actions,function(i,h){if(h.action_type==="HideDatasetAction"){a=true}})}}});wf.id_counter=c+1;$.each(b.steps,function(g,f){var d=wf.nodes[g];$.each(f.input_connections,function(i,h){if(h){if($.isArray(h)){$.each(h,function(m,k){var n=wf.nodes[k.id];var o=new Connector();o.connect(n.output_terminals[k.output_name],d.input_terminals[i]);o.redraw()})}else{var j=wf.nodes[h.id];var l=new Connector();l.connect(j.output_terminals[h.output_name],d.input_terminals[i]);l.redraw()}}});if(a&&d.type==="tool"){$.each(d.output_terminals,function(h,i){if(d.post_job_actions["HideDatasetAction"+i.name]===undefined){d.workflow_outputs.push(i.name);callout=$(d.element).find(".callout."+i.name);callout.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png");workflow.has_changes=true}})}})},check_changes_in_active_form:function(){if(this.active_form_has_changes){this.has_changes=true;$("#right-content").find("form").submit();this.active_form_has_changes=false}},reload_active_node:function(){if(this.active_node){var a=this.active_node;this.clear_active_node();this.activate_node(a)}},clear_active_node:function(){if(this.active_node){this.active_node.make_inactive();this.active_node=null}parent.show_form_for_tool("<div>No node selected</div>")},activate_node:function(a){if(this.active_node!=a){this.check_changes_in_active_form();this.clear_active_node();parent.show_form_for_tool(a.form_html+a.tooltip,a);a.make_active();this.active_node=a}},node_changed:function(a){this.has_changes=true;if(this.active_node==a){this.check_changes_in_active_form();parent.show_form_for_tool(a.form_html+a.tooltip,a)}},layout:function(){this.check_changes_in_active_form();this.has_changes=true;var i={};var b={};$.each(this.nodes,function(l,k){if(i[l]===undefined){i[l]=0}if(b[l]===undefined){b[l]=[]}});$.each(this.nodes,function(l,k){$.each(k.input_terminals,function(m,n){$.each(n.connectors,function(p,q){var o=q.handle1.node;i[k.id]+=1;b[o.id].push(k.id)})})});node_ids_by_level=[];while(true){level_parents=[];for(var a in i){if(i[a]==0){level_parents.push(a)}}if(level_parents.length==0){break}node_ids_by_level.push(level_parents);for(var f in level_parents){var j=level_parents[f];delete i[j];for(var g in b[j]){i[b[j][g]]-=1}}}if(i.length){return}var d=this.nodes;var h=80;v_pad=30;var c=h;$.each(node_ids_by_level,function(k,l){l.sort(function(p,o){return $(d[p].element).position().top-$(d[o].element).position().top});var m=0;var n=v_pad;$.each(l,function(o,r){var q=d[r];var p=$(q.element);$(p).css({top:n,left:c});m=Math.max(m,$(p).width());n+=$(p).height()+v_pad});c+=m+h});$.each(d,function(k,l){l.redraw()})},bounds_for_all_nodes:function(){var d=Infinity,b=-Infinity,c=Infinity,a=-Infinity,f;$.each(this.nodes,function(h,g){e=$(g.element);f=e.position();d=Math.min(d,f.left);b=Math.max(b,f.left+e.width());c=Math.min(c,f.top);a=Math.max(a,f.top+e.width())});return{xmin:d,xmax:b,ymin:c,ymax:a}},fit_canvas_to_nodes:function(){var a=this.bounds_for_all_nodes();var f=this.canvas_container.position();var i=this.canvas_container.parent();var d=fix_delta(a.xmin,100);var h=fix_delta(a.ymin,100);d=Math.max(d,f.left);h=Math.max(h,f.top);var c=f.left-d;var g=f.top-h;var b=round_up(a.xmax+100,100)+d;var j=round_up(a.ymax+100,100)+h;b=Math.max(b,-c+i.width());j=Math.max(j,-g+i.height());this.canvas_container.css({left:c,top:g,width:b,height:j});this.canvas_container.children().each(function(){var k=$(this).position();$(this).css("left",k.left+d);$(this).css("top",k.top+h)})}});function fix_delta(a,b){if(a<b||a>3*b){new_pos=(Math.ceil(((a%b))/b)+1)*b;return(-(a-new_pos))}return 0}function round_up(a,b){return Math.ceil(a/b)*b}function prebuild_node(l,j,r){var i=$("<div class='toolForm toolFormInCanvas'></div>");var g=new Node(i);g.type=l;if(l=="tool"){g.tool_id=r}var n=$("<div class='toolFormTitle unselectable'>"+j+"</div>");i.append(n);i.css("left",$(window).scrollLeft()+20);i.css("top",$(window).scrollTop()+20);var m=$("<div class='toolFormBody'></div>");var h="<div><img height='16' align='middle' src='"+galaxy_config.root+"static/images/loading_small_white_bg.gif'/> loading tool info...</div>";m.append(h);g.form_html=h;i.append(m);var k=$("<div class='buttons' style='float: right;'></div>");k.append($("<div>").addClass("fa-icon-button fa fa-times").click(function(b){g.destroy()}));i.appendTo("#canvas-container");var d=$("#canvas-container").position();var c=$("#canvas-container").parent();var a=i.width();var q=i.height();i.css({left:(-d.left)+(c.width()/2)-(a/2),top:(-d.top)+(c.height()/2)-(q/2)});k.prependTo(n);a+=(k.width()+10);i.css("width",a);$(i).bind("dragstart",function(){workflow.activate_node(g)}).bind("dragend",function(){workflow.node_changed(this);workflow.fit_canvas_to_nodes();canvas_manager.draw_overview()}).bind("dragclickonly",function(){workflow.activate_node(g)}).bind("drag",function(o,p){var f=$(this).offsetParent().offset(),b=p.offsetX-f.left,s=p.offsetY-f.top;$(this).css({left:b,top:s});$(this).find(".terminal").each(function(){this.terminal.redraw()})});return g}var ext_to_type=null;var type_to_type=null;function issubtype(b,a){b=ext_to_type[b];a=ext_to_type[a];return(type_to_type[b])&&(a in type_to_type[b])}function populate_datatype_info(a){ext_to_type=a.ext_to_class_name;type_to_type=a.class_to_classes}function ScrollPanel(a){this.panel=a}$.extend(ScrollPanel.prototype,{test:function(v,d){clearTimeout(this.timeout);var k=v.pageX,j=v.pageY,l=$(this.panel),c=l.position(),b=l.width(),i=l.height(),w=l.parent(),s=w.width(),a=w.height(),r=w.offset(),p=r.left,m=r.top,A=p+w.width(),u=m+w.height(),B=-(b-(s/2)),z=-(i-(a/2)),g=(s/2),f=(a/2),h=false,q=5,o=23;if(k-q<p){if(c.left<g){var n=Math.min(o,g-c.left);l.css("left",c.left+n);h=true}}else{if(k+q>A){if(c.left>B){var n=Math.min(o,c.left-B);l.css("left",c.left-n);h=true}}else{if(j-q<m){if(c.top<f){var n=Math.min(o,f-c.top);l.css("top",c.top+n);h=true}}else{if(j+q>u){if(c.top>z){var n=Math.min(o,c.top-B);l.css("top",(c.top-n)+"px");h=true}}}}}if(h){d();var l=this;this.timeout=setTimeout(function(){l.test(v,d)},50)}},stop:function(b,a){clearTimeout(this.timeout)}});function CanvasManager(b,a){this.cv=b;this.cc=this.cv.find("#canvas-container");this.oc=a.find("#overview-canvas");this.ov=a.find("#overview-viewport");this.init_drag()}$.extend(CanvasManager.prototype,{init_drag:function(){var b=this;var a=function(f,g){f=Math.min(f,b.cv.width()/2);f=Math.max(f,-b.cc.width()+b.cv.width()/2);g=Math.min(g,b.cv.height()/2);g=Math.max(g,-b.cc.height()+b.cv.height()/2);b.cc.css({left:f,top:g});b.update_viewport_overlay()};this.cc.each(function(){this.scroll_panel=new ScrollPanel(this)});var d,c;this.cv.bind("dragstart",function(){var g=$(this).offset();var f=b.cc.position();c=f.top-g.top;d=f.left-g.left}).bind("drag",function(f,g){a(g.offsetX+d,g.offsetY+c)}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});this.ov.bind("drag",function(k,l){var h=b.cc.width(),n=b.cc.height(),m=b.oc.width(),j=b.oc.height(),f=$(this).offsetParent().offset(),i=l.offsetX-f.left,g=l.offsetY-f.top;a(-(i/m*h),-(g/j*n))}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});$("#overview-border").bind("drag",function(g,i){var j=$(this).offsetParent();var h=j.offset();var f=Math.max(j.width()-(i.offsetX-h.left),j.height()-(i.offsetY-h.top));$(this).css({width:f,height:f});b.draw_overview()});$("#overview-border div").bind("drag",function(){})},update_viewport_overlay:function(){var b=this.cc,f=this.cv,a=this.oc,c=this.ov,d=b.width(),j=b.height(),i=a.width(),g=a.height(),h=b.position();c.css({left:-(h.left/d*i),top:-(h.top/j*g),width:(f.width()/d*i)-2,height:(f.height()/j*g)-2})},draw_overview:function(){var j=$("#overview-canvas"),m=j.parent().parent().width(),i=j.get(0).getContext("2d"),d=$("#canvas-container").width(),l=$("#canvas-container").height();var g,a,k,f;var h=this.cv.width();var b=this.cv.height();if(d<h&&l<b){k=d/h*m;f=(m-k)/2;g=l/b*m;a=(m-g)/2}else{if(d<l){a=0;g=m;k=Math.ceil(g*d/l);f=(m-k)/2}else{k=m;f=0;g=Math.ceil(k*l/d);a=(m-g)/2}}j.parent().css({left:f,top:a,width:k,height:g});j.attr("width",k);j.attr("height",g);$.each(workflow.nodes,function(t,q){i.fillStyle="#D2C099";i.strokeStyle="#D8B365";i.lineWidth=1;var s=$(q.element),n=s.position(),c=n.left/d*k,r=n.top/l*g,o=s.width()/d*k,p=s.height()/l*g;if(q.tool_errors){i.fillStyle="#FFCCCC";i.strokeStyle="#AA6666"}else{if(q.workflow_outputs!=undefined&&q.workflow_outputs.length>0){i.fillStyle="#E8A92D";i.strokeStyle="#E8A92D"}}i.fillRect(c,r,o,p);i.strokeRect(c,r,o,p)});this.update_viewport_overlay()}});
\ No newline at end of file
+function Terminal(a){this.element=a;this.connectors=[]}$.extend(Terminal.prototype,{connect:function(a){this.connectors.push(a);if(this.node){this.node.changed()}},disconnect:function(a){this.connectors.splice($.inArray(a,this.connectors),1);if(this.node){this.node.changed()}},redraw:function(){$.each(this.connectors,function(a,b){b.redraw()})},destroy:function(){$.each(this.connectors.slice(),function(a,b){b.destroy()})}});function OutputTerminal(a,b){Terminal.call(this,a);this.datatypes=b}OutputTerminal.prototype=new Terminal();function InputTerminal(b,c,a){Terminal.call(this,b);this.datatypes=c;this.multiple=a}InputTerminal.prototype=new Terminal();$.extend(InputTerminal.prototype,{can_accept:function(a){if(this.connectors.length<1||this.multiple){for(var c in this.datatypes){var f=new Array();f=f.concat(a.datatypes);if(a.node.post_job_actions){for(var d in a.node.post_job_actions){var g=a.node.post_job_actions[d];if(g.action_type=="ChangeDatatypeAction"&&(g.output_name==""||g.output_name==a.name)&&g.action_arguments){f.push(g.action_arguments.newtype)}}}for(var b in f){if(f[b]=="input"||issubtype(f[b],this.datatypes[c])){return true}}}}return false}});function Connector(b,a){this.canvas=null;this.dragging=false;this.inner_color="#FFFFFF";this.outer_color="#D8B365";if(b&&a){this.connect(b,a)}}$.extend(Connector.prototype,{connect:function(b,a){this.handle1=b;if(this.handle1){this.handle1.connect(this)}this.handle2=a;if(this.handle2){this.handle2.connect(this)}},destroy:function(){if(this.handle1){this.handle1.disconnect(this)}if(this.handle2){this.handle2.disconnect(this)}$(this.canvas).remove()},redraw:function(){var d=$("#canvas-container");if(!this.canvas){this.canvas=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(this.canvas)}d.append($(this.canvas));if(this.dragging){this.canvas.style.zIndex="300"}}var n=function(c){return $(c).offset().left-d.offset().left};var i=function(c){return $(c).offset().top-d.offset().top};if(!this.handle1||!this.handle2){return}var h=n(this.handle1.element)+5;var g=i(this.handle1.element)+5;var p=n(this.handle2.element)+5;var m=i(this.handle2.element)+5;var f=100;var k=Math.min(h,p);var a=Math.max(h,p);var j=Math.min(g,m);var t=Math.max(g,m);var b=Math.min(Math.max(Math.abs(t-j)/2,100),300);var o=k-f;var s=j-f;var q=a-k+2*f;var l=t-j+2*f;this.canvas.style.left=o+"px";this.canvas.style.top=s+"px";this.canvas.setAttribute("width",q);this.canvas.setAttribute("height",l);h-=o;g-=s;p-=o;m-=s;var r=this.canvas.getContext("2d");r.lineCap="round";r.strokeStyle=this.outer_color;r.lineWidth=7;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke();r.strokeStyle=this.inner_color;r.lineWidth=5;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke()}});function Node(a){this.element=a;this.input_terminals={};this.output_terminals={};this.tool_errors={}}$.extend(Node.prototype,{enable_input_terminal:function(f,b,c,a){var d=this;$(f).each(function(){var g=this.terminal=new InputTerminal(this,c,a);g.node=d;g.name=b;$(this).bind("dropinit",function(h,i){return $(i.drag).hasClass("output-terminal")&&g.can_accept(i.drag.terminal)}).bind("dropstart",function(h,i){if(i.proxy.terminal){i.proxy.terminal.connectors[0].inner_color="#BBFFBB"}}).bind("dropend",function(h,i){if(i.proxy.terminal){i.proxy.terminal.connectors[0].inner_color="#FFFFFF"}}).bind("drop",function(h,i){(new Connector(i.drag.terminal,g)).redraw()}).bind("hover",function(){if(g.connectors.length>0){var h=$("<div class='callout'></div>").css({display:"none"}).appendTo("body").append($("<div class='button'></div>").append($("<div/>").addClass("fa-icon-button fa fa-times").click(function(){$.each(g.connectors,function(j,i){if(i){i.destroy()}});h.remove()}))).bind("mouseleave",function(){$(this).remove()});h.css({top:$(this).offset().top-2,left:$(this).offset().left-h.width(),"padding-right":$(this).width()}).show()}});d.input_terminals[b]=g})},enable_output_terminal:function(d,a,b){var c=this;$(d).each(function(){var g=this;var f=this.terminal=new OutputTerminal(this,b);f.node=c;f.name=a;$(this).bind("dragstart",function(j,k){$(k.available).addClass("input-terminal-active");workflow.check_changes_in_active_form();var i=$('<div class="drag-terminal" style="position: absolute;"></div>').appendTo("#canvas-container").get(0);i.terminal=new OutputTerminal(i);var l=new Connector();l.dragging=true;l.connect(this.terminal,i.terminal);return i}).bind("drag",function(i,j){var h=function(){var l=$(j.proxy).offsetParent().offset(),k=j.offsetX-l.left,m=j.offsetY-l.top;$(j.proxy).css({left:k,top:m});j.proxy.terminal.redraw();canvas_manager.update_viewport_overlay()};h();$("#canvas-container").get(0).scroll_panel.test(i,h)}).bind("dragend",function(h,i){i.proxy.terminal.connectors[0].destroy();$(i.proxy).remove();$(i.available).removeClass("input-terminal-active");$("#canvas-container").get(0).scroll_panel.stop()});c.output_terminals[a]=f})},redraw:function(){$.each(this.input_terminals,function(a,b){b.redraw()});$.each(this.output_terminals,function(a,b){b.redraw()})},destroy:function(){$.each(this.input_terminals,function(a,b){b.destroy()});$.each(this.output_terminals,function(a,b){b.destroy()});workflow.remove_node(this);$(this.element).remove()},make_active:function(){$(this.element).addClass("toolForm-active")},make_inactive:function(){var a=this.element.get(0);(function(b){b.removeChild(a);b.appendChild(a)})(a.parentNode);$(a).removeClass("toolForm-active")},init_field_data:function(h){var g=this.element;if(h.type){this.type=h.type}this.name=h.name;this.form_html=h.form_html;this.tool_state=h.tool_state;this.tool_errors=h.tool_errors;this.tooltip=h.tooltip?h.tooltip:"";this.annotation=h.annotation;this.post_job_actions=h.post_job_actions?h.post_job_actions:{};this.workflow_outputs=h.workflow_outputs?h.workflow_outputs:[];if(this.tool_errors){g.addClass("tool-node-error")}else{g.removeClass("tool-node-error")}var d=this;var c=Math.max(150,g.width());var a=g.find(".toolFormBody");a.find("div").remove();var i=$("<div class='inputs'></div>").appendTo(a);$.each(h.data_inputs,function(k,f){var j=$("<div class='terminal input-terminal'></div>");d.enable_input_terminal(j,f.name,f.extensions,f.multiple);var b=$("<div class='form-row dataRow input-data-row' name='"+f.name+"'>"+f.label+"</div>");b.css({position:"absolute",left:-1000,top:-1000,display:"none"});$("body").append(b);c=Math.max(c,b.outerWidth());b.css({position:"",left:"",top:"",display:""});b.remove();i.append(b.prepend(j))});if((h.data_inputs.length>0)&&(h.data_outputs.length>0)){a.append($("<div class='rule'></div>"))}$.each(h.data_outputs,function(k,b){var j=$("<div class='terminal output-terminal'></div>");d.enable_output_terminal(j,b.name,b.extensions);var f=b.name;if(b.extensions.indexOf("input")<0){f=f+" ("+b.extensions.join(", ")+")"}var m=$("<div class='form-row dataRow'>"+f+"</div>");if(d.type=="tool"){var l=$("<div class='callout "+f+"'></div>").css({display:"none"}).append($("<div class='buttons'></div>").append($("<img/>").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png").click(function(){if($.inArray(b.name,d.workflow_outputs)!=-1){d.workflow_outputs.splice($.inArray(b.name,d.workflow_outputs),1);l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{d.workflow_outputs.push(b.name);l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}workflow.has_changes=true;canvas_manager.draw_overview()}))).tooltip({delay:500,title:"Mark dataset as a workflow output. All unmarked datasets will be hidden."});l.css({top:"50%",margin:"-8px 0px 0px 0px",right:8});l.show();m.append(l);if($.inArray(b.name,d.workflow_outputs)===-1){l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}m.hover(function(){l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-yellow.png")},function(){if($.inArray(b.name,d.workflow_outputs)===-1){l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small-outline.png")}else{l.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png")}})}m.css({position:"absolute",left:-1000,top:-1000,display:"none"});$("body").append(m);c=Math.max(c,m.outerWidth()+17);m.css({position:"",left:"",top:"",display:""});m.detach();a.append(m.append(j))});g.css("width",Math.min(250,Math.max(g.width(),c)));workflow.node_changed(this)},update_field_data:function(f){var c=$(this.element),d=this;this.tool_state=f.tool_state;this.form_html=f.form_html;this.tool_errors=f.tool_errors;this.annotation=f.annotation;var g=$.parseJSON(f.post_job_actions);this.post_job_actions=g?g:{};if(this.tool_errors){c.addClass("tool-node-error")}else{c.removeClass("tool-node-error")}var h=c.find("div.inputs");var b=$("<div class='inputs'></div>");var a=h.find("div.input-data-row");$.each(f.data_inputs,function(l,j){var k=$("<div class='terminal input-terminal'></div>");d.enable_input_terminal(k,j.name,j.extensions,j.multiple);h.find("div[name='"+j.name+"']").each(function(){$(this).find(".input-terminal").each(function(){var i=this.terminal.connectors[0];if(i){k[0].terminal.connectors[0]=i;i.handle2=k[0].terminal}});$(this).remove()});b.append($("<div class='form-row dataRow input-data-row' name='"+j.name+"'>"+j.label+"</div>").prepend(k))});h.replaceWith(b);h.find("div.input-data-row > .terminal").each(function(){this.terminal.destroy()});this.changed();this.redraw()},error:function(d){var a=$(this.element).find(".toolFormBody");a.find("div").remove();var c="<div style='color: red; text-style: italic;'>"+d+"</div>";this.form_html=c;a.html(c);workflow.node_changed(this)},changed:function(){workflow.node_changed(this)}});function Workflow(a){this.canvas_container=a;this.id_counter=0;this.nodes={};this.name=null;this.has_changes=false;this.active_form_has_changes=false}$.extend(Workflow.prototype,{add_node:function(a){a.id=this.id_counter;a.element.attr("id","wf-node-step-"+a.id);this.id_counter++;this.nodes[a.id]=a;this.has_changes=true;a.workflow=this},remove_node:function(a){if(this.active_node==a){this.clear_active_node()}delete this.nodes[a.id];this.has_changes=true},remove_all:function(){wf=this;$.each(this.nodes,function(b,a){a.destroy();wf.remove_node(a)})},rectify_workflow_outputs:function(){var b=false;var a=false;$.each(this.nodes,function(c,d){if(d.workflow_outputs&&d.workflow_outputs.length>0){b=true}$.each(d.post_job_actions,function(g,f){if(f.action_type==="HideDatasetAction"){a=true}})});if(b!==false||a!==false){$.each(this.nodes,function(c,g){if(g.type==="tool"){var f=false;if(g.post_job_actions==null){g.post_job_actions={};f=true}var d=[];$.each(g.post_job_actions,function(i,h){if(h.action_type=="HideDatasetAction"){d.push(i)}});if(d.length>0){$.each(d,function(h,j){f=true;delete g.post_job_actions[j]})}if(b){$.each(g.output_terminals,function(i,j){var h=true;$.each(g.workflow_outputs,function(l,m){if(j.name===m){h=false}});if(h===true){f=true;var k={action_type:"HideDatasetAction",output_name:j.name,action_arguments:{}};g.post_job_actions["HideDatasetAction"+j.name]=null;g.post_job_actions["HideDatasetAction"+j.name]=k}})}if(workflow.active_node==g&&f===true){workflow.reload_active_node()}}})}},to_simple:function(){var a={};$.each(this.nodes,function(c,f){var g={};$.each(f.input_terminals,function(i,j){g[j.name]=null;var h=[];$.each(j.connectors,function(k,l){h[k]={id:l.handle1.node.id,output_name:l.handle1.name};g[j.name]=h})});var b={};if(f.post_job_actions){$.each(f.post_job_actions,function(j,h){var k={action_type:h.action_type,output_name:h.output_name,action_arguments:h.action_arguments};b[h.action_type+h.output_name]=null;b[h.action_type+h.output_name]=k})}if(!f.workflow_outputs){f.workflow_outputs=[]}var d={id:f.id,type:f.type,tool_id:f.tool_id,tool_state:f.tool_state,tool_errors:f.tool_errors,input_connections:g,position:$(f.element).position(),annotation:f.annotation,post_job_actions:f.post_job_actions,workflow_outputs:f.workflow_outputs};a[f.id]=d});return{steps:a}},from_simple:function(b){wf=this;var c=0;wf.name=b.name;var a=false;$.each(b.steps,function(g,f){var d=prebuild_node("tool",f.name,f.tool_id);d.init_field_data(f);if(f.position){d.element.css({top:f.position.top,left:f.position.left})}d.id=f.id;wf.nodes[d.id]=d;c=Math.max(c,parseInt(g));if(!a&&d.type==="tool"){if(d.workflow_outputs.length>0){a=true}else{$.each(d.post_job_actions,function(i,h){if(h.action_type==="HideDatasetAction"){a=true}})}}});wf.id_counter=c+1;$.each(b.steps,function(g,f){var d=wf.nodes[g];$.each(f.input_connections,function(i,h){if(h){if($.isArray(h)){$.each(h,function(m,k){var n=wf.nodes[k.id];var o=new Connector();o.connect(n.output_terminals[k.output_name],d.input_terminals[i]);o.redraw()})}else{var j=wf.nodes[h.id];var l=new Connector();l.connect(j.output_terminals[h.output_name],d.input_terminals[i]);l.redraw()}}});if(a&&d.type==="tool"){$.each(d.output_terminals,function(h,i){if(d.post_job_actions["HideDatasetAction"+i.name]===undefined){d.workflow_outputs.push(i.name);callout=$(d.element).find(".callout."+i.name);callout.find("img").attr("src",galaxy_config.root+"static/images/fugue/asterisk-small.png");workflow.has_changes=true}})}})},check_changes_in_active_form:function(){if(this.active_form_has_changes){this.has_changes=true;$("#right-content").find("form").submit();this.active_form_has_changes=false}},reload_active_node:function(){if(this.active_node){var a=this.active_node;this.clear_active_node();this.activate_node(a)}},clear_active_node:function(){if(this.active_node){this.active_node.make_inactive();this.active_node=null}parent.show_form_for_tool("<div>No node selected</div>")},activate_node:function(a){if(this.active_node!=a){this.check_changes_in_active_form();this.clear_active_node();parent.show_form_for_tool(a.form_html+a.tooltip,a);a.make_active();this.active_node=a}},node_changed:function(a){this.has_changes=true;if(this.active_node==a){this.check_changes_in_active_form();parent.show_form_for_tool(a.form_html+a.tooltip,a)}},layout:function(){this.check_changes_in_active_form();this.has_changes=true;var i={};var b={};$.each(this.nodes,function(l,k){if(i[l]===undefined){i[l]=0}if(b[l]===undefined){b[l]=[]}});$.each(this.nodes,function(l,k){$.each(k.input_terminals,function(m,n){$.each(n.connectors,function(p,q){var o=q.handle1.node;i[k.id]+=1;b[o.id].push(k.id)})})});node_ids_by_level=[];while(true){level_parents=[];for(var a in i){if(i[a]==0){level_parents.push(a)}}if(level_parents.length==0){break}node_ids_by_level.push(level_parents);for(var f in level_parents){var j=level_parents[f];delete i[j];for(var g in b[j]){i[b[j][g]]-=1}}}if(i.length){return}var d=this.nodes;var h=80;v_pad=30;var c=h;$.each(node_ids_by_level,function(k,l){l.sort(function(p,o){return $(d[p].element).position().top-$(d[o].element).position().top});var m=0;var n=v_pad;$.each(l,function(o,r){var q=d[r];var p=$(q.element);$(p).css({top:n,left:c});m=Math.max(m,$(p).width());n+=$(p).height()+v_pad});c+=m+h});$.each(d,function(k,l){l.redraw()})},bounds_for_all_nodes:function(){var d=Infinity,b=-Infinity,c=Infinity,a=-Infinity,f;$.each(this.nodes,function(h,g){e=$(g.element);f=e.position();d=Math.min(d,f.left);b=Math.max(b,f.left+e.width());c=Math.min(c,f.top);a=Math.max(a,f.top+e.width())});return{xmin:d,xmax:b,ymin:c,ymax:a}},fit_canvas_to_nodes:function(){var a=this.bounds_for_all_nodes();var f=this.canvas_container.position();var i=this.canvas_container.parent();var d=fix_delta(a.xmin,100);var h=fix_delta(a.ymin,100);d=Math.max(d,f.left);h=Math.max(h,f.top);var c=f.left-d;var g=f.top-h;var b=round_up(a.xmax+100,100)+d;var j=round_up(a.ymax+100,100)+h;b=Math.max(b,-c+i.width());j=Math.max(j,-g+i.height());this.canvas_container.css({left:c,top:g,width:b,height:j});this.canvas_container.children().each(function(){var k=$(this).position();$(this).css("left",k.left+d);$(this).css("top",k.top+h)})}});function fix_delta(a,b){if(a<b||a>3*b){new_pos=(Math.ceil(((a%b))/b)+1)*b;return(-(a-new_pos))}return 0}function round_up(a,b){return Math.ceil(a/b)*b}function prebuild_node(l,j,r){var i=$("<div class='toolForm toolFormInCanvas'></div>");var g=new Node(i);g.type=l;if(l=="tool"){g.tool_id=r}var n=$("<div class='toolFormTitle unselectable'>"+j+"</div>");i.append(n);i.css("left",$(window).scrollLeft()+20);i.css("top",$(window).scrollTop()+20);var m=$("<div class='toolFormBody'></div>");var h="<div><img height='16' align='middle' src='"+galaxy_config.root+"static/images/loading_small_white_bg.gif'/> loading tool info...</div>";m.append(h);g.form_html=h;i.append(m);var k=$("<div class='buttons' style='float: right;'></div>");k.append($("<div>").addClass("fa-icon-button fa fa-times").click(function(b){g.destroy()}));i.appendTo("#canvas-container");var d=$("#canvas-container").position();var c=$("#canvas-container").parent();var a=i.width();var q=i.height();i.css({left:(-d.left)+(c.width()/2)-(a/2),top:(-d.top)+(c.height()/2)-(q/2)});k.prependTo(n);a+=(k.width()+10);i.css("width",a);$(i).bind("dragstart",function(){workflow.activate_node(g)}).bind("dragend",function(){workflow.node_changed(this);workflow.fit_canvas_to_nodes();canvas_manager.draw_overview()}).bind("dragclickonly",function(){workflow.activate_node(g)}).bind("drag",function(o,p){var f=$(this).offsetParent().offset(),b=p.offsetX-f.left,s=p.offsetY-f.top;$(this).css({left:b,top:s});$(this).find(".terminal").each(function(){this.terminal.redraw()})});return g}var ext_to_type=null;var type_to_type=null;function issubtype(b,a){b=ext_to_type[b];a=ext_to_type[a];return(type_to_type[b])&&(a in type_to_type[b])}function populate_datatype_info(a){ext_to_type=a.ext_to_class_name;type_to_type=a.class_to_classes}function ScrollPanel(a){this.panel=a}$.extend(ScrollPanel.prototype,{test:function(v,d){clearTimeout(this.timeout);var k=v.pageX,j=v.pageY,l=$(this.panel),c=l.position(),b=l.width(),i=l.height(),w=l.parent(),s=w.width(),a=w.height(),r=w.offset(),p=r.left,m=r.top,A=p+w.width(),u=m+w.height(),B=-(b-(s/2)),z=-(i-(a/2)),g=(s/2),f=(a/2),h=false,q=5,o=23;if(k-q<p){if(c.left<g){var n=Math.min(o,g-c.left);l.css("left",c.left+n);h=true}}else{if(k+q>A){if(c.left>B){var n=Math.min(o,c.left-B);l.css("left",c.left-n);h=true}}else{if(j-q<m){if(c.top<f){var n=Math.min(o,f-c.top);l.css("top",c.top+n);h=true}}else{if(j+q>u){if(c.top>z){var n=Math.min(o,c.top-B);l.css("top",(c.top-n)+"px");h=true}}}}}if(h){d();var l=this;this.timeout=setTimeout(function(){l.test(v,d)},50)}},stop:function(b,a){clearTimeout(this.timeout)}});function CanvasManager(b,a){this.cv=b;this.cc=this.cv.find("#canvas-container");this.oc=a.find("#overview-canvas");this.ov=a.find("#overview-viewport");this.init_drag()}$.extend(CanvasManager.prototype,{init_drag:function(){var b=this;var a=function(f,g){f=Math.min(f,b.cv.width()/2);f=Math.max(f,-b.cc.width()+b.cv.width()/2);g=Math.min(g,b.cv.height()/2);g=Math.max(g,-b.cc.height()+b.cv.height()/2);b.cc.css({left:f,top:g});b.update_viewport_overlay()};this.cc.each(function(){this.scroll_panel=new ScrollPanel(this)});var d,c;this.cv.bind("dragstart",function(){var g=$(this).offset();var f=b.cc.position();c=f.top-g.top;d=f.left-g.left}).bind("drag",function(f,g){a(g.offsetX+d,g.offsetY+c)}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});this.ov.bind("drag",function(k,l){var h=b.cc.width(),n=b.cc.height(),m=b.oc.width(),j=b.oc.height(),f=$(this).offsetParent().offset(),i=l.offsetX-f.left,g=l.offsetY-f.top;a(-(i/m*h),-(g/j*n))}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});$("#overview-border").bind("drag",function(g,i){var j=$(this).offsetParent();var h=j.offset();var f=Math.max(j.width()-(i.offsetX-h.left),j.height()-(i.offsetY-h.top));$(this).css({width:f,height:f});b.draw_overview()});$("#overview-border div").bind("drag",function(){})},update_viewport_overlay:function(){var b=this.cc,f=this.cv,a=this.oc,c=this.ov,d=b.width(),j=b.height(),i=a.width(),g=a.height(),h=b.position();c.css({left:-(h.left/d*i),top:-(h.top/j*g),width:(f.width()/d*i)-2,height:(f.height()/j*g)-2})},draw_overview:function(){var j=$("#overview-canvas"),m=j.parent().parent().width(),i=j.get(0).getContext("2d"),d=$("#canvas-container").width(),l=$("#canvas-container").height();var g,a,k,f;var h=this.cv.width();var b=this.cv.height();if(d<h&&l<b){k=d/h*m;f=(m-k)/2;g=l/b*m;a=(m-g)/2}else{if(d<l){a=0;g=m;k=Math.ceil(g*d/l);f=(m-k)/2}else{k=m;f=0;g=Math.ceil(k*l/d);a=(m-g)/2}}j.parent().css({left:f,top:a,width:k,height:g});j.attr("width",k);j.attr("height",g);$.each(workflow.nodes,function(t,q){i.fillStyle="#D2C099";i.strokeStyle="#D8B365";i.lineWidth=1;var s=$(q.element),n=s.position(),c=n.left/d*k,r=n.top/l*g,o=s.width()/d*k,p=s.height()/l*g;if(q.tool_errors){i.fillStyle="#FFCCCC";i.strokeStyle="#AA6666"}else{if(q.workflow_outputs!=undefined&&q.workflow_outputs.length>0){i.fillStyle="#E8A92D";i.strokeStyle="#E8A92D"}}i.fillRect(c,r,o,p);i.strokeRect(c,r,o,p)});this.update_viewport_overlay()}});
\ No newline at end of file
diff -r a3e2c3464298ebea3fd2ab93a43aac479ba9665a -r 9fa754a203b7312d58211b5e1e7140bf36aec76a static/scripts/packed/mvc/base-mvc.js
--- a/static/scripts/packed/mvc/base-mvc.js
+++ b/static/scripts/packed/mvc/base-mvc.js
@@ -1,1 +1,1 @@
-var BaseModel=Backbone.Model.extend({defaults:{name:null,hidden:false},show:function(){this.set("hidden",false)},hide:function(){this.set("hidden",true)},is_visible:function(){return !this.attributes.hidden}});var BaseView=Backbone.View.extend({initialize:function(){this.model.on("change:hidden",this.update_visible,this);this.update_visible()},update_visible:function(){if(this.model.attributes.hidden){this.$el.hide()}else{this.$el.show()}}});var LoggableMixin={logger:null,log:function(){if(this.logger){var a=this.logger.log;if(typeof this.logger.log==="object"){a=Function.prototype.bind.call(this.logger.log,this.logger)}return a.apply(this.logger,arguments)}return undefined}};var SessionStorageModel=Backbone.Model.extend({initialize:function(b){b.id=(!_.isString(b.id))?(_.uniqueId()):(b.id);this.id=b.id;var a=(!this.isNew())?(this._read(this)):({});this.clear({silent:true});this.save(_.extend({},this.defaults,a,b),{silent:true});this.on("change",function(){this.save()})},sync:function(d,b,a){if(!a.silent){b.trigger("request",b,{},a)}var c;switch(d){case"create":c=this._create(b);break;case"read":c=this._read(b);break;case"update":c=this._update(b);break;case"delete":c=this._delete(b);break}if(c!==undefined||c!==null){if(a.success){a.success()}}else{if(a.error){a.error()}}return c},_create:function(a){var b=a.toJSON(),c=sessionStorage.setItem(a.id,JSON.stringify(b));return(c===null)?(c):(b)},_read:function(a){return JSON.parse(sessionStorage.getItem(a.id))},_update:function(a){return a._create(a)},_delete:function(a){return sessionStorage.removeItem(a.id)},isNew:function(){return !sessionStorage.hasOwnProperty(this.id)},_log:function(){return JSON.stringify(this.toJSON(),null," ")},toString:function(){return"SessionStorageModel("+this.id+")"}});(function(){SessionStorageModel.prototype=_.omit(SessionStorageModel.prototype,"url","urlRoot")}());var HiddenUntilActivatedViewMixin={hiddenUntilActivated:function(a,c){c=c||{};this.HUAVOptions={$elementShown:this.$el,showFn:jQuery.prototype.toggle,showSpeed:"fast"};_.extend(this.HUAVOptions,c||{});this.HUAVOptions.hasBeenShown=this.HUAVOptions.$elementShown.is(":visible");this.hidden=this.isHidden();if(a){var b=this;a.on("click",function(d){b.toggle(b.HUAVOptions.showSpeed)})}},isHidden:function(){return(this.HUAVOptions.$elementShown.is(":hidden"))},toggle:function(){if(this.isHidden()){if(!this.HUAVOptions.hasBeenShown){if(_.isFunction(this.HUAVOptions.onshowFirstTime)){this.HUAVOptions.hasBeenShown=true;this.HUAVOptions.onshowFirstTime.call(this)}}if(_.isFunction(this.HUAVOptions.onshow)){this.HUAVOptions.onshow.call(this)}this.hidden=false}else{if(_.isFunction(this.HUAVOptions.onhide)){this.HUAVOptions.onhide.call(this)}this.hidden=true}this.trigger("hiddenUntilActivated:"+((this.isHidden())?("shown"):("hidden")),this);return this.HUAVOptions.showFn.apply(this.HUAVOptions.$elementShown,arguments)}};
\ No newline at end of file
+var BaseView=Backbone.View.extend({initialize:function(){this.model.on("change:hidden",this.update_visible,this);this.update_visible()},update_visible:function(){if(this.model.attributes.hidden){this.$el.hide()}else{this.$el.show()}}});var LoggableMixin={logger:null,log:function(){if(this.logger){var a=this.logger.log;if(typeof this.logger.log==="object"){a=Function.prototype.bind.call(this.logger.log,this.logger)}return a.apply(this.logger,arguments)}return undefined}};var SessionStorageModel=Backbone.Model.extend({initialize:function(b){b.id=(!_.isString(b.id))?(_.uniqueId()):(b.id);this.id=b.id;var a=(!this.isNew())?(this._read(this)):({});this.clear({silent:true});this.save(_.extend({},this.defaults,a,b),{silent:true});this.on("change",function(){this.save()})},sync:function(d,b,a){if(!a.silent){b.trigger("request",b,{},a)}var c;switch(d){case"create":c=this._create(b);break;case"read":c=this._read(b);break;case"update":c=this._update(b);break;case"delete":c=this._delete(b);break}if(c!==undefined||c!==null){if(a.success){a.success()}}else{if(a.error){a.error()}}return c},_create:function(a){var b=a.toJSON(),c=sessionStorage.setItem(a.id,JSON.stringify(b));return(c===null)?(c):(b)},_read:function(a){return JSON.parse(sessionStorage.getItem(a.id))},_update:function(a){return a._create(a)},_delete:function(a){return sessionStorage.removeItem(a.id)},isNew:function(){return !sessionStorage.hasOwnProperty(this.id)},_log:function(){return JSON.stringify(this.toJSON(),null," ")},toString:function(){return"SessionStorageModel("+this.id+")"}});(function(){SessionStorageModel.prototype=_.omit(SessionStorageModel.prototype,"url","urlRoot")}());var HiddenUntilActivatedViewMixin={hiddenUntilActivated:function(a,c){c=c||{};this.HUAVOptions={$elementShown:this.$el,showFn:jQuery.prototype.toggle,showSpeed:"fast"};_.extend(this.HUAVOptions,c||{});this.HUAVOptions.hasBeenShown=this.HUAVOptions.$elementShown.is(":visible");this.hidden=this.isHidden();if(a){var b=this;a.on("click",function(d){b.toggle(b.HUAVOptions.showSpeed)})}},isHidden:function(){return(this.HUAVOptions.$elementShown.is(":hidden"))},toggle:function(){if(this.hidden){if(!this.HUAVOptions.hasBeenShown){if(_.isFunction(this.HUAVOptions.onshowFirstTime)){this.HUAVOptions.hasBeenShown=true;this.HUAVOptions.onshowFirstTime.call(this)}}if(_.isFunction(this.HUAVOptions.onshow)){this.HUAVOptions.onshow.call(this);this.trigger("hiddenUntilActivated:shown",this)}this.hidden=false}else{if(_.isFunction(this.HUAVOptions.onhide)){this.HUAVOptions.onhide.call(this);this.trigger("hiddenUntilActivated:hidden",this)}this.hidden=true}return this.HUAVOptions.showFn.apply(this.HUAVOptions.$elementShown,arguments)}};
\ No newline at end of file
diff -r a3e2c3464298ebea3fd2ab93a43aac479ba9665a -r 9fa754a203b7312d58211b5e1e7140bf36aec76a static/scripts/packed/mvc/history/history-panel.js
--- a/static/scripts/packed/mvc/history/history-panel.js
+++ b/static/scripts/packed/mvc/history/history-panel.js
@@ -1,1 +1,1 @@
-define(["mvc/history/history-model","mvc/dataset/hda-model","mvc/dataset/hda-base","mvc/dataset/hda-edit"],function(c,f,a,i){var g=SessionStorageModel.extend({defaults:{searching:false,tagsEditorShown:false,annotationEditorShown:false},toString:function(){return"HistoryPanelPrefs("+JSON.stringify(this.toJSON())+")"}});g.storageKey=function h(){return("history-panel")};var d=SessionStorageModel.extend({defaults:{expandedHdas:{},show_deleted:false,show_hidden:false},addExpandedHda:function(j){this.save("expandedHdas",_.extend(this.get("expandedHdas"),_.object([j],[true])))},removeExpandedHda:function(j){this.save("expandedHdas",_.omit(this.get("expandedHdas"),j))},toString:function(){return"HistoryPrefs("+this.id+")"}});d.historyStorageKey=function b(j){if(!j){throw new Error("HistoryPrefs.historyStorageKey needs valid id: "+j)}return("history:"+j)};var e=Backbone.View.extend(LoggableMixin).extend({defaultHDAViewClass:i.HDAEditView,tagName:"div",className:"history-panel",fxSpeed:"fast",datasetsSelector:".datasets-list",emptyMsgSelector:".empty-history-message",msgsSelector:".message-container",initialize:function(j){j=j||{};if(j.logger){this.logger=j.logger}this.log(this+".initialize:",j);this.HDAViewClass=j.HDAViewClass||this.defaultHDAViewClass;this.linkTarget=j.linkTarget||"_blank";this.hdaViews={};this.indicator=new LoadingIndicator(this.$el);this.preferences=new g(_.extend({id:g.storageKey()},_.pick(j,_.keys(g.prototype.defaults))));this.filters=[];this.selecting=j.selecting||false;this.annotationEditorShown=j.annotationEditorShown||false;this._setUpListeners();if(this.model){this._setUpWebStorage(j.initiallyExpanded,j.show_deleted,j.show_hidden);this._setUpModelEventHandlers()}if(j.onready){j.onready.call(this)}},_setUpListeners:function(){this.on("error",function(k,n,j,m,l){this.errorHandler(k,n,j,m,l)});this.on("loading-history",function(){this.showLoadingIndicator("loading history...")});this.on("loading-done",function(){this.hideLoadingIndicator()});this.once("rendered",function(){this.trigger("rendered:initial",this);return false});this.on("switched-history current-history new-history",function(){if(_.isEmpty(this.hdaViews)){this.trigger("empty-history",this)}});if(this.logger){this.on("all",function(j){this.log(this+"",arguments)},this)}},errorHandler:function(l,o,k,n,m){var j=this._parseErrorMessage(l,o,k,n,m);if(o&&o.status===0&&o.readyState===0){}else{if(o&&o.status===502){}else{if(!this.$el.find(this.msgsSelector).is(":visible")){this.once("rendered",function(){this.displayMessage("error",j.message,j.details)})}else{this.displayMessage("error",j.message,j.details)}}}},_parseErrorMessage:function(m,q,l,p,o){var k=Galaxy.currUser,j={message:this._bePolite(p),details:{user:(k instanceof User)?(k.toJSON()):(k+""),source:(m instanceof Backbone.Model)?(m.toJSON()):(m+""),xhr:q,options:(q)?(_.omit(l,"xhr")):(l)}};_.extend(j.details,o||{});if(q&&_.isFunction(q.getAllResponseHeaders)){var n=q.getAllResponseHeaders();n=_.compact(n.split("\n"));n=_.map(n,function(r){return r.split(": ")});j.details.xhr.responseHeaders=_.object(n)}return j},_bePolite:function(j){j=j||_l("An error occurred while getting updates from the server");return j+". "+_l("Please contact a Galaxy administrator if the problem persists.")},loadCurrentHistory:function(k){var j=this;return this.loadHistoryWithHDADetails("current",k).then(function(m,l){j.trigger("current-history",j)})},switchToHistory:function(m,l){var j=this,k=function(){return jQuery.post(galaxy_config.root+"api/histories/"+m+"/set_as_current")};return this.loadHistoryWithHDADetails(m,l,k).then(function(o,n){j.trigger("switched-history",j)})},createNewHistory:function(l){if(!Galaxy||!Galaxy.currUser||Galaxy.currUser.isAnonymous()){this.displayMessage("error",_l("You must be logged in to create histories"));return $.when()}var j=this,k=function(){return jQuery.post(galaxy_config.root+"api/histories",{current:true})};return this.loadHistory(undefined,l,k).then(function(n,m){j.trigger("new-history",j)})},loadHistoryWithHDADetails:function(m,l,k,o){var j=this,n=function(p){return j.getExpandedHdaIds(p.id)};return this.loadHistory(m,l,k,o,n)},loadHistory:function(m,l,k,p,n){this.trigger("loading-history",this);l=l||{};var j=this;var o=c.History.getHistoryData(m,{historyFn:k,hdaFn:p,hdaDetailIds:l.initiallyExpanded||n});return this._loadHistoryFromXHR(o,l).fail(function(s,q,r){j.trigger("error",j,s,l,_l("An error was encountered while "+q),{historyId:m,history:r||{}})}).always(function(){j.trigger("loading-done",j)})},_loadHistoryFromXHR:function(l,k){var j=this;l.then(function(m,n){j.setModel(m,n,k)});l.fail(function(n,m){j.render()});return l},setModel:function(l,j,k){k=k||{};if(this.model){this.model.clearUpdateTimeout();this.stopListening(this.model);this.stopListening(this.model.hdas)}this.hdaViews={};if(Galaxy&&Galaxy.currUser){l.user=Galaxy.currUser.toJSON()}this.model=new c.History(l,j,k);this._setUpWebStorage(k.initiallyExpanded,k.show_deleted,k.show_hidden);this._setUpModelEventHandlers();this.trigger("new-model",this);this.render();return this},_setUpWebStorage:function(k,j,l){this.storage=new d({id:d.historyStorageKey(this.model.get("id"))});if(_.isObject(k)){this.storage.set("exandedHdas",k)}if(_.isBoolean(j)){this.storage.set("show_deleted",j)}if(_.isBoolean(l)){this.storage.set("show_hidden",l)}this.trigger("new-storage",this.storage,this);this.log(this+" (init'd) storage:",this.storage.get())},clearWebStorage:function(){for(var j in sessionStorage){if(j.indexOf("history:")===0){sessionStorage.removeItem(j)}}},getStoredOptions:function(k){if(!k||k==="current"){return(this.storage)?(this.storage.get()):({})}var j=sessionStorage.getItem(d.historyStorageKey(k));return(j===null)?({}):(JSON.parse(j))},getExpandedHdaIds:function(j){var k=this.getStoredOptions(j).expandedHdas;return((_.isEmpty(k))?([]):(_.keys(k)))},_setUpModelEventHandlers:function(){this.model.on("error error:hdas",function(k,m,j,l){this.errorHandler(k,m,j,l)},this);this.model.on("change:nice_size",this.updateHistoryDiskSize,this);if(Galaxy&&Galaxy.quotaMeter){this.listenTo(this.model,"change:nice_size",function(){Galaxy.quotaMeter.update()})}this.model.hdas.on("add",this.addHdaView,this);this.model.hdas.on("change:deleted",this.handleHdaDeletionChange,this);this.model.hdas.on("change:visible",this.handleHdaVisibleChange,this);this.model.hdas.on("change:purged",function(j){this.model.fetch()},this);this.model.hdas.on("state:ready",function(k,l,j){if((!k.get("visible"))&&(!this.storage.get("show_hidden"))){this.removeHdaView(this.hdaViews[k.id])}},this)},render:function(l,m){l=(l===undefined)?(this.fxSpeed):(l);var j=this,k;if(this.model){k=this.renderModel()}else{k=this.renderWithoutModel()}$(j).queue("fx",[function(n){if(l&&j.$el.is(":visible")){j.$el.fadeOut(l,n)}else{n()}},function(n){j.$el.empty();if(k){j.$el.append(k.children());j.renderBasedOnPrefs()}n()},function(n){if(l&&!j.$el.is(":visible")){j.$el.fadeIn(l,n)}else{n()}},function(n){if(m){m.call(this)}j.trigger("rendered",this);n()}]);return this},renderWithoutModel:function(){var j=$("<div/>"),k=$("<div/>").addClass("message-container").css({"margin-left":"4px","margin-right":"4px"});return j.append(k)},renderModel:function(){var j=$("<div/>");if(!Galaxy||!Galaxy.currUser||Galaxy.currUser.isAnonymous()){j.append(e.templates.anonHistoryPanel(this.model.toJSON()))}else{j.append(e.templates.historyPanel(this.model.toJSON()));if(Galaxy.currUser.id&&Galaxy.currUser.id===this.model.get("user_id")){this._renderTags(j);this._renderAnnotation(j)}}j.find(".history-secondary-actions").prepend(this._renderSearchButton());this._setUpBehaviours(j);this.renderHdas(j);return j},renderBasedOnPrefs:function(){if(this.preferences.get("searching")){this.showSearchControls(0)}},_renderTags:function(j){var k=this;this.tagsEditor=new TagsEditor({model:this.model,el:j.find(".history-controls .tags-display"),onshowFirstTime:function(){this.render()},onshow:function(){k.preferences.set("tagsEditorShown",true);k.toggleHDATagEditors(true,k.fxSpeed)},onhide:function(){k.preferences.set("tagsEditorShown",false);k.toggleHDATagEditors(false,k.fxSpeed)},$activator:faIconButton({title:_l("Edit history tags"),classes:"history-tag-btn",faIcon:"fa-tags"}).appendTo(j.find(".history-secondary-actions"))});if(this.preferences.get("tagsEditorShown")){this.tagsEditor.toggle(true)}},_renderAnnotation:function(j){var k=this;this.annotationEditor=new AnnotationEditor({model:this.model,el:j.find(".history-controls .annotation-display"),onshowFirstTime:function(){this.render()},onshow:function(){k.preferences.set("annotationEditorShown",true);k.toggleHDAAnnotationEditors(true,k.fxSpeed)},onhide:function(){k.preferences.set("annotationEditorShown",false);k.toggleHDAAnnotationEditors(false,k.fxSpeed)},$activator:faIconButton({title:_l("Edit history Annotation"),classes:"history-annotate-btn",faIcon:"fa-comment"}).appendTo(j.find(".history-secondary-actions"))});if(this.preferences.get("annotationEditorShown")){this.annotationEditor.toggle(true)}},_renderSearchButton:function(j){return faIconButton({title:_l("Search datasets"),classes:"history-search-btn",faIcon:"fa-search"})},_renderSelectButton:function(j){return faIconButton({title:_l("Operations on multiple datasets"),classes:"history-select-btn",faIcon:"fa-check-square-o"})},_setUpBehaviours:function(j){j=j||this.$el;j.find("[title]").tooltip({placement:"bottom"});if((!this.model)||(!Galaxy.currUser||Galaxy.currUser.isAnonymous())||(Galaxy.currUser.id!==this.model.get("user_id"))){return}var k=this;j.find(".history-name").attr("title",_l("Click to rename history")).tooltip({placement:"bottom"}).make_text_editable({on_finish:function(l){j.find(".history-name").text(l);k.model.save({name:l}).fail(function(){j.find(".history-name").text(k.model.previous("name"))})}});this._setUpDatasetActionsPopup(j)},_setUpDatasetActionsPopup:function(j){var k=this;(new PopupMenu(j.find(".history-dataset-action-popup-btn"),[{html:_l("Hide datasets"),func:function(){var l=f.HistoryDatasetAssociation.prototype.hide;k.getSelectedHdaCollection().ajaxQueue(l)}},{html:_l("Unhide datasets"),func:function(){var l=f.HistoryDatasetAssociation.prototype.unhide;k.getSelectedHdaCollection().ajaxQueue(l)}},{html:_l("Delete datasets"),func:function(){var l=f.HistoryDatasetAssociation.prototype["delete"];k.getSelectedHdaCollection().ajaxQueue(l)}},{html:_l("Undelete datasets"),func:function(){var l=f.HistoryDatasetAssociation.prototype.undelete;k.getSelectedHdaCollection().ajaxQueue(l)}},{html:_l("Permanently delete datasets"),func:function(){if(confirm(_l("This will permanently remove the data in your datasets. Are you sure?"))){var l=f.HistoryDatasetAssociation.prototype.purge;k.getSelectedHdaCollection().ajaxQueue(l)}}}]))},refreshHdas:function(k,j){if(this.model){return this.model.refresh(k,j)}return $.when()},addHdaView:function(m){this.log("add."+this,m);var k=this;if(!m.isVisible(this.storage.get("show_deleted"),this.storage.get("show_hidden"))){return}$({}).queue([function l(o){var n=k.$el.find(k.emptyMsgSelector);if(n.is(":visible")){n.fadeOut(k.fxSpeed,o)}else{o()}},function j(o){k.scrollToTop();var n=k.$el.find(k.datasetsSelector);k.createHdaView(m).$el.hide().prependTo(n).slideDown(k.fxSpeed)}])},createHdaView:function(l){var k=l.get("id"),j=this.storage.get("expandedHdas")[k],m=new this.HDAViewClass({model:l,linkTarget:this.linkTarget,expanded:j,tagsEditorShown:this.preferences.get("tagsEditorShown"),annotationEditorShown:this.preferences.get("annotationEditorShown"),selectable:this.selecting,hasUser:this.model.ownedByCurrUser(),logger:this.logger});this._setUpHdaListeners(m);this.hdaViews[k]=m;return m.render()},_setUpHdaListeners:function(k){var j=this;k.on("body-expanded",function(l){j.storage.addExpandedHda(l)});k.on("body-collapsed",function(l){j.storage.removeExpandedHda(l)});k.on("error",function(m,o,l,n){j.errorHandler(m,o,l,n)})},handleHdaDeletionChange:function(j){if(j.get("deleted")&&!this.storage.get("show_deleted")){this.removeHdaView(this.hdaViews[j.id])}},handleHdaVisibleChange:function(j){if(j.hidden()&&!this.storage.get("show_hidden")){this.removeHdaView(this.hdaViews[j.id])}},removeHdaView:function(k){if(!k){return}var j=this;k.$el.fadeOut(j.fxSpeed,function(){k.off();k.remove();delete j.hdaViews[k.model.id];if(_.isEmpty(j.hdaViews)){j.$el.find(j.emptyMsgSelector).fadeIn(j.fxSpeed,function(){j.trigger("empty-history",j)})}})},renderHdas:function(l){l=l||this.$el;this.hdaViews={};var k=this,j=l.find(this.datasetsSelector),m=this.model.hdas.getVisible(this.storage.get("show_deleted"),this.storage.get("show_hidden"),this.filters);j.empty();if(m.length){m.each(function(n){j.prepend(k.createHdaView(n).$el)});l.find(this.emptyMsgSelector).hide()}else{l.find(this.emptyMsgSelector).show()}return this.hdaViews},toggleHDATagEditors:function(){var j=arguments;_.each(this.hdaViews,function(k){if(k.tagsEditor){k.tagsEditor.toggle.apply(k.tagsEditor,j)}})},toggleHDAAnnotationEditors:function(j){var k=arguments;_.each(this.hdaViews,function(l){if(l.annotationEditor){l.annotationEditor.toggle.apply(l.annotationEditor,k)}})},events:{"click .message-container":"clearMessages","click .history-search-btn":"toggleSearchControls","click .history-select-btn":function(j){this.toggleSelectors(this.fxSpeed)},"click .history-select-all-datasets-btn":"selectAllDatasets"},updateHistoryDiskSize:function(){this.$el.find(".history-size").text(this.model.get("nice_size"))},collapseAllHdaBodies:function(){_.each(this.hdaViews,function(j){j.toggleBodyVisibility(null,false)});this.storage.set("expandedHdas",{})},toggleShowDeleted:function(){this.storage.set("show_deleted",!this.storage.get("show_deleted"));this.renderHdas();return this.storage.get("show_deleted")},toggleShowHidden:function(){this.storage.set("show_hidden",!this.storage.get("show_hidden"));this.renderHdas();return this.storage.get("show_hidden")},renderSearchControls:function(k){var l=this;function n(o){l.searchFor=o;l.filters=[function(p){return p.matchesAll(l.searchFor)}];l.trigger("search:searching",o,l);l.renderHdas()}function j(o){if(l.model.hdas.haveDetails()){n(o);return}l.$el.find(".history-search-controls").searchInput("toggle-loading");l.model.hdas.fetchAllDetails({silent:true}).always(function(){l.$el.find(".history-search-controls").searchInput("toggle-loading")}).done(function(){n(o)})}function m(){l.searchFor="";l.filters=[];l.trigger("search:clear",l);l.renderHdas()}return k.searchInput({initialVal:l.searchFor,name:"history-search",placeholder:"search datasets",classes:"history-search",onfirstsearch:j,onsearch:n,onclear:m})},showSearchControls:function(l){l=(l===undefined)?(this.fxSpeed):(l);var j=this,k=this.$el.find(".history-search-controls");if(!k.children().size()){k=this.renderSearchControls(k).hide()}k.show(l,function(){$(this).find("input").focus();j.preferences.set("searching",true)})},hideSearchControls:function(){speed=(speed===undefined)?(this.fxSpeed):(speed);var j=this;this.$el.find(".history-search-controls").hide(speed,function(){j.preferences.set("searching",false)})},toggleSearchControls:function(j){speed=(jQuery.type(j)==="number")?(j):(this.fxSpeed);if(this.$el.find(".history-search-controls").is(":visible")){this.hideSearchControls(speed)}else{this.showSearchControls(speed)}},showSelectors:function(j){this.selecting=true;this.$el.find(".history-dataset-actions").slideDown(j);_.each(this.hdaViews,function(k){k.showSelector(j)})},hideSelectors:function(j){this.selecting=false;this.$el.find(".history-dataset-actions").slideUp(j);_.each(this.hdaViews,function(k){k.hideSelector(j)})},toggleSelectors:function(j){if(!this.selecting){this.showSelectors(j)}else{this.hideSelectors(j)}},selectAllDatasets:function(k){var j=this.$el.find(".history-select-all-datasets-btn");currMode=j.data("mode");if(currMode==="select"){_.each(this.hdaViews,function(l){l.select(k)});j.data("mode","deselect");j.text(_l("De-select all"))}else{if(currMode==="deselect"){_.each(this.hdaViews,function(l){l.deselect(k)});j.data("mode","select");j.text(_l("Select all"))}}},getSelectedHdaViews:function(){return _.filter(this.hdaViews,function(j){return j.selected})},getSelectedHdaCollection:function(){return new f.HDACollection(_.map(this.getSelectedHdaViews(),function(j){return j.model}),{historyId:this.model.id})},showLoadingIndicator:function(k,j,l){j=(j!==undefined)?(j):(this.fxSpeed);if(!this.indicator){this.indicator=new LoadingIndicator(this.$el,this.$el.parent())}if(!this.$el.is(":visible")){this.indicator.show(0,l)}else{this.$el.fadeOut(j);this.indicator.show(k,j,l)}},hideLoadingIndicator:function(j,k){j=(j!==undefined)?(j):(this.fxSpeed);if(this.indicator){this.indicator.hide(j,k)}},displayMessage:function(o,p,n){var l=this;this.scrollToTop();var m=this.$el.find(this.msgsSelector),j=$("<div/>").addClass(o+"message").html(p);if(!_.isEmpty(n)){var k=$('<a href="javascript:void(0)">Details</a>').click(function(){Galaxy.modal.show(l.messageToModalOptions(o,p,n));return false});j.append(" ",k)}return m.html(j)},messageToModalOptions:function(n,p,m){var j=this,o=$("<div/>"),l={title:"Details"};function k(q){q=_.omit(q,_.functions(q));return["<table>",_.map(q,function(s,r){s=(_.isObject(s))?(k(s)):(s);return'<tr><td style="vertical-align: top; color: grey">'+r+'</td><td style="padding-left: 8px">'+s+"</td></tr>"}).join(""),"</table>"].join("")}if(_.isObject(m)){l.body=o.append(k(m))}else{l.body=o.html(m)}l.buttons={Ok:function(){Galaxy.modal.hide();j.clearMessages()}};return l},clearMessages:function(){var j=this.$el.find(this.msgsSelector);j.empty()},scrollPosition:function(){return this.$el.parent().scrollTop()},scrollTo:function(j){this.$el.parent().scrollTop(j)},scrollToTop:function(){this.$el.parent().scrollTop(0);return this},scrollIntoView:function(k,l){if(!l){this.$el.parent().parent().scrollTop(k);return this}var j=window,m=this.$el.parent().parent(),o=$(j).innerHeight(),n=(o/2)-(l/2);$(m).scrollTop(k-n);return this},scrollToId:function(k){if((!k)||(!this.hdaViews[k])){return this}var j=this.hdaViews[k].$el;this.scrollIntoView(j.offset().top,j.outerHeight());return this},scrollToHid:function(j){var k=this.model.hdas.getByHid(j);if(!k){return this}return this.scrollToId(k.id)},connectToQuotaMeter:function(j){if(!j){return this}this.listenTo(j,"quota:over",this.showQuotaMessage);this.listenTo(j,"quota:under",this.hideQuotaMessage);this.on("rendered rendered:initial",function(){if(j&&j.isOverQuota()){this.showQuotaMessage()}});return this},showQuotaMessage:function(){var j=this.$el.find(".quota-message");if(j.is(":hidden")){j.slideDown(this.fxSpeed)}},hideQuotaMessage:function(){var j=this.$el.find(".quota-message");if(!j.is(":hidden")){j.slideUp(this.fxSpeed)}},connectToOptionsMenu:function(j){if(!j){return this}this.on("new-storage",function(l,k){if(j&&l){j.findItemByHtml(_l("Include Deleted Datasets")).checked=l.get("show_deleted");j.findItemByHtml(_l("Include Hidden Datasets")).checked=l.get("show_hidden")}});return this},toString:function(){return"HistoryPanel("+((this.model)?(this.model.get("name")):(""))+")"}});e.templates={historyPanel:Handlebars.templates["template-history-historyPanel"],anonHistoryPanel:Handlebars.templates["template-history-historyPanel-anon"]};return{HistoryPanel:e}});
\ No newline at end of file
+define(["mvc/history/history-model","mvc/dataset/hda-model","mvc/dataset/hda-base","mvc/dataset/hda-edit"],function(c,f,a,i){var g=SessionStorageModel.extend({defaults:{searching:false,tagsEditorShown:false,annotationEditorShown:false},toString:function(){return"HistoryPanelPrefs("+JSON.stringify(this.toJSON())+")"}});g.storageKey=function h(){return("history-panel")};var d=SessionStorageModel.extend({defaults:{expandedHdas:{},show_deleted:false,show_hidden:false},addExpandedHda:function(j){this.save("expandedHdas",_.extend(this.get("expandedHdas"),_.object([j],[true])))},removeExpandedHda:function(j){this.save("expandedHdas",_.omit(this.get("expandedHdas"),j))},toString:function(){return"HistoryPrefs("+this.id+")"}});d.historyStorageKey=function b(j){if(!j){throw new Error("HistoryPrefs.historyStorageKey needs valid id: "+j)}return("history:"+j)};var e=Backbone.View.extend(LoggableMixin).extend({defaultHDAViewClass:i.HDAEditView,tagName:"div",className:"history-panel",fxSpeed:"fast",datasetsSelector:".datasets-list",emptyMsgSelector:".empty-history-message",msgsSelector:".message-container",initialize:function(j){j=j||{};if(j.logger){this.logger=j.logger}this.log(this+".initialize:",j);this.HDAViewClass=j.HDAViewClass||this.defaultHDAViewClass;this.linkTarget=j.linkTarget||"_blank";this.hdaViews={};this.indicator=new LoadingIndicator(this.$el);this.preferences=new g(_.extend({id:g.storageKey()},_.pick(j,_.keys(g.prototype.defaults))));this.filters=[];this.selecting=j.selecting||false;this.annotationEditorShown=j.annotationEditorShown||false;this._setUpListeners();if(this.model){this._setUpWebStorage(j.initiallyExpanded,j.show_deleted,j.show_hidden);this._setUpModelEventHandlers()}if(j.onready){j.onready.call(this)}},_setUpListeners:function(){this.on("error",function(k,n,j,m,l){this.errorHandler(k,n,j,m,l)});this.on("loading-history",function(){this.showLoadingIndicator("loading history...")});this.on("loading-done",function(){this.hideLoadingIndicator()});this.once("rendered",function(){this.trigger("rendered:initial",this);return false});this.on("switched-history current-history new-history",function(){if(_.isEmpty(this.hdaViews)){this.trigger("empty-history",this)}});if(this.logger){this.on("all",function(j){this.log(this+"",arguments)},this)}},errorHandler:function(l,o,k,n,m){var j=this._parseErrorMessage(l,o,k,n,m);if(o&&o.status===0&&o.readyState===0){}else{if(o&&o.status===502){}else{if(!this.$el.find(this.msgsSelector).is(":visible")){this.once("rendered",function(){this.displayMessage("error",j.message,j.details)})}else{this.displayMessage("error",j.message,j.details)}}}},_parseErrorMessage:function(m,q,l,p,o){var k=Galaxy.currUser,j={message:this._bePolite(p),details:{user:(k instanceof User)?(k.toJSON()):(k+""),source:(m instanceof Backbone.Model)?(m.toJSON()):(m+""),xhr:q,options:(q)?(_.omit(l,"xhr")):(l)}};_.extend(j.details,o||{});if(q&&_.isFunction(q.getAllResponseHeaders)){var n=q.getAllResponseHeaders();n=_.compact(n.split("\n"));n=_.map(n,function(r){return r.split(": ")});j.details.xhr.responseHeaders=_.object(n)}return j},_bePolite:function(j){j=j||_l("An error occurred while getting updates from the server");return j+". "+_l("Please contact a Galaxy administrator if the problem persists.")},loadCurrentHistory:function(k){var j=this;return this.loadHistoryWithHDADetails("current",k).then(function(m,l){j.trigger("current-history",j)})},switchToHistory:function(m,l){var j=this,k=function(){return jQuery.post(galaxy_config.root+"api/histories/"+m+"/set_as_current")};return this.loadHistoryWithHDADetails(m,l,k).then(function(o,n){j.trigger("switched-history",j)})},createNewHistory:function(l){if(!Galaxy||!Galaxy.currUser||Galaxy.currUser.isAnonymous()){this.displayMessage("error",_l("You must be logged in to create histories"));return $.when()}var j=this,k=function(){return jQuery.post(galaxy_config.root+"api/histories",{current:true})};return this.loadHistory(undefined,l,k).then(function(n,m){j.trigger("new-history",j)})},loadHistoryWithHDADetails:function(m,l,k,o){var j=this,n=function(p){return j.getExpandedHdaIds(p.id)};return this.loadHistory(m,l,k,o,n)},loadHistory:function(m,l,k,p,n){this.trigger("loading-history",this);l=l||{};var j=this;var o=c.History.getHistoryData(m,{historyFn:k,hdaFn:p,hdaDetailIds:l.initiallyExpanded||n});return this._loadHistoryFromXHR(o,l).fail(function(s,q,r){j.trigger("error",j,s,l,_l("An error was encountered while "+q),{historyId:m,history:r||{}})}).always(function(){j.trigger("loading-done",j)})},_loadHistoryFromXHR:function(l,k){var j=this;l.then(function(m,n){j.setModel(m,n,k)});l.fail(function(n,m){j.render()});return l},setModel:function(l,j,k){k=k||{};if(this.model){this.model.clearUpdateTimeout();this.stopListening(this.model);this.stopListening(this.model.hdas)}this.hdaViews={};if(Galaxy&&Galaxy.currUser){l.user=Galaxy.currUser.toJSON()}this.model=new c.History(l,j,k);this._setUpWebStorage(k.initiallyExpanded,k.show_deleted,k.show_hidden);this._setUpModelEventHandlers();this.trigger("new-model",this);this.render();return this},_setUpWebStorage:function(k,j,l){this.storage=new d({id:d.historyStorageKey(this.model.get("id"))});if(_.isObject(k)){this.storage.set("exandedHdas",k)}if(_.isBoolean(j)){this.storage.set("show_deleted",j)}if(_.isBoolean(l)){this.storage.set("show_hidden",l)}this.trigger("new-storage",this.storage,this);this.log(this+" (init'd) storage:",this.storage.get())},clearWebStorage:function(){for(var j in sessionStorage){if(j.indexOf("history:")===0){sessionStorage.removeItem(j)}}},getStoredOptions:function(k){if(!k||k==="current"){return(this.storage)?(this.storage.get()):({})}var j=sessionStorage.getItem(d.historyStorageKey(k));return(j===null)?({}):(JSON.parse(j))},getExpandedHdaIds:function(j){var k=this.getStoredOptions(j).expandedHdas;return((_.isEmpty(k))?([]):(_.keys(k)))},_setUpModelEventHandlers:function(){this.model.on("error error:hdas",function(k,m,j,l){this.errorHandler(k,m,j,l)},this);this.model.on("change:nice_size",this.updateHistoryDiskSize,this);if(Galaxy&&Galaxy.quotaMeter){this.listenTo(this.model,"change:nice_size",function(){Galaxy.quotaMeter.update()})}this.model.hdas.on("add",this.addHdaView,this);this.model.hdas.on("change:deleted",this.handleHdaDeletionChange,this);this.model.hdas.on("change:visible",this.handleHdaVisibleChange,this);this.model.hdas.on("change:purged",function(j){this.model.fetch()},this);this.model.hdas.on("state:ready",function(k,l,j){if((!k.get("visible"))&&(!this.storage.get("show_hidden"))){this.removeHdaView(this.hdaViews[k.id])}},this)},render:function(l,m){l=(l===undefined)?(this.fxSpeed):(l);var j=this,k;if(this.model){k=this.renderModel()}else{k=this.renderWithoutModel()}$(j).queue("fx",[function(n){if(l&&j.$el.is(":visible")){j.$el.fadeOut(l,n)}else{n()}},function(n){j.$el.empty();if(k){j.$el.append(k.children());j.renderBasedOnPrefs()}n()},function(n){if(l&&!j.$el.is(":visible")){j.$el.fadeIn(l,n)}else{n()}},function(n){if(m){m.call(this)}j.trigger("rendered",this);n()}]);return this},renderWithoutModel:function(){var j=$("<div/>"),k=$("<div/>").addClass("message-container").css({"margin-left":"4px","margin-right":"4px"});return j.append(k)},renderModel:function(){var j=$("<div/>");if(!Galaxy||!Galaxy.currUser||Galaxy.currUser.isAnonymous()){j.append(e.templates.anonHistoryPanel(this.model.toJSON()))}else{j.append(e.templates.historyPanel(this.model.toJSON()));if(Galaxy.currUser.id&&Galaxy.currUser.id===this.model.get("user_id")){this._renderTags(j);this._renderAnnotation(j)}}j.find(".history-secondary-actions").prepend(this._renderSearchButton());this._setUpBehaviours(j);this.renderHdas(j);return j},renderBasedOnPrefs:function(){if(this.preferences.get("searching")){this.showSearchControls(0)}},_renderTags:function(j){var k=this;this.tagsEditor=new TagsEditor({model:this.model,el:j.find(".history-controls .tags-display"),onshowFirstTime:function(){this.render()},onshow:function(){k.preferences.set("tagsEditorShown",true);k.toggleHDATagEditors(true,k.fxSpeed)},onhide:function(){k.preferences.set("tagsEditorShown",false);k.toggleHDATagEditors(false,k.fxSpeed)},$activator:faIconButton({title:_l("Edit history tags"),classes:"history-tag-btn",faIcon:"fa-tags"}).appendTo(j.find(".history-secondary-actions"))});if(this.preferences.get("tagsEditorShown")){this.tagsEditor.toggle(true)}},_renderAnnotation:function(j){var k=this;this.annotationEditor=new AnnotationEditor({model:this.model,el:j.find(".history-controls .annotation-display"),onshowFirstTime:function(){this.render()},onshow:function(){k.preferences.set("annotationEditorShown",true);k.toggleHDAAnnotationEditors(true,k.fxSpeed)},onhide:function(){k.preferences.set("annotationEditorShown",false);k.toggleHDAAnnotationEditors(false,k.fxSpeed)},$activator:faIconButton({title:_l("Edit history Annotation"),classes:"history-annotate-btn",faIcon:"fa-comment"}).appendTo(j.find(".history-secondary-actions"))});if(this.preferences.get("annotationEditorShown")){this.annotationEditor.toggle(true)}},_renderSearchButton:function(j){return faIconButton({title:_l("Search datasets"),classes:"history-search-btn",faIcon:"fa-search"})},_renderSelectButton:function(j){return faIconButton({title:_l("Operations on multiple datasets"),classes:"history-select-btn",faIcon:"fa-check-square-o"})},_setUpBehaviours:function(j){j=j||this.$el;j.find("[title]").tooltip({placement:"bottom"});if((!this.model)||(!Galaxy.currUser||Galaxy.currUser.isAnonymous())||(Galaxy.currUser.id!==this.model.get("user_id"))){return}var k=this;j.find(".history-name").attr("title",_l("Click to rename history")).tooltip({placement:"bottom"}).make_text_editable({on_finish:function(l){j.find(".history-name").text(l);k.model.save({name:l}).fail(function(){j.find(".history-name").text(k.model.previous("name"))})}});this._setUpDatasetActionsPopup(j)},_setUpDatasetActionsPopup:function(j){var k=this;(new PopupMenu(j.find(".history-dataset-action-popup-btn"),[{html:_l("Hide datasets"),func:function(){var l=f.HistoryDatasetAssociation.prototype.hide;k.getSelectedHdaCollection().ajaxQueue(l)}},{html:_l("Unhide datasets"),func:function(){var l=f.HistoryDatasetAssociation.prototype.unhide;k.getSelectedHdaCollection().ajaxQueue(l)}},{html:_l("Delete datasets"),func:function(){var l=f.HistoryDatasetAssociation.prototype["delete"];k.getSelectedHdaCollection().ajaxQueue(l)}},{html:_l("Undelete datasets"),func:function(){var l=f.HistoryDatasetAssociation.prototype.undelete;k.getSelectedHdaCollection().ajaxQueue(l)}},{html:_l("Permanently delete datasets"),func:function(){if(confirm(_l("This will permanently remove the data in your datasets. Are you sure?"))){var l=f.HistoryDatasetAssociation.prototype.purge;k.getSelectedHdaCollection().ajaxQueue(l)}}}]))},refreshHdas:function(k,j){if(this.model){return this.model.refresh(k,j)}return $.when()},addHdaView:function(m){this.log("add."+this,m);var k=this;if(!m.isVisible(this.storage.get("show_deleted"),this.storage.get("show_hidden"))){return}$({}).queue([function l(o){var n=k.$el.find(k.emptyMsgSelector);if(n.is(":visible")){n.fadeOut(k.fxSpeed,o)}else{o()}},function j(o){k.scrollToTop();var n=k.$el.find(k.datasetsSelector);k.createHdaView(m).$el.hide().prependTo(n).slideDown(k.fxSpeed)}])},createHdaView:function(l){var k=l.get("id"),j=this.storage.get("expandedHdas")[k],m=new this.HDAViewClass({model:l,linkTarget:this.linkTarget,expanded:j,tagsEditorShown:this.preferences.get("tagsEditorShown"),annotationEditorShown:this.preferences.get("annotationEditorShown"),selectable:this.selecting,hasUser:this.model.ownedByCurrUser(),logger:this.logger});this._setUpHdaListeners(m);this.hdaViews[k]=m;return m.render()},_setUpHdaListeners:function(k){var j=this;k.on("body-expanded",function(l){j.storage.addExpandedHda(l)});k.on("body-collapsed",function(l){j.storage.removeExpandedHda(l)});k.on("error",function(m,o,l,n){j.errorHandler(m,o,l,n)})},handleHdaDeletionChange:function(j){if(j.get("deleted")&&!this.storage.get("show_deleted")){this.removeHdaView(this.hdaViews[j.id])}},handleHdaVisibleChange:function(j){if(j.hidden()&&!this.storage.get("show_hidden")){this.removeHdaView(this.hdaViews[j.id])}},removeHdaView:function(k){if(!k){return}var j=this;k.$el.fadeOut(j.fxSpeed,function(){k.off();k.remove();delete j.hdaViews[k.model.id];if(_.isEmpty(j.hdaViews)){j.$el.find(j.emptyMsgSelector).fadeIn(j.fxSpeed,function(){j.trigger("empty-history",j)})}})},renderHdas:function(l){l=l||this.$el;this.hdaViews={};var k=this,j=l.find(this.datasetsSelector),m=this.model.hdas.getVisible(this.storage.get("show_deleted"),this.storage.get("show_hidden"),this.filters);j.empty();if(m.length){m.each(function(n){j.prepend(k.createHdaView(n).$el)});l.find(this.emptyMsgSelector).hide()}else{l.find(this.emptyMsgSelector).show()}return this.hdaViews},toggleHDATagEditors:function(j){var k=arguments;_.each(this.hdaViews,function(l){if(l.tagsEditor){l.tagsEditor.toggle.apply(l.tagsEditor,k)}})},toggleHDAAnnotationEditors:function(j){var k=arguments;_.each(this.hdaViews,function(l){if(l.annotationEditor){l.annotationEditor.toggle.apply(l.annotationEditor,k)}})},events:{"click .message-container":"clearMessages","click .history-search-btn":"toggleSearchControls","click .history-select-btn":function(j){this.toggleSelectors(this.fxSpeed)},"click .history-select-all-datasets-btn":"selectAllDatasets"},updateHistoryDiskSize:function(){this.$el.find(".history-size").text(this.model.get("nice_size"))},collapseAllHdaBodies:function(){_.each(this.hdaViews,function(j){j.toggleBodyVisibility(null,false)});this.storage.set("expandedHdas",{})},toggleShowDeleted:function(){this.storage.set("show_deleted",!this.storage.get("show_deleted"));this.renderHdas();return this.storage.get("show_deleted")},toggleShowHidden:function(){this.storage.set("show_hidden",!this.storage.get("show_hidden"));this.renderHdas();return this.storage.get("show_hidden")},renderSearchControls:function(k){var l=this;function n(o){l.searchFor=o;l.filters=[function(p){return p.matchesAll(l.searchFor)}];l.trigger("search:searching",o,l);l.renderHdas()}function j(o){if(l.model.hdas.haveDetails()){n(o);return}l.$el.find(".history-search-controls").searchInput("toggle-loading");l.model.hdas.fetchAllDetails({silent:true}).always(function(){l.$el.find(".history-search-controls").searchInput("toggle-loading")}).done(function(){n(o)})}function m(){l.searchFor="";l.filters=[];l.trigger("search:clear",l);l.renderHdas()}return k.searchInput({initialVal:l.searchFor,name:"history-search",placeholder:"search datasets",classes:"history-search",onfirstsearch:j,onsearch:n,onclear:m})},showSearchControls:function(l){l=(l===undefined)?(this.fxSpeed):(l);var j=this,k=this.$el.find(".history-search-controls");if(!k.children().size()){k=this.renderSearchControls(k).hide()}k.show(l,function(){$(this).find("input").focus();j.preferences.set("searching",true)})},hideSearchControls:function(){speed=(speed===undefined)?(this.fxSpeed):(speed);var j=this;this.$el.find(".history-search-controls").hide(speed,function(){j.preferences.set("searching",false)})},toggleSearchControls:function(j){speed=(jQuery.type(j)==="number")?(j):(this.fxSpeed);if(this.$el.find(".history-search-controls").is(":visible")){this.hideSearchControls(speed)}else{this.showSearchControls(speed)}},showSelectors:function(j){this.selecting=true;this.$el.find(".history-dataset-actions").slideDown(j);_.each(this.hdaViews,function(k){k.showSelector(j)})},hideSelectors:function(j){this.selecting=false;this.$el.find(".history-dataset-actions").slideUp(j);_.each(this.hdaViews,function(k){k.hideSelector(j)})},toggleSelectors:function(j){if(!this.selecting){this.showSelectors(j)}else{this.hideSelectors(j)}},selectAllDatasets:function(k){var j=this.$el.find(".history-select-all-datasets-btn");currMode=j.data("mode");if(currMode==="select"){_.each(this.hdaViews,function(l){l.select(k)});j.data("mode","deselect");j.text(_l("De-select all"))}else{if(currMode==="deselect"){_.each(this.hdaViews,function(l){l.deselect(k)});j.data("mode","select");j.text(_l("Select all"))}}},getSelectedHdaViews:function(){return _.filter(this.hdaViews,function(j){return j.selected})},getSelectedHdaCollection:function(){return new f.HDACollection(_.map(this.getSelectedHdaViews(),function(j){return j.model}),{historyId:this.model.id})},showLoadingIndicator:function(k,j,l){j=(j!==undefined)?(j):(this.fxSpeed);if(!this.indicator){this.indicator=new LoadingIndicator(this.$el,this.$el.parent())}if(!this.$el.is(":visible")){this.indicator.show(0,l)}else{this.$el.fadeOut(j);this.indicator.show(k,j,l)}},hideLoadingIndicator:function(j,k){j=(j!==undefined)?(j):(this.fxSpeed);if(this.indicator){this.indicator.hide(j,k)}},displayMessage:function(o,p,n){var l=this;this.scrollToTop();var m=this.$el.find(this.msgsSelector),j=$("<div/>").addClass(o+"message").html(p);if(!_.isEmpty(n)){var k=$('<a href="javascript:void(0)">Details</a>').click(function(){Galaxy.modal.show(l.messageToModalOptions(o,p,n));return false});j.append(" ",k)}return m.html(j)},messageToModalOptions:function(n,p,m){var j=this,o=$("<div/>"),l={title:"Details"};function k(q){q=_.omit(q,_.functions(q));return["<table>",_.map(q,function(s,r){s=(_.isObject(s))?(k(s)):(s);return'<tr><td style="vertical-align: top; color: grey">'+r+'</td><td style="padding-left: 8px">'+s+"</td></tr>"}).join(""),"</table>"].join("")}if(_.isObject(m)){l.body=o.append(k(m))}else{l.body=o.html(m)}l.buttons={Ok:function(){Galaxy.modal.hide();j.clearMessages()}};return l},clearMessages:function(){var j=this.$el.find(this.msgsSelector);j.empty()},scrollPosition:function(){return this.$el.parent().scrollTop()},scrollTo:function(j){this.$el.parent().scrollTop(j)},scrollToTop:function(){this.$el.parent().scrollTop(0);return this},scrollIntoView:function(k,l){if(!l){this.$el.parent().parent().scrollTop(k);return this}var j=window,m=this.$el.parent().parent(),o=$(j).innerHeight(),n=(o/2)-(l/2);$(m).scrollTop(k-n);return this},scrollToId:function(k){if((!k)||(!this.hdaViews[k])){return this}var j=this.hdaViews[k].$el;this.scrollIntoView(j.offset().top,j.outerHeight());return this},scrollToHid:function(j){var k=this.model.hdas.getByHid(j);if(!k){return this}return this.scrollToId(k.id)},connectToQuotaMeter:function(j){if(!j){return this}this.listenTo(j,"quota:over",this.showQuotaMessage);this.listenTo(j,"quota:under",this.hideQuotaMessage);this.on("rendered rendered:initial",function(){if(j&&j.isOverQuota()){this.showQuotaMessage()}});return this},showQuotaMessage:function(){var j=this.$el.find(".quota-message");if(j.is(":hidden")){j.slideDown(this.fxSpeed)}},hideQuotaMessage:function(){var j=this.$el.find(".quota-message");if(!j.is(":hidden")){j.slideUp(this.fxSpeed)}},connectToOptionsMenu:function(j){if(!j){return this}this.on("new-storage",function(l,k){if(j&&l){j.findItemByHtml(_l("Include Deleted Datasets")).checked=l.get("show_deleted");j.findItemByHtml(_l("Include Hidden Datasets")).checked=l.get("show_hidden")}});return this},toString:function(){return"HistoryPanel("+((this.model)?(this.model.get("name")):(""))+")"}});e.templates={historyPanel:Handlebars.templates["template-history-historyPanel"],anonHistoryPanel:Handlebars.templates["template-history-historyPanel-anon"]};return{HistoryPanel:e}});
\ No newline at end of file
diff -r a3e2c3464298ebea3fd2ab93a43aac479ba9665a -r 9fa754a203b7312d58211b5e1e7140bf36aec76a static/scripts/packed/mvc/user/user-model.js
--- a/static/scripts/packed/mvc/user/user-model.js
+++ b/static/scripts/packed/mvc/user/user-model.js
@@ -1,1 +1,1 @@
-var User=Backbone.Model.extend(LoggableMixin).extend({urlRoot:galaxy_config.root+"api/users",defaults:{id:null,username:"("+_l("anonymous user")+")",email:"",total_disk_usage:0,nice_total_disk_usage:"",quota_percent:null},initialize:function(a){this.log("User.initialize:",a);this.on("loaded",function(b,c){this.log(this+" has loaded:",b,c)});this.on("change",function(b,c){this.log(this+" has changed:",b,c.changes)})},isAnonymous:function(){return(!this.get("email"))},loadFromApi:function(d,b){d=d||User.CURRENT_ID_STR;b=b||{};var a=this,c=b.success;b.success=function(f,e){a.trigger("loaded",f,e);if(c){c(f,e)}};if(d===User.CURRENT_ID_STR){b.url=this.urlRoot+"/"+User.CURRENT_ID_STR}return BaseModel.prototype.fetch.call(this,b)},clearSessionStorage:function(){for(var a in sessionStorage){if(a.indexOf("HistoryView.")===0){sessionStorage.removeItem(a)}}},toString:function(){var a=[this.get("username")];if(this.get("id")){a.unshift(this.get("id"));a.push(this.get("email"))}return"User("+a.join(":")+")"}});User.CURRENT_ID_STR="current";User.getCurrentUserFromApi=function(b){var a=new User();a.loadFromApi(User.CURRENT_ID_STR,b);return a};var UserCollection=Backbone.Collection.extend(LoggableMixin).extend({model:User,urlRoot:galaxy_config.root+"api/users"});
\ No newline at end of file
+var User=Backbone.Model.extend(LoggableMixin).extend({urlRoot:galaxy_config.root+"api/users",defaults:{id:null,username:"("+_l("anonymous user")+")",email:"",total_disk_usage:0,nice_total_disk_usage:"",quota_percent:null},initialize:function(a){this.log("User.initialize:",a);this.on("loaded",function(b,c){this.log(this+" has loaded:",b,c)});this.on("change",function(b,c){this.log(this+" has changed:",b,c.changes)})},isAnonymous:function(){return(!this.get("email"))},loadFromApi:function(d,b){d=d||User.CURRENT_ID_STR;b=b||{};var a=this,c=b.success;b.success=function(f,e){a.trigger("loaded",f,e);if(c){c(f,e)}};if(d===User.CURRENT_ID_STR){b.url=this.urlRoot+"/"+User.CURRENT_ID_STR}return Backbone.Model.prototype.fetch.call(this,b)},clearSessionStorage:function(){for(var a in sessionStorage){if(a.indexOf("HistoryView.")===0){sessionStorage.removeItem(a)}}},toString:function(){var a=[this.get("username")];if(this.get("id")){a.unshift(this.get("id"));a.push(this.get("email"))}return"User("+a.join(":")+")"}});User.CURRENT_ID_STR="current";User.getCurrentUserFromApi=function(b){var a=new User();a.loadFromApi(User.CURRENT_ID_STR,b);return a};var UserCollection=Backbone.Collection.extend(LoggableMixin).extend({model:User,urlRoot:galaxy_config.root+"api/users"});
\ No newline at end of file
diff -r a3e2c3464298ebea3fd2ab93a43aac479ba9665a -r 9fa754a203b7312d58211b5e1e7140bf36aec76a templates/grid_base.mako
--- a/templates/grid_base.mako
+++ b/templates/grid_base.mako
@@ -207,18 +207,11 @@
##
<%def name="center_panel()">
- ${self.grid_body()}
+ ${self.load()}
</%def>
## Render the grid's basic elements. Each of these elements can be subclassed.
<%def name="body()">
- ${self.grid_body()}
-</%def>
-
-## Because body() is special and always exists even if not explicitly defined,
-## it's not possible to override body() in the topmost template in the chain.
-## Because of this, override grid_body() instead.
-<%def name="grid_body()">
${self.load()}
</%def>
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: Grids: Push code into js, async refresh based on json
by commits-noreply@bitbucket.org 18 Dec '13
by commits-noreply@bitbucket.org 18 Dec '13
18 Dec '13
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/a3e2c3464298/
Changeset: a3e2c3464298
User: guerler
Date: 2013-12-18 23:16:43
Summary: Grids: Push code into js, async refresh based on json
Affected #: 3 files
diff -r 350c72df26815c0483a268fd1a097f0af8360930 -r a3e2c3464298ebea3fd2ab93a43aac479ba9665a static/scripts/galaxy.grids.js
--- a/static/scripts/galaxy.grids.js
+++ b/static/scripts/galaxy.grids.js
@@ -130,7 +130,13 @@
});
return url_data;
+ },
+
+ // Return URL for obtaining a new grid
+ get_url: function (args) {
+ return this.get('url_base') + "?" + $.param(this.get_url_data()) + '&' + $.param(args);
}
+
});
// grid view
@@ -140,9 +146,10 @@
grid: null,
// Initialize
- initialize: function(grid)
+ initialize: function(grid_config)
{
- this.init_grid(grid);
+ // initialize controls
+ this.init_grid(grid_config);
this.init_grid_controls();
// Initialize text filters to select text on click and use normal font when user is typing.
@@ -153,9 +160,30 @@
},
// Initialize
- init_grid: function(grid)
+ init_grid: function(grid_config)
{
- this.grid = grid;
+ // link grid model
+ this.grid = new Grid(grid_config);
+
+ // get options
+ var options = this.grid.attributes;
+
+ // strip protocol and domain
+ var url = this.grid.get('url_base');
+ url = url.replace(/^.*\/\/[^\/]+/, '');
+ this.grid.set('url_base', url);
+
+ // update div contents
+ $('#grid-table-body').html(this.template_body(options));
+ $('#grid-table-footer').html(this.template_footer(options));
+
+ // update message
+ if (options.message) {
+ $('#grid-message').html(this.template_message(options));
+ setTimeout( function() { $('#grid-message').html(''); }, 5000);
+ }
+
+ // configure elements
this.init_grid_elements();
},
@@ -537,7 +565,7 @@
// check for operation details
if (operation && id) {
// show confirmation box
- if (confirmation_text && confirmation_text != '' && confirmation_text != 'None')
+ if (confirmation_text && confirmation_text != '' && confirmation_text != 'None' && confirmation_text != 'null')
if(!confirm(confirmation_text))
return false;
@@ -622,30 +650,16 @@
type: method,
url: self.grid.get('url_base'),
data: self.grid.get_url_data(),
- error: function(response) { alert( "Grid refresh failed" );},
+ error: function(response) { alert( 'Grid refresh failed' );},
success: function(response_text) {
- // HACK: use a simple string to separate the elements in the
- // response: (1) table body; (2) number of pages in table; and (3) message.
- var parsed_response_text = response_text.split("*****");
-
- // Update grid body and footer.
- $('#grid-table-body').html(parsed_response_text[0]);
- // FIXME: this does not work at all; what's needed is a function
- // that updates page links when number of pages changes.
- $('#grid-table-footer').html(parsed_response_text[1]);
-
+ // Initialize new grid config
+ self.init_grid($.parseJSON(response_text));
+
// Trigger custom event to indicate grid body has changed.
$('#grid-table-body').trigger('update');
// Hide loading overlay.
$('.loading-elt-overlay').hide();
-
- // Show message if there is one.
- var message = $.trim( parsed_response_text[2] );
- if (message !== "") {
- $('#grid-message').html( message ).show();
- setTimeout( function() { $('#grid-message').hide(); }, 5000);
- }
},
complete: function() {
// Clear grid of transient request attributes.
@@ -688,6 +702,253 @@
if (cur_page !== null && cur_page !== undefined && cur_page !== 'all') {
this.grid.set('cur_page', 1);
}
+ },
+
+ // template
+ template_body: function(options) {
+ // initialize
+ var tmpl = '';
+ var num_rows_rendered = 0;
+ var items_length = options.items.length;
+
+ // empty grid?
+ if (items_length == 0) {
+ // No results.
+ tmpl += '<tr><td colspan="100"><em>No Items</em></td></tr>';
+ num_rows_rendered = 1;
+ }
+
+ // create rows
+ for (i in options.items) {
+
+ // encode ids
+ var item = options.items[i];
+ var encoded_id = item.encode_id;
+ var popupmenu_id = 'grid-' + i + '-popup';
+
+ // Tag current
+ tmpl += '<tr ';
+ if (options.current_item_id == item.id) {
+ tmpl += 'class="current"';
+ }
+ tmpl += '>';
+
+ // Item selection column
+ if (options.show_item_checkboxes) {
+ tmpl += '<td style="width: 1.5em;">' +
+ '<input type="checkbox" name="id" value="' + encoded_id + '" id="' + encoded_id + '" class="grid-row-select-checkbox" />' +
+ '</td>';
+ }
+
+ // Data columns
+ for (j in options.columns) {
+ var column = options.columns[j];
+ if (column.visible) {
+ // Nowrap
+ var nowrap = '';
+ if (column.nowrap) {
+ nowrap = 'style="white-space:nowrap;"';
+ }
+
+ // get column settings
+ var column_settings = item.column_config[column.label];
+
+ // load attributes
+ var link = column_settings.link;
+ var value = column_settings.value;
+ var inbound = column_settings.inbound;
+
+ // unescape value
+ if (jQuery.type( value ) === 'string') {
+ value = value.replace(/\/\//g, '/');
+ }
+
+ // Attach popup menu?
+ var id = "";
+ var cls = "";
+ if (column.attach_popup) {
+ id = 'grid-' + i + '-popup';
+ cls = "menubutton"
+ if (link != '') {
+ cls += " split";
+ }
+ cls += " popup";
+ }
+
+ // Check for row wrapping
+ tmpl += '<td ' + nowrap + '>';
+
+ // Link
+ if (link) {
+ if (options.operations.length != 0) {
+ tmpl += '<div id="' + id + '" class="' + cls + '" style="float: left;">';
+ }
+
+ var label_class = "";
+ if (inbound) {
+ label_class = "use-inbound"
+ } else {
+ label_class = "use-outbound"
+ }
+ tmpl += '<a class="label ' + label_class + '" href="' + link + '" onclick="return false;">' + value + '</a>';
+ if (options.operations.length != 0) {
+ tmpl += '</div>';
+ }
+ } else {
+ tmpl += '<div id="' + id + '" class="' + cls + '"><label id="' + column.label_id_prefix + encoded_id + '" for="' + encoded_id + '">' + value + '</label></div>';
+ }
+ tmpl += '</td>';
+ }
+ }
+ tmpl += '</tr>';
+ num_rows_rendered++;
+ }
+ return tmpl;
+ },
+
+ // template
+ template_footer: function(options) {
+
+ // create template string
+ var tmpl = '';
+
+ // paging
+ if (options.use_paging && options.num_pages > 1) {
+ // get configuration
+ var num_page_links = options.num_page_links;
+ var cur_page_num = options.cur_page_num;
+ var num_pages = options.num_pages;
+
+ // First pass on min page.
+ var page_link_range = num_page_links / 2;
+ var min_page = cur_page_num - page_link_range
+ var min_offset = 0;
+ if (min_page == 0) {
+ // Min page is too low.
+ min_page = 1;
+ min_offset = page_link_range - ( cur_page_num - min_page );
+ }
+
+ // Set max page.
+ var max_range = page_link_range + min_offset;
+ var max_page = cur_page_num + max_range;
+ if (max_page <= num_pages) {
+ // Max page is fine.
+ max_offset = 0;
+ } else {
+ // Max page is too high.
+ max_page = num_pages;
+ // +1 to account for the +1 in the loop below.
+ max_offset = max_range - ( max_page + 1 - cur_page_num );
+ }
+
+ // Second and final pass on min page to add any unused
+ // offset from max to min.
+ if (max_offset != 0) {
+ min_page -= max_offset
+ if (min_page < 1) {
+ min_page = 1
+ }
+ }
+
+ // template header
+ tmpl += '<tr id="page-links-row">';
+ if (options.show_item_checkboxes) {
+ tmpl += '<td></td>';
+ }
+ tmpl += '<td colspan="100">' +
+ '<span id="page-link-container">' +
+ 'Page:';
+
+ if (min_page > 1) {
+ tmpl += '<span class="page-link" id="page-link-1"><a href="' + this.grid.get_url({page : page_index}) + '" page_num="1" onclick="return false;">1</a></span> ...';
+ }
+
+ // create page urls
+ for (var page_index = min_page; page_index < max_page + 1; page_index++) {
+
+ if (page_index == options.cur_page_num) {
+ tmpl += '<span class="page-link inactive-link" id="page-link-' + page_index + '">' + page_index + '</span>';
+ } else {
+ tmpl += '<span class="page-link" id="page-link-' + page_index + '"><a href="' + this.grid.get_url({page : page_index}) + '" onclick="return false;" page_num="' + page_index + '">' + page_index + '</a></span>';
+ }
+ }
+
+ // show last page
+ if (max_page < num_pages) {
+ tmpl += '...' +
+ '<span class="page-link" id="page-link-' + num_pages + '"><a href="' + this.grid.get_url({page : num_pages}) + '" onclick="return false;" page_num="' + num_pages + '">' + num_pages + '</a></span>';
+ }
+ tmpl += '</span>';
+
+ // Show all link
+ tmpl += '<span class="page-link" id="show-all-link-span"> | <a href="' + this.grid.get_url({page : 'all'}) + '" onclick="return false;" page_num="all">Show All</a></span>' +
+ '</td>' +
+ '</tr>';
+ }
+
+ // Grid operations for multiple items.
+ if (options.show_item_checkboxes) {
+ // start template
+ tmpl += '<tr>' +
+ '<input type="hidden" id="operation" name="operation" value="">' +
+ '<td></td>' +
+ '<td colspan="100">' +
+ 'For <span class="grid-selected-count"></span> selected ' + options.get_class_plural + ': ';
+
+ // configure buttons for operations
+ for (i in options.operations) {
+ var operation = options.operations[i];
+ if (operation.allow_multiple) {
+ tmpl += '<input type="button" value="' + operation.label + '" class="action-button" onclick="gridView.submit_operation(this, \'' + operation.confirm + '\')"> ';
+ }
+ }
+
+ // finalize template
+ tmpl += '</td>' +
+ '</tr>';
+ }
+
+ // count global operations
+ var found_global = false;
+ for (i in options.operations) {
+ if (options.operations[i].global_operation) {
+ found_global = true;
+ break;
+ }
+ }
+
+ // add global operations
+ if (found_global) {
+ tmpl += '<tr>' +
+ '<td colspan="100">';
+ for (i in options.operations) {
+ var operation = options.operations[i];
+ if (operation.global_operation) {
+ tmpl += '<a class="action-button" href="' + operation.global_operation + '">' + operation.label + '</a>';
+ }
+ }
+ tmpl += '</td>' +
+ '</tr>';
+ }
+
+ // add legend
+ if (options.legend) {
+ tmpl += '<tr>' +
+ '<td colspan="100">' + options.legend + '</td>' +
+ '</tr>';
+ }
+
+ // return
+ return tmpl;
+ },
+
+ // template
+ template_message: function(options) {
+ return '<p>' +
+ '<div class="' + options.status + 'message transient-message">' + options.message + '</div>' +
+ '<div style="clear: both"></div>' +
+ '</p>';
}
});
diff -r 350c72df26815c0483a268fd1a097f0af8360930 -r a3e2c3464298ebea3fd2ab93a43aac479ba9665a templates/grid_base.mako
--- a/templates/grid_base.mako
+++ b/templates/grid_base.mako
@@ -1,6 +1,7 @@
<%!
from galaxy.web.framework.helpers.grids import TextColumn, StateColumn, GridColumnFilter
from galaxy.web.framework.helpers import iff
+ import urllib
import galaxy.util
def inherit(context):
@@ -24,7 +25,7 @@
self.grid_javascripts()
if embedded:
self.render_grid_header( grid, False )
- self.render_grid_table( grid, show_item_checkboxes=show_item_checkboxes )
+ self.render_grid_table( grid )
else:
self.make_grid( grid )
endif
@@ -50,6 +51,7 @@
'show_item_checkboxes' : context.get('show_item_checkboxes', False),
'cur_page_num' : cur_page_num,
'num_pages' : num_pages,
+ 'num_page_links' : num_page_links,
'history_tag_autocomplete_url' : url( controller='tag', action='tag_autocomplete_data', item_class='History' ),
'history_name_autocomplete_url' : url( controller='history', action='name_autocomplete_data' ),
'status' : status,
@@ -58,7 +60,6 @@
'operations' : [],
'items' : [],
'columns' : [],
- 'multiple_item_ops_exist' : None,
'get_class_plural' : get_class_plural( grid.model_class ).lower(),
'use_paging' : grid.use_paging,
'legend' : grid.legend,
@@ -68,7 +69,7 @@
'default_filter_dict' : default_filter_dict,
'advanced_search' : advanced_search
}
-
+
## add current item if exists
if current_item:
self.grid_config['current_item_id'] = current_item.id
@@ -119,7 +120,7 @@
'global_operation' : False
})
if operation.allow_multiple:
- self.grid_config['multiple_item_ops_exist'] = True
+ self.grid_config['show_item_checkboxes'] = True
if operation.global_operation:
self.grid_config['global_operation'] = url( ** (operation.global_operation()) )
@@ -176,8 +177,6 @@
# Handle non-ascii chars.
if isinstance(value, str):
value = unicode(value, 'utf-8')
-
- # escape string
value = value.replace('/', '//')
endif
@@ -242,7 +241,16 @@
}
gridView.add_filter_condition("tags", tag);
};
+
+ ## load grid viewer
+ $(function() {
+ require(['galaxy.grids'], function(mod_grids) {
+ gridView = new mod_grids.GridView(${h.to_json_string(self.grid_config)});
+ });
+ });
</script>
+
+ ${handle_refresh_frames()}
</%def><%def name="stylesheets()">
@@ -268,20 +276,13 @@
<td></td></tr><tr>
- <td width="100%" id="grid-message" valign="top">
- %if message:
- <p>
- <div class="${self.grid_config['status']}message transient-message">${self.grid_config['message']}</div>
- <div style="clear: both"></div>
- </p>
- %endif
- </td>
+ <td width="100%" id="grid-message" valign="top"></td><td></td><td></td></tr></table>
- ${self.render_grid_table( grid, show_item_checkboxes )}
+ ${self.render_grid_table( grid )}
</%def><%def name="grid_title()">
@@ -328,16 +329,11 @@
</%def>
## Render grid.
-<%def name="render_grid_table( grid, show_item_checkboxes=False)">
+<%def name="render_grid_table( grid )"><%
# get configuration
show_item_checkboxes = self.grid_config['show_item_checkboxes']
- multiple_item_ops_exist = self.grid_config['multiple_item_ops_exist']
sort_key = self.grid_config['sort_key']
-
- # Show checkboxes if flag is set or if multiple item ops exist.
- if show_item_checkboxes or multiple_item_ops_exist:
- show_item_checkboxes = True
%><form method="post" onsubmit="return false;"><table id="grid-table" class="grid">
@@ -364,238 +360,14 @@
</th>
%endif
%endfor
- <th></th></tr></thead>
- <tbody id="grid-table-body">
- ${render_grid_table_body_contents( grid, show_item_checkboxes )}
- </tbody>
- <tfoot id="grid-table-footer">
- ${render_grid_table_footer_contents( grid, show_item_checkboxes )}
- </tfoot>
+ <tbody id="grid-table-body"></tbody>
+ <tfoot id="grid-table-footer"></tfoot></table></form></%def>
-## Render grid table body contents.
-<%def name="render_grid_table_body_contents(grid, show_item_checkboxes=False)">
- <% num_rows_rendered = 0 %>
- %if len(self.grid_config['items']) == 0:
- ## No results.
- <tr><td colspan="100"><em>No Items</em></td></tr>
- <% num_rows_rendered = 1 %>
- %endif
- %for i, item in enumerate( self.grid_config['items'] ):
- <% encoded_id = item['encode_id'] %>
- <% popupmenu_id = "grid-" + str(i) + "-popup" %>
- <tr \
- %if self.grid_config['current_item_id'] == item['id']:
- class="current" \
- %endif
- >
- ## Item selection column
- %if show_item_checkboxes:
- <td style="width: 1.5em;">
- <input type="checkbox" name="id" value="${encoded_id}" id="${encoded_id}" class="grid-row-select-checkbox" />
- </td>
- %endif
- ## Data columns
- %for column in self.grid_config['columns']:
- %if column['visible']:
- <%
- ## Nowrap
- nowrap = ""
- if column['nowrap']:
- nowrap = 'style="white-space:nowrap;"'
-
- # get column settings
- column_settings = item['column_config'][column['label']]
-
- # load attributes
- link = column_settings['link']
- value = column_settings['value']
- inbound = column_settings['inbound']
-
- # unescape value
- if isinstance(value, unicode):
- value = value.replace('//', '/')
-
- # Attach popup menu?
- id = ""
- cls = ""
- if column['attach_popup']:
- id = 'grid-%d-popup' % i
- cls = "menubutton"
- if link:
- cls += " split"
- endif
- cls += " popup"
- endif
- %>
- <td ${nowrap}>
- %if link:
- %if len(self.grid_config['operations']) != 0:
- <div id="${id}" class="${cls}" style="float: left;">
- %endif
-
- <%
- label_class = ""
- if inbound:
- label_class = "use-inbound"
- else:
- label_class = "use-outbound"
- endif
- %>
- <a class="label ${label_class}" href="${link}" onclick="return false;">${value}</a>
- %if len(self.grid_config['operations']) != 0:
- </div>
- %endif
- %else:
- <div id="${id}" class="${cls}"><label id="${column['label_id_prefix']}${encoded_id}" for="${encoded_id}">${value}</label></div>
- %endif
- </td>
- %endif
- %endfor
- </tr>
- <% num_rows_rendered += 1 %>
- %endfor
-
- ## update configuration
- <script type="text/javascript">
- $(function() {
- require(['galaxy.grids'], function(mod_grids) {
- ## get configuration
- var grid_config = ${ h.to_json_string( self.grid_config ) };
-
- // Create grid.
- var grid = new mod_grids.Grid(grid_config);
-
- // strip protocol and domain
- var url = grid.get('url_base');
- url = url.replace(/^.*\/\/[^\/]+/, '');
- grid.set('url_base', url);
-
- // Create view.
- if (!gridView)
- gridView = new mod_grids.GridView(grid);
- else
- gridView.init_grid(grid);
- });
- });
- </script>
-
- ${handle_refresh_frames()}
-</%def>
-
-## Render grid table footer contents.
-<%def name="render_grid_table_footer_contents(grid, show_item_checkboxes=False)">
- <%
- items_plural = self.grid_config['get_class_plural']
- num_pages = self.grid_config['num_pages']
- cur_page_num = self.grid_config['cur_page_num']
- %>
- %if self.grid_config['use_paging'] and num_pages > 1:
- <tr id="page-links-row">
- %if show_item_checkboxes:
- <td></td>
- %endif
- <td colspan="100">
- <span id='page-link-container'>
- ## Page links. Show 10 pages around current page.
- <%
- #
- # Set minimum & maximum page.
- #
- page_link_range = num_page_links/2
-
- # First pass on min page.
- min_page = cur_page_num - page_link_range
- if min_page >= 1:
- # Min page is fine.
- min_offset = 0
- else:
- # Min page is too low.
- min_page = 1
- min_offset = page_link_range - ( cur_page_num - min_page )
-
- # Set max page.
- max_range = page_link_range + min_offset
- max_page = cur_page_num + max_range
- if max_page <= num_pages:
- # Max page is fine.
- max_offset = 0
- else:
- # Max page is too high.
- max_page = num_pages
- # +1 to account for the +1 in the loop below.
- max_offset = max_range - ( max_page + 1 - cur_page_num )
-
- # Second and final pass on min page to add any unused
- # offset from max to min.
- if max_offset != 0:
- min_page -= max_offset
- if min_page < 1:
- min_page = 1
- %>
- Page:
- % if min_page > 1:
- <span class='page-link' id="page-link-1"><a href="${url( page=1 )}" page_num="1" onclick="return false;">1</a></span> ...
- % endif
- %for page_index in range(min_page, max_page + 1):
- %if page_index == cur_page_num:
- <span class='page-link inactive-link' id="page-link-${page_index}">${page_index}</span>
- %else:
- <% args = { 'page' : page_index } %>
- <span class='page-link' id="page-link-${page_index}"><a href="${url( args )}" onclick="return false;" page_num='${page_index}'>${page_index}</a></span>
- %endif
- %endfor
- %if max_page < num_pages:
- ...
- <span class='page-link' id="page-link-${num_pages}"><a href="${url( page=num_pages )}" onclick="return false;" page_num="${num_pages}">${num_pages}</a></span>
- %endif
- </span>
-
- ## Show all link
- <span class='page-link' id='show-all-link-span'> | <a href="${url( page='all' )}" onclick="return false;" page_num="all">Show All</a></span>
- </td>
- </tr>
- %endif
- ## Grid operations for multiple items.
- %if show_item_checkboxes:
- <tr>
- ## place holder for multiple operation commands
- <input type="hidden" id="operation" name="operation" value="">
- <td></td>
- <td colspan="100">
- For <span class="grid-selected-count"></span> selected ${items_plural}:
- %for operation in self.grid_config['operations']:
- %if operation['allow_multiple']:
- <input type="button" value="${operation['label']}" class="action-button" onclick="gridView.submit_operation(this, '${operation['confirm']}')">
- %endif
- %endfor
- </td>
- </tr>
- %endif
- %if len([o for o in self.grid_config['operations'] if o['global_operation']]) > 0:
- <tr>
- <td colspan="100">
- %for operation in self.grid_config['operations']:
- %if operation['global_operation']:
- <a class="action-button" href="${operation['global_operation']}">${operation['label']}</a>
- %endif
- %endfor
- </td>
- </tr>
- %endif
- %if self.grid_config['legend']:
- <tr>
- <td colspan="100">
- ${self.grid_config['legend']}
- </td>
- </tr>
- %endif
-</%def>
-
## Print grid search/filtering UI.
<%def name="render_grid_filters( grid, render_advanced_search=True )"><%
diff -r 350c72df26815c0483a268fd1a097f0af8360930 -r a3e2c3464298ebea3fd2ab93a43aac479ba9665a templates/grid_base_async.mako
--- a/templates/grid_base_async.mako
+++ b/templates/grid_base_async.mako
@@ -1,18 +1,4 @@
-<%namespace file="./grid_base.mako" import="*" />
-<%namespace file="/display_common.mako" import="render_message" />
+<%namespace name="grid_base" file="./grid_base.mako" import="*" />
${init()}
-
-<%
- # Set flag to indicate whether grid has operations that operate on multiple items.
- multiple_item_ops_exist = False
- for operation in grid.operations:
- if operation.allow_multiple:
- multiple_item_ops_exist = True
-%>
-
-${render_grid_table_body_contents( grid, show_item_checkboxes=( show_item_checkboxes or multiple_item_ops_exist ) )}
-*****
-${render_grid_table_footer_contents( grid, show_item_checkboxes=( show_item_checkboxes or multiple_item_ops_exist ) )}
-*****
-${render_message( message, status )}
\ No newline at end of file
+${h.to_json_string( grid_base.grid_config )}
\ 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: simleo: tools/fastq/fastq_paired_end_joiner: added support for recent Illumina headers
by commits-noreply@bitbucket.org 18 Dec '13
by commits-noreply@bitbucket.org 18 Dec '13
18 Dec '13
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/e232573b7c62/
Changeset: e232573b7c62
User: simleo
Date: 2013-06-06 17:33:46
Summary: tools/fastq/fastq_paired_end_joiner: added support for recent Illumina headers
Affected #: 2 files
diff -r af91c734dbb76b8c0e3166c7471370f9ba8260b5 -r e232573b7c629a94ab60e6b615ecedf156913308 tools/fastq/fastq_paired_end_joiner.py
--- a/tools/fastq/fastq_paired_end_joiner.py
+++ b/tools/fastq/fastq_paired_end_joiner.py
@@ -1,38 +1,162 @@
-#Dan Blankenberg
-import sys, os, shutil
-from galaxy_utils.sequence.fastq import fastqReader, fastqNamedReader, fastqWriter, fastqJoiner
+"""
+Extended version of Dan Blankenberg's fastq joiner (adds support for
+recent Illumina headers).
+"""
+
+import sys, re
+import galaxy_utils.sequence.fastq as fq
+
+
+class IDManager(object):
+
+ def __init__(self, sep="\t"):
+ """
+ Recent Illumina FASTQ header format::
+
+ @<COORDS><FLAGS>
+ COORDS = <Instrument>:<Run #>:<Flowcell ID>:<Lane>:<Tile>:<X>:<Y>
+ FLAGS = <Read>:<Is Filtered>:<Control Number>:<Index Sequence>
+
+ where the whitespace character between <COORDS> and <FLAGS> can be
+ either a space or a tab.
+ """
+ self.sep = sep
+
+ def parse_id(self, identifier):
+ try:
+ coords, flags = identifier.strip()[1:].split(self.sep, 1)
+ except ValueError:
+ raise RuntimeError("bad identifier: %r" % (identifier,))
+ return coords.split(":"), flags.split(":")
+
+ def join_id(self, parsed_id):
+ coords, flags = parsed_id
+ return "@%s%s%s" % (":".join(coords), self.sep, ":".join(flags))
+
+ def get_read_number(self, parsed_id):
+ return int(parsed_id[1][0])
+
+ def set_read_number(self, parsed_id, n):
+ parsed_id[1][0] = "%d" % n
+
+ def get_paired_identifier(self, read):
+ t = self.parse_id(read.identifier)
+ n = self.get_read_number(t)
+ if n == 1:
+ pn = 2
+ elif n == 2:
+ pn = 1
+ else:
+ raise RuntimeError("Unknown read number '%d'" % n)
+ self.set_read_number(t, pn)
+ return self.join_id(t)
+
+
+class FastqJoiner(fq.fastqJoiner):
+
+ def __init__(self, format, force_quality_encoding=None, sep="\t"):
+ super(FastqJoiner, self).__init__(format, force_quality_encoding)
+ self.id_manager = IDManager(sep)
+
+ def join(self, read1, read2):
+ force_quality_encoding = self.force_quality_encoding
+ if not force_quality_encoding:
+ if read1.is_ascii_encoded():
+ force_quality_encoding = 'ascii'
+ else:
+ force_quality_encoding = 'decimal'
+ read1 = read1.convert_read_to_format(
+ self.format, force_quality_encoding=force_quality_encoding
+ )
+ read2 = read2.convert_read_to_format(
+ self.format, force_quality_encoding=force_quality_encoding
+ )
+ #--
+ t1, t2 = [
+ self.id_manager.parse_id(r.identifier) for r in (read1, read2)
+ ]
+ if self.id_manager.get_read_number(t1) == 2:
+ if not self.id_manager.get_read_number(t2) == 1:
+ raise RuntimeError("input files are not from mated pairs")
+ read1, read2 = read2, read1
+ t1, t2 = t2, t1
+ #--
+ rval = fq.FASTQ_FORMATS[self.format]()
+ rval.identifier = read1.identifier
+ rval.description = "+"
+ if len(read1.description) > 1:
+ rval.description += rval.identifier[1:]
+ if rval.sequence_space == 'color':
+ # convert to nuc space, join, then convert back
+ rval.sequence = rval.convert_base_to_color_space(
+ read1.convert_color_to_base_space(read1.sequence) +
+ read2.convert_color_to_base_space(read2.sequence)
+ )
+ else:
+ rval.sequence = read1.sequence + read2.sequence
+ if force_quality_encoding == 'ascii':
+ rval.quality = read1.quality + read2.quality
+ else:
+ rval.quality = "%s %s" % (
+ read1.quality.strip(), read2.quality.strip()
+ )
+ return rval
+
+ def get_paired_identifier(self, read):
+ return self.id_manager.get_paired_identifier(read)
+
+
+def sniff_sep(fastq_fn):
+ header = ""
+ with open(fastq_fn) as f:
+ while header == "":
+ try:
+ header = f.next().strip()
+ except StopIteration:
+ raise RuntimeError("%r: empty file" % (fastq_fn,))
+ return re.search(r"\s", header).group()
+
def main():
- #Read command line arguments
input1_filename = sys.argv[1]
input1_type = sys.argv[2] or 'sanger'
input2_filename = sys.argv[3]
input2_type = sys.argv[4] or 'sanger'
output_filename = sys.argv[5]
-
+ fastq_style = sys.argv[6] or 'old'
+ #--
if input1_type != input2_type:
- print "WARNING: You are trying to join files of two different types: %s and %s." % ( input1_type, input2_type )
-
- input2 = fastqNamedReader( open( input2_filename, 'rb' ), input2_type )
- joiner = fastqJoiner( input1_type )
- out = fastqWriter( open( output_filename, 'wb' ), format = input1_type )
-
+ print "WARNING: trying to join files of different types: %s and %s" % (
+ input1_type, input2_type
+ )
+ if fastq_style == 'new':
+ sep = sniff_sep(input1_filename)
+ joiner = FastqJoiner(input1_type, sep=sep)
+ else:
+ joiner = fq.fastqJoiner(input1_type)
+ #--
+ input2 = fq.fastqNamedReader(open(input2_filename, 'rb'), input2_type)
+ out = fq.fastqWriter(open(output_filename, 'wb'), format=input1_type)
i = None
skip_count = 0
- for i, fastq_read in enumerate( fastqReader( open( input1_filename, 'rb' ), format = input1_type ) ):
- identifier = joiner.get_paired_identifier( fastq_read )
- fastq_paired = input2.get( identifier )
+ for i, fastq_read in enumerate(fq.fastqReader(
+ open(input1_filename, 'rb' ), format=input1_type
+ )):
+ identifier = joiner.get_paired_identifier(fastq_read)
+ fastq_paired = input2.get(identifier)
if fastq_paired is None:
skip_count += 1
else:
- out.write( joiner.join( fastq_read, fastq_paired ) )
+ out.write(joiner.join(fastq_read, fastq_paired))
out.close()
-
if i is None:
- print "Your file contains no valid FASTQ reads."
+ print "Your file contains no valid FASTQ reads"
else:
print input2.has_data()
- print 'Joined %s of %s read pairs (%.2f%%).' % ( i - skip_count + 1, i + 1, float( i - skip_count + 1 ) / float( i + 1 ) * 100.0 )
+ print 'Joined %s of %s read pairs (%.2f%%)' % (
+ i - skip_count + 1, i + 1, (i - skip_count + 1) / (i + 1) * 100.0
+ )
+
if __name__ == "__main__":
main()
diff -r af91c734dbb76b8c0e3166c7471370f9ba8260b5 -r e232573b7c629a94ab60e6b615ecedf156913308 tools/fastq/fastq_paired_end_joiner.xml
--- a/tools/fastq/fastq_paired_end_joiner.xml
+++ b/tools/fastq/fastq_paired_end_joiner.xml
@@ -1,9 +1,13 @@
-<tool id="fastq_paired_end_joiner" name="FASTQ joiner" version="1.0.0">
+<tool id="fastq_paired_end_joiner" name="FASTQ joiner" version="2.0.0"><description>on paired end reads</description>
- <command interpreter="python">fastq_paired_end_joiner.py '$input1_file' '${input1_file.extension[len( 'fastq' ):]}' '$input2_file' '${input2_file.extension[len( 'fastq' ):]}' '$output_file'</command>
+ <command interpreter="python">fastq_paired_end_joiner.py '$input1_file' '${input1_file.extension[len( 'fastq' ):]}' '$input2_file' '${input2_file.extension[len( 'fastq' ):]}' '$output_file' '$style'</command><inputs><param name="input1_file" type="data" format="fastqsanger,fastqcssanger" label="Left-hand Reads" /><param name="input2_file" type="data" format="fastqsanger,fastqcssanger" label="Right-hand Reads" />
+ <param name="style" type="select" label="FASTQ Header Style">
+ <option value="old" selected="true">old</option>
+ <option value="new">new</option>
+ </param></inputs><outputs><data name="output_file" format="input" />
@@ -18,14 +22,19 @@
<help>
**What it does**
-This tool joins paired end FASTQ reads from two separate files into a single read in one file. The join is performed using sequence identifiers, allowing the two files to contain differing ordering. If a sequence identifier does not appear in both files, it is excluded from the output.
-
-Sequence identifiers with /1 and /2 appended override the left-hand and right-hand designation; i.e. if the reads end with /1 and /2, the read containing /1 will be used as the left-hand read and the read containing /2 will be used as the right-hand read. Sequences without this designation will follow the left-hand and right-hand settings set by the user.
+This tool joins paired end FASTQ reads from two separate files into a
+single read in one file. The join is performed using sequence
+identifiers, allowing the two files to contain differing ordering. If
+a sequence identifier does not appear in both files, it is excluded
+from the output.
-----
**Input formats**
+Both old and new (from recent Illumina software) style FASTQ headers
+are supported. The following example uses the "old" style.
+
Left-hand Read::
@HWI-EAS91_1_30788AAXX:7:21:1542:1758/1
@@ -53,10 +62,26 @@
------
-**Citation**
+**The "new" style**
-If you use this tool, please cite `Blankenberg D, Gordon A, Von Kuster G, Coraor N, Taylor J, Nekrutenko A; Galaxy Team. Manipulation of FASTQ data with Galaxy. Bioinformatics. 2010 Jul 15;26(14):1783-5. <http://www.ncbi.nlm.nih.gov/pubmed/20562416>`_
+Recent Illumina FASTQ headers are structured as follows::
+ @COORDS FLAGS
+ COORDS = INSTRUMENT:RUN_#:FLOWCELL_ID:LANE:TILE:X:Y
+ FLAGS = READ:IS_FILTERED:CONTROL_NUMBER:INDEX_SEQUENCE
+where the whitespace character between COORDS and FLAGS can be either
+a space or a tab.
+
+------
+
+**Credits**
+
+This is an extended version (adds support for "new" style FASTQ headers)
+of D. Blankenberg's fastq joiner:
+
+`Blankenberg D, Gordon A, Von Kuster G, Coraor N, Taylor J, Nekrutenko A; Galaxy Team. Manipulation of FASTQ data with Galaxy. Bioinformatics. 2010 Jul 15;26(14):1783-5. <http://www.ncbi.nlm.nih.gov/pubmed/20562416>`_
+
+New style header support added by Simone Leo <simone.leo(a)crs4.it>
</help></tool>
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: Corrections to statistics for the tool shed's install and test runs and successful installation results for repositories of type tool_dependency_definition now reported to the tool shed.
by commits-noreply@bitbucket.org 18 Dec '13
by commits-noreply@bitbucket.org 18 Dec '13
18 Dec '13
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/a950019c26a9/
Changeset: a950019c26a9
User: greg
Date: 2013-12-18 22:20:36
Summary: Corrections to statistics for the tool shed's install and test runs and successful installation results for repositories of type tool_dependency_definition now reported to the tool shed.
Affected #: 5 files
diff -r f1cb7f07af2c923d3f3be77a0ae0ccb25c6453a7 -r a950019c26a9189f145d4da87c589f64babaa8e2 install_and_test_tool_shed_repositories.sh
--- a/install_and_test_tool_shed_repositories.sh
+++ b/install_and_test_tool_shed_repositories.sh
@@ -70,12 +70,16 @@
done
case $which in
- dependencies)
+ # Use "-w tool_dependency_definitions" when you want to test repositories of type tool_dependency_definition.
+ tool_dependency_definitions)
test_tool_dependency_definitions
;;
- tools)
+ # Use "-w repositories_with_tools" parameter when you want to test repositories that contain tools.
+ repositories_with_tools)
test_repositories_with_tools
;;
+ # No received parameters or any received parameter not in [ tool_dependency_definitions, repositories_with_tools ]
+ # will execute both scripts.
*)
test_tool_dependency_definitions
test_repositories_with_tools
diff -r f1cb7f07af2c923d3f3be77a0ae0ccb25c6453a7 -r a950019c26a9189f145d4da87c589f64babaa8e2 lib/tool_shed/scripts/check_tool_dependency_definition_repositories.py
--- a/lib/tool_shed/scripts/check_tool_dependency_definition_repositories.py
+++ b/lib/tool_shed/scripts/check_tool_dependency_definition_repositories.py
@@ -89,8 +89,9 @@
now = strftime( "%Y-%m-%d %H:%M:%S" )
print "#############################################################################"
- print "# %s - Validating repositories of type %s on %s..." % ( now, TOOL_DEPENDENCY_DEFINITION, config_parser.get( config_section, 'host' ) )
- print "# This tool shed is configured to listen on %s:%s" % ( config_parser.get( config_section, 'host' ), config_parser.get( config_section, 'port' ) )
+ print "# %s - Validating repositories of type %s" % ( now, TOOL_DEPENDENCY_DEFINITION )
+ print "# This tool shed is configured to listen on %s:%s" % ( config_parser.get( config_section, 'host' ),
+ config_parser.get( config_section, 'port' ) )
app = RepositoriesApplication( config )
diff -r f1cb7f07af2c923d3f3be77a0ae0ccb25c6453a7 -r a950019c26a9189f145d4da87c589f64babaa8e2 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
@@ -225,7 +225,8 @@
return suc.INITIAL_CHANGELOG_HASH, error_message
def get_missing_tool_dependencies( repository ):
- log.debug( 'Checking %s repository %s for missing tool dependencies.' % ( repository.status, repository.name ) )
+ log.debug( 'Checking revision %s of repository %s owned by %s for missing tool dependencies.' % \
+ ( str( repository.changeset_revision ), str( repository.name ), str( repository.changeset_revision ) ) )
missing_tool_dependencies = repository.missing_tool_dependencies
for tool_dependency in repository.tool_dependencies:
log.debug( 'Tool dependency %s version %s has status %s.' % ( tool_dependency.name, tool_dependency.version, tool_dependency.status ) )
@@ -423,12 +424,13 @@
return global_conf
def handle_missing_dependencies( app, repository, missing_tool_dependencies, repository_dict, tool_test_results_dicts,
- tool_test_results_dict, results_dict, can_update_tool_shed ):
+ tool_test_results_dict, can_update_tool_shed ):
"""Handle missing repository or tool dependencies for an installed repository."""
# If a tool dependency fails to install correctly, this should be considered an installation error,
# and functional tests should be skipped, since the tool dependency needs to be correctly installed
# for the test to be considered reliable.
- log.debug( 'The following dependencies of this repository are missing, so skipping functional tests.' )
+ log.debug( 'The following dependencies of revision %s of repository %s owned by %s are missing.' % \
+ ( str( repository.changeset_revision ), str( repository.name ), str( repository.owner ) ) )
# In keeping with the standard display layout, add the error message to the dict for each tool individually.
for dependency in repository.missing_tool_dependencies:
name = str( dependency.name )
@@ -436,24 +438,25 @@
version = str( dependency.version )
error_message = unicodify( dependency.error_message )
log.debug( 'Missing tool dependency %s of type %s version %s: %s' % ( name, type, version, error_message ) )
- test_result = dict( type=dependency.type,
- name=dependency.name,
- version=dependency.version,
- error_message=dependency.error_message )
- tool_test_results_dict[ 'installation_errors' ][ 'tool_dependencies' ].append( test_result )
+ missing_tool_dependency_info_dict = dict( type=type,
+ name=name,
+ version=version,
+ error_message=error_message )
+ tool_test_results_dict[ 'installation_errors' ][ 'tool_dependencies' ].append( missing_tool_dependency_info_dict )
for dependency in repository.missing_repository_dependencies:
+ tool_shed = str( dependency.tool_shed )
name = str( dependency.name )
owner = str( dependency.owner )
changeset_revision = str( dependency.changeset_revision )
error_message = unicodify( dependency.error_message )
log.debug( 'Missing repository dependency %s changeset revision %s owned by %s: %s' % \
( name, changeset_revision, owner, error_message ) )
- test_result = dict( tool_shed=dependency.tool_shed,
- name=dependency.name,
- owner=dependency.owner,
- changeset_revision=dependency.changeset_revision,
- error_message=dependency.error_message )
- tool_test_results_dict[ 'installation_errors' ][ 'repository_dependencies' ].append( test_result )
+ missing_repository_dependency_info_dict = dict( tool_shed=tool_shed,
+ name=name,
+ owner=owner,
+ changeset_revision=changeset_revision,
+ error_message=error_message )
+ tool_test_results_dict[ 'installation_errors' ][ 'repository_dependencies' ].append( missing_repository_dependency_info_dict )
# Record the status of this repository in the tool shed.
params = dict( tools_functionally_correct=False,
do_not_test=False,
@@ -465,26 +468,25 @@
repository_dict,
params,
can_update_tool_shed )
- # Since this repository is missing components we do not want to test it, uninstall it.
+ # Uninstall this repository since it is missing dependencies.
uninstall_repository_and_repository_dependencies( app, repository_dict )
- results_dict[ 'repositories_failed_install' ].append( dict( name=str( repository.name ),
- owner=str( repository.owner ),
- changeset_revision=str( repository.changeset_revision ) ) )
- return results_dict
-def initialize_results_dict( test_framework ):
+def initialize_install_and_test_statistics_dict( test_framework ):
# Initialize a dictionary for the summary that will be printed to stdout.
- results_dict = {}
+ install_and_test_statistics_dict = {}
if test_framework == REPOSITORIES_WITH_TOOLS:
- results_dict[ 'total_repositories_tested' ] = 0
- results_dict[ 'all_tests_passed' ] = []
- results_dict[ 'at_least_one_test_failed' ] = []
- results_dict[ 'repositories_failed_install' ] = []
+ install_and_test_statistics_dict[ 'total_repositories_processed' ] = 0
+ install_and_test_statistics_dict[ 'all_tests_passed' ] = []
+ install_and_test_statistics_dict[ 'at_least_one_test_failed' ] = []
+ install_and_test_statistics_dict[ 'successful_installations' ] = []
+ install_and_test_statistics_dict[ 'repositories_with_installation_error' ] = []
+ install_and_test_statistics_dict[ 'tool_dependencies_with_installation_error' ] = []
elif test_framework == TOOL_DEPENDENCY_DEFINITIONS:
- results_dict[ 'total_repositories_installed' ] = 0
- results_dict[ 'repositories_with_installation_error' ] = 0
- results_dict[ 'tool_dependencies_with_installation_error' ] = 0
- return results_dict
+ install_and_test_statistics_dict[ 'total_repositories_processed' ] = 0
+ install_and_test_statistics_dict[ 'successful_installations' ] = []
+ install_and_test_statistics_dict[ 'repositories_with_installation_error' ] = []
+ install_and_test_statistics_dict[ 'tool_dependencies_with_installation_error' ] = []
+ return install_and_test_statistics_dict
def initialize_tool_tests_results_dict( app, tool_test_results_dict ):
test_environment_dict = tool_test_results_dict.get( 'test_environment', {} )
diff -r f1cb7f07af2c923d3f3be77a0ae0ccb25c6453a7 -r a950019c26a9189f145d4da87c589f64babaa8e2 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
@@ -134,10 +134,10 @@
return tool_id, tool_version
def install_and_test_repositories( app, galaxy_shed_tools_dict, galaxy_shed_tool_conf_file ):
- results_dict = install_and_test_base_util.initialize_results_dict( test_framework )
+ install_and_test_statistics_dict = install_and_test_base_util.initialize_install_and_test_statistics_dict( test_framework )
error_message = ''
# Initialize a dictionary for the summary that will be printed to stdout.
- total_repositories_tested = results_dict[ 'total_repositories_tested' ]
+ total_repositories_processed = install_and_test_statistics_dict[ 'total_repositories_processed' ]
repositories_to_install, error_message = \
install_and_test_base_util.get_repositories_to_install( install_and_test_base_util.galaxy_tool_shed_url, test_framework )
if error_message:
@@ -213,8 +213,7 @@
break
if this_repository_is_in_the_exclude_list:
tool_test_results_dict[ 'not_tested' ] = dict( reason=skip_reason )
- params = dict( tools_functionally_correct=False,
- do_not_test=False )
+ params = dict( do_not_test=False )
# TODO: do something useful with response_dict
response_dict = install_and_test_base_util.register_test_result( install_and_test_base_util.galaxy_tool_shed_url,
tool_test_results_dicts,
@@ -223,30 +222,29 @@
params,
can_update_tool_shed )
log.debug( "Not testing revision %s of repository %s owned by %s because it is in the exclude list for this test run." % \
- ( changeset_revision, name, owner ) )
+ ( changeset_revision, name, owner ) )
else:
tool_test_results_dict = install_and_test_base_util.initialize_tool_tests_results_dict( app, tool_test_results_dict )
# Explicitly clear tests from twill's test environment.
remove_generated_tests( app )
# Proceed with installing repositories and testing contained tools.
repository, error_message = install_and_test_base_util.install_repository( app, repository_dict )
+ install_and_test_statistics_dict[ 'total_repositories_processed' ] += 1
if error_message:
+ # The repository installation failed.
+ log.debug( 'Installation failed for revision %s of repository %s owned by %s.' % \
+ ( changeset_revision, name, owner ) )
+ install_and_test_statistics_dict[ 'repositories_with_installation_error' ].append( repository_identifier_dict )
tool_test_results_dict[ 'installation_errors' ][ 'current_repository' ] = error_message
# Even if the repository failed to install, execute the uninstall method, in case a dependency did succeed.
- log.debug( 'Attempting to uninstall repository %s owned by %s.' % ( name, owner ) )
+ log.debug( 'Attempting to uninstall revision %s of repository %s owned by %s.' % ( changeset_revision, name, owner ) )
try:
repository = test_db_util.get_installed_repository_by_name_owner_changeset_revision( name, owner, changeset_revision )
except Exception, e:
- error_message = 'Unable to find installed repository %s owned by %s: %s.' % ( name, owner, str( e ) )
+ error_message = 'Unable to find revision %s of repository %s owned by %s: %s.' % \
+ ( changeset_revision, name, owner, str( e ) )
log.exception( error_message )
- test_result = dict( tool_shed=install_and_test_base_util.galaxy_tool_shed_url,
- name=name,
- owner=owner,
- changeset_revision=changeset_revision,
- error_message=error_message )
- tool_test_results_dict[ 'installation_errors' ][ 'repository_dependencies' ].append( test_result )
- params = dict( tools_functionally_correct=False,
- test_install_error=True,
+ params = dict( test_install_error=True,
do_not_test=False )
# TODO: do something useful with response_dict
response_dict = install_and_test_base_util.register_test_result( install_and_test_base_util.galaxy_tool_shed_url,
@@ -263,18 +261,23 @@
( changeset_revision, name, owner, str( e ) ) )
# Clean out any generated tests. This is necessary for Twill.
remove_generated_tests( app )
- results_dict[ 'repositories_failed_install' ].append( repository_identifier_dict )
- log.debug( 'Repository %s failed to install correctly.' % str( name ) )
+ install_and_test_statistics_dict[ 'repositories_with_installation_error' ].append( repository_identifier_dict )
+ log.debug( 'Installation succeeded for revision %s of repository %s owned by %s.' % \
+ ( changeset_revision, name, owner ) )
else:
- # Configure and run functional tests for this repository. This is equivalent to sh run_functional_tests.sh -installed
- remove_install_tests()
- log.debug( 'Installation of %s succeeded, running all defined functional tests.' % str( repository.name ) )
- # Generate the shed_tools_dict that specifies the location of test data contained within this repository. If the repository
- # does not have a test-data directory, this will return has_test_data = False, and we will set the do_not_test flag to True,
- # and the tools_functionally_correct flag to False, as well as updating tool_test_results.
- file( galaxy_shed_tools_dict, 'w' ).write( to_json_string( {} ) )
- has_test_data, shed_tools_dict = parse_tool_panel_config( galaxy_shed_tool_conf_file,
- from_json_string( file( galaxy_shed_tools_dict, 'r' ).read() ) )
+ log.debug( 'Installation succeeded for revision %s of repository %s owned by %s.' % \
+ ( changeset_revision, name, owner ) )
+ # Keep statistics for this repository's tool dependencies that resulted in installation errors.
+ for missing_tool_dependency in repository.missing_tool_dependencies:
+ name = str( missing_tool_dependency.name )
+ type = str( missing_tool_dependency.type )
+ version = str( missing_tool_dependency.version )
+ error_message = unicodify( missing_tool_dependency.error_message )
+ missing_tool_dependency_info_dict = dict( type=type,
+ name=name,
+ version=version,
+ error_message=error_message )
+ install_and_test_statistics_dict[ 'tool_dependencies_with_installation_error' ].append( missing_tool_dependency_info_dict )
# Add an empty 'missing_test_results' entry if it is missing from the tool_test_results_dict. The
# ~/tool_shed/scripts/check_repositories_for_functional_tests.py will have entered information in the
# 'missing_test_components' entry of the tool_test_results_dict dictionary for repositories that are
@@ -283,28 +286,40 @@
tool_test_results_dict[ 'missing_test_components' ] = []
missing_tool_dependencies = install_and_test_base_util.get_missing_tool_dependencies( repository )
if missing_tool_dependencies or repository.missing_repository_dependencies:
- results_dict = install_and_test_base_util.handle_missing_dependencies( app,
- repository,
- missing_tool_dependencies,
- repository_dict,
- tool_test_results_dicts,
- tool_test_results_dict,
- results_dict,
- can_update_tool_shed )
+ install_and_test_statistics_dict = \
+ install_and_test_base_util.handle_missing_dependencies( app,
+ repository,
+ missing_tool_dependencies,
+ repository_dict,
+ tool_test_results_dicts,
+ tool_test_results_dict,
+ install_and_test_statistics_dict,
+ can_update_tool_shed )
# Set the test_toolbox.toolbox module-level variable to the new app.toolbox.
test_toolbox.toolbox = app.toolbox
else:
+ # This repository and all of its dependencies were successfully installed.
+ install_and_test_statistics_dict[ 'successful_installations' ].append( repository_identifier_dict )
+ # Configure and run functional tests for this repository. This is equivalent to sh run_functional_tests.sh -installed
+ remove_install_tests()
+ log.debug( 'Installation of %s succeeded, running all defined functional tests.' % str( repository.name ) )
+ # Generate the shed_tools_dict that specifies the location of test data contained within this repository. If the repository
+ # does not have a test-data directory, this will return has_test_data = False, and we will set the do_not_test flag to True,
+ # and the tools_functionally_correct flag to False, as well as updating tool_test_results.
+ file( galaxy_shed_tools_dict, 'w' ).write( to_json_string( {} ) )
+ has_test_data, shed_tools_dict = parse_tool_panel_config( galaxy_shed_tool_conf_file,
+ from_json_string( file( galaxy_shed_tools_dict, 'r' ).read() ) )
# If the repository has a test-data directory we write the generated shed_tools_dict to a file, so the functional
# test framework can find it.
file( galaxy_shed_tools_dict, 'w' ).write( to_json_string( shed_tools_dict ) )
log.debug( 'Saved generated shed_tools_dict to %s\nContents: %s' % ( str( galaxy_shed_tools_dict ), str( shed_tools_dict ) ) )
try:
- results_dict = test_repository_tools( app,
- repository,
- repository_dict,
- tool_test_results_dicts,
- tool_test_results_dict,
- results_dict )
+ install_and_test_statistics_dict = test_repository_tools( app,
+ repository,
+ repository_dict,
+ tool_test_results_dicts,
+ tool_test_results_dict,
+ install_and_test_statistics_dict )
except Exception, e:
exception_message = 'Error executing tests for repository %s: %s' % ( name, str( e ) )
log.exception( exception_message )
@@ -321,10 +336,8 @@
repository_dict,
params,
can_update_tool_shed )
- results_dict[ 'at_least_one_test_failed' ].append( repository_identifier_dict )
- total_repositories_tested += 1
- results_dict[ 'total_repositories_tested' ] = total_repositories_tested
- return results_dict, error_message
+ install_and_test_statistics_dict[ 'at_least_one_test_failed' ].append( repository_identifier_dict )
+ return install_and_test_statistics_dict, error_message
def main():
if install_and_test_base_util.tool_shed_api_key is None:
@@ -535,35 +548,45 @@
persist=False )
now = time.strftime( "%Y-%m-%d %H:%M:%S" )
print "####################################################################################"
- print "# %s - running repository installation and testing script." % now
+ print "# %s - installation script for repositories containing tools started." % now
+ if not can_update_tool_shed:
+ print "# This run will not update the Tool Shed database."
print "####################################################################################"
- results_dict, error_message = install_and_test_repositories( app, galaxy_shed_tools_dict, galaxy_shed_tool_conf_file )
+ install_and_test_statistics_dict, error_message = \
+ install_and_test_repositories( app, galaxy_shed_tools_dict, galaxy_shed_tool_conf_file )
if error_message:
log.debug( error_message )
else:
- total_repositories_tested = results_dict[ 'total_repositories_tested' ]
- all_tests_passed = results_dict[ 'all_tests_passed' ]
- at_least_one_test_failed = results_dict[ 'at_least_one_test_failed' ]
- repositories_failed_install = results_dict[ 'repositories_failed_install' ]
+ total_repositories_processed = install_and_test_statistics_dict[ 'total_repositories_processed' ]
+ all_tests_passed = install_and_test_statistics_dict[ 'all_tests_passed' ]
+ at_least_one_test_failed = install_and_test_statistics_dict[ 'at_least_one_test_failed' ]
+ successful_installations = install_and_test_statistics_dict[ 'successful_installations' ]
+ repositories_with_installation_error = install_and_test_statistics_dict[ 'repositories_with_installation_error' ]
+ tool_dependencies_with_installation_error = install_and_test_statistics_dict[ 'tool_dependencies_with_installation_error' ]
now = time.strftime( "%Y-%m-%d %H:%M:%S" )
print "####################################################################################"
- print "# %s - repository installation and testing script completed." % now
- print "# Repository revisions tested: %s" % str( total_repositories_tested )
- if not can_update_tool_shed:
- print "# This run will not update the Tool Shed database."
- if total_repositories_tested > 0:
- if all_tests_passed:
- print '# ----------------------------------------------------------------------------------'
- print "# %d repositories successfully passed all functional tests:" % len( all_tests_passed )
- install_and_test_base_util.show_summary_output( all_tests_passed )
- if at_least_one_test_failed:
- print '# ----------------------------------------------------------------------------------'
- print "# %d repositories failed at least 1 functional test:" % len( at_least_one_test_failed )
- install_and_test_base_util.show_summary_output( at_least_one_test_failed )
- if repositories_failed_install:
- print '# ----------------------------------------------------------------------------------'
- print "# %d repositories have installation errors:" % len( repositories_failed_install )
- install_and_test_base_util.show_summary_output( repositories_failed_install )
+ print "# %s - installation script for repositories containing tools completed." % now
+ print "# Repository revisions processed: %s" % str( total_repositories_processed )
+ if successful_installations:
+ print "# ----------------------------------------------------------------------------------"
+ print "# The following %d revisions with all dependencies were successfully installed:" % len( successful_installations )
+ install_and_test_base_util.show_summary_output( successful_installations )
+ if all_tests_passed:
+ print '# ----------------------------------------------------------------------------------'
+ print "# %d repositories successfully passed all functional tests:" % len( all_tests_passed )
+ install_and_test_base_util.show_summary_output( all_tests_passed )
+ if at_least_one_test_failed:
+ print '# ----------------------------------------------------------------------------------'
+ print "# %d repositories failed at least 1 functional test:" % len( at_least_one_test_failed )
+ install_and_test_base_util.show_summary_output( at_least_one_test_failed )
+ if repositories_with_installation_error:
+ print '# ----------------------------------------------------------------------------------'
+ print "# %d repositories have installation errors:" % len( repositories_with_installation_error )
+ install_and_test_base_util.show_summary_output( repositories_with_installation_error )
+ if tool_dependencies_with_installation_error:
+ print "# ----------------------------------------------------------------------------------"
+ print "# The following %d tool dependencies have installation errors:" % len( tool_dependencies_with_installation_error )
+ install_and_test_base_util.show_summary_output( tool_dependencies_with_installation_error )
print "####################################################################################"
log.debug( "Shutting down..." )
# Gracefully shut down the embedded web server and UniverseApplication.
@@ -632,7 +655,8 @@
# Now delete the tests found in the previous loop.
del test_install_repositories.__dict__[ key ]
-def test_repository_tools( app, repository, repository_dict, tool_test_results_dicts, tool_test_results_dict, results_dict ):
+def test_repository_tools( app, repository, repository_dict, tool_test_results_dicts, tool_test_results_dict,
+ install_and_test_statistics_dict ):
"""Test tools contained in the received repository."""
name = str( repository.name )
owner = str( repository.owner )
@@ -685,7 +709,7 @@
failed_test_dicts = get_failed_test_dicts( result, from_tool_test=True )
tool_test_results_dict[ 'failed_tests' ] = failed_test_dicts
failed_repository_dict = repository_identifier_dict
- results_dict[ 'at_least_one_test_failed' ].append( failed_repository_dict )
+ install_and_test_statistics_dict[ 'at_least_one_test_failed' ].append( failed_repository_dict )
set_do_not_test = not is_latest_downloadable_revision( install_and_test_base_util.galaxy_tool_shed_url, repository_dict )
params = dict( tools_functionally_correct=False,
test_install_error=False,
@@ -708,7 +732,7 @@
remove_generated_tests( app )
# Set the test_toolbox.toolbox module-level variable to the new app.toolbox.
test_toolbox.toolbox = app.toolbox
- return results_dict
+ return install_and_test_statistics_dict
if __name__ == "__main__":
# The tool_test_results_dict should always have the following structure:
diff -r f1cb7f07af2c923d3f3be77a0ae0ccb25c6453a7 -r a950019c26a9189f145d4da87c589f64babaa8e2 test/install_and_test_tool_shed_repositories/tool_dependency_definitions/functional_tests.py
--- a/test/install_and_test_tool_shed_repositories/tool_dependency_definitions/functional_tests.py
+++ b/test/install_and_test_tool_shed_repositories/tool_dependency_definitions/functional_tests.py
@@ -73,10 +73,10 @@
test_framework = install_and_test_base_util.TOOL_DEPENDENCY_DEFINITIONS
def install_and_test_repositories( app, galaxy_shed_tools_dict, galaxy_shed_tool_conf_file ):
- results_dict = install_and_test_base_util.initialize_results_dict( test_framework )
+ install_and_test_statistics_dict = install_and_test_base_util.initialize_install_and_test_statistics_dict( test_framework )
error_message = ''
# Initialize a dictionary for the summary that will be printed to stdout.
- total_repositories_installed = results_dict[ 'total_repositories_installed' ]
+ total_repositories_processed = install_and_test_statistics_dict[ 'total_repositories_processed' ]
repositories_to_install, error_message = \
install_and_test_base_util.get_repositories_to_install( install_and_test_base_util.galaxy_tool_shed_url, test_framework )
if error_message:
@@ -161,27 +161,26 @@
params,
can_update_tool_shed )
log.debug( "Not testing revision %s of repository %s owned by %s because it is in the exclude list for this test run." % \
- ( changeset_revision, name, owner ) )
+ ( changeset_revision, name, owner ) )
else:
tool_test_results_dict = install_and_test_base_util.initialize_tool_tests_results_dict( app, tool_test_results_dict )
repository, error_message = install_and_test_base_util.install_repository( app, repository_dict )
+ install_and_test_statistics_dict[ 'total_repositories_processed' ] += 1
if error_message:
+ # The repository installation failed.
+ log.debug( 'Installation failed for revision %s of repository %s owned by %s.' % \
+ ( changeset_revision, name, owner ) )
+ install_and_test_statistics_dict[ 'repositories_with_installation_error' ].append( repository_identifier_dict )
tool_test_results_dict[ 'installation_errors' ][ 'current_repository' ] = error_message
# Even if the repository failed to install, execute the uninstall method, in case a dependency did succeed.
- log.debug( 'Attempting to uninstall repository %s owned by %s.' % ( name, owner ) )
+ log.debug( 'Attempting to uninstall revision %s of repository %s owned by %s.' % ( changeset_revision, name, owner ) )
try:
repository = test_db_util.get_installed_repository_by_name_owner_changeset_revision( name, owner, changeset_revision )
except Exception, e:
- error_message = 'Unable to find installed repository %s owned by %s: %s.' % ( name, owner, str( e ) )
+ error_message = 'Unable to find revision %s of repository %s owned by %s: %s.' % \
+ ( changeset_revision, name, owner, str( e ) )
log.exception( error_message )
- test_result = dict( tool_shed=install_and_test_base_util.galaxy_tool_shed_url,
- name=name,
- owner=owner,
- changeset_revision=changeset_revision,
- error_message=error_message )
- tool_test_results_dict[ 'installation_errors' ][ 'repository_dependencies' ].append( test_result )
- params = dict( tools_functionally_correct=False,
- test_install_error=True,
+ params = dict( test_install_error=True,
do_not_test=False )
# TODO: do something useful with response_dict
response_dict = install_and_test_base_util.register_test_result( install_and_test_base_util.galaxy_tool_shed_url,
@@ -196,22 +195,50 @@
except Exception, e:
log.exception( 'Error attempting to uninstall revision %s of repository %s owned by %s: %s' % \
( changeset_revision, name, owner, str( e ) ) )
- results_dict[ 'repositories_with_installation_error' ].append( repository_identifier_dict )
- log.debug( 'Repository %s failed to install correctly.' % str( name ) )
+ log.debug( 'Installation failed for revision %s of repository %s owned by %s.' % \
+ ( changeset_revision, name, owner ) )
else:
- log.debug( 'Installation of %s succeeded.' % str( repository.name ) )
+ log.debug( 'Installation succeeded for revision %s of repository %s owned by %s.' % \
+ ( changeset_revision, name, owner ) )
+ # Keep statistics for this repository's tool dependencies that resulted in installation errors.
+ for missing_tool_dependency in repository.missing_tool_dependencies:
+ name = str( missing_tool_dependency.name )
+ type = str( missing_tool_dependency.type )
+ version = str( missing_tool_dependency.version )
+ error_message = unicodify( missing_tool_dependency.error_message )
+ missing_tool_dependency_info_dict = dict( type=type,
+ name=name,
+ version=version,
+ error_message=error_message )
+ install_and_test_statistics_dict[ 'tool_dependencies_with_installation_error' ].append( missing_tool_dependency_info_dict )
+ # Attempt to uninstall this repository and all of its dependencies if its repository dependencies or
+ # tool dependencies resulted in an installation error.
missing_tool_dependencies = install_and_test_base_util.get_missing_tool_dependencies( repository )
if missing_tool_dependencies or repository.missing_repository_dependencies:
- results_dict = install_and_test_base_util.handle_missing_dependencies( app,
- repository,
- missing_tool_dependencies,
- repository_dict,
- tool_test_results_dicts,
- tool_test_results_dict,
- results_dict,
- can_update_tool_shed )
- results_dict[ 'total_repositories_installed' ] = total_repositories_installed
- return results_dict, error_message
+ install_and_test_base_util.handle_missing_dependencies( app,
+ repository,
+ missing_tool_dependencies,
+ repository_dict,
+ tool_test_results_dicts,
+ tool_test_results_dict,
+ install_and_test_statistics_dict,
+ can_update_tool_shed )
+ else:
+ # This repository and all of its dependencies were successfully installed.
+ install_and_test_statistics_dict[ 'successful_installations' ].append( repository_identifier_dict )
+ tool_test_results_dict[ 'passed_tests' ].append( repository_identifier_dict )
+ params = dict( test_install_error=False,
+ do_not_test=False )
+ # TODO: do something useful with response_dict
+ response_dict = install_and_test_base_util.register_test_result( install_and_test_base_util.galaxy_tool_shed_url,
+ tool_test_results_dicts,
+ tool_test_results_dict,
+ repository_dict,
+ params,
+ can_update_tool_shed )
+
+ install_and_test_statistics_dict[ 'total_repositories_processed' ] = total_repositories_processed
+ return install_and_test_statistics_dict, error_message
def main():
if install_and_test_base_util.tool_shed_api_key is None:
@@ -419,28 +446,34 @@
persist=False )
now = time.strftime( "%Y-%m-%d %H:%M:%S" )
print "####################################################################################"
- print "# %s - running repository installation and testing script." % now
+ print "# %s - installation script for repositories of type tool_dependency_definition started." % now
+ if not can_update_tool_shed:
+ print "# This run will not update the Tool Shed database."
print "####################################################################################"
- results_dict, error_message = install_and_test_repositories( app, galaxy_shed_tools_dict, galaxy_shed_tool_conf_file )
+ install_and_test_statistics_dict, error_message = \
+ install_and_test_repositories( app, galaxy_shed_tools_dict, galaxy_shed_tool_conf_file )
if error_message:
log.debug( error_message )
else:
- total_repositories_installed = results_dict[ 'total_repositories_installed' ]
- repositories_with_installation_error = results_dict[ 'repositories_with_installation_error' ]
- tool_dependencies_with_installation_error = results_dict[ 'tool_dependencies_with_installation_error' ]
+ total_repositories_processed = install_and_test_statistics_dict[ 'total_repositories_processed' ]
+ successful_installations = install_and_test_statistics_dict[ 'successful_installations' ]
+ repositories_with_installation_error = install_and_test_statistics_dict[ 'repositories_with_installation_error' ]
+ tool_dependencies_with_installation_error = install_and_test_statistics_dict[ 'tool_dependencies_with_installation_error' ]
now = time.strftime( "%Y-%m-%d %H:%M:%S" )
print "####################################################################################"
- print "# %s - repository installation and testing script completed." % now
- print "# Repository revisions tested: %s" % str( total_repositories_installed )
- if not can_update_tool_shed:
- print "# This run will not update the Tool Shed database."
+ print "# %s - installation script for repositories of type tool_dependency_definition completed." % now
+ print "# Repository revisions processed: %s" % str( total_repositories_processed )
+ if successful_installations:
+ print "# ----------------------------------------------------------------------------------"
+ print "# The following %d revisions with all dependencies were successfully installed:" % len( successful_installations )
+ install_and_test_base_util.show_summary_output( successful_installations )
if repositories_with_installation_error:
- print '# ----------------------------------------------------------------------------------'
- print "# %d repositories have installation errors:" % len( repositories_with_installation_error )
+ print "# ----------------------------------------------------------------------------------"
+ print "# The following %d revisions have installation errors:" % len( repositories_with_installation_error )
install_and_test_base_util.show_summary_output( repositories_with_installation_error )
if tool_dependencies_with_installation_error:
- print '# ----------------------------------------------------------------------------------'
- print "# %d tool dependencies have installation errors:" % len( tool_dependencies_with_installation_error )
+ print "# ----------------------------------------------------------------------------------"
+ print "# The following %d tool dependencies have installation errors:" % len( tool_dependencies_with_installation_error )
install_and_test_base_util.show_summary_output( tool_dependencies_with_installation_error )
print "####################################################################################"
log.debug( "Shutting down..." )
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/f1cb7f07af2c/
Changeset: f1cb7f07af2c
User: jmchilton
Date: 2013-12-18 21:59:11
Summary: Use get_history() in tools API controller.
Affected #: 1 file
diff -r 0b2676366a82d61b5e46f4cae6a235e643548f78 -r f1cb7f07af2c923d3f3be77a0ae0ccb25c6453a7 lib/galaxy/webapps/galaxy/api/tools.py
--- a/lib/galaxy/webapps/galaxy/api/tools.py
+++ b/lib/galaxy/webapps/galaxy/api/tools.py
@@ -1,7 +1,7 @@
import urllib
from galaxy import web, util
-from galaxy.web.base.controller import BaseAPIController, UsesHistoryDatasetAssociationMixin, UsesVisualizationMixin
+from galaxy.web.base.controller import BaseAPIController, UsesHistoryDatasetAssociationMixin, UsesVisualizationMixin, UsesHistoryMixin
from galaxy.visualization.genomes import GenomeRegion
from galaxy.util.json import to_json_string, from_json_string
from galaxy.visualization.data_providers.genome import *
@@ -10,7 +10,7 @@
log = logging.getLogger( __name__ )
-class ToolsController( BaseAPIController, UsesVisualizationMixin ):
+class ToolsController( BaseAPIController, UsesVisualizationMixin, UsesHistoryMixin ):
"""
RESTful controller for interactions with tools.
"""
@@ -86,8 +86,7 @@
# dataset upload.
history_id = payload.get("history_id", None)
if history_id:
- target_history = trans.sa_session.query(trans.app.model.History).get(
- trans.security.decode_id(history_id))
+ target_history = self.get_history( trans, history_id )
else:
target_history = None
https://bitbucket.org/galaxy/galaxy-central/commits/26da838b778c/
Changeset: 26da838b778c
Branch: stable
User: jmchilton
Date: 2013-12-18 21:59:11
Summary: Use get_history() in tools API controller.
Affected #: 1 file
diff -r e059c6607f34b603e92e85cf0113b7b9b9635571 -r 26da838b778c68a5577d4cca9836f6ef70b8ed1b lib/galaxy/webapps/galaxy/api/tools.py
--- a/lib/galaxy/webapps/galaxy/api/tools.py
+++ b/lib/galaxy/webapps/galaxy/api/tools.py
@@ -1,7 +1,7 @@
import urllib
from galaxy import web, util
-from galaxy.web.base.controller import BaseAPIController, UsesHistoryDatasetAssociationMixin, UsesVisualizationMixin
+from galaxy.web.base.controller import BaseAPIController, UsesHistoryDatasetAssociationMixin, UsesVisualizationMixin, UsesHistoryMixin
from galaxy.visualization.genomes import GenomeRegion
from galaxy.util.json import to_json_string, from_json_string
from galaxy.visualization.data_providers.genome import *
@@ -9,7 +9,7 @@
import logging
log = logging.getLogger( __name__ )
-class ToolsController( BaseAPIController, UsesVisualizationMixin ):
+class ToolsController( BaseAPIController, UsesVisualizationMixin, UsesHistoryMixin ):
"""
RESTful controller for interactions with tools.
"""
@@ -85,8 +85,7 @@
# dataset upload.
history_id = payload.get("history_id", None)
if history_id:
- target_history = trans.sa_session.query(trans.app.model.History).get(
- trans.security.decode_id(history_id))
+ target_history = self.get_history( trans, history_id )
else:
target_history = None
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/0bb5714cb801/
Changeset: 0bb5714cb801
User: lepsiobec
Date: 2013-12-18 19:59:20
Summary: aiding security flaw with downloading datasets in archives
Affected #: 1 file
diff -r cbd1387437ceba5be9b47dcbf9eb951086e410a1 -r 0bb5714cb8012515824fd3e435b683afd554cdd2 lib/galaxy/webapps/galaxy/controllers/library_common.py
--- a/lib/galaxy/webapps/galaxy/controllers/library_common.py
+++ b/lib/galaxy/webapps/galaxy/controllers/library_common.py
@@ -18,7 +18,7 @@
from galaxy.util import inflector
from galaxy.util.json import to_json_string, from_json_string
from galaxy.util.streamball import StreamBall
-from galaxy.web.base.controller import BaseUIController, UsesFormDefinitionsMixin, UsesExtendedMetadataMixin
+from galaxy.web.base.controller import BaseUIController, UsesFormDefinitionsMixin, UsesExtendedMetadataMixin, UsesLibraryMixinItems
from galaxy.web.form_builder import AddressField, CheckboxField, SelectField, build_select_field
from galaxy.model.orm import and_, eagerload_all
@@ -65,7 +65,7 @@
except:
pass
-class LibraryCommon( BaseUIController, UsesFormDefinitionsMixin, UsesExtendedMetadataMixin ):
+class LibraryCommon( BaseUIController, UsesFormDefinitionsMixin, UsesExtendedMetadataMixin, UsesLibraryMixinItems ):
@web.json
def library_item_updates( self, trans, ids=None, states=None ):
# Avoid caching
@@ -1750,7 +1750,8 @@
ldda_ids = util.listify( ldda_ids )
for ldda_id in ldda_ids:
try:
- ldda = trans.sa_session.query( trans.app.model.LibraryDatasetDatasetAssociation ).get( trans.security.decode_id( ldda_id ) )
+ # Load the ldda requested and check whether the user has access to them
+ ldda = self.get_library_dataset_dataset_association( trans, ldda_id )
assert not ldda.dataset.purged
lddas.append( ldda )
except:
https://bitbucket.org/galaxy/galaxy-central/commits/0b2676366a82/
Changeset: 0b2676366a82
User: lepsiobec
Date: 2013-12-18 20:08:19
Summary: Merge
Affected #: 1 file
diff -r 0bb5714cb8012515824fd3e435b683afd554cdd2 -r 0b2676366a82d61b5e46f4cae6a235e643548f78 install_and_test_tool_shed_repositories.sh
--- a/install_and_test_tool_shed_repositories.sh
+++ b/install_and_test_tool_shed_repositories.sh
@@ -13,6 +13,10 @@
# If the tool shed url is not specified in tool_sheds_conf.xml, GALAXY_INSTALL_TEST_TOOL_SHEDS_CONF must be set to
# a tool sheds configuration file that does specify that url or repository installation will fail.
+# This script accepts the command line option -w to select which set of tests to run. The default behavior is to test
+# first tool_dependency_definition repositories and then repositories with tools. Provide the value 'dependencies'
+# to test only tool_dependency_definition repositories or 'tools' to test only repositories with tools.
+
if [ -z $GALAXY_INSTALL_TEST_TOOL_SHED_API_KEY ] ; then
echo "This script requires the GALAXY_INSTALL_TEST_TOOL_SHED_API_KEY environment variable to be set and non-empty."
exit 1
@@ -39,14 +43,41 @@
fi
fi
-# Test installation of repositories of type tool_dependency_definition.
-python test/install_and_test_tool_shed_repositories/tool_dependency_definitions/functional_tests.py $* -v --with-nosehtml --html-report-file \
- test/install_and_test_tool_shed_repositories/tool_dependency_definitions/run_functional_tests.html \
- test/install_and_test_tool_shed_repositories/functional/test_install_repositories.py \
- test/functional/test_toolbox.py
+test_tool_dependency_definitions () {
+ # Test installation of repositories of type tool_dependency_definition.
+ python test/install_and_test_tool_shed_repositories/tool_dependency_definitions/functional_tests.py $* -v --with-nosehtml --html-report-file \
+ test/install_and_test_tool_shed_repositories/tool_dependency_definitions/run_functional_tests.html \
+ test/install_and_test_tool_shed_repositories/functional/test_install_repositories.py \
+ test/functional/test_toolbox.py
+}
-# Test installation of repositories that contain valid tools with defined functional tests and a test-data directory containing test files.
-#python test/install_and_test_tool_shed_repositories/repositories_with_tools/functional_tests.py $* -v --with-nosehtml --html-report-file \
-# test/install_and_test_tool_shed_repositories/repositories_with_tools/run_functional_tests.html \
-# test/install_and_test_tool_shed_repositories/functional/test_install_repositories.py \
-# test/functional/test_toolbox.py
+test_repositories_with_tools () {
+ # Test installation of repositories that contain valid tools with defined functional tests and a test-data directory containing test files.
+ python test/install_and_test_tool_shed_repositories/repositories_with_tools/functional_tests.py $* -v --with-nosehtml --html-report-file \
+ test/install_and_test_tool_shed_repositories/repositories_with_tools/run_functional_tests.html \
+ test/install_and_test_tool_shed_repositories/functional/test_install_repositories.py \
+ test/functional/test_toolbox.py
+}
+
+which='both'
+
+while getopts "w:" arg; do
+ case $arg in
+ w)
+ which=$OPTARG
+ ;;
+ esac
+done
+
+case $which in
+ dependencies)
+ test_tool_dependency_definitions
+ ;;
+ tools)
+ test_repositories_with_tools
+ ;;
+ *)
+ test_tool_dependency_definitions
+ test_repositories_with_tools
+ ;;
+esac
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: Add command line option to select which set of tests to run.
by commits-noreply@bitbucket.org 18 Dec '13
by commits-noreply@bitbucket.org 18 Dec '13
18 Dec '13
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/9c17939bb282/
Changeset: 9c17939bb282
User: inithello
Date: 2013-12-18 19:53:18
Summary: Add command line option to select which set of tests to run.
Affected #: 1 file
diff -r cbd1387437ceba5be9b47dcbf9eb951086e410a1 -r 9c17939bb28242a1532daf2c24c2920786b3502f install_and_test_tool_shed_repositories.sh
--- a/install_and_test_tool_shed_repositories.sh
+++ b/install_and_test_tool_shed_repositories.sh
@@ -13,6 +13,10 @@
# If the tool shed url is not specified in tool_sheds_conf.xml, GALAXY_INSTALL_TEST_TOOL_SHEDS_CONF must be set to
# a tool sheds configuration file that does specify that url or repository installation will fail.
+# This script accepts the command line option -w to select which set of tests to run. The default behavior is to test
+# first tool_dependency_definition repositories and then repositories with tools. Provide the value 'dependencies'
+# to test only tool_dependency_definition repositories or 'tools' to test only repositories with tools.
+
if [ -z $GALAXY_INSTALL_TEST_TOOL_SHED_API_KEY ] ; then
echo "This script requires the GALAXY_INSTALL_TEST_TOOL_SHED_API_KEY environment variable to be set and non-empty."
exit 1
@@ -39,14 +43,41 @@
fi
fi
-# Test installation of repositories of type tool_dependency_definition.
-python test/install_and_test_tool_shed_repositories/tool_dependency_definitions/functional_tests.py $* -v --with-nosehtml --html-report-file \
- test/install_and_test_tool_shed_repositories/tool_dependency_definitions/run_functional_tests.html \
- test/install_and_test_tool_shed_repositories/functional/test_install_repositories.py \
- test/functional/test_toolbox.py
+test_tool_dependency_definitions () {
+ # Test installation of repositories of type tool_dependency_definition.
+ python test/install_and_test_tool_shed_repositories/tool_dependency_definitions/functional_tests.py $* -v --with-nosehtml --html-report-file \
+ test/install_and_test_tool_shed_repositories/tool_dependency_definitions/run_functional_tests.html \
+ test/install_and_test_tool_shed_repositories/functional/test_install_repositories.py \
+ test/functional/test_toolbox.py
+}
-# Test installation of repositories that contain valid tools with defined functional tests and a test-data directory containing test files.
-#python test/install_and_test_tool_shed_repositories/repositories_with_tools/functional_tests.py $* -v --with-nosehtml --html-report-file \
-# test/install_and_test_tool_shed_repositories/repositories_with_tools/run_functional_tests.html \
-# test/install_and_test_tool_shed_repositories/functional/test_install_repositories.py \
-# test/functional/test_toolbox.py
+test_repositories_with_tools () {
+ # Test installation of repositories that contain valid tools with defined functional tests and a test-data directory containing test files.
+ python test/install_and_test_tool_shed_repositories/repositories_with_tools/functional_tests.py $* -v --with-nosehtml --html-report-file \
+ test/install_and_test_tool_shed_repositories/repositories_with_tools/run_functional_tests.html \
+ test/install_and_test_tool_shed_repositories/functional/test_install_repositories.py \
+ test/functional/test_toolbox.py
+}
+
+which='both'
+
+while getopts "w:" arg; do
+ case $arg in
+ w)
+ which=$OPTARG
+ ;;
+ esac
+done
+
+case $which in
+ dependencies)
+ test_tool_dependency_definitions
+ ;;
+ tools)
+ test_repositories_with_tools
+ ;;
+ *)
+ test_tool_dependency_definitions
+ test_repositories_with_tools
+ ;;
+esac
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: Another bugfix to the tool dependency cleaning script.
by commits-noreply@bitbucket.org 18 Dec '13
by commits-noreply@bitbucket.org 18 Dec '13
18 Dec '13
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/cbd1387437ce/
Changeset: cbd1387437ce
User: inithello
Date: 2013-12-18 19:14:24
Summary: Another bugfix to the tool dependency cleaning script.
Affected #: 1 file
diff -r d1b1558308dc1cbb8076d20a7b7d130ca4051e1d -r cbd1387437ceba5be9b47dcbf9eb951086e410a1 lib/tool_shed/scripts/clean_up_tool_dependency_directory.py
--- a/lib/tool_shed/scripts/clean_up_tool_dependency_directory.py
+++ b/lib/tool_shed/scripts/clean_up_tool_dependency_directory.py
@@ -11,10 +11,11 @@
else:
for content in os.listdir( args.tool_dependency_dir ):
print 'Deleting directory %s from %s.' % ( content, args.tool_dependency_dir )
- if os.path.isdir( content ):
- shutil.rmtree( os.path.join( args.tool_dependency_dir, content ) )
+ full_path = os.path.join( args.tool_dependency_dir, content )
+ if os.path.isdir( full_path ):
+ shutil.rmtree( full_path )
else:
- os.remove( content )
+ os.remove( full_path )
if __name__ == '__main__':
description = 'Clean out the configured tool dependency path, creating it if it does not exist.'
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: Fix error when attempting to remove a file.
by commits-noreply@bitbucket.org 18 Dec '13
by commits-noreply@bitbucket.org 18 Dec '13
18 Dec '13
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/d1b1558308dc/
Changeset: d1b1558308dc
User: inithello
Date: 2013-12-18 19:11:37
Summary: Fix error when attempting to remove a file.
Affected #: 1 file
diff -r c4c6e8ea9837d4aa4fbbf08a681fd0c72b34f5b6 -r d1b1558308dc1cbb8076d20a7b7d130ca4051e1d lib/tool_shed/scripts/clean_up_tool_dependency_directory.py
--- a/lib/tool_shed/scripts/clean_up_tool_dependency_directory.py
+++ b/lib/tool_shed/scripts/clean_up_tool_dependency_directory.py
@@ -9,9 +9,12 @@
os.mkdir( args.tool_dependency_dir )
return 0
else:
- for subdirectory in os.listdir( args.tool_dependency_dir ):
- print 'Deleting directory %s from %s.' % ( subdirectory, args.tool_dependency_dir )
- shutil.rmtree( os.path.join( args.tool_dependency_dir, subdirectory ) )
+ for content in os.listdir( args.tool_dependency_dir ):
+ print 'Deleting directory %s from %s.' % ( content, args.tool_dependency_dir )
+ if os.path.isdir( content ):
+ shutil.rmtree( os.path.join( args.tool_dependency_dir, content ) )
+ else:
+ os.remove( content )
if __name__ == '__main__':
description = 'Clean out the configured tool dependency path, creating it if it does not exist.'
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: Clean up maintenance scripts for the EC2 environment.
by commits-noreply@bitbucket.org 18 Dec '13
by commits-noreply@bitbucket.org 18 Dec '13
18 Dec '13
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/c4c6e8ea9837/
Changeset: c4c6e8ea9837
User: inithello
Date: 2013-12-18 18:07:49
Summary: Clean up maintenance scripts for the EC2 environment.
Affected #: 2 files
diff -r 356e0b061fb4c0500db7faf11de8bf5edb2f9c41 -r c4c6e8ea9837d4aa4fbbf08a681fd0c72b34f5b6 lib/tool_shed/scripts/clean_up_tool_dependency_directory.py
--- a/lib/tool_shed/scripts/clean_up_tool_dependency_directory.py
+++ b/lib/tool_shed/scripts/clean_up_tool_dependency_directory.py
@@ -4,55 +4,23 @@
import shutil
def main( args ):
- if not os.path.exists( args.basepath ):
- print 'Tool dependency path %s does not exist.' % str( args.basepath )
- return 1
- if args.delete:
- print 'Deleting contents of tool dependency path %s.' % args.basepath
- for node in os.listdir( args.basepath ):
- path = os.path.join( args.basepath, node )
- if os.path.isdir( path ):
- try:
- shutil.rmtree( path )
- print 'Deleted directory %s and all its contents.' % path
- except Exception, e:
- print 'Error deleting directory %s: %s' % ( path, str( e ) )
- pass
- elif os.path.isfile( path ):
- try:
- os.remove( path )
- print 'Deleted file %s.' % path
- except Exception, e:
- print 'Error deleting file %s: %s' % ( path, str( e ) )
- pass
- elif os.path.islink( path ):
- print 'Deleting symlink %s with target %s.' % ( path, os.path.realpath( path ) )
- try:
- os.remove( path )
- except Exception, e:
- print 'Error deleting symlink %s: %s' % ( path, str( e ) )
- pass
+ if not os.path.exists( args.tool_dependency_dir ):
+ print 'Tool dependency base path %s does not exist, creating.' % str( args.tool_dependency_dir )
+ os.mkdir( args.tool_dependency_dir )
+ return 0
else:
- print 'Tool dependency path %s contains the following files and directories:' % args.basepath
- for element in os.listdir( args.basepath ):
- print element
- return 0
+ for subdirectory in os.listdir( args.tool_dependency_dir ):
+ print 'Deleting directory %s from %s.' % ( subdirectory, args.tool_dependency_dir )
+ shutil.rmtree( os.path.join( args.tool_dependency_dir, subdirectory ) )
if __name__ == '__main__':
- description = 'Clean out or list the contents of the provided tool dependency path. Remove if '
- description += 'the --delete command line argument is provided.'
+ description = 'Clean out the configured tool dependency path, creating it if it does not exist.'
parser = argparse.ArgumentParser( description=description )
- parser.add_argument( '--delete',
- dest='delete',
- required=False,
- action='store_true',
- default=False,
- help='Whether to delete all folders and files or list them on exit.' )
- parser.add_argument( '--basepath',
- dest='basepath',
+ parser.add_argument( '--tool_dependency_dir',
+ dest='tool_dependency_dir',
required=True,
action='store',
metavar='name',
- help='The base path where tool dependencies are installed.' )
+ help='The base path where tool dependencies will be installed.' )
args = parser.parse_args()
sys.exit( main( args ) )
diff -r 356e0b061fb4c0500db7faf11de8bf5edb2f9c41 -r c4c6e8ea9837d4aa4fbbf08a681fd0c72b34f5b6 lib/tool_shed/scripts/show_tool_dependency_installation_dir_contents.py
--- /dev/null
+++ b/lib/tool_shed/scripts/show_tool_dependency_installation_dir_contents.py
@@ -0,0 +1,75 @@
+import argparse
+import os
+import sys
+
+new_path = [ os.path.join( os.getcwd(), "lib" ) ]
+new_path.extend( sys.path[ 1: ] )
+sys.path = new_path
+
+from galaxy import eggs
+eggs.require( "SQLAlchemy >= 0.4" )
+
+import galaxy.model
+import galaxy.model.tool_shed_install.mapping as install_mapper
+import galaxy.config as galaxy_config
+
+
+class CleanUpDependencyApplication( object ):
+ """Application that enables querying the database using the tool_shed_install model."""
+
+ def __init__( self, config ):
+ self.config = config
+ # Setup the database engine and ORM
+ self.model = install_mapper.init( self.config.database_connection, engine_options={}, create_tables=False )
+
+ @property
+ def sa_session( self ):
+ """Returns a SQLAlchemy session."""
+ return self.model.context.current
+
+ def shutdown( self ):
+ pass
+
+def main( args, app ):
+ if not os.path.exists( args.basepath ):
+ print 'Tool dependency base path %s does not exist.' % str( args.basepath )
+ return
+ print 'Checking tool dependency path %s' % args.basepath
+ tool_dependency_dirs = get_tool_dependency_dirs( app )
+ for tool_dependency_dir in tool_dependency_dirs:
+ path = os.path.join( args.basepath, tool_dependency_dir )
+ if os.path.exists( path ):
+ path_contents = os.listdir( path )
+ if len( path_contents ) > 0:
+ print 'Found non-empty tool dependency installation directory %s.' % path
+ print 'Directory has the following contents: \n %s' % '\n '.join( path_contents )
+
+def get_tool_dependency_dirs( app ):
+ dependency_paths = []
+ for tool_dependency in app.sa_session.query( galaxy.model.tool_shed_install.ToolDependency ).all():
+ dependency_paths.append( tool_dependency.installation_directory( app ) )
+ return dependency_paths
+
+if __name__ == '__main__':
+ description = 'Clean out or list the contents any tool dependency directory under the provided'
+ description += 'tool dependency path. Remove any non-empty directories found if the '
+ description += '--delete command line argument is provided.'
+ parser = argparse.ArgumentParser( description=description )
+ parser.add_argument( '--basepath',
+ dest='basepath',
+ required=True,
+ action='store',
+ metavar='name',
+ help='The base path where tool dependencies are installed.' )
+ parser.add_argument( '--dburi',
+ dest='dburi',
+ required=True,
+ action='store',
+ metavar='dburi',
+ help='The database URI to connect to.' )
+ args = parser.parse_args()
+ database_connection = args.dburi
+ config_dict = dict( database_connection=database_connection, tool_dependency_dir=args.basepath )
+ config = galaxy_config.Configuration( **config_dict )
+ app = CleanUpDependencyApplication( config )
+ sys.exit( main( args, 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