galaxy-commits
Threads by month
- ----- 2026 -----
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- 15302 discussions
commit/galaxy-central: Jeremy Goecks: Do not propagate keyboard events in JS editable text plugin; this prevents unwanted side effects with other elmements on the page using keyboard events.
by commits-noreply@bitbucket.org 25 Apr '14
by commits-noreply@bitbucket.org 25 Apr '14
25 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/de882c903511/
Changeset: de882c903511
User: Jeremy Goecks
Date: 2014-04-25 22:58:21
Summary: Do not propagate keyboard events in JS editable text plugin; this prevents unwanted side effects with other elmements on the page using keyboard events.
Affected #: 1 file
diff -r 986d7190844d5f7b68804242699a8049af80a937 -r de882c9035116eccd7563c9f89aec586a017ce2f static/scripts/galaxy.base.js
--- a/static/scripts/galaxy.base.js
+++ b/static/scripts/galaxy.base.js
@@ -356,6 +356,9 @@
// Enter key.
set_text($(this).val());
}
+
+ // Do not propogate event to avoid unwanted side effects.
+ e.stopPropagation();
});
}
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: martenson: data libraries: improved folder rendering flow
by commits-noreply@bitbucket.org 25 Apr '14
by commits-noreply@bitbucket.org 25 Apr '14
25 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/986d7190844d/
Changeset: 986d7190844d
User: martenson
Date: 2014-04-25 21:36:39
Summary: data libraries: improved folder rendering flow
Affected #: 8 files
diff -r 4fa2b864adca65df5ac73a3fa60e5a4d98b1461c -r 986d7190844d5f7b68804242699a8049af80a937 static/scripts/mvc/library/library-folderlist-view.js
--- a/static/scripts/mvc/library/library-folderlist-view.js
+++ b/static/scripts/mvc/library/library-folderlist-view.js
@@ -12,7 +12,6 @@
mod_library_folderrow_view) {
var FolderListView = Backbone.View.extend({
- // main element definition
el : '#folder_items_element',
// progress percentage
progress: 0,
@@ -32,29 +31,31 @@
},
initialize : function(options){
- var that = this;
- this.options = _.defaults(this.options || {}, options);
- this.collection = new mod_library_model.Folder();
+ this.options = _.defaults(this.options || {}, options);
+ this.collection = new mod_library_model.Folder();
+ // start to listen if someone adds a model to the collection
+ this.listenTo(this.collection, 'add', this.renderOne);
+ this.fetchFolder();
+ },
- // start to listen if someone adds a model to the collection
- this.listenTo(this.collection, 'add', this.addOne);
-
- this.folderContainer = new mod_library_model.FolderContainer({id: this.options.id});
- this.folderContainer.url = this.folderContainer.attributes.urlRoot + this.options.id + '/contents';
- this.folderContainer.fetch({
- success: function (folder_container) {
- that.render();
- var items = folder_container.get('folder').models;
- that.addAll(items);
- },
- error: function(model, response){
- if (typeof response.responseJSON !== "undefined"){
- mod_toastr.error(response.responseJSON.err_msg);
- } else {
- mod_toastr.error('An error ocurred :(');
- }
+ fetchFolder: function(){
+ var that = this;
+ this.folderContainer = new mod_library_model.FolderContainer({id: this.options.id});
+ this.folderContainer.url = this.folderContainer.attributes.urlRoot + this.options.id + '/contents';
+ this.folderContainer.fetch({
+ success: function(folder_container) {
+ that.folder_container = folder_container;
+ that.render();
+ that.addAll(folder_container.get('folder').models)
+ },
+ error: function(model, response){
+ if (typeof response.responseJSON !== "undefined"){
+ mod_toastr.error(response.responseJSON.err_msg);
+ } else {
+ mod_toastr.error('An error ocurred :(');
}
- });
+ }
+ });
},
render: function (options) {
@@ -83,16 +84,33 @@
$("#center").css('overflow','auto');
},
- /** Adds all given models to the collection. */
- addAll:function(items){
- _.each(items.reverse(), function(item) {
- Galaxy.libraries.folderListView.collection.add(item);
+ /**
+ * Adds all given models to the collection.
+ * @param {array of Item or FolderAsModel} array of models that should
+ * be added to the view's collection.
+ */
+ addAll: function(models){
+ _.each(models.reverse(), function(model) {
+ Galaxy.libraries.folderListView.collection.add(model);
});
this.checkEmptiness();
},
- /** Creates a view for the given model and adds it to the folder view. */
- addOne: function(model){
+ /**
+ * Renders whole collection of models as views
+ */
+ renderAll: function(){
+ var that = this;
+ _.each(this.collection.models.reverse(), function(model) {
+ that.renderOne(model);
+ });
+ },
+
+ /**
+ * Creates a view for the given model and adds it to the folder view.
+ * @param {Item or FolderAsModel} model of the view that will be rendered
+ */
+ renderOne: function(model){
if (model.get('data_type') !== 'folder'){
this.options.contains_file = true;
model.set('readable_size', this.size_to_string(model.get('file_size')));
@@ -124,34 +142,42 @@
this.sort = 'asc';
}
this.render();
+ this.renderAll();
},
- /** Sorts the underlying collection according to the parameters received.
- * Currently supports only sorting by name. */
+ /**
+ * Sorts the underlying collection according to the parameters received.
+ * Currently supports only sorting by name.
+ */
sortFolder: function(sort_by, order){
if (sort_by === 'name'){
if (order === 'asc'){
- this.collection.sortByNameAsc();
+ return this.collection.sortByNameAsc();
} else if (order === 'desc'){
- this.collection.sortByNameDesc();
+ return this.collection.sortByNameDesc();
}
}
},
- /** convert size to nice string */
+ /**
+ * convert size to nice string
+ * @param {int} size
+ * @return {string} readable representation of size with units
+ */
size_to_string : function (size){
- // identify unit
var unit = "";
if (size >= 100000000000) { size = size / 100000000000; unit = "TB"; } else
if (size >= 100000000) { size = size / 100000000; unit = "GB"; } else
if (size >= 100000) { size = size / 100000; unit = "MB"; } else
if (size >= 100) { size = size / 100; unit = "KB"; } else
{ size = size * 10; unit = "b"; }
- // return formatted string
return (Math.round(size) / 10) + unit;
},
- /** User clicked the checkbox in the table heading */
+ /**
+ * User clicked the checkbox in the table heading
+ * @param {context} event
+ */
selectAll : function (event) {
var selected = event.target.checked;
that = this;
@@ -168,8 +194,10 @@
});
},
- /** Check checkbox if user clicks on the whole row or
- * on the checkbox itself */
+ /**
+ * Check checkbox if user clicks on the whole row or
+ * on the checkbox itself
+ */
selectClickedRow : function (event) {
var checkbox = '';
var $row;
diff -r 4fa2b864adca65df5ac73a3fa60e5a4d98b1461c -r 986d7190844d5f7b68804242699a8049af80a937 static/scripts/mvc/library/library-foldertoolbar-view.js
--- a/static/scripts/mvc/library/library-foldertoolbar-view.js
+++ b/static/scripts/mvc/library/library-foldertoolbar-view.js
@@ -396,14 +396,15 @@
tmpl_array.push('<div class="library_style_container">');
tmpl_array.push('<h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');
// TOOLBAR
- tmpl_array.push('<div id="library_folder_toolbar" >');
+ tmpl_array.push('<div id="library_folder_toolbar">');
+ tmpl_array.push('<span data-toggle="tooltip" data-placement="top" title="Include deleted datasets"><input id="include_deleted_datasets_chk" style="margin: 0;" type="checkbox"><span class="fa fa-trash-o fa-lg"></span></input></span>');
tmpl_array.push('<div class="btn-group">');
tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Create New Folder" id="toolbtn_create_folder" class="btn btn-default primary-button" type="button" style="display:none;"><span class="fa fa-plus"></span><span class="fa fa-folder"></span></button>');
tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Add Datasets to Current Folder" id="toolbtn_add_files" class="btn btn-default toolbtn_add_files primary-button" type="button" style="display:none;"><span class="fa fa-plus"></span><span class="fa fa-file"></span></span></button>');
tmpl_array.push('</div>');
tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Import selected datasets into history" id="toolbtn_bulk_import" class="primary-button" style="margin-left: 0.5em; " type="button"><span class="fa fa-book"></span> to history</button>');
tmpl_array.push(' <div id="toolbtn_dl" class="btn-group" style="margin-left: 0.5em; ">');
- tmpl_array.push(' <button title="Download selected datasets" id="drop_toggle" type="button" class="primary-button dropdown-toggle" data-toggle="dropdown">');
+ tmpl_array.push(' <button title="Download selected datasets as archive" id="drop_toggle" type="button" class="primary-button dropdown-toggle" data-toggle="dropdown">');
tmpl_array.push(' <span class="fa fa-download"></span> download <span class="caret"></span>');
tmpl_array.push(' </button>');
tmpl_array.push(' <ul class="dropdown-menu" role="menu">');
@@ -412,6 +413,7 @@
tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/zip">.zip</a></li>');
tmpl_array.push(' </ul>');
tmpl_array.push(' </div>');
+ tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Mark selected datasets deleted" id="toolbtn_bulk_delete" class="primary-button" style="margin-left: 0.5em; " type="button"><span class="fa fa-trash-o"></span> delete</button>');
tmpl_array.push(' </div>');
tmpl_array.push(' <div id="folder_items_element">');
// library items will append here
diff -r 4fa2b864adca65df5ac73a3fa60e5a4d98b1461c -r 986d7190844d5f7b68804242699a8049af80a937 static/scripts/mvc/library/library-librarytoolbar-view.js
--- a/static/scripts/mvc/library/library-librarytoolbar-view.js
+++ b/static/scripts/mvc/library/library-librarytoolbar-view.js
@@ -1,6 +1,9 @@
define([],
function() {
-
+/**
+ * This view represents the top part of the library page.
+ * It contains the tool bar with buttons.
+ */
var LibraryToolbarView = Backbone.View.extend({
el: '#center',
@@ -30,7 +33,7 @@
},
delegate_modal: function(event){
- // probably should refactor to have this functionality in this view, not in the library list view
+ // TODO probably should refactor to have this functionality in this view, not in the library list view
Galaxy.libraries.libraryListView.show_library_modal(event);
},
diff -r 4fa2b864adca65df5ac73a3fa60e5a4d98b1461c -r 986d7190844d5f7b68804242699a8049af80a937 static/scripts/packed/mvc/library/library-folderlist-view.js
--- a/static/scripts/packed/mvc/library/library-folderlist-view.js
+++ b/static/scripts/packed/mvc/library/library-folderlist-view.js
@@ -1,1 +1,1 @@
-define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model","mvc/library/library-folderrow-view"],function(c,e,f,d,a){var b=Backbone.View.extend({el:"#folder_items_element",progress:0,progressStep:1,modal:null,folderContainer:null,sort:"asc",events:{"click #select-all-checkboxes":"selectAll","click .dataset_row":"selectClickedRow","click .sort-folder-link":"sort_clicked"},initialize:function(g){var h=this;this.options=_.defaults(this.options||{},g);this.collection=new d.Folder();this.listenTo(this.collection,"add",this.addOne);this.folderContainer=new d.FolderContainer({id:this.options.id});this.folderContainer.url=this.folderContainer.attributes.urlRoot+this.options.id+"/contents";this.folderContainer.fetch({success:function(i){h.render();var j=i.get("folder").models;h.addAll(j)},error:function(j,i){if(typeof i.responseJSON!=="undefined"){f.error(i.responseJSON.err_msg)}else{f.error("An error ocurred :(")}}})},render:function(g){this.options=_.defaults(this.options||{},g);var i=this.templateFolder();var j=this.folderContainer.attributes.metadata.full_path;var k;if(j.length===1){k=0}else{k=j[j.length-2][0]}this.$el.html(i({path:this.folderContainer.attributes.metadata.full_path,id:this.options.id,upper_folder_id:k,order:this.sort}));var h=this.folderContainer.attributes.metadata;h.contains_file=this.options.contains_file;Galaxy.libraries.folderToolbarView.configureElements(h);$("#center [data-toggle]").tooltip();$("#center").css("overflow","auto")},addAll:function(g){_.each(g.reverse(),function(h){Galaxy.libraries.folderListView.collection.add(h)});this.checkEmptiness()},addOne:function(h){if(h.get("data_type")!=="folder"){this.options.contains_file=true;h.set("readable_size",this.size_to_string(h.get("file_size")))}var g=new a.FolderRowView(h);this.$el.find("#first_folder_item").after(g.el);this.checkEmptiness()},checkEmptiness:function(){if((this.$el.find(".dataset_row").length===0)&&(this.$el.find(".folder_row").length===0)){var g=this.templateEmptyFolder();this.$el.find("#folder_list_body").append(g())}else{this.$el.find("#empty_folder_message").remove()}},sort_clicked:function(g){g.preventDefault();if(this.sort==="asc"){this.sortFolder("name","desc");this.sort="desc"}else{this.sortFolder("name","asc");this.sort="asc"}this.render()},sortFolder:function(h,g){if(h==="name"){if(g==="asc"){this.collection.sortByNameAsc()}else{if(g==="desc"){this.collection.sortByNameDesc()}}}},size_to_string:function(g){var h="";if(g>=100000000000){g=g/100000000000;h="TB"}else{if(g>=100000000){g=g/100000000;h="GB"}else{if(g>=100000){g=g/100000;h="MB"}else{if(g>=100){g=g/100;h="KB"}else{g=g*10;h="b"}}}}return(Math.round(g)/10)+h},selectAll:function(h){var g=h.target.checked;that=this;$(":checkbox").each(function(){this.checked=g;$row=$(this.parentElement.parentElement);if(g){that.makeDarkRow($row)}else{that.makeWhiteRow($row)}})},selectClickedRow:function(h){var j="";var g;var i;if(h.target.localName==="input"){j=h.target;g=$(h.target.parentElement.parentElement);i="input"}else{if(h.target.localName==="td"){j=$("#"+h.target.parentElement.id).find(":checkbox")[0];g=$(h.target.parentElement);i="td"}}if(j.checked){if(i==="td"){j.checked="";this.makeWhiteRow(g)}else{if(i==="input"){this.makeDarkRow(g)}}}else{if(i==="td"){j.checked="selected";this.makeDarkRow(g)}else{if(i==="input"){this.makeWhiteRow(g)}}}},makeDarkRow:function(g){g.removeClass("light");g.find("a").removeClass("light");g.addClass("dark");g.find("a").addClass("dark");g.find("span").removeClass("fa-file-o");g.find("span").addClass("fa-file")},makeWhiteRow:function(g){g.removeClass("dark");g.find("a").removeClass("dark");g.addClass("light");g.find("a").addClass("light");g.find("span").addClass("fa-file-o");g.find("span").removeClass("fa-file")},templateFolder:function(){var g=[];g.push('<ol class="breadcrumb">');g.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');g.push(" <% _.each(path, function(path_item) { %>");g.push(" <% if (path_item[0] != id) { %>");g.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');g.push("<% } else { %>");g.push(' <li class="active"><span title="You are in this folder"><%- path_item[1] %></span></li>');g.push(" <% } %>");g.push(" <% }); %>");g.push("</ol>");g.push('<table id="folder_table" class="grid table table-condensed">');g.push(" <thead>");g.push(' <th class="button_heading"></th>');g.push(' <th style="text-align: center; width: 20px; " title="Check to select all datasets"><input id="select-all-checkboxes" style="margin: 0;" type="checkbox"></th>');g.push(' <th><a class="sort-folder-link" title="Click to reverse order" href="#">name</a><span title="Sorted alphabetically" class="fa fa-sort-alpha-<%- order %>"></span></th>');g.push(" <th>data type</th>");g.push(" <th>size</th>");g.push(" <th>time updated (UTC)</th>");g.push(" </thead>");g.push(' <tbody id="folder_list_body">');g.push(' <tr id="first_folder_item">');g.push(' <td><a href="#<% if (upper_folder_id !== 0){ print("folders/" + upper_folder_id)} %>" title="Go to parent folder" class="btn_open_folder btn btn-default btn-xs">..<a></td>');g.push(" <td></td>");g.push(" <td></td>");g.push(" <td></td>");g.push(" <td></td>");g.push(" <td></td>");g.push(" </tr>");g.push(" </tbody>");g.push("</table>");return _.template(g.join(""))},templateEmptyFolder:function(){var g=[];g.push('<tr id="empty_folder_message">');g.push('<td colspan="6" style="text-align:center">');g.push("This folder is either empty or you do not have proper access permissions to see the contents.");g.push("</td>");g.push("</tr>");return _.template(g.join(""))}});return{FolderListView:b}});
\ No newline at end of file
+define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model","mvc/library/library-folderrow-view"],function(c,e,f,d,a){var b=Backbone.View.extend({el:"#folder_items_element",progress:0,progressStep:1,modal:null,folderContainer:null,sort:"asc",events:{"click #select-all-checkboxes":"selectAll","click .dataset_row":"selectClickedRow","click .sort-folder-link":"sort_clicked"},initialize:function(g){this.options=_.defaults(this.options||{},g);this.collection=new d.Folder();this.listenTo(this.collection,"add",this.renderOne);this.fetchFolder()},fetchFolder:function(){var g=this;this.folderContainer=new d.FolderContainer({id:this.options.id});this.folderContainer.url=this.folderContainer.attributes.urlRoot+this.options.id+"/contents";this.folderContainer.fetch({success:function(h){g.folder_container=h;g.render();g.addAll(h.get("folder").models)},error:function(i,h){if(typeof h.responseJSON!=="undefined"){f.error(h.responseJSON.err_msg)}else{f.error("An error ocurred :(")}}})},render:function(g){this.options=_.defaults(this.options||{},g);var i=this.templateFolder();var j=this.folderContainer.attributes.metadata.full_path;var k;if(j.length===1){k=0}else{k=j[j.length-2][0]}this.$el.html(i({path:this.folderContainer.attributes.metadata.full_path,id:this.options.id,upper_folder_id:k,order:this.sort}));var h=this.folderContainer.attributes.metadata;h.contains_file=this.options.contains_file;Galaxy.libraries.folderToolbarView.configureElements(h);$("#center [data-toggle]").tooltip();$("#center").css("overflow","auto")},addAll:function(g){_.each(g.reverse(),function(h){Galaxy.libraries.folderListView.collection.add(h)});this.checkEmptiness()},renderAll:function(){var g=this;_.each(this.collection.models.reverse(),function(h){g.renderOne(h)})},renderOne:function(h){if(h.get("data_type")!=="folder"){this.options.contains_file=true;h.set("readable_size",this.size_to_string(h.get("file_size")))}var g=new a.FolderRowView(h);this.$el.find("#first_folder_item").after(g.el);this.checkEmptiness()},checkEmptiness:function(){if((this.$el.find(".dataset_row").length===0)&&(this.$el.find(".folder_row").length===0)){var g=this.templateEmptyFolder();this.$el.find("#folder_list_body").append(g())}else{this.$el.find("#empty_folder_message").remove()}},sort_clicked:function(g){g.preventDefault();if(this.sort==="asc"){this.sortFolder("name","desc");this.sort="desc"}else{this.sortFolder("name","asc");this.sort="asc"}this.render();this.renderAll()},sortFolder:function(h,g){if(h==="name"){if(g==="asc"){return this.collection.sortByNameAsc()}else{if(g==="desc"){return this.collection.sortByNameDesc()}}}},size_to_string:function(g){var h="";if(g>=100000000000){g=g/100000000000;h="TB"}else{if(g>=100000000){g=g/100000000;h="GB"}else{if(g>=100000){g=g/100000;h="MB"}else{if(g>=100){g=g/100;h="KB"}else{g=g*10;h="b"}}}}return(Math.round(g)/10)+h},selectAll:function(h){var g=h.target.checked;that=this;$(":checkbox").each(function(){this.checked=g;$row=$(this.parentElement.parentElement);if(g){that.makeDarkRow($row)}else{that.makeWhiteRow($row)}})},selectClickedRow:function(h){var j="";var g;var i;if(h.target.localName==="input"){j=h.target;g=$(h.target.parentElement.parentElement);i="input"}else{if(h.target.localName==="td"){j=$("#"+h.target.parentElement.id).find(":checkbox")[0];g=$(h.target.parentElement);i="td"}}if(j.checked){if(i==="td"){j.checked="";this.makeWhiteRow(g)}else{if(i==="input"){this.makeDarkRow(g)}}}else{if(i==="td"){j.checked="selected";this.makeDarkRow(g)}else{if(i==="input"){this.makeWhiteRow(g)}}}},makeDarkRow:function(g){g.removeClass("light");g.find("a").removeClass("light");g.addClass("dark");g.find("a").addClass("dark");g.find("span").removeClass("fa-file-o");g.find("span").addClass("fa-file")},makeWhiteRow:function(g){g.removeClass("dark");g.find("a").removeClass("dark");g.addClass("light");g.find("a").addClass("light");g.find("span").addClass("fa-file-o");g.find("span").removeClass("fa-file")},templateFolder:function(){var g=[];g.push('<ol class="breadcrumb">');g.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');g.push(" <% _.each(path, function(path_item) { %>");g.push(" <% if (path_item[0] != id) { %>");g.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');g.push("<% } else { %>");g.push(' <li class="active"><span title="You are in this folder"><%- path_item[1] %></span></li>');g.push(" <% } %>");g.push(" <% }); %>");g.push("</ol>");g.push('<table id="folder_table" class="grid table table-condensed">');g.push(" <thead>");g.push(' <th class="button_heading"></th>');g.push(' <th style="text-align: center; width: 20px; " title="Check to select all datasets"><input id="select-all-checkboxes" style="margin: 0;" type="checkbox"></th>');g.push(' <th><a class="sort-folder-link" title="Click to reverse order" href="#">name</a><span title="Sorted alphabetically" class="fa fa-sort-alpha-<%- order %>"></span></th>');g.push(" <th>data type</th>");g.push(" <th>size</th>");g.push(" <th>time updated (UTC)</th>");g.push(" </thead>");g.push(' <tbody id="folder_list_body">');g.push(' <tr id="first_folder_item">');g.push(' <td><a href="#<% if (upper_folder_id !== 0){ print("folders/" + upper_folder_id)} %>" title="Go to parent folder" class="btn_open_folder btn btn-default btn-xs">..<a></td>');g.push(" <td></td>");g.push(" <td></td>");g.push(" <td></td>");g.push(" <td></td>");g.push(" <td></td>");g.push(" </tr>");g.push(" </tbody>");g.push("</table>");return _.template(g.join(""))},templateEmptyFolder:function(){var g=[];g.push('<tr id="empty_folder_message">');g.push('<td colspan="6" style="text-align:center">');g.push("This folder is either empty or you do not have proper access permissions to see the contents.");g.push("</td>");g.push("</tr>");return _.template(g.join(""))}});return{FolderListView:b}});
\ No newline at end of file
diff -r 4fa2b864adca65df5ac73a3fa60e5a4d98b1461c -r 986d7190844d5f7b68804242699a8049af80a937 static/scripts/packed/mvc/library/library-foldertoolbar-view.js
--- a/static/scripts/packed/mvc/library/library-foldertoolbar-view.js
+++ b/static/scripts/packed/mvc/library/library-foldertoolbar-view.js
@@ -1,1 +1,1 @@
-define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model"],function(b,d,e,c){var a=Backbone.View.extend({el:"#center",events:{"click #toolbtn_create_folder":"createFolderFromModal","click #toolbtn_bulk_import":"modalBulkImport","click .toolbtn_add_files":"addFilesToFolderModal"},defaults:{can_add_library_item:false,contains_file:false,chain_call_control:{total_number:0,failed_number:0}},modal:null,histories:null,initialize:function(f){this.options=_.defaults(f||{},this.defaults);this.render()},render:function(f){this.options=_.extend(this.options,f);var h=this.templateToolBar();var g=false;if(Galaxy.currUser){g=Galaxy.currUser.isAdmin()}this.$el.html(h({id:this.options.id,admin_user:g}))},configureElements:function(f){this.options=_.extend(this.options,f);if(this.options.can_add_library_item===true){$("#toolbtn_create_folder").show();$(".toolbtn_add_files").show()}if(this.options.contains_file===true){$("#toolbtn_bulk_import").show();$("#toolbtn_dl").show()}this.$el.find("[data-toggle]").tooltip()},createFolderFromModal:function(){event.preventDefault();event.stopPropagation();var f=this;var g=this.templateNewFolderInModal();this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Create New Folder",body:g(),buttons:{Create:function(){f.create_new_folder_event()},Close:function(){Galaxy.modal.hide()}}})},create_new_folder_event:function(){var f=this.serialize_new_folder();if(this.validate_new_folder(f)){var g=new c.FolderAsModel();url_items=Backbone.history.fragment.split("/");current_folder_id=url_items[url_items.length-1];g.url=g.urlRoot+"/"+current_folder_id;g.save(f,{success:function(h){Galaxy.modal.hide();e.success("Folder created");h.set({type:"folder"});Galaxy.libraries.folderListView.collection.add(h)},error:function(i,h){Galaxy.modal.hide();if(typeof h.responseJSON!=="undefined"){e.error(h.responseJSON.err_msg)}else{e.error("An error ocurred :(")}}})}else{e.error("Folder's name is missing")}return false},serialize_new_folder:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val()}},validate_new_folder:function(f){return f.name!==""},modalBulkImport:function(){var f=$("#folder_table").find(":checked");if(f.length===0){e.info("You have to select some datasets first")}else{this.refreshUserHistoriesList(function(g){var h=g.templateBulkImportInModal();g.modal=Galaxy.modal;g.modal.show({closing_events:true,title:"Import into History",body:h({histories:g.histories.models}),buttons:{Import:function(){g.importAllIntoHistory()},Close:function(){Galaxy.modal.hide()}}})})}},refreshUserHistoriesList:function(g){var f=this;this.histories=new c.GalaxyHistories();this.histories.fetch({success:function(){g(f)},error:function(i,h){if(typeof h.responseJSON!=="undefined"){e.error(h.responseJSON.err_msg)}else{e.error("An error ocurred :(")}}})},importAllIntoHistory:function(){this.modal.disableButton("Import");this.options.chain_call_control.total_number=0;this.options.chain_call_control.failed_number=0;var j=$("select[name=dataset_import_bulk] option:selected").val();this.options.last_used_history_id=j;var m=$("select[name=dataset_import_bulk] option:selected").text();var o=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!==""){o.push(this.parentElement.parentElement.id)}});var n=this.templateImportIntoHistoryProgressBar();this.modal.$el.find(".modal-body").html(n({history_name:m}));var k=100/o.length;this.initProgress(k);var f=[];for(var g=o.length-1;g>=0;g--){var h=o[g];var l=new c.HistoryItem();l.url=l.urlRoot+j+"/contents";l.content=h;l.source="library";f.push(l)}this.options.chain_call_control.total_number=f.length;this.chainCall(f,m)},chainCall:function(g,j){var f=this;var h=g.pop();if(typeof h==="undefined"){if(this.options.chain_call_control.failed_number===0){e.success("Selected datasets imported into history")}else{if(this.options.chain_call_control.failed_number===this.options.chain_call_control.total_number){e.error("There was an error and no datasets were imported into history.")}else{if(this.options.chain_call_control.failed_number<this.options.chain_call_control.total_number){e.warning("Some of the datasets could not be imported into history")}}}Galaxy.modal.hide();return}var i=$.when(h.save({content:h.content,source:h.source}));i.done(function(){f.updateProgress();f.chainCall(g,j)}).fail(function(){f.options.chain_call_control.failed_number+=1;f.updateProgress();f.chainCall(g,j)})},initProgress:function(f){this.progress=0;this.progressStep=f},updateProgress:function(){this.progress+=this.progressStep;$(".progress-bar-import").width(Math.round(this.progress)+"%");txt_representation=Math.round(this.progress)+"% Complete";$(".completion_span").text(txt_representation)},download:function(f,j){var h=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!==""){h.push(this.parentElement.parentElement.id)}});var g="/api/libraries/datasets/download/"+j;var i={ldda_ids:h};this.processDownload(g,i,"get")},processDownload:function(g,h,i){if(g&&h){h=typeof h==="string"?h:$.param(h);var f="";$.each(h.split("&"),function(){var j=this.split("=");f+='<input type="hidden" name="'+j[0]+'" value="'+j[1]+'" />'});$('<form action="'+g+'" method="'+(i||"post")+'">'+f+"</form>").appendTo("body").submit().remove();e.info("Your download will begin soon")}},addFilesToFolderModal:function(){this.refreshUserHistoriesList(function(f){f.modal=Galaxy.modal;var g=f.templateAddFilesInModal();f.modal.show({closing_events:true,title:"Add datasets from history to "+f.options.folder_name,body:g({histories:f.histories.models}),buttons:{Add:function(){f.addAllDatasetsFromHistory()},Close:function(){Galaxy.modal.hide()}}});if(f.histories.models.length>0){f.fetchAndDisplayHistoryContents(f.histories.models[0].id);$("#dataset_add_bulk").change(function(h){f.fetchAndDisplayHistoryContents(h.target.value)})}else{e.error("An error ocurred :(")}})},fetchAndDisplayHistoryContents:function(h){var g=new c.HistoryContents({id:h});var f=this;g.fetch({success:function(j){var i=f.templateHistoryContents();f.histories.get(h).set({contents:j});f.modal.$el.find("#selected_history_content").html(i({history_contents:j.models.reverse()}))},error:function(){e.error("An error ocurred :(")}})},addAllDatasetsFromHistory:function(){this.modal.disableButton("Add");this.options.chain_call_control.total_number=0;this.options.chain_call_control.failed_number=0;var f=[];this.modal.$el.find("#selected_history_content").find(":checked").each(function(){var i=$(this.parentElement).data("id");if(i){f.push(i)}});var l=this.options.folder_name;var k=this.templateAddingDatasetsProgressBar();this.modal.$el.find(".modal-body").html(k({folder_name:l}));this.progressStep=100/f.length;this.progress=0;var j=[];for(var h=f.length-1;h>=0;h--){history_dataset_id=f[h];var g=new c.Item();g.url="/api/folders/"+this.options.id+"/contents";g.set({from_hda_id:history_dataset_id});j.push(g)}this.options.chain_call_control.total_number=j.length;this.chainCallAddingHdas(j)},chainCallAddingHdas:function(g){var f=this;this.added_hdas=new c.Folder();var h=g.pop();if(typeof h==="undefined"){if(this.options.chain_call_control.failed_number===0){e.success("Selected datasets from history added to the folder")}else{if(this.options.chain_call_control.failed_number===this.options.chain_call_control.total_number){e.error("There was an error and no datasets were added to the folder.")}else{if(this.options.chain_call_control.failed_number<this.options.chain_call_control.total_number){e.warning("Some of the datasets could not be added to the folder")}}}Galaxy.modal.hide();return this.added_hdas}var i=$.when(h.save({from_hda_id:h.get("from_hda_id")}));i.done(function(j){Galaxy.libraries.folderListView.collection.add(j);f.updateProgress();f.chainCallAddingHdas(g)}).fail(function(){f.options.chain_call_control.failed_number+=1;f.updateProgress();f.chainCallAddingHdas(g)})},templateToolBar:function(){tmpl_array=[];tmpl_array.push('<div class="library_style_container">');tmpl_array.push('<h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');tmpl_array.push('<div id="library_folder_toolbar" >');tmpl_array.push('<div class="btn-group">');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Create New Folder" id="toolbtn_create_folder" class="btn btn-default primary-button" type="button" style="display:none;"><span class="fa fa-plus"></span><span class="fa fa-folder"></span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Add Datasets to Current Folder" id="toolbtn_add_files" class="btn btn-default toolbtn_add_files primary-button" type="button" style="display:none;"><span class="fa fa-plus"></span><span class="fa fa-file"></span></span></button>');tmpl_array.push("</div>");tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Import selected datasets into history" id="toolbtn_bulk_import" class="primary-button" style="margin-left: 0.5em; " type="button"><span class="fa fa-book"></span> to history</button>');tmpl_array.push(' <div id="toolbtn_dl" class="btn-group" style="margin-left: 0.5em; ">');tmpl_array.push(' <button title="Download selected datasets" id="drop_toggle" type="button" class="primary-button dropdown-toggle" data-toggle="dropdown">');tmpl_array.push(' <span class="fa fa-download"></span> download <span class="caret"></span>');tmpl_array.push(" </button>");tmpl_array.push(' <ul class="dropdown-menu" role="menu">');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/tgz">.tar.gz</a></li>');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/tbz">.tar.bz</a></li>');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/zip">.zip</a></li>');tmpl_array.push(" </ul>");tmpl_array.push(" </div>");tmpl_array.push(" </div>");tmpl_array.push(' <div id="folder_items_element">');tmpl_array.push(" </div>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateNewFolderInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_folder_modal">');tmpl_array.push("<form>");tmpl_array.push('<input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push('<input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push("</form>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateBulkImportInModal:function(){var f=[];f.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');f.push("Select history: ");f.push('<select id="dataset_import_bulk" name="dataset_import_bulk" style="width:50%; margin-bottom: 1em; "> ');f.push(" <% _.each(histories, function(history) { %>");f.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');f.push(" <% }); %>");f.push("</select>");f.push("</span>");return _.template(f.join(""))},templateImportIntoHistoryProgressBar:function(){var f=[];f.push('<div class="import_text">');f.push("Importing selected datasets to history <b><%= _.escape(history_name) %></b>");f.push("</div>");f.push('<div class="progress">');f.push(' <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');f.push(' <span class="completion_span">0% Complete</span>');f.push(" </div>");f.push("</div>");f.push("");return _.template(f.join(""))},templateAddingDatasetsProgressBar:function(){var f=[];f.push('<div class="import_text">');f.push("Adding selected datasets from history to library folder <b><%= _.escape(folder_name) %></b>");f.push("</div>");f.push('<div class="progress">');f.push(' <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');f.push(' <span class="completion_span">0% Complete</span>');f.push(" </div>");f.push("</div>");f.push("");return _.template(f.join(""))},templateAddFilesInModal:function(){var f=[];f.push('<div id="add_files_modal">');f.push('<div id="history_modal_combo_bulk">');f.push("Select history: ");f.push('<select id="dataset_add_bulk" name="dataset_add_bulk" style="width:66%; "> ');f.push(" <% _.each(histories, function(history) { %>");f.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');f.push(" <% }); %>");f.push("</select>");f.push("</div>");f.push('<div id="selected_history_content">');f.push("</div>");f.push("</div>");return _.template(f.join(""))},templateHistoryContents:function(){var f=[];f.push("Choose the datasets to import:");f.push("<ul>");f.push(" <% _.each(history_contents, function(history_item) { %>");f.push(' <li data-id="<%= _.escape(history_item.get("id")) %>">');f.push(' <input style="margin: 0;" type="checkbox"><%= _.escape(history_item.get("hid")) %>: <%= _.escape(history_item.get("name")) %>');f.push(" </li>");f.push(" <% }); %>");f.push("</ul>");return _.template(f.join(""))}});return{FolderToolbarView:a}});
\ No newline at end of file
+define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model"],function(b,d,e,c){var a=Backbone.View.extend({el:"#center",events:{"click #toolbtn_create_folder":"createFolderFromModal","click #toolbtn_bulk_import":"modalBulkImport","click .toolbtn_add_files":"addFilesToFolderModal"},defaults:{can_add_library_item:false,contains_file:false,chain_call_control:{total_number:0,failed_number:0}},modal:null,histories:null,initialize:function(f){this.options=_.defaults(f||{},this.defaults);this.render()},render:function(f){this.options=_.extend(this.options,f);var h=this.templateToolBar();var g=false;if(Galaxy.currUser){g=Galaxy.currUser.isAdmin()}this.$el.html(h({id:this.options.id,admin_user:g}))},configureElements:function(f){this.options=_.extend(this.options,f);if(this.options.can_add_library_item===true){$("#toolbtn_create_folder").show();$(".toolbtn_add_files").show()}if(this.options.contains_file===true){$("#toolbtn_bulk_import").show();$("#toolbtn_dl").show()}this.$el.find("[data-toggle]").tooltip()},createFolderFromModal:function(){event.preventDefault();event.stopPropagation();var f=this;var g=this.templateNewFolderInModal();this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Create New Folder",body:g(),buttons:{Create:function(){f.create_new_folder_event()},Close:function(){Galaxy.modal.hide()}}})},create_new_folder_event:function(){var f=this.serialize_new_folder();if(this.validate_new_folder(f)){var g=new c.FolderAsModel();url_items=Backbone.history.fragment.split("/");current_folder_id=url_items[url_items.length-1];g.url=g.urlRoot+"/"+current_folder_id;g.save(f,{success:function(h){Galaxy.modal.hide();e.success("Folder created");h.set({type:"folder"});Galaxy.libraries.folderListView.collection.add(h)},error:function(i,h){Galaxy.modal.hide();if(typeof h.responseJSON!=="undefined"){e.error(h.responseJSON.err_msg)}else{e.error("An error ocurred :(")}}})}else{e.error("Folder's name is missing")}return false},serialize_new_folder:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val()}},validate_new_folder:function(f){return f.name!==""},modalBulkImport:function(){var f=$("#folder_table").find(":checked");if(f.length===0){e.info("You have to select some datasets first")}else{this.refreshUserHistoriesList(function(g){var h=g.templateBulkImportInModal();g.modal=Galaxy.modal;g.modal.show({closing_events:true,title:"Import into History",body:h({histories:g.histories.models}),buttons:{Import:function(){g.importAllIntoHistory()},Close:function(){Galaxy.modal.hide()}}})})}},refreshUserHistoriesList:function(g){var f=this;this.histories=new c.GalaxyHistories();this.histories.fetch({success:function(){g(f)},error:function(i,h){if(typeof h.responseJSON!=="undefined"){e.error(h.responseJSON.err_msg)}else{e.error("An error ocurred :(")}}})},importAllIntoHistory:function(){this.modal.disableButton("Import");this.options.chain_call_control.total_number=0;this.options.chain_call_control.failed_number=0;var j=$("select[name=dataset_import_bulk] option:selected").val();this.options.last_used_history_id=j;var m=$("select[name=dataset_import_bulk] option:selected").text();var o=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!==""){o.push(this.parentElement.parentElement.id)}});var n=this.templateImportIntoHistoryProgressBar();this.modal.$el.find(".modal-body").html(n({history_name:m}));var k=100/o.length;this.initProgress(k);var f=[];for(var g=o.length-1;g>=0;g--){var h=o[g];var l=new c.HistoryItem();l.url=l.urlRoot+j+"/contents";l.content=h;l.source="library";f.push(l)}this.options.chain_call_control.total_number=f.length;this.chainCall(f,m)},chainCall:function(g,j){var f=this;var h=g.pop();if(typeof h==="undefined"){if(this.options.chain_call_control.failed_number===0){e.success("Selected datasets imported into history")}else{if(this.options.chain_call_control.failed_number===this.options.chain_call_control.total_number){e.error("There was an error and no datasets were imported into history.")}else{if(this.options.chain_call_control.failed_number<this.options.chain_call_control.total_number){e.warning("Some of the datasets could not be imported into history")}}}Galaxy.modal.hide();return}var i=$.when(h.save({content:h.content,source:h.source}));i.done(function(){f.updateProgress();f.chainCall(g,j)}).fail(function(){f.options.chain_call_control.failed_number+=1;f.updateProgress();f.chainCall(g,j)})},initProgress:function(f){this.progress=0;this.progressStep=f},updateProgress:function(){this.progress+=this.progressStep;$(".progress-bar-import").width(Math.round(this.progress)+"%");txt_representation=Math.round(this.progress)+"% Complete";$(".completion_span").text(txt_representation)},download:function(f,j){var h=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!==""){h.push(this.parentElement.parentElement.id)}});var g="/api/libraries/datasets/download/"+j;var i={ldda_ids:h};this.processDownload(g,i,"get")},processDownload:function(g,h,i){if(g&&h){h=typeof h==="string"?h:$.param(h);var f="";$.each(h.split("&"),function(){var j=this.split("=");f+='<input type="hidden" name="'+j[0]+'" value="'+j[1]+'" />'});$('<form action="'+g+'" method="'+(i||"post")+'">'+f+"</form>").appendTo("body").submit().remove();e.info("Your download will begin soon")}},addFilesToFolderModal:function(){this.refreshUserHistoriesList(function(f){f.modal=Galaxy.modal;var g=f.templateAddFilesInModal();f.modal.show({closing_events:true,title:"Add datasets from history to "+f.options.folder_name,body:g({histories:f.histories.models}),buttons:{Add:function(){f.addAllDatasetsFromHistory()},Close:function(){Galaxy.modal.hide()}}});if(f.histories.models.length>0){f.fetchAndDisplayHistoryContents(f.histories.models[0].id);$("#dataset_add_bulk").change(function(h){f.fetchAndDisplayHistoryContents(h.target.value)})}else{e.error("An error ocurred :(")}})},fetchAndDisplayHistoryContents:function(h){var g=new c.HistoryContents({id:h});var f=this;g.fetch({success:function(j){var i=f.templateHistoryContents();f.histories.get(h).set({contents:j});f.modal.$el.find("#selected_history_content").html(i({history_contents:j.models.reverse()}))},error:function(){e.error("An error ocurred :(")}})},addAllDatasetsFromHistory:function(){this.modal.disableButton("Add");this.options.chain_call_control.total_number=0;this.options.chain_call_control.failed_number=0;var f=[];this.modal.$el.find("#selected_history_content").find(":checked").each(function(){var i=$(this.parentElement).data("id");if(i){f.push(i)}});var l=this.options.folder_name;var k=this.templateAddingDatasetsProgressBar();this.modal.$el.find(".modal-body").html(k({folder_name:l}));this.progressStep=100/f.length;this.progress=0;var j=[];for(var h=f.length-1;h>=0;h--){history_dataset_id=f[h];var g=new c.Item();g.url="/api/folders/"+this.options.id+"/contents";g.set({from_hda_id:history_dataset_id});j.push(g)}this.options.chain_call_control.total_number=j.length;this.chainCallAddingHdas(j)},chainCallAddingHdas:function(g){var f=this;this.added_hdas=new c.Folder();var h=g.pop();if(typeof h==="undefined"){if(this.options.chain_call_control.failed_number===0){e.success("Selected datasets from history added to the folder")}else{if(this.options.chain_call_control.failed_number===this.options.chain_call_control.total_number){e.error("There was an error and no datasets were added to the folder.")}else{if(this.options.chain_call_control.failed_number<this.options.chain_call_control.total_number){e.warning("Some of the datasets could not be added to the folder")}}}Galaxy.modal.hide();return this.added_hdas}var i=$.when(h.save({from_hda_id:h.get("from_hda_id")}));i.done(function(j){Galaxy.libraries.folderListView.collection.add(j);f.updateProgress();f.chainCallAddingHdas(g)}).fail(function(){f.options.chain_call_control.failed_number+=1;f.updateProgress();f.chainCallAddingHdas(g)})},templateToolBar:function(){tmpl_array=[];tmpl_array.push('<div class="library_style_container">');tmpl_array.push('<h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');tmpl_array.push('<div id="library_folder_toolbar">');tmpl_array.push('<span data-toggle="tooltip" data-placement="top" title="Include deleted datasets"><input id="include_deleted_datasets_chk" style="margin: 0;" type="checkbox"><span class="fa fa-trash-o fa-lg"></span></input></span>');tmpl_array.push('<div class="btn-group">');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Create New Folder" id="toolbtn_create_folder" class="btn btn-default primary-button" type="button" style="display:none;"><span class="fa fa-plus"></span><span class="fa fa-folder"></span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Add Datasets to Current Folder" id="toolbtn_add_files" class="btn btn-default toolbtn_add_files primary-button" type="button" style="display:none;"><span class="fa fa-plus"></span><span class="fa fa-file"></span></span></button>');tmpl_array.push("</div>");tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Import selected datasets into history" id="toolbtn_bulk_import" class="primary-button" style="margin-left: 0.5em; " type="button"><span class="fa fa-book"></span> to history</button>');tmpl_array.push(' <div id="toolbtn_dl" class="btn-group" style="margin-left: 0.5em; ">');tmpl_array.push(' <button title="Download selected datasets as archive" id="drop_toggle" type="button" class="primary-button dropdown-toggle" data-toggle="dropdown">');tmpl_array.push(' <span class="fa fa-download"></span> download <span class="caret"></span>');tmpl_array.push(" </button>");tmpl_array.push(' <ul class="dropdown-menu" role="menu">');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/tgz">.tar.gz</a></li>');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/tbz">.tar.bz</a></li>');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/zip">.zip</a></li>');tmpl_array.push(" </ul>");tmpl_array.push(" </div>");tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Mark selected datasets deleted" id="toolbtn_bulk_delete" class="primary-button" style="margin-left: 0.5em; " type="button"><span class="fa fa-trash-o"></span> delete</button>');tmpl_array.push(" </div>");tmpl_array.push(' <div id="folder_items_element">');tmpl_array.push(" </div>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateNewFolderInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_folder_modal">');tmpl_array.push("<form>");tmpl_array.push('<input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push('<input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push("</form>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateBulkImportInModal:function(){var f=[];f.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');f.push("Select history: ");f.push('<select id="dataset_import_bulk" name="dataset_import_bulk" style="width:50%; margin-bottom: 1em; "> ');f.push(" <% _.each(histories, function(history) { %>");f.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');f.push(" <% }); %>");f.push("</select>");f.push("</span>");return _.template(f.join(""))},templateImportIntoHistoryProgressBar:function(){var f=[];f.push('<div class="import_text">');f.push("Importing selected datasets to history <b><%= _.escape(history_name) %></b>");f.push("</div>");f.push('<div class="progress">');f.push(' <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');f.push(' <span class="completion_span">0% Complete</span>');f.push(" </div>");f.push("</div>");f.push("");return _.template(f.join(""))},templateAddingDatasetsProgressBar:function(){var f=[];f.push('<div class="import_text">');f.push("Adding selected datasets from history to library folder <b><%= _.escape(folder_name) %></b>");f.push("</div>");f.push('<div class="progress">');f.push(' <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');f.push(' <span class="completion_span">0% Complete</span>');f.push(" </div>");f.push("</div>");f.push("");return _.template(f.join(""))},templateAddFilesInModal:function(){var f=[];f.push('<div id="add_files_modal">');f.push('<div id="history_modal_combo_bulk">');f.push("Select history: ");f.push('<select id="dataset_add_bulk" name="dataset_add_bulk" style="width:66%; "> ');f.push(" <% _.each(histories, function(history) { %>");f.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');f.push(" <% }); %>");f.push("</select>");f.push("</div>");f.push('<div id="selected_history_content">');f.push("</div>");f.push("</div>");return _.template(f.join(""))},templateHistoryContents:function(){var f=[];f.push("Choose the datasets to import:");f.push("<ul>");f.push(" <% _.each(history_contents, function(history_item) { %>");f.push(' <li data-id="<%= _.escape(history_item.get("id")) %>">');f.push(' <input style="margin: 0;" type="checkbox"><%= _.escape(history_item.get("hid")) %>: <%= _.escape(history_item.get("name")) %>');f.push(" </li>");f.push(" <% }); %>");f.push("</ul>");return _.template(f.join(""))}});return{FolderToolbarView:a}});
\ No newline at end of file
diff -r 4fa2b864adca65df5ac73a3fa60e5a4d98b1461c -r 986d7190844d5f7b68804242699a8049af80a937 static/style/blue/base.css
--- a/static/style/blue/base.css
+++ b/static/style/blue/base.css
@@ -1309,7 +1309,7 @@
.modal_table th{border:none !important}
.modal_table td{border:none !important}
th.button_heading{width:2em}
-#library_folder_toolbar{margin-bottom:1em}
+#library_folder_toolbar{margin-bottom:1em}#library_folder_toolbar span{margin-right:0.2em}
#library_toolbar{margin-bottom:1em}#library_toolbar span{margin-right:0.2em}
img.expanderIcon{padding-right:4px}
input.datasetCheckbox,li,ul{padding:0;margin:0}
diff -r 4fa2b864adca65df5ac73a3fa60e5a4d98b1461c -r 986d7190844d5f7b68804242699a8049af80a937 static/style/blue/library.css
--- a/static/style/blue/library.css
+++ b/static/style/blue/library.css
@@ -20,7 +20,7 @@
.modal_table th{border:none !important}
.modal_table td{border:none !important}
th.button_heading{width:2em}
-#library_folder_toolbar{margin-bottom:1em}
+#library_folder_toolbar{margin-bottom:1em}#library_folder_toolbar span{margin-right:0.2em}
#library_toolbar{margin-bottom:1em}#library_toolbar span{margin-right:0.2em}
img.expanderIcon{padding-right:4px}
input.datasetCheckbox,li,ul{padding:0;margin:0}
diff -r 4fa2b864adca65df5ac73a3fa60e5a4d98b1461c -r 986d7190844d5f7b68804242699a8049af80a937 static/style/src/less/library.less
--- a/static/style/src/less/library.less
+++ b/static/style/src/less/library.less
@@ -99,6 +99,9 @@
#library_folder_toolbar {
margin-bottom: 1em;
+ span {
+ margin-right: 0.2em;
+ }
}
#library_toolbar {
margin-bottom: 1em;
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: davebgx: Fix library security functional tests.
by commits-noreply@bitbucket.org 25 Apr '14
by commits-noreply@bitbucket.org 25 Apr '14
25 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/4fa2b864adca/
Changeset: 4fa2b864adca
User: davebgx
Date: 2014-04-25 21:29:56
Summary: Fix library security functional tests.
Affected #: 4 files
diff -r 267d03b5c9cdcad228fd40e12340f01c45f12c60 -r 4fa2b864adca65df5ac73a3fa60e5a4d98b1461c test-data/library/3.bed
--- /dev/null
+++ b/test-data/library/3.bed
@@ -0,0 +1,25 @@
+chr1 147962006 147975713 NM_005997 0 - 147962192 147975670 0 6 574,145,177,115,153,160, 0,1543,7859,9048,9340,13547,
+chr1 147984101 148035079 BC007833 0 + 147984545 148033414 0 14 529,32,81,131,118,153,300,206,84,49,85,130,46,1668, 0,25695,28767,33118,33695,33998,35644,38005,39629,40577,41402,43885,48367,49310,
+chr1 148077485 148111797 NM_002651 0 - 148078400 148111728 0 12 1097,121,133,266,124,105,110,228,228,45,937,77, 0,2081,2472,6871,9907,10257,11604,14199,15637,18274,23636,34235,
+chr1 148185113 148187485 NM_002796 0 + 148185136 148187378 0 7 163,207,147,82,117,89,120, 0,416,877,1199,1674,1977,2252,
+chr2 118288484 118306183 NM_006773 0 + 118288583 118304530 0 14 184,285,144,136,101,200,115,140,162,153,114,57,178,1796, 0,2765,4970,6482,6971,7183,7468,9890,10261,10768,11590,14270,14610,15903,
+chr2 118389378 118390700 BC005078 0 - 118390395 118390500 0 1 1322, 0,
+chr2 220108603 220116964 NM_001927 0 + 220108689 220116217 0 9 664,61,96,162,126,221,44,83,789, 0,1718,1874,2118,2451,2963,5400,7286,7572,
+chr2 220229182 220233943 NM_024536 0 - 220229609 220233765 0 4 1687,180,574,492, 0,1990,2660,4269,
+chr5 131170738 131357870 AF099740 0 - 131311206 131357817 0 31 112,124,120,81,65,40,120,129,61,88,94,79,72,102,144,117,89,73,96,135,135,78,74,52,33,179,100,102,65,115,248, 0,11593,44117,47607,104668,109739,114675,126366,135488,137518,138009,140437,152389,153373,155388,159269,160793,162981,164403,165577,166119,167611,169501,178260,179675,180901,181658,182260,182953,183706,186884,
+chr5 131424245 131426795 NM_000588 0 + 131424298 131426383 0 5 215,42,90,42,535, 0,313,1658,1872,2015,
+chr5 131556201 131590458 NM_004199 0 - 131556601 131582218 0 15 471,97,69,66,54,100,71,177,194,240,138,152,97,100,170, 0,2316,2802,5596,6269,11138,11472,15098,16528,17674,21306,24587,25142,25935,34087,
+chr5 131621285 131637046 NM_003687 0 + 131621326 131635821 0 7 134,152,82,179,164,118,1430, 0,4915,8770,13221,13609,14097,14331,
+chr6 108298214 108386086 NM_007214 0 - 108299600 108385906 0 21 1530,105,99,102,159,174,60,83,148,155,93,133,95,109,51,59,62,113,115,100,304, 0,2490,6246,10831,12670,23164,23520,27331,31052,32526,34311,36130,36365,38609,41028,42398,43048,51479,54500,59097,87568,
+chr6 108593954 108616704 NM_003269 0 + 108594662 108615360 0 9 733,146,88,236,147,97,150,106,1507, 0,5400,8778,10445,12037,14265,14749,15488,21243,
+chr6 108639410 108689143 NM_152827 0 - 108640045 108688818 0 3 741,125,487, 0,2984,49246,
+chr6 108722790 108950942 NM_145315 0 + 108722976 108950321 0 13 325,224,52,102,131,100,59,83,71,101,141,114,750, 0,28931,52094,60760,61796,71339,107102,152319,181970,182297,215317,224802,227402,
+chr7 113320332 113924911 AK131266 0 + 113862563 113893433 0 20 285,91,178,90,58,75,138,51,201,178,214,105,88,84,77,102,122,70,164,1124, 0,201692,340175,448290,451999,484480,542213,543265,543478,545201,556083,558358,565876,567599,573029,573245,575738,577123,577946,603455,
+chr7 116511232 116557294 NM_003391 0 - 116512159 116556994 0 5 1157,265,278,227,383, 0,20384,37843,43339,45679,
+chr7 116713967 116902666 NM_000492 0 + 116714099 116901113 0 27 185,111,109,216,90,164,126,247,93,183,192,95,87,724,129,38,251,80,151,228,101,249,156,90,173,106,1754, 0,24290,29071,50936,54313,55285,56585,60137,62053,68678,79501,107776,110390,111971,114967,122863,123569,126711,130556,131618,134650,147559,162475,172879,184725,185496,186945,
+chr7 116944658 117107512 AF377960 0 - 116945541 116979926 0 23 1129,102,133,64,186,206,179,188,153,100,87,80,96,276,118,255,151,100,204,1654,225,108,173, 0,7364,8850,10413,13893,14398,17435,24259,24615,35177,35359,45901,47221,49781,56405,66857,69787,72208,73597,80474,100111,150555,162681,
+chr8 118880786 119193239 NM_000127 0 - 118881131 119192466 0 11 531,172,161,90,96,119,133,120,108,94,1735, 0,5355,7850,13505,19068,20309,23098,30863,36077,37741,310718,
+chr9 128763240 128783870 NM_174933 0 + 128764156 128783586 0 12 261,118,74,159,76,48,56,63,129,117,127,370, 0,522,875,5630,12374,12603,15040,15175,18961,19191,20037,20260,
+chr9 128787362 128789566 NM_014908 0 - 128787519 128789136 0 1 2204, 0,
+chr9 128789530 128848928 NM_015354 0 + 128789552 128848511 0 44 54,55,74,85,81,45,93,120,212,115,201,90,66,120,127,153,127,88,77,115,121,67,129,140,107,207,170,70,68,196,78,86,146,182,201,93,159,138,75,228,132,74,130,594, 0,1491,5075,8652,9254,10312,11104,11317,20808,21702,23060,25462,31564,32908,33566,34851,35204,35595,35776,37202,38860,39111,39891,40349,42422,45499,45827,46675,47158,47621,50453,50840,51474,51926,53831,54186,55119,55619,57449,57605,57947,58352,58541,58804,
+chr9 128849867 128870133 NM_020145 0 - 128850516 128869987 0 11 757,241,101,90,24,63,93,134,129,142,209, 0,1071,1736,2085,2635,4201,6376,6736,13056,14247,20057,
diff -r 267d03b5c9cdcad228fd40e12340f01c45f12c60 -r 4fa2b864adca65df5ac73a3fa60e5a4d98b1461c test-data/library/4.bed
--- /dev/null
+++ b/test-data/library/4.bed
@@ -0,0 +1,1 @@
+chr22 30128507 31828507 uc003bnx.1_cds_2_0_chr22_29227_f 0 +
diff -r 267d03b5c9cdcad228fd40e12340f01c45f12c60 -r 4fa2b864adca65df5ac73a3fa60e5a4d98b1461c test-data/library/5.bed
--- /dev/null
+++ b/test-data/library/5.bed
@@ -0,0 +1,134 @@
+chr7 115444712 115444739 CCDS5763.1_cds_0_0_chr7_115444713_f 0 +
+chr7 115468538 115468624 CCDS5763.1_cds_1_0_chr7_115468539_f 0 +
+chr7 115483024 115483277 CCDS5763.1_cds_2_0_chr7_115483025_f 0 +
+chr7 115484165 115484501 CCDS5763.1_cds_3_0_chr7_115484166_f 0 +
+chr7 115485764 115485980 CCDS5763.1_cds_4_0_chr7_115485765_f 0 +
+chr7 115486322 115486481 CCDS5763.1_cds_5_0_chr7_115486323_f 0 +
+chr7 115491298 115491487 CCDS5763.1_cds_6_0_chr7_115491299_f 0 +
+chr7 115468538 115468624 CCDS5764.1_cds_0_0_chr7_115468539_f 0 +
+chr7 115483024 115483277 CCDS5764.1_cds_1_0_chr7_115483025_f 0 +
+chr7 115484165 115484501 CCDS5764.1_cds_2_0_chr7_115484166_f 0 +
+chr7 115485764 115485980 CCDS5764.1_cds_3_0_chr7_115485765_f 0 +
+chr7 115486322 115486481 CCDS5764.1_cds_4_0_chr7_115486323_f 0 +
+chr7 115491298 115491487 CCDS5764.1_cds_5_0_chr7_115491299_f 0 +
+chr7 115733786 115733936 CCDS5766.1_cds_0_0_chr7_115733787_f 0 +
+chr7 115734264 115734452 CCDS5766.1_cds_1_0_chr7_115734265_f 0 +
+chr7 115739975 115740126 CCDS5766.1_cds_2_0_chr7_115739976_f 0 +
+chr7 115733786 115733936 CCDS5765.1_cds_0_0_chr7_115733787_f 0 +
+chr7 115739975 115740164 CCDS5765.1_cds_1_0_chr7_115739976_f 0 +
+chr7 115759067 115759097 CCDS5767.1_cds_0_0_chr7_115759068_f 0 +
+chr7 115760529 115760694 CCDS5767.1_cds_1_0_chr7_115760530_f 0 +
+chr7 115792950 115793292 CCDS5767.1_cds_2_0_chr7_115792951_f 0 +
+chr7 116096616 116096655 CCDS5768.1_cds_0_0_chr7_116096617_f 0 +
+chr7 116122131 116122195 CCDS5768.1_cds_1_0_chr7_116122132_f 0 +
+chr7 116126998 116127050 CCDS5768.1_cds_2_0_chr7_116126999_f 0 +
+chr7 116132776 116132840 CCDS5768.1_cds_3_0_chr7_116132777_f 0 +
+chr7 116138181 116138388 CCDS5768.1_cds_4_0_chr7_116138182_f 0 +
+chr7 116140267 116140347 CCDS5768.1_cds_5_0_chr7_116140268_f 0 +
+chr7 116144237 116144316 CCDS5768.1_cds_6_0_chr7_116144238_f 0 +
+chr7 116146073 116146145 CCDS5768.1_cds_7_0_chr7_116146074_f 0 +
+chr7 116150064 116150127 CCDS5768.1_cds_8_0_chr7_116150065_f 0 +
+chr7 116151731 116151872 CCDS5768.1_cds_9_0_chr7_116151732_f 0 +
+chr7 116187545 116187696 CCDS5770.1_cds_0_0_chr7_116187546_f 0 +
+chr7 116333766 116333849 CCDS5770.1_cds_1_0_chr7_116333767_f 0 +
+chr7 116353565 116353725 CCDS5770.1_cds_2_0_chr7_116353566_f 0 +
+chr7 116363797 116363852 CCDS5770.1_cds_3_0_chr7_116363798_f 0 +
+chr7 116364495 116364611 CCDS5770.1_cds_4_0_chr7_116364496_f 0 +
+chr7 116365889 116365965 CCDS5770.1_cds_5_0_chr7_116365890_f 0 +
+chr7 116368128 116368197 CCDS5770.1_cds_6_0_chr7_116368129_f 0 +
+chr7 116370085 116370240 CCDS5770.1_cds_7_0_chr7_116370086_f 0 +
+chr7 116372439 116372537 CCDS5770.1_cds_8_0_chr7_116372440_f 0 +
+chr7 116404866 116404981 CCDS5770.1_cds_9_0_chr7_116404867_f 0 +
+chr7 116423325 116423398 CCDS5770.1_cds_10_0_chr7_116423326_f 0 +
+chr7 116424838 116424941 CCDS5770.1_cds_11_0_chr7_116424839_f 0 +
+chr7 116443791 116443942 CCDS5770.1_cds_12_0_chr7_116443792_f 0 +
+chr7 116453088 116453181 CCDS5770.1_cds_13_0_chr7_116453089_f 0 +
+chr7 116455927 116456067 CCDS5770.1_cds_14_0_chr7_116455928_f 0 +
+chr7 116456865 116456985 CCDS5770.1_cds_15_0_chr7_116456866_f 0 +
+chr7 116187545 116187696 CCDS5769.1_cds_0_0_chr7_116187546_f 0 +
+chr7 116333766 116333849 CCDS5769.1_cds_1_0_chr7_116333767_f 0 +
+chr7 116353565 116353725 CCDS5769.1_cds_2_0_chr7_116353566_f 0 +
+chr7 116363797 116363852 CCDS5769.1_cds_3_0_chr7_116363798_f 0 +
+chr7 116364495 116364611 CCDS5769.1_cds_4_0_chr7_116364496_f 0 +
+chr7 116365889 116365965 CCDS5769.1_cds_5_0_chr7_116365890_f 0 +
+chr7 116370085 116370240 CCDS5769.1_cds_6_0_chr7_116370086_f 0 +
+chr7 116372439 116372537 CCDS5769.1_cds_7_0_chr7_116372440_f 0 +
+chr7 116404866 116404981 CCDS5769.1_cds_8_0_chr7_116404867_f 0 +
+chr7 116423325 116423398 CCDS5769.1_cds_9_0_chr7_116423326_f 0 +
+chr7 116424838 116424941 CCDS5769.1_cds_10_0_chr7_116424839_f 0 +
+chr7 116443791 116443942 CCDS5769.1_cds_11_0_chr7_116443792_f 0 +
+chr7 116453088 116453181 CCDS5769.1_cds_12_0_chr7_116453089_f 0 +
+chr7 116455927 116456067 CCDS5769.1_cds_13_0_chr7_116455928_f 0 +
+chr7 116463766 116463862 CCDS5769.1_cds_14_0_chr7_116463767_f 0 +
+chr7 116512159 116512389 CCDS5771.1_cds_0_0_chr7_116512160_r 0 -
+chr7 116531616 116531881 CCDS5771.1_cds_1_0_chr7_116531617_r 0 -
+chr7 116549075 116549353 CCDS5771.1_cds_2_0_chr7_116549076_r 0 -
+chr7 116554571 116554798 CCDS5771.1_cds_3_0_chr7_116554572_r 0 -
+chr7 116556911 116556994 CCDS5771.1_cds_4_0_chr7_116556912_r 0 -
+chr7 116597600 116597753 CCDS5772.1_cds_0_0_chr7_116597601_r 0 -
+chr7 116601356 116601470 CCDS5772.1_cds_1_0_chr7_116601357_r 0 -
+chr7 116602616 116602722 CCDS5772.1_cds_2_0_chr7_116602617_r 0 -
+chr7 116613942 116614052 CCDS5772.1_cds_3_0_chr7_116613943_r 0 -
+chr7 116615015 116615072 CCDS5772.1_cds_4_0_chr7_116615016_r 0 -
+chr7 116616073 116616149 CCDS5772.1_cds_5_0_chr7_116616074_r 0 -
+chr7 116616990 116617115 CCDS5772.1_cds_6_0_chr7_116616991_r 0 -
+chr7 116618730 116618865 CCDS5772.1_cds_7_0_chr7_116618731_r 0 -
+chr7 116619702 116619814 CCDS5772.1_cds_8_0_chr7_116619703_r 0 -
+chr7 116654167 116654279 CCDS5772.1_cds_9_0_chr7_116654168_r 0 -
+chr7 116656241 116656364 CCDS5772.1_cds_10_0_chr7_116656242_r 0 -
+chr7 116660840 116660940 CCDS5772.1_cds_11_0_chr7_116660841_r 0 -
+chr7 116661360 116661465 CCDS5772.1_cds_12_0_chr7_116661361_r 0 -
+chr7 116714099 116714152 CCDS5773.1_cds_0_0_chr7_116714100_f 0 +
+chr7 116738257 116738368 CCDS5773.1_cds_1_0_chr7_116738258_f 0 +
+chr7 116743038 116743147 CCDS5773.1_cds_2_0_chr7_116743039_f 0 +
+chr7 116764903 116765119 CCDS5773.1_cds_3_0_chr7_116764904_f 0 +
+chr7 116768280 116768370 CCDS5773.1_cds_4_0_chr7_116768281_f 0 +
+chr7 116769252 116769416 CCDS5773.1_cds_5_0_chr7_116769253_f 0 +
+chr7 116770552 116770678 CCDS5773.1_cds_6_0_chr7_116770553_f 0 +
+chr7 116774104 116774351 CCDS5773.1_cds_7_0_chr7_116774105_f 0 +
+chr7 116776020 116776113 CCDS5773.1_cds_8_0_chr7_116776021_f 0 +
+chr7 116782645 116782828 CCDS5773.1_cds_9_0_chr7_116782646_f 0 +
+chr7 116793468 116793660 CCDS5773.1_cds_10_0_chr7_116793469_f 0 +
+chr7 116821743 116821838 CCDS5773.1_cds_11_0_chr7_116821744_f 0 +
+chr7 116824357 116824444 CCDS5773.1_cds_12_0_chr7_116824358_f 0 +
+chr7 116825938 116826662 CCDS5773.1_cds_13_0_chr7_116825939_f 0 +
+chr7 116828934 116829063 CCDS5773.1_cds_14_0_chr7_116828935_f 0 +
+chr7 116836830 116836868 CCDS5773.1_cds_15_0_chr7_116836831_f 0 +
+chr7 116837536 116837787 CCDS5773.1_cds_16_0_chr7_116837537_f 0 +
+chr7 116840678 116840758 CCDS5773.1_cds_17_0_chr7_116840679_f 0 +
+chr7 116844523 116844674 CCDS5773.1_cds_18_0_chr7_116844524_f 0 +
+chr7 116845585 116845813 CCDS5773.1_cds_19_0_chr7_116845586_f 0 +
+chr7 116848617 116848718 CCDS5773.1_cds_20_0_chr7_116848618_f 0 +
+chr7 116861526 116861775 CCDS5773.1_cds_21_0_chr7_116861527_f 0 +
+chr7 116876442 116876598 CCDS5773.1_cds_22_0_chr7_116876443_f 0 +
+chr7 116886846 116886936 CCDS5773.1_cds_23_0_chr7_116886847_f 0 +
+chr7 116898692 116898865 CCDS5773.1_cds_24_0_chr7_116898693_f 0 +
+chr7 116899463 116899569 CCDS5773.1_cds_25_0_chr7_116899464_f 0 +
+chr7 116900912 116901113 CCDS5773.1_cds_26_0_chr7_116900913_f 0 +
+chr7 116945541 116945787 CCDS5774.1_cds_0_0_chr7_116945542_r 0 -
+chr7 116952022 116952124 CCDS5774.1_cds_1_0_chr7_116952023_r 0 -
+chr7 116953508 116953641 CCDS5774.1_cds_2_0_chr7_116953509_r 0 -
+chr7 116955071 116955135 CCDS5774.1_cds_3_0_chr7_116955072_r 0 -
+chr7 116958551 116958737 CCDS5774.1_cds_4_0_chr7_116958552_r 0 -
+chr7 116959056 116959262 CCDS5774.1_cds_5_0_chr7_116959057_r 0 -
+chr7 116962093 116962272 CCDS5774.1_cds_6_0_chr7_116962094_r 0 -
+chr7 116968917 116969105 CCDS5774.1_cds_7_0_chr7_116968918_r 0 -
+chr7 116969273 116969426 CCDS5774.1_cds_8_0_chr7_116969274_r 0 -
+chr7 116979835 116979935 CCDS5774.1_cds_9_0_chr7_116979836_r 0 -
+chr7 116980017 116980104 CCDS5774.1_cds_10_0_chr7_116980018_r 0 -
+chr7 116990559 116990639 CCDS5774.1_cds_11_0_chr7_116990560_r 0 -
+chr7 116991879 116991975 CCDS5774.1_cds_12_0_chr7_116991880_r 0 -
+chr7 116994439 116994715 CCDS5774.1_cds_13_0_chr7_116994440_r 0 -
+chr7 117001063 117001181 CCDS5774.1_cds_14_0_chr7_117001064_r 0 -
+chr7 117011515 117011770 CCDS5774.1_cds_15_0_chr7_117011516_r 0 -
+chr7 117014445 117014596 CCDS5774.1_cds_16_0_chr7_117014446_r 0 -
+chr7 117016866 117016966 CCDS5774.1_cds_17_0_chr7_117016867_r 0 -
+chr7 117018255 117018459 CCDS5774.1_cds_18_0_chr7_117018256_r 0 -
+chr7 117025132 117026786 CCDS5774.1_cds_19_0_chr7_117025133_r 0 -
+chr7 117044769 117044994 CCDS5774.1_cds_20_0_chr7_117044770_r 0 -
+chr7 117095213 117095321 CCDS5774.1_cds_21_0_chr7_117095214_r 0 -
+chr7 117107339 117107420 CCDS5774.1_cds_22_0_chr7_117107340_r 0 -
+chr5 131424298 131424460 CCDS4149.1_cds_0_0_chr5_131424299_f 0 +
+chr5 131424558 131424600 CCDS4149.1_cds_1_0_chr5_131424559_f 0 +
+chr5 131425903 131425993 CCDS4149.1_cds_2_0_chr5_131425904_f 0 +
+chr5 131426117 131426159 CCDS4149.1_cds_3_0_chr5_131426118_f 0 +
diff -r 267d03b5c9cdcad228fd40e12340f01c45f12c60 -r 4fa2b864adca65df5ac73a3fa60e5a4d98b1461c test/base/twilltestcase.py
--- a/test/base/twilltestcase.py
+++ b/test/base/twilltestcase.py
@@ -2254,7 +2254,7 @@
# NOTE: due to the library_wait() method call at the end of this method, no tests should be done
# for strings_displayed_after_submit.
params = dict( cntrller=cntrller, library_id=library_id, folder_id=folder_id )
- url = "%s/library_common/upload_library_dataset" % self.url
+ url = "/library_common/upload_library_dataset"
if replace_id:
# If we're uploading a new version of a library dataset, we have to include the replace_id param in the
# request because the form field named replace_id will not be displayed on the upload form if we dont.
@@ -2309,17 +2309,15 @@
def ldda_permissions( self, cntrller, library_id, folder_id, id, role_ids_str,
permissions_in=[], permissions_out=[], strings_displayed=[], ldda_name='' ):
# role_ids_str must be a comma-separated string of role ids
- url = "%s/library_common/ldda_permissions?cntrller=%s&library_id=%s&folder_id=%s&id=%s" % \
- ( self.url, cntrller, library_id, folder_id, id )
+ params = dict( cntrller=cntrller, library_id=library_id, folder_id=folder_id, id=id )
+ url = "/library_common/ldda_permissions"
for po in permissions_out:
- key = '%s_out' % po
- url = "%s&%s=%s" % ( url, key, role_ids_str )
+ params[ '%s_out' % po ] = role_ids_str
for pi in permissions_in:
- key = '%s_in' % pi
- url = "%s&%s=%s" % ( url, key, role_ids_str )
+ params[ '%s_in' % pi ] = role_ids_str
if permissions_in or permissions_out:
- url += "&update_roles_button=Save"
- self.visit_url( url )
+ params[ 'update_roles_button' ] = 'Save'
+ self.visit_url( url, params )
if not strings_displayed:
strings_displayed = [ "Permissions updated for dataset '%s'." % ldda_name ]
for check_str in strings_displayed:
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: davebgx: Fix tool shed functional test for repository dependency handling.
by commits-noreply@bitbucket.org 25 Apr '14
by commits-noreply@bitbucket.org 25 Apr '14
25 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/267d03b5c9cd/
Changeset: 267d03b5c9cd
User: davebgx
Date: 2014-04-25 20:28:17
Summary: Fix tool shed functional test for repository dependency handling.
Affected #: 1 file
diff -r 666a75d94ee91091d94b65ffbfe700224ad58f15 -r 267d03b5c9cdcad228fd40e12340f01c45f12c60 test/base/twilltestcase.py
--- a/test/base/twilltestcase.py
+++ b/test/base/twilltestcase.py
@@ -18,6 +18,7 @@
from galaxy.web import security
from galaxy.web.framework.helpers import iff
from galaxy.util.json import from_json_string
+from galaxy.util import asbool
from base.asserts import verify_assertions
from galaxy import eggs
@@ -1325,11 +1326,25 @@
params[ key ] = value
if params:
url += '?%s' % urllib.urlencode( params )
+ checked_boxes = dict()
+ unchecked_boxes = dict()
if checkbox_params is not None:
+ for checkbox_field in checkbox_params:
+ if checkbox_field in checked_boxes or checkbox_field in unchecked_boxes:
+ continue
+ if asbool( checkbox_params[ checkbox_field ] ):
+ checked_boxes[ checkbox_field ] = True
+ else:
+ unchecked_boxes[ checkbox_field ] = False
+ # Any checkbox field that is found twice in the controller's incoming parameters is considered checked,
+ # while any field that only appears once is considered unchecked.
+ checkbox_params = '&'.join( [ urllib.urlencode( checked_boxes ),
+ urllib.urlencode( checked_boxes ),
+ urllib.urlencode( unchecked_boxes ) ] )
if params or parsed_url.query:
- url += '&%s&%s' % ( urllib.urlencode( checkbox_params ), urllib.urlencode( checkbox_params ) )
+ url += '&%s' % checkbox_params
else:
- url += '?%s&%s' % ( urllib.urlencode( checkbox_params ), urllib.urlencode( checkbox_params ) )
+ url += '?%s' % checkbox_params
new_url = tc.go( url )
return_code = tc.browser.get_code()
assert return_code in allowed_codes, 'Invalid HTTP return code %s, allowed codes: %s' % \
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: davebgx: Fix for persisting data table entries generated by installed data managers.
by commits-noreply@bitbucket.org 25 Apr '14
by commits-noreply@bitbucket.org 25 Apr '14
25 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/666a75d94ee9/
Changeset: 666a75d94ee9
User: davebgx
Date: 2014-04-25 19:21:32
Summary: Fix for persisting data table entries generated by installed data managers.
Affected #: 1 file
diff -r dda514ffa5e99b1b13bc3d88dbf35c1fb336742d -r 666a75d94ee91091d94b65ffbfe700224ad58f15 lib/galaxy/tools/data_manager/manager.py
--- a/lib/galaxy/tools/data_manager/manager.py
+++ b/lib/galaxy/tools/data_manager/manager.py
@@ -134,15 +134,15 @@
tool_shed_url = tool_elem.find( 'tool_shed' ).text
# Handle protocol changes.
tool_shed_url = common_util.get_tool_shed_url_from_tool_shed_registry( self.data_managers.app, tool_shed_url )
+ # The protocol is not stored in the database.
+ tool_shed = common_util.remove_protocol_from_tool_shed_url( tool_shed_url )
repository_name = tool_elem.find( 'repository_name' ).text
repository_owner = tool_elem.find( 'repository_owner' ).text
installed_changeset_revision = tool_elem.find( 'installed_changeset_revision' ).text
- self.tool_shed_repository_info_dict = dict( tool_shed_url=tool_shed_url,
+ self.tool_shed_repository_info_dict = dict( tool_shed=tool_shed,
name=repository_name,
owner=repository_owner,
installed_changeset_revision=installed_changeset_revision )
- # The protocol is not stored in the database.
- tool_shed = common_util.remove_protocol_from_tool_shed_url( tool_shed_url )
tool_shed_repository = \
suc.get_tool_shed_repository_by_shed_name_owner_installed_changeset_revision( self.data_managers.app,
tool_shed,
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: greg: Add support for 3 new tool dependency installation recipe action tag types: assert_directory_exists, assert_file_exists and assert_file_executable.
by commits-noreply@bitbucket.org 25 Apr '14
by commits-noreply@bitbucket.org 25 Apr '14
25 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/dda514ffa5e9/
Changeset: dda514ffa5e9
User: greg
Date: 2014-04-25 16:58:15
Summary: Add support for 3 new tool dependency installation recipe action tag types: assert_directory_exists, assert_file_exists and assert_file_executable.
Affected #: 4 files
diff -r 2edce562ccaa8bdd12e40b2263646f7b9cf93966 -r dda514ffa5e99b1b13bc3d88dbf35c1fb336742d lib/tool_shed/galaxy_install/tool_dependencies/fabric_util.py
--- a/lib/tool_shed/galaxy_install/tool_dependencies/fabric_util.py
+++ b/lib/tool_shed/galaxy_install/tool_dependencies/fabric_util.py
@@ -4,6 +4,8 @@
from galaxy import eggs
eggs.require( 'Fabric' )
+eggs.require( 'ssh' )
+eggs.require( 'paramiko' )
from fabric.api import env
from fabric.api import lcd
diff -r 2edce562ccaa8bdd12e40b2263646f7b9cf93966 -r dda514ffa5e99b1b13bc3d88dbf35c1fb336742d lib/tool_shed/galaxy_install/tool_dependencies/recipe/recipe_manager.py
--- a/lib/tool_shed/galaxy_install/tool_dependencies/recipe/recipe_manager.py
+++ b/lib/tool_shed/galaxy_install/tool_dependencies/recipe/recipe_manager.py
@@ -13,6 +13,8 @@
# TODO: eliminate the use of fabric here.
from galaxy import eggs
eggs.require( 'Fabric' )
+eggs.require( 'ssh' )
+eggs.require( 'paramiko' )
from fabric.operations import _AttributeString
from fabric import state
@@ -412,7 +414,10 @@
return tool_dependency, filtered_actions, dir
def load_step_handlers( self ):
- step_handlers_by_type = dict( autoconf=step_handler.Autoconf(),
+ step_handlers_by_type = dict( assert_directory_exists=step_handler.AssertDirectoryExists(),
+ assert_file_executable=step_handler.AssertFileExecutable(),
+ assert_file_exists=step_handler.AssertFileExists(),
+ autoconf=step_handler.Autoconf(),
change_directory=step_handler.ChangeDirectory(),
chmod=step_handler.Chmod(),
download_binary=step_handler.DownloadBinary(),
diff -r 2edce562ccaa8bdd12e40b2263646f7b9cf93966 -r dda514ffa5e99b1b13bc3d88dbf35c1fb336742d lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py
--- a/lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py
+++ b/lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py
@@ -14,6 +14,9 @@
# TODO: eliminate the use of fabric here.
from galaxy import eggs
eggs.require( 'Fabric' )
+eggs.require( 'ssh' )
+eggs.require( 'paramiko' )
+
from fabric.api import settings
from fabric.api import lcd
@@ -33,6 +36,105 @@
raise "Unimplemented Method"
+class AssertDirectoryExists( RecipeStep ):
+
+ def __init__( self ):
+ self.type = 'assert_directory_exists'
+
+ def execute_step( self, app, tool_dependency, package_name, actions, action_dict, filtered_actions, env_file_builder,
+ install_environment, work_dir, install_dir, current_dir=None, initial_download=False ):
+ """
+ Make sure a directory on disk exists. Since this class is not used in the initial download stage,
+ no recipe step filtering is performed here, and None values are always returned for filtered_actions
+ and dir.
+ """
+ if os.path.isabs( action_dict[ 'full_path' ] ):
+ full_path = action_dict[ 'full_path' ]
+ else:
+ full_path = os.path.join( current_dir, action_dict[ 'full_path' ] )
+ if not td_common_util.assert_directory_exists( full_path=full_path ):
+ status = app.install_model.ToolDependency.installation_status.ERROR
+ error_message = 'The required directory %s does not exist.' % str( full_path )
+ tool_dependency = tool_dependency_util.set_tool_dependency_attributes( app,
+ tool_dependency,
+ status=status,
+ error_message=error_message,
+ remove_from_disk=False )
+ return tool_dependency, None, None
+
+ def prepare_step( self, app, tool_dependency, action_elem, action_dict, install_dir, is_binary_download ):
+ # <action type="make_directory">$INSTALL_DIR/mira</action>
+ if action_elem.text:
+ action_dict[ 'full_path' ] = td_common_util.evaluate_template( action_elem.text, install_dir )
+ return action_dict
+
+
+class AssertFileExecutable( RecipeStep ):
+
+ def __init__( self ):
+ self.type = 'assert_file_executable'
+
+ def execute_step( self, app, tool_dependency, package_name, actions, action_dict, filtered_actions, env_file_builder,
+ install_environment, work_dir, install_dir, current_dir=None, initial_download=False ):
+ """
+ Make sure a file on disk exists and is executable. Since this class is not used in the initial
+ download stage, no recipe step filtering is performed here, and None values are always returned
+ for filtered_actions and dir.
+ """
+ if os.path.isabs( action_dict[ 'full_path' ] ):
+ full_path = action_dict[ 'full_path' ]
+ else:
+ full_path = os.path.join( current_dir, action_dict[ 'full_path' ] )
+ if not td_common_util.assert_file_executable( full_path=full_path ):
+ status = app.install_model.ToolDependency.installation_status.ERROR
+ error_message = 'The file %s is not executable by the owner.' % str( full_path )
+ tool_dependency = tool_dependency_util.set_tool_dependency_attributes( app,
+ tool_dependency,
+ status=status,
+ error_message=error_message,
+ remove_from_disk=False )
+ return tool_dependency, None, None
+
+ def prepare_step( self, app, tool_dependency, action_elem, action_dict, install_dir, is_binary_download ):
+ # <action type="assert_executable">$INSTALL_DIR/mira/my_file</action>
+ if action_elem.text:
+ action_dict[ 'full_path' ] = td_common_util.evaluate_template( action_elem.text, install_dir )
+ return action_dict
+
+
+class AssertFileExists( RecipeStep ):
+
+ def __init__( self ):
+ self.type = 'assert_file_exists'
+
+ def execute_step( self, app, tool_dependency, package_name, actions, action_dict, filtered_actions, env_file_builder,
+ install_environment, work_dir, install_dir, current_dir=None, initial_download=False ):
+ """
+ Make sure a file on disk exists. Since this class is not used in the initial download stage,
+ no recipe step filtering is performed here, and None values are always returned for
+ filtered_actions and dir.
+ """
+ if os.path.isabs( action_dict[ 'full_path' ] ):
+ full_path = action_dict[ 'full_path' ]
+ else:
+ full_path = os.path.join( current_dir, action_dict[ 'full_path' ] )
+ if not td_common_util.assert_file_exists( full_path=full_path ):
+ status = app.install_model.ToolDependency.installation_status.ERROR
+ error_message = 'The required file %s does not exist.' % str( full_path )
+ tool_dependency = tool_dependency_util.set_tool_dependency_attributes( app,
+ tool_dependency,
+ status=status,
+ error_message=error_message,
+ remove_from_disk=False )
+ return tool_dependency, None, None
+
+ def prepare_step( self, app, tool_dependency, action_elem, action_dict, install_dir, is_binary_download ):
+ # <action type="assert_on_path">$INSTALL_DIR/mira/my_file</action>
+ if action_elem.text:
+ action_dict[ 'full_path' ] = td_common_util.evaluate_template( action_elem.text, install_dir )
+ return action_dict
+
+
class Autoconf( RecipeStep ):
def __init__( self ):
diff -r 2edce562ccaa8bdd12e40b2263646f7b9cf93966 -r dda514ffa5e99b1b13bc3d88dbf35c1fb336742d lib/tool_shed/galaxy_install/tool_dependencies/td_common_util.py
--- a/lib/tool_shed/galaxy_install/tool_dependencies/td_common_util.py
+++ b/lib/tool_shed/galaxy_install/tool_dependencies/td_common_util.py
@@ -2,6 +2,7 @@
import os
import re
import shutil
+import stat
import sys
import tarfile
import time
@@ -110,6 +111,31 @@
def open_zip( self, filepath, mode ):
return zipfile.ZipFile( filepath, mode )
+def assert_directory_exists( full_path ):
+ """Return True if a directory exists and is not a symbolic link."""
+ if os.path.islink( full_path ):
+ return False
+ if os.path.is_dir( full_path ):
+ return True
+ return False
+
+def assert_file_exists( full_path ):
+ """Return True if a file exists. This will work for both symbolic linke and files."""
+ if os.path.exists( full_path ):
+ return True
+ return False
+
+def assert_file_executable( full_path ):
+ """Return True if a file exists and is executable."""
+ if os.path.islink( full_path ):
+ return False
+ if os.path.is_file( full_path ):
+ # Make sure the owner has execute permission on the file.
+ # See http://docs.python.org/2/library/stat.html
+ if stat.S_IXUSR & os.stat( full_path )[ stat.ST_MODE ] == 64:
+ return True
+ return False
+
def create_env_var_dict( elem, tool_dependency_install_dir=None, tool_shed_repository_install_dir=None ):
env_var_name = elem.get( 'name', 'PATH' )
env_var_action = elem.get( 'action', 'prepend_to' )
@@ -155,6 +181,10 @@
regex = regex.replace( r"\'", "'" )
return regex
+def evaluate_template( text, install_dir ):
+ """ Substitute variables defined in XML blocks from dependencies file."""
+ return Template( text ).safe_substitute( get_env_var_values( install_dir ) )
+
def format_traceback():
ex_type, ex, tb = sys.exc_info()
return ''.join( traceback.format_tb( tb ) )
@@ -444,6 +474,10 @@
continue
return actions_elem_tuples
+def __shellquote( s ):
+ """Quote and escape the supplied string for use in shell expressions."""
+ return "'" + s.replace( "'", "'\\''" ) + "'"
+
def url_download( install_dir, downloaded_file_name, download_url, extract=True ):
file_path = os.path.join( install_dir, downloaded_file_name )
src = None
@@ -494,11 +528,3 @@
if not member_path.startswith( basename ):
return False
return True
-
-def __shellquote(s):
- """Quote and escape the supplied string for use in shell expressions."""
- return "'" + s.replace( "'", "'\\''" ) + "'"
-
-def evaluate_template( text, install_dir ):
- """ Substitute variables defined in XML blocks from dependencies file."""
- return Template( text ).safe_substitute( get_env_var_values( install_dir ) )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: Jeremy Goecks: BAM data provider: hash to create read guids. This is line with other data providers and decreases payload size slightly.
by commits-noreply@bitbucket.org 25 Apr '14
by commits-noreply@bitbucket.org 25 Apr '14
25 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/2edce562ccaa/
Changeset: 2edce562ccaa
User: Jeremy Goecks
Date: 2014-04-25 16:50:47
Summary: BAM data provider: hash to create read guids. This is line with other data providers and decreases payload size slightly.
Affected #: 1 file
diff -r 611117ed0a88654c736bc5722016b81874475c95 -r 2edce562ccaa8bdd12e40b2263646f7b9cf93966 lib/galaxy/visualization/data_providers/genome.py
--- a/lib/galaxy/visualization/data_providers/genome.py
+++ b/lib/galaxy/visualization/data_providers/genome.py
@@ -1018,7 +1018,7 @@
if qname in paired_pending:
# Found pair.
pair = paired_pending[qname]
- results.append( [ "%i_%s" % ( pair['start'], qname ),
+ results.append( [ hash( "%i_%s" % ( pair['start'], qname ) ),
pair['start'],
read.pos + read_len,
qname,
@@ -1033,7 +1033,7 @@
'rlen': read_len, 'strand': strand, 'cigar': read.cigar, 'mapq': read.mapq }
count += 1
else:
- results.append( [ "%i_%s" % ( read.pos, qname ),
+ results.append( [ hash( "%i_%s" % ( read.pos, qname ) ),
read.pos, read.pos + read_len, qname,
read.cigar, strand, read.seq, read.mapq ] )
count += 1
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/09c44c3db98c/
Changeset: 09c44c3db98c
User: davebgx
Date: 2014-04-25 16:41:34
Summary: Fix tool shed functional tests for roles and email notifications.
Affected #: 1 file
diff -r 880974da3ca4d3d76bcf8b11184cb42c4aee95b7 -r 09c44c3db98cef9fa33b8e511e52928dcec5d2f5 test/tool_shed/base/twilltestcase.py
--- a/test/tool_shed/base/twilltestcase.py
+++ b/test/tool_shed/base/twilltestcase.py
@@ -525,7 +525,7 @@
def enable_email_alerts( self, repository, strings_displayed=[], strings_not_displayed=[] ):
repository_id = self.security.encode_id( repository.id )
params = dict( operation='Receive email alerts', id=repository_id )
- self.visit_url( '/repository/browse_repositories' )
+ self.visit_url( '/repository/browse_repositories', params )
self.check_for_strings( strings_displayed )
def escape_html( self, string, unescape=False ):
@@ -796,7 +796,7 @@
self.check_for_strings( strings_displayed, strings_not_displayed )
params = dict( operation='manage users and groups', id=self.security.encode_id( role.id ) )
url = '/admin/roles'
- self.visit_url( url )
+ self.visit_url( url, params )
strings_displayed = [ common.test_user_1_email, common.test_user_2_email ]
self.check_for_strings( strings_displayed, strings_not_displayed )
# As elsewhere, twill limits the possibility of submitting the form, this time due to not executing the javascript
https://bitbucket.org/galaxy/galaxy-central/commits/611117ed0a88/
Changeset: 611117ed0a88
User: davebgx
Date: 2014-04-25 16:41:53
Summary: Fix functional tests for library templates.
Affected #: 2 files
diff -r 09c44c3db98cef9fa33b8e511e52928dcec5d2f5 -r 611117ed0a88654c736bc5722016b81874475c95 test/base/twilltestcase.py
--- a/test/base/twilltestcase.py
+++ b/test/base/twilltestcase.py
@@ -2040,16 +2040,13 @@
dis-inherit your template, call the manage_library_template_inheritance() below immediately after you call this
method in your test code. Templates added to Requesttype objects are always inherited to samples.
"""
- if item_type == 'library':
- url = "%s/library_common/add_template?cntrller=%s&item_type=%s&form_type=%s&library_id=%s" % \
- ( self.url, cntrller, item_type, form_type, library_id )
- elif item_type == 'folder':
- url = "%s/library_common/add_template?cntrller=%s&item_type=%s&form_type=%s&library_id=%s&folder_id=%s" % \
- ( self.url, cntrller, item_type, form_type, library_id, folder_id )
+ params = dict( cntrller=cntrller, item_type=item_type, form_type=form_type, library_id=library_id )
+ url = "/library_common/add_template"
+ if item_type == 'folder':
+ params[ 'folder_id' ] = folder_id
elif item_type == 'ldda':
- url = "%s/library_common/add_template?cntrller=%s&item_type=%s&form_type=%s&library_id=%s&folder_id=%s&ldda_id=%s" % \
- ( self.url, cntrller, item_type, form_type, library_id, folder_id, ldda_id )
- self.visit_url( url )
+ params[ 'ldda_id' ] = ldda_id
+ self.visit_url( url, params )
self.check_page_for_string ( "Select a template for the" )
self.refresh_form( "form_id", form_id )
# For some unknown reason, twill barfs if the form number ( 1 ) is used in the following
diff -r 09c44c3db98cef9fa33b8e511e52928dcec5d2f5 -r 611117ed0a88654c736bc5722016b81874475c95 test/functional/test_library_templates.py
--- a/test/functional/test_library_templates.py
+++ b/test/functional/test_library_templates.py
@@ -72,12 +72,14 @@
# Pass number of options we want in our SelectField
num_options = 2
# Create form for library template
+ strings_displayed_after_submit = [ "The form '%s' has been updated with the changes." % type ]
self.create_form( name=type,
description=form_desc,
form_type=galaxy.model.FormDefinition.types.LIBRARY_INFO_TEMPLATE,
field_type=type,
num_options=num_options,
- field_name=field_name )
+ field_name=field_name,
+ strings_displayed_after_submit=strings_displayed_after_submit )
# Get all of the new form definitions for later use
global AddressField_form
AddressField_form = get_form( 'AddressField' )
@@ -145,7 +147,7 @@
# Add a template containing an AddressField to library1
self.add_template( cntrller='library_admin',
item_type='library',
- form_type=galaxy.model.FormDefinition.types.LIBRARY_INFO_TEMPLATE.replace( ' ', '+' ),
+ form_type=galaxy.model.FormDefinition.types.LIBRARY_INFO_TEMPLATE,
form_id=self.security.encode_id( AddressField_form.id ),
form_name=AddressField_form.name,
library_id=self.security.encode_id( library1.id ) )
@@ -287,7 +289,7 @@
# Add a template containing an CheckboxField to library1
self.add_template( cntrller='library_admin',
item_type='library',
- form_type=galaxy.model.FormDefinition.types.LIBRARY_INFO_TEMPLATE.replace( ' ', '+' ),
+ form_type=galaxy.model.FormDefinition.types.LIBRARY_INFO_TEMPLATE,
form_id=self.security.encode_id( CheckboxField_form.id ),
form_name=CheckboxField_form.name,
library_id=self.security.encode_id( library2.id ) )
@@ -363,7 +365,7 @@
# Logged in as admin_user
self.add_template( cntrller='library_admin',
item_type='library',
- form_type=galaxy.model.FormDefinition.types.LIBRARY_INFO_TEMPLATE.replace( ' ', '+' ),
+ form_type=galaxy.model.FormDefinition.types.LIBRARY_INFO_TEMPLATE,
form_id=self.security.encode_id( SelectField_form.id ),
form_name=SelectField_form.name,
library_id=self.security.encode_id( library3.id ) )
@@ -464,7 +466,7 @@
# Add an inheritable template to library4
self.add_template( cntrller='library_admin',
item_type='library',
- form_type=galaxy.model.FormDefinition.types.LIBRARY_INFO_TEMPLATE.replace( ' ', '+' ),
+ form_type=galaxy.model.FormDefinition.types.LIBRARY_INFO_TEMPLATE,
form_id=self.security.encode_id( TextArea_form.id ),
form_name=TextArea_form.name,
library_id=self.security.encode_id( library4.id ) )
@@ -533,7 +535,7 @@
# Add an inheritable template to library5
self.add_template( cntrller='library_admin',
item_type='library',
- form_type=galaxy.model.FormDefinition.types.LIBRARY_INFO_TEMPLATE.replace( ' ', '+' ),
+ form_type=galaxy.model.FormDefinition.types.LIBRARY_INFO_TEMPLATE,
form_id=self.security.encode_id( TextField_form.id ),
form_name=TextField_form.name,
library_id=self.security.encode_id( library5.id ) )
@@ -602,7 +604,7 @@
# Currently there is only a TextField, and we'll add a TextArea.
self.edit_template( cntrller='library_admin',
item_type='library',
- form_type=galaxy.model.FormDefinition.types.LIBRARY_INFO_TEMPLATE.replace( ' ', '+' ),
+ form_type=galaxy.model.FormDefinition.types.LIBRARY_INFO_TEMPLATE,
library_id=self.security.encode_id( library5.id ),
field_type='TextArea',
field_label_1=TextArea_form.name,
@@ -647,7 +649,7 @@
# We won't select an option since we have no workflow to select
self.add_template( cntrller='library_admin',
item_type='library',
- form_type=galaxy.model.FormDefinition.types.LIBRARY_INFO_TEMPLATE.replace( ' ', '+' ),
+ form_type=galaxy.model.FormDefinition.types.LIBRARY_INFO_TEMPLATE,
form_id=self.security.encode_id( WorkflowField_form.id ),
form_name=WorkflowField_form.name,
library_id=self.security.encode_id( library6.id ) )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: Jeremy Goecks: Simplification for dowsampler in bam data provider
by commits-noreply@bitbucket.org 25 Apr '14
by commits-noreply@bitbucket.org 25 Apr '14
25 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/880974da3ca4/
Changeset: 880974da3ca4
User: Jeremy Goecks
Date: 2014-04-25 03:24:33
Summary: Simplification for dowsampler in bam data provider
Affected #: 1 file
diff -r d1dd573cdce2bd122cbb0e98e947dc7992fe3ed0 -r 880974da3ca4d3d76bcf8b11184cb42c4aee95b7 lib/galaxy/visualization/data_providers/genome.py
--- a/lib/galaxy/visualization/data_providers/genome.py
+++ b/lib/galaxy/visualization/data_providers/genome.py
@@ -952,8 +952,7 @@
# Convert threshold to N for stepping through iterator.
n = int( 1/threshold )
- for e in itertools.islice( read_iterator, None, None, n ):
- yield e
+ return itertools.islice( read_iterator, None, None, n )
# Alternatate and much slower implementation that looks for pending pairs.
'''
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: Move some hg utility functions out of shed_util_common and into hg_util.
by commits-noreply@bitbucket.org 24 Apr '14
by commits-noreply@bitbucket.org 24 Apr '14
24 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/d1dd573cdce2/
Changeset: d1dd573cdce2
User: greg
Date: 2014-04-24 21:45:55
Summary: Move some hg utility functions out of shed_util_common and into hg_util.
Affected #: 12 files
diff -r 203623b931507dcd182e2521911ab036021faf61 -r d1dd573cdce2bd122cbb0e98e947dc7992fe3ed0 lib/galaxy/webapps/galaxy/controllers/admin_toolshed.py
--- a/lib/galaxy/webapps/galaxy/controllers/admin_toolshed.py
+++ b/lib/galaxy/webapps/galaxy/controllers/admin_toolshed.py
@@ -1855,7 +1855,7 @@
repo = hg.repository( hg_util.get_configured_ui(), path=repo_files_dir )
repository_clone_url = os.path.join( tool_shed_url, 'repos', owner, name )
repository_util.pull_repository( repo, repository_clone_url, latest_ctx_rev )
- suc.update_repository( repo, latest_ctx_rev )
+ hg_util.update_repository( repo, latest_ctx_rev )
# Remove old Data Manager entries
if repository.includes_data_managers:
data_manager_util.remove_from_data_manager( trans.app, repository )
diff -r 203623b931507dcd182e2521911ab036021faf61 -r d1dd573cdce2bd122cbb0e98e947dc7992fe3ed0 lib/galaxy/webapps/tool_shed/controllers/hg.py
--- a/lib/galaxy/webapps/tool_shed/controllers/hg.py
+++ b/lib/galaxy/webapps/tool_shed/controllers/hg.py
@@ -2,7 +2,7 @@
from galaxy import web
from galaxy.web.base.controller import BaseUIController
from tool_shed.util.shed_util_common import get_repository_by_name_and_owner
-from tool_shed.util.shed_util_common import update_repository
+from tool_shed.util.hg_util import update_repository
from tool_shed.util.metadata_util import set_repository_metadata
from galaxy import eggs
diff -r 203623b931507dcd182e2521911ab036021faf61 -r d1dd573cdce2bd122cbb0e98e947dc7992fe3ed0 lib/galaxy/webapps/tool_shed/controllers/repository.py
--- a/lib/galaxy/webapps/tool_shed/controllers/repository.py
+++ b/lib/galaxy/webapps/tool_shed/controllers/repository.py
@@ -722,7 +722,7 @@
repository = suc.get_repository_in_tool_shed( trans, id )
repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) )
# Update repository files for browsing.
- suc.update_repository( repo )
+ hg_util.update_repository( repo )
changeset_revision = repository.tip( trans.app )
metadata = metadata_util.get_repository_metadata_by_repository_id_changeset_revision( trans, id, changeset_revision, metadata_only=True )
repository_type_select_field = rt_util.build_repository_type_select_field( trans, repository=repository )
@@ -2743,7 +2743,7 @@
commands.commit( repo.ui, repo, repo_dir, user=trans.user.username, message=commit_message )
suc.handle_email_alerts( trans, repository )
# Update the repository files for browsing.
- suc.update_repository( repo )
+ hg_util.update_repository( repo )
# Get the new repository tip.
repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
if tip == repository.tip( trans.app ):
@@ -3117,7 +3117,7 @@
else:
ctx_child = None
diffs = []
- options_dict = suc.get_mercurial_default_options_dict( 'diff' )
+ options_dict = hg_util.get_mercurial_default_options_dict( 'diff' )
# Not quite sure if the following settings make any difference, but with a combination of them and the size check on each
# diff, we don't run out of memory when viewing the changelog of the cisortho2 repository on the test tool shed.
options_dict[ 'maxfile' ] = suc.MAXDIFFSIZE
@@ -3252,7 +3252,11 @@
else:
message += malicious_error
status = 'error'
- containers_dict = container_util.build_repository_containers_for_tool_shed( trans, repository, changeset_revision, repository_dependencies, repository_metadata )
+ containers_dict = container_util.build_repository_containers_for_tool_shed( trans,
+ repository,
+ changeset_revision,
+ repository_dependencies,
+ repository_metadata )
repository_type_select_field = rt_util.build_repository_type_select_field( trans, repository=repository )
heads = suc.get_repository_heads( repo )
return trans.fill_template( '/webapps/tool_shed/repository/view_repository.mako',
diff -r 203623b931507dcd182e2521911ab036021faf61 -r d1dd573cdce2bd122cbb0e98e947dc7992fe3ed0 lib/galaxy/webapps/tool_shed/controllers/upload.py
--- a/lib/galaxy/webapps/tool_shed/controllers/upload.py
+++ b/lib/galaxy/webapps/tool_shed/controllers/upload.py
@@ -226,7 +226,7 @@
admin_only=admin_only )
if ok:
# Update the repository files for browsing.
- suc.update_repository( repo )
+ hg_util.update_repository( repo )
# Get the new repository tip.
if tip == repository.tip( trans.app ):
message = 'No changes to repository. '
diff -r 203623b931507dcd182e2521911ab036021faf61 -r d1dd573cdce2bd122cbb0e98e947dc7992fe3ed0 lib/tool_shed/galaxy_install/install_manager.py
--- a/lib/tool_shed/galaxy_install/install_manager.py
+++ b/lib/tool_shed/galaxy_install/install_manager.py
@@ -2,6 +2,7 @@
Manage automatic installation of tools configured in the xxx.xml files in ~/scripts/migrate_tools (e.g., 0002_tools.xml).
All of the tools were at some point included in the Galaxy distribution, but are now hosted in the main Galaxy tool shed.
"""
+import json
import os
import shutil
import tempfile
@@ -9,12 +10,11 @@
import logging
from galaxy import util
from galaxy.tools import ToolSection
-from galaxy.util.json import from_json_string
-from galaxy.util.json import to_json_string
import tool_shed.util.shed_util_common as suc
from tool_shed.util import common_install_util
from tool_shed.util import common_util
from tool_shed.util import datatype_util
+from tool_shed.util import hg_util
from tool_shed.util import metadata_util
from tool_shed.util import tool_dependency_util
from tool_shed.util import tool_util
@@ -505,8 +505,10 @@
tool_shed_repository.owner,
tool_shed_repository.installed_changeset_revision )
if not cloned_ok:
- suc.update_tool_shed_repository_status( self.app, tool_shed_repository, self.app.install_model.ToolShedRepository.installation_status.CLONING )
- cloned_ok, error_message = suc.clone_repository( repository_clone_url, os.path.abspath( install_dir ), ctx_rev )
+ suc.update_tool_shed_repository_status( self.app,
+ tool_shed_repository,
+ self.app.install_model.ToolShedRepository.installation_status.CLONING )
+ cloned_ok, error_message = hg_util.clone_repository( repository_clone_url, os.path.abspath( install_dir ), ctx_rev )
if cloned_ok and not is_installed:
self.handle_repository_contents( tool_shed_repository=tool_shed_repository,
repository_clone_url=repository_clone_url,
@@ -525,7 +527,7 @@
( self.tool_shed_url, tool_shed_repository.name, self.repository_owner, tool_shed_repository.installed_changeset_revision )
text = common_util.tool_shed_get( self.app, self.tool_shed_url, url )
if text:
- tool_version_dicts = from_json_string( text )
+ tool_version_dicts = json.loads( text )
tool_util.handle_tool_versions( self.app, tool_version_dicts, tool_shed_repository )
else:
# Set the tool versions since they seem to be missing for this repository in the tool shed.
diff -r 203623b931507dcd182e2521911ab036021faf61 -r d1dd573cdce2bd122cbb0e98e947dc7992fe3ed0 lib/tool_shed/galaxy_install/repository_util.py
--- a/lib/tool_shed/galaxy_install/repository_util.py
+++ b/lib/tool_shed/galaxy_install/repository_util.py
@@ -560,14 +560,17 @@
if isinstance( repo_info_dict, basestring ):
repo_info_dict = encoding_util.tool_shed_decode( repo_info_dict )
# Clone each repository to the configured location.
- suc.update_tool_shed_repository_status( trans.app, tool_shed_repository, trans.install_model.ToolShedRepository.installation_status.CLONING )
+ suc.update_tool_shed_repository_status( trans.app,
+ tool_shed_repository,
+ trans.install_model.ToolShedRepository.installation_status.CLONING )
repo_info_tuple = repo_info_dict[ tool_shed_repository.name ]
description, repository_clone_url, changeset_revision, ctx_rev, repository_owner, repository_dependencies, tool_dependencies = repo_info_tuple
- relative_clone_dir = suc.generate_tool_shed_repository_install_dir( repository_clone_url, tool_shed_repository.installed_changeset_revision )
+ relative_clone_dir = suc.generate_tool_shed_repository_install_dir( repository_clone_url,
+ tool_shed_repository.installed_changeset_revision )
clone_dir = os.path.join( tool_path, relative_clone_dir )
relative_install_dir = os.path.join( relative_clone_dir, tool_shed_repository.name )
install_dir = os.path.join( tool_path, relative_install_dir )
- cloned_ok, error_message = suc.clone_repository( repository_clone_url, os.path.abspath( install_dir ), ctx_rev )
+ cloned_ok, error_message = hg_util.clone_repository( repository_clone_url, os.path.abspath( install_dir ), ctx_rev )
if cloned_ok:
if reinstalling:
# Since we're reinstalling the repository we need to find the latest changeset revision to which it can be updated.
@@ -577,7 +580,7 @@
if current_ctx_rev != ctx_rev:
repo = hg.repository( hg_util.get_configured_ui(), path=os.path.abspath( install_dir ) )
pull_repository( repo, repository_clone_url, current_changeset_revision )
- suc.update_repository( repo, ctx_rev=current_ctx_rev )
+ hg_util.update_repository( repo, ctx_rev=current_ctx_rev )
handle_repository_contents( trans,
tool_shed_repository=tool_shed_repository,
tool_path=tool_path,
diff -r 203623b931507dcd182e2521911ab036021faf61 -r d1dd573cdce2bd122cbb0e98e947dc7992fe3ed0 lib/tool_shed/scripts/check_repositories_for_functional_tests.py
--- a/lib/tool_shed/scripts/check_repositories_for_functional_tests.py
+++ b/lib/tool_shed/scripts/check_repositories_for_functional_tests.py
@@ -112,7 +112,7 @@
repo_dir = repository.repo_path( app )
repo = hg.repository( hg_util.get_configured_ui(), repo_dir )
work_dir = tempfile.mkdtemp( prefix="tmp-toolshed-cafr" )
- cloned_ok, error_message = suc.clone_repository( repo_dir, work_dir, changeset_revision )
+ cloned_ok, error_message = hg_util.clone_repository( repo_dir, work_dir, changeset_revision )
if cloned_ok:
# Iterate through all the directories in the cloned changeset revision and determine whether there's a
# directory named test-data. If this directory is not present update the metadata record for the changeset
diff -r 203623b931507dcd182e2521911ab036021faf61 -r d1dd573cdce2bd122cbb0e98e947dc7992fe3ed0 lib/tool_shed/util/export_util.py
--- a/lib/tool_shed/util/export_util.py
+++ b/lib/tool_shed/util/export_util.py
@@ -39,7 +39,7 @@
def archive_repository_revision( trans, ui, repository, archive_dir, changeset_revision ):
'''Create an un-versioned archive of a repository.'''
repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( trans.app ) )
- options_dict = suc.get_mercurial_default_options_dict( 'archive' )
+ options_dict = hg_util.get_mercurial_default_options_dict( 'archive' )
options_dict[ 'rev' ] = changeset_revision
error_message = ''
return_code = None
diff -r 203623b931507dcd182e2521911ab036021faf61 -r d1dd573cdce2bd122cbb0e98e947dc7992fe3ed0 lib/tool_shed/util/hg_util.py
--- a/lib/tool_shed/util/hg_util.py
+++ b/lib/tool_shed/util/hg_util.py
@@ -3,6 +3,7 @@
from time import gmtime
from time import strftime
+from galaxy.util import listify
from galaxy import eggs
eggs.require( 'mercurial' )
@@ -11,6 +12,26 @@
from mercurial import hg
from mercurial import ui
+log = logging.getLogger( __name__ )
+
+def clone_repository( repository_clone_url, repository_file_dir, ctx_rev ):
+ """
+ Clone the repository up to the specified changeset_revision. No subsequent revisions will be
+ present in the cloned repository.
+ """
+ try:
+ commands.clone( get_configured_ui(),
+ str( repository_clone_url ),
+ dest=str( repository_file_dir ),
+ pull=True,
+ noupdate=False,
+ rev=listify( str( ctx_rev ) ) )
+ return True, None
+ except Exception, e:
+ error_message = 'Error cloning repository: %s' % str( e )
+ log.debug( error_message )
+ return False, error_message
+
def get_changectx_for_changeset( repo, changeset_revision, **kwd ):
"""Retrieve a specified changectx from a repository."""
for changeset in repo.changelog:
@@ -28,7 +49,19 @@
# quiet = True
_ui.setconfig( 'ui', 'quiet', True )
return _ui
-
+
+def get_mercurial_default_options_dict( command, command_table=None, **kwd ):
+ '''Borrowed from repoman - get default parameters for a mercurial command.'''
+ if command_table is None:
+ command_table = commands.table
+ possible = cmdutil.findpossible( command, command_table )
+ if len( possible ) != 1:
+ raise Exception, 'unable to find mercurial command "%s"' % command
+ default_options_dict = dict( ( r[ 1 ].replace( '-', '_' ), r[ 2 ] ) for r in possible[ possible.keys()[ 0 ] ][ 1 ][ 1 ] )
+ for option in kwd:
+ default_options_dict[ option ] = kwd[ option ]
+ return default_options_dict
+
def get_readable_ctx_date( ctx ):
"""Convert the date of the changeset (the received ctx) to a human-readable date."""
t, tz = ctx.date()
@@ -106,3 +139,21 @@
rev = '-1'
label = "-1:%s" % changeset_revision
return rev, label
+
+def update_repository( repo, ctx_rev=None ):
+ """
+ Update the cloned repository to changeset_revision. It is critical that the installed repository is updated to the desired
+ changeset_revision before metadata is set because the process for setting metadata uses the repository files on disk.
+ """
+ # TODO: We may have files on disk in the repo directory that aren't being tracked, so they must be removed.
+ # The codes used to show the status of files are as follows.
+ # M = modified
+ # A = added
+ # R = removed
+ # C = clean
+ # ! = deleted, but still tracked
+ # ? = not tracked
+ # I = ignored
+ # It would be nice if we could use mercurial's purge extension to remove untracked files. The problem is that
+ # purging is not supported by the mercurial API.
+ commands.update( get_configured_ui(), repo, rev=ctx_rev )
diff -r 203623b931507dcd182e2521911ab036021faf61 -r d1dd573cdce2bd122cbb0e98e947dc7992fe3ed0 lib/tool_shed/util/metadata_util.py
--- a/lib/tool_shed/util/metadata_util.py
+++ b/lib/tool_shed/util/metadata_util.py
@@ -1799,7 +1799,7 @@
current_changeset_revision = str( repo.changectx( changeset ) )
ctx = repo.changectx( changeset )
log.debug( "Cloning repository changeset revision: %s", str( ctx.rev() ) )
- cloned_ok, error_message = suc.clone_repository( repository_clone_url, work_dir, str( ctx.rev() ) )
+ cloned_ok, error_message = hg_util.clone_repository( repository_clone_url, work_dir, str( ctx.rev() ) )
if cloned_ok:
log.debug( "Generating metadata for changset revision: %s", str( ctx.rev() ) )
current_metadata_dict, invalid_tups = generate_metadata_for_changeset_revision( app=trans.app,
@@ -1811,7 +1811,8 @@
resetting_all_metadata_on_repository=True,
updating_installed_repository=False,
persist=False )
- # We'll only display error messages for the repository tip (it may be better to display error messages for each installable changeset revision).
+ # We'll only display error messages for the repository tip (it may be better to display error
+ # messages for each installable changeset revision).
if current_changeset_revision == repository.tip( trans.app ):
invalid_file_tups.extend( invalid_tups )
if current_metadata_dict:
diff -r 203623b931507dcd182e2521911ab036021faf61 -r d1dd573cdce2bd122cbb0e98e947dc7992fe3ed0 lib/tool_shed/util/shed_util_common.py
--- a/lib/tool_shed/util/shed_util_common.py
+++ b/lib/tool_shed/util/shed_util_common.py
@@ -25,10 +25,7 @@
from galaxy import eggs
eggs.require( 'mercurial' )
-from mercurial import cmdutil
-from mercurial import commands
from mercurial import hg
-from mercurial import ui
eggs.require( 'markupsafe' )
import markupsafe
@@ -139,15 +136,6 @@
return repository_metadata.malicious
return False
-def changeset_is_valid( app, repository, changeset_revision ):
- """Make sure a changeset hash is valid for a specified repository."""
- repo = hg.repository( hg_util.get_configured_ui(), repository.repo_path( app ) )
- for changeset in repo.changelog:
- changeset_hash = str( repo.changectx( changeset ) )
- if changeset_revision == changeset_hash:
- return True
- return False
-
def check_or_update_tool_shed_status_for_installed_repository( trans, repository ):
updated = False
tool_shed_status_dict = get_tool_shed_status_for_installed_repository( trans.app, repository )
@@ -162,21 +150,6 @@
ok = False
return ok, updated
-def clone_repository( repository_clone_url, repository_file_dir, ctx_rev ):
- """Clone the repository up to the specified changeset_revision. No subsequent revisions will be present in the cloned repository."""
- try:
- commands.clone( hg_util.get_configured_ui(),
- str( repository_clone_url ),
- dest=str( repository_file_dir ),
- pull=True,
- noupdate=False,
- rev=util.listify( str( ctx_rev ) ) )
- return True, None
- except Exception, e:
- error_message = 'Error cloning repository: %s' % str( e )
- log.debug( error_message )
- return False, error_message
-
def config_elems_to_xml_file( app, config_elems, config_filename, tool_path ):
"""Persist the current in-memory list of config_elems to a file named by the value of config_filename."""
fd, filename = tempfile.mkstemp( prefix="tmp-toolshed-cetxf" )
@@ -655,18 +628,6 @@
return changeset_revisions[ -1 ]
return INITIAL_CHANGELOG_HASH
-def get_mercurial_default_options_dict( command, command_table=None, **kwd ):
- '''Borrowed from repoman - get default parameters for a mercurial command.'''
- if command_table is None:
- command_table = commands.table
- possible = cmdutil.findpossible( command, command_table )
- if len( possible ) != 1:
- raise Exception, 'unable to find mercurial command "%s"' % command
- default_options_dict = dict( ( r[ 1 ].replace( '-', '_' ), r[ 2 ] ) for r in possible[ possible.keys()[ 0 ] ][ 1 ][ 1 ] )
- for option in kwd:
- default_options_dict[ option ] = kwd[ option ]
- return default_options_dict
-
def get_named_tmpfile_from_ctx( ctx, filename, dir ):
"""Return a named temporary file created from a specified file with a given name included in a repository changeset revision."""
filename = strip_path( filename )
@@ -1784,24 +1745,6 @@
config_elems.append( elem )
config_elems_to_xml_file( app, config_elems, shed_tool_conf, tool_path )
-def update_repository( repo, ctx_rev=None ):
- """
- Update the cloned repository to changeset_revision. It is critical that the installed repository is updated to the desired
- changeset_revision before metadata is set because the process for setting metadata uses the repository files on disk.
- """
- # TODO: We may have files on disk in the repo directory that aren't being tracked, so they must be removed.
- # The codes used to show the status of files are as follows.
- # M = modified
- # A = added
- # R = removed
- # C = clean
- # ! = deleted, but still tracked
- # ? = not tracked
- # I = ignored
- # It would be nice if we could use mercurial's purge extension to remove untracked files. The problem is that
- # purging is not supported by the mercurial API.
- commands.update( hg_util.get_configured_ui(), repo, rev=ctx_rev )
-
def update_tool_shed_repository_status( app, tool_shed_repository, status, error_message=None ):
"""Update the status of a tool shed repository in the process of being installed into Galaxy."""
context = app.install_model.context
diff -r 203623b931507dcd182e2521911ab036021faf61 -r d1dd573cdce2bd122cbb0e98e947dc7992fe3ed0 test/tool_shed/base/twilltestcase.py
--- a/test/tool_shed/base/twilltestcase.py
+++ b/test/tool_shed/base/twilltestcase.py
@@ -19,6 +19,7 @@
from galaxy.web import security
from tool_shed.util.encoding_util import tool_shed_encode
from tool_shed.util import shed_util_common as suc
+from tool_shed.util import hg_util
from tool_shed.util import xml_util
from galaxy import eggs
@@ -260,7 +261,7 @@
def clone_repository( self, repository, destination_path ):
url = '%s/repos/%s/%s' % ( self.url, repository.user.username, repository.name )
- success, message = suc.clone_repository( url, destination_path, self.get_repository_tip( repository ) )
+ success, message = hg_util.clone_repository( url, destination_path, self.get_repository_tip( repository ) )
assert success is True, message
def commit_and_push( self, repository, hgrepo, options, username, password ):
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: greg: Fix for the execute_step() method in the SetEnvironment class.
by commits-noreply@bitbucket.org 24 Apr '14
by commits-noreply@bitbucket.org 24 Apr '14
24 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/203623b93150/
Changeset: 203623b93150
User: greg
Date: 2014-04-24 21:11:43
Summary: Fix for the execute_step() method in the SetEnvironment class.
Affected #: 1 file
diff -r 99056011d2dbbfa64f8b9ab56871e1d4da279f69 -r 203623b931507dcd182e2521911ab036021faf61 lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py
--- a/lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py
+++ b/lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py
@@ -450,14 +450,20 @@
env_var_dicts = action_dict[ 'environment_variable' ]
for env_var_dict in env_var_dicts:
# Check for the presence of the $ENV[] key string and populate it if possible.
- env_var_dict = self.handle_environment_variables( app, tool_dependency, install_dir, env_var_dict, cmds )
+ env_var_dict = self.handle_environment_variables( app=app,
+ install_environment=install_environment,
+ tool_dependency=tool_dependency,
+ install_dir=install_dir,
+ env_var_dict=env_var_dict,
+ set_prior_environment_commands=cmds )
env_file_builder.append_line( **env_var_dict )
# The caller should check the status of the returned tool_dependency since return_code is not
# returned by this function.
return_code = env_file_builder.return_code
return tool_dependency, None, None
- def handle_environment_variables( self, app, tool_dependency, install_dir, env_var_dict, set_prior_environment_commands ):
+ def handle_environment_variables( self, app, install_environment, tool_dependency, install_dir, env_var_dict,
+ set_prior_environment_commands ):
"""
This method works with with a combination of three tool dependency definition tag sets, which are defined
in the tool_dependencies.xml file in the order discussed here. The example for this discussion is the
@@ -539,7 +545,6 @@
set_prior_environment_commands.append( 'echo %s: $%s' % ( inherited_env_var_name, inherited_env_var_name ) )
command = ' ; '.join( set_prior_environment_commands )
# Run the command and capture the output.
- install_environment = recipe_manager.InstallEnvironment()
command_return = install_environment.handle_command( app, tool_dependency, install_dir, command, return_output=True )
# And extract anything labeled with the name of the environment variable we're populating here.
if '%s: ' % inherited_env_var_name in command_return:
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: greg: Fix tool shed unit tests I broke with my last commit.
by commits-noreply@bitbucket.org 24 Apr '14
by commits-noreply@bitbucket.org 24 Apr '14
24 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/99056011d2db/
Changeset: 99056011d2db
User: greg
Date: 2014-04-24 19:45:04
Summary: Fix tool shed unit tests I broke with my last commit.
Affected #: 2 files
diff -r ffafb6350791453b31c841e5462314bcd04ffa88 -r 99056011d2dbbfa64f8b9ab56871e1d4da279f69 test/unit/tool_shed_unit_tests/test_fabric_util.py
--- a/test/unit/tool_shed_unit_tests/test_fabric_util.py
+++ b/test/unit/tool_shed_unit_tests/test_fabric_util.py
@@ -1,6 +1,5 @@
from contextlib import contextmanager
-from tool_shed.galaxy_install.recipe.recipe_manager import EnvFileBuilder
-from tool_shed.galaxy_install.tool_dependencies import fabric_util
+from tool_shed.galaxy_install.tool_dependencies.recipe.recipe_manager import EnvFileBuilder
def test_env_file_builder():
@@ -10,10 +9,10 @@
mock_return = dict(value=0)
def mock_file_append( text, file_path, **kwds ):
- added_lines.append(text)
- return mock_return["value"]
+ added_lines.append( text )
+ return mock_return[ "value" ]
- with __mock_fabric_util_method("file_append", mock_file_append):
+ with __mock_env_file_builder_method( env_file_builder, "file_append", mock_file_append ):
env_file_builder.append_line( name="PATH", action="prepend_to", value="/usr/bin/local/R" )
assert added_lines == [ "PATH=/usr/bin/local/R:$PATH; export PATH" ]
assert env_file_builder.return_code == 0
@@ -37,10 +36,10 @@
## Poor man's mocking. Need to get a real mocking library as real Galaxy development
## dependnecy.
@contextmanager
-def __mock_fabric_util_method(name, mock_method):
- real_method = getattr(fabric_util, name)
+def __mock_env_file_builder_method( env_file_builder, name, mock_method ):
+ real_method = getattr( env_file_builder, name )
try:
- setattr(fabric_util, name, mock_method)
+ setattr( env_file_builder, name, mock_method )
yield
finally:
- setattr(fabric_util, name, real_method)
+ setattr( env_file_builder, name, real_method )
diff -r ffafb6350791453b31c841e5462314bcd04ffa88 -r 99056011d2dbbfa64f8b9ab56871e1d4da279f69 test/unit/tool_shed_unit_tests/test_td_common_util.py
--- a/test/unit/tool_shed_unit_tests/test_td_common_util.py
+++ b/test/unit/tool_shed_unit_tests/test_td_common_util.py
@@ -4,7 +4,8 @@
from tool_shed.galaxy_install.tool_dependencies import fabric_util
from tool_shed.galaxy_install.tool_dependencies import td_common_util
-from tool_shed.galaxy_install.recipe.recipe_manager import EnvFileBuilder
+from tool_shed.galaxy_install.tool_dependencies.recipe.recipe_manager import EnvFileBuilder
+
TEST_DEPENDENCIES_DIR = "/opt/galaxy/dependencies"
TEST_INSTALL_DIR = "%s/test_install_dir" % TEST_DEPENDENCIES_DIR
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: davebgx: Get tool dependency status from the install model.
by commits-noreply@bitbucket.org 24 Apr '14
by commits-noreply@bitbucket.org 24 Apr '14
24 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/ffafb6350791/
Changeset: ffafb6350791
User: davebgx
Date: 2014-04-24 17:24:24
Summary: Get tool dependency status from the install model.
Affected #: 1 file
diff -r cf9cd1027e2a7e3f29201125fbbacf929ef55d0b -r ffafb6350791453b31c841e5462314bcd04ffa88 lib/tool_shed/galaxy_install/tool_dependencies/fabric_util.py
--- a/lib/tool_shed/galaxy_install/tool_dependencies/fabric_util.py
+++ b/lib/tool_shed/galaxy_install/tool_dependencies/fabric_util.py
@@ -86,7 +86,7 @@
install_dir=install_dir,
current_dir=current_dir,
initial_download=False )
- if tool_dependency.status in [ app.model.ToolDependency.installation_status.ERROR ]:
+ if tool_dependency.status in [ app.install_model.ToolDependency.installation_status.ERROR ]:
# If the tool_dependency status is in an error state, return it with no additional
# processing.
return tool_dependency
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: davebgx: Update tool shed twilltestcase methods to reflect changes in the base twilltestcase's visit_url method. Fix functional tests for the tool shed. Update test tool dependencies to not actually compile EMBOSS and freebayes.
by commits-noreply@bitbucket.org 24 Apr '14
by commits-noreply@bitbucket.org 24 Apr '14
24 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/cf9cd1027e2a/
Changeset: cf9cd1027e2a
User: davebgx
Date: 2014-04-24 17:23:03
Summary: Update tool shed twilltestcase methods to reflect changes in the base twilltestcase's visit_url method. Fix functional tests for the tool shed. Update test tool dependencies to not actually compile EMBOSS and freebayes.
Affected #: 4 files
diff -r f1cb12e876c659c456c0b10f577494f79211b7f4 -r cf9cd1027e2a7e3f29201125fbbacf929ef55d0b test/tool_shed/base/twilltestcase.py
--- a/test/tool_shed/base/twilltestcase.py
+++ b/test/tool_shed/base/twilltestcase.py
@@ -284,30 +284,6 @@
category = test_db_util.get_category_by_name( kwd[ 'name' ] )
return category
- def create_checkbox_query_string( self, field_name, value ):
- '''
- From galaxy.web.form_builder.CheckboxField:
- The hidden field is necessary because if the check box is not checked on the form, it will
- not be included in the request params. The hidden field ensure that this will happen. When
- parsing the request, the value 'true' in the hidden field actually means it is NOT checked.
- See the is_checked() method below. The prefix is necessary in each case to ensure functional
- correctness when the param is inside a conditional.
-
- This may look strange upon initial inspection, but see the comments in the get_html() method
- above for clarification. Basically, if value is not True, then it will always be a list with
- 2 input fields ( a checkbox and a hidden field ) if the checkbox is checked. If it is not
- checked, then value will be only the hidden field.
-
- The create_checkbox_query_string method emulates the described behavior with URL query parameters.
- This is currently necessary because twill does not correctly parse certain forms, so the test
- method has to visit the intended form target "manually".
- '''
- field_value = str( value ).lower()
- if value:
- return '%s=%s&%s=%s' % ( field_name, field_value, field_name, field_value )
- else:
- return '%s=%s' % ( field_name, field_value )
-
def create_repository_dependency( self,
repository=None,
repository_tuples=[],
@@ -547,7 +523,8 @@
def enable_email_alerts( self, repository, strings_displayed=[], strings_not_displayed=[] ):
repository_id = self.security.encode_id( repository.id )
- self.visit_url( '/repository/browse_repositories?operation=Receive+email+alerts&id=%s' % repository_id )
+ params = dict( operation='Receive email alerts', id=repository_id )
+ self.visit_url( '/repository/browse_repositories' )
self.check_for_strings( strings_displayed )
def escape_html( self, string, unescape=False ):
@@ -816,15 +793,19 @@
strings_not_displayed = []
self.visit_url( '/admin/roles' )
self.check_for_strings( strings_displayed, strings_not_displayed )
- url = '/admin/roles?operation=manage+users+and+groups&id=%s' % self.security.encode_id( role.id )
+ params = dict( operation='manage users and groups', id=self.security.encode_id( role.id ) )
+ url = '/admin/roles'
self.visit_url( url )
strings_displayed = [ common.test_user_1_email, common.test_user_2_email ]
self.check_for_strings( strings_displayed, strings_not_displayed )
# As elsewhere, twill limits the possibility of submitting the form, this time due to not executing the javascript
# attached to the role selection form. Visit the action url directly with the necessary parameters.
- url = '/admin/manage_users_and_groups_for_role?id=%s&in_users=%d&operation=manage+users+and+groups&role_members_edit_button=Save' % \
- ( self.security.encode_id( role.id ), user.id )
- self.visit_url( url )
+ params = dict( id=self.security.encode_id( role.id ),
+ in_users=user.id,
+ operation='manage users and groups',
+ role_members_edit_button='Save' )
+ url = '/admin/manage_users_and_groups_for_role'
+ self.visit_url( url, params )
strings_displayed = [ "Role '%s' has been updated" % role.name ]
self.check_for_strings( strings_displayed, strings_not_displayed )
@@ -1050,8 +1031,9 @@
self.check_for_strings( strings_displayed, strings_not_displayed )
def reactivate_repository( self, installed_repository ):
- url = '/admin_toolshed/browse_repositories?operation=activate+or+reinstall&id=%s' % self.security.encode_id( installed_repository.id )
- self.visit_galaxy_url( url )
+ params = dict( operation='activate or reinstall', id=self.security.encode_id( installed_repository.id ) )
+ url = '/admin_toolshed/browse_repositories'
+ self.visit_galaxy_url( url, params )
strings_displayed = [ installed_repository.name, 'repository has been activated' ]
self.check_for_strings( strings_displayed, [] )
@@ -1068,12 +1050,12 @@
self.check_for_strings( strings_displayed, strings_not_displayed=[] )
# Build the url that will simulate a filled-out form being submitted. Due to a limitation in twill, the reselect_tool_panel_section
# form doesn't get parsed correctly.
- repo_dependencies = self.create_checkbox_query_string( field_name='install_repository_dependencies', value=install_repository_dependencies )
- tool_dependencies = self.create_checkbox_query_string( field_name='install_tool_dependencies', value=install_tool_dependencies )
encoded_repository_id = self.security.encode_id( installed_repository.id )
- url = '/admin_toolshed/reinstall_repository?id=%s&%s&%s&no_changes=%s&new_tool_panel_section_label=%s' % \
- ( encoded_repository_id, repo_dependencies, tool_dependencies, str( no_changes ), new_tool_panel_section_label )
- self.visit_galaxy_url( url )
+ params = dict( id=encoded_repository_id, no_changes=no_changes, new_tool_panel_section_label=new_tool_panel_section_label )
+ checkbox_params = dict( install_repository_dependencies=install_repository_dependencies,
+ install_tool_dependencies=install_tool_dependencies )
+ url = '/admin_toolshed/reinstall_repository'
+ self.visit_galaxy_url( url, params=params, checkbox_params=checkbox_params )
# Manually initiate the install process, as with installing a repository. See comments in the
# initiate_installation_process method for details.
repository_ids = self.initiate_installation_process( install_tool_dependencies,
@@ -1429,8 +1411,9 @@
for tool in installed_repository.metadata[ 'tools' ]:
strings = list( strings_displayed )
strings.extend( [ tool[ 'id' ], tool[ 'description' ], tool[ 'version' ], tool[ 'guid' ], tool[ 'name' ] ] )
- url = '/admin_toolshed/view_tool_metadata?repository_id=%s&tool_id=%s' % ( repository_id, urllib.quote_plus( tool[ 'id' ] ) )
- self.visit_galaxy_url( url )
+ params = dict( repository_id=repository_id, tool_id=tool[ 'id' ] )
+ url = '/admin_toolshed/view_tool_metadata'
+ self.visit_galaxy_url( url, params )
self.check_for_strings( strings, strings_not_displayed )
def verify_unchanged_repository_metadata( self, repository ):
@@ -1451,9 +1434,9 @@
self.visit_galaxy_url( url )
self.check_for_strings( strings, strings_not_displayed )
- def visit_galaxy_url( self, url ):
+ def visit_galaxy_url( self, url, params=None, checkbox_params=None ):
url = '%s%s' % ( self.galaxy_url, url )
- self.visit_url( url )
+ self.visit_url( url, params=params, checkbox_params=checkbox_params )
def wait_for_repository_installation( self, repository_ids ):
final_states = [ galaxy_model.ToolShedRepository.installation_status.ERROR,
diff -r f1cb12e876c659c456c0b10f577494f79211b7f4 -r cf9cd1027e2a7e3f29201125fbbacf929ef55d0b test/tool_shed/functional/test_1087_install_updated_repository_dependencies.py
--- a/test/tool_shed/functional/test_1087_install_updated_repository_dependencies.py
+++ b/test/tool_shed/functional/test_1087_install_updated_repository_dependencies.py
@@ -111,8 +111,9 @@
convert_repository = self.test_db_util.get_repository_by_name_and_owner( convert_repository_name, common.test_user_1_name )
strings_displayed=[ 'Handle repository dependencies', 'convert_chars_1087', self.get_repository_tip( convert_repository ) ]
# Due to twill's limitations, only check for strings on the (redirected) reselect tool panel section page, don't actually reinstall.
- url = '/admin_toolshed/browse_repositories?operation=activate+or+reinstall&id=%s' % self.security.encode_id( installed_column_repository.id )
- self.visit_galaxy_url( url )
+ params = dict( operation='activate or reinstall', id=self.security.encode_id( installed_column_repository.id ) )
+ url = '/admin_toolshed/browse_repositories'
+ self.visit_galaxy_url( url, params )
self.check_for_strings( strings_displayed )
strings_not_displayed = [ 'column_maker_1087' ]
- self.display_galaxy_browse_repositories_page( strings_not_displayed=strings_not_displayed )
+ self.display_galaxy_browse_repositories_page( strings_not_displayed=strings_not_displayed )
\ No newline at end of file
diff -r f1cb12e876c659c456c0b10f577494f79211b7f4 -r cf9cd1027e2a7e3f29201125fbbacf929ef55d0b test/tool_shed/test_data/emboss/emboss.tar
Binary file test/tool_shed/test_data/emboss/emboss.tar has changed
diff -r f1cb12e876c659c456c0b10f577494f79211b7f4 -r cf9cd1027e2a7e3f29201125fbbacf929ef55d0b test/tool_shed/test_data/freebayes/tool_dependencies.xml
--- a/test/tool_shed/test_data/freebayes/tool_dependencies.xml
+++ b/test/tool_shed/test_data/freebayes/tool_dependencies.xml
@@ -3,13 +3,7 @@
<package name="freebayes" version="0.9.4_9696d0ce8a962f7bb61c4791be5ce44312b81cf8"><install version="1.0"><actions>
- <action type="shell_command">git clone --recursive git://github.com/ekg/freebayes.git</action>
- <action type="shell_command">git reset --hard 9696d0ce8a962f7bb61c4791be5ce44312b81cf8</action>
- <action type="shell_command">make</action>
- <action type="move_directory_files">
- <source_directory>bin</source_directory>
- <destination_directory>$INSTALL_DIR/bin</destination_directory>
- </action>
+ <action type="shell_command">echo "Success."</action><action type="set_environment"><environment_variable name="PATH" action="prepend_to">$INSTALL_DIR/bin</environment_variable></action>
@@ -23,17 +17,7 @@
<package name="samtools" version="0.1.18"><install version="1.0"><actions>
- <action type="download_by_url">http://sourceforge.net/projects/samtools/files/samtools/0.1.18/samtools-0.1…</action>
- <action type="shell_command">sed -i .bak -e 's/-lcurses/-lncurses/g' Makefile</action>
- <action type="shell_command">make</action>
- <action type="move_file">
- <source>samtools</source>
- <destination>$INSTALL_DIR/bin</destination>
- </action>
- <action type="move_file">
- <source>misc/maq2sam-long</source>
- <destination>$INSTALL_DIR/bin</destination>
- </action>
+ <action type="shell_command">echo "Success."</action><action type="set_environment"><environment_variable name="PATH" action="prepend_to">$INSTALL_DIR/bin</environment_variable></action>
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: davebgx: Fix typo in step handler.
by commits-noreply@bitbucket.org 24 Apr '14
by commits-noreply@bitbucket.org 24 Apr '14
24 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/f1cb12e876c6/
Changeset: f1cb12e876c6
User: davebgx
Date: 2014-04-24 17:06:59
Summary: Fix typo in step handler.
Affected #: 1 file
diff -r 3b6e94371b8a8e996cc8e317de8cbfe45790b94e -r f1cb12e876c659c456c0b10f577494f79211b7f4 lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py
--- a/lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py
+++ b/lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py
@@ -592,7 +592,7 @@
install_environment.add_env_shell_file_paths( action_dict[ 'env_shell_file_paths' ] )
return tool_dependency, None, None
- def prepare_step( self, app, tool_dependency, action_elem, action_dict, install_dir, is_binary_downloa ):
+ def prepare_step( self, app, tool_dependency, action_elem, action_dict, install_dir, is_binary_download ):
# <action type="set_environment_for_install">
# <repository toolshed="http://localhost:9009/" name="package_numpy_1_7" owner="test" changeset_revision="c84c6a8be056">
# <package name="numpy" version="1.7.1" />
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: dannon: Add simplejson back again until 'anyjson' changes are pushed through bioblend.
by commits-noreply@bitbucket.org 24 Apr '14
by commits-noreply@bitbucket.org 24 Apr '14
24 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/3b6e94371b8a/
Changeset: 3b6e94371b8a
User: dannon
Date: 2014-04-24 17:03:23
Summary: Add simplejson back again until 'anyjson' changes are pushed through bioblend.
Affected #: 1 file
diff -r de54998e192b99bd70751d692969b508463e1805 -r 3b6e94371b8a8e996cc8e317de8cbfe45790b94e eggs.ini
--- a/eggs.ini
+++ b/eggs.ini
@@ -61,6 +61,7 @@
pytz = 2013.9
requests = 2.2.1
Routes = 1.12.3
+simplejson = 2.1.1
sqlalchemy_migrate = 0.7.2
ssh = 1.7.14
SVGFig = 1.1.6
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
24 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/de54998e192b/
Changeset: de54998e192b
User: greg
Date: 2014-04-24 16:46:56
Summary: Add a new recipe manager to support tool dependency package installation. Create new classes for each recipe step where classes contain both a prepare_step() and an execute_step() function. This implementation breaks up the very large loops in install_util.py (where recipe steps are prepared) and fabric_util.py (where recipe steps are executed). The recipe manager currently loads all of the recipe step classes when it is instantiated - this approach could be tweaked if desired.
Affected #: 11 files
diff -r 369bb0f7ebef50a72f36cf2f74d23f7d351d61c4 -r de54998e192b99bd70751d692969b508463e1805 lib/tool_shed/galaxy_install/tool_dependencies/fabric_util.py
--- a/lib/tool_shed/galaxy_install/tool_dependencies/fabric_util.py
+++ b/lib/tool_shed/galaxy_install/tool_dependencies/fabric_util.py
@@ -1,765 +1,64 @@
-# For Python 2.5
-from __future__ import with_statement
-
import logging
import os
-import Queue
-import shutil
-import stat
-import subprocess
-import sys
-import tempfile
-import td_common_util
-import threading
-import time
-import shlex
-from contextlib import contextmanager
-from galaxy.util import DATABASE_MAX_STRING_SIZE
-from galaxy.util import DATABASE_MAX_STRING_SIZE_PRETTY
-from galaxy.util import shrink_string_by_size
-from galaxy.util import unicodify
-from galaxy.util.template import fill_template
from galaxy import eggs
-eggs.require( 'ssh' )
-eggs.require( 'paramiko' )
eggs.require( 'Fabric' )
-from fabric import state
from fabric.api import env
-from fabric.api import hide
from fabric.api import lcd
-from fabric.api import settings
-from fabric.api import prefix
-from fabric.operations import _AttributeString
+
+from tool_shed.galaxy_install.tool_dependencies.recipe.recipe_manager import EnvFileBuilder
+from tool_shed.galaxy_install.tool_dependencies.recipe.recipe_manager import InstallEnvironment
+from tool_shed.galaxy_install.tool_dependencies.recipe.recipe_manager import RecipeManager
log = logging.getLogger( __name__ )
-INSTALLATION_LOG = 'INSTALLATION.log'
-VIRTUALENV_URL = 'https://pypi.python.org/packages/source/v/virtualenv/virtualenv-1.9.1.tar.gz'
-
-
-class AsynchronousReader( threading.Thread ):
- """
- A helper class to implement asynchronous reading of a stream in a separate thread. Read lines are pushed
- onto a queue to be consumed in another thread.
- """
-
- def __init__( self, fd, queue ):
- threading.Thread.__init__( self )
- self._fd = fd
- self._queue = queue
- self.lines = []
-
- def run( self ):
- """Read lines and put them on the queue."""
- thread_lock = threading.Lock()
- thread_lock.acquire()
- for line in iter( self._fd.readline, '' ):
- stripped_line = line.rstrip()
- self.lines.append( stripped_line )
- self._queue.put( stripped_line )
- thread_lock.release()
-
- def installation_complete( self ):
- """Make sure there is more installation and compilation logging content expected."""
- return not self.is_alive() and self._queue.empty()
-
-
-class EnvFileBuilder( object ):
-
- def __init__( self, install_dir ):
- self.install_dir = install_dir
- self.return_code = 0
-
- def append_line( self, make_executable=True, **kwd ):
- env_var_dict = dict( **kwd )
- env_entry, env_file = self.create_or_update_env_shell_file( self.install_dir, env_var_dict )
- return_code = file_append( env_entry, env_file, make_executable=make_executable )
- self.return_code = self.return_code or return_code
- return self.return_code
-
- @staticmethod
- def create_or_update_env_shell_file( install_dir, env_var_dict ):
- env_var_action = env_var_dict[ 'action' ]
- env_var_value = env_var_dict[ 'value' ]
- if env_var_action in [ 'prepend_to', 'set_to', 'append_to' ]:
- env_var_name = env_var_dict[ 'name' ]
- if env_var_action == 'prepend_to':
- changed_value = '%s:$%s' % ( env_var_value, env_var_name )
- elif env_var_action == 'set_to':
- changed_value = '%s' % env_var_value
- elif env_var_action == 'append_to':
- changed_value = '$%s:%s' % ( env_var_name, env_var_value )
- line = "%s=%s; export %s" % ( env_var_name, changed_value, env_var_name )
- elif env_var_action == "source":
- line = "if [ -f %s ] ; then . %s ; fi" % ( env_var_value, env_var_value )
- else:
- raise Exception( "Unknown shell file action %s" % env_var_action )
- env_shell_file_path = os.path.join( install_dir, 'env.sh' )
- return line, env_shell_file_path
-
-
-class InstallEnvironment( object ):
- """Object describing the environment built up as part of the process of building and installing a package."""
-
- def add_env_shell_file_paths( self, paths ):
- for path in paths:
- self.env_shell_file_paths.append( str( path ) )
-
- def build_command( self, command, action_type='shell_command' ):
- """
- Build command line for execution from simple command, but
- configuring environment described by this object.
- """
- env_cmds = self.environment_commands( action_type )
- return '\n'.join( env_cmds + [ command ] )
-
- def __call__( self, install_dir ):
- with settings( warn_only=True, **td_common_util.get_env_var_values( install_dir ) ):
- with prefix( self.__setup_environment() ):
- yield
-
- def environment_commands( self, action_type ):
- """Build a list of commands used to construct the environment described by this object."""
- cmds = []
- for env_shell_file_path in self.env_shell_file_paths:
- if os.path.exists( env_shell_file_path ):
- for env_setting in open( env_shell_file_path ):
- cmds.append( env_setting.strip( '\n' ) )
- else:
- log.debug( 'Invalid file %s specified, ignoring %s action.' % ( str( env_shell_file_path ), str( action_type ) ) )
- return cmds
-
- def environment_dict( self, action_type='template_command' ):
- env_vars = dict()
- for env_shell_file_path in self.env_shell_file_paths:
- if os.path.exists( env_shell_file_path ):
- for env_setting in open( env_shell_file_path ):
- env_string = env_setting.split( ';' )[ 0 ]
- env_name, env_path = env_string.split( '=' )
- env_vars[ env_name ] = env_path
- else:
- log.debug( 'Invalid file %s specified, ignoring template_command action.' % str( env_shell_file_path ) )
- return env_vars
-
- def __init__( self ):
- self.env_shell_file_paths = []
-
- def __setup_environment( self ):
- return "&&".join( [ ". %s" % file for file in self.__valid_env_shell_file_paths() ] )
-
- def __valid_env_shell_file_paths( self ):
- return [ file for file in self.env_shell_file_paths if os.path.exists( file ) ]
+INSTALL_ACTIONS = [ 'download_binary', 'download_by_url', 'download_file', 'setup_perl_environmnet',
+ 'setup_r_environmnet', 'setup_ruby_environmnet', 'shell_command' ]
def check_fabric_version():
version = env.version
if int( version.split( "." )[ 0 ] ) < 1:
raise NotImplementedError( "Install Fabric version 1.0 or later." )
-def close_file_descriptor( fd ):
- """Attempt to close a file descriptor."""
- start_timer = time.time()
- error = ''
- while True:
- try:
- fd.close()
- break
- except IOError, e:
- # Undoubtedly close() was called during a concurrent operation on the same file object.
- log.debug( 'Error closing file descriptor: %s' % str( e ) )
- time.sleep( .5 )
- current_wait_time = time.time() - start_timer
- if current_wait_time >= 600:
- error = 'Error closing file descriptor: %s' % str( e )
- break
- return error
-
-def enqueue_output( stdout, stdout_queue, stderr, stderr_queue ):
- """
- This method places streamed stdout and stderr into a threaded IPC queue target. Received data
- is printed and saved to that thread's queue. The calling thread can then retrieve the data using
- thread.stdout and thread.stderr.
- """
- stdout_logger = logging.getLogger( 'fabric_util.STDOUT' )
- stderr_logger = logging.getLogger( 'fabric_util.STDERR' )
- for line in iter( stdout.readline, '' ):
- output = line.rstrip()
- stdout_logger.debug( output )
- stdout_queue.put( output )
- stdout_queue.put( None )
- for line in iter( stderr.readline, '' ):
- output = line.rstrip()
- stderr_logger.debug( output )
- stderr_queue.put( output )
- stderr_queue.put( None )
-
-def file_append( text, file_path, make_executable=True ):
- """
- Append a line to a file unless the line already exists in the file. This method creates the file if
- it doesn't exist. If make_executable is True, the permissions on the file are set to executable by
- the owner.
- """
- file_dir = os.path.dirname( file_path )
- if not os.path.exists( file_dir ):
- try:
- os.makedirs( file_dir )
- except Exception, e:
- log.exception( str( e ) )
- return 1
- if os.path.exists( file_path ):
- try:
- new_env_file_contents = []
- env_file_contents = file( file_path, 'r' ).readlines()
- # Clean out blank lines from the env.sh file.
- for line in env_file_contents:
- line = line.rstrip()
- if line:
- new_env_file_contents.append( line )
- env_file_contents = new_env_file_contents
- except Exception, e:
- log.exception( str( e ) )
- return 1
- else:
- env_file_handle = open( file_path, 'w' )
- env_file_handle.close()
- env_file_contents = []
- if make_executable:
- # Explicitly set the file's executable bits.
- try:
- os.chmod( file_path, int( '111', base=8 ) | os.stat( file_path )[ stat.ST_MODE ] )
- except Exception, e:
- log.exception( str( e ) )
- return 1
- # Convert the received text to a list, in order to support adding one or more lines to the file.
- if isinstance( text, basestring ):
- text = [ text ]
- for line in text:
- line = line.rstrip()
- if line and line not in env_file_contents:
- env_file_contents.append( line )
- try:
- file( file_path, 'w' ).write( '\n'.join( env_file_contents ) )
- except Exception, e:
- log.exception( str( e ) )
- return 1
- return 0
-
-def filter_actions_after_binary_installation( actions ):
- '''Filter out actions that should not be processed if a binary download succeeded.'''
- filtered_actions = []
- for action in actions:
- action_type, action_dict = action
- if action_type in [ 'set_environment', 'chmod', 'download_binary' ]:
- filtered_actions.append( action )
- return filtered_actions
-
-def handle_action_shell_file_paths( env_file_builder, action_dict ):
- shell_file_paths = action_dict.get( 'action_shell_file_paths', [] )
- for shell_file_path in shell_file_paths:
- env_file_builder.append_line( action="source", value=shell_file_path )
-
-def handle_command( app, tool_dependency, install_dir, cmd, return_output=False ):
- """
- Handle a command by determining if it is "simple" or "complex" and redirecting appropriately and then
- logging the results.
- """
- context = app.install_model.context
- command = str( cmd )
- output = handle_complex_command( command )
- log_results( cmd, output, os.path.join( install_dir, INSTALLATION_LOG ) )
- stdout = output.stdout
- stderr = output.stderr
- if len( stdout ) > DATABASE_MAX_STRING_SIZE:
- print "Length of stdout > %s, so only a portion will be saved in the database." % str( DATABASE_MAX_STRING_SIZE_PRETTY )
- stdout = shrink_string_by_size( stdout, DATABASE_MAX_STRING_SIZE, join_by="\n..\n", left_larger=True, beginning_on_size_error=True )
- if len( stderr ) > DATABASE_MAX_STRING_SIZE:
- print "Length of stderr > %s, so only a portion will be saved in the database." % str( DATABASE_MAX_STRING_SIZE_PRETTY )
- stderr = shrink_string_by_size( stderr, DATABASE_MAX_STRING_SIZE, join_by="\n..\n", left_larger=True, beginning_on_size_error=True )
- if output.return_code not in [ 0 ]:
- tool_dependency.status = app.install_model.ToolDependency.installation_status.ERROR
- if stderr:
- tool_dependency.error_message = unicodify( stderr )
- elif stdout:
- tool_dependency.error_message = unicodify( stdout )
- else:
- # We have a problem if there was no stdout and no stderr.
- tool_dependency.error_message = "Unknown error occurred executing shell command %s, return_code: %s" % \
- ( str( cmd ), str( output.return_code ) )
- context.add( tool_dependency )
- context.flush()
- if return_output:
- return output
- return output.return_code
-
-def handle_complex_command( command ):
- """
- Wrap subprocess.Popen in such a way that the stderr and stdout from running a shell command will
- be captured and logged in nearly real time. This is similar to fabric.local, but allows us to
- retain control over the process. This method is named "complex" because it uses queues and
- threads to execute a command while capturing and displaying the output.
- """
- # Launch the command as subprocess. A bufsize of 1 means line buffered.
- process_handle = subprocess.Popen( str( command ),
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- bufsize=1,
- close_fds=False,
- shell=True,
- cwd=state.env[ 'lcwd' ] )
- pid = process_handle.pid
- # Launch the asynchronous readers of the process' stdout and stderr.
- stdout_queue = Queue.Queue()
- stdout_reader = AsynchronousReader( process_handle.stdout, stdout_queue )
- stdout_reader.start()
- stderr_queue = Queue.Queue()
- stderr_reader = AsynchronousReader( process_handle.stderr, stderr_queue )
- stderr_reader.start()
- # Place streamed stdout and stderr into a threaded IPC queue target so it can
- # be printed and stored for later retrieval when generating the INSTALLATION.log.
- stdio_thread = threading.Thread( target=enqueue_output,
- args=( process_handle.stdout,
- stdout_queue,
- process_handle.stderr,
- stderr_queue ) )
- thread_lock = threading.Lock()
- thread_lock.acquire()
- stdio_thread.start()
- # Check the queues for output until there is nothing more to get.
- start_timer = time.time()
- while not stdout_reader.installation_complete() or not stderr_reader.installation_complete():
- # Show what we received from standard output.
- while not stdout_queue.empty():
- try:
- line = stdout_queue.get()
- except Queue.Empty:
- line = None
- break
- if line:
- print line
- start_timer = time.time()
- else:
- break
- # Show what we received from standard error.
- while not stderr_queue.empty():
- try:
- line = stderr_queue.get()
- except Queue.Empty:
- line = None
- break
- if line:
- print line
- start_timer = time.time()
- else:
- stderr_queue.task_done()
- break
- # Sleep a bit before asking the readers again.
- time.sleep( .1 )
- current_wait_time = time.time() - start_timer
- if stdout_queue.empty() and stderr_queue.empty() and current_wait_time > td_common_util.NO_OUTPUT_TIMEOUT:
- err_msg = "\nShutting down process id %s because it generated no output for the defined timeout period of %.1f seconds.\n" % \
- ( pid, td_common_util.NO_OUTPUT_TIMEOUT )
- stderr_reader.lines.append( err_msg )
- process_handle.kill()
- break
- thread_lock.release()
- # Wait until each of the threads we've started terminate. The following calls will block each thread
- # until it terminates either normally, through an unhandled exception, or until the timeout occurs.
- stdio_thread.join( td_common_util.NO_OUTPUT_TIMEOUT )
- stdout_reader.join( td_common_util.NO_OUTPUT_TIMEOUT )
- stderr_reader.join( td_common_util.NO_OUTPUT_TIMEOUT )
- # Close subprocess' file descriptors.
- error = close_file_descriptor( process_handle.stdout )
- error = close_file_descriptor( process_handle.stderr )
- stdout = '\n'.join( stdout_reader.lines )
- stderr = '\n'.join( stderr_reader.lines )
- # Handle error condition (deal with stdout being None, too)
- output = _AttributeString( stdout.strip() if stdout else "" )
- errors = _AttributeString( stderr.strip() if stderr else "" )
- # Make sure the process has finished.
- process_handle.poll()
- output.return_code = process_handle.returncode
- output.stderr = errors
- return output
-
-def handle_environment_variables( app, tool_dependency, install_dir, env_var_dict, set_prior_environment_commands ):
- """
- This method works with with a combination of three tool dependency definition tag sets, which are defined
- in the tool_dependencies.xml file in the order discussed here. The example for this discussion is the
- tool_dependencies.xml file contained in the osra repository, which is available at:
-
- http://testtoolshed.g2.bx.psu.edu/view/bgruening/osra
-
- The first tag set defines a complex repository dependency like this. This tag set ensures that changeset
- revision XXX of the repository named package_graphicsmagick_1_3 owned by YYY in the tool shed ZZZ has been
- previously installed.
-
- <tool_dependency>
- <package name="graphicsmagick" version="1.3.18">
- <repository changeset_revision="XXX" name="package_graphicsmagick_1_3" owner="YYY" prior_installation_required="True" toolshed="ZZZ" />
- </package>
- ...
-
- * By the way, there is an env.sh file associated with version 1.3.18 of the graphicsmagick package which looks
- something like this (we'll reference this file later in this discussion.
- ----
- GRAPHICSMAGICK_ROOT_DIR=/<my configured tool dependency path>/graphicsmagick/1.3.18/YYY/package_graphicsmagick_1_3/XXX/gmagick;
- export GRAPHICSMAGICK_ROOT_DIR
- ----
-
- The second tag set defines a specific package dependency that has been previously installed (guaranteed by the
- tag set discussed above) and compiled, where the compiled dependency is needed by the tool dependency currently
- being installed (osra version 2.0.0 in this case) and complied in order for its installation and compilation to
- succeed. This tag set is contained within the <package name="osra" version="2.0.0"> tag set, which implies that
- version 2.0.0 of the osra package requires version 1.3.18 of the graphicsmagick package in order to successfully
- compile. When this tag set is handled, one of the effects is that the env.sh file associated with graphicsmagick
- version 1.3.18 is "sourced", which undoubtedly sets or alters certain environment variables (e.g. PATH, PYTHONPATH,
- etc).
-
- <!-- populate the environment variables from the dependent repositories -->
- <action type="set_environment_for_install">
- <repository changeset_revision="XXX" name="package_graphicsmagick_1_3" owner="YYY" toolshed="ZZZ">
- <package name="graphicsmagick" version="1.3.18" />
- </repository>
- </action>
-
- The third tag set enables discovery of the same required package dependency discussed above for correctly compiling
- the osra version 2.0.0 package, but in this case the package can be discovered at tool execution time. Using the
- $ENV[] option as shown in this example, the value of the environment variable named GRAPHICSMAGICK_ROOT_DIR (which
- was set in the environment using the second tag set described above) will be used to automatically alter the env.sh
- file associated with the osra version 2.0.0 tool dependency when it is installed into Galaxy. * Refer to where we
- discussed the env.sh file for version 1.3.18 of the graphicsmagick package above.
-
- <action type="set_environment">
- <environment_variable action="prepend_to" name="LD_LIBRARY_PATH">$ENV[GRAPHICSMAGICK_ROOT_DIR]/lib/</environment_variable>
- <environment_variable action="prepend_to" name="LD_LIBRARY_PATH">$INSTALL_DIR/potrace/build/lib/</environment_variable>
- <environment_variable action="prepend_to" name="PATH">$INSTALL_DIR/bin</environment_variable>
- <!-- OSRA_DATA_FILES is only used by the galaxy wrapper and is not part of OSRA -->
- <environment_variable action="set_to" name="OSRA_DATA_FILES">$INSTALL_DIR/share</environment_variable>
- </action>
-
- The above tag will produce an env.sh file for version 2.0.0 of the osra package when it it installed into Galaxy
- that looks something like this. Notice that the path to the gmagick binary is included here since it expands the
- defined $ENV[GRAPHICSMAGICK_ROOT_DIR] value in the above tag set.
-
- ----
- LD_LIBRARY_PATH=/<my configured tool dependency path>/graphicsmagick/1.3.18/YYY/package_graphicsmagick_1_3/XXX/gmagick/lib/:$LD_LIBRARY_PATH;
- export LD_LIBRARY_PATH
- LD_LIBRARY_PATH=/<my configured tool dependency path>/osra/1.4.0/YYY/depends_on/XXX/potrace/build/lib/:$LD_LIBRARY_PATH;
- export LD_LIBRARY_PATH
- PATH=/<my configured tool dependency path>/osra/1.4.0/YYY/depends_on/XXX/bin:$PATH;
- export PATH
- OSRA_DATA_FILES=/<my configured tool dependency path>/osra/1.4.0/YYY/depends_on/XXX/share;
- export OSRA_DATA_FILES
- ----
- """
- env_var_value = env_var_dict[ 'value' ]
- # env_var_value is the text of an environment variable tag like this: <environment_variable action="prepend_to" name="LD_LIBRARY_PATH">
- # Here is an example of what env_var_value could look like: $ENV[GRAPHICSMAGICK_ROOT_DIR]/lib/
- if '$ENV[' in env_var_value and ']' in env_var_value:
- # Pull out the name of the environment variable to populate.
- inherited_env_var_name = env_var_value.split( '[' )[1].split( ']' )[0]
- to_replace = '$ENV[%s]' % inherited_env_var_name
- # Build a command line that outputs VARIABLE_NAME: <the value of the variable>.
- set_prior_environment_commands.append( 'echo %s: $%s' % ( inherited_env_var_name, inherited_env_var_name ) )
- command = ' ; '.join( set_prior_environment_commands )
- # Run the command and capture the output.
- command_return = handle_command( app, tool_dependency, install_dir, command, return_output=True )
- # And extract anything labeled with the name of the environment variable we're populating here.
- if '%s: ' % inherited_env_var_name in command_return:
- environment_variable_value = command_return.split( '\n' )
- for line in environment_variable_value:
- if line.startswith( inherited_env_var_name ):
- inherited_env_var_value = line.replace( '%s: ' % inherited_env_var_name, '' )
- log.info( 'Replacing %s with %s in env.sh for this repository.', to_replace, inherited_env_var_value )
- env_var_value = env_var_value.replace( to_replace, inherited_env_var_value )
- else:
- # If the return is empty, replace the original $ENV[] with nothing, to avoid any shell misparsings later on.
- log.error( 'Environment variable %s not found, removing from set_environment.', inherited_env_var_name )
- env_var_value = env_var_value.replace( to_replace, '$%s' % inherited_env_var_name )
- env_var_dict[ 'value' ] = env_var_value
- return env_var_dict
-
-def install_virtualenv( app, venv_dir ):
- if not os.path.exists( venv_dir ):
- with make_tmp_dir() as work_dir:
- downloaded_filename = VIRTUALENV_URL.rsplit('/', 1)[-1]
- try:
- dir = td_common_util.url_download( work_dir, downloaded_filename, VIRTUALENV_URL )
- except:
- log.error( "Failed to download virtualenv: td_common_util.url_download( '%s', '%s', '%s' ) threw an exception", work_dir, downloaded_filename, VIRTUALENV_URL )
- return False
- full_path_to_dir = os.path.abspath( os.path.join( work_dir, dir ) )
- shutil.move( full_path_to_dir, venv_dir )
- return True
-
def install_and_build_package( app, tool_dependency, actions_dict ):
"""Install a Galaxy tool dependency package either via a url or a mercurial or git clone command."""
install_dir = actions_dict[ 'install_dir' ]
package_name = actions_dict[ 'package_name' ]
actions = actions_dict.get( 'actions', None )
filtered_actions = []
+ env_file_builder = EnvFileBuilder( install_dir )
install_environment = InstallEnvironment()
+ recipe_manager = RecipeManager()
if actions:
- with make_tmp_dir() as work_dir:
+ with install_environment.make_tmp_dir() as work_dir:
with lcd( work_dir ):
- # The first action in the list of actions will be the one that defines the installation process. There
- # are currently three supported processes; download_binary, download_by_url and clone via a "shell_command"
- # action type.
+ # The first action in the list of actions will be the one that defines the initial download process.
+ # There are currently three supported actions; download_binary, download_by_url and clone via a
+ # shell_command action type. The recipe steps will be filtered at this stage in the process, with
+ # the filtered actions being used in the next stage below. The installation directory (i.e., dir)
+ # is also defined in this stage and is used in the next stage below when defining current_dir.
action_type, action_dict = actions[ 0 ]
- if action_type == 'download_binary':
- url = action_dict[ 'url' ]
- # Get the target directory for this download, if the user has specified one. Default to the root of $INSTALL_DIR.
- target_directory = action_dict.get( 'target_directory', None )
- # Attempt to download a binary from the specified URL.
- log.debug( 'Attempting to download from %s to %s', url, str( target_directory ) )
- downloaded_filename = None
- try:
- downloaded_filename = td_common_util.download_binary( url, work_dir )
- # Filter out any actions that are not download_binary, chmod, or set_environment.
- filtered_actions = filter_actions_after_binary_installation( actions[ 1: ] )
- # Set actions to the same, so that the current download_binary doesn't get re-run in the
- # filtered actions below.
- actions = filtered_actions
- except Exception, e:
- log.exception( str( e ) )
- # No binary exists, or there was an error downloading the binary from the generated URL.
- # Proceed with the remaining actions.
- filtered_actions = actions[ 1: ]
- action_type, action_dict = filtered_actions[ 0 ]
- # If the downloaded file exists, move it to $INSTALL_DIR. Put this outside the try/catch above so that
- # any errors in the move step are correctly sent to the tool dependency error handler.
- if downloaded_filename and os.path.exists( os.path.join( work_dir, downloaded_filename ) ):
- if target_directory:
- target_directory = os.path.realpath( os.path.normpath( os.path.join( install_dir, target_directory ) ) )
- # Make sure the target directory is not outside of $INSTALL_DIR.
- if target_directory.startswith( os.path.realpath( install_dir ) ):
- full_path_to_dir = os.path.abspath( os.path.join( install_dir, target_directory ) )
- else:
- full_path_to_dir = os.path.abspath( install_dir )
- else:
- full_path_to_dir = os.path.abspath( install_dir )
- td_common_util.move_file( current_dir=work_dir,
- source=downloaded_filename,
- destination=full_path_to_dir )
- if action_type == 'download_by_url':
- # Eliminate the download_by_url action so remaining actions can be processed correctly.
- filtered_actions = actions[ 1: ]
- url = action_dict[ 'url' ]
- is_binary = action_dict.get( 'is_binary', False )
- log.debug( 'Attempting to download via url: %s', url )
- if 'target_filename' in action_dict:
- # Sometimes compressed archives extract their content to a folder other than the default
- # defined file name. Using this attribute will ensure that the file name is set appropriately
- # and can be located after download, decompression and extraction.
- downloaded_filename = action_dict[ 'target_filename' ]
- else:
- downloaded_filename = os.path.split( url )[ -1 ]
- dir = td_common_util.url_download( work_dir, downloaded_filename, url, extract=True )
- if is_binary:
- log_file = os.path.join( install_dir, INSTALLATION_LOG )
- if os.path.exists( log_file ):
- logfile = open( log_file, 'ab' )
- else:
- logfile = open( log_file, 'wb' )
- logfile.write( 'Successfully downloaded from url: %s\n' % action_dict[ 'url' ] )
- logfile.close()
- log.debug( 'Successfully downloaded from url: %s' % action_dict[ 'url' ] )
- elif action_type == 'shell_command':
- # <action type="shell_command">git clone --recursive git://github.com/ekg/freebayes.git</action>
- # Eliminate the shell_command clone action so remaining actions can be processed correctly.
- filtered_actions = actions[ 1: ]
- return_code = handle_command( app, tool_dependency, install_dir, action_dict[ 'command' ] )
- if return_code:
- return tool_dependency
- dir = package_name
- elif action_type == 'download_file':
- # <action type="download_file">http://effectors.org/download/version/TTSS_GUI-1.0.1.jar</action>
- # Download a single file to the working directory.
- filtered_actions = actions[ 1: ]
- url = action_dict[ 'url' ]
- if 'target_filename' in action_dict:
- # Sometimes compressed archives extracts their content to a folder other than the default
- # defined file name. Using this attribute will ensure that the file name is set appropriately
- # and can be located after download, decompression and extraction.
- filename = action_dict[ 'target_filename' ]
- else:
- filename = url.split( '/' )[ -1 ]
- td_common_util.url_download( work_dir, filename, url )
- dir = os.path.curdir
- elif action_type == 'setup_r_environment':
- # setup an R environment
- # <action type="setup_r_environment">
- # <repository name="package_r_3_0_1" owner="bgruening">
- # <package name="R" version="3.0.1" />
- # </repository>
- # <!-- allow installing an R packages -->
- # <package>https://github.com/bgruening/download_store/raw/master/DESeq2-1_0_18/BiocGe…</package>
- # </action>
- filtered_actions = actions[ 1: ]
- env_shell_file_paths = action_dict.get( 'env_shell_file_paths', None )
- if env_shell_file_paths is None:
- log.debug( 'Missing R environment. Please check your specified R installation exists.' )
- return tool_dependency
- else:
- install_environment.add_env_shell_file_paths( env_shell_file_paths )
- log.debug( 'Handling setup_r_environment for tool dependency %s with install_environment.env_shell_file_paths:\n%s' % \
- ( str( tool_dependency.name ), str( install_environment.env_shell_file_paths ) ) )
- tarball_names = []
- for url in action_dict[ 'r_packages' ]:
- filename = url.split( '/' )[ -1 ]
- tarball_names.append( filename )
- td_common_util.url_download( work_dir, filename, url, extract=False )
- dir = os.path.curdir
- current_dir = os.path.abspath( os.path.join( work_dir, dir ) )
- with lcd( current_dir ):
- with settings( warn_only=True ):
- for tarball_name in tarball_names:
- # Use raw strings so that python won't automatically unescape the quotes before passing the command
- # to subprocess.Popen.
- cmd = r'''PATH=$PATH:$R_HOME/bin; export PATH; R_LIBS=$INSTALL_DIR; export R_LIBS;
- Rscript -e "install.packages(c('%s'),lib='$INSTALL_DIR', repos=NULL, dependencies=FALSE)"''' % \
- ( str( tarball_name ) )
- cmd = install_environment.build_command( td_common_util.evaluate_template( cmd, install_dir ) )
- return_code = handle_command( app, tool_dependency, install_dir, cmd )
- if return_code:
- return tool_dependency
- # R libraries are installed to $INSTALL_DIR (install_dir), we now set the R_LIBS path to that directory
- env_file_builder = EnvFileBuilder( install_dir )
- # Pull in R environment (runtime).
- handle_action_shell_file_paths( env_file_builder, action_dict )
- env_file_builder.append_line( name="R_LIBS", action="prepend_to", value=install_dir )
- return_code = env_file_builder.return_code
- if return_code:
- return tool_dependency
- elif action_type == 'setup_ruby_environment':
- # setup an Ruby environment
- # <action type="setup_ruby_environment">
- # <repository name="package_ruby_2_0" owner="bgruening">
- # <package name="ruby" version="2.0" />
- # </repository>
- # <!-- allow downloading and installing an Ruby package from http://rubygems.org/ -->
- # <package>protk</package>
- # <package>protk=1.2.4</package>
- # <package>http://url-to-some-gem-file.de/protk.gem</package>
- # </action>
- filtered_actions = actions[ 1: ]
- env_shell_file_paths = action_dict.get( 'env_shell_file_paths', None )
- if env_shell_file_paths is None:
- log.debug( 'Missing Ruby environment, make sure your specified Ruby installation exists.' )
- return tool_dependency
- else:
- install_environment.add_env_shell_file_paths( env_shell_file_paths )
- log.debug( 'Handling setup_ruby_environment for tool dependency %s with install_environment.env_shell_file_paths:\n%s' % \
- ( str( tool_dependency.name ), str( install_environment.env_shell_file_paths ) ) )
- dir = os.path.curdir
- current_dir = os.path.abspath( os.path.join( work_dir, dir ) )
- with lcd( current_dir ):
- with settings( warn_only=True ):
- ruby_package_tups = action_dict.get( 'ruby_package_tups', [] )
- for ruby_package_tup in ruby_package_tups:
- gem, gem_version = ruby_package_tup
- if os.path.isfile( gem ):
- # we assume a local shipped gem file
- cmd = '''PATH=$PATH:$RUBY_HOME/bin; export PATH; GEM_HOME=$INSTALL_DIR; export GEM_HOME;
- gem install --local %s''' % ( gem )
- elif gem.find( '://' ) != -1:
- # We assume a URL to a gem file.
- url = gem
- gem_name = url.split( '/' )[ -1 ]
- td_common_util.url_download( work_dir, gem_name, url, extract=False )
- cmd = '''PATH=$PATH:$RUBY_HOME/bin; export PATH; GEM_HOME=$INSTALL_DIR; export GEM_HOME;
- gem install --local %s ''' % ( gem_name )
- else:
- # gem file from rubygems.org with or without version number
- if gem_version:
- # Specific ruby gem version was requested.
- # Use raw strings so that python won't automatically unescape the quotes before passing the command
- # to subprocess.Popen.
- cmd = r'''PATH=$PATH:$RUBY_HOME/bin; export PATH; GEM_HOME=$INSTALL_DIR; export GEM_HOME;
- gem install %s --version "=%s"''' % ( gem, gem_version)
- else:
- # no version number given
- cmd = '''PATH=$PATH:$RUBY_HOME/bin; export PATH; GEM_HOME=$INSTALL_DIR; export GEM_HOME;
- gem install %s''' % ( gem )
- cmd = install_environment.build_command( td_common_util.evaluate_template( cmd, install_dir ) )
- return_code = handle_command( app, tool_dependency, install_dir, cmd )
- if return_code:
- return tool_dependency
- env_file_builder = EnvFileBuilder( install_dir )
- # Pull in ruby dependencies (runtime).
- handle_action_shell_file_paths( env_file_builder, action_dict )
- env_file_builder.append_line( name="GEM_PATH", action="prepend_to", value=install_dir )
- env_file_builder.append_line( name="PATH", action="prepend_to", value=os.path.join(install_dir, 'bin') )
- return_code = env_file_builder.return_code
- if return_code:
- return tool_dependency
- elif action_type == 'setup_perl_environment':
- # setup an Perl environment
- # <action type="setup_perl_environment">
- # <repository name="package_perl_5_18" owner="bgruening">
- # <package name="perl" version="5.18.1" />
- # </repository>
- # <!-- allow downloading and installing an Perl package from cpan.org-->
- # <package>XML::Parser</package>
- # <package>http://search.cpan.org/CPAN/authors/id/C/CJ/CJFIELDS/BioPerl-1.6.922.tar.gz</package>
- # </action>
- filtered_actions = actions[ 1: ]
- env_shell_file_paths = action_dict.get( 'env_shell_file_paths', None )
- if env_shell_file_paths is None:
- log.debug( 'Missing Rerl environment, make sure your specified Rerl installation exists.' )
- return tool_dependency
- else:
- install_environment.add_env_shell_file_paths( env_shell_file_paths )
- log.debug( 'Handling setup_perl_environment for tool dependency %s with install_environment.env_shell_file_paths:\n%s' % \
- ( str( tool_dependency.name ), str( install_environment.env_shell_file_paths ) ) )
- dir = os.path.curdir
- current_dir = os.path.abspath( os.path.join( work_dir, dir ) )
- with lcd( current_dir ):
- with settings( warn_only=True ):
- perl_packages = action_dict.get( 'perl_packages', [] )
- for perl_package in perl_packages:
- # If set to a true value then MakeMaker's prompt function will always
- # return the default without waiting for user input.
- cmd = '''PERL_MM_USE_DEFAULT=1; export PERL_MM_USE_DEFAULT; '''
- if perl_package.find( '://' ) != -1:
- # We assume a URL to a gem file.
- url = perl_package
- perl_package_name = url.split( '/' )[ -1 ]
- dir = td_common_util.url_download( work_dir, perl_package_name, url, extract=True )
- # Search for Build.PL or Makefile.PL (ExtUtils::MakeMaker vs. Module::Build).
- tmp_work_dir = os.path.join( work_dir, dir )
- if os.path.exists( os.path.join( tmp_work_dir, 'Makefile.PL' ) ):
- cmd += '''perl Makefile.PL INSTALL_BASE=$INSTALL_DIR && make && make install'''
- elif os.path.exists( os.path.join( tmp_work_dir, 'Build.PL' ) ):
- cmd += '''perl Build.PL --install_base $INSTALL_DIR && perl Build && perl Build install'''
- else:
- log.debug( 'No Makefile.PL or Build.PL file found in %s. Skipping installation of %s.' % \
- ( url, perl_package_name ) )
- return tool_dependency
- with lcd( tmp_work_dir ):
- cmd = install_environment.build_command( td_common_util.evaluate_template( cmd, install_dir ) )
- return_code = handle_command( app, tool_dependency, install_dir, cmd )
- if return_code:
- return tool_dependency
- else:
- # perl package from CPAN without version number.
- # cpanm should be installed with the parent perl distribution, otherwise this will not work.
- cmd += '''cpanm --local-lib=$INSTALL_DIR %s''' % ( perl_package )
- cmd = install_environment.build_command( td_common_util.evaluate_template( cmd, install_dir ) )
- return_code = handle_command( app, tool_dependency, install_dir, cmd )
- if return_code:
- return tool_dependency
- env_file_builder = EnvFileBuilder( install_dir )
- # Pull in perl dependencies (runtime).
- handle_action_shell_file_paths( env_file_builder, action_dict )
- # Recursively add dependent PERL5LIB and PATH to env.sh & anything else needed.
- env_file_builder.append_line( name="PERL5LIB", action="prepend_to", value=os.path.join( install_dir, 'lib', 'perl5' ) )
- env_file_builder.append_line( name="PATH", action="prepend_to", value=os.path.join( install_dir, 'bin' ) )
- return_code = env_file_builder.return_code
- if return_code:
- return tool_dependency
+ if action_type in INSTALL_ACTIONS:
+ # Some of the parameters passed here are needed only by a subset of the step handler classes,
+ # but to allow for a standard method signature we'll pass them along. We don't check the
+ # tool_dependency status in this stage because it should not have been changed based on a
+ # download.
+ tool_dependency, filtered_actions, dir = \
+ recipe_manager.execute_step( app=app,
+ tool_dependency=tool_dependency,
+ package_name=package_name,
+ actions=actions,
+ action_type=action_type,
+ action_dict=action_dict,
+ filtered_actions=filtered_actions,
+ env_file_builder=env_file_builder,
+ install_environment=install_environment,
+ work_dir=work_dir,
+ install_dir=install_dir,
+ current_dir=None,
+ initial_download=True )
else:
# We're handling a complex repository dependency where we only have a set_environment tag set.
# <action type="set_environment">
@@ -767,207 +66,33 @@
# </action>
filtered_actions = [ a for a in actions ]
dir = install_dir
- full_path_to_dir = os.path.abspath( os.path.join( work_dir, dir ) )
- if not os.path.exists( full_path_to_dir ):
- os.makedirs( full_path_to_dir )
- # The package has been down-loaded, so we can now perform all of the actions defined for building it.
+ # We're in stage 2 of the installation process. The package has been down-loaded, so we can
+ # now perform all of the actions defined for building it.
for action_tup in filtered_actions:
current_dir = os.path.abspath( os.path.join( work_dir, dir ) )
with lcd( current_dir ):
action_type, action_dict = action_tup
- if action_type == 'make_directory':
- if os.path.isabs( action_dict[ 'full_path' ] ):
- full_path = action_dict[ 'full_path' ]
- else:
- full_path = os.path.join( current_dir, action_dict[ 'full_path' ] )
- td_common_util.make_directory( full_path=full_path )
- elif action_type == 'move_directory_files':
- td_common_util.move_directory_files( current_dir=current_dir,
- source_dir=os.path.join( action_dict[ 'source_directory' ] ),
- destination_dir=os.path.join( action_dict[ 'destination_directory' ] ) )
- elif action_type == 'move_file':
- td_common_util.move_file( current_dir=current_dir,
- source=os.path.join( action_dict[ 'source' ] ),
- destination=os.path.join( action_dict[ 'destination' ] ),
- rename_to=action_dict[ 'rename_to' ] )
- elif action_type == 'set_environment':
- # Currently the only action supported in this category is "environment_variable".
- # Build a command line from the prior_installation_required, in case an environment variable is referenced
- # in the set_environment action.
- cmds = install_environment.environment_commands( 'set_environment' )
- env_var_dicts = action_dict[ 'environment_variable' ]
- env_file_builder = EnvFileBuilder( install_dir )
- for env_var_dict in env_var_dicts:
- # Check for the presence of the $ENV[] key string and populate it if possible.
- env_var_dict = handle_environment_variables( app, tool_dependency, install_dir, env_var_dict, cmds )
- env_file_builder.append_line( **env_var_dict )
- return_code = env_file_builder.return_code
- if return_code:
- return tool_dependency
- elif action_type == 'set_environment_for_install':
- # Currently the only action supported in this category is a list of paths to one or more tool dependency env.sh files,
- # the environment setting in each of which will be injected into the environment for all <action type="shell_command">
- # tags that follow this <action type="set_environment_for_install"> tag set in the tool_dependencies.xml file.
- install_environment.add_env_shell_file_paths( action_dict[ 'env_shell_file_paths' ] )
- elif action_type == 'setup_virtualenv':
- # TODO: maybe should be configurable
- venv_src_directory = os.path.abspath( os.path.join( app.config.tool_dependency_dir, '__virtualenv_src' ) )
- if not install_virtualenv( app, venv_src_directory ):
- log.error( 'Unable to install virtualenv' )
- return tool_dependency
- requirements = action_dict[ 'requirements' ]
- if os.path.exists( os.path.join( dir, requirements ) ):
- # requirements specified as path to a file
- requirements_path = requirements
- else:
- # requirements specified directly in XML, create a file with these for pip.
- requirements_path = os.path.join( install_dir, "requirements.txt" )
- with open( requirements_path, "w" ) as f:
- f.write( requirements )
- venv_directory = os.path.join( install_dir, "venv" )
- # TODO: Consider making --no-site-packages optional.
- setup_command = "python %s/virtualenv.py --no-site-packages '%s'" % (venv_src_directory, venv_directory)
- # POSIXLY_CORRECT forces shell commands . and source to have the same
- # and well defined behavior in bash/zsh.
- activate_command = "POSIXLY_CORRECT=1; . %s" % os.path.join( venv_directory, "bin", "activate" )
- install_command = "python '%s' install -r '%s'" % ( os.path.join( venv_directory, "bin", "pip" ), requirements_path )
- full_setup_command = "%s; %s; %s" % ( setup_command, activate_command, install_command )
- return_code = handle_command( app, tool_dependency, install_dir, full_setup_command )
- if return_code:
- return tool_dependency
- # Use raw strings so that python won't automatically unescape the quotes before passing the command
- # to subprocess.Popen.
- site_packages_command = r"""%s -c 'import os, sys; print os.path.join(sys.prefix, "lib", "python" + sys.version[:3], "site-packages")'""" % os.path.join( venv_directory, "bin", "python" )
- output = handle_command( app, tool_dependency, install_dir, site_packages_command, return_output=True )
- if output.return_code:
- return tool_dependency
- if not os.path.exists( output.stdout ):
- log.debug( "virtualenv's site-packages directory '%s' does not exist", output.stdout )
- return tool_dependency
- env_file_builder = EnvFileBuilder( install_dir )
- env_file_builder.append_line( name="PYTHONPATH", action="prepend_to", value=output.stdout )
- env_file_builder.append_line( name="PATH", action="prepend_to", value=os.path.join( venv_directory, "bin" ) )
- return_code = env_file_builder.return_code
- if return_code:
- return tool_dependency
- elif action_type == 'shell_command':
- with settings( warn_only=True ):
- cmd = install_environment.build_command( action_dict[ 'command' ] )
- return_code = handle_command( app, tool_dependency, install_dir, cmd )
- if return_code:
- return tool_dependency
- elif action_type == 'template_command':
- env_vars = dict()
- env_vars = install_environment.environment_dict()
- env_vars.update( td_common_util.get_env_var_values( install_dir ) )
- language = action_dict[ 'language' ]
- with settings( warn_only=True, **env_vars ):
- if language == 'cheetah':
- # We need to import fabric.api.env so that we can access all collected environment variables.
- cmd = fill_template( '#from fabric.api import env\n%s' % action_dict[ 'command' ], context=env_vars )
- return_code = handle_command( app, tool_dependency, install_dir, cmd )
- if return_code:
- return tool_dependency
- elif action_type == 'make_install':
- # make; make install; allow providing make options
- with settings( warn_only=True ):
- make_opts = action_dict.get( 'make_opts', '' )
- cmd = install_environment.build_command( 'make %s && make install' % make_opts )
- return_code = handle_command( app, tool_dependency, install_dir, cmd )
- if return_code:
- return tool_dependency
- elif action_type == 'autoconf':
- # Handle configure, make and make install allow providing configuration options
- with settings( warn_only=True ):
- configure_opts = action_dict.get( 'configure_opts', '' )
- if 'prefix=' in configure_opts:
- pre_cmd = './configure %s && make && make install' % configure_opts
- else:
- pre_cmd = './configure --prefix=$INSTALL_DIR %s && make && make install' % configure_opts
- cmd = install_environment.build_command( td_common_util.evaluate_template( pre_cmd, install_dir ) )
- return_code = handle_command( app, tool_dependency, install_dir, cmd )
- if return_code:
- return tool_dependency
- elif action_type == 'download_file':
- # Download a single file to the current working directory.
- url = action_dict[ 'url' ]
- if 'target_filename' in action_dict:
- filename = action_dict[ 'target_filename' ]
- else:
- filename = url.split( '/' )[ -1 ]
- extract = action_dict.get( 'extract', False )
- td_common_util.url_download( current_dir, filename, url, extract=extract )
- elif action_type == 'change_directory':
- target_directory = os.path.realpath( os.path.normpath( os.path.join( current_dir, action_dict[ 'directory' ] ) ) )
- if target_directory.startswith( os.path.realpath( current_dir ) ) and os.path.exists( target_directory ):
- # Change directory to a directory within the current working directory.
- dir = target_directory
- elif target_directory.startswith( os.path.realpath( work_dir ) ) and os.path.exists( target_directory ):
- # Change directory to a directory above the current working directory, but within the defined work_dir.
- dir = target_directory.replace( os.path.realpath( work_dir ), '' ).lstrip( '/' )
- else:
- log.error( 'Invalid or nonexistent directory %s specified, ignoring change_directory action.', target_directory )
- elif action_type == 'chmod':
- for target_file, mode in action_dict[ 'change_modes' ]:
- if os.path.exists( target_file ):
- os.chmod( target_file, mode )
- else:
- log.error( 'Invalid file %s specified, ignoring %s action.', target_file, action_type )
- elif action_type == 'download_binary':
- url = action_dict[ 'url' ]
- target_directory = action_dict.get( 'target_directory', None )
- try:
- downloaded_filename = td_common_util.download_binary( url, work_dir )
- except Exception, e:
- log.exception( str( e ) )
- # If the downloaded file exists, move it to $INSTALL_DIR. Put this outside the try/catch above so that
- # any errors in the move step are correctly sent to the tool dependency error handler.
- if downloaded_filename and os.path.exists( os.path.join( work_dir, downloaded_filename ) ):
- if target_directory:
- target_directory = os.path.realpath( os.path.normpath( os.path.join( install_dir, target_directory ) ) )
- # Make sure the target directory is not outside of $INSTALL_DIR.
- if target_directory.startswith( os.path.realpath( install_dir ) ):
- full_path_to_dir = os.path.abspath( os.path.join( install_dir, target_directory ) )
- else:
- full_path_to_dir = os.path.abspath( install_dir )
- else:
- full_path_to_dir = os.path.abspath( install_dir )
- td_common_util.move_file( current_dir=work_dir,
- source=downloaded_filename,
- destination=full_path_to_dir )
+ tool_dependency, tmp_filtered_actions, tmp_dir = \
+ recipe_manager.execute_step( app=app,
+ tool_dependency=tool_dependency,
+ package_name=package_name,
+ actions=actions,
+ action_type=action_type,
+ action_dict=action_dict,
+ filtered_actions=filtered_actions,
+ env_file_builder=env_file_builder,
+ install_environment=install_environment,
+ work_dir=work_dir,
+ install_dir=install_dir,
+ current_dir=current_dir,
+ initial_download=False )
+ if tool_dependency.status in [ app.model.ToolDependency.installation_status.ERROR ]:
+ # If the tool_dependency status is in an error state, return it with no additional
+ # processing.
+ return tool_dependency
+ # Make sure to handle the special case where the value of dir is reset (this happens when
+ # the action_type is change_directiory). In all other action types, dir will be returned as
+ # None.
+ if tmp_dir is not None:
+ dir = tmp_dir
return tool_dependency
-
-def log_results( command, fabric_AttributeString, file_path ):
- """Write attributes of fabric.operations._AttributeString to a specified log file."""
- if os.path.exists( file_path ):
- logfile = open( file_path, 'ab' )
- else:
- logfile = open( file_path, 'wb' )
- logfile.write( "\n#############################################\n" )
- logfile.write( '%s\nSTDOUT\n' % command )
- logfile.write( str( fabric_AttributeString.stdout ) )
- logfile.write( "\n#############################################\n" )
- logfile.write( "\n#############################################\n" )
- logfile.write( '%s\nSTDERR\n' % command )
- logfile.write( str( fabric_AttributeString.stderr ) )
- logfile.write( "\n#############################################\n" )
- logfile.close()
-
-@contextmanager
-def make_tmp_dir():
- work_dir = tempfile.mkdtemp( prefix="tmp-toolshed-mtd" )
- yield work_dir
- if os.path.exists( work_dir ):
- try:
- shutil.rmtree( work_dir )
- except Exception, e:
- log.exception( str( e ) )
-
-def set_galaxy_environment( galaxy_user, tool_dependency_dir, host='localhost', shell='/bin/bash -l -c' ):
- """General Galaxy environment configuration. This method is not currently used."""
- env.user = galaxy_user
- env.install_dir = tool_dependency_dir
- env.host_string = host
- env.shell = shell
- env.use_sudo = False
- return env
diff -r 369bb0f7ebef50a72f36cf2f74d23f7d351d61c4 -r de54998e192b99bd70751d692969b508463e1805 lib/tool_shed/galaxy_install/tool_dependencies/install_util.py
--- a/lib/tool_shed/galaxy_install/tool_dependencies/install_util.py
+++ b/lib/tool_shed/galaxy_install/tool_dependencies/install_util.py
@@ -5,9 +5,10 @@
import subprocess
import sys
import tempfile
-from string import Template
import fabric_util
import td_common_util
+from tool_shed.galaxy_install.tool_dependencies.recipe.recipe_manager import EnvFileBuilder
+from tool_shed.galaxy_install.tool_dependencies.recipe.recipe_manager import RecipeManager
import tool_shed.util.shed_util_common as suc
from tool_shed.util import common_util
from tool_shed.util import encoding_util
@@ -94,7 +95,7 @@
package_name,
package_version,
required_repository )
- env_file_builder = fabric_util.EnvFileBuilder( tool_dependency.installation_directory( app ) )
+ env_file_builder = EnvFileBuilder( tool_dependency.installation_directory( app ) )
env_file_builder.append_line( action="source", value=required_tool_dependency_env_file_path )
return_code = env_file_builder.return_code
if return_code:
@@ -497,19 +498,24 @@
elif package_elem.tag == 'readme':
# Nothing to be done.
continue
- #elif package_elem.tag == 'proprietary_fabfile':
+ #elif package_elem.tag == 'custom_fabfile':
# # TODO: This is not yet supported or functionally correct...
- # # Handle tool dependency installation where the repository includes one or more proprietary fabric scripts.
+ # # Handle tool dependency installation where the repository includes one or more custom fabric scripts.
# if not fabric_version_checked:
# check_fabric_version()
# fabric_version_checked = True
# fabfile_name = package_elem.get( 'name', None )
- # proprietary_fabfile_path = os.path.abspath( os.path.join( os.path.split( tool_dependencies_config )[ 0 ], fabfile_name ) )
- # print 'Installing tool dependencies via fabric script ', proprietary_fabfile_path
+ # custom_fabfile_path = os.path.abspath( os.path.join( os.path.split( tool_dependencies_config )[ 0 ], fabfile_name ) )
+ # print 'Installing tool dependencies via fabric script ', custom_fabfile_path
return tool_dependency
-def install_via_fabric( app, tool_dependency, install_dir, package_name=None, proprietary_fabfile_path=None, actions_elem=None, action_elem=None, **kwd ):
- """Parse a tool_dependency.xml file's <actions> tag set to gather information for the installation via fabric."""
+def install_via_fabric( app, tool_dependency, install_dir, package_name=None, custom_fabfile_path=None,
+ actions_elem=None, action_elem=None, **kwd ):
+ """
+ Parse a tool_dependency.xml file's <actions> tag set to gather information for installation using the
+ fabric_util.install_and_build_package() method. The use of fabric is being eliminated, so some of these
+ functions may need to be renamed at some point.
+ """
sa_session = app.install_model.context
if not os.path.exists( install_dir ):
os.makedirs( install_dir )
@@ -517,278 +523,30 @@
if package_name:
actions_dict[ 'package_name' ] = package_name
actions = []
- all_env_shell_file_paths = []
- env_var_dicts = []
+ is_binary_download = False
if actions_elem is not None:
elems = actions_elem
if elems.get( 'os' ) is not None and elems.get( 'architecture' ) is not None:
is_binary_download = True
- else:
- is_binary_download = False
elif action_elem is not None:
# We were provided with a single <action> element to perform certain actions after a platform-specific tarball was downloaded.
elems = [ action_elem ]
else:
elems = []
+ recipe_manager = RecipeManager()
for action_elem in elems:
# Make sure to skip all comments, since they are now included in the XML tree.
if action_elem.tag != 'action':
continue
action_dict = {}
action_type = action_elem.get( 'type', 'shell_command' )
- if action_type == 'download_binary':
- platform_info_dict = tool_dependency_util.get_platform_info_dict()
- platform_info_dict[ 'name' ] = tool_dependency.name
- platform_info_dict[ 'version' ] = tool_dependency.version
- url_template_elems = action_elem.findall( 'url_template' )
- # Check if there are multiple url_template elements, each with attrib entries for a specific platform.
- if len( url_template_elems ) > 1:
- # <base_url os="darwin" extract="false">http://hgdownload.cse.ucsc.edu/admin/exe/macOSX.${architecture}/faToTwoBit</base_url>
- # This method returns the url_elem that best matches the current platform as received from os.uname().
- # Currently checked attributes are os and architecture.
- # These correspond to the values sysname and processor from the Python documentation for os.uname().
- url_template_elem = tool_dependency_util.get_download_url_for_platform( url_template_elems, platform_info_dict )
- else:
- url_template_elem = url_template_elems[ 0 ]
- action_dict[ 'url' ] = Template( url_template_elem.text ).safe_substitute( platform_info_dict )
- action_dict[ 'target_directory' ] = action_elem.get( 'target_directory', None )
- elif action_type == 'shell_command':
- # <action type="shell_command">make</action>
- action_elem_text = td_common_util.evaluate_template( action_elem.text, install_dir )
- if action_elem_text:
- action_dict[ 'command' ] = action_elem_text
- else:
- continue
- elif action_type == 'template_command':
- # Default to Cheetah as it's the first template language supported.
- language = action_elem.get( 'language', 'cheetah' ).lower()
- if language == 'cheetah':
- # Cheetah template syntax.
- # <action type="template_command" language="cheetah">
- # #if env.PATH:
- # make
- # #end if
- # </action>
- action_elem_text = action_elem.text.strip()
- if action_elem_text:
- action_dict[ 'language' ] = language
- action_dict[ 'command' ] = action_elem_text
- else:
- continue
- else:
- log.debug( "Unsupported template language '%s'. Not proceeding." % str( language ) )
- raise Exception( "Unsupported template language '%s' in tool dependency definition." % str( language ) )
- elif action_type == 'download_by_url':
- # <action type="download_by_url">http://sourceforge.net/projects/samtools/files/samtools/0.1.18/samtools-0.1…</action>
- if is_binary_download:
- action_dict[ 'is_binary' ] = True
- if action_elem.text:
- action_dict[ 'url' ] = action_elem.text
- target_filename = action_elem.get( 'target_filename', None )
- if target_filename:
- action_dict[ 'target_filename' ] = target_filename
- else:
- continue
- elif action_type == 'download_file':
- # <action type="download_file">http://effectors.org/download/version/TTSS_GUI-1.0.1.jar</action>
- if action_elem.text:
- action_dict[ 'url' ] = action_elem.text
- target_filename = action_elem.get( 'target_filename', None )
- if target_filename:
- action_dict[ 'target_filename' ] = target_filename
- action_dict[ 'extract' ] = asbool( action_elem.get( 'extract', False ) )
- else:
- continue
- elif action_type == 'make_directory':
- # <action type="make_directory">$INSTALL_DIR/lib/python</action>
- if action_elem.text:
- action_dict[ 'full_path' ] = td_common_util.evaluate_template( action_elem.text, install_dir )
- else:
- continue
- elif action_type == 'change_directory':
- # <action type="change_directory">PHYLIP-3.6b</action>
- if action_elem.text:
- action_dict[ 'directory' ] = action_elem.text
- else:
- continue
- elif action_type == 'move_directory_files':
- # <action type="move_directory_files">
- # <source_directory>bin</source_directory>
- # <destination_directory>$INSTALL_DIR/bin</destination_directory>
- # </action>
- for move_elem in action_elem:
- move_elem_text = td_common_util.evaluate_template( move_elem.text, install_dir )
- if move_elem_text:
- action_dict[ move_elem.tag ] = move_elem_text
- elif action_type == 'move_file':
- # <action type="move_file" rename_to="new_file_name">
- # <source>misc/some_file</source>
- # <destination>$INSTALL_DIR/bin</destination>
- # </action>
- action_dict[ 'source' ] = td_common_util.evaluate_template( action_elem.find( 'source' ).text, install_dir )
- action_dict[ 'destination' ] = td_common_util.evaluate_template( action_elem.find( 'destination' ).text, install_dir )
- action_dict[ 'rename_to' ] = action_elem.get( 'rename_to' )
- elif action_type == 'set_environment':
- # <action type="set_environment">
- # <environment_variable name="PYTHONPATH" action="append_to">$INSTALL_DIR/lib/python</environment_variable>
- # <environment_variable name="PATH" action="prepend_to">$INSTALL_DIR/bin</environment_variable>
- # </action>
- for env_elem in action_elem:
- if env_elem.tag == 'environment_variable':
- env_var_dict = td_common_util.create_env_var_dict( env_elem, tool_dependency_install_dir=install_dir )
- if env_var_dict:
- env_var_dicts.append( env_var_dict )
- if env_var_dicts:
- # The last child of an <action type="set_environment"> might be a comment, so manually set it to be 'environment_variable'.
- action_dict[ 'environment_variable' ] = env_var_dicts
- else:
- continue
- elif action_type == 'set_environment_for_install':
- # <action type="set_environment_for_install">
- # <repository toolshed="http://localhost:9009/" name="package_numpy_1_7" owner="test" changeset_revision="c84c6a8be056">
- # <package name="numpy" version="1.7.1" />
- # </repository>
- # </action>
- # This action type allows for defining an environment that will properly compile a tool dependency. Currently, tag set definitions like
- # that above are supported, but in the future other approaches to setting environment variables or other environment attributes can be
- # supported. The above tag set will result in the installed and compiled numpy version 1.7.1 binary to be used when compiling the current
- # tool dependency package. See the package_matplotlib_1_2 repository in the test tool shed for a real-world example.
- for env_elem in action_elem:
- if env_elem.tag == 'repository':
- env_shell_file_paths = td_common_util.get_env_shell_file_paths( app, env_elem )
- if env_shell_file_paths:
- all_env_shell_file_paths.extend( env_shell_file_paths )
- if all_env_shell_file_paths:
- action_dict[ 'env_shell_file_paths' ] = all_env_shell_file_paths
- else:
- continue
- elif action_type == 'setup_virtualenv':
- # <action type="setup_virtualenv" />
- ## Install requirements from file requirements.txt of downloaded bundle - or -
- # <action type="setup_virtualenv">tools/requirements.txt</action>
- ## Install requirements from specified file from downloaded bundle -or -
- # <action type="setup_virtualenv">pyyaml==3.2.0
- # lxml==2.3.0</action>
- ## Manually specify contents of requirements.txt file to create dynamically.
- action_dict[ 'requirements' ] = td_common_util.evaluate_template( action_elem.text or 'requirements.txt', install_dir )
- elif action_type == 'autoconf':
- # Handle configure, make and make install allow providing configuration options
- if action_elem.text:
- configure_opts = td_common_util.evaluate_template( action_elem.text, install_dir )
- action_dict[ 'configure_opts' ] = configure_opts
- elif action_type == 'setup_r_environment':
- # setup an R environment.
- # <action type="setup_r_environment">
- # <repository name="package_r_3_0_1" owner="bgruening">
- # <package name="R" version="3.0.1" />
- # </repository>
- # <!-- allow installing an R packages -->
- # <package>https://github.com/bgruening/download_store/raw/master/DESeq2-1_0_18/BiocGe…</package>
- # </action>
- # Discover all child repository dependency tags and define the path to an env.sh file associated with each repository.
- # This will potentially update the value of the 'env_shell_file_paths' entry in action_dict.
- action_dict = td_common_util.get_env_shell_file_paths_from_setup_environment_elem( app, all_env_shell_file_paths, action_elem, action_dict )
- r_packages = list()
- for env_elem in action_elem:
- if env_elem.tag == 'package':
- r_packages.append( env_elem.text.strip() )
- if r_packages:
- action_dict[ 'r_packages' ] = r_packages
- else:
- continue
- elif action_type == 'setup_ruby_environment':
- # setup a Ruby environment.
- # <action type="setup_ruby_environment">
- # <repository name="package_ruby_2_0" owner="bgruening">
- # <package name="ruby" version="2.0" />
- # </repository>
- # <!-- allow downloading and installing an Ruby package from http://rubygems.org/ -->
- # <package>protk</package>
- # <package>protk=1.2.4</package>
- # <package>http://url-to-some-gem-file.de/protk.gem</package>
- # </action>
- # Discover all child repository dependency tags and define the path to an env.sh file associated with each repository.
- # This will potentially update the value of the 'env_shell_file_paths' entry in action_dict.
- action_dict = td_common_util.get_env_shell_file_paths_from_setup_environment_elem( app, all_env_shell_file_paths, action_elem, action_dict )
- ruby_package_tups = []
- for env_elem in action_elem:
- if env_elem.tag == 'package':
- #A valid gem definition can be:
- # protk=1.2.4
- # protk
- # ftp://ftp.gruening.de/protk.gem
- gem_token = env_elem.text.strip().split( '=' )
- if len( gem_token ) == 2:
- # version string
- gem_name = gem_token[ 0 ]
- gem_version = gem_token[ 1 ]
- ruby_package_tups.append( ( gem_name, gem_version ) )
- else:
- # gem name for rubygems.org without version number
- gem = env_elem.text.strip()
- ruby_package_tups.append( ( gem, None ) )
- if ruby_package_tups:
- action_dict[ 'ruby_package_tups' ] = ruby_package_tups
- else:
- continue
- elif action_type == 'setup_perl_environment':
- # setup a Perl environment.
- # <action type="setup_perl_environment">
- # <repository name="package_perl_5_18" owner="bgruening">
- # <package name="perl" version="5.18.1" />
- # </repository>
- # <!-- allow downloading and installing an Perl package from cpan.org-->
- # <package>XML::Parser</package>
- # <package>http://search.cpan.org/CPAN/authors/id/C/CJ/CJFIELDS/BioPerl-1.6.922.tar.gz</package>
- # </action>
- # Discover all child repository dependency tags and define the path to an env.sh file associated with each repository.
- # This will potentially update the value of the 'env_shell_file_paths' entry in action_dict.
- action_dict = td_common_util.get_env_shell_file_paths_from_setup_environment_elem( app, all_env_shell_file_paths, action_elem, action_dict )
- perl_packages = []
- for env_elem in action_elem:
- if env_elem.tag == 'package':
- # A valid package definition can be:
- # XML::Parser
- # http://search.cpan.org/CPAN/authors/id/C/CJ/CJFIELDS/BioPerl-1.6.922.tar.gz
- # Unfortunately CPAN does not support versioning, so if you want real reproducibility you need to specify
- # the tarball path and the right order of different tarballs manually.
- perl_packages.append( env_elem.text.strip() )
- if perl_packages:
- action_dict[ 'perl_packages' ] = perl_packages
- else:
- continue
- elif action_type == 'make_install':
- # make; make install; allow providing make options
- if action_elem.text:
- make_opts = td_common_util.evaluate_template( action_elem.text, install_dir )
- action_dict[ 'make_opts' ] = make_opts
- elif action_type == 'chmod':
- # Change the read, write, and execute bits on a file.
- # <action type="chmod">
- # <file mode="750">$INSTALL_DIR/bin/faToTwoBit</file>
- # </action>
- file_elems = action_elem.findall( 'file' )
- chmod_actions = []
- # A unix octal mode is the sum of the following values:
- # Owner:
- # 400 Read 200 Write 100 Execute
- # Group:
- # 040 Read 020 Write 010 Execute
- # World:
- # 004 Read 002 Write 001 Execute
- for file_elem in file_elems:
- # So by the above table, owner read/write/execute and group read permission would be 740.
- # Python's os.chmod uses base 10 modes, convert received unix-style octal modes to base 10.
- received_mode = int( file_elem.get( 'mode', 600 ), base=8 )
- # For added security, ensure that the setuid and setgid bits are not set.
- mode = received_mode & ~( stat.S_ISUID | stat.S_ISGID )
- file = td_common_util.evaluate_template( file_elem.text, install_dir )
- chmod_tuple = ( file, mode )
- chmod_actions.append( chmod_tuple )
- action_dict[ 'change_modes' ] = chmod_actions
- else:
- log.debug( "Unsupported action type '%s'. Not proceeding." % str( action_type ) )
- raise Exception( "Unsupported action type '%s' in tool dependency definition." % str( action_type ) )
+ action_dict = recipe_manager.prepare_step( app=app,
+ tool_dependency=tool_dependency,
+ action_type=action_type,
+ action_elem=action_elem,
+ action_dict=action_dict,
+ install_dir=install_dir,
+ is_binary_download=is_binary_download )
action_tuple = ( action_type, action_dict )
if action_type == 'set_environment':
if action_tuple not in actions:
@@ -797,15 +555,15 @@
actions.append( action_tuple )
if actions:
actions_dict[ 'actions' ] = actions
- if proprietary_fabfile_path:
+ if custom_fabfile_path is not None:
# TODO: this is not yet supported or functional, but when it is handle it using the fabric api.
- # run_proprietary_fabric_method( app, elem, proprietary_fabfile_path, install_dir, package_name=package_name )
+ # execute_custom_fabric_script( app, elem, custom_fabfile_path, install_dir, package_name=package_name )
raise Exception( 'Tool dependency installation using proprietary fabric scripts is not yet supported.' )
else:
tool_dependency = install_and_build_package_via_fabric( app, tool_dependency, actions_dict )
return tool_dependency
-def run_proprietary_fabric_method( app, elem, proprietary_fabfile_path, install_dir, package_name=None, **kwd ):
+def execute_custom_fabric_script( app, elem, custom_fabfile_path, install_dir, package_name=None, **kwd ):
"""
TODO: Handle this using the fabric api.
Parse a tool_dependency.xml file's fabfile <method> tag set to build the method parameters and execute the method.
@@ -834,10 +592,10 @@
else:
params_str = params_str.rstrip( ',' )
try:
- cmd = 'fab -f %s %s:%s' % ( proprietary_fabfile_path, method_name, params_str )
+ cmd = 'fab -f %s %s:%s' % ( custom_fabfile_path, method_name, params_str )
returncode, message = run_subprocess( app, cmd )
except Exception, e:
- return "Exception executing fabric script %s: %s. " % ( str( proprietary_fabfile_path ), str( e ) )
+ return "Exception executing fabric script %s: %s. " % ( str( custom_fabfile_path ), str( e ) )
if returncode:
return message
handle_environment_settings( app, tool_dependency, install_dir, cmd )
@@ -913,7 +671,7 @@
set_status=True )
if env_var_version == '1.0':
# Create this tool dependency's env.sh file.
- env_file_builder = fabric_util.EnvFileBuilder( install_dir )
+ env_file_builder = EnvFileBuilder( install_dir )
return_code = env_file_builder.append_line( make_executable=True, **env_var_dict )
if return_code:
error_message = 'Error creating env.sh file for tool dependency %s, return_code: %s' % \
diff -r 369bb0f7ebef50a72f36cf2f74d23f7d351d61c4 -r de54998e192b99bd70751d692969b508463e1805 lib/tool_shed/galaxy_install/tool_dependencies/recipe/recipe_manager.py
--- /dev/null
+++ b/lib/tool_shed/galaxy_install/tool_dependencies/recipe/recipe_manager.py
@@ -0,0 +1,449 @@
+import logging
+import os
+import Queue
+import shutil
+import stat
+import subprocess
+import tempfile
+import threading
+import time
+
+from contextlib import contextmanager
+
+# TODO: eliminate the use of fabric here.
+from galaxy import eggs
+eggs.require( 'Fabric' )
+
+from fabric.operations import _AttributeString
+from fabric import state
+from fabric.api import prefix
+
+from galaxy.util import DATABASE_MAX_STRING_SIZE
+from galaxy.util import DATABASE_MAX_STRING_SIZE_PRETTY
+from galaxy.util import shrink_string_by_size
+from galaxy.util import unicodify
+
+from tool_shed.galaxy_install.tool_dependencies import td_common_util
+from tool_shed.galaxy_install.tool_dependencies.recipe import step_handler
+
+log = logging.getLogger( __name__ )
+
+
+class AsynchronousReader( threading.Thread ):
+ """
+ A helper class to implement asynchronous reading of a stream in a separate thread. Read lines are pushed
+ onto a queue to be consumed in another thread.
+ """
+
+ def __init__( self, fd, queue ):
+ threading.Thread.__init__( self )
+ self._fd = fd
+ self._queue = queue
+ self.lines = []
+
+ def run( self ):
+ """Read lines and put them on the queue."""
+ thread_lock = threading.Lock()
+ thread_lock.acquire()
+ for line in iter( self._fd.readline, '' ):
+ stripped_line = line.rstrip()
+ self.lines.append( stripped_line )
+ self._queue.put( stripped_line )
+ thread_lock.release()
+
+ def installation_complete( self ):
+ """Make sure there is more installation and compilation logging content expected."""
+ return not self.is_alive() and self._queue.empty()
+
+
+class EnvFileBuilder( object ):
+
+ def __init__( self, install_dir ):
+ self.install_dir = install_dir
+ self.return_code = 0
+
+ def append_line( self, make_executable=True, **kwd ):
+ env_var_dict = dict( **kwd )
+ env_entry, env_file = self.create_or_update_env_shell_file( self.install_dir, env_var_dict )
+ return_code = self.file_append( env_entry, env_file, make_executable=make_executable )
+ self.return_code = self.return_code or return_code
+ return self.return_code
+
+ @staticmethod
+ def create_or_update_env_shell_file( install_dir, env_var_dict ):
+ env_var_action = env_var_dict[ 'action' ]
+ env_var_value = env_var_dict[ 'value' ]
+ if env_var_action in [ 'prepend_to', 'set_to', 'append_to' ]:
+ env_var_name = env_var_dict[ 'name' ]
+ if env_var_action == 'prepend_to':
+ changed_value = '%s:$%s' % ( env_var_value, env_var_name )
+ elif env_var_action == 'set_to':
+ changed_value = '%s' % env_var_value
+ elif env_var_action == 'append_to':
+ changed_value = '$%s:%s' % ( env_var_name, env_var_value )
+ line = "%s=%s; export %s" % ( env_var_name, changed_value, env_var_name )
+ elif env_var_action == "source":
+ line = "if [ -f %s ] ; then . %s ; fi" % ( env_var_value, env_var_value )
+ else:
+ raise Exception( "Unknown shell file action %s" % env_var_action )
+ env_shell_file_path = os.path.join( install_dir, 'env.sh' )
+ return line, env_shell_file_path
+
+ def file_append( self, text, file_path, make_executable=True ):
+ """
+ Append a line to a file unless the line already exists in the file. This method creates the file if
+ it doesn't exist. If make_executable is True, the permissions on the file are set to executable by
+ the owner.
+ """
+ file_dir = os.path.dirname( file_path )
+ if not os.path.exists( file_dir ):
+ try:
+ os.makedirs( file_dir )
+ except Exception, e:
+ log.exception( str( e ) )
+ return 1
+ if os.path.exists( file_path ):
+ try:
+ new_env_file_contents = []
+ env_file_contents = file( file_path, 'r' ).readlines()
+ # Clean out blank lines from the env.sh file.
+ for line in env_file_contents:
+ line = line.rstrip()
+ if line:
+ new_env_file_contents.append( line )
+ env_file_contents = new_env_file_contents
+ except Exception, e:
+ log.exception( str( e ) )
+ return 1
+ else:
+ env_file_handle = open( file_path, 'w' )
+ env_file_handle.close()
+ env_file_contents = []
+ if make_executable:
+ # Explicitly set the file's executable bits.
+ try:
+ os.chmod( file_path, int( '111', base=8 ) | os.stat( file_path )[ stat.ST_MODE ] )
+ except Exception, e:
+ log.exception( str( e ) )
+ return 1
+ # Convert the received text to a list, in order to support adding one or more lines to the file.
+ if isinstance( text, basestring ):
+ text = [ text ]
+ for line in text:
+ line = line.rstrip()
+ if line and line not in env_file_contents:
+ env_file_contents.append( line )
+ try:
+ file( file_path, 'w' ).write( '\n'.join( env_file_contents ) )
+ except Exception, e:
+ log.exception( str( e ) )
+ return 1
+ return 0
+
+ def handle_action_shell_file_paths( self, action_dict ):
+ shell_file_paths = action_dict.get( 'action_shell_file_paths', [] )
+ for shell_file_path in shell_file_paths:
+ self.append_line( action="source", value=shell_file_path )
+
+
+class InstallEnvironment( object ):
+ """Object describing the environment built up as part of the process of building and installing a package."""
+
+
+ def __init__( self ):
+ self.env_shell_file_paths = []
+
+ def __call__( self, install_dir ):
+ with settings( warn_only=True, **td_common_util.get_env_var_values( install_dir ) ):
+ with prefix( self.__setup_environment() ):
+ yield
+
+ def add_env_shell_file_paths( self, paths ):
+ for path in paths:
+ self.env_shell_file_paths.append( str( path ) )
+
+ def build_command( self, command, action_type='shell_command' ):
+ """
+ Build command line for execution from simple command, but
+ configuring environment described by this object.
+ """
+ env_cmds = self.environment_commands( action_type )
+ return '\n'.join( env_cmds + [ command ] )
+
+ def close_file_descriptor( self, fd ):
+ """Attempt to close a file descriptor."""
+ start_timer = time.time()
+ error = ''
+ while True:
+ try:
+ fd.close()
+ break
+ except IOError, e:
+ # Undoubtedly close() was called during a concurrent operation on the same file object.
+ log.debug( 'Error closing file descriptor: %s' % str( e ) )
+ time.sleep( .5 )
+ current_wait_time = time.time() - start_timer
+ if current_wait_time >= 600:
+ error = 'Error closing file descriptor: %s' % str( e )
+ break
+ return error
+
+ def enqueue_output( self, stdout, stdout_queue, stderr, stderr_queue ):
+ """
+ This method places streamed stdout and stderr into a threaded IPC queue target. Received data
+ is printed and saved to that thread's queue. The calling thread can then retrieve the data using
+ thread.stdout and thread.stderr.
+ """
+ stdout_logger = logging.getLogger( 'fabric_util.STDOUT' )
+ stderr_logger = logging.getLogger( 'fabric_util.STDERR' )
+ for line in iter( stdout.readline, '' ):
+ output = line.rstrip()
+ stdout_logger.debug( output )
+ stdout_queue.put( output )
+ stdout_queue.put( None )
+ for line in iter( stderr.readline, '' ):
+ output = line.rstrip()
+ stderr_logger.debug( output )
+ stderr_queue.put( output )
+ stderr_queue.put( None )
+
+ def environment_commands( self, action_type ):
+ """Build a list of commands used to construct the environment described by this object."""
+ cmds = []
+ for env_shell_file_path in self.env_shell_file_paths:
+ if os.path.exists( env_shell_file_path ):
+ for env_setting in open( env_shell_file_path ):
+ cmds.append( env_setting.strip( '\n' ) )
+ else:
+ log.debug( 'Invalid file %s specified, ignoring %s action.' % ( str( env_shell_file_path ), str( action_type ) ) )
+ return cmds
+
+ def environment_dict( self, action_type='template_command' ):
+ env_vars = dict()
+ for env_shell_file_path in self.env_shell_file_paths:
+ if os.path.exists( env_shell_file_path ):
+ for env_setting in open( env_shell_file_path ):
+ env_string = env_setting.split( ';' )[ 0 ]
+ env_name, env_path = env_string.split( '=' )
+ env_vars[ env_name ] = env_path
+ else:
+ log.debug( 'Invalid file %s specified, ignoring template_command action.' % str( env_shell_file_path ) )
+ return env_vars
+
+ def handle_command( self, app, tool_dependency, install_dir, cmd, return_output=False ):
+ """Handle a command and log the results."""
+ context = app.install_model.context
+ command = str( cmd )
+ output = self.handle_complex_command( command )
+ self.log_results( cmd, output, os.path.join( install_dir, td_common_util.INSTALLATION_LOG ) )
+ stdout = output.stdout
+ stderr = output.stderr
+ if len( stdout ) > DATABASE_MAX_STRING_SIZE:
+ print "Length of stdout > %s, so only a portion will be saved in the database." % str( DATABASE_MAX_STRING_SIZE_PRETTY )
+ stdout = shrink_string_by_size( stdout, DATABASE_MAX_STRING_SIZE, join_by="\n..\n", left_larger=True, beginning_on_size_error=True )
+ if len( stderr ) > DATABASE_MAX_STRING_SIZE:
+ print "Length of stderr > %s, so only a portion will be saved in the database." % str( DATABASE_MAX_STRING_SIZE_PRETTY )
+ stderr = shrink_string_by_size( stderr, DATABASE_MAX_STRING_SIZE, join_by="\n..\n", left_larger=True, beginning_on_size_error=True )
+ if output.return_code not in [ 0 ]:
+ tool_dependency.status = app.install_model.ToolDependency.installation_status.ERROR
+ if stderr:
+ tool_dependency.error_message = unicodify( stderr )
+ elif stdout:
+ tool_dependency.error_message = unicodify( stdout )
+ else:
+ # We have a problem if there was no stdout and no stderr.
+ tool_dependency.error_message = "Unknown error occurred executing shell command %s, return_code: %s" % \
+ ( str( cmd ), str( output.return_code ) )
+ context.add( tool_dependency )
+ context.flush()
+ if return_output:
+ return output
+ return output.return_code
+
+ def handle_complex_command( self, command ):
+ """
+ Wrap subprocess.Popen in such a way that the stderr and stdout from running a shell command will
+ be captured and logged in nearly real time. This is similar to fabric.local, but allows us to
+ retain control over the process. This method is named "complex" because it uses queues and
+ threads to execute a command while capturing and displaying the output.
+ """
+ # Launch the command as subprocess. A bufsize of 1 means line buffered.
+ process_handle = subprocess.Popen( str( command ),
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ bufsize=1,
+ close_fds=False,
+ shell=True,
+ cwd=state.env[ 'lcwd' ] )
+ pid = process_handle.pid
+ # Launch the asynchronous readers of the process' stdout and stderr.
+ stdout_queue = Queue.Queue()
+ stdout_reader = AsynchronousReader( process_handle.stdout, stdout_queue )
+ stdout_reader.start()
+ stderr_queue = Queue.Queue()
+ stderr_reader = AsynchronousReader( process_handle.stderr, stderr_queue )
+ stderr_reader.start()
+ # Place streamed stdout and stderr into a threaded IPC queue target so it can
+ # be printed and stored for later retrieval when generating the INSTALLATION.log.
+ stdio_thread = threading.Thread( target=self.enqueue_output,
+ args=( process_handle.stdout,
+ stdout_queue,
+ process_handle.stderr,
+ stderr_queue ) )
+ thread_lock = threading.Lock()
+ thread_lock.acquire()
+ stdio_thread.start()
+ # Check the queues for output until there is nothing more to get.
+ start_timer = time.time()
+ while not stdout_reader.installation_complete() or not stderr_reader.installation_complete():
+ # Show what we received from standard output.
+ while not stdout_queue.empty():
+ try:
+ line = stdout_queue.get()
+ except Queue.Empty:
+ line = None
+ break
+ if line:
+ print line
+ start_timer = time.time()
+ else:
+ break
+ # Show what we received from standard error.
+ while not stderr_queue.empty():
+ try:
+ line = stderr_queue.get()
+ except Queue.Empty:
+ line = None
+ break
+ if line:
+ print line
+ start_timer = time.time()
+ else:
+ stderr_queue.task_done()
+ break
+ # Sleep a bit before asking the readers again.
+ time.sleep( .1 )
+ current_wait_time = time.time() - start_timer
+ if stdout_queue.empty() and stderr_queue.empty() and current_wait_time > td_common_util.NO_OUTPUT_TIMEOUT:
+ err_msg = "\nShutting down process id %s because it generated no output for the defined timeout period of %.1f seconds.\n" % \
+ ( pid, td_common_util.NO_OUTPUT_TIMEOUT )
+ stderr_reader.lines.append( err_msg )
+ process_handle.kill()
+ break
+ thread_lock.release()
+ # Wait until each of the threads we've started terminate. The following calls will block each thread
+ # until it terminates either normally, through an unhandled exception, or until the timeout occurs.
+ stdio_thread.join( td_common_util.NO_OUTPUT_TIMEOUT )
+ stdout_reader.join( td_common_util.NO_OUTPUT_TIMEOUT )
+ stderr_reader.join( td_common_util.NO_OUTPUT_TIMEOUT )
+ # Close subprocess' file descriptors.
+ error = self.close_file_descriptor( process_handle.stdout )
+ error = self.close_file_descriptor( process_handle.stderr )
+ stdout = '\n'.join( stdout_reader.lines )
+ stderr = '\n'.join( stderr_reader.lines )
+ # Handle error condition (deal with stdout being None, too)
+ output = _AttributeString( stdout.strip() if stdout else "" )
+ errors = _AttributeString( stderr.strip() if stderr else "" )
+ # Make sure the process has finished.
+ process_handle.poll()
+ output.return_code = process_handle.returncode
+ output.stderr = errors
+ return output
+
+ def log_results( self, command, fabric_AttributeString, file_path ):
+ """Write attributes of fabric.operations._AttributeString to a specified log file."""
+ if os.path.exists( file_path ):
+ logfile = open( file_path, 'ab' )
+ else:
+ logfile = open( file_path, 'wb' )
+ logfile.write( "\n#############################################\n" )
+ logfile.write( '%s\nSTDOUT\n' % command )
+ logfile.write( str( fabric_AttributeString.stdout ) )
+ logfile.write( "\n#############################################\n" )
+ logfile.write( "\n#############################################\n" )
+ logfile.write( '%s\nSTDERR\n' % command )
+ logfile.write( str( fabric_AttributeString.stderr ) )
+ logfile.write( "\n#############################################\n" )
+ logfile.close()
+
+ @contextmanager
+ def make_tmp_dir( self ):
+ work_dir = tempfile.mkdtemp( prefix="tmp-toolshed-mtd" )
+ yield work_dir
+ if os.path.exists( work_dir ):
+ try:
+ shutil.rmtree( work_dir )
+ except Exception, e:
+ log.exception( str( e ) )
+
+ def __setup_environment( self ):
+ return "&&".join( [ ". %s" % file for file in self.__valid_env_shell_file_paths() ] )
+
+ def __valid_env_shell_file_paths( self ):
+ return [ file for file in self.env_shell_file_paths if os.path.exists( file ) ]
+
+
+class RecipeManager( object ):
+
+ def __init__( self ):
+ self.step_handlers_by_type = self.load_step_handlers()
+
+ def get_step_handler_by_type( self, type ):
+ return self.step_handlers_by_type.get( type, None )
+
+ def execute_step( self, app, tool_dependency, package_name, actions, action_type, action_dict, filtered_actions,
+ env_file_builder, install_environment, work_dir, install_dir, current_dir=None, initial_download=False ):
+ if actions:
+ step_handler = self.get_step_handler_by_type( action_type )
+ tool_dependency, filtered_actions, dir = step_handler.execute_step( app=app,
+ tool_dependency=tool_dependency,
+ package_name=package_name,
+ actions=actions,
+ action_dict=action_dict,
+ filtered_actions=filtered_actions,
+ env_file_builder=env_file_builder,
+ install_environment=install_environment,
+ work_dir=work_dir,
+ install_dir=install_dir,
+ current_dir=current_dir,
+ initial_download=initial_download )
+ else:
+ dir = None
+ return tool_dependency, filtered_actions, dir
+
+ def load_step_handlers( self ):
+ step_handlers_by_type = dict( autoconf=step_handler.Autoconf(),
+ change_directory=step_handler.ChangeDirectory(),
+ chmod=step_handler.Chmod(),
+ download_binary=step_handler.DownloadBinary(),
+ download_by_url=step_handler.DownloadByUrl(),
+ download_file=step_handler.DownloadFile(),
+ make_directory=step_handler.MakeDirectory(),
+ make_install=step_handler.MakeInstall(),
+ move_directory_files=step_handler.MoveDirectoryFiles(),
+ move_file=step_handler.MoveFile(),
+ set_environment=step_handler.SetEnvironment(),
+ set_environment_for_install=step_handler.SetEnvironmentForInstall(),
+ setup_perl_environment=step_handler.SetupPerlEnvironment(),
+ setup_r_environment=step_handler.SetupREnvironment(),
+ setup_ruby_environment=step_handler.SetupRubyEnvironment(),
+ setup_virtual_env=step_handler.SetupVirtualEnv(),
+ shell_command=step_handler.ShellCommand(),
+ template_command=step_handler.TemplateCommand() )
+ return step_handlers_by_type
+
+ def prepare_step( self, app, tool_dependency, action_type, action_elem, action_dict, install_dir, is_binary_download ):
+ """
+ Prepare the recipe step for later execution. This generally alters the received action_dict
+ with new information needed during this step's execution.
+ """
+ if action_elem is not None:
+ step_handler = self.get_step_handler_by_type( action_type )
+ action_dict = step_handler.prepare_step( app=app,
+ tool_dependency=tool_dependency,
+ action_elem=action_elem,
+ action_dict=action_dict,
+ install_dir=install_dir,
+ is_binary_download=is_binary_download )
+ return action_dict
+
\ No newline at end of file
This diff is so big that we needed to truncate the remainder.
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: carlfeberhard: Client app: extract method on client app init to javascript_app so it isn't called twice when using parent.javascripts()
by commits-noreply@bitbucket.org 24 Apr '14
by commits-noreply@bitbucket.org 24 Apr '14
24 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/369bb0f7ebef/
Changeset: 369bb0f7ebef
User: carlfeberhard
Date: 2014-04-24 16:34:24
Summary: Client app: extract method on client app init to javascript_app so it isn't called twice when using parent.javascripts()
Affected #: 5 files
diff -r 641f7063ce3c5dcf375aafdd9a65a2e3f7ccfa4c -r 369bb0f7ebef50a72f36cf2f74d23f7d351d61c4 templates/base.mako
--- a/templates/base.mako
+++ b/templates/base.mako
@@ -12,6 +12,7 @@
${self.metas()}
${self.stylesheets()}
${self.javascripts()}
+ ${self.javascript_app()}
</head><body class="inbound">
${next.body()}
@@ -83,8 +84,6 @@
});
</script>
- ${ galaxy_client.load( app=self.js_app ) }
-
%if not form_input_auto_focus is UNDEFINED and form_input_auto_focus:
<script type="text/javascript">
$(document).ready( function() {
@@ -98,5 +97,9 @@
</%def>
+<%def name="javascript_app()">
+ ${ galaxy_client.load( app=self.js_app ) }
+</%def>
+
## Additional metas can be defined by templates inheriting from this one.
<%def name="metas()"></%def>
diff -r 641f7063ce3c5dcf375aafdd9a65a2e3f7ccfa4c -r 369bb0f7ebef50a72f36cf2f74d23f7d351d61c4 templates/base/base_panels.mako
--- a/templates/base/base_panels.mako
+++ b/templates/base/base_panels.mako
@@ -1,6 +1,6 @@
<!DOCTYPE HTML>
+<%namespace name="galaxy_client" file="/galaxy_client_app.mako" />
-<%namespace name="galaxy_client" file="/galaxy_client_app.mako" /><%
self.has_left_panel = hasattr( self, 'left_panel' )
self.has_right_panel = hasattr( self, 'right_panel' )
@@ -20,7 +20,10 @@
## Default stylesheets
<%def name="stylesheets()">
- ${h.css('base','jquery.rating')}
+ ${h.css(
+ 'base',
+ 'jquery.rating'
+ )}
<style type="text/css">
#center {
%if not self.has_left_panel:
@@ -67,9 +70,9 @@
root: '${h.url_for( "/" )}'
};
- ## load additional style sheet
- if (window != window.top)
- $('<link href="' + galaxy_config.root + 'static/style/galaxy.frame.masthead.css" rel="stylesheet">').appendTo('head');
+ //## load additional style sheet
+ //if (window != window.top)
+ // $('<link href="' + galaxy_config.root + 'static/style/galaxy.frame.masthead.css" rel="stylesheet">').appendTo('head');
// console protection
window.console = window.console || {
@@ -91,16 +94,24 @@
});
</script>
+</%def>
+
+<%def name="javascript_app()">
## load the Galaxy global js var
${ galaxy_client.load() }
-
</%def>
## Default late-load javascripts
<%def name="late_javascripts()">
## Scripts can be loaded later since they progressively add features to
## the panels, but do not change layout
- ${h.js( 'libs/jquery/jquery.event.drag', 'libs/jquery/jquery.event.hover', 'libs/jquery/jquery.form', 'libs/jquery/jquery.rating', 'galaxy.panels' )}
+ ${h.js(
+ 'libs/jquery/jquery.event.drag',
+ 'libs/jquery/jquery.event.hover',
+ 'libs/jquery/jquery.form',
+ 'libs/jquery/jquery.rating',
+ 'galaxy.panels'
+ )}
<script type="text/javascript">
ensure_dd_helper();
@@ -295,6 +306,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
${self.stylesheets()}
${self.javascripts()}
+ ${self.javascript_app()}
</head><%
diff -r 641f7063ce3c5dcf375aafdd9a65a2e3f7ccfa4c -r 369bb0f7ebef50a72f36cf2f74d23f7d351d61c4 templates/webapps/galaxy/base_panels.mako
--- a/templates/webapps/galaxy/base_panels.mako
+++ b/templates/webapps/galaxy/base_panels.mako
@@ -1,4 +1,5 @@
<%inherit file="/base/base_panels.mako"/>
+<!-- webapps/galaxy/base_panels.mako --><%namespace name="mod_masthead" file="/webapps/galaxy/galaxy.masthead.mako"/>
## Default title
@@ -17,4 +18,4 @@
<%
mod_masthead.load(self.active_view);
%>
-</%def>
\ No newline at end of file
+</%def>
diff -r 641f7063ce3c5dcf375aafdd9a65a2e3f7ccfa4c -r 369bb0f7ebef50a72f36cf2f74d23f7d351d61c4 templates/webapps/galaxy/galaxy.panels.mako
--- a/templates/webapps/galaxy/galaxy.panels.mako
+++ b/templates/webapps/galaxy/galaxy.panels.mako
@@ -101,6 +101,11 @@
});
var galaxy_config = ${ h.to_json_string( self.galaxy_config ) };
+ </script>
+</%def>
+
+<%def name="javascript_app()">
+ <script type="text/javascript">
// load any app configured
define( 'app', function(){
var jscript = galaxy_config.app.jscript;
@@ -116,6 +121,7 @@
}
});
</script>
+
## load the Galaxy global js var and run 'app' from above
${ galaxy_client.load( app='app' ) }
@@ -125,7 +131,6 @@
##${ galaxy_client.load( app=( app_config[ 'jscript' ] if 'jscript' in app_config else None )) }
##TODO: at that point, we can think about optimizing the various apps
-
</%def>
## default late-load javascripts
@@ -165,6 +170,7 @@
## load scripts
${self.javascripts()}
+ ${self.javascript_app()}
</head><body scroll="no" class="full-content">
diff -r 641f7063ce3c5dcf375aafdd9a65a2e3f7ccfa4c -r 369bb0f7ebef50a72f36cf2f74d23f7d351d61c4 templates/webapps/galaxy/root/history.mako
--- a/templates/webapps/galaxy/root/history.mako
+++ b/templates/webapps/galaxy/root/history.mako
@@ -8,13 +8,16 @@
## -----------------------------------------------------------------------------
<%def name="javascripts()">
${ parent.javascripts() }
-
<script type="text/javascript">
$(function(){
$( 'body' ).addClass( 'historyPage' ).addClass( 'history-panel' )
.css({ margin: '0px', padding: '0px' });
});
+</script>
+</%def>
+<%def name="javascript_app()">
+<script type="text/javascript">
define( 'app', function(){
require([
'mvc/history/current-history-panel'
@@ -34,8 +37,7 @@
});
});
});
-})
+});
</script>
${ galaxy_client.load( app='app', history=history, hdas=hdas, show_deleted=show_deleted, show_hidden=show_hidden ) }
-
</%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: jmchilton: Update LWR client through LWR changeset bd8d1cc.
by commits-noreply@bitbucket.org 24 Apr '14
by commits-noreply@bitbucket.org 24 Apr '14
24 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/641f7063ce3c/
Changeset: 641f7063ce3c
User: jmchilton
Date: 2014-04-24 07:31:57
Summary: Update LWR client through LWR changeset bd8d1cc.
Needed for LWR runner to be able to use env tags from job conf file.
Affected #: 4 files
diff -r b172ca94e169ccf2450432398d67623f79c5588f -r 641f7063ce3c5dcf375aafdd9a65a2e3f7ccfa4c lib/galaxy/jobs/runners/lwr_client/client.py
--- a/lib/galaxy/jobs/runners/lwr_client/client.py
+++ b/lib/galaxy/jobs/runners/lwr_client/client.py
@@ -39,6 +39,7 @@
)
else:
job_directory = None
+ self.env = destination_params.get( "env", [] )
self.files_endpoint = destination_params.get("files_endpoint", None)
self.job_directory = job_directory
@@ -81,7 +82,7 @@
super(JobClient, self).__init__(destination_params, job_id)
self.job_manager_interface = job_manager_interface
- def launch(self, command_line, requirements=[], remote_staging=[], job_config=None):
+ def launch(self, command_line, requirements=[], env=[], remote_staging=[], job_config=None):
"""
Queue up the execution of the supplied `command_line` on the remote
server. Called launch for historical reasons, should be renamed to
@@ -98,6 +99,8 @@
launch_params['params'] = dumps(submit_params_dict)
if requirements:
launch_params['requirements'] = dumps([requirement.to_dict() for requirement in requirements])
+ if env:
+ launch_params['env'] = dumps(env)
if remote_staging:
launch_params['remote_staging'] = dumps(remote_staging)
if job_config and self.setup_handler.local:
@@ -291,7 +294,7 @@
raise Exception(error_message)
self.client_manager = client_manager
- def launch(self, command_line, requirements=[], remote_staging=[], job_config=None):
+ def launch(self, command_line, requirements=[], env=[], remote_staging=[], job_config=None):
"""
"""
launch_params = dict(command_line=command_line, job_id=self.job_id)
@@ -300,6 +303,8 @@
launch_params['params'] = submit_params_dict
if requirements:
launch_params['requirements'] = [requirement.to_dict() for requirement in requirements]
+ if env:
+ launch_params['env'] = env
if remote_staging:
launch_params['remote_staging'] = remote_staging
if job_config and self.setup_handler.local:
diff -r b172ca94e169ccf2450432398d67623f79c5588f -r 641f7063ce3c5dcf375aafdd9a65a2e3f7ccfa4c lib/galaxy/jobs/runners/lwr_client/staging/__init__.py
--- a/lib/galaxy/jobs/runners/lwr_client/staging/__init__.py
+++ b/lib/galaxy/jobs/runners/lwr_client/staging/__init__.py
@@ -32,6 +32,8 @@
Local path created by Galaxy for running this job.
requirements : list
List of requirements for tool execution.
+ env: list
+ List of dict object describing environment variables to populate.
version_file : str
Path to version file expected on the client server
arbitrary_files : dict()
@@ -54,6 +56,7 @@
client_outputs,
working_directory,
requirements,
+ env=[],
arbitrary_files=None,
rewrite_paths=True,
):
@@ -64,6 +67,7 @@
self.client_outputs = client_outputs
self.working_directory = working_directory
self.requirements = requirements
+ self.env = env
self.rewrite_paths = rewrite_paths
self.arbitrary_files = arbitrary_files or {}
@@ -156,5 +160,5 @@
return join(output_directory, self.path_helper.local_name(name))
files_directory = "%s_files%s" % (basename(output_file)[0:-len(".dat")], self.path_helper.separator)
- names = filter(lambda o: o.startswith(files_directory), self.output_directory_contents)
+ names = filter(lambda o: o.startswith(files_directory), self.output_directory_contents)
return dict(map(lambda name: (local_path(name), name), names))
diff -r b172ca94e169ccf2450432398d67623f79c5588f -r 641f7063ce3c5dcf375aafdd9a65a2e3f7ccfa4c lib/galaxy/jobs/runners/lwr_client/staging/down.py
--- a/lib/galaxy/jobs/runners/lwr_client/staging/down.py
+++ b/lib/galaxy/jobs/runners/lwr_client/staging/down.py
@@ -80,7 +80,10 @@
if self._attempt_collect_output('output_workdir', path=output_file, name=lwr_name):
self.downloaded_working_directory_files.append(lwr_name)
# Remove from full output_files list so don't try to download directly.
- self.output_files.remove(output_file)
+ try:
+ self.output_files.remove(output_file)
+ except ValueError:
+ raise Exception("Failed to remove %s from %s" % (output_file, self.output_files))
def __collect_outputs(self):
# Legacy LWR not returning list of files, iterate over the list of
diff -r b172ca94e169ccf2450432398d67623f79c5588f -r 641f7063ce3c5dcf375aafdd9a65a2e3f7ccfa4c lib/galaxy/jobs/runners/lwr_client/staging/up.py
--- a/lib/galaxy/jobs/runners/lwr_client/staging/up.py
+++ b/lib/galaxy/jobs/runners/lwr_client/staging/up.py
@@ -25,6 +25,7 @@
launch_kwds = dict(
command_line=rebuilt_command_line,
requirements=client_job_description.requirements,
+ env=client_job_description.env,
)
if file_stager.job_config:
launch_kwds["job_config"] = file_stager.job_config
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: jmchilton: Fix Python 3 incompat in galaxy.jobs.runners.util.
by commits-noreply@bitbucket.org 24 Apr '14
by commits-noreply@bitbucket.org 24 Apr '14
24 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/b172ca94e169/
Changeset: b172ca94e169
User: jmchilton
Date: 2014-04-24 03:33:41
Summary: Fix Python 3 incompat in galaxy.jobs.runners.util.
Module shared with LWR so hoping for Python 3 compat.
Affected #: 2 files
diff -r 776e13962bbc861a94242e142e73278c9499dc70 -r b172ca94e169ccf2450432398d67623f79c5588f lib/galaxy/jobs/runners/util/__init__.py
--- a/lib/galaxy/jobs/runners/util/__init__.py
+++ b/lib/galaxy/jobs/runners/util/__init__.py
@@ -3,7 +3,5 @@
processes and interfacing with job managers. This module should contain
functionality shared between Galaxy and the LWR.
"""
-try:
- from galaxy.util.bunch import Bunch
-except ImportError:
- from lwr.util import Bunch
+
+from galaxy.util.bunch import Bunch
diff -r 776e13962bbc861a94242e142e73278c9499dc70 -r b172ca94e169ccf2450432398d67623f79c5588f lib/galaxy/jobs/runners/util/condor/__init__.py
--- a/lib/galaxy/jobs/runners/util/condor/__init__.py
+++ b/lib/galaxy/jobs/runners/util/condor/__init__.py
@@ -20,7 +20,8 @@
def submission_params(prefix=SUBMIT_PARAM_PREFIX, **kwds):
submission_params = {}
- for key, value in kwds.iteritems():
+ for key in kwds:
+ value = kwds[key]
key = key.lower()
if key.startswith(prefix):
condor_key = key[len(prefix):]
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: martenson: data libraries: default sorting; cleanup; refactor; jslint; start on getting rid of modals for library/folder creation
by commits-noreply@bitbucket.org 23 Apr '14
by commits-noreply@bitbucket.org 23 Apr '14
23 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/776e13962bbc/
Changeset: 776e13962bbc
User: martenson
Date: 2014-04-23 23:31:01
Summary: data libraries: default sorting; cleanup; refactor; jslint; start on getting rid of modals for library/folder creation
Affected #: 15 files
diff -r 51643642564f214f09c2eff32307360f5e09dfaf -r 776e13962bbc861a94242e142e73278c9499dc70 static/scripts/galaxy.library.js
--- a/static/scripts/galaxy.library.js
+++ b/static/scripts/galaxy.library.js
@@ -79,7 +79,7 @@
this.library_router.on('route:download', function(folder_id, format) {
if ($('#center').find(':checked').length === 0) {
- mod_toastr.info('You have to select some datasets to download')
+ mod_toastr.info('You have to select some datasets to download');
} else {
Galaxy.libraries.folderToolbarView.download(folder_id, format);
Galaxy.libraries.library_router.navigate('folders/' + folder_id, {trigger: false, replace: true});
diff -r 51643642564f214f09c2eff32307360f5e09dfaf -r 776e13962bbc861a94242e142e73278c9499dc70 static/scripts/mvc/library/library-folderlist-view.js
--- a/static/scripts/mvc/library/library-folderlist-view.js
+++ b/static/scripts/mvc/library/library-folderlist-view.js
@@ -25,253 +25,257 @@
sort: 'asc',
- // event binding
events: {
'click #select-all-checkboxes' : 'selectAll',
'click .dataset_row' : 'selectClickedRow',
'click .sort-folder-link' : 'sort_clicked'
},
- // initialize
- initialize : function(options){
- var that = this;
- this.options = _.defaults(this.options || {}, options);
- this.queue = jQuery.Deferred();
- this.queue.resolve();
- this.collection = new mod_library_model.Folder();
- this.listenTo(this.collection, 'add', this.addOne);
-
- this.folderContainer = new mod_library_model.FolderContainer({id: this.options.id});
- this.folderContainer.url = this.folderContainer.attributes.urlRoot + this.options.id + '/contents';
- this.folderContainer.fetch({
- success: function (folder_container) {
- that.render();
+
+ initialize : function(options){
+ var that = this;
+ this.options = _.defaults(this.options || {}, options);
+ this.collection = new mod_library_model.Folder();
- var items = folder_container.get('folder').models;
- that.addAll(items);
+ // start to listen if someone adds a model to the collection
+ this.listenTo(this.collection, 'add', this.addOne);
+
+ this.folderContainer = new mod_library_model.FolderContainer({id: this.options.id});
+ this.folderContainer.url = this.folderContainer.attributes.urlRoot + this.options.id + '/contents';
+ this.folderContainer.fetch({
+ success: function (folder_container) {
+ that.render();
+ var items = folder_container.get('folder').models;
+ that.addAll(items);
+ },
+ error: function(model, response){
+ if (typeof response.responseJSON !== "undefined"){
+ mod_toastr.error(response.responseJSON.err_msg);
+ } else {
+ mod_toastr.error('An error ocurred :(');
+ }
+ }
+ });
+ },
- },
- error: function(){
- mod_toastr.error('An error occured :(');
- }
- });
- },
+ render: function (options) {
+ this.options = _.defaults(this.options || {}, options);
+ var template = this.templateFolder();
- render: function (options) {
- this.options = _.defaults(this.options || {}, options);
- var template = this.templateFolder();
- var contains_file = false;
+ // TODO move to server
+ // find the upper id in the full path
+ var path = this.folderContainer.attributes.metadata.full_path;
+ var upper_folder_id;
+ if (path.length === 1){ // the library is above us
+ upper_folder_id = 0;
+ } else {
+ upper_folder_id = path[path.length-2][0];
+ }
- // TODO move to server
- // prepare nice size strings
- // for (var i = 0; i < this.collection.models.length; i++) {
- // var model = this.collection.models[i];
- // if (model.get('type') === 'file'){
- // contains_file = true;
- // model.set('readable_size', this.size_to_string(model.get('file_size')));
- // }
- // }
+ this.$el.html(template({ path: this.folderContainer.attributes.metadata.full_path, id: this.options.id, upper_folder_id: upper_folder_id, order: this.sort}));
- // TODO move to server
- // find the upper id in the full path
- var path = this.folderContainer.attributes.metadata.full_path;
- var upper_folder_id;
- if (path.length === 1){ // the library is above us
- upper_folder_id = 0;
- } else {
- upper_folder_id = path[path.length-2][0];
+ var fetched_metadata = this.folderContainer.attributes.metadata;
+ fetched_metadata.contains_file = this.options.contains_file;
+ Galaxy.libraries.folderToolbarView.configureElements(fetched_metadata);
+
+ // initialize the library tooltips
+ $("#center [data-toggle]").tooltip();
+ //hack to show scrollbars
+ $("#center").css('overflow','auto');
+ },
+
+ /** Adds all given models to the collection. */
+ addAll:function(items){
+ _.each(items.reverse(), function(item) {
+ Galaxy.libraries.folderListView.collection.add(item);
+ });
+ this.checkEmptiness();
+ },
+
+ /** Creates a view for the given model and adds it to the folder view. */
+ addOne: function(model){
+ if (model.get('data_type') !== 'folder'){
+ this.options.contains_file = true;
+ model.set('readable_size', this.size_to_string(model.get('file_size')));
}
- // TODO add template when folder is empty
+ var rowView = new mod_library_folderrow_view.FolderRowView(model);
+ this.$el.find('#first_folder_item').after(rowView.el);
+ this.checkEmptiness();
+ },
- this.$el.html(template({ path: this.folderContainer.attributes.metadata.full_path, id: this.options.id, upper_folder_id: upper_folder_id, order: this.sort}));
- // this.$el.html(template({ path: this.folderContainer.attributes.metadata.full_path, items: this.folderContainer.attributes.folder.models, id: this.options.id, upper_folder_id: upper_folder_id }));
+ /** Checks whether the list is empty and adds/removes the message */
+ // TODO needs refactor
+ checkEmptiness : function(){
+ if ((this.$el.find('.dataset_row').length === 0) && (this.$el.find('.folder_row').length === 0)){
+ var empty_folder_tmpl = this.templateEmptyFolder();
+ this.$el.find('#folder_list_body').append(empty_folder_tmpl());
+ } else {
+ this.$el.find('#empty_folder_message').remove();
+ }
+ },
- if (this.collection.models.length > 0){
- this.renderRows();
+ /** User clicked the table heading = he wants to sort stuff */
+ sort_clicked : function(event){
+ event.preventDefault();
+ if (this.sort === 'asc'){
+ this.sortFolder('name','desc');
+ this.sort = 'desc';
+ } else {
+ this.sortFolder('name','asc');
+ this.sort = 'asc';
+ }
+ this.render();
+ },
+
+ /** Sorts the underlying collection according to the parameters received.
+ * Currently supports only sorting by name. */
+ sortFolder: function(sort_by, order){
+ if (sort_by === 'name'){
+ if (order === 'asc'){
+ this.collection.sortByNameAsc();
+ } else if (order === 'desc'){
+ this.collection.sortByNameDesc();
+ }
}
- // if (this.folderContainer.attributes.metadata.can_add_library_item === true){
- var options = this.folderContainer.attributes.metadata;
- options.contains_file = this.options.contains_file;
- Galaxy.libraries.folderToolbarView.configureElements(options);
- // Galaxy.libraries.folderToolbarView.configureElements({ can_add_library_item: this.folderContainer.attributes.metadata.can_add_library_item, contains_file: contains_file });
- // }
+ },
- // initialize the library tooltips
- $("#center [data-toggle]").tooltip();
- //hack to show scrollbars
- $("#center").css('overflow','auto');
- },
+ /** convert size to nice string */
+ size_to_string : function (size){
+ // identify unit
+ var unit = "";
+ if (size >= 100000000000) { size = size / 100000000000; unit = "TB"; } else
+ if (size >= 100000000) { size = size / 100000000; unit = "GB"; } else
+ if (size >= 100000) { size = size / 100000; unit = "MB"; } else
+ if (size >= 100) { size = size / 100; unit = "KB"; } else
+ { size = size * 10; unit = "b"; }
+ // return formatted string
+ return (Math.round(size) / 10) + unit;
+ },
- renderRows: function(){
- for (var i = 0; i < this.collection.models.length; i++) {
- var folder_item = this.collection.models[i];
- var rowView = new mod_library_folderrow_view.FolderRowView(folder_item);
- this.$el.find('#folder_list_body').append(rowView.el);
- }
- },
+ /** User clicked the checkbox in the table heading */
+ selectAll : function (event) {
+ var selected = event.target.checked;
+ that = this;
+ // Iterate each checkbox
+ $(':checkbox').each(function() {
+ this.checked = selected;
+ $row = $(this.parentElement.parentElement);
+ // Change color of selected/unselected
+ if (selected) {
+ that.makeDarkRow($row);
+ } else {
+ that.makeWhiteRow($row);
+ }
+ });
+ },
- addAll:function(items){
- _.each(items.reverse(), function(item) {
- Galaxy.libraries.folderListView.collection.add(item);
- });
- },
+ /** Check checkbox if user clicks on the whole row or
+ * on the checkbox itself */
+ selectClickedRow : function (event) {
+ var checkbox = '';
+ var $row;
+ var source;
+ if (event.target.localName === 'input'){
+ checkbox = event.target;
+ $row = $(event.target.parentElement.parentElement);
+ source = 'input';
+ } else if (event.target.localName === 'td') {
+ checkbox = $("#" + event.target.parentElement.id).find(':checkbox')[0];
+ $row = $(event.target.parentElement);
+ source = 'td';
+ }
+ if (checkbox.checked){
+ if (source==='td'){
+ checkbox.checked = '';
+ this.makeWhiteRow($row);
+ } else if (source==='input') {
+ this.makeDarkRow($row);
+ }
+ } else {
+ if (source==='td'){
+ checkbox.checked = 'selected';
+ this.makeDarkRow($row);
+ } else if (source==='input') {
+ this.makeWhiteRow($row);
+ }
+ }
+ },
- addOne: function(model){
- if (model.get('data_type') !== 'folder'){
- this.options.contains_file = true;
- model.set('readable_size', this.size_to_string(model.get('file_size')));
- }
- var rowView = new mod_library_folderrow_view.FolderRowView(model);
- this.$el.find('#first_folder_item').after(rowView.el);
- },
+ makeDarkRow: function($row){
+ $row.removeClass('light');
+ $row.find('a').removeClass('light');
+ $row.addClass('dark');
+ $row.find('a').addClass('dark');
+ $row.find('span').removeClass('fa-file-o');
+ $row.find('span').addClass('fa-file');
+ },
- sort_clicked : function(event){
- event.preventDefault();
- if (this.sort === 'asc'){
- this.sortFolder('name','desc');
- this.sort = 'desc';
- } else {
- this.sortFolder('name','asc');
- this.sort = 'asc';
- }
- this.render();
- },
-
- /** Sorts the underlying collection according to the parameters received.
- Currently supports only sorting by name. */
- sortFolder: function(sort_by, order){
- if (sort_by === 'name'){
- if (order === 'asc'){
- this.collection.sortByNameAsc();
- } else if (order === 'desc'){
- this.collection.sortByNameDesc();
- }
- }
- },
-
- // convert size to nice string
- size_to_string : function (size){
- // identify unit
- var unit = "";
- if (size >= 100000000000) { size = size / 100000000000; unit = "TB"; } else
- if (size >= 100000000) { size = size / 100000000; unit = "GB"; } else
- if (size >= 100000) { size = size / 100000; unit = "MB"; } else
- if (size >= 100) { size = size / 100; unit = "KB"; } else
- { size = size * 10; unit = "b"; }
- // return formatted string
- return (Math.round(size) / 10) + unit;
- },
-
- // select all datasets
- selectAll : function (event) {
- var selected = event.target.checked;
- that = this;
- // Iterate each checkbox
- $(':checkbox').each(function() {
- this.checked = selected;
- $row = $(this.parentElement.parentElement);
- // Change color of selected/unselected
- (selected) ? that.makeDarkRow($row) : that.makeWhiteRow($row);
- });
- // Show the tools in menu
- // this.checkTools();
- },
-
- // Check checkbox on row itself or row checkbox click
- selectClickedRow : function (event) {
- var checkbox = '';
- var $row;
- var source;
- if (event.target.localName === 'input'){
- checkbox = event.target;
- $row = $(event.target.parentElement.parentElement);
- source = 'input';
- } else if (event.target.localName === 'td') {
- checkbox = $("#" + event.target.parentElement.id).find(':checkbox')[0];
- $row = $(event.target.parentElement);
- source = 'td';
- }
- if (checkbox.checked){
- if (source==='td'){
- checkbox.checked = '';
- this.makeWhiteRow($row);
- } else if (source==='input') {
- this.makeDarkRow($row);
- }
- } else {
- if (source==='td'){
- checkbox.checked = 'selected';
- this.makeDarkRow($row);
- } else if (source==='input') {
- this.makeWhiteRow($row);
- }
- }
- },
-
- makeDarkRow: function($row){
- $row.removeClass('light');
- $row.find('a').removeClass('light');
- $row.addClass('dark');
- $row.find('a').addClass('dark');
- $row.find('span').removeClass('fa-file-o');
- $row.find('span').addClass('fa-file');
- },
-
- makeWhiteRow: function($row){
- $row.removeClass('dark');
- $row.find('a').removeClass('dark');
- $row.addClass('light');
- $row.find('a').addClass('light');
- $row.find('span').addClass('fa-file-o');
- $row.find('span').removeClass('fa-file');
- },
+ makeWhiteRow: function($row){
+ $row.removeClass('dark');
+ $row.find('a').removeClass('dark');
+ $row.addClass('light');
+ $row.find('a').addClass('light');
+ $row.find('span').addClass('fa-file-o');
+ $row.find('span').removeClass('fa-file');
+ },
// MMMMMMMMMMMMMMMMMM
// === TEMPLATES ====
// MMMMMMMMMMMMMMMMMM
- // main template for folder browsing
- templateFolder : function (){
- var tmpl_array = [];
+ templateFolder : function (){
+ var tmpl_array = [];
- // BREADCRUMBS
- tmpl_array.push('<ol class="breadcrumb">');
- tmpl_array.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');
- tmpl_array.push(' <% _.each(path, function(path_item) { %>');
- tmpl_array.push(' <% if (path_item[0] != id) { %>');
- tmpl_array.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');
- tmpl_array.push( '<% } else { %>');
- tmpl_array.push(' <li class="active"><span title="You are in this folder"><%- path_item[1] %></span></li>');
- tmpl_array.push(' <% } %>');
- tmpl_array.push(' <% }); %>');
- tmpl_array.push('</ol>');
+ // BREADCRUMBS
+ tmpl_array.push('<ol class="breadcrumb">');
+ tmpl_array.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');
+ tmpl_array.push(' <% _.each(path, function(path_item) { %>');
+ tmpl_array.push(' <% if (path_item[0] != id) { %>');
+ tmpl_array.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');
+ tmpl_array.push( '<% } else { %>');
+ tmpl_array.push(' <li class="active"><span title="You are in this folder"><%- path_item[1] %></span></li>');
+ tmpl_array.push(' <% } %>');
+ tmpl_array.push(' <% }); %>');
+ tmpl_array.push('</ol>');
- // FOLDER CONTENT
- tmpl_array.push('<table id="folder_table" class="grid table table-condensed">');
- tmpl_array.push(' <thead>');
- tmpl_array.push(' <th class="button_heading"></th>');
- tmpl_array.push(' <th style="text-align: center; width: 20px; "><input id="select-all-checkboxes" style="margin: 0;" type="checkbox"></th>');
- tmpl_array.push(' <th><a class="sort-folder-link" title="Click to reverse order" href="#">name</a><span title="Sorted alphabetically" class="fa fa-sort-alpha-<%- order %>"></span></th>');
- tmpl_array.push(' <th>data type</th>');
- tmpl_array.push(' <th>size</th>');
- tmpl_array.push(' <th>time updated (UTC)</th>');
- tmpl_array.push(' </thead>');
- tmpl_array.push(' <tbody id="folder_list_body">');
- tmpl_array.push(' <tr id="first_folder_item">');
- tmpl_array.push(' <td><a href="#<% if (upper_folder_id !== 0){ print("folders/" + upper_folder_id)} %>" title="Go to parent folder" class="btn_open_folder btn btn-default btn-xs">..<a></td>');
- tmpl_array.push(' <td></td>');
- tmpl_array.push(' <td></td>');
- tmpl_array.push(' <td></td>');
- tmpl_array.push(' <td></td>');
- tmpl_array.push(' <td></td>');
- tmpl_array.push(' </tr>');
+ // FOLDER CONTENT
+ tmpl_array.push('<table id="folder_table" class="grid table table-condensed">');
+ tmpl_array.push(' <thead>');
+ tmpl_array.push(' <th class="button_heading"></th>');
+ tmpl_array.push(' <th style="text-align: center; width: 20px; " title="Check to select all datasets"><input id="select-all-checkboxes" style="margin: 0;" type="checkbox"></th>');
+ tmpl_array.push(' <th><a class="sort-folder-link" title="Click to reverse order" href="#">name</a><span title="Sorted alphabetically" class="fa fa-sort-alpha-<%- order %>"></span></th>');
+ tmpl_array.push(' <th>data type</th>');
+ tmpl_array.push(' <th>size</th>');
+ tmpl_array.push(' <th>time updated (UTC)</th>');
+ tmpl_array.push(' </thead>');
+ tmpl_array.push(' <tbody id="folder_list_body">');
+ tmpl_array.push(' <tr id="first_folder_item">');
+ tmpl_array.push(' <td><a href="#<% if (upper_folder_id !== 0){ print("folders/" + upper_folder_id)} %>" title="Go to parent folder" class="btn_open_folder btn btn-default btn-xs">..<a></td>');
+ tmpl_array.push(' <td></td>');
+ tmpl_array.push(' <td></td>');
+ tmpl_array.push(' <td></td>');
+ tmpl_array.push(' <td></td>');
+ tmpl_array.push(' <td></td>');
+ tmpl_array.push(' </tr>');
- tmpl_array.push(' </tbody>');
- tmpl_array.push('</table>');
+ tmpl_array.push(' </tbody>');
+ tmpl_array.push('</table>');
- return _.template(tmpl_array.join(''));
- }
+ return _.template(tmpl_array.join(''));
+ },
- });
+ templateEmptyFolder: function(){
+ var tmpl_array = [];
+
+ tmpl_array.push('<tr id="empty_folder_message">');
+ tmpl_array.push('<td colspan="6" style="text-align:center">');
+ tmpl_array.push('This folder is either empty or you do not have proper access permissions to see the contents.');
+ tmpl_array.push('</td>');
+ tmpl_array.push('</tr>');
+
+ return _.template(tmpl_array.join(''));
+ }
+
+ });
return {
FolderListView: FolderListView
diff -r 51643642564f214f09c2eff32307360f5e09dfaf -r 776e13962bbc861a94242e142e73278c9499dc70 static/scripts/mvc/library/library-foldertoolbar-view.js
--- a/static/scripts/mvc/library/library-foldertoolbar-view.js
+++ b/static/scripts/mvc/library/library-foldertoolbar-view.js
@@ -221,12 +221,12 @@
}
var promise = $.when(popped_item.save({content: popped_item.content, source: popped_item.source}));
- promise.done(function(a1){
+ promise.done(function(){
// we are fine
self.updateProgress();
self.chainCall(history_item_set, history_name);
})
- .fail(function(a1){
+ .fail(function(){
// we have a problem
self.options.chain_call_control.failed_number += 1;
self.updateProgress();
@@ -315,7 +315,7 @@
self.histories.get(history_id).set({'contents' : history_contents});
self.modal.$el.find('#selected_history_content').html(history_contents_template({history_contents: history_contents.models.reverse()}));
},
- error: function(model, response){
+ error: function(){
mod_toastr.error('An error ocurred :(');
}
});
@@ -381,7 +381,7 @@
self.updateProgress();
self.chainCallAddingHdas(hdas_set);
})
- .fail(function(data){
+ .fail(function(){
// we have a problem
self.options.chain_call_control.failed_number += 1;
self.updateProgress();
diff -r 51643642564f214f09c2eff32307360f5e09dfaf -r 776e13962bbc861a94242e142e73278c9499dc70 static/scripts/mvc/library/library-librarylist-view.js
--- a/static/scripts/mvc/library/library-librarylist-view.js
+++ b/static/scripts/mvc/library/library-librarylist-view.js
@@ -27,7 +27,6 @@
// map of library model ids to library views = cache
rowViews: {},
- // initialize
initialize : function(options){
this.options = _.defaults(this.options || {}, options);
var viewContext = this;
@@ -37,18 +36,18 @@
this.collection = new mod_library_model.Libraries();
this.collection.fetch({
- success: function(libraries){
+ success: function(){
viewContext.render();
},
- error: function(model, response){
+ error: function(){
mod_toastr.error('An error occured. Please try again.');
}
});
},
/** Renders the libraries table either from the object's own collection,
- or from a given array of library models,
- or renders an empty list in case no data is given. */
+ * or from a given array of library models,
+ * or renders an empty list in case no data is given. */
render: function (options) {
var template = this.templateLibraryList();
var libraries_to_render = null;
@@ -60,6 +59,7 @@
}
if (this.collection !== null && models === null){
+ this.sortLibraries();
if (include_deleted){ // show all the libraries
libraries_to_render = this.collection.models;
} else{ // show only undeleted libraries
@@ -82,6 +82,7 @@
$("#center").css('overflow','auto');
},
+ /** Render all given models as rows in the library list */
renderRows: function(libraries_to_render){
for (var i = 0; i < libraries_to_render.length; i++) {
var library = libraries_to_render[i];
@@ -98,12 +99,11 @@
}
},
+ /** Table heading was clicked, update sorting preferences and re-render */
sort_clicked : function(){
if (Galaxy.libraries.preferences.get('sort_order') === 'asc'){
- this.sortLibraries('name','desc');
Galaxy.libraries.preferences.set({'sort_order': 'desc'});
} else {
- this.sortLibraries('name','asc');
Galaxy.libraries.preferences.set({'sort_order': 'asc'});
}
this.render();
@@ -111,11 +111,11 @@
/** Sorts the underlying collection according to the parameters received.
Currently supports only sorting by name. */
- sortLibraries: function(sort_by, order){
- if (sort_by === 'name'){
- if (order === 'asc'){
+ sortLibraries: function(){
+ if (Galaxy.libraries.preferences.get('sort_by') === 'name'){
+ if (Galaxy.libraries.preferences.get('sort_order') === 'asc'){
this.collection.sortByNameAsc();
- } else if (order === 'desc'){
+ } else if (Galaxy.libraries.preferences.get('sort_order') === 'desc'){
this.collection.sortByNameDesc();
}
}
@@ -220,7 +220,7 @@
$("input[name='Synopsis']").val('');
},
- // serialize data from the form
+ // serialize data from the new library form
serialize_new_library : function(){
return {
name: $("input[name='Name']").val(),
diff -r 51643642564f214f09c2eff32307360f5e09dfaf -r 776e13962bbc861a94242e142e73278c9499dc70 static/scripts/mvc/library/library-libraryrow-view.js
--- a/static/scripts/mvc/library/library-libraryrow-view.js
+++ b/static/scripts/mvc/library/library-libraryrow-view.js
@@ -2,12 +2,10 @@
define([
"galaxy.masthead",
"utils/utils",
- "libs/toastr",
- "mvc/library/library-model"],
+ "libs/toastr"],
function(mod_masthead,
mod_utils,
- mod_toastr,
- mod_library_model) {
+ mod_toastr) {
// galaxy library row view
var LibraryRowView = Backbone.View.extend({
@@ -161,7 +159,7 @@
row_view.repaint(library);
mod_toastr.success('Changes to library saved');
},
- error: function(model, response){
+ error: function(){
mod_toastr.error('An error occured during updating the library :(');
}
});
@@ -237,7 +235,7 @@
tmpl_array.push(' <% } else if(library.get("public") === true) { %>');
tmpl_array.push(' <span data-toggle="tooltip" data-placement="top" title="Public" style="color:grey;" class="fa fa-globe fa-lg public_lib_ico"></span>');
tmpl_array.push(' <% }%>');
- tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Upload to library" class="primary-button btn-xs upload_library_btn" type="button" style="<% if(button_config.upload_library_btn === false) { print("display:none;") } %>"><span class="fa fa-upload"></span></button>');
+ // tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Upload to library" class="primary-button btn-xs upload_library_btn" type="button" style="<% if(button_config.upload_library_btn === false) { print("display:none;") } %>"><span class="fa fa-upload"></span></button>');
tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Modify library" class="primary-button btn-xs edit_library_btn" type="button" style="<% if(button_config.edit_library_btn === false) { print("display:none;") } %>"><span class="fa fa-pencil"></span></button>');
tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Modify permissions" class="primary-button btn-xs permission_library_btn" type="button" style="<% if(button_config.permission_library_btn === false) { print("display:none;") } %>"><span class="fa fa-group"></span></button>');
tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Save changes" class="primary-button btn-xs save_library_btn" type="button" style="<% if(button_config.save_library_btn === false) { print("display:none;") } %>"><span class="fa fa-floppy-o"> Save</span></button>');
diff -r 51643642564f214f09c2eff32307360f5e09dfaf -r 776e13962bbc861a94242e142e73278c9499dc70 static/scripts/mvc/library/library-librarytoolbar-view.js
--- a/static/scripts/mvc/library/library-librarytoolbar-view.js
+++ b/static/scripts/mvc/library/library-librarytoolbar-view.js
@@ -1,12 +1,5 @@
-define([
- "galaxy.masthead",
- "utils/utils",
- "libs/toastr",
- "mvc/library/library-model"],
-function(mod_masthead,
- mod_utils,
- mod_toastr,
- mod_library_model) {
+define([],
+function() {
var LibraryToolbarView = Backbone.View.extend({
el: '#center',
diff -r 51643642564f214f09c2eff32307360f5e09dfaf -r 776e13962bbc861a94242e142e73278c9499dc70 static/scripts/mvc/library/library-model.js
--- a/static/scripts/mvc/library/library-model.js
+++ b/static/scripts/mvc/library/library-model.js
@@ -11,7 +11,7 @@
*/
isVisible : function(show_deleted){
var isVisible = true;
- if( (!show_delete) && (this.get('deleted')) ){
+ if( (!show_deleted) && (this.get('deleted')) ){
isVisible = false;
}
return isVisible;
diff -r 51643642564f214f09c2eff32307360f5e09dfaf -r 776e13962bbc861a94242e142e73278c9499dc70 static/scripts/packed/mvc/library/library-folderlist-view.js
--- a/static/scripts/packed/mvc/library/library-folderlist-view.js
+++ b/static/scripts/packed/mvc/library/library-folderlist-view.js
@@ -1,1 +1,1 @@
-define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model","mvc/library/library-folderrow-view"],function(c,e,f,d,a){var b=Backbone.View.extend({el:"#folder_items_element",progress:0,progressStep:1,modal:null,folderContainer:null,sort:"asc",events:{"click #select-all-checkboxes":"selectAll","click .dataset_row":"selectClickedRow","click .sort-folder-link":"sort_clicked"},initialize:function(g){var h=this;this.options=_.defaults(this.options||{},g);this.queue=jQuery.Deferred();this.queue.resolve();this.collection=new d.Folder();this.listenTo(this.collection,"add",this.addOne);this.folderContainer=new d.FolderContainer({id:this.options.id});this.folderContainer.url=this.folderContainer.attributes.urlRoot+this.options.id+"/contents";this.folderContainer.fetch({success:function(i){h.render();var j=i.get("folder").models;h.addAll(j)},error:function(){f.error("An error occured :(")}})},render:function(g){this.options=_.defaults(this.options||{},g);var h=this.templateFolder();var i=false;var j=this.folderContainer.attributes.metadata.full_path;var k;if(j.length===1){k=0}else{k=j[j.length-2][0]}this.$el.html(h({path:this.folderContainer.attributes.metadata.full_path,id:this.options.id,upper_folder_id:k,order:this.sort}));if(this.collection.models.length>0){this.renderRows()}var g=this.folderContainer.attributes.metadata;g.contains_file=this.options.contains_file;Galaxy.libraries.folderToolbarView.configureElements(g);$("#center [data-toggle]").tooltip();$("#center").css("overflow","auto")},renderRows:function(){for(var j=0;j<this.collection.models.length;j++){var h=this.collection.models[j];var g=new a.FolderRowView(h);this.$el.find("#folder_list_body").append(g.el)}},addAll:function(g){_.each(g.reverse(),function(h){Galaxy.libraries.folderListView.collection.add(h)})},addOne:function(h){if(h.get("data_type")!=="folder"){this.options.contains_file=true;h.set("readable_size",this.size_to_string(h.get("file_size")))}var g=new a.FolderRowView(h);this.$el.find("#first_folder_item").after(g.el)},sort_clicked:function(g){g.preventDefault();if(this.sort==="asc"){this.sortFolder("name","desc");this.sort="desc"}else{this.sortFolder("name","asc");this.sort="asc"}this.render()},sortFolder:function(h,g){if(h==="name"){if(g==="asc"){this.collection.sortByNameAsc()}else{if(g==="desc"){this.collection.sortByNameDesc()}}}},size_to_string:function(g){var h="";if(g>=100000000000){g=g/100000000000;h="TB"}else{if(g>=100000000){g=g/100000000;h="GB"}else{if(g>=100000){g=g/100000;h="MB"}else{if(g>=100){g=g/100;h="KB"}else{g=g*10;h="b"}}}}return(Math.round(g)/10)+h},selectAll:function(h){var g=h.target.checked;that=this;$(":checkbox").each(function(){this.checked=g;$row=$(this.parentElement.parentElement);(g)?that.makeDarkRow($row):that.makeWhiteRow($row)})},selectClickedRow:function(h){var j="";var g;var i;if(h.target.localName==="input"){j=h.target;g=$(h.target.parentElement.parentElement);i="input"}else{if(h.target.localName==="td"){j=$("#"+h.target.parentElement.id).find(":checkbox")[0];g=$(h.target.parentElement);i="td"}}if(j.checked){if(i==="td"){j.checked="";this.makeWhiteRow(g)}else{if(i==="input"){this.makeDarkRow(g)}}}else{if(i==="td"){j.checked="selected";this.makeDarkRow(g)}else{if(i==="input"){this.makeWhiteRow(g)}}}},makeDarkRow:function(g){g.removeClass("light");g.find("a").removeClass("light");g.addClass("dark");g.find("a").addClass("dark");g.find("span").removeClass("fa-file-o");g.find("span").addClass("fa-file")},makeWhiteRow:function(g){g.removeClass("dark");g.find("a").removeClass("dark");g.addClass("light");g.find("a").addClass("light");g.find("span").addClass("fa-file-o");g.find("span").removeClass("fa-file")},templateFolder:function(){var g=[];g.push('<ol class="breadcrumb">');g.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');g.push(" <% _.each(path, function(path_item) { %>");g.push(" <% if (path_item[0] != id) { %>");g.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');g.push("<% } else { %>");g.push(' <li class="active"><span title="You are in this folder"><%- path_item[1] %></span></li>');g.push(" <% } %>");g.push(" <% }); %>");g.push("</ol>");g.push('<table id="folder_table" class="grid table table-condensed">');g.push(" <thead>");g.push(' <th class="button_heading"></th>');g.push(' <th style="text-align: center; width: 20px; "><input id="select-all-checkboxes" style="margin: 0;" type="checkbox"></th>');g.push(' <th><a class="sort-folder-link" title="Click to reverse order" href="#">name</a><span title="Sorted alphabetically" class="fa fa-sort-alpha-<%- order %>"></span></th>');g.push(" <th>data type</th>");g.push(" <th>size</th>");g.push(" <th>time updated (UTC)</th>");g.push(" </thead>");g.push(' <tbody id="folder_list_body">');g.push(' <tr id="first_folder_item">');g.push(' <td><a href="#<% if (upper_folder_id !== 0){ print("folders/" + upper_folder_id)} %>" title="Go to parent folder" class="btn_open_folder btn btn-default btn-xs">..<a></td>');g.push(" <td></td>");g.push(" <td></td>");g.push(" <td></td>");g.push(" <td></td>");g.push(" <td></td>");g.push(" </tr>");g.push(" </tbody>");g.push("</table>");return _.template(g.join(""))}});return{FolderListView:b}});
\ No newline at end of file
+define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model","mvc/library/library-folderrow-view"],function(c,e,f,d,a){var b=Backbone.View.extend({el:"#folder_items_element",progress:0,progressStep:1,modal:null,folderContainer:null,sort:"asc",events:{"click #select-all-checkboxes":"selectAll","click .dataset_row":"selectClickedRow","click .sort-folder-link":"sort_clicked"},initialize:function(g){var h=this;this.options=_.defaults(this.options||{},g);this.collection=new d.Folder();this.listenTo(this.collection,"add",this.addOne);this.folderContainer=new d.FolderContainer({id:this.options.id});this.folderContainer.url=this.folderContainer.attributes.urlRoot+this.options.id+"/contents";this.folderContainer.fetch({success:function(i){h.render();var j=i.get("folder").models;h.addAll(j)},error:function(j,i){if(typeof i.responseJSON!=="undefined"){f.error(i.responseJSON.err_msg)}else{f.error("An error ocurred :(")}}})},render:function(g){this.options=_.defaults(this.options||{},g);var i=this.templateFolder();var j=this.folderContainer.attributes.metadata.full_path;var k;if(j.length===1){k=0}else{k=j[j.length-2][0]}this.$el.html(i({path:this.folderContainer.attributes.metadata.full_path,id:this.options.id,upper_folder_id:k,order:this.sort}));var h=this.folderContainer.attributes.metadata;h.contains_file=this.options.contains_file;Galaxy.libraries.folderToolbarView.configureElements(h);$("#center [data-toggle]").tooltip();$("#center").css("overflow","auto")},addAll:function(g){_.each(g.reverse(),function(h){Galaxy.libraries.folderListView.collection.add(h)});this.checkEmptiness()},addOne:function(h){if(h.get("data_type")!=="folder"){this.options.contains_file=true;h.set("readable_size",this.size_to_string(h.get("file_size")))}var g=new a.FolderRowView(h);this.$el.find("#first_folder_item").after(g.el);this.checkEmptiness()},checkEmptiness:function(){if((this.$el.find(".dataset_row").length===0)&&(this.$el.find(".folder_row").length===0)){var g=this.templateEmptyFolder();this.$el.find("#folder_list_body").append(g())}else{this.$el.find("#empty_folder_message").remove()}},sort_clicked:function(g){g.preventDefault();if(this.sort==="asc"){this.sortFolder("name","desc");this.sort="desc"}else{this.sortFolder("name","asc");this.sort="asc"}this.render()},sortFolder:function(h,g){if(h==="name"){if(g==="asc"){this.collection.sortByNameAsc()}else{if(g==="desc"){this.collection.sortByNameDesc()}}}},size_to_string:function(g){var h="";if(g>=100000000000){g=g/100000000000;h="TB"}else{if(g>=100000000){g=g/100000000;h="GB"}else{if(g>=100000){g=g/100000;h="MB"}else{if(g>=100){g=g/100;h="KB"}else{g=g*10;h="b"}}}}return(Math.round(g)/10)+h},selectAll:function(h){var g=h.target.checked;that=this;$(":checkbox").each(function(){this.checked=g;$row=$(this.parentElement.parentElement);if(g){that.makeDarkRow($row)}else{that.makeWhiteRow($row)}})},selectClickedRow:function(h){var j="";var g;var i;if(h.target.localName==="input"){j=h.target;g=$(h.target.parentElement.parentElement);i="input"}else{if(h.target.localName==="td"){j=$("#"+h.target.parentElement.id).find(":checkbox")[0];g=$(h.target.parentElement);i="td"}}if(j.checked){if(i==="td"){j.checked="";this.makeWhiteRow(g)}else{if(i==="input"){this.makeDarkRow(g)}}}else{if(i==="td"){j.checked="selected";this.makeDarkRow(g)}else{if(i==="input"){this.makeWhiteRow(g)}}}},makeDarkRow:function(g){g.removeClass("light");g.find("a").removeClass("light");g.addClass("dark");g.find("a").addClass("dark");g.find("span").removeClass("fa-file-o");g.find("span").addClass("fa-file")},makeWhiteRow:function(g){g.removeClass("dark");g.find("a").removeClass("dark");g.addClass("light");g.find("a").addClass("light");g.find("span").addClass("fa-file-o");g.find("span").removeClass("fa-file")},templateFolder:function(){var g=[];g.push('<ol class="breadcrumb">');g.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');g.push(" <% _.each(path, function(path_item) { %>");g.push(" <% if (path_item[0] != id) { %>");g.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');g.push("<% } else { %>");g.push(' <li class="active"><span title="You are in this folder"><%- path_item[1] %></span></li>');g.push(" <% } %>");g.push(" <% }); %>");g.push("</ol>");g.push('<table id="folder_table" class="grid table table-condensed">');g.push(" <thead>");g.push(' <th class="button_heading"></th>');g.push(' <th style="text-align: center; width: 20px; " title="Check to select all datasets"><input id="select-all-checkboxes" style="margin: 0;" type="checkbox"></th>');g.push(' <th><a class="sort-folder-link" title="Click to reverse order" href="#">name</a><span title="Sorted alphabetically" class="fa fa-sort-alpha-<%- order %>"></span></th>');g.push(" <th>data type</th>");g.push(" <th>size</th>");g.push(" <th>time updated (UTC)</th>");g.push(" </thead>");g.push(' <tbody id="folder_list_body">');g.push(' <tr id="first_folder_item">');g.push(' <td><a href="#<% if (upper_folder_id !== 0){ print("folders/" + upper_folder_id)} %>" title="Go to parent folder" class="btn_open_folder btn btn-default btn-xs">..<a></td>');g.push(" <td></td>");g.push(" <td></td>");g.push(" <td></td>");g.push(" <td></td>");g.push(" <td></td>");g.push(" </tr>");g.push(" </tbody>");g.push("</table>");return _.template(g.join(""))},templateEmptyFolder:function(){var g=[];g.push('<tr id="empty_folder_message">');g.push('<td colspan="6" style="text-align:center">');g.push("This folder is either empty or you do not have proper access permissions to see the contents.");g.push("</td>");g.push("</tr>");return _.template(g.join(""))}});return{FolderListView:b}});
\ No newline at end of file
diff -r 51643642564f214f09c2eff32307360f5e09dfaf -r 776e13962bbc861a94242e142e73278c9499dc70 static/scripts/packed/mvc/library/library-foldertoolbar-view.js
--- a/static/scripts/packed/mvc/library/library-foldertoolbar-view.js
+++ b/static/scripts/packed/mvc/library/library-foldertoolbar-view.js
@@ -1,1 +1,1 @@
-define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model"],function(b,d,e,c){var a=Backbone.View.extend({el:"#center",events:{"click #toolbtn_create_folder":"createFolderFromModal","click #toolbtn_bulk_import":"modalBulkImport","click .toolbtn_add_files":"addFilesToFolderModal"},defaults:{can_add_library_item:false,contains_file:false,chain_call_control:{total_number:0,failed_number:0}},modal:null,histories:null,initialize:function(f){this.options=_.defaults(f||{},this.defaults);this.render()},render:function(f){this.options=_.extend(this.options,f);var h=this.templateToolBar();var g=false;if(Galaxy.currUser){g=Galaxy.currUser.isAdmin()}this.$el.html(h({id:this.options.id,admin_user:g}))},configureElements:function(f){this.options=_.extend(this.options,f);if(this.options.can_add_library_item===true){$("#toolbtn_create_folder").show();$(".toolbtn_add_files").show()}if(this.options.contains_file===true){$("#toolbtn_bulk_import").show();$("#toolbtn_dl").show()}this.$el.find("[data-toggle]").tooltip()},createFolderFromModal:function(){event.preventDefault();event.stopPropagation();var f=this;var g=this.templateNewFolderInModal();this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Create New Folder",body:g(),buttons:{Create:function(){f.create_new_folder_event()},Close:function(){Galaxy.modal.hide()}}})},create_new_folder_event:function(){var f=this.serialize_new_folder();if(this.validate_new_folder(f)){var g=new c.FolderAsModel();url_items=Backbone.history.fragment.split("/");current_folder_id=url_items[url_items.length-1];g.url=g.urlRoot+"/"+current_folder_id;g.save(f,{success:function(h){Galaxy.modal.hide();e.success("Folder created");h.set({type:"folder"});Galaxy.libraries.folderListView.collection.add(h)},error:function(i,h){Galaxy.modal.hide();if(typeof h.responseJSON!=="undefined"){e.error(h.responseJSON.err_msg)}else{e.error("An error ocurred :(")}}})}else{e.error("Folder's name is missing")}return false},serialize_new_folder:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val()}},validate_new_folder:function(f){return f.name!==""},modalBulkImport:function(){var f=$("#folder_table").find(":checked");if(f.length===0){e.info("You have to select some datasets first")}else{this.refreshUserHistoriesList(function(g){var h=g.templateBulkImportInModal();g.modal=Galaxy.modal;g.modal.show({closing_events:true,title:"Import into History",body:h({histories:g.histories.models}),buttons:{Import:function(){g.importAllIntoHistory()},Close:function(){Galaxy.modal.hide()}}})})}},refreshUserHistoriesList:function(g){var f=this;this.histories=new c.GalaxyHistories();this.histories.fetch({success:function(){g(f)},error:function(i,h){if(typeof h.responseJSON!=="undefined"){e.error(h.responseJSON.err_msg)}else{e.error("An error ocurred :(")}}})},importAllIntoHistory:function(){this.modal.disableButton("Import");this.options.chain_call_control.total_number=0;this.options.chain_call_control.failed_number=0;var j=$("select[name=dataset_import_bulk] option:selected").val();this.options.last_used_history_id=j;var m=$("select[name=dataset_import_bulk] option:selected").text();var o=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!==""){o.push(this.parentElement.parentElement.id)}});var n=this.templateImportIntoHistoryProgressBar();this.modal.$el.find(".modal-body").html(n({history_name:m}));var k=100/o.length;this.initProgress(k);var f=[];for(var g=o.length-1;g>=0;g--){var h=o[g];var l=new c.HistoryItem();l.url=l.urlRoot+j+"/contents";l.content=h;l.source="library";f.push(l)}this.options.chain_call_control.total_number=f.length;this.chainCall(f,m)},chainCall:function(g,j){var f=this;var h=g.pop();if(typeof h==="undefined"){if(this.options.chain_call_control.failed_number===0){e.success("Selected datasets imported into history")}else{if(this.options.chain_call_control.failed_number===this.options.chain_call_control.total_number){e.error("There was an error and no datasets were imported into history.")}else{if(this.options.chain_call_control.failed_number<this.options.chain_call_control.total_number){e.warning("Some of the datasets could not be imported into history")}}}Galaxy.modal.hide();return}var i=$.when(h.save({content:h.content,source:h.source}));i.done(function(k){f.updateProgress();f.chainCall(g,j)}).fail(function(k){f.options.chain_call_control.failed_number+=1;f.updateProgress();f.chainCall(g,j)})},initProgress:function(f){this.progress=0;this.progressStep=f},updateProgress:function(){this.progress+=this.progressStep;$(".progress-bar-import").width(Math.round(this.progress)+"%");txt_representation=Math.round(this.progress)+"% Complete";$(".completion_span").text(txt_representation)},download:function(f,j){var h=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!==""){h.push(this.parentElement.parentElement.id)}});var g="/api/libraries/datasets/download/"+j;var i={ldda_ids:h};this.processDownload(g,i,"get")},processDownload:function(g,h,i){if(g&&h){h=typeof h==="string"?h:$.param(h);var f="";$.each(h.split("&"),function(){var j=this.split("=");f+='<input type="hidden" name="'+j[0]+'" value="'+j[1]+'" />'});$('<form action="'+g+'" method="'+(i||"post")+'">'+f+"</form>").appendTo("body").submit().remove();e.info("Your download will begin soon")}},addFilesToFolderModal:function(){this.refreshUserHistoriesList(function(f){f.modal=Galaxy.modal;var g=f.templateAddFilesInModal();f.modal.show({closing_events:true,title:"Add datasets from history to "+f.options.folder_name,body:g({histories:f.histories.models}),buttons:{Add:function(){f.addAllDatasetsFromHistory()},Close:function(){Galaxy.modal.hide()}}});if(f.histories.models.length>0){f.fetchAndDisplayHistoryContents(f.histories.models[0].id);$("#dataset_add_bulk").change(function(h){f.fetchAndDisplayHistoryContents(h.target.value)})}else{e.error("An error ocurred :(")}})},fetchAndDisplayHistoryContents:function(h){var g=new c.HistoryContents({id:h});var f=this;g.fetch({success:function(j){var i=f.templateHistoryContents();f.histories.get(h).set({contents:j});f.modal.$el.find("#selected_history_content").html(i({history_contents:j.models.reverse()}))},error:function(j,i){e.error("An error ocurred :(")}})},addAllDatasetsFromHistory:function(){this.modal.disableButton("Add");this.options.chain_call_control.total_number=0;this.options.chain_call_control.failed_number=0;var f=[];this.modal.$el.find("#selected_history_content").find(":checked").each(function(){var i=$(this.parentElement).data("id");if(i){f.push(i)}});var l=this.options.folder_name;var k=this.templateAddingDatasetsProgressBar();this.modal.$el.find(".modal-body").html(k({folder_name:l}));this.progressStep=100/f.length;this.progress=0;var j=[];for(var h=f.length-1;h>=0;h--){history_dataset_id=f[h];var g=new c.Item();g.url="/api/folders/"+this.options.id+"/contents";g.set({from_hda_id:history_dataset_id});j.push(g)}this.options.chain_call_control.total_number=j.length;this.chainCallAddingHdas(j)},chainCallAddingHdas:function(g){var f=this;this.added_hdas=new c.Folder();var h=g.pop();if(typeof h==="undefined"){if(this.options.chain_call_control.failed_number===0){e.success("Selected datasets from history added to the folder")}else{if(this.options.chain_call_control.failed_number===this.options.chain_call_control.total_number){e.error("There was an error and no datasets were added to the folder.")}else{if(this.options.chain_call_control.failed_number<this.options.chain_call_control.total_number){e.warning("Some of the datasets could not be added to the folder")}}}Galaxy.modal.hide();return this.added_hdas}var i=$.when(h.save({from_hda_id:h.get("from_hda_id")}));i.done(function(j){Galaxy.libraries.folderListView.collection.add(j);f.updateProgress();f.chainCallAddingHdas(g)}).fail(function(j){f.options.chain_call_control.failed_number+=1;f.updateProgress();f.chainCallAddingHdas(g)})},templateToolBar:function(){tmpl_array=[];tmpl_array.push('<div class="library_style_container">');tmpl_array.push('<h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');tmpl_array.push('<div id="library_folder_toolbar" >');tmpl_array.push('<div class="btn-group">');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Create New Folder" id="toolbtn_create_folder" class="btn btn-default primary-button" type="button" style="display:none;"><span class="fa fa-plus"></span><span class="fa fa-folder"></span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Add Datasets to Current Folder" id="toolbtn_add_files" class="btn btn-default toolbtn_add_files primary-button" type="button" style="display:none;"><span class="fa fa-plus"></span><span class="fa fa-file"></span></span></button>');tmpl_array.push("</div>");tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Import selected datasets into history" id="toolbtn_bulk_import" class="primary-button" style="margin-left: 0.5em; " type="button"><span class="fa fa-book"></span> to history</button>');tmpl_array.push(' <div id="toolbtn_dl" class="btn-group" style="margin-left: 0.5em; ">');tmpl_array.push(' <button title="Download selected datasets" id="drop_toggle" type="button" class="primary-button dropdown-toggle" data-toggle="dropdown">');tmpl_array.push(' <span class="fa fa-download"></span> download <span class="caret"></span>');tmpl_array.push(" </button>");tmpl_array.push(' <ul class="dropdown-menu" role="menu">');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/tgz">.tar.gz</a></li>');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/tbz">.tar.bz</a></li>');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/zip">.zip</a></li>');tmpl_array.push(" </ul>");tmpl_array.push(" </div>");tmpl_array.push(" </div>");tmpl_array.push(' <div id="folder_items_element">');tmpl_array.push(" </div>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateNewFolderInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_folder_modal">');tmpl_array.push("<form>");tmpl_array.push('<input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push('<input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push("</form>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateBulkImportInModal:function(){var f=[];f.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');f.push("Select history: ");f.push('<select id="dataset_import_bulk" name="dataset_import_bulk" style="width:50%; margin-bottom: 1em; "> ');f.push(" <% _.each(histories, function(history) { %>");f.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');f.push(" <% }); %>");f.push("</select>");f.push("</span>");return _.template(f.join(""))},templateImportIntoHistoryProgressBar:function(){var f=[];f.push('<div class="import_text">');f.push("Importing selected datasets to history <b><%= _.escape(history_name) %></b>");f.push("</div>");f.push('<div class="progress">');f.push(' <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');f.push(' <span class="completion_span">0% Complete</span>');f.push(" </div>");f.push("</div>");f.push("");return _.template(f.join(""))},templateAddingDatasetsProgressBar:function(){var f=[];f.push('<div class="import_text">');f.push("Adding selected datasets from history to library folder <b><%= _.escape(folder_name) %></b>");f.push("</div>");f.push('<div class="progress">');f.push(' <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');f.push(' <span class="completion_span">0% Complete</span>');f.push(" </div>");f.push("</div>");f.push("");return _.template(f.join(""))},templateAddFilesInModal:function(){var f=[];f.push('<div id="add_files_modal">');f.push('<div id="history_modal_combo_bulk">');f.push("Select history: ");f.push('<select id="dataset_add_bulk" name="dataset_add_bulk" style="width:66%; "> ');f.push(" <% _.each(histories, function(history) { %>");f.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');f.push(" <% }); %>");f.push("</select>");f.push("</div>");f.push('<div id="selected_history_content">');f.push("</div>");f.push("</div>");return _.template(f.join(""))},templateHistoryContents:function(){var f=[];f.push("Choose the datasets to import:");f.push("<ul>");f.push(" <% _.each(history_contents, function(history_item) { %>");f.push(' <li data-id="<%= _.escape(history_item.get("id")) %>">');f.push(' <input style="margin: 0;" type="checkbox"><%= _.escape(history_item.get("hid")) %>: <%= _.escape(history_item.get("name")) %>');f.push(" </li>");f.push(" <% }); %>");f.push("</ul>");return _.template(f.join(""))}});return{FolderToolbarView:a}});
\ No newline at end of file
+define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model"],function(b,d,e,c){var a=Backbone.View.extend({el:"#center",events:{"click #toolbtn_create_folder":"createFolderFromModal","click #toolbtn_bulk_import":"modalBulkImport","click .toolbtn_add_files":"addFilesToFolderModal"},defaults:{can_add_library_item:false,contains_file:false,chain_call_control:{total_number:0,failed_number:0}},modal:null,histories:null,initialize:function(f){this.options=_.defaults(f||{},this.defaults);this.render()},render:function(f){this.options=_.extend(this.options,f);var h=this.templateToolBar();var g=false;if(Galaxy.currUser){g=Galaxy.currUser.isAdmin()}this.$el.html(h({id:this.options.id,admin_user:g}))},configureElements:function(f){this.options=_.extend(this.options,f);if(this.options.can_add_library_item===true){$("#toolbtn_create_folder").show();$(".toolbtn_add_files").show()}if(this.options.contains_file===true){$("#toolbtn_bulk_import").show();$("#toolbtn_dl").show()}this.$el.find("[data-toggle]").tooltip()},createFolderFromModal:function(){event.preventDefault();event.stopPropagation();var f=this;var g=this.templateNewFolderInModal();this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Create New Folder",body:g(),buttons:{Create:function(){f.create_new_folder_event()},Close:function(){Galaxy.modal.hide()}}})},create_new_folder_event:function(){var f=this.serialize_new_folder();if(this.validate_new_folder(f)){var g=new c.FolderAsModel();url_items=Backbone.history.fragment.split("/");current_folder_id=url_items[url_items.length-1];g.url=g.urlRoot+"/"+current_folder_id;g.save(f,{success:function(h){Galaxy.modal.hide();e.success("Folder created");h.set({type:"folder"});Galaxy.libraries.folderListView.collection.add(h)},error:function(i,h){Galaxy.modal.hide();if(typeof h.responseJSON!=="undefined"){e.error(h.responseJSON.err_msg)}else{e.error("An error ocurred :(")}}})}else{e.error("Folder's name is missing")}return false},serialize_new_folder:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val()}},validate_new_folder:function(f){return f.name!==""},modalBulkImport:function(){var f=$("#folder_table").find(":checked");if(f.length===0){e.info("You have to select some datasets first")}else{this.refreshUserHistoriesList(function(g){var h=g.templateBulkImportInModal();g.modal=Galaxy.modal;g.modal.show({closing_events:true,title:"Import into History",body:h({histories:g.histories.models}),buttons:{Import:function(){g.importAllIntoHistory()},Close:function(){Galaxy.modal.hide()}}})})}},refreshUserHistoriesList:function(g){var f=this;this.histories=new c.GalaxyHistories();this.histories.fetch({success:function(){g(f)},error:function(i,h){if(typeof h.responseJSON!=="undefined"){e.error(h.responseJSON.err_msg)}else{e.error("An error ocurred :(")}}})},importAllIntoHistory:function(){this.modal.disableButton("Import");this.options.chain_call_control.total_number=0;this.options.chain_call_control.failed_number=0;var j=$("select[name=dataset_import_bulk] option:selected").val();this.options.last_used_history_id=j;var m=$("select[name=dataset_import_bulk] option:selected").text();var o=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!==""){o.push(this.parentElement.parentElement.id)}});var n=this.templateImportIntoHistoryProgressBar();this.modal.$el.find(".modal-body").html(n({history_name:m}));var k=100/o.length;this.initProgress(k);var f=[];for(var g=o.length-1;g>=0;g--){var h=o[g];var l=new c.HistoryItem();l.url=l.urlRoot+j+"/contents";l.content=h;l.source="library";f.push(l)}this.options.chain_call_control.total_number=f.length;this.chainCall(f,m)},chainCall:function(g,j){var f=this;var h=g.pop();if(typeof h==="undefined"){if(this.options.chain_call_control.failed_number===0){e.success("Selected datasets imported into history")}else{if(this.options.chain_call_control.failed_number===this.options.chain_call_control.total_number){e.error("There was an error and no datasets were imported into history.")}else{if(this.options.chain_call_control.failed_number<this.options.chain_call_control.total_number){e.warning("Some of the datasets could not be imported into history")}}}Galaxy.modal.hide();return}var i=$.when(h.save({content:h.content,source:h.source}));i.done(function(){f.updateProgress();f.chainCall(g,j)}).fail(function(){f.options.chain_call_control.failed_number+=1;f.updateProgress();f.chainCall(g,j)})},initProgress:function(f){this.progress=0;this.progressStep=f},updateProgress:function(){this.progress+=this.progressStep;$(".progress-bar-import").width(Math.round(this.progress)+"%");txt_representation=Math.round(this.progress)+"% Complete";$(".completion_span").text(txt_representation)},download:function(f,j){var h=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!==""){h.push(this.parentElement.parentElement.id)}});var g="/api/libraries/datasets/download/"+j;var i={ldda_ids:h};this.processDownload(g,i,"get")},processDownload:function(g,h,i){if(g&&h){h=typeof h==="string"?h:$.param(h);var f="";$.each(h.split("&"),function(){var j=this.split("=");f+='<input type="hidden" name="'+j[0]+'" value="'+j[1]+'" />'});$('<form action="'+g+'" method="'+(i||"post")+'">'+f+"</form>").appendTo("body").submit().remove();e.info("Your download will begin soon")}},addFilesToFolderModal:function(){this.refreshUserHistoriesList(function(f){f.modal=Galaxy.modal;var g=f.templateAddFilesInModal();f.modal.show({closing_events:true,title:"Add datasets from history to "+f.options.folder_name,body:g({histories:f.histories.models}),buttons:{Add:function(){f.addAllDatasetsFromHistory()},Close:function(){Galaxy.modal.hide()}}});if(f.histories.models.length>0){f.fetchAndDisplayHistoryContents(f.histories.models[0].id);$("#dataset_add_bulk").change(function(h){f.fetchAndDisplayHistoryContents(h.target.value)})}else{e.error("An error ocurred :(")}})},fetchAndDisplayHistoryContents:function(h){var g=new c.HistoryContents({id:h});var f=this;g.fetch({success:function(j){var i=f.templateHistoryContents();f.histories.get(h).set({contents:j});f.modal.$el.find("#selected_history_content").html(i({history_contents:j.models.reverse()}))},error:function(){e.error("An error ocurred :(")}})},addAllDatasetsFromHistory:function(){this.modal.disableButton("Add");this.options.chain_call_control.total_number=0;this.options.chain_call_control.failed_number=0;var f=[];this.modal.$el.find("#selected_history_content").find(":checked").each(function(){var i=$(this.parentElement).data("id");if(i){f.push(i)}});var l=this.options.folder_name;var k=this.templateAddingDatasetsProgressBar();this.modal.$el.find(".modal-body").html(k({folder_name:l}));this.progressStep=100/f.length;this.progress=0;var j=[];for(var h=f.length-1;h>=0;h--){history_dataset_id=f[h];var g=new c.Item();g.url="/api/folders/"+this.options.id+"/contents";g.set({from_hda_id:history_dataset_id});j.push(g)}this.options.chain_call_control.total_number=j.length;this.chainCallAddingHdas(j)},chainCallAddingHdas:function(g){var f=this;this.added_hdas=new c.Folder();var h=g.pop();if(typeof h==="undefined"){if(this.options.chain_call_control.failed_number===0){e.success("Selected datasets from history added to the folder")}else{if(this.options.chain_call_control.failed_number===this.options.chain_call_control.total_number){e.error("There was an error and no datasets were added to the folder.")}else{if(this.options.chain_call_control.failed_number<this.options.chain_call_control.total_number){e.warning("Some of the datasets could not be added to the folder")}}}Galaxy.modal.hide();return this.added_hdas}var i=$.when(h.save({from_hda_id:h.get("from_hda_id")}));i.done(function(j){Galaxy.libraries.folderListView.collection.add(j);f.updateProgress();f.chainCallAddingHdas(g)}).fail(function(){f.options.chain_call_control.failed_number+=1;f.updateProgress();f.chainCallAddingHdas(g)})},templateToolBar:function(){tmpl_array=[];tmpl_array.push('<div class="library_style_container">');tmpl_array.push('<h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');tmpl_array.push('<div id="library_folder_toolbar" >');tmpl_array.push('<div class="btn-group">');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Create New Folder" id="toolbtn_create_folder" class="btn btn-default primary-button" type="button" style="display:none;"><span class="fa fa-plus"></span><span class="fa fa-folder"></span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Add Datasets to Current Folder" id="toolbtn_add_files" class="btn btn-default toolbtn_add_files primary-button" type="button" style="display:none;"><span class="fa fa-plus"></span><span class="fa fa-file"></span></span></button>');tmpl_array.push("</div>");tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Import selected datasets into history" id="toolbtn_bulk_import" class="primary-button" style="margin-left: 0.5em; " type="button"><span class="fa fa-book"></span> to history</button>');tmpl_array.push(' <div id="toolbtn_dl" class="btn-group" style="margin-left: 0.5em; ">');tmpl_array.push(' <button title="Download selected datasets" id="drop_toggle" type="button" class="primary-button dropdown-toggle" data-toggle="dropdown">');tmpl_array.push(' <span class="fa fa-download"></span> download <span class="caret"></span>');tmpl_array.push(" </button>");tmpl_array.push(' <ul class="dropdown-menu" role="menu">');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/tgz">.tar.gz</a></li>');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/tbz">.tar.bz</a></li>');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/zip">.zip</a></li>');tmpl_array.push(" </ul>");tmpl_array.push(" </div>");tmpl_array.push(" </div>");tmpl_array.push(' <div id="folder_items_element">');tmpl_array.push(" </div>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateNewFolderInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_folder_modal">');tmpl_array.push("<form>");tmpl_array.push('<input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push('<input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push("</form>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateBulkImportInModal:function(){var f=[];f.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');f.push("Select history: ");f.push('<select id="dataset_import_bulk" name="dataset_import_bulk" style="width:50%; margin-bottom: 1em; "> ');f.push(" <% _.each(histories, function(history) { %>");f.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');f.push(" <% }); %>");f.push("</select>");f.push("</span>");return _.template(f.join(""))},templateImportIntoHistoryProgressBar:function(){var f=[];f.push('<div class="import_text">');f.push("Importing selected datasets to history <b><%= _.escape(history_name) %></b>");f.push("</div>");f.push('<div class="progress">');f.push(' <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');f.push(' <span class="completion_span">0% Complete</span>');f.push(" </div>");f.push("</div>");f.push("");return _.template(f.join(""))},templateAddingDatasetsProgressBar:function(){var f=[];f.push('<div class="import_text">');f.push("Adding selected datasets from history to library folder <b><%= _.escape(folder_name) %></b>");f.push("</div>");f.push('<div class="progress">');f.push(' <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');f.push(' <span class="completion_span">0% Complete</span>');f.push(" </div>");f.push("</div>");f.push("");return _.template(f.join(""))},templateAddFilesInModal:function(){var f=[];f.push('<div id="add_files_modal">');f.push('<div id="history_modal_combo_bulk">');f.push("Select history: ");f.push('<select id="dataset_add_bulk" name="dataset_add_bulk" style="width:66%; "> ');f.push(" <% _.each(histories, function(history) { %>");f.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');f.push(" <% }); %>");f.push("</select>");f.push("</div>");f.push('<div id="selected_history_content">');f.push("</div>");f.push("</div>");return _.template(f.join(""))},templateHistoryContents:function(){var f=[];f.push("Choose the datasets to import:");f.push("<ul>");f.push(" <% _.each(history_contents, function(history_item) { %>");f.push(' <li data-id="<%= _.escape(history_item.get("id")) %>">');f.push(' <input style="margin: 0;" type="checkbox"><%= _.escape(history_item.get("hid")) %>: <%= _.escape(history_item.get("name")) %>');f.push(" </li>");f.push(" <% }); %>");f.push("</ul>");return _.template(f.join(""))}});return{FolderToolbarView:a}});
\ No newline at end of file
diff -r 51643642564f214f09c2eff32307360f5e09dfaf -r 776e13962bbc861a94242e142e73278c9499dc70 static/scripts/packed/mvc/library/library-librarylist-view.js
--- a/static/scripts/packed/mvc/library/library-librarylist-view.js
+++ b/static/scripts/packed/mvc/library/library-librarylist-view.js
@@ -1,1 +1,1 @@
-define(["galaxy.masthead","mvc/base-mvc","utils/utils","libs/toastr","mvc/library/library-model","mvc/library/library-libraryrow-view"],function(b,g,d,e,c,a){var f=Backbone.View.extend({el:"#libraries_element",events:{"click .sort-libraries-link":"sort_clicked"},modal:null,collection:null,rowViews:{},initialize:function(i){this.options=_.defaults(this.options||{},i);var h=this;this.rowViews={};this.collection=new c.Libraries();this.collection.fetch({success:function(j){h.render()},error:function(k,j){e.error("An error occured. Please try again.")}})},render:function(i){var j=this.templateLibraryList();var k=null;var h=Galaxy.libraries.preferences.get("with_deleted");var l=null;if(typeof i!=="undefined"){h=typeof i.with_deleted!=="undefined"?i.with_deleted:false;l=typeof i.models!=="undefined"?i.models:null}if(this.collection!==null&&l===null){if(h){k=this.collection.models}else{k=this.collection.where({deleted:false})}}else{if(l!==null){k=l}else{k=[]}}this.$el.html(j({length:k.length,order:Galaxy.libraries.preferences.get("sort_order")}));if(k.length>0){this.renderRows(k)}$("#center [data-toggle]").tooltip();$("#center").css("overflow","auto")},renderRows:function(m){for(var l=0;l<m.length;l++){var k=m[l];var j=_.findWhere(this.rowViews,{id:k.get("id")});if(j!==undefined&&this instanceof Backbone.View){j.delegateEvents();this.$el.find("#library_list_body").append(j.el)}else{var h=new a.LibraryRowView(k);this.$el.find("#library_list_body").append(h.el);this.rowViews[k.get("id")]=h}}},sort_clicked:function(){if(Galaxy.libraries.preferences.get("sort_order")==="asc"){this.sortLibraries("name","desc");Galaxy.libraries.preferences.set({sort_order:"desc"})}else{this.sortLibraries("name","asc");Galaxy.libraries.preferences.set({sort_order:"asc"})}this.render()},sortLibraries:function(i,h){if(i==="name"){if(h==="asc"){this.collection.sortByNameAsc()}else{if(h==="desc"){this.collection.sortByNameDesc()}}}},templateLibraryList:function(){tmpl_array=[];tmpl_array.push('<div class="library_container table-responsive">');tmpl_array.push("<% if(length === 0) { %>");tmpl_array.push('<div>There are no libraries visible to you. If you expected some to show up please consult the <a href="https://wiki.galaxyproject.org/Admin/DataLibraries/LibrarySecurity">library security wikipage</a>.</div>');tmpl_array.push("<% } else{ %>");tmpl_array.push('<table class="grid table table-condensed">');tmpl_array.push(" <thead>");tmpl_array.push(' <th style="width:30%;"><a class="sort-libraries-link" title="Click to reverse order" href="#">name</a><span title="Sorted alphabetically" class="fa fa-sort-alpha-<%- order %>"></span></th>');tmpl_array.push(' <th style="width:22%;">description</th>');tmpl_array.push(' <th style="width:22%;">synopsis</th> ');tmpl_array.push(' <th style="width:26%;"></th> ');tmpl_array.push(" </thead>");tmpl_array.push(' <tbody id="library_list_body">');tmpl_array.push(" </tbody>");tmpl_array.push("</table>");tmpl_array.push("<% }%>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateNewLibraryInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_library_modal">');tmpl_array.push(" <form>");tmpl_array.push(' <input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push(' <input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push(' <input type="text" name="Synopsis" value="" placeholder="Synopsis">');tmpl_array.push(" </form>");tmpl_array.push("</div>");return tmpl_array.join("")},redirectToHome:function(){window.location="../"},redirectToLogin:function(){window.location="/user/login"},show_library_modal:function(i){i.preventDefault();i.stopPropagation();var h=this;this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Create New Library",body:this.templateNewLibraryInModal(),buttons:{Create:function(){h.create_new_library_event()},Close:function(){h.modal.hide()}}})},create_new_library_event:function(){var j=this.serialize_new_library();if(this.validate_new_library(j)){var i=new c.Library();var h=this;i.save(j,{success:function(k){h.collection.add(k);h.modal.hide();h.clear_library_modal();h.render();e.success("Library created")},error:function(){e.error("An error occured :(")}})}else{e.error("Library's name is missing")}return false},clear_library_modal:function(){$("input[name='Name']").val("");$("input[name='Description']").val("");$("input[name='Synopsis']").val("")},serialize_new_library:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val(),synopsis:$("input[name='Synopsis']").val()}},validate_new_library:function(h){return h.name!==""}});return{LibraryListView:f}});
\ No newline at end of file
+define(["galaxy.masthead","mvc/base-mvc","utils/utils","libs/toastr","mvc/library/library-model","mvc/library/library-libraryrow-view"],function(b,g,d,e,c,a){var f=Backbone.View.extend({el:"#libraries_element",events:{"click .sort-libraries-link":"sort_clicked"},modal:null,collection:null,rowViews:{},initialize:function(i){this.options=_.defaults(this.options||{},i);var h=this;this.rowViews={};this.collection=new c.Libraries();this.collection.fetch({success:function(){h.render()},error:function(){e.error("An error occured. Please try again.")}})},render:function(i){var j=this.templateLibraryList();var k=null;var h=Galaxy.libraries.preferences.get("with_deleted");var l=null;if(typeof i!=="undefined"){h=typeof i.with_deleted!=="undefined"?i.with_deleted:false;l=typeof i.models!=="undefined"?i.models:null}if(this.collection!==null&&l===null){this.sortLibraries();if(h){k=this.collection.models}else{k=this.collection.where({deleted:false})}}else{if(l!==null){k=l}else{k=[]}}this.$el.html(j({length:k.length,order:Galaxy.libraries.preferences.get("sort_order")}));if(k.length>0){this.renderRows(k)}$("#center [data-toggle]").tooltip();$("#center").css("overflow","auto")},renderRows:function(m){for(var l=0;l<m.length;l++){var k=m[l];var j=_.findWhere(this.rowViews,{id:k.get("id")});if(j!==undefined&&this instanceof Backbone.View){j.delegateEvents();this.$el.find("#library_list_body").append(j.el)}else{var h=new a.LibraryRowView(k);this.$el.find("#library_list_body").append(h.el);this.rowViews[k.get("id")]=h}}},sort_clicked:function(){if(Galaxy.libraries.preferences.get("sort_order")==="asc"){Galaxy.libraries.preferences.set({sort_order:"desc"})}else{Galaxy.libraries.preferences.set({sort_order:"asc"})}this.render()},sortLibraries:function(){if(Galaxy.libraries.preferences.get("sort_by")==="name"){if(Galaxy.libraries.preferences.get("sort_order")==="asc"){this.collection.sortByNameAsc()}else{if(Galaxy.libraries.preferences.get("sort_order")==="desc"){this.collection.sortByNameDesc()}}}},templateLibraryList:function(){tmpl_array=[];tmpl_array.push('<div class="library_container table-responsive">');tmpl_array.push("<% if(length === 0) { %>");tmpl_array.push('<div>There are no libraries visible to you. If you expected some to show up please consult the <a href="https://wiki.galaxyproject.org/Admin/DataLibraries/LibrarySecurity">library security wikipage</a>.</div>');tmpl_array.push("<% } else{ %>");tmpl_array.push('<table class="grid table table-condensed">');tmpl_array.push(" <thead>");tmpl_array.push(' <th style="width:30%;"><a class="sort-libraries-link" title="Click to reverse order" href="#">name</a><span title="Sorted alphabetically" class="fa fa-sort-alpha-<%- order %>"></span></th>');tmpl_array.push(' <th style="width:22%;">description</th>');tmpl_array.push(' <th style="width:22%;">synopsis</th> ');tmpl_array.push(' <th style="width:26%;"></th> ');tmpl_array.push(" </thead>");tmpl_array.push(' <tbody id="library_list_body">');tmpl_array.push(" </tbody>");tmpl_array.push("</table>");tmpl_array.push("<% }%>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateNewLibraryInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_library_modal">');tmpl_array.push(" <form>");tmpl_array.push(' <input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push(' <input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push(' <input type="text" name="Synopsis" value="" placeholder="Synopsis">');tmpl_array.push(" </form>");tmpl_array.push("</div>");return tmpl_array.join("")},redirectToHome:function(){window.location="../"},redirectToLogin:function(){window.location="/user/login"},show_library_modal:function(i){i.preventDefault();i.stopPropagation();var h=this;this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Create New Library",body:this.templateNewLibraryInModal(),buttons:{Create:function(){h.create_new_library_event()},Close:function(){h.modal.hide()}}})},create_new_library_event:function(){var j=this.serialize_new_library();if(this.validate_new_library(j)){var i=new c.Library();var h=this;i.save(j,{success:function(k){h.collection.add(k);h.modal.hide();h.clear_library_modal();h.render();e.success("Library created")},error:function(){e.error("An error occured :(")}})}else{e.error("Library's name is missing")}return false},clear_library_modal:function(){$("input[name='Name']").val("");$("input[name='Description']").val("");$("input[name='Synopsis']").val("")},serialize_new_library:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val(),synopsis:$("input[name='Synopsis']").val()}},validate_new_library:function(h){return h.name!==""}});return{LibraryListView:f}});
\ No newline at end of file
diff -r 51643642564f214f09c2eff32307360f5e09dfaf -r 776e13962bbc861a94242e142e73278c9499dc70 static/scripts/packed/mvc/library/library-libraryrow-view.js
--- a/static/scripts/packed/mvc/library/library-libraryrow-view.js
+++ b/static/scripts/packed/mvc/library/library-libraryrow-view.js
@@ -1,1 +1,1 @@
-define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model"],function(b,d,e,c){var a=Backbone.View.extend({events:{"click .edit_library_btn":"edit_button_clicked","click .cancel_library_btn":"cancel_library_modification","click .save_library_btn":"save_library_modification","click .delete_library_btn":"delete_library","click .undelete_library_btn":"undelete_library","click .upload_library_btn":"upload_to_library","click .permission_library_btn":"permissions_on_library"},edit_mode:false,element_visibility_config:{upload_library_btn:false,edit_library_btn:false,permission_library_btn:false,save_library_btn:false,cancel_library_btn:false,delete_library_btn:false,undelete_library_btn:false},initialize:function(f){this.render(f)},render:function(g){if(typeof g==="undefined"){g=Galaxy.libraries.libraryListView.collection.get(this.$el.data("id"))}this.prepareButtons(g);var f=this.templateRow();this.setElement(f({library:g,button_config:this.element_visibility_config,edit_mode:this.edit_mode}));this.$el.show();return this},repaint:function(f){$(".tooltip").hide();var g=this.$el;this.render(f);g.replaceWith(this.$el);this.$el.find("[data-toggle]").tooltip()},prepareButtons:function(f){vis_config=this.element_visibility_config;if(this.edit_mode===false){vis_config.save_library_btn=false;vis_config.cancel_library_btn=false;vis_config.delete_library_btn=false;if(f.get("deleted")===true){vis_config.undelete_library_btn=true;vis_config.upload_library_btn=false;vis_config.edit_library_btn=false;vis_config.permission_library_btn=false}else{if(f.get("deleted")===false){vis_config.save_library_btn=false;vis_config.cancel_library_btn=false;vis_config.undelete_library_btn=false;if(f.get("can_user_add")===true){vis_config.upload_library_btn=true}if(f.get("can_user_modify")===true){vis_config.edit_library_btn=true}if(f.get("can_user_manage")===true){vis_config.permission_library_btn=true}}}}else{if(this.edit_mode===true){vis_config.upload_library_btn=false;vis_config.edit_library_btn=false;vis_config.permission_library_btn=false;vis_config.save_library_btn=true;vis_config.cancel_library_btn=true;vis_config.delete_library_btn=true}}this.element_visibility_config=vis_config},upload_to_library:function(){e.info("Coming soon. Stay tuned.")},permissions_on_library:function(){e.info("Coming soon. Stay tuned.")},edit_button_clicked:function(){this.edit_mode=true;this.repaint()},cancel_library_modification:function(){e.info("Modifications canceled");this.edit_mode=false;this.repaint()},save_library_modification:function(){var g=Galaxy.libraries.libraryListView.collection.get(this.$el.data("id"));var h=false;var j=this.$el.find(".input_library_name").val();if(typeof j!=="undefined"&&j!==g.get("name")){if(j.length>2){g.set("name",j);h=true}else{e.warning("Library name has to be at least 3 characters long");return}}var i=this.$el.find(".input_library_description").val();if(typeof i!=="undefined"&&i!==g.get("description")){g.set("description",i);h=true}var k=this.$el.find(".input_library_synopsis").val();if(typeof k!=="undefined"&&k!==g.get("synopsis")){g.set("synopsis",k);h=true}if(h){var f=this;g.save(null,{patch:true,success:function(l){f.edit_mode=false;f.repaint(l);e.success("Changes to library saved")},error:function(m,l){e.error("An error occured during updating the library :(")}})}else{this.edit_mode=false;this.repaint(g);e.info("Nothing has changed")}},delete_library:function(){var g=Galaxy.libraries.libraryListView.collection.get(this.$el.data("id"));var f=this;g.destroy({success:function(h){h.set("deleted",true);Galaxy.libraries.libraryListView.collection.add(h);f.edit_mode=false;if(Galaxy.libraries.preferences.get("with_deleted")===false){$(".tooltip").hide();f.$el.remove()}else{if(Galaxy.libraries.preferences.get("with_deleted")===true){f.repaint(h)}}e.success("Library has been marked deleted")},error:function(){e.error("An error occured during deleting the library :(")}})},undelete_library:function(){var g=Galaxy.libraries.libraryListView.collection.get(this.$el.data("id"));var f=this;g.url=g.urlRoot+g.id+"?undelete=true";g.destroy({success:function(h){h.set("deleted",false);Galaxy.libraries.libraryListView.collection.add(h);f.edit_mode=false;f.repaint(h);e.success("Library has been undeleted")},error:function(){e.error("An error occured while undeleting the library :(")}})},templateRow:function(){tmpl_array=[];tmpl_array.push(' <tr class="<% if(library.get("deleted") === true) { print("active") } %>" style="display:none;" data-id="<%- library.get("id") %>">');tmpl_array.push(" <% if(!edit_mode) { %>");tmpl_array.push(' <td><a href="#folders/<%- library.get("root_folder_id") %>"><%- library.get("name") %></a></td>');tmpl_array.push(' <td><%= _.escape(library.get("description")) %></td>');tmpl_array.push(' <td><%= _.escape(library.get("synopsis")) %></td>');tmpl_array.push(" <% } else if(edit_mode){ %>");tmpl_array.push(' <td><input type="text" class="form-control input_library_name" placeholder="name" value="<%- library.get("name") %>"></td>');tmpl_array.push(' <td><input type="text" class="form-control input_library_description" placeholder="description" value="<%- library.get("description") %>"></td>');tmpl_array.push(' <td><input type="text" class="form-control input_library_synopsis" placeholder="synopsis" value="<%- library.get("synopsis") %>"></td>');tmpl_array.push(" <% } %>");tmpl_array.push(' <td class="right-center">');tmpl_array.push(' <% if(library.get("deleted") === true) { %>');tmpl_array.push(' <span data-toggle="tooltip" data-placement="top" title="Marked deleted" style="color:grey;" class="fa fa-ban fa-lg deleted_lib_ico"></span>');tmpl_array.push(' <% } else if(library.get("public") === true) { %>');tmpl_array.push(' <span data-toggle="tooltip" data-placement="top" title="Public" style="color:grey;" class="fa fa-globe fa-lg public_lib_ico"></span>');tmpl_array.push(" <% }%>");tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Upload to library" class="primary-button btn-xs upload_library_btn" type="button" style="<% if(button_config.upload_library_btn === false) { print("display:none;") } %>"><span class="fa fa-upload"></span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Modify library" class="primary-button btn-xs edit_library_btn" type="button" style="<% if(button_config.edit_library_btn === false) { print("display:none;") } %>"><span class="fa fa-pencil"></span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Modify permissions" class="primary-button btn-xs permission_library_btn" type="button" style="<% if(button_config.permission_library_btn === false) { print("display:none;") } %>"><span class="fa fa-group"></span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Save changes" class="primary-button btn-xs save_library_btn" type="button" style="<% if(button_config.save_library_btn === false) { print("display:none;") } %>"><span class="fa fa-floppy-o"> Save</span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Discard changes" class="primary-button btn-xs cancel_library_btn" type="button" style="<% if(button_config.cancel_library_btn === false) { print("display:none;") } %>"><span class="fa fa-times"> Cancel</span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Delete library (can be undeleted later)" class="primary-button btn-xs delete_library_btn" type="button" style="<% if(button_config.delete_library_btn === false) { print("display:none;") } %>"><span class="fa fa-trash-o"> Delete</span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Undelete library" class="primary-button btn-xs undelete_library_btn" type="button" style="<% if(button_config.undelete_library_btn === false) { print("display:none;") } %>"><span class="fa fa-unlock"> Undelete</span></button>');tmpl_array.push(" </td>");tmpl_array.push(" </tr>");return _.template(tmpl_array.join(""))}});return{LibraryRowView:a}});
\ No newline at end of file
+define(["galaxy.masthead","utils/utils","libs/toastr"],function(b,c,d){var a=Backbone.View.extend({events:{"click .edit_library_btn":"edit_button_clicked","click .cancel_library_btn":"cancel_library_modification","click .save_library_btn":"save_library_modification","click .delete_library_btn":"delete_library","click .undelete_library_btn":"undelete_library","click .upload_library_btn":"upload_to_library","click .permission_library_btn":"permissions_on_library"},edit_mode:false,element_visibility_config:{upload_library_btn:false,edit_library_btn:false,permission_library_btn:false,save_library_btn:false,cancel_library_btn:false,delete_library_btn:false,undelete_library_btn:false},initialize:function(e){this.render(e)},render:function(f){if(typeof f==="undefined"){f=Galaxy.libraries.libraryListView.collection.get(this.$el.data("id"))}this.prepareButtons(f);var e=this.templateRow();this.setElement(e({library:f,button_config:this.element_visibility_config,edit_mode:this.edit_mode}));this.$el.show();return this},repaint:function(e){$(".tooltip").hide();var f=this.$el;this.render(e);f.replaceWith(this.$el);this.$el.find("[data-toggle]").tooltip()},prepareButtons:function(e){vis_config=this.element_visibility_config;if(this.edit_mode===false){vis_config.save_library_btn=false;vis_config.cancel_library_btn=false;vis_config.delete_library_btn=false;if(e.get("deleted")===true){vis_config.undelete_library_btn=true;vis_config.upload_library_btn=false;vis_config.edit_library_btn=false;vis_config.permission_library_btn=false}else{if(e.get("deleted")===false){vis_config.save_library_btn=false;vis_config.cancel_library_btn=false;vis_config.undelete_library_btn=false;if(e.get("can_user_add")===true){vis_config.upload_library_btn=true}if(e.get("can_user_modify")===true){vis_config.edit_library_btn=true}if(e.get("can_user_manage")===true){vis_config.permission_library_btn=true}}}}else{if(this.edit_mode===true){vis_config.upload_library_btn=false;vis_config.edit_library_btn=false;vis_config.permission_library_btn=false;vis_config.save_library_btn=true;vis_config.cancel_library_btn=true;vis_config.delete_library_btn=true}}this.element_visibility_config=vis_config},upload_to_library:function(){d.info("Coming soon. Stay tuned.")},permissions_on_library:function(){d.info("Coming soon. Stay tuned.")},edit_button_clicked:function(){this.edit_mode=true;this.repaint()},cancel_library_modification:function(){d.info("Modifications canceled");this.edit_mode=false;this.repaint()},save_library_modification:function(){var f=Galaxy.libraries.libraryListView.collection.get(this.$el.data("id"));var g=false;var i=this.$el.find(".input_library_name").val();if(typeof i!=="undefined"&&i!==f.get("name")){if(i.length>2){f.set("name",i);g=true}else{d.warning("Library name has to be at least 3 characters long");return}}var h=this.$el.find(".input_library_description").val();if(typeof h!=="undefined"&&h!==f.get("description")){f.set("description",h);g=true}var j=this.$el.find(".input_library_synopsis").val();if(typeof j!=="undefined"&&j!==f.get("synopsis")){f.set("synopsis",j);g=true}if(g){var e=this;f.save(null,{patch:true,success:function(k){e.edit_mode=false;e.repaint(k);d.success("Changes to library saved")},error:function(){d.error("An error occured during updating the library :(")}})}else{this.edit_mode=false;this.repaint(f);d.info("Nothing has changed")}},delete_library:function(){var f=Galaxy.libraries.libraryListView.collection.get(this.$el.data("id"));var e=this;f.destroy({success:function(g){g.set("deleted",true);Galaxy.libraries.libraryListView.collection.add(g);e.edit_mode=false;if(Galaxy.libraries.preferences.get("with_deleted")===false){$(".tooltip").hide();e.$el.remove()}else{if(Galaxy.libraries.preferences.get("with_deleted")===true){e.repaint(g)}}d.success("Library has been marked deleted")},error:function(){d.error("An error occured during deleting the library :(")}})},undelete_library:function(){var f=Galaxy.libraries.libraryListView.collection.get(this.$el.data("id"));var e=this;f.url=f.urlRoot+f.id+"?undelete=true";f.destroy({success:function(g){g.set("deleted",false);Galaxy.libraries.libraryListView.collection.add(g);e.edit_mode=false;e.repaint(g);d.success("Library has been undeleted")},error:function(){d.error("An error occured while undeleting the library :(")}})},templateRow:function(){tmpl_array=[];tmpl_array.push(' <tr class="<% if(library.get("deleted") === true) { print("active") } %>" style="display:none;" data-id="<%- library.get("id") %>">');tmpl_array.push(" <% if(!edit_mode) { %>");tmpl_array.push(' <td><a href="#folders/<%- library.get("root_folder_id") %>"><%- library.get("name") %></a></td>');tmpl_array.push(' <td><%= _.escape(library.get("description")) %></td>');tmpl_array.push(' <td><%= _.escape(library.get("synopsis")) %></td>');tmpl_array.push(" <% } else if(edit_mode){ %>");tmpl_array.push(' <td><input type="text" class="form-control input_library_name" placeholder="name" value="<%- library.get("name") %>"></td>');tmpl_array.push(' <td><input type="text" class="form-control input_library_description" placeholder="description" value="<%- library.get("description") %>"></td>');tmpl_array.push(' <td><input type="text" class="form-control input_library_synopsis" placeholder="synopsis" value="<%- library.get("synopsis") %>"></td>');tmpl_array.push(" <% } %>");tmpl_array.push(' <td class="right-center">');tmpl_array.push(' <% if(library.get("deleted") === true) { %>');tmpl_array.push(' <span data-toggle="tooltip" data-placement="top" title="Marked deleted" style="color:grey;" class="fa fa-ban fa-lg deleted_lib_ico"></span>');tmpl_array.push(' <% } else if(library.get("public") === true) { %>');tmpl_array.push(' <span data-toggle="tooltip" data-placement="top" title="Public" style="color:grey;" class="fa fa-globe fa-lg public_lib_ico"></span>');tmpl_array.push(" <% }%>");tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Modify library" class="primary-button btn-xs edit_library_btn" type="button" style="<% if(button_config.edit_library_btn === false) { print("display:none;") } %>"><span class="fa fa-pencil"></span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Modify permissions" class="primary-button btn-xs permission_library_btn" type="button" style="<% if(button_config.permission_library_btn === false) { print("display:none;") } %>"><span class="fa fa-group"></span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Save changes" class="primary-button btn-xs save_library_btn" type="button" style="<% if(button_config.save_library_btn === false) { print("display:none;") } %>"><span class="fa fa-floppy-o"> Save</span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Discard changes" class="primary-button btn-xs cancel_library_btn" type="button" style="<% if(button_config.cancel_library_btn === false) { print("display:none;") } %>"><span class="fa fa-times"> Cancel</span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Delete library (can be undeleted later)" class="primary-button btn-xs delete_library_btn" type="button" style="<% if(button_config.delete_library_btn === false) { print("display:none;") } %>"><span class="fa fa-trash-o"> Delete</span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Undelete library" class="primary-button btn-xs undelete_library_btn" type="button" style="<% if(button_config.undelete_library_btn === false) { print("display:none;") } %>"><span class="fa fa-unlock"> Undelete</span></button>');tmpl_array.push(" </td>");tmpl_array.push(" </tr>");return _.template(tmpl_array.join(""))}});return{LibraryRowView:a}});
\ No newline at end of file
diff -r 51643642564f214f09c2eff32307360f5e09dfaf -r 776e13962bbc861a94242e142e73278c9499dc70 static/scripts/packed/mvc/library/library-librarytoolbar-view.js
--- a/static/scripts/packed/mvc/library/library-librarytoolbar-view.js
+++ b/static/scripts/packed/mvc/library/library-librarytoolbar-view.js
@@ -1,1 +1,1 @@
-define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model"],function(a,c,d,b){var e=Backbone.View.extend({el:"#center",events:{"click #create_new_library_btn":"delegate_modal","click #include_deleted_chk":"check_include_deleted"},initialize:function(){this.render()},render:function(){var h=this.templateToolBar();var g=false;var f=false;if(Galaxy.currUser){g=Galaxy.currUser.isAdmin();f=Galaxy.currUser.isAnonymous()}else{f=true}this.$el.html(h({admin_user:g,anon_user:f}));if(g){this.$el.find("#include_deleted_chk")[0].checked=Galaxy.libraries.preferences.get("with_deleted")}},delegate_modal:function(f){Galaxy.libraries.libraryListView.show_library_modal(f)},check_include_deleted:function(f){if(f.target.checked){Galaxy.libraries.preferences.set({with_deleted:true});Galaxy.libraries.libraryListView.render()}else{Galaxy.libraries.preferences.set({with_deleted:false});Galaxy.libraries.libraryListView.render()}},templateToolBar:function(){tmpl_array=[];tmpl_array.push('<div class="library_style_container">');tmpl_array.push(' <div id="toolbar_form" margin-top:0.5em; ">');tmpl_array.push(' <h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');tmpl_array.push(" <% if(admin_user === true) { %>");tmpl_array.push(' <div id="library_toolbar">');tmpl_array.push(' <span data-toggle="tooltip" data-placement="top" title="Include deleted libraries"><input id="include_deleted_chk" style="margin: 0;" type="checkbox"><span class="fa fa-trash-o fa-lg"></span></input></span>');tmpl_array.push(' <span data-toggle="tooltip" data-placement="top" title="Create New Library"><button id="create_new_library_btn" class="primary-button btn-xs" type="button"><span class="fa fa-plus"></span> New Library</button><span>');tmpl_array.push(" </div>");tmpl_array.push(" <% } %>");tmpl_array.push(" </div>");tmpl_array.push(' <div id="libraries_element">');tmpl_array.push(" </div>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))}});return{LibraryToolbarView:e}});
\ No newline at end of file
+define([],function(){var a=Backbone.View.extend({el:"#center",events:{"click #create_new_library_btn":"delegate_modal","click #include_deleted_chk":"check_include_deleted"},initialize:function(){this.render()},render:function(){var d=this.templateToolBar();var c=false;var b=false;if(Galaxy.currUser){c=Galaxy.currUser.isAdmin();b=Galaxy.currUser.isAnonymous()}else{b=true}this.$el.html(d({admin_user:c,anon_user:b}));if(c){this.$el.find("#include_deleted_chk")[0].checked=Galaxy.libraries.preferences.get("with_deleted")}},delegate_modal:function(b){Galaxy.libraries.libraryListView.show_library_modal(b)},check_include_deleted:function(b){if(b.target.checked){Galaxy.libraries.preferences.set({with_deleted:true});Galaxy.libraries.libraryListView.render()}else{Galaxy.libraries.preferences.set({with_deleted:false});Galaxy.libraries.libraryListView.render()}},templateToolBar:function(){tmpl_array=[];tmpl_array.push('<div class="library_style_container">');tmpl_array.push(' <div id="toolbar_form" margin-top:0.5em; ">');tmpl_array.push(' <h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');tmpl_array.push(" <% if(admin_user === true) { %>");tmpl_array.push(' <div id="library_toolbar">');tmpl_array.push(' <span data-toggle="tooltip" data-placement="top" title="Include deleted libraries"><input id="include_deleted_chk" style="margin: 0;" type="checkbox"><span class="fa fa-trash-o fa-lg"></span></input></span>');tmpl_array.push(' <span data-toggle="tooltip" data-placement="top" title="Create New Library"><button id="create_new_library_btn" class="primary-button btn-xs" type="button"><span class="fa fa-plus"></span> New Library</button><span>');tmpl_array.push(" </div>");tmpl_array.push(" <% } %>");tmpl_array.push(" </div>");tmpl_array.push(' <div id="libraries_element">');tmpl_array.push(" </div>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))}});return{LibraryToolbarView:a}});
\ No newline at end of file
diff -r 51643642564f214f09c2eff32307360f5e09dfaf -r 776e13962bbc861a94242e142e73278c9499dc70 static/scripts/packed/mvc/library/library-model.js
--- a/static/scripts/packed/mvc/library/library-model.js
+++ b/static/scripts/packed/mvc/library/library-model.js
@@ -1,1 +1,1 @@
-define([],function(){var f=Backbone.Model.extend({urlRoot:"/api/libraries/",isVisible:function(l){var k=true;if((!show_delete)&&(this.get("deleted"))){k=false}return k}});var i=Backbone.Collection.extend({url:"/api/libraries",model:f,sort_key:"name",sort_order:null,initialize:function(k){k=k||{}},getVisible:function(l,m){m=m||[];var k=new i(this.filter(function(n){return n.isVisible(l)}));return k},sortByNameAsc:function(){this.comparator=function(l,k){if(l.get("name").toLowerCase()>k.get("name").toLowerCase()){return 1}if(k.get("name").toLowerCase()>l.get("name").toLowerCase()){return -1}return 0};this.sort();return this},sortByNameDesc:function(){this.comparator=function(l,k){if(l.get("name").toLowerCase()>k.get("name").toLowerCase()){return -1}if(k.get("name").toLowerCase()>l.get("name").toLowerCase()){return 1}return 0};this.sort();return this}});var g=Backbone.Model.extend({urlRoot:"/api/libraries/datasets"});var a=Backbone.Model.extend({urlRoot:"/api/folders"});var c=Backbone.Collection.extend({model:g,sortByNameAsc:function(){this.comparator=function(l,k){if(l.get("type")===k.get("type")){if(l.get("name").toLowerCase()>k.get("name").toLowerCase()){return 1}if(k.get("name").toLowerCase()>l.get("name").toLowerCase()){return -1}return 0}else{if(l.get("type")==="folder"){return -1}else{return 1}}};this.sort();return this},sortByNameDesc:function(){this.comparator=function(l,k){if(l.get("type")===k.get("type")){if(l.get("name").toLowerCase()>k.get("name").toLowerCase()){return -1}if(k.get("name").toLowerCase()>l.get("name").toLowerCase()){return 1}return 0}else{if(l.get("type")==="folder"){return -1}else{return 1}}};this.sort();return this}});var e=Backbone.Model.extend({defaults:{folder:new c(),urlRoot:"/api/folders/",id:"unknown"},parse:function(k){this.get("folder").reset(k.folder_contents);return k}});var b=Backbone.Model.extend({urlRoot:"/api/histories/"});var d=Backbone.Collection.extend({urlRoot:"/api/histories/",initialize:function(k){this.id=k.id},url:function(){return this.urlRoot+this.id+"/contents"},model:b});var h=Backbone.Model.extend({urlRoot:"/api/histories/"});var j=Backbone.Collection.extend({url:"/api/histories",model:h});return{Library:f,FolderAsModel:a,Libraries:i,Item:g,Folder:c,FolderContainer:e,HistoryItem:b,HistoryContents:d,GalaxyHistory:h,GalaxyHistories:j}});
\ No newline at end of file
+define([],function(){var f=Backbone.Model.extend({urlRoot:"/api/libraries/",isVisible:function(l){var k=true;if((!l)&&(this.get("deleted"))){k=false}return k}});var i=Backbone.Collection.extend({url:"/api/libraries",model:f,sort_key:"name",sort_order:null,initialize:function(k){k=k||{}},getVisible:function(l,m){m=m||[];var k=new i(this.filter(function(n){return n.isVisible(l)}));return k},sortByNameAsc:function(){this.comparator=function(l,k){if(l.get("name").toLowerCase()>k.get("name").toLowerCase()){return 1}if(k.get("name").toLowerCase()>l.get("name").toLowerCase()){return -1}return 0};this.sort();return this},sortByNameDesc:function(){this.comparator=function(l,k){if(l.get("name").toLowerCase()>k.get("name").toLowerCase()){return -1}if(k.get("name").toLowerCase()>l.get("name").toLowerCase()){return 1}return 0};this.sort();return this}});var g=Backbone.Model.extend({urlRoot:"/api/libraries/datasets"});var a=Backbone.Model.extend({urlRoot:"/api/folders"});var c=Backbone.Collection.extend({model:g,sortByNameAsc:function(){this.comparator=function(l,k){if(l.get("type")===k.get("type")){if(l.get("name").toLowerCase()>k.get("name").toLowerCase()){return 1}if(k.get("name").toLowerCase()>l.get("name").toLowerCase()){return -1}return 0}else{if(l.get("type")==="folder"){return -1}else{return 1}}};this.sort();return this},sortByNameDesc:function(){this.comparator=function(l,k){if(l.get("type")===k.get("type")){if(l.get("name").toLowerCase()>k.get("name").toLowerCase()){return -1}if(k.get("name").toLowerCase()>l.get("name").toLowerCase()){return 1}return 0}else{if(l.get("type")==="folder"){return -1}else{return 1}}};this.sort();return this}});var e=Backbone.Model.extend({defaults:{folder:new c(),urlRoot:"/api/folders/",id:"unknown"},parse:function(k){this.get("folder").reset(k.folder_contents);return k}});var b=Backbone.Model.extend({urlRoot:"/api/histories/"});var d=Backbone.Collection.extend({urlRoot:"/api/histories/",initialize:function(k){this.id=k.id},url:function(){return this.urlRoot+this.id+"/contents"},model:b});var h=Backbone.Model.extend({urlRoot:"/api/histories/"});var j=Backbone.Collection.extend({url:"/api/histories",model:h});return{Library:f,FolderAsModel:a,Libraries:i,Item:g,Folder:c,FolderContainer:e,HistoryItem:b,HistoryContents:d,GalaxyHistory:h,GalaxyHistories:j}});
\ No newline at end of file
diff -r 51643642564f214f09c2eff32307360f5e09dfaf -r 776e13962bbc861a94242e142e73278c9499dc70 static/scripts/packed/viz/trackster/painters.js
--- a/static/scripts/packed/viz/trackster/painters.js
+++ b/static/scripts/packed/viz/trackster/painters.js
@@ -1,1 +1,1 @@
-define(["libs/underscore"],function(_){var extend=_.extend;var BEFORE=1001,CONTAINS=1002,OVERLAP_START=1003,OVERLAP_END=1004,CONTAINED_BY=1005,AFTER=1006;var compute_overlap=function(first_region,second_region){var first_start=first_region[0],first_end=first_region[1],second_start=second_region[0],second_end=second_region[1],overlap;if(first_start<second_start){if(first_end<=second_start){overlap=BEFORE}else{if(first_end<=second_end){overlap=OVERLAP_START}else{overlap=CONTAINS}}}else{if(first_start>second_end){overlap=AFTER}else{if(first_end<=second_end){overlap=CONTAINED_BY}else{overlap=OVERLAP_END}}}return overlap};var is_overlap=function(first_region,second_region){var overlap=compute_overlap(first_region,second_region);return(overlap!==BEFORE&&overlap!==AFTER)};var dashedLine=function(ctx,x1,y1,x2,y2,dashLen){if(dashLen===undefined){dashLen=4}var dX=x2-x1;var dY=y2-y1;var dashes=Math.floor(Math.sqrt(dX*dX+dY*dY)/dashLen);var dashX=dX/dashes;var dashY=dY/dashes;var q;for(q=0;q<dashes;q++,x1+=dashX,y1+=dashY){if(q%2!==0){continue}ctx.fillRect(x1,y1,dashLen,1)}};var drawDownwardEquilateralTriangle=function(ctx,down_vertex_x,down_vertex_y,side_len){var x1=down_vertex_x-side_len/2,x2=down_vertex_x+side_len/2,y=down_vertex_y-Math.sqrt(side_len*3/2);ctx.beginPath();ctx.moveTo(x1,y);ctx.lineTo(x2,y);ctx.lineTo(down_vertex_x,down_vertex_y);ctx.lineTo(x1,y);ctx.strokeStyle=this.fillStyle;ctx.fill();ctx.stroke();ctx.closePath()};var Scaler=function(default_val){this.default_val=(default_val?default_val:1)};Scaler.prototype.gen_val=function(input){return this.default_val};var DrawResults=function(options){this.incomplete_features=options.incomplete_features;this.feature_mapper=options.feature_mapper};var Painter=function(data,view_start,view_end,prefs,mode){this.data=data;this.view_start=view_start;this.view_end=view_end;this.prefs=extend({},this.default_prefs,prefs);this.mode=mode};Painter.prototype.default_prefs={};Painter.prototype.draw=function(ctx,width,height,w_scale){};var LinePainter=function(data,view_start,view_end,prefs,mode){Painter.call(this,data,view_start,view_end,prefs,mode);if(this.prefs.min_value===undefined){this.prefs.min_value=_.min(_.map(this.data,function(d){return d[1]}))||0}if(this.prefs.max_value===undefined){this.prefs.max_value=_.max(_.map(this.data,function(d){return d[1]}))||0}};LinePainter.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Histogram",color:"#000",overflow_color:"#F66"};LinePainter.prototype.draw=function(ctx,width,height,w_scale){var in_path=false,min_value=this.prefs.min_value,max_value=this.prefs.max_value,vertical_range=max_value-min_value,height_px=height,view_start=this.view_start,mode=this.mode,data=this.data;ctx.save();var y_zero=Math.round(height+min_value/vertical_range*height);if(mode!=="Intensity"){ctx.fillStyle="#aaa";ctx.fillRect(0,y_zero,width,1)}ctx.beginPath();var x_scaled,y,delta_x_px;if(data.length>1){delta_x_px=Math.ceil((data[1][0]-data[0][0])*w_scale)}else{delta_x_px=10}var painter_color=this.prefs.block_color||this.prefs.color,pref_color=parseInt(painter_color.slice(1),16),pref_r=(pref_color&16711680)>>16,pref_g=(pref_color&65280)>>8,pref_b=pref_color&255,top_overflow=false,bot_overflow=false;for(var i=0,len=data.length;i<len;i++){ctx.fillStyle=ctx.strokeStyle=painter_color;top_overflow=bot_overflow=false;x_scaled=Math.round((data[i][0]-view_start)*w_scale);y=data[i][1];if(y===null){if(in_path&&mode==="Filled"){ctx.lineTo(x_scaled,height_px)}in_path=false;continue}if(y<min_value){bot_overflow=true;y=min_value}else{if(y>max_value){top_overflow=true;y=max_value}}if(mode==="Histogram"){y=Math.round(y/vertical_range*height_px);ctx.fillRect(x_scaled,y_zero,delta_x_px,-y)}else{if(mode==="Intensity"){var saturation=(y-min_value)/vertical_range,new_r=Math.round(pref_r+(255-pref_r)*(1-saturation)),new_g=Math.round(pref_g+(255-pref_g)*(1-saturation)),new_b=Math.round(pref_b+(255-pref_b)*(1-saturation));ctx.fillStyle="rgb("+new_r+","+new_g+","+new_b+")";ctx.fillRect(x_scaled,0,delta_x_px,height_px)}else{y=Math.round(height_px-(y-min_value)/vertical_range*height_px);if(in_path){ctx.lineTo(x_scaled,y)}else{in_path=true;if(mode==="Filled"){ctx.moveTo(x_scaled,height_px);ctx.lineTo(x_scaled,y)}else{ctx.moveTo(x_scaled,y)}}}}ctx.fillStyle=this.prefs.overflow_color;if(top_overflow||bot_overflow){var overflow_x;if(mode==="Histogram"||mode==="Intensity"){overflow_x=delta_x_px}else{x_scaled-=2;overflow_x=4}if(top_overflow){ctx.fillRect(x_scaled,0,overflow_x,3)}if(bot_overflow){ctx.fillRect(x_scaled,height_px-3,overflow_x,3)}}ctx.fillStyle=painter_color}if(mode==="Filled"){if(in_path){ctx.lineTo(x_scaled,y_zero);ctx.lineTo(0,y_zero)}ctx.fill()}else{ctx.stroke()}ctx.restore()};var FeaturePositionMapper=function(slot_height){this.feature_positions={};this.slot_height=slot_height;this.translation=0;this.y_translation=0};FeaturePositionMapper.prototype.map_feature_data=function(feature_data,slot,x_start,x_end){if(!this.feature_positions[slot]){this.feature_positions[slot]=[]}this.feature_positions[slot].push({data:feature_data,x_start:x_start,x_end:x_end})};FeaturePositionMapper.prototype.get_feature_data=function(x,y){var slot=Math.floor((y-this.y_translation)/this.slot_height),feature_dict;if(!this.feature_positions[slot]){return null}x+=this.translation;for(var i=0;i<this.feature_positions[slot].length;i++){feature_dict=this.feature_positions[slot][i];if(x>=feature_dict.x_start&&x<=feature_dict.x_end){return feature_dict.data}}};var FeaturePainter=function(data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler){Painter.call(this,data,view_start,view_end,prefs,mode);this.alpha_scaler=(alpha_scaler?alpha_scaler:new Scaler());this.height_scaler=(height_scaler?height_scaler:new Scaler());this.max_label_length=200};FeaturePainter.prototype.default_prefs={block_color:"#FFF",connector_color:"#FFF"};extend(FeaturePainter.prototype,{get_required_height:function(rows_required,width){var required_height=this.get_row_height(),y_scale=required_height,mode=this.mode;if(mode==="no_detail"||mode==="Squish"||mode==="Pack"){required_height=rows_required*y_scale}return required_height+this.get_top_padding(width)},get_top_padding:function(width){return 0},draw:function(ctx,width,height,w_scale,slots){var data=this.data,view_start=this.view_start,view_end=this.view_end;ctx.save();ctx.fillStyle=this.prefs.block_color;ctx.textAlign="right";var y_scale=this.get_row_height(),feature_mapper=new FeaturePositionMapper(y_scale),x_draw_coords,incomplete_features=[];for(var i=0,len=data.length;i<len;i++){var feature=data[i],feature_uid=feature[0],feature_start=feature[1],feature_end=feature[2],slot=(slots&&slots[feature_uid]!==undefined?slots[feature_uid]:null);if((this.mode==="Dense"||slot!==null)&&(feature_start<view_end&&feature_end>view_start)){x_draw_coords=this.draw_element(ctx,this.mode,feature,slot,view_start,view_end,w_scale,y_scale,width);feature_mapper.map_feature_data(feature,slot,x_draw_coords[0],x_draw_coords[1]);if(feature_start<view_start||feature_end>view_end){incomplete_features.push(feature)}}}ctx.restore();feature_mapper.y_translation=this.get_top_padding(width);return new DrawResults({incomplete_features:incomplete_features,feature_mapper:feature_mapper})},draw_element:function(ctx,mode,feature,slot,tile_low,tile_high,w_scale,y_scale,width){return[0,0]}});var DENSE_TRACK_HEIGHT=10,NO_DETAIL_TRACK_HEIGHT=3,SQUISH_TRACK_HEIGHT=5,PACK_TRACK_HEIGHT=10,NO_DETAIL_FEATURE_HEIGHT=1,DENSE_FEATURE_HEIGHT=9,SQUISH_FEATURE_HEIGHT=3,PACK_FEATURE_HEIGHT=9,LABEL_SPACING=2,CONNECTOR_COLOR="#ccc";var LinkedFeaturePainter=function(data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler){FeaturePainter.call(this,data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler);this.draw_background_connector=true;this.draw_individual_connectors=false};extend(LinkedFeaturePainter.prototype,FeaturePainter.prototype,{get_row_height:function(){var mode=this.mode,height;if(mode==="Dense"){height=DENSE_TRACK_HEIGHT}else{if(mode==="no_detail"){height=NO_DETAIL_TRACK_HEIGHT}else{if(mode==="Squish"){height=SQUISH_TRACK_HEIGHT}else{height=PACK_TRACK_HEIGHT}}}return height},draw_element:function(ctx,mode,feature,slot,tile_low,tile_high,w_scale,y_scale,width){var feature_uid=feature[0],feature_start=feature[1],feature_end=feature[2],feature_name=feature[3],feature_strand=feature[4],f_start=Math.floor(Math.max(0,(feature_start-tile_low-0.5)*w_scale)),f_end=Math.ceil(Math.min(width,Math.max(0,(feature_end-tile_low-0.5)*w_scale))),draw_start=f_start,draw_end=f_end,y_start=(mode==="Dense"?0:(0+slot))*y_scale+this.get_top_padding(width),thickness,y_start,thick_start=null,thick_end=null,block_color=(!feature_strand||feature_strand==="+"||feature_strand==="."?this.prefs.block_color:this.prefs.reverse_strand_color);label_color=this.prefs.label_color;ctx.globalAlpha=this.alpha_scaler.gen_val(feature);if(mode==="Dense"){slot=1}if(mode==="no_detail"){ctx.fillStyle=block_color;ctx.fillRect(f_start,y_start+5,f_end-f_start,NO_DETAIL_FEATURE_HEIGHT)}else{var feature_ts=feature[5],feature_te=feature[6],feature_blocks=feature[7],full_height=true;if(feature_ts&&feature_te){thick_start=Math.floor(Math.max(0,(feature_ts-tile_low)*w_scale));thick_end=Math.ceil(Math.min(width,Math.max(0,(feature_te-tile_low)*w_scale)))}var thin_height,thick_height;if(mode==="Squish"){thin_height=1;thick_height=SQUISH_FEATURE_HEIGHT;full_height=false}else{if(mode==="Dense"){thin_height=5;thick_height=DENSE_FEATURE_HEIGHT}else{thin_height=5;thick_height=PACK_FEATURE_HEIGHT}}if(!feature_blocks){ctx.fillStyle=block_color;ctx.fillRect(f_start,y_start+1,f_end-f_start,thick_height);if(feature_strand&&full_height){if(feature_strand==="+"){ctx.fillStyle=ctx.canvas.manager.get_pattern("right_strand_inv")}else{if(feature_strand==="-"){ctx.fillStyle=ctx.canvas.manager.get_pattern("left_strand_inv")}}ctx.fillRect(f_start,y_start+1,f_end-f_start,thick_height)}}else{var cur_y_start,cur_height;if(mode==="Squish"||mode==="Dense"){cur_y_start=y_start+Math.floor(SQUISH_FEATURE_HEIGHT/2)+1;cur_height=1}else{if(feature_strand){cur_y_start=y_start;cur_height=thick_height}else{cur_y_start+=(SQUISH_FEATURE_HEIGHT/2)+1;cur_height=1}}if(this.draw_background_connector){if(mode==="Squish"||mode==="Dense"){ctx.fillStyle=CONNECTOR_COLOR}else{if(feature_strand){if(feature_strand==="+"){ctx.fillStyle=ctx.canvas.manager.get_pattern("right_strand")}else{if(feature_strand==="-"){ctx.fillStyle=ctx.canvas.manager.get_pattern("left_strand")}}}else{ctx.fillStyle=CONNECTOR_COLOR}}ctx.fillRect(f_start,cur_y_start,f_end-f_start,cur_height)}var start_and_height;for(var k=0,k_len=feature_blocks.length;k<k_len;k++){var block=feature_blocks[k],block_start=Math.floor(Math.max(0,(block[0]-tile_low-0.5)*w_scale)),block_end=Math.ceil(Math.min(width,Math.max((block[1]-tile_low-0.5)*w_scale))),last_block_start,last_block_end;if(block_start>block_end){continue}ctx.fillStyle=block_color;ctx.fillRect(block_start,y_start+(thick_height-thin_height)/2+1,block_end-block_start,thin_height);if(thick_start!==undefined&&feature_te>feature_ts&&!(block_start>thick_end||block_end<thick_start)){var block_thick_start=Math.max(block_start,thick_start),block_thick_end=Math.min(block_end,thick_end);ctx.fillRect(block_thick_start,y_start+1,block_thick_end-block_thick_start,thick_height);if(feature_blocks.length===1&&mode==="Pack"){if(feature_strand==="+"){ctx.fillStyle=ctx.canvas.manager.get_pattern("right_strand_inv")}else{if(feature_strand==="-"){ctx.fillStyle=ctx.canvas.manager.get_pattern("left_strand_inv")}}if(block_thick_start+14<block_thick_end){block_thick_start+=2;block_thick_end-=2}ctx.fillRect(block_thick_start,y_start+1,block_thick_end-block_thick_start,thick_height)}}if(this.draw_individual_connectors&&last_block_start){this.draw_connector(ctx,last_block_start,last_block_end,block_start,block_end,y_start)}last_block_start=block_start;last_block_end=block_end}if(mode==="Pack"){ctx.globalAlpha=1;ctx.fillStyle="white";var hscale_factor=this.height_scaler.gen_val(feature),new_height=Math.ceil(thick_height*hscale_factor),ws_height=Math.round((thick_height-new_height)/2);if(hscale_factor!==1){ctx.fillRect(f_start,cur_y_start+1,f_end-f_start,ws_height);ctx.fillRect(f_start,cur_y_start+thick_height-ws_height+1,f_end-f_start,ws_height)}}}ctx.globalAlpha=1;if(feature_name&&mode==="Pack"&&feature_start>tile_low){ctx.fillStyle=label_color;if(tile_low===0&&f_start-ctx.measureText(feature_name).width<0){ctx.textAlign="left";ctx.fillText(feature_name,f_end+LABEL_SPACING,y_start+8,this.max_label_length);draw_end+=ctx.measureText(feature_name).width+LABEL_SPACING}else{ctx.textAlign="right";ctx.fillText(feature_name,f_start-LABEL_SPACING,y_start+8,this.max_label_length);draw_start-=ctx.measureText(feature_name).width+LABEL_SPACING}}}ctx.globalAlpha=1;return[draw_start,draw_end]}});var ReadPainter=function(data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler,ref_seq,base_color_fn){FeaturePainter.call(this,data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler);this.ref_seq=(ref_seq?ref_seq.data:null);this.base_color_fn=base_color_fn};extend(ReadPainter.prototype,FeaturePainter.prototype,{get_row_height:function(){var height,mode=this.mode;if(mode==="Dense"){height=DENSE_TRACK_HEIGHT}else{if(mode==="Squish"){height=SQUISH_TRACK_HEIGHT}else{height=PACK_TRACK_HEIGHT;if(this.prefs.show_insertions){height*=2}}}return height},_parse_cigar:function(cigar_str){var cigar_ops="MIDNSHP=X";var blocks=[[0,0]],cur_block=blocks[0],base_pos=0,parsed_cigar=_.map(cigar_str.match(/[0-9]+[MIDNSHP=X]/g),function(op){var op_len=parseInt(op.slice(0,-1),10),op_char=op.slice(-1);if(op_char==="N"){if(cur_block[1]!==0){cur_block=[base_pos+op_len,base_pos+op_len];blocks.push(cur_block)}}else{if("ISHP".indexOf(op_char)===-1){cur_block[1]+=op_len;base_pos+=op_len}}return[cigar_ops.indexOf(op_char),op_len]});return{blocks:blocks,cigar:parsed_cigar}},draw_read:function(ctx,mode,w_scale,y_start,tile_low,tile_high,feature_start,cigar,strand,read_seq){var update_base_offset=function(offset,cig_op,cig_len){if("M=NXD".indexOf(cig_op)!==-1){offset+=cig_len}return offset},update_seq_offset=function(offset,cig_op,cig_len){if("IX".indexOf(cig_op)!==-1){offset+=cig_len}return offset};ctx.textAlign="center";var tile_region=[tile_low,tile_high],base_offset=0,seq_offset=0,gap=Math.round(w_scale/2),char_width_px=ctx.canvas.manager.char_width_px,block_color=(strand==="+"?this.prefs.block_color:this.prefs.reverse_strand_color),pack_mode=(mode==="Pack"),paint_utils=new ReadPainterUtils(ctx,(pack_mode?PACK_FEATURE_HEIGHT:SQUISH_FEATURE_HEIGHT),w_scale,mode),drawing_blocks=[];var draw_last=[];var t=this._parse_cigar(cigar);cigar=t.cigar;drawing_blocks=t.blocks;for(var i=0;i<drawing_blocks.length;i++){var block=drawing_blocks[i];if(is_overlap([feature_start+block[0],feature_start+block[1]],tile_region)){var s_start=Math.floor(Math.max(-0.5*w_scale,(feature_start+block[0]-tile_low-0.5)*w_scale)),s_end=Math.floor(Math.max(0,(feature_start+block[1]-tile_low-0.5)*w_scale));if(s_start===s_end){s_end+=1}ctx.fillStyle=block_color;ctx.fillRect(s_start,y_start+(pack_mode?1:4),s_end-s_start,(pack_mode?PACK_FEATURE_HEIGHT:SQUISH_FEATURE_HEIGHT))}}for(var cig_id=0,len=cigar.length;cig_id<len;cig_id++){var cig=cigar[cig_id],cig_op="MIDNSHP=X"[cig[0]],cig_len=cig[1];var seq_start=feature_start+base_offset,s_start=Math.floor(Math.max(-0.5*w_scale,(seq_start-tile_low-0.5)*w_scale)),s_end=Math.floor(Math.max(0,(seq_start+cig_len-tile_low-0.5)*w_scale));if(!is_overlap([seq_start,seq_start+cig_len],tile_region)){base_offset=update_base_offset(base_offset,cig_op,cig_len);seq_offset=update_seq_offset(seq_offset,cig_op,cig_len);continue}if(s_start===s_end){s_end+=1}switch(cig_op){case"H":case"S":case"P":break;case"M":base_offset+=cig_len;break;case"=":case"X":var cur_seq="";if(cig_op==="X"){cur_seq=read_seq.slice(seq_offset,seq_offset+cig_len)}else{if(this.ref_seq){cur_seq=this.ref_seq.slice(Math.max(0,seq_start-tile_low),Math.min(seq_start-tile_low+cig_len,tile_high-tile_low))}}var start_pos=Math.max(seq_start,tile_low);for(var c=0;c<cur_seq.length;c++){if(cur_seq&&!this.prefs.show_differences||cig_op==="X"){var c_start=Math.floor(Math.max(0,(start_pos+c-tile_low)*w_scale));ctx.fillStyle=this.base_color_fn(cur_seq[c]);if(pack_mode&&w_scale>char_width_px){ctx.fillText(cur_seq[c],c_start,y_start+9)}else{if(w_scale>0.05){ctx.fillRect(c_start-gap,y_start+(pack_mode?1:4),Math.max(1,Math.round(w_scale)),(pack_mode?PACK_FEATURE_HEIGHT:SQUISH_FEATURE_HEIGHT))}}}}if(cig_op==="X"){seq_offset+=cig_len}base_offset+=cig_len;break;case"N":ctx.fillStyle=CONNECTOR_COLOR;ctx.fillRect(s_start,y_start+5,s_end-s_start,1);base_offset+=cig_len;break;case"D":paint_utils.draw_deletion(s_start,y_start+(pack_mode?1:4),cig_len);base_offset+=cig_len;break;case"I":var insert_x_coord=s_start-gap;if(is_overlap([seq_start,seq_start+cig_len],tile_region)){var seq=read_seq.slice(seq_offset,seq_offset+cig_len);if(this.prefs.show_insertions){var x_center=s_start-(s_end-s_start)/2;if((mode==="Pack"||this.mode==="Auto")&&read_seq!==undefined&&w_scale>char_width_px){ctx.fillStyle="yellow";ctx.fillRect(x_center-gap,y_start-9,s_end-s_start,9);draw_last[draw_last.length]={type:"triangle",data:[insert_x_coord,y_start+4,5]};ctx.fillStyle=CONNECTOR_COLOR;switch(compute_overlap([seq_start,seq_start+cig_len],tile_region)){case (OVERLAP_START):seq=seq.slice(tile_low-seq_start);break;case (OVERLAP_END):seq=seq.slice(0,seq_start-tile_high);break;case (CONTAINED_BY):break;case (CONTAINS):seq=seq.slice(tile_low-seq_start,seq_start-tile_high);break}for(var c=0,str_len=seq.length;c<str_len;c++){var c_start=Math.floor(Math.max(0,(seq_start+c-tile_low)*w_scale));ctx.fillText(seq[c],c_start-(s_end-s_start)/2,y_start)}}else{ctx.fillStyle="yellow";ctx.fillRect(x_center,y_start+(this.mode!=="Dense"?2:5),s_end-s_start,(mode!=="Dense"?SQUISH_FEATURE_HEIGHT:DENSE_FEATURE_HEIGHT))}}else{if((mode==="Pack"||this.mode==="Auto")&&read_seq!==undefined&&w_scale>char_width_px){draw_last.push({type:"text",data:[seq.length,insert_x_coord,y_start+9]})}else{}}}seq_offset+=cig_len;break}}ctx.fillStyle="yellow";var item,type,data;for(var i=0;i<draw_last.length;i++){item=draw_last[i];type=item.type;data=item.data;if(type==="text"){ctx.save();ctx.font="bold "+ctx.font;ctx.fillText(data[0],data[1],data[2]);ctx.restore()}else{if(type==="triangle"){drawDownwardEquilateralTriangle(ctx,data[0],data[1],data[2])}}}},draw_element:function(ctx,mode,feature,slot,tile_low,tile_high,w_scale,y_scale,width){var feature_uid=feature[0],feature_start=feature[1],feature_end=feature[2],feature_name=feature[3],f_start=Math.floor(Math.max(-0.5*w_scale,(feature_start-tile_low-0.5)*w_scale)),f_end=Math.ceil(Math.min(width,Math.max(0,(feature_end-tile_low-0.5)*w_scale))),y_start=(mode==="Dense"?0:(0+slot))*y_scale,label_color=this.prefs.label_color;if(feature[5] instanceof Array){var connector=true;if(feature[4][1]>=tile_low&&feature[4][0]<=tile_high&&feature[4][2]){this.draw_read(ctx,mode,w_scale,y_start,tile_low,tile_high,feature[4][0],feature[4][2],feature[4][3],feature[4][4])}else{connector=false}if(feature[5][1]>=tile_low&&feature[5][0]<=tile_high&&feature[5][2]){this.draw_read(ctx,mode,w_scale,y_start,tile_low,tile_high,feature[5][0],feature[5][2],feature[5][3],feature[5][4])}else{connector=false}var b1_end=Math.ceil(Math.min(width,Math.max(-0.5*w_scale,(feature[4][1]-tile_low-0.5)*w_scale))),b2_start=Math.floor(Math.max(-0.5*w_scale,(feature[5][0]-tile_low-0.5)*w_scale));if(connector&&b2_start>b1_end){ctx.fillStyle=CONNECTOR_COLOR;dashedLine(ctx,b1_end,y_start+5,b2_start,y_start+5)}}else{this.draw_read(ctx,mode,w_scale,y_start,tile_low,tile_high,feature_start,feature[4],feature[5],feature[6])}if(mode==="Pack"&&feature_start>=tile_low&&feature_name!=="."){ctx.fillStyle=this.prefs.label_color;if(tile_low===0&&f_start-ctx.measureText(feature_name).width<0){ctx.textAlign="left";ctx.fillText(feature_name,f_end+LABEL_SPACING,y_start+8,this.max_label_length)}else{ctx.textAlign="right";ctx.fillText(feature_name,f_start-LABEL_SPACING,y_start+8,this.max_label_length)}}return[0,0]}});var ArcLinkedFeaturePainter=function(data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler){LinkedFeaturePainter.call(this,data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler);this.longest_feature_length=this.calculate_longest_feature_length();this.draw_background_connector=false;this.draw_individual_connectors=true};extend(ArcLinkedFeaturePainter.prototype,FeaturePainter.prototype,LinkedFeaturePainter.prototype,{calculate_longest_feature_length:function(){var longest_feature_length=0;for(var i=0,len=this.data.length;i<len;i++){var feature=this.data[i],feature_start=feature[1],feature_end=feature[2];longest_feature_length=Math.max(longest_feature_length,feature_end-feature_start)}return longest_feature_length},get_top_padding:function(width){var view_range=this.view_end-this.view_start,w_scale=width/view_range;return Math.min(128,Math.ceil((this.longest_feature_length/2)*w_scale))},draw_connector:function(ctx,block1_start,block1_end,block2_start,block2_end,y_start){var x_center=(block1_end+block2_start)/2,radius=block2_start-x_center;var angle1=Math.PI,angle2=0;if(radius>0){ctx.beginPath();ctx.arc(x_center,y_start,block2_start-x_center,Math.PI,0);ctx.stroke()}}});var Color=function(rgb,a){if(Array.isArray(rgb)){this.rgb=rgb}else{if(rgb.length==6){this.rgb=rgb.match(/.{2}/g).map(function(c){return parseInt(c,16)})}else{if(rgb.length==7){this.rgb=rgb.substring(1,7).match(/.{2}/g).map(function(c){return parseInt(c,16)})}else{this.rgb=rgb.split("").map(function(c){return parseInt(c+c,16)})}}}this.alpha=typeof(a)==="number"?a:1};Color.prototype={eval:function(){return this},toCSS:function(){if(this.alpha<1){return"rgba("+this.rgb.map(function(c){return Math.round(c)}).concat(this.alpha).join(", ")+")"}else{return"#"+this.rgb.map(function(i){i=Math.round(i);i=(i>255?255:(i<0?0:i)).toString(16);return i.length===1?"0"+i:i}).join("")}},toHSL:function(){var r=this.rgb[0]/255,g=this.rgb[1]/255,b=this.rgb[2]/255,a=this.alpha;var max=Math.max(r,g,b),min=Math.min(r,g,b);var h,s,l=(max+min)/2,d=max-min;if(max===min){h=s=0}else{s=l>0.5?d/(2-max-min):d/(max+min);switch(max){case r:h=(g-b)/d+(g<b?6:0);break;case g:h=(b-r)/d+2;break;case b:h=(r-g)/d+4;break}h/=6}return{h:h*360,s:s,l:l,a:a}},toARGB:function(){var argb=[Math.round(this.alpha*255)].concat(this.rgb);return"#"+argb.map(function(i){i=Math.round(i);i=(i>255?255:(i<0?0:i)).toString(16);return i.length===1?"0"+i:i}).join("")},mix:function(color2,weight){color1=this;var p=weight;var w=p*2-1;var a=color1.toHSL().a-color2.toHSL().a;var w1=(((w*a==-1)?w:(w+a)/(1+w*a))+1)/2;var w2=1-w1;var rgb=[color1.rgb[0]*w1+color2.rgb[0]*w2,color1.rgb[1]*w1+color2.rgb[1]*w2,color1.rgb[2]*w1+color2.rgb[2]*w2];var alpha=color1.alpha*p+color2.alpha*(1-p);return new Color(rgb,alpha)}};var LinearRamp=function(start_color,end_color,start_value,end_value){this.start_color=new Color(start_color);this.end_color=new Color(end_color);this.start_value=start_value;this.end_value=end_value;this.value_range=end_value-start_value};LinearRamp.prototype.map_value=function(value){value=Math.max(value,this.start_value);value=Math.min(value,this.end_value);value=(value-this.start_value)/this.value_range;return this.start_color.mix(this.end_color,1-value).toCSS()};var SplitRamp=function(start_color,middle_color,end_color,start_value,end_value){this.positive_ramp=new LinearRamp(middle_color,end_color,0,end_value);this.negative_ramp=new LinearRamp(middle_color,start_color,0,-start_value);this.start_value=start_value;this.end_value=end_value};SplitRamp.prototype.map_value=function(value){value=Math.max(value,this.start_value);value=Math.min(value,this.end_value);if(value>=0){return this.positive_ramp.map_value(value)}else{return this.negative_ramp.map_value(-value)}};var DiagonalHeatmapPainter=function(data,view_start,view_end,prefs,mode){Painter.call(this,data,view_start,view_end,prefs,mode);var i,len;if(this.prefs.min_value===undefined){var min_value=Infinity;for(i=0,len=this.data.length;i<len;i++){min_value=Math.min(min_value,this.data[i][5])}this.prefs.min_value=min_value}if(this.prefs.max_value===undefined){var max_value=-Infinity;for(i=0,len=this.data.length;i<len;i++){max_value=Math.max(max_value,this.data[i][5])}this.prefs.max_value=max_value}};DiagonalHeatmapPainter.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Heatmap",pos_color:"#FF8C00",neg_color:"#4169E1"};DiagonalHeatmapPainter.prototype.draw=function(ctx,width,height,w_scale){var min_value=this.prefs.min_value,max_value=this.prefs.max_value,value_range=max_value-min_value,height_px=height,view_start=this.view_start,mode=this.mode,data=this.data,invsqrt2=1/Math.sqrt(2);var ramp=(new SplitRamp(this.prefs.neg_color,"#FFFFFF",this.prefs.pos_color,min_value,max_value));var d,s1,e1,s2,e2,value;var scale=function(p){return(p-view_start)*w_scale};ctx.save();ctx.rotate(-45*Math.PI/180);ctx.scale(invsqrt2,invsqrt2);for(var i=0,len=data.length;i<len;i++){d=data[i];s1=scale(d[1]);e1=scale(d[2]);s2=scale(d[4]);e2=scale(d[5]);value=d[6];ctx.fillStyle=(ramp.map_value(value));ctx.fillRect(s1,s2,(e1-s1),(e2-s2))}ctx.restore()};var ReadPainterUtils=function(ctx,row_height,px_per_base,mode){this.ctx=ctx;this.row_height=row_height;this.px_per_base=px_per_base;this.draw_details=(mode==="Pack"||mode==="Auto")&&(px_per_base>=ctx.canvas.manager.char_width_px);this.delete_details_thickness=0.2};extend(ReadPainterUtils.prototype,{draw_deletion:function(x,y,len){this.ctx.fillStyle="black";var thickness=(this.draw_details?this.delete_details_thickness:1)*this.row_height;y+=0.5*(this.row_height-thickness);this.ctx.fillRect(x,y,len*this.px_per_base,thickness)}});var VariantPainter=function(data,view_start,view_end,prefs,mode,base_color_fn){Painter.call(this,data,view_start,view_end,prefs,mode);this.base_color_fn=base_color_fn;this.divider_height=1};extend(VariantPainter.prototype,Painter.prototype,{get_row_height:function(){var mode=this.mode,height;if(mode==="Dense"){height=DENSE_TRACK_HEIGHT}else{if(mode==="Squish"){height=SQUISH_TRACK_HEIGHT}else{height=PACK_TRACK_HEIGHT}}return height},get_required_height:function(num_samples){var height=this.prefs.summary_height;if(num_samples>1&&this.prefs.show_sample_data){height+=this.divider_height+num_samples*this.get_row_height()}return height},draw:function(ctx,width,height,w_scale){ctx.save();var get_deletion_info=function(ref,alt){var ref_len=ref.length,alt_len=alt.length,start=0,len=1,is_delete=false;if(alt==="-"){is_delete=true;len=ref.length}else{if(ref.indexOf(alt)===0&&ref_len>alt_len){is_delete=true;len=ref_len=alt_len;start+=alt_len}}return(is_delete?{start:start,len:len}:null)};var locus_data,pos,id,ref,alt,qual,filter,sample_gts,allele_counts,variant,draw_x_start,char_x_start,draw_y_start,genotype,base_px=Math.max(1,Math.floor(w_scale)),num_samples=(this.data.length?this.data[0][7].split(",").length:0),row_height=(this.mode==="Squish"?SQUISH_TRACK_HEIGHT:PACK_TRACK_HEIGHT),feature_height=(w_scale<0.1?row_height:(this.mode==="Squish"?SQUISH_FEATURE_HEIGHT:PACK_FEATURE_HEIGHT)),draw_summary=true,paint_utils=new ReadPainterUtils(ctx,row_height,w_scale,this.mode),j;if(num_samples===1){row_height=feature_height=(w_scale<ctx.canvas.manager.char_width_px?this.prefs.summary_height:row_height);draw_summary=false}if(this.prefs.show_sample_data&&draw_summary){ctx.fillStyle="#F3F3F3";ctx.globalAlpha=1;ctx.fillRect(0,this.prefs.summary_height-this.divider_height,width,this.divider_height)}ctx.textAlign="center";for(var i=0;i<this.data.length;i++){locus_data=this.data[i];pos=locus_data[1];ref=locus_data[3];alt=[locus_data[4].split(",")];sample_gts=locus_data[7].split(",");allele_counts=locus_data.slice(8);alt=_.map(_.flatten(alt),function(a){var type,alt_info={},delete_info=get_deletion_info(ref,a);if(delete_info){type="deletion";_.extend(alt_info,delete_info)}else{type="snp"}return _.extend(alt_info,{type:type,value:a,})});if(pos<this.view_start||pos>this.view_end){continue}draw_x_start=Math.floor(Math.max(-0.5*w_scale,(pos-this.view_start-0.5)*w_scale));char_x_start=Math.floor(Math.max(0,(pos-this.view_start)*w_scale));if(draw_summary){ctx.fillStyle="#999999";ctx.globalAlpha=1;ctx.fillRect(draw_x_start,0,base_px,this.prefs.summary_height);draw_y_start=this.prefs.summary_height;for(j=0;j<alt.length;j++){ctx.fillStyle=(alt[j].type==="deletion"?"black":this.base_color_fn(alt[j].value));allele_frac=allele_counts/sample_gts.length;draw_height=Math.ceil(this.prefs.summary_height*allele_frac);ctx.fillRect(draw_x_start,draw_y_start-draw_height,base_px,draw_height);draw_y_start-=draw_height}}if(!this.prefs.show_sample_data){continue}draw_y_start=(draw_summary?this.prefs.summary_height+this.divider_height:0);for(j=0;j<sample_gts.length;j++,draw_y_start+=row_height){genotype=(sample_gts[j]?sample_gts[j].split(/\/|\|/):["0","0"]);variant=null;if(genotype[0]===genotype[1]){if(genotype[0]==="."){}else{if(genotype[0]!=="0"){variant=alt[parseInt(genotype[0],10)-1];ctx.globalAlpha=1}}}else{variant=(genotype[0]!=="0"?genotype[0]:genotype[1]);variant=alt[parseInt(variant,10)-1];ctx.globalAlpha=0.5}if(variant){if(variant.type==="snp"){var snp=variant.value;ctx.fillStyle=this.base_color_fn(snp);if(paint_utils.draw_details){ctx.fillText(snp,char_x_start,draw_y_start+row_height)}else{ctx.fillRect(draw_x_start,draw_y_start+1,base_px,feature_height)}}else{if(variant.type==="deletion"){paint_utils.draw_deletion(draw_x_start+base_px*variant.start,draw_y_start+1,variant.len)}else{}}}}}ctx.restore()}});return{Scaler:Scaler,LinePainter:LinePainter,LinkedFeaturePainter:LinkedFeaturePainter,ReadPainter:ReadPainter,ArcLinkedFeaturePainter:ArcLinkedFeaturePainter,DiagonalHeatmapPainter:DiagonalHeatmapPainter,VariantPainter:VariantPainter}});
\ No newline at end of file
+define(["libs/underscore"],function(_){var extend=_.extend;var BEFORE=1001,CONTAINS=1002,OVERLAP_START=1003,OVERLAP_END=1004,CONTAINED_BY=1005,AFTER=1006;var compute_overlap=function(first_region,second_region){var first_start=first_region[0],first_end=first_region[1],second_start=second_region[0],second_end=second_region[1],overlap;if(first_start<second_start){if(first_end<=second_start){overlap=BEFORE}else{if(first_end<=second_end){overlap=OVERLAP_START}else{overlap=CONTAINS}}}else{if(first_start>second_end){overlap=AFTER}else{if(first_end<=second_end){overlap=CONTAINED_BY}else{overlap=OVERLAP_END}}}return overlap};var is_overlap=function(first_region,second_region){var overlap=compute_overlap(first_region,second_region);return(overlap!==BEFORE&&overlap!==AFTER)};var dashedLine=function(ctx,x1,y1,x2,y2,dashLen){if(dashLen===undefined){dashLen=4}var dX=x2-x1;var dY=y2-y1;var dashes=Math.floor(Math.sqrt(dX*dX+dY*dY)/dashLen);var dashX=dX/dashes;var dashY=dY/dashes;var q;for(q=0;q<dashes;q++,x1+=dashX,y1+=dashY){if(q%2!==0){continue}ctx.fillRect(x1,y1,dashLen,1)}};var drawDownwardEquilateralTriangle=function(ctx,down_vertex_x,down_vertex_y,side_len){var x1=down_vertex_x-side_len/2,x2=down_vertex_x+side_len/2,y=down_vertex_y-Math.sqrt(side_len*3/2);ctx.beginPath();ctx.moveTo(x1,y);ctx.lineTo(x2,y);ctx.lineTo(down_vertex_x,down_vertex_y);ctx.lineTo(x1,y);ctx.strokeStyle=this.fillStyle;ctx.fill();ctx.stroke();ctx.closePath()};var Scaler=function(default_val){this.default_val=(default_val?default_val:1)};Scaler.prototype.gen_val=function(input){return this.default_val};var DrawResults=function(options){this.incomplete_features=options.incomplete_features;this.feature_mapper=options.feature_mapper};var Painter=function(data,view_start,view_end,prefs,mode){this.data=data;this.view_start=view_start;this.view_end=view_end;this.prefs=extend({},this.default_prefs,prefs);this.mode=mode};Painter.prototype.default_prefs={};Painter.prototype.draw=function(ctx,width,height,w_scale){};var LinePainter=function(data,view_start,view_end,prefs,mode){Painter.call(this,data,view_start,view_end,prefs,mode);if(this.prefs.min_value===undefined){this.prefs.min_value=_.min(_.map(this.data,function(d){return d[1]}))||0}if(this.prefs.max_value===undefined){this.prefs.max_value=_.max(_.map(this.data,function(d){return d[1]}))||0}};LinePainter.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Histogram",color:"#000",overflow_color:"#F66"};LinePainter.prototype.draw=function(ctx,width,height,w_scale){var in_path=false,min_value=this.prefs.min_value,max_value=this.prefs.max_value,vertical_range=max_value-min_value,height_px=height,view_start=this.view_start,mode=this.mode,data=this.data;ctx.save();var y_zero=Math.round(height+min_value/vertical_range*height);if(mode!=="Intensity"){ctx.fillStyle="#aaa";ctx.fillRect(0,y_zero,width,1)}ctx.beginPath();var x_scaled,y,delta_x_px;if(data.length>1){delta_x_px=Math.ceil((data[1][0]-data[0][0])*w_scale)}else{delta_x_px=10}var painter_color=this.prefs.block_color||this.prefs.color,pref_color=parseInt(painter_color.slice(1),16),pref_r=(pref_color&16711680)>>16,pref_g=(pref_color&65280)>>8,pref_b=pref_color&255,top_overflow=false,bot_overflow=false;for(var i=0,len=data.length;i<len;i++){ctx.fillStyle=ctx.strokeStyle=painter_color;top_overflow=bot_overflow=false;x_scaled=Math.round((data[i][0]-view_start)*w_scale);y=data[i][1];if(y===null){if(in_path&&mode==="Filled"){ctx.lineTo(x_scaled,height_px)}in_path=false;continue}if(y<min_value){bot_overflow=true;y=min_value}else{if(y>max_value){top_overflow=true;y=max_value}}if(mode==="Histogram"){y=Math.round(y/vertical_range*height_px);ctx.fillRect(x_scaled,y_zero,delta_x_px,-y)}else{if(mode==="Intensity"){var saturation=(y-min_value)/vertical_range,new_r=Math.round(pref_r+(255-pref_r)*(1-saturation)),new_g=Math.round(pref_g+(255-pref_g)*(1-saturation)),new_b=Math.round(pref_b+(255-pref_b)*(1-saturation));ctx.fillStyle="rgb("+new_r+","+new_g+","+new_b+")";ctx.fillRect(x_scaled,0,delta_x_px,height_px)}else{y=Math.round(height_px-(y-min_value)/vertical_range*height_px);if(in_path){ctx.lineTo(x_scaled,y)}else{in_path=true;if(mode==="Filled"){ctx.moveTo(x_scaled,height_px);ctx.lineTo(x_scaled,y)}else{ctx.moveTo(x_scaled,y)}}}}ctx.fillStyle=this.prefs.overflow_color;if(top_overflow||bot_overflow){var overflow_x;if(mode==="Histogram"||mode==="Intensity"){overflow_x=delta_x_px}else{x_scaled-=2;overflow_x=4}if(top_overflow){ctx.fillRect(x_scaled,0,overflow_x,3)}if(bot_overflow){ctx.fillRect(x_scaled,height_px-3,overflow_x,3)}}ctx.fillStyle=painter_color}if(mode==="Filled"){if(in_path){ctx.lineTo(x_scaled,y_zero);ctx.lineTo(0,y_zero)}ctx.fill()}else{ctx.stroke()}ctx.restore()};var FeaturePositionMapper=function(slot_height){this.feature_positions={};this.slot_height=slot_height;this.translation=0;this.y_translation=0};FeaturePositionMapper.prototype.map_feature_data=function(feature_data,slot,x_start,x_end){if(!this.feature_positions[slot]){this.feature_positions[slot]=[]}this.feature_positions[slot].push({data:feature_data,x_start:x_start,x_end:x_end})};FeaturePositionMapper.prototype.get_feature_data=function(x,y){var slot=Math.floor((y-this.y_translation)/this.slot_height),feature_dict;if(!this.feature_positions[slot]){return null}x+=this.translation;for(var i=0;i<this.feature_positions[slot].length;i++){feature_dict=this.feature_positions[slot][i];if(x>=feature_dict.x_start&&x<=feature_dict.x_end){return feature_dict.data}}};var FeaturePainter=function(data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler){Painter.call(this,data,view_start,view_end,prefs,mode);this.alpha_scaler=(alpha_scaler?alpha_scaler:new Scaler());this.height_scaler=(height_scaler?height_scaler:new Scaler());this.max_label_length=200};FeaturePainter.prototype.default_prefs={block_color:"#FFF",connector_color:"#FFF"};extend(FeaturePainter.prototype,{get_required_height:function(rows_required,width){var required_height=this.get_row_height(),y_scale=required_height,mode=this.mode;if(mode==="no_detail"||mode==="Squish"||mode==="Pack"){required_height=rows_required*y_scale}return required_height+this.get_top_padding(width)},get_top_padding:function(width){return 0},draw:function(ctx,width,height,w_scale,slots){var data=this.data,view_start=this.view_start,view_end=this.view_end;ctx.save();ctx.fillStyle=this.prefs.block_color;ctx.textAlign="right";var y_scale=this.get_row_height(),feature_mapper=new FeaturePositionMapper(y_scale),x_draw_coords,incomplete_features=[];for(var i=0,len=data.length;i<len;i++){var feature=data[i],feature_uid=feature[0],feature_start=feature[1],feature_end=feature[2],slot=(slots&&slots[feature_uid]!==undefined?slots[feature_uid]:null);if((this.mode==="Dense"||slot!==null)&&(feature_start<view_end&&feature_end>view_start)){x_draw_coords=this.draw_element(ctx,this.mode,feature,slot,view_start,view_end,w_scale,y_scale,width);feature_mapper.map_feature_data(feature,slot,x_draw_coords[0],x_draw_coords[1]);if(feature_start<view_start||feature_end>view_end){incomplete_features.push(feature)}}}ctx.restore();feature_mapper.y_translation=this.get_top_padding(width);return new DrawResults({incomplete_features:incomplete_features,feature_mapper:feature_mapper})},draw_element:function(ctx,mode,feature,slot,tile_low,tile_high,w_scale,y_scale,width){return[0,0]}});var DENSE_TRACK_HEIGHT=10,NO_DETAIL_TRACK_HEIGHT=3,SQUISH_TRACK_HEIGHT=5,PACK_TRACK_HEIGHT=10,NO_DETAIL_FEATURE_HEIGHT=1,DENSE_FEATURE_HEIGHT=9,SQUISH_FEATURE_HEIGHT=3,PACK_FEATURE_HEIGHT=9,LABEL_SPACING=2,CONNECTOR_COLOR="#ccc";var LinkedFeaturePainter=function(data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler){FeaturePainter.call(this,data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler);this.draw_background_connector=true;this.draw_individual_connectors=false};extend(LinkedFeaturePainter.prototype,FeaturePainter.prototype,{get_row_height:function(){var mode=this.mode,height;if(mode==="Dense"){height=DENSE_TRACK_HEIGHT}else{if(mode==="no_detail"){height=NO_DETAIL_TRACK_HEIGHT}else{if(mode==="Squish"){height=SQUISH_TRACK_HEIGHT}else{height=PACK_TRACK_HEIGHT}}}return height},draw_element:function(ctx,mode,feature,slot,tile_low,tile_high,w_scale,y_scale,width){var feature_uid=feature[0],feature_start=feature[1],feature_end=feature[2],feature_name=feature[3],feature_strand=feature[4],f_start=Math.floor(Math.max(0,(feature_start-tile_low-0.5)*w_scale)),f_end=Math.ceil(Math.min(width,Math.max(0,(feature_end-tile_low-0.5)*w_scale))),draw_start=f_start,draw_end=f_end,y_start=(mode==="Dense"?0:(0+slot))*y_scale+this.get_top_padding(width),thickness,y_start,thick_start=null,thick_end=null,block_color=(!feature_strand||feature_strand==="+"||feature_strand==="."?this.prefs.block_color:this.prefs.reverse_strand_color);label_color=this.prefs.label_color;ctx.globalAlpha=this.alpha_scaler.gen_val(feature);if(mode==="Dense"){slot=1}if(mode==="no_detail"){ctx.fillStyle=block_color;ctx.fillRect(f_start,y_start+5,f_end-f_start,NO_DETAIL_FEATURE_HEIGHT)}else{var feature_ts=feature[5],feature_te=feature[6],feature_blocks=feature[7],full_height=true;if(feature_ts&&feature_te){thick_start=Math.floor(Math.max(0,(feature_ts-tile_low)*w_scale));thick_end=Math.ceil(Math.min(width,Math.max(0,(feature_te-tile_low)*w_scale)))}var thin_height,thick_height;if(mode==="Squish"){thin_height=1;thick_height=SQUISH_FEATURE_HEIGHT;full_height=false}else{if(mode==="Dense"){thin_height=5;thick_height=DENSE_FEATURE_HEIGHT}else{thin_height=5;thick_height=PACK_FEATURE_HEIGHT}}if(!feature_blocks){ctx.fillStyle=block_color;ctx.fillRect(f_start,y_start+1,f_end-f_start,thick_height);if(feature_strand&&full_height){if(feature_strand==="+"){ctx.fillStyle=ctx.canvas.manager.get_pattern("right_strand_inv")}else{if(feature_strand==="-"){ctx.fillStyle=ctx.canvas.manager.get_pattern("left_strand_inv")}}ctx.fillRect(f_start,y_start+1,f_end-f_start,thick_height)}}else{var cur_y_start,cur_height;if(mode==="Squish"||mode==="Dense"){cur_y_start=y_start+Math.floor(SQUISH_FEATURE_HEIGHT/2)+1;cur_height=1}else{if(feature_strand){cur_y_start=y_start;cur_height=thick_height}else{cur_y_start+=(SQUISH_FEATURE_HEIGHT/2)+1;cur_height=1}}if(this.draw_background_connector){if(mode==="Squish"||mode==="Dense"){ctx.fillStyle=CONNECTOR_COLOR}else{if(feature_strand){if(feature_strand==="+"){ctx.fillStyle=ctx.canvas.manager.get_pattern("right_strand")}else{if(feature_strand==="-"){ctx.fillStyle=ctx.canvas.manager.get_pattern("left_strand")}}}else{ctx.fillStyle=CONNECTOR_COLOR}}ctx.fillRect(f_start,cur_y_start,f_end-f_start,cur_height)}var start_and_height;for(var k=0,k_len=feature_blocks.length;k<k_len;k++){var block=feature_blocks[k],block_start=Math.floor(Math.max(0,(block[0]-tile_low-0.5)*w_scale)),block_end=Math.ceil(Math.min(width,Math.max((block[1]-tile_low-0.5)*w_scale))),last_block_start,last_block_end;if(block_start>block_end){continue}ctx.fillStyle=block_color;ctx.fillRect(block_start,y_start+(thick_height-thin_height)/2+1,block_end-block_start,thin_height);if(thick_start!==undefined&&feature_te>feature_ts&&!(block_start>thick_end||block_end<thick_start)){var block_thick_start=Math.max(block_start,thick_start),block_thick_end=Math.min(block_end,thick_end);ctx.fillRect(block_thick_start,y_start+1,block_thick_end-block_thick_start,thick_height);if(feature_blocks.length===1&&mode==="Pack"){if(feature_strand==="+"){ctx.fillStyle=ctx.canvas.manager.get_pattern("right_strand_inv")}else{if(feature_strand==="-"){ctx.fillStyle=ctx.canvas.manager.get_pattern("left_strand_inv")}}if(block_thick_start+14<block_thick_end){block_thick_start+=2;block_thick_end-=2}ctx.fillRect(block_thick_start,y_start+1,block_thick_end-block_thick_start,thick_height)}}if(this.draw_individual_connectors&&last_block_start){this.draw_connector(ctx,last_block_start,last_block_end,block_start,block_end,y_start)}last_block_start=block_start;last_block_end=block_end}if(mode==="Pack"){ctx.globalAlpha=1;ctx.fillStyle="white";var hscale_factor=this.height_scaler.gen_val(feature),new_height=Math.ceil(thick_height*hscale_factor),ws_height=Math.round((thick_height-new_height)/2);if(hscale_factor!==1){ctx.fillRect(f_start,cur_y_start+1,f_end-f_start,ws_height);ctx.fillRect(f_start,cur_y_start+thick_height-ws_height+1,f_end-f_start,ws_height)}}}ctx.globalAlpha=1;if(feature_name&&mode==="Pack"&&feature_start>tile_low){ctx.fillStyle=label_color;if(tile_low===0&&f_start-ctx.measureText(feature_name).width<0){ctx.textAlign="left";ctx.fillText(feature_name,f_end+LABEL_SPACING,y_start+8,this.max_label_length);draw_end+=ctx.measureText(feature_name).width+LABEL_SPACING}else{ctx.textAlign="right";ctx.fillText(feature_name,f_start-LABEL_SPACING,y_start+8,this.max_label_length);draw_start-=ctx.measureText(feature_name).width+LABEL_SPACING}}}ctx.globalAlpha=1;return[draw_start,draw_end]}});var ReadPainter=function(data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler,ref_seq,base_color_fn){FeaturePainter.call(this,data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler);this.ref_seq=(ref_seq?ref_seq.data:null);this.base_color_fn=base_color_fn};extend(ReadPainter.prototype,FeaturePainter.prototype,{get_row_height:function(){var height,mode=this.mode;if(mode==="Dense"){height=DENSE_TRACK_HEIGHT}else{if(mode==="Squish"){height=SQUISH_TRACK_HEIGHT}else{height=PACK_TRACK_HEIGHT;if(this.prefs.show_insertions){height*=2}}}return height},_parse_cigar:function(cigar_str){var cigar_ops="MIDNSHP=X";var blocks=[[0,0]],cur_block=blocks[0],base_pos=0,parsed_cigar=_.map(cigar_str.match(/[0-9]+[MIDNSHP=X]/g),function(op){var op_len=parseInt(op.slice(0,-1),10),op_char=op.slice(-1);if(op_char==="N"){if(cur_block[1]!==0){cur_block=[base_pos+op_len,base_pos+op_len];blocks.push(cur_block)}}else{if("ISHP".indexOf(op_char)===-1){cur_block[1]+=op_len;base_pos+=op_len}}return[cigar_ops.indexOf(op_char),op_len]});return{blocks:blocks,cigar:parsed_cigar}},draw_read:function(ctx,mode,w_scale,y_start,tile_low,tile_high,feature_start,cigar,strand,read_seq){var update_base_offset=function(offset,cig_op,cig_len){if("M=NXD".indexOf(cig_op)!==-1){offset+=cig_len}return offset},update_seq_offset=function(offset,cig_op,cig_len){if("IX".indexOf(cig_op)!==-1){offset+=cig_len}return offset};ctx.textAlign="center";var tile_region=[tile_low,tile_high],base_offset=0,seq_offset=0,gap=Math.round(w_scale/2),char_width_px=ctx.canvas.manager.char_width_px,block_color=(strand==="+"?this.prefs.detail_block_color:this.prefs.reverse_strand_color),pack_mode=(mode==="Pack"),paint_utils=new ReadPainterUtils(ctx,(pack_mode?PACK_FEATURE_HEIGHT:SQUISH_FEATURE_HEIGHT),w_scale,mode),drawing_blocks=[];var draw_last=[];var t=this._parse_cigar(cigar);cigar=t.cigar;drawing_blocks=t.blocks;for(var i=0;i<drawing_blocks.length;i++){var block=drawing_blocks[i];if(is_overlap([feature_start+block[0],feature_start+block[1]],tile_region)){var s_start=Math.floor(Math.max(-0.5*w_scale,(feature_start+block[0]-tile_low-0.5)*w_scale)),s_end=Math.floor(Math.max(0,(feature_start+block[1]-tile_low-0.5)*w_scale));if(s_start===s_end){s_end+=1}ctx.fillStyle=block_color;ctx.fillRect(s_start,y_start+(pack_mode?1:4),s_end-s_start,(pack_mode?PACK_FEATURE_HEIGHT:SQUISH_FEATURE_HEIGHT))}}for(var cig_id=0,len=cigar.length;cig_id<len;cig_id++){var cig=cigar[cig_id],cig_op="MIDNSHP=X"[cig[0]],cig_len=cig[1];var seq_start=feature_start+base_offset,s_start=Math.floor(Math.max(-0.5*w_scale,(seq_start-tile_low-0.5)*w_scale)),s_end=Math.floor(Math.max(0,(seq_start+cig_len-tile_low-0.5)*w_scale));if(!is_overlap([seq_start,seq_start+cig_len],tile_region)){base_offset=update_base_offset(base_offset,cig_op,cig_len);seq_offset=update_seq_offset(seq_offset,cig_op,cig_len);continue}if(s_start===s_end){s_end+=1}switch(cig_op){case"H":case"S":case"P":break;case"M":base_offset+=cig_len;break;case"=":case"X":var cur_seq="";if(cig_op==="X"){cur_seq=read_seq.slice(seq_offset,seq_offset+cig_len)}else{if(this.ref_seq){cur_seq=this.ref_seq.slice(Math.max(0,seq_start-tile_low),Math.min(seq_start-tile_low+cig_len,tile_high-tile_low))}}var start_pos=Math.max(seq_start,tile_low);for(var c=0;c<cur_seq.length;c++){if(cur_seq&&!this.prefs.show_differences||cig_op==="X"){var c_start=Math.floor(Math.max(0,(start_pos+c-tile_low)*w_scale));ctx.fillStyle=this.base_color_fn(cur_seq[c]);if(pack_mode&&w_scale>char_width_px){ctx.fillText(cur_seq[c],c_start,y_start+9)}else{if(w_scale>0.05){ctx.fillRect(c_start-gap,y_start+(pack_mode?1:4),Math.max(1,Math.round(w_scale)),(pack_mode?PACK_FEATURE_HEIGHT:SQUISH_FEATURE_HEIGHT))}}}}if(cig_op==="X"){seq_offset+=cig_len}base_offset+=cig_len;break;case"N":ctx.fillStyle=CONNECTOR_COLOR;ctx.fillRect(s_start,y_start+5,s_end-s_start,1);base_offset+=cig_len;break;case"D":paint_utils.draw_deletion(s_start,y_start+(pack_mode?1:4),cig_len);base_offset+=cig_len;break;case"I":var insert_x_coord=s_start-gap;if(is_overlap([seq_start,seq_start+cig_len],tile_region)){var seq=read_seq.slice(seq_offset,seq_offset+cig_len);if(this.prefs.show_insertions){var x_center=s_start-(s_end-s_start)/2;if((mode==="Pack"||this.mode==="Auto")&&read_seq!==undefined&&w_scale>char_width_px){ctx.fillStyle="yellow";ctx.fillRect(x_center-gap,y_start-9,s_end-s_start,9);draw_last[draw_last.length]={type:"triangle",data:[insert_x_coord,y_start+4,5]};ctx.fillStyle=CONNECTOR_COLOR;switch(compute_overlap([seq_start,seq_start+cig_len],tile_region)){case (OVERLAP_START):seq=seq.slice(tile_low-seq_start);break;case (OVERLAP_END):seq=seq.slice(0,seq_start-tile_high);break;case (CONTAINED_BY):break;case (CONTAINS):seq=seq.slice(tile_low-seq_start,seq_start-tile_high);break}for(var c=0,str_len=seq.length;c<str_len;c++){var c_start=Math.floor(Math.max(0,(seq_start+c-tile_low)*w_scale));ctx.fillText(seq[c],c_start-(s_end-s_start)/2,y_start)}}else{ctx.fillStyle="yellow";ctx.fillRect(x_center,y_start+(this.mode!=="Dense"?2:5),s_end-s_start,(mode!=="Dense"?SQUISH_FEATURE_HEIGHT:DENSE_FEATURE_HEIGHT))}}else{if((mode==="Pack"||this.mode==="Auto")&&read_seq!==undefined&&w_scale>char_width_px){draw_last.push({type:"text",data:[seq.length,insert_x_coord,y_start+9]})}else{}}}seq_offset+=cig_len;break}}ctx.fillStyle="yellow";var item,type,data;for(var i=0;i<draw_last.length;i++){item=draw_last[i];type=item.type;data=item.data;if(type==="text"){ctx.save();ctx.font="bold "+ctx.font;ctx.fillText(data[0],data[1],data[2]);ctx.restore()}else{if(type==="triangle"){drawDownwardEquilateralTriangle(ctx,data[0],data[1],data[2])}}}},draw_element:function(ctx,mode,feature,slot,tile_low,tile_high,w_scale,y_scale,width){var feature_uid=feature[0],feature_start=feature[1],feature_end=feature[2],feature_name=feature[3],f_start=Math.floor(Math.max(-0.5*w_scale,(feature_start-tile_low-0.5)*w_scale)),f_end=Math.ceil(Math.min(width,Math.max(0,(feature_end-tile_low-0.5)*w_scale))),y_start=(mode==="Dense"?0:(0+slot))*y_scale,label_color=this.prefs.label_color;if(feature[5] instanceof Array){var connector=true;if(feature[4][1]>=tile_low&&feature[4][0]<=tile_high&&feature[4][2]){this.draw_read(ctx,mode,w_scale,y_start,tile_low,tile_high,feature[4][0],feature[4][2],feature[4][3],feature[4][4])}else{connector=false}if(feature[5][1]>=tile_low&&feature[5][0]<=tile_high&&feature[5][2]){this.draw_read(ctx,mode,w_scale,y_start,tile_low,tile_high,feature[5][0],feature[5][2],feature[5][3],feature[5][4])}else{connector=false}var b1_end=Math.ceil(Math.min(width,Math.max(-0.5*w_scale,(feature[4][1]-tile_low-0.5)*w_scale))),b2_start=Math.floor(Math.max(-0.5*w_scale,(feature[5][0]-tile_low-0.5)*w_scale));if(connector&&b2_start>b1_end){ctx.fillStyle=CONNECTOR_COLOR;dashedLine(ctx,b1_end,y_start+5,b2_start,y_start+5)}}else{this.draw_read(ctx,mode,w_scale,y_start,tile_low,tile_high,feature_start,feature[4],feature[5],feature[6])}if(mode==="Pack"&&feature_start>=tile_low&&feature_name!=="."){ctx.fillStyle=this.prefs.label_color;if(tile_low===0&&f_start-ctx.measureText(feature_name).width<0){ctx.textAlign="left";ctx.fillText(feature_name,f_end+LABEL_SPACING,y_start+8,this.max_label_length)}else{ctx.textAlign="right";ctx.fillText(feature_name,f_start-LABEL_SPACING,y_start+8,this.max_label_length)}}return[0,0]}});var ArcLinkedFeaturePainter=function(data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler){LinkedFeaturePainter.call(this,data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler);this.longest_feature_length=this.calculate_longest_feature_length();this.draw_background_connector=false;this.draw_individual_connectors=true};extend(ArcLinkedFeaturePainter.prototype,FeaturePainter.prototype,LinkedFeaturePainter.prototype,{calculate_longest_feature_length:function(){var longest_feature_length=0;for(var i=0,len=this.data.length;i<len;i++){var feature=this.data[i],feature_start=feature[1],feature_end=feature[2];longest_feature_length=Math.max(longest_feature_length,feature_end-feature_start)}return longest_feature_length},get_top_padding:function(width){var view_range=this.view_end-this.view_start,w_scale=width/view_range;return Math.min(128,Math.ceil((this.longest_feature_length/2)*w_scale))},draw_connector:function(ctx,block1_start,block1_end,block2_start,block2_end,y_start){var x_center=(block1_end+block2_start)/2,radius=block2_start-x_center;var angle1=Math.PI,angle2=0;if(radius>0){ctx.beginPath();ctx.arc(x_center,y_start,block2_start-x_center,Math.PI,0);ctx.stroke()}}});var Color=function(rgb,a){if(Array.isArray(rgb)){this.rgb=rgb}else{if(rgb.length==6){this.rgb=rgb.match(/.{2}/g).map(function(c){return parseInt(c,16)})}else{if(rgb.length==7){this.rgb=rgb.substring(1,7).match(/.{2}/g).map(function(c){return parseInt(c,16)})}else{this.rgb=rgb.split("").map(function(c){return parseInt(c+c,16)})}}}this.alpha=typeof(a)==="number"?a:1};Color.prototype={eval:function(){return this},toCSS:function(){if(this.alpha<1){return"rgba("+this.rgb.map(function(c){return Math.round(c)}).concat(this.alpha).join(", ")+")"}else{return"#"+this.rgb.map(function(i){i=Math.round(i);i=(i>255?255:(i<0?0:i)).toString(16);return i.length===1?"0"+i:i}).join("")}},toHSL:function(){var r=this.rgb[0]/255,g=this.rgb[1]/255,b=this.rgb[2]/255,a=this.alpha;var max=Math.max(r,g,b),min=Math.min(r,g,b);var h,s,l=(max+min)/2,d=max-min;if(max===min){h=s=0}else{s=l>0.5?d/(2-max-min):d/(max+min);switch(max){case r:h=(g-b)/d+(g<b?6:0);break;case g:h=(b-r)/d+2;break;case b:h=(r-g)/d+4;break}h/=6}return{h:h*360,s:s,l:l,a:a}},toARGB:function(){var argb=[Math.round(this.alpha*255)].concat(this.rgb);return"#"+argb.map(function(i){i=Math.round(i);i=(i>255?255:(i<0?0:i)).toString(16);return i.length===1?"0"+i:i}).join("")},mix:function(color2,weight){color1=this;var p=weight;var w=p*2-1;var a=color1.toHSL().a-color2.toHSL().a;var w1=(((w*a==-1)?w:(w+a)/(1+w*a))+1)/2;var w2=1-w1;var rgb=[color1.rgb[0]*w1+color2.rgb[0]*w2,color1.rgb[1]*w1+color2.rgb[1]*w2,color1.rgb[2]*w1+color2.rgb[2]*w2];var alpha=color1.alpha*p+color2.alpha*(1-p);return new Color(rgb,alpha)}};var LinearRamp=function(start_color,end_color,start_value,end_value){this.start_color=new Color(start_color);this.end_color=new Color(end_color);this.start_value=start_value;this.end_value=end_value;this.value_range=end_value-start_value};LinearRamp.prototype.map_value=function(value){value=Math.max(value,this.start_value);value=Math.min(value,this.end_value);value=(value-this.start_value)/this.value_range;return this.start_color.mix(this.end_color,1-value).toCSS()};var SplitRamp=function(start_color,middle_color,end_color,start_value,end_value){this.positive_ramp=new LinearRamp(middle_color,end_color,0,end_value);this.negative_ramp=new LinearRamp(middle_color,start_color,0,-start_value);this.start_value=start_value;this.end_value=end_value};SplitRamp.prototype.map_value=function(value){value=Math.max(value,this.start_value);value=Math.min(value,this.end_value);if(value>=0){return this.positive_ramp.map_value(value)}else{return this.negative_ramp.map_value(-value)}};var DiagonalHeatmapPainter=function(data,view_start,view_end,prefs,mode){Painter.call(this,data,view_start,view_end,prefs,mode);var i,len;if(this.prefs.min_value===undefined){var min_value=Infinity;for(i=0,len=this.data.length;i<len;i++){min_value=Math.min(min_value,this.data[i][5])}this.prefs.min_value=min_value}if(this.prefs.max_value===undefined){var max_value=-Infinity;for(i=0,len=this.data.length;i<len;i++){max_value=Math.max(max_value,this.data[i][5])}this.prefs.max_value=max_value}};DiagonalHeatmapPainter.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Heatmap",pos_color:"#FF8C00",neg_color:"#4169E1"};DiagonalHeatmapPainter.prototype.draw=function(ctx,width,height,w_scale){var min_value=this.prefs.min_value,max_value=this.prefs.max_value,value_range=max_value-min_value,height_px=height,view_start=this.view_start,mode=this.mode,data=this.data,invsqrt2=1/Math.sqrt(2);var ramp=(new SplitRamp(this.prefs.neg_color,"#FFFFFF",this.prefs.pos_color,min_value,max_value));var d,s1,e1,s2,e2,value;var scale=function(p){return(p-view_start)*w_scale};ctx.save();ctx.rotate(-45*Math.PI/180);ctx.scale(invsqrt2,invsqrt2);for(var i=0,len=data.length;i<len;i++){d=data[i];s1=scale(d[1]);e1=scale(d[2]);s2=scale(d[4]);e2=scale(d[5]);value=d[6];ctx.fillStyle=(ramp.map_value(value));ctx.fillRect(s1,s2,(e1-s1),(e2-s2))}ctx.restore()};var ReadPainterUtils=function(ctx,row_height,px_per_base,mode){this.ctx=ctx;this.row_height=row_height;this.px_per_base=px_per_base;this.draw_details=(mode==="Pack"||mode==="Auto")&&(px_per_base>=ctx.canvas.manager.char_width_px);this.delete_details_thickness=0.2};extend(ReadPainterUtils.prototype,{draw_deletion:function(x,y,len){this.ctx.fillStyle="black";var thickness=(this.draw_details?this.delete_details_thickness:1)*this.row_height;y+=0.5*(this.row_height-thickness);this.ctx.fillRect(x,y,len*this.px_per_base,thickness)}});var VariantPainter=function(data,view_start,view_end,prefs,mode,base_color_fn){Painter.call(this,data,view_start,view_end,prefs,mode);this.base_color_fn=base_color_fn;this.divider_height=1};extend(VariantPainter.prototype,Painter.prototype,{get_row_height:function(){var mode=this.mode,height;if(mode==="Dense"){height=DENSE_TRACK_HEIGHT}else{if(mode==="Squish"){height=SQUISH_TRACK_HEIGHT}else{height=PACK_TRACK_HEIGHT}}return height},get_required_height:function(num_samples){var height=this.prefs.summary_height;if(num_samples>1&&this.prefs.show_sample_data){height+=this.divider_height+num_samples*this.get_row_height()}return height},draw:function(ctx,width,height,w_scale){ctx.save();var get_deletion_info=function(ref,alt){var ref_len=ref.length,alt_len=alt.length,start=0,len=1,is_delete=false;if(alt==="-"){is_delete=true;len=ref.length}else{if(ref.indexOf(alt)===0&&ref_len>alt_len){is_delete=true;len=ref_len=alt_len;start+=alt_len}}return(is_delete?{start:start,len:len}:null)};var locus_data,pos,id,ref,alt,qual,filter,sample_gts,allele_counts,variant,draw_x_start,char_x_start,draw_y_start,genotype,base_px=Math.max(1,Math.floor(w_scale)),num_samples=(this.data.length?this.data[0][7].split(",").length:0),row_height=(this.mode==="Squish"?SQUISH_TRACK_HEIGHT:PACK_TRACK_HEIGHT),feature_height=(w_scale<0.1?row_height:(this.mode==="Squish"?SQUISH_FEATURE_HEIGHT:PACK_FEATURE_HEIGHT)),draw_summary=true,paint_utils=new ReadPainterUtils(ctx,row_height,w_scale,this.mode),j;if(num_samples===1){row_height=feature_height=(w_scale<ctx.canvas.manager.char_width_px?this.prefs.summary_height:row_height);draw_summary=false}if(this.prefs.show_sample_data&&draw_summary){ctx.fillStyle="#F3F3F3";ctx.globalAlpha=1;ctx.fillRect(0,this.prefs.summary_height-this.divider_height,width,this.divider_height)}ctx.textAlign="center";for(var i=0;i<this.data.length;i++){locus_data=this.data[i];pos=locus_data[1];ref=locus_data[3];alt=[locus_data[4].split(",")];sample_gts=locus_data[7].split(",");allele_counts=locus_data.slice(8);alt=_.map(_.flatten(alt),function(a){var type,alt_info={},delete_info=get_deletion_info(ref,a);if(delete_info){type="deletion";_.extend(alt_info,delete_info)}else{type="snp"}return _.extend(alt_info,{type:type,value:a,})});if(pos<this.view_start||pos>this.view_end){continue}draw_x_start=Math.floor(Math.max(-0.5*w_scale,(pos-this.view_start-0.5)*w_scale));char_x_start=Math.floor(Math.max(0,(pos-this.view_start)*w_scale));if(draw_summary){ctx.fillStyle="#999999";ctx.globalAlpha=1;ctx.fillRect(draw_x_start,0,base_px,this.prefs.summary_height);draw_y_start=this.prefs.summary_height;for(j=0;j<alt.length;j++){ctx.fillStyle=(alt[j].type==="deletion"?"black":this.base_color_fn(alt[j].value));allele_frac=allele_counts/sample_gts.length;draw_height=Math.ceil(this.prefs.summary_height*allele_frac);ctx.fillRect(draw_x_start,draw_y_start-draw_height,base_px,draw_height);draw_y_start-=draw_height}}if(!this.prefs.show_sample_data){continue}draw_y_start=(draw_summary?this.prefs.summary_height+this.divider_height:0);for(j=0;j<sample_gts.length;j++,draw_y_start+=row_height){genotype=(sample_gts[j]?sample_gts[j].split(/\/|\|/):["0","0"]);variant=null;if(genotype[0]===genotype[1]){if(genotype[0]==="."){}else{if(genotype[0]!=="0"){variant=alt[parseInt(genotype[0],10)-1];ctx.globalAlpha=1}}}else{variant=(genotype[0]!=="0"?genotype[0]:genotype[1]);variant=alt[parseInt(variant,10)-1];ctx.globalAlpha=0.5}if(variant){if(variant.type==="snp"){var snp=variant.value;ctx.fillStyle=this.base_color_fn(snp);if(paint_utils.draw_details){ctx.fillText(snp,char_x_start,draw_y_start+row_height)}else{ctx.fillRect(draw_x_start,draw_y_start+1,base_px,feature_height)}}else{if(variant.type==="deletion"){paint_utils.draw_deletion(draw_x_start+base_px*variant.start,draw_y_start+1,variant.len)}else{}}}}}ctx.restore()}});return{Scaler:Scaler,LinePainter:LinePainter,LinkedFeaturePainter:LinkedFeaturePainter,ReadPainter:ReadPainter,ArcLinkedFeaturePainter:ArcLinkedFeaturePainter,DiagonalHeatmapPainter:DiagonalHeatmapPainter,VariantPainter:VariantPainter}});
\ No newline at end of file
diff -r 51643642564f214f09c2eff32307360f5e09dfaf -r 776e13962bbc861a94242e142e73278c9499dc70 static/scripts/packed/viz/trackster/tracks.js
--- a/static/scripts/packed/viz/trackster/tracks.js
+++ b/static/scripts/packed/viz/trackster/tracks.js
@@ -1,1 +1,1 @@
-define(["libs/underscore","viz/visualization","viz/trackster/util","viz/trackster/slotting","viz/trackster/painters","viz/trackster/filters","mvc/data","mvc/tools","utils/config"],function(aa,w,j,s,J,h,W,P,R){var o=aa.extend;var l={};var i=function(ab,ac){l[ab.attr("id")]=ac};var k=function(ab,ac,ae,ad){ae=".group";l[ab.attr("id")]=ad;ab.bind("drag",{handle:"."+ac,relative:true},function(am,an){var al=$(this),aq=$(this).parent(),ai=aq.children(".track,.group"),ak=l[$(this).attr("id")],ah,ag,ao,af,aj;ag=$(this).parents(ae);if(ag.length!==0){ao=ag.position().top;af=ao+ag.outerHeight();var ap=l[ag.attr("id")];if(an.offsetY<ao){$(this).insertBefore(ag);ap.remove_drawable(ak);ap.container.add_drawable_before(ak,ap);return}else{if(an.offsetY>af){$(this).insertAfter(ag);ap.remove_drawable(ak);ap.container.add_drawable(ak);return}}}ag=null;for(aj=0;aj<ai.length;aj++){ah=$(ai.get(aj));ao=ah.position().top;af=ao+ah.outerHeight();if(ah.is(ae)&&this!==ah.get(0)&&an.offsetY>=ao&&an.offsetY<=af){if(an.offsetY-ao<af-an.offsetY){ah.find(".content-div").prepend(this)}else{ah.find(".content-div").append(this)}if(ak.container){ak.container.remove_drawable(ak)}l[ah.attr("id")].add_drawable(ak);return}}for(aj=0;aj<ai.length;aj++){ah=$(ai.get(aj));if(an.offsetY<ah.position().top&&!(ah.hasClass("reference-track")||ah.hasClass("intro"))){break}}if(aj===ai.length){if(this!==ai.get(aj-1)){aq.append(this);l[aq.attr("id")].move_drawable(ak,aj)}}else{if(this!==ai.get(aj)){$(this).insertBefore(ai.get(aj));l[aq.attr("id")].move_drawable(ak,(an.deltaY>0?aj-1:aj))}}}).bind("dragstart",function(){$(this).addClass("dragging")}).bind("dragend",function(){$(this).removeClass("dragging")})};var D=20,z=100,G=12000,Q=400,I=5000,v=100,m="Cannot display dataset due to an error. ",H="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",E="No data for this chrom/contig.",u="Preparing data. This can take a while for a large dataset. If the visualization is saved and closed, preparation will continue in the background.",x="Tool cannot be rerun: ",a="Loading data...",T="Ready for display",O=10,F=20,A=["Histogram","Line","Filled","Intensity"];function U(ac,ab){if(!ab){ab=0}var ad=Math.pow(10,ab);return Math.round(ac*ad)/ad}var p=function(ac,ab,ae){if(!p.id_counter){p.id_counter=0}this.id=p.id_counter++;this.view=ac;this.container=ab;this.drag_handle_class=ae.drag_handle_class;this.is_overview=false;this.action_icons={};this.config=R.ConfigSettingCollection.from_models_and_saved_values(this.config_params,ae.prefs);if(!this.config.get_value("name")){this.config.set_value("name",ae.name)}if(this.config_onchange){this.config.on("change",this.config_onchange,this)}this.container_div=this.build_container_div();this.header_div=this.build_header_div();if(this.header_div){this.container_div.append(this.header_div);this.icons_div=$("<div/>").addClass("track-icons").hide().appendTo(this.header_div);this.build_action_icons(this.action_icons_def);this.header_div.append($("<div style='clear: both'/>"));this.header_div.dblclick(function(af){af.stopPropagation()});var ad=this;this.container_div.hover(function(){ad.icons_div.show()},function(){ad.icons_div.hide()});$("<div style='clear: both'/>").appendTo(this.container_div)}};p.prototype.action_icons_def=[{name:"toggle_icon",title:"Hide/show content",css_class:"toggle",on_click_fn:function(ab){if(ab.config.get_value("content_visible")){ab.action_icons.toggle_icon.addClass("toggle-expand").removeClass("toggle");ab.hide_contents();ab.config.set_value("content_visible",false)}else{ab.action_icons.toggle_icon.addClass("toggle").removeClass("toggle-expand");ab.config.set_value("content_visible",true);ab.show_contents()}}},{name:"settings_icon",title:"Edit settings",css_class:"gear",on_click_fn:function(ac){var ab=new R.ConfigSettingCollectionView({collection:ac.config});ab.render_in_modal("Configure Track")}},{name:"remove_icon",title:"Remove",css_class:"remove-icon",on_click_fn:function(ab){$(".tooltip").remove();ab.remove()}}];o(p.prototype,{config_params:[{key:"name",label:"Name",type:"text",default_value:""},{key:"content_visible",type:"bool",default_value:true,hidden:true}],config_onchange:function(){},init:function(){},changed:function(){this.view.changed()},can_draw:function(){if(this.enabled&&this.config.get_value("content_visible")){return true}return false},request_draw:function(){},_draw:function(ab){},to_dict:function(){},set_name:function(ab){this.old_name=this.config.get_value("name");this.config.set_value("name",ab);this.name_div.text(ab)},revert_name:function(){if(this.old_name){this.config.set_value("name",this.old_name);this.name_div.text(this.old_name)}},remove:function(){this.changed();this.container.remove_drawable(this);var ab=this.view;this.container_div.hide(0,function(){$(this).remove();ab.update_intro_div()})},build_container_div:function(){},build_header_div:function(){},add_action_icon:function(ac,ah,ag,af,ab,ae){var ad=this;this.action_icons[ac]=$("<a/>").attr("title",ah).addClass("icon-button").addClass(ag).tooltip().click(function(){af(ad)}).appendTo(this.icons_div);if(ae){this.action_icons[ac].hide()}},build_action_icons:function(ab){var ad;for(var ac=0;ac<ab.length;ac++){ad=ab[ac];this.add_action_icon(ad.name,ad.title,ad.css_class,ad.on_click_fn,ad.prepend,ad.hide)}},update_icons:function(){},hide_contents:function(){},show_contents:function(){},get_drawables:function(){}});var y=function(ac,ab,ad){p.call(this,ac,ab,ad);this.obj_type=ad.obj_type;this.drawables=[]};o(y.prototype,p.prototype,{unpack_drawables:function(ad){this.drawables=[];var ac;for(var ab=0;ab<ad.length;ab++){ac=n(ad[ab],this.view,this);this.add_drawable(ac)}},init:function(){for(var ab=0;ab<this.drawables.length;ab++){this.drawables[ab].init()}},_draw:function(ab){for(var ac=0;ac<this.drawables.length;ac++){this.drawables[ac]._draw(ab)}},to_dict:function(){var ac=[];for(var ab=0;ab<this.drawables.length;ab++){ac.push(this.drawables[ab].to_dict())}return{prefs:this.config.to_key_value_dict(),obj_type:this.obj_type,drawables:ac}},add_drawable:function(ab){this.drawables.push(ab);ab.container=this;this.changed()},add_drawable_before:function(ad,ab){this.changed();var ac=this.drawables.indexOf(ab);if(ac!==-1){this.drawables.splice(ac,0,ad);return true}return false},replace_drawable:function(ad,ab,ac){var ae=this.drawables.indexOf(ad);if(ae!==-1){this.drawables[ae]=ab;if(ac){ad.container_div.replaceWith(ab.container_div)}this.changed()}return ae},remove_drawable:function(ac){var ab=this.drawables.indexOf(ac);if(ab!==-1){this.drawables.splice(ab,1);ac.container=null;this.changed();return true}return false},move_drawable:function(ac,ad){var ab=this.drawables.indexOf(ac);if(ab!==-1){this.drawables.splice(ab,1);this.drawables.splice(ad,0,ac);this.changed();return true}return false},get_drawables:function(){return this.drawables},get_tracks:function(ae){var ab=this.drawables.slice(0),ac=[],ad;while(ab.length!==0){ad=ab.shift();if(ad instanceof ae){ac.push(ad)}else{if(ad.drawables){ab=ab.concat(ad.drawables)}}}return ac}});var N=function(ac,ab,ae){o(ae,{obj_type:"DrawableGroup",drag_handle_class:"group-handle"});y.call(this,ac,ab,ae);this.content_div=$("<div/>").addClass("content-div").attr("id","group_"+this.id+"_content_div").appendTo(this.container_div);i(this.container_div,this);i(this.content_div,this);k(this.container_div,this.drag_handle_class,".group",this);this.filters_manager=new h.FiltersManager(this);this.header_div.after(this.filters_manager.parent_div);this.saved_filters_managers=[];if("drawables" in ae){this.unpack_drawables(ae.drawables)}if("filters" in ae){var ad=this.filters_manager;this.filters_manager=new h.FiltersManager(this,ae.filters);ad.parent_div.replaceWith(this.filters_manager.parent_div);if(ae.filters.visible){this.setup_multitrack_filtering()}}};o(N.prototype,p.prototype,y.prototype,{action_icons_def:[p.prototype.action_icons_def[0],p.prototype.action_icons_def[1],{name:"composite_icon",title:"Show composite track",css_class:"layers-stack",on_click_fn:function(ab){$(".tooltip").remove();ab.show_composite_track()}},{name:"filters_icon",title:"Filters",css_class:"filters-icon",on_click_fn:function(ab){if(ab.filters_manager.visible()){ab.filters_manager.clear_filters();ab._restore_filter_managers()}else{ab.setup_multitrack_filtering();ab.request_draw({clear_tile_cache:true})}ab.filters_manager.toggle()}},p.prototype.action_icons_def[2]],build_container_div:function(){var ab=$("<div/>").addClass("group").attr("id","group_"+this.id);if(this.container){this.container.content_div.append(ab)}return ab},build_header_div:function(){var ab=$("<div/>").addClass("track-header");ab.append($("<div/>").addClass(this.drag_handle_class));this.name_div=$("<div/>").addClass("track-name").text(this.config.get_value("name")).appendTo(ab);return ab},hide_contents:function(){this.tiles_div.hide()},show_contents:function(){this.tiles_div.show();this.request_draw()},update_icons:function(){var ad=this.drawables.length;if(ad===0){this.action_icons.composite_icon.hide();this.action_icons.filters_icon.hide()}else{if(ad===1){if(this.drawables[0] instanceof e){this.action_icons.composite_icon.show()}this.action_icons.filters_icon.hide()}else{var ak,aj,ah,an=true,af=this.drawables[0].get_type(),ab=0;for(ak=0;ak<ad;ak++){ah=this.drawables[ak];if(ah.get_type()!==af){can_composite=false;break}if(ah instanceof c){ab++}}if(an&&this.drawables[0] instanceof g){this.action_icons.composite_icon.show()}else{this.action_icons.composite_icon.hide();$(".tooltip").remove()}if(ab>1&&ab===this.drawables.length){var ao={},ac;ah=this.drawables[0];for(aj=0;aj<ah.filters_manager.filters.length;aj++){ac=ah.filters_manager.filters[aj];ao[ac.name]=[ac]}for(ak=1;ak<this.drawables.length;ak++){ah=this.drawables[ak];for(aj=0;aj<ah.filters_manager.filters.length;aj++){ac=ah.filters_manager.filters[aj];if(ac.name in ao){ao[ac.name].push(ac)}}}this.filters_manager.remove_all();var ae,ag,ai,al;for(var am in ao){ae=ao[am];if(ae.length===ab){ag=new h.NumberFilter({name:ae[0].name,index:ae[0].index});this.filters_manager.add_filter(ag)}}if(this.filters_manager.filters.length>0){this.action_icons.filters_icon.show()}else{this.action_icons.filters_icon.hide()}}else{this.action_icons.filters_icon.hide()}}}},_restore_filter_managers:function(){for(var ab=0;ab<this.drawables.length;ab++){this.drawables[ab].filters_manager=this.saved_filters_managers[ab]}this.saved_filters_managers=[]},setup_multitrack_filtering:function(){if(this.filters_manager.filters.length>0){this.saved_filters_managers=[];for(var ab=0;ab<this.drawables.length;ab++){drawable=this.drawables[ab];this.saved_filters_managers.push(drawable.filters_manager);drawable.filters_manager=this.filters_manager}}this.filters_manager.init_filters()},show_composite_track:function(){var ac=new e(this.view,this.view,{name:this.config.get_value("name"),drawables:this.drawables});var ab=this.container.replace_drawable(this,ac,true);ac.request_draw()},add_drawable:function(ab){y.prototype.add_drawable.call(this,ab);this.update_icons()},remove_drawable:function(ab){y.prototype.remove_drawable.call(this,ab);this.update_icons()},to_dict:function(){if(this.filters_manager.visible()){this._restore_filter_managers()}var ab=o(y.prototype.to_dict.call(this),{filters:this.filters_manager.to_dict()});if(this.filters_manager.visible()){this.setup_multitrack_filtering()}return ab},request_draw:function(ab){aa.each(this.drawables,function(ac){ac.request_draw(ab)})}});var X=Backbone.View.extend({initialize:function(ab){o(ab,{obj_type:"View"});y.call(this,"View",ab.container,ab);this.chrom=null;this.vis_id=ab.vis_id;this.dbkey=ab.dbkey;this.label_tracks=[];this.tracks_to_be_redrawn=[];this.max_low=0;this.max_high=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.load_chroms_deferred=null;this.render();this.canvas_manager=new w.CanvasManager(this.container.get(0).ownerDocument);this.reset();this.config=R.ConfigSettingCollection.from_models_and_saved_values([{key:"name",label:"Name",type:"text",default_value:""},{key:"a_color",label:"A Color",type:"color",default_value:"#FF0000"},{key:"c_color",label:"C Color",type:"color",default_value:"#00FF00"},{key:"g_color",label:"G Color",type:"color",default_value:"#0000FF"},{key:"t_color",label:"T Color",type:"color",default_value:"#FF00FF"},{key:"n_color",label:"N Color",type:"color",default_value:"#AAAAAA"}],{name:ab.name})},render:function(){this.requested_redraw=false;var ad=this.container,ab=this;this.top_container=$("<div/>").addClass("top-container").appendTo(ad);this.browser_content_div=$("<div/>").addClass("content").appendTo(ad);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(ad);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);this.viewport_container=$("<div/>").addClass("viewport-container").attr("id","viewport-container").appendTo(this.browser_content_div);this.content_div=this.viewport_container;i(this.viewport_container,ab);this.intro_div=$("<div/>").addClass("intro").appendTo(this.viewport_container).hide();var ae=$("<div/>").text("Add Datasets to Visualization").addClass("action-button").appendTo(this.intro_div).click(function(){w.select_datasets(galaxy_config.root+"visualization/list_current_history_datasets",galaxy_config.root+"api/datasets",{"f-dbkey":ab.dbkey},function(af){aa.each(af,function(ag){ab.add_drawable(n(ag,ab,ab))})})});this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("trackster-nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("trackster-nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.bottom_container);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_close=$("<a/>").attr("title","Close overview").addClass("icon-button overview-close tooltip").hide().appendTo(this.overview_viewport);this.overview_highlight=$("<div/>").addClass("overview-highlight").hide().appendTo(this.overview_viewport);this.overview_box_background=$("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_select=$("<select/>").attr({name:"chrom"}).addClass("chrom-nav").append("<option value=''>Loading</option>").appendTo(this.nav_controls);var ac=function(af){if(af.type==="focusout"||(af.keyCode||af.which)===13||(af.keyCode||af.which)===27){if((af.keyCode||af.which)!==27){ab.go_to($(this).val())}$(this).hide();$(this).val("");ab.location_span.show();ab.chrom_select.show()}af.stopPropagation()};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",ac).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").attr("title","Click to change location").tooltip({placement:"bottom"}).appendTo(this.nav_controls);this.location_span.click(function(){ab.location_span.hide();ab.chrom_select.hide();ab.nav_input.val(ab.chrom+":"+ab.low+"-"+ab.high);ab.nav_input.css("display","inline-block");ab.nav_input.select();ab.nav_input.focus();ab.nav_input.autocomplete({source:function(ah,af){var ai=[],ag=$.map(ab.get_tracks(c),function(aj){return aj.data_manager.search_features(ah.term).success(function(ak){ai=ai.concat(ak)})});$.when.apply($,ag).done(function(){af($.map(ai,function(aj){return{label:aj[0],value:aj[1]}}))})}})});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.nav_controls)}this.zo_link=$("<a/>").attr("id","zoom-out").attr("title","Zoom out").tooltip({placement:"bottom"}).click(function(){ab.zoom_out()}).appendTo(this.nav_controls);this.zi_link=$("<a/>").attr("id","zoom-in").attr("title","Zoom in").tooltip({placement:"bottom"}).click(function(){ab.zoom_in()}).appendTo(this.nav_controls);this.load_chroms_deferred=this.load_chroms({low:0});this.chrom_select.bind("change",function(){ab.change_chrom(ab.chrom_select.val())});this.browser_content_div.click(function(af){$(this).find("input").trigger("blur")});this.browser_content_div.bind("dblclick",function(af){ab.zoom_in(af.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(af,ag){this.current_x=ag.offsetX}).bind("drag",function(af,ah){var ai=ah.offsetX-this.current_x;this.current_x=ah.offsetX;var ag=Math.round(ai/ab.viewport_container.width()*(ab.max_high-ab.max_low));ab.move_delta(-ag)});this.overview_close.click(function(){ab.reset_overview()});this.viewport_container.bind("draginit",function(af,ag){if(af.clientX>ab.viewport_container.width()-16){return false}}).bind("dragstart",function(af,ag){ag.original_low=ab.low;ag.current_height=af.clientY;ag.current_x=ag.offsetX}).bind("drag",function(ah,aj){var af=$(this);var ak=aj.offsetX-aj.current_x;var ag=af.scrollTop()-(ah.clientY-aj.current_height);af.scrollTop(ag);aj.current_height=ah.clientY;aj.current_x=aj.offsetX;var ai=Math.round(ak/ab.viewport_container.width()*(ab.high-ab.low));ab.move_delta(ai)}).bind("mousewheel",function(ah,aj,ag,af){if(ag){ag*=50;var ai=Math.round(-ag/ab.viewport_container.width()*(ab.high-ab.low));ab.move_delta(ai)}});this.top_labeltrack.bind("dragstart",function(af,ag){return $("<div/>").addClass("zoom-area").css("height",ab.browser_content_div.height()+ab.top_labeltrack.height()+ab.nav_labeltrack.height()+1).appendTo($(this))}).bind("drag",function(aj,ak){$(ak.proxy).css({left:Math.min(aj.pageX,ak.startX)-ab.container.offset().left,width:Math.abs(aj.pageX-ak.startX)});var ag=Math.min(aj.pageX,ak.startX)-ab.container.offset().left,af=Math.max(aj.pageX,ak.startX)-ab.container.offset().left,ai=(ab.high-ab.low),ah=ab.viewport_container.width();ab.update_location(Math.round(ag/ah*ai)+ab.low,Math.round(af/ah*ai)+ab.low)}).bind("dragend",function(ak,al){var ag=Math.min(ak.pageX,al.startX),af=Math.max(ak.pageX,al.startX),ai=(ab.high-ab.low),ah=ab.viewport_container.width(),aj=ab.low;ab.low=Math.round(ag/ah*ai)+aj;ab.high=Math.round(af/ah*ai)+aj;$(al.proxy).remove();ab.request_redraw()});this.add_label_track(new V(this,{content_div:this.top_labeltrack}));this.add_label_track(new V(this,{content_div:this.nav_labeltrack}));$(window).bind("resize",function(){if(this.resize_timer){clearTimeout(this.resize_timer)}this.resize_timer=setTimeout(function(){ab.resize_window()},500)});$(document).bind("redraw",function(){ab.redraw()});this.reset();$(window).trigger("resize")},get_base_color:function(ab){return this.config.get_value(ab.toLowerCase()+"_color")||this.config.get_value("n_color")}});o(X.prototype,y.prototype,{changed:function(){this.has_changes=true},update_intro_div:function(){if(this.drawables.length===0){this.intro_div.show()}else{this.intro_div.hide()}},trigger_navigate:function(ac,ae,ab,af){if(this.timer){clearTimeout(this.timer)}if(af){var ad=this;this.timer=setTimeout(function(){ad.trigger("navigate",ac+":"+ae+"-"+ab)},500)}else{view.trigger("navigate",ac+":"+ae+"-"+ab)}},update_location:function(ab,ad){this.location_span.text(commatize(ab)+" - "+commatize(ad));this.nav_input.val(this.chrom+":"+commatize(ab)+"-"+commatize(ad));var ac=view.chrom_select.val();if(ac!==""){this.trigger_navigate(ac,view.low,view.high,true)}},load_chroms:function(ad){ad.num=v;var ab=this,ac=$.Deferred();$.ajax({url:galaxy_config.root+"api/genomes/"+this.dbkey,data:ad,dataType:"json",success:function(af){if(af.chrom_info.length===0){return}if(af.reference){var ag=new B(ab);ab.add_label_track(ag);ab.reference_track=ag}ab.chrom_data=af.chrom_info;var aj='<option value="">Select Chrom/Contig</option>';for(var ai=0,ae=ab.chrom_data.length;ai<ae;ai++){var ah=ab.chrom_data[ai].chrom;aj+='<option value="'+ah+'">'+ah+"</option>"}if(af.prev_chroms){aj+='<option value="previous">Previous '+v+"</option>"}if(af.next_chroms){aj+='<option value="next">Next '+v+"</option>"}ab.chrom_select.html(aj);ab.chrom_start_index=af.start_index;ac.resolve(af.chrom_info)},error:function(){alert("Could not load chroms for this dbkey: "+ab.dbkey)}});return ac},change_chrom:function(ag,ac,ai){var ad=this;if(!ad.chrom_data){ad.load_chroms_deferred.then(function(){ad.change_chrom(ag,ac,ai)});return}if(!ag||ag==="None"){return}if(ag==="previous"){ad.load_chroms({low:this.chrom_start_index-v});return}if(ag==="next"){ad.load_chroms({low:this.chrom_start_index+v});return}var ah=$.grep(ad.chrom_data,function(aj,ak){return aj.chrom===ag})[0];if(ah===undefined){ad.load_chroms({chrom:ag},function(){ad.change_chrom(ag,ac,ai)});return}else{if(ag!==ad.chrom){ad.chrom=ag;ad.chrom_select.val(ad.chrom);ad.max_high=ah.len-1;ad.reset();for(var af=0,ab=ad.drawables.length;af<ab;af++){var ae=ad.drawables[af];if(ae.init){ae.init()}}if(ad.reference_track){ad.reference_track.init()}}if(ac===undefined&&ai===undefined){ad.low=0;ad.high=ad.max_high}else{ad.low=(ac!==undefined?Math.max(ac,0):0);if(ai===undefined){ad.low=Math.max(ad.low-15,0);ad.high=ad.low+30}else{ad.high=Math.min(ai,ad.max_high)}}ad.reset_overview();ad.request_redraw()}},go_to:function(af){af=af.replace(/,/g,"");af=af.replace(/:|\-/g," ");var ac=af.split(/\s+/),ae=ac[0],ad=(ac[1]?parseInt(ac[1],10):undefined),ab=(ac[2]?parseInt(ac[2],10):undefined);this.change_chrom(ae,ad,ab)},move_fraction:function(ad){var ab=this;var ac=ab.high-ab.low;this.move_delta(ad*ac)},move_delta:function(ae){var ab=this;var ad=ab.high-ab.low;if(ab.low-ae<ab.max_low){ab.low=ab.max_low;ab.high=ab.max_low+ad}else{if(ab.high-ae>ab.max_high){ab.high=ab.max_high;ab.low=ab.max_high-ad}else{ab.high-=ae;ab.low-=ae}}ab.request_redraw({data_fetch:false});if(this.redraw_on_move_fn){clearTimeout(this.redraw_on_move_fn)}this.redraw_on_move_fn=setTimeout(function(){ab.request_redraw()},200);var ac=ab.chrom_select.val();this.trigger_navigate(ac,ab.low,ab.high,true)},add_drawable:function(ab){y.prototype.add_drawable.call(this,ab);ab.init();this.changed();this.update_intro_div()},add_label_track:function(ab){ab.view=this;ab.init();this.label_tracks.push(ab)},remove_drawable:function(ad,ac){y.prototype.remove_drawable.call(this,ad);if(ac){var ab=this;ad.container_div.hide(0,function(){$(this).remove();ab.update_intro_div()})}},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},request_redraw:function(ac,ad){var ab=this,ae=(ad?[ad]:ab.drawables);aa.each(ae,function(af){var ag=aa.find(ab.tracks_to_be_redrawn,function(ah){return ah[0]===af});if(ag){ag[1]=ac}else{ab.tracks_to_be_redrawn.push([af,ac])}});if(!this.requested_redraw){requestAnimationFrame(function(){ab._redraw()});this.requested_redraw=true}},_redraw:function(){this.requested_redraw=false;var ab=this.low,af=this.high;if(ab<this.max_low){ab=this.max_low}if(af>this.max_high){af=this.max_high}var ac=this.high-this.low;if(this.high!==0&&ac<this.min_separation){af=ab+this.min_separation}this.low=Math.floor(ab);this.high=Math.ceil(af);this.update_location(this.low,this.high);this.resolution_px_b=this.viewport_container.width()/(this.high-this.low);var ae=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var ag=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var ad=13;this.overview_box.css({left:ae,width:Math.max(ad,ag)}).show();if(ag<ad){this.overview_box.css("left",ae-(ad-ag)/2)}if(this.overview_highlight){this.overview_highlight.css({left:ae,width:ag})}aa.each(this.tracks_to_be_redrawn,function(aj){var ah=aj[0],ai=aj[1];if(ah){ah._draw(ai)}});this.tracks_to_be_redrawn=[];aa.each(this.label_tracks,function(ah){ah._draw()})},zoom_in:function(ac,ad){if(this.max_high===0||this.high-this.low<=this.min_separation){return}var ae=this.high-this.low,af=ae/2+this.low,ab=(ae/this.zoom_factor)/2;if(ac){af=ac/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(af-ab);this.high=Math.round(af+ab);this.changed();this.request_redraw()},zoom_out:function(){if(this.max_high===0){return}var ac=this.high-this.low,ad=ac/2+this.low,ab=(ac*this.zoom_factor)/2;this.low=Math.round(ad-ab);this.high=Math.round(ad+ab);this.changed();this.request_redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.request_redraw()},set_overview:function(ad){if(this.overview_drawable){if(this.overview_drawable.dataset.id===ad.dataset.id){return}this.overview_viewport.find(".track").remove()}var ac=ad.copy({content_div:this.overview_viewport}),ab=this;ac.header_div.hide();ac.is_overview=true;ab.overview_drawable=ac;this.overview_drawable.postdraw_actions=function(){ab.overview_highlight.show().height(ab.overview_drawable.content_div.height());ab.overview_viewport.height(ab.overview_drawable.content_div.height()+ab.overview_box.outerHeight());ab.overview_close.show();ab.resize_window()};ab.overview_drawable.request_draw();this.changed()},reset_overview:function(){$(".tooltip").remove();this.overview_viewport.find(".track-tile").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide();view.resize_window();view.overview_drawable=null}});var q=P.Tool.extend({defaults:{track:null},initialize:function(ab){P.Tool.prototype.initialize.call(this,ab);var ac=true;if(ab.tool_state!==undefined&&ab.tool_state.hidden!==undefined){ac=ab.tool_state.hidden}this.set("hidden",ac);this.remove_inputs(["data","hidden_data","conditional"])},state_dict:function(ab){return aa.extend(this.get_inputs_dict(),{hidden:!this.is_visible()})}});var t=Backbone.View.extend({events:{"change :input":"update_value"},render:function(){var ad=this.$el.addClass("param-row"),ae=this.model;var ab=$("<div>").addClass("param-label").text(ae.get("label")).appendTo(ad);var ac=$("<div/>").addClass("param-input").html(ae.get("html")).appendTo(ad);ac.find(":input").val(ae.get("value"));$("<div style='clear: both;'/>").appendTo(ad)},update_value:function(ab){this.model.set_value($(ab.target).val())}});var Z=Backbone.View.extend({initialize:function(ab){this.model.on("change:hidden",this.set_visible,this)},render:function(){var ac=this;tool=this.model,parent_div=this.$el.addClass("dynamic-tool").hide();parent_div.bind("drag",function(ag){ag.stopPropagation()}).click(function(ag){ag.stopPropagation()}).bind("dblclick",function(ag){ag.stopPropagation()}).keydown(function(ag){ag.stopPropagation()});var ad=$("<div class='tool-name'>").appendTo(parent_div).text(tool.get("name"));tool.get("inputs").each(function(ah){var ag=new t({model:ah});ag.render();parent_div.append(ag.$el)});parent_div.find("input").click(function(){$(this).select()});var ae=$("<div>").addClass("param-row").appendTo(parent_div);var af=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(ae);var ab=$("<input type='submit'>").attr("value","Run on visible region").appendTo(ae);ab.click(function(){ac.run_on_region()});af.click(function(){ac.run_on_dataset()});if(tool.is_visible()){this.$el.show()}},set_visible:function(){if(this.model.is_visible()){this.$el.show()}else{this.$el.hide()}},update_params:function(){for(var ab=0;ab<this.params.length;ab++){this.params[ab].update_value()}},run_on_dataset:function(){var ab=this.model;this.run({target_dataset_id:this.model.get("track").dataset.id,action:"rerun",tool_id:ab.id},null,function(ac){Galaxy.modal.show({title:ab.get("name")+" is Running",body:ab.get("name")+" is running on the complete dataset. Tool outputs are in dataset's history.",buttons:{Close:function(){Galaxy.modal.hide()}}})})},run_on_region:function(){var ac=this.model.get("track"),af=this.model,ah=new w.GenomeRegion({chrom:ac.view.chrom,start:ac.view.low,end:ac.view.high}),ai={target_dataset_id:ac.dataset.id,action:"rerun",tool_id:af.id,regions:[ah.toJSON()]},ag=ac,ak=af.get("name")+ag.tool_region_and_parameters_str(ah),ab;if(ag.container===view){var aj=new N(view,view,{name:ac.config.get_value("name")});var ae=ag.container.replace_drawable(ag,aj,false);aj.container_div.insertBefore(ag.view.content_div.children()[ae]);aj.add_drawable(ag);ag.container_div.appendTo(aj.content_div);ab=aj}else{ab=ag.container}var ad=new ag.constructor(view,ab,{name:ak,hda_ldda:"hda"});ad.init_for_tool_data();ad.change_mode(ag.mode);ad.set_filters_manager(ag.filters_manager.copy(ad));ad.update_icons();ab.add_drawable(ad);ad.tiles_div.text("Starting job.");this.run(ai,ad,function(al){ad.set_dataset(new W.Dataset(al));ad.tiles_div.text("Running job.");ad.init()})},run:function(ab,ad,ae){ab.inputs=this.model.get_inputs_dict();var ac=new j.ServerStateDeferred({ajax_settings:{url:galaxy_config.root+"api/tools",data:JSON.stringify(ab),dataType:"json",contentType:"application/json",type:"POST"},interval:2000,success_fn:function(af){return af!=="pending"}});$.when(ac.go()).then(function(af){if(af==="no converter"){ad.container_div.addClass("error");ad.content_div.text(H)}else{if(af.error){ad.container_div.addClass("error");ad.content_div.text(x+af.message)}else{ae(af)}}})}});var C=function(ab,ac){J.Scaler.call(this,ac);this.filter=ab};C.prototype.gen_val=function(ab){if(this.filter.high===Number.MAX_VALUE||this.filter.low===-Number.MAX_VALUE||this.filter.low===this.filter.high){return this.default_val}return((parseFloat(ab[this.filter.index])-this.filter.low)/(this.filter.high-this.filter.low))};var b=function(ab,ae,af,ac,ad){this.track=ab;this.region=ae;this.low=ae.get("start");this.high=ae.get("end");this.w_scale=af;this.canvas=ac;this.html_elt=$("<div class='track-tile'/>").append(ac);this.data=ad;this.stale=false};b.prototype.predisplay_actions=function(){};var K=function(ab,ae,af,ac,ad){b.call(this,ab,ae,af,ac,ad)};K.prototype.predisplay_actions=function(){};var M=function(ad,ai,ak,ac,af,ag,al,ab,ah,ae,aj){b.call(this,ad,ai,ak,ac,af);this.mode=ag;this.all_slotted=ab;this.feature_mapper=ah;this.has_icons=false;this.incomplete_features=ae;this.seq_data=aj};o(M.prototype,b.prototype);M.prototype.predisplay_actions=function(){var ac=this,ab={};if(ac.mode!=="Pack"){return}$(this.html_elt).hover(function(){this.hovered=true;$(this).mousemove()},function(){this.hovered=false;$(this).parents(".track-content").children(".overlay").children(".feature-popup").remove()}).mousemove(function(an){if(!this.hovered){return}var ai=$(this).offset(),am=an.pageX-ai.left,al=an.pageY-ai.top,ar=ac.feature_mapper.get_feature_data(am,al),aj=(ar?ar[0]:null);$(this).parents(".track-content").children(".overlay").children(".feature-popup").each(function(){if(!aj||$(this).attr("id")!==aj.toString()){$(this).remove()}});if(ar){var ae=ab[aj];if(!ae){var ao={name:ar[3],start:ar[1],end:ar[2],strand:ar[4]},ah=ac.track.filters_manager.filters,ag;for(var ak=0;ak<ah.length;ak++){ag=ah[ak];ao[ag.name]=ar[ag.index]}ae=$("<div/>").attr("id",aj).addClass("feature-popup");var at=$("<table/>"),aq,ap,au;for(aq in ao){ap=ao[aq];au=$("<tr/>").appendTo(at);$("<th/>").appendTo(au).text(aq);$("<td/>").attr("align","left").appendTo(au).text(typeof(ap)==="number"?U(ap,2):ap)}ae.append($("<div class='feature-popup-inner'>").append(at));ab[aj]=ae}ae.appendTo($(this).parents(".track-content").children(".overlay"));var af=am+parseInt(ac.html_elt.css("left"),10)-ae.width()/2,ad=al+parseInt(ac.html_elt.css("top"),10)+7;ae.css("left",af+"px").css("top",ad+"px")}else{if(!an.isPropagationStopped()){an.stopPropagation();$(this).siblings().each(function(){$(this).trigger(an)})}}}).mouseleave(function(){$(this).parents(".track-content").children(".overlay").children(".feature-popup").remove()})};var f=function(ac,ab,ad){o(ad,{drag_handle_class:"draghandle"});p.call(this,ac,ab,ad);this.dataset=null;if(ad.dataset){this.dataset=(ad.dataset instanceof Backbone.Model?ad.dataset:new W.Dataset(ad.dataset))}this.dataset_check_type="converted_datasets_state";this.data_url_extra_params={};this.data_query_wait=("data_query_wait" in ad?ad.data_query_wait:I);this.data_manager=("data_manager" in ad?ad.data_manager:new w.GenomeDataManager({dataset:this.dataset,genome:new w.Genome({key:ac.dbkey,chroms_info:{chrom_info:ac.chrom_data}}),data_mode_compatible:this.data_and_mode_compatible,can_subset:this.can_subset}));this.min_height_px=16;this.max_height_px=800;this.visible_height_px=this.config.get_value("height");this.content_div=$("<div class='track-content'>").appendTo(this.container_div);if(this.container){this.container.content_div.append(this.container_div);if(!("resize" in ad)||ad.resize){this.add_resize_handle()}}};o(f.prototype,p.prototype,{action_icons_def:[{name:"mode_icon",title:"Set display mode",css_class:"chevron-expand",on_click_fn:function(){}},p.prototype.action_icons_def[0],{name:"overview_icon",title:"Set as overview",css_class:"application-dock-270",on_click_fn:function(ab){ab.view.set_overview(ab)}},p.prototype.action_icons_def[1],{name:"filters_icon",title:"Filters",css_class:"ui-slider-050",on_click_fn:function(ab){if(ab.filters_manager.visible()){ab.filters_manager.clear_filters()}else{ab.filters_manager.init_filters()}ab.filters_manager.toggle()}},{name:"tools_icon",title:"Tool",css_class:"hammer",on_click_fn:function(ab){ab.tool.toggle();if(ab.tool.is_visible()){ab.set_name(ab.config.get_value("name")+ab.tool_region_and_parameters_str())}else{ab.revert_name()}$(".tooltip").remove()}},{name:"param_space_viz_icon",title:"Tool parameter space visualization",css_class:"arrow-split",on_click_fn:function(ab){var ae='<strong>Tool</strong>: <%= track.tool.get("name") %><br/><strong>Dataset</strong>: <%= track.config.get_value("name") %><br/><strong>Region(s)</strong>: <select name="regions"><option value="cur">current viewing area</option><option value="bookmarks">bookmarks</option><option value="both">current viewing area and bookmarks</option></select>',ad=aa.template(ae,{track:ab});var ag=function(){Galaxy.modal.hide();$(window).unbind("keypress.check_enter_esc")},ac=function(){var ai=$('select[name="regions"] option:selected').val(),ak,ah=new w.GenomeRegion({chrom:view.chrom,start:view.low,end:view.high}),aj=aa.map($(".bookmark"),function(al){return new w.GenomeRegion({from_str:$(al).children(".position").text()})});if(ai==="cur"){ak=[ah]}else{if(ai==="bookmarks"){ak=aj}else{ak=[ah].concat(aj)}}Galaxy.modal.hide();window.location.href=galaxy_config.root+"visualization/sweepster?"+$.param({dataset_id:ab.dataset.id,hda_ldda:ab.dataset.get("hda_ldda"),regions:JSON.stringify(new Backbone.Collection(ak).toJSON())})},af=function(ah){if((ah.keyCode||ah.which)===27){ag()}else{if((ah.keyCode||ah.which)===13){ac()}}};Galaxy.modal.show({title:"Visualize tool parameter space and output from different parameter settings?",body:ad,buttons:{No:ag,Yes:ac}})}},p.prototype.action_icons_def[2]],can_draw:function(){return this.dataset&&p.prototype.can_draw.call(this)},build_container_div:function(){return $("<div/>").addClass("track").attr("id","track_"+this.id)},build_header_div:function(){var ab=$("<div class='track-header'/>");if(this.view.editor){this.drag_div=$("<div/>").addClass(this.drag_handle_class).appendTo(ab)}this.name_div=$("<div/>").addClass("track-name").appendTo(ab).text(this.config.get_value("name")).attr("id",this.config.get_value("name").replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase());return ab},set_dataset:function(ab){this.dataset=ab;this.data_manager.set("dataset",ab)},on_resize:function(){this.request_draw({clear_tile_cache:true})},add_resize_handle:function(){var ab=this;var ae=false;var ad=false;var ac=$("<div class='track-resize'>");$(ab.container_div).hover(function(){if(ab.config.get_value("content_visible")){ae=true;ac.show()}},function(){ae=false;if(!ad){ac.hide()}});ac.hide().bind("dragstart",function(af,ag){ad=true;ag.original_height=$(ab.content_div).height()}).bind("drag",function(ag,ah){var af=Math.min(Math.max(ah.original_height+ah.deltaY,ab.min_height_px),ab.max_height_px);$(ab.tiles_div).css("height",af);ab.visible_height_px=(ab.max_height_px===af?0:af);ab.on_resize()}).bind("dragend",function(af,ag){ab.tile_cache.clear();ad=false;if(!ae){ac.hide()}ab.config.set_value("height",ab.visible_height_px);ab.changed()}).appendTo(ab.container_div)},set_display_modes:function(ae,ah){this.display_modes=ae;this.mode=(ah?ah:(this.config&&this.config.get_value("mode")?this.config.get_value("mode"):this.display_modes[0]));this.action_icons.mode_icon.attr("title","Set display mode (now: "+this.mode+")");var ac=this,af={};for(var ad=0,ab=ac.display_modes.length;ad<ab;ad++){var ag=ac.display_modes[ad];af[ag]=function(ai){return function(){ac.change_mode(ai);ac.icons_div.show();ac.container_div.mouseleave(function(){ac.icons_div.hide()})}}(ag)}make_popupmenu(this.action_icons.mode_icon,af)},build_action_icons:function(){p.prototype.build_action_icons.call(this,this.action_icons_def);if(this.display_modes!==undefined){this.set_display_modes(this.display_modes)}},hide_contents:function(){this.tiles_div.hide();this.container_div.find(".yaxislabel, .track-resize").hide()},show_contents:function(){this.tiles_div.show();this.container_div.find(".yaxislabel, .track-resize").show();this.request_draw()},get_type:function(){if(this instanceof V){return"LabelTrack"}else{if(this instanceof B){return"ReferenceTrack"}else{if(this instanceof g){return"LineTrack"}else{if(this instanceof S){return"ReadTrack"}else{if(this instanceof Y){return"VariantTrack"}else{if(this instanceof e){return"CompositeTrack"}else{if(this instanceof c){return"FeatureTrack"}}}}}}}return""},show_message:function(ab){this.tiles_div.remove();return $("<span/>").addClass("message").html(ab).appendTo(this.content_div)},init:function(ad){var ac=this;ac.enabled=false;ac.tile_cache.clear();ac.data_manager.clear();ac.content_div.children().remove();ac.container_div.removeClass("nodata error pending");ac.tiles_div=$("<div/>").addClass("tiles").appendTo(ac.content_div);if(!ac.dataset.id){return}var ab=$.Deferred(),ae={hda_ldda:ac.dataset.get("hda_ldda"),data_type:this.dataset_check_type,chrom:ac.view.chrom,retry:ad};$.getJSON(this.dataset.url(),ae,function(af){if(!af||af==="error"||af.kind==="error"){ac.container_div.addClass("error");var ag=ac.show_message(m);if(af.message){ag.append($("<a href='javascript:void(0);'></a>").text("View error").click(function(){Galaxy.modal.show({title:"Trackster Error",body:"<pre>"+af.message+"</pre>",buttons:{Close:function(){Galaxy.modal.hide()}}})}));ag.append($("<span/>").text(" "));ag.append($("<a href='javascript:void(0);'></a>").text("Try again").click(function(){ac.init(true)}))}}else{if(af==="no converter"){ac.container_div.addClass("error");ac.show_message(H)}else{if(af==="no data"||(af.data!==undefined&&(af.data===null||af.data.length===0))){ac.container_div.addClass("nodata");ac.show_message(E)}else{if(af==="pending"){ac.container_div.addClass("pending");ac.show_message(u);setTimeout(function(){ac.init()},ac.data_query_wait)}else{if(af==="data"||af.status==="data"){if(af.valid_chroms){ac.valid_chroms=af.valid_chroms;ac.update_icons()}ac.tiles_div.text(T);if(ac.view.chrom){ac.tiles_div.text("");ac.tiles_div.css("height",ac.visible_height_px+"px");ac.enabled=true;$.when.apply($,ac.predraw_init()).done(function(){ab.resolve();ac.container_div.removeClass("nodata error pending");ac.request_draw()})}else{ab.resolve()}}}}}}});this.update_icons();return ab},predraw_init:function(){var ab=this;return $.getJSON(ab.dataset.url(),{data_type:"data",stats:true,chrom:ab.view.chrom,low:0,high:ab.view.max_high,hda_ldda:ab.dataset.get("hda_ldda")},function(ac){var ae=ac.data;if(ae&&ae.min&&ae.max){var ad=ae.min,af=ae.max;ad=Math.floor(Math.min(0,Math.max(ad,ae.mean-2*ae.sd)));af=Math.ceil(Math.max(0,Math.min(af,ae.mean+2*ae.sd)));ab.config.set_default_value("min_value",ad);ab.config.set_default_value("max_value",af);ab.config.set_value("min_value",ad);ab.config.set_value("max_value",af)}})},get_drawables:function(){return this}});var L=function(ad,ac,af){f.call(this,ad,ac,af);var ab=this;k(ab.container_div,ab.drag_handle_class,".group",ab);this.filters_manager=new h.FiltersManager(this,("filters" in af?af.filters:null));this.data_manager.set("filters_manager",this.filters_manager);this.filters_available=false;this.tool=(af.tool?new q(aa.extend(af.tool,{track:this,tool_state:af.tool_state})):null);this.tile_cache=new w.Cache(O);this.left_offset=0;if(this.header_div){this.set_filters_manager(this.filters_manager);if(this.tool){var ae=new Z({model:this.tool});ae.render();this.dynamic_tool_div=ae.$el;this.header_div.after(this.dynamic_tool_div)}}this.tiles_div=$("<div/>").addClass("tiles").appendTo(this.content_div);if(!this.config.get_value("content_visible")){this.tiles_div.hide()}this.overlay_div=$("<div/>").addClass("overlay").appendTo(this.content_div);if(af.mode){this.change_mode(af.mode)}};o(L.prototype,p.prototype,f.prototype,{action_icons_def:f.prototype.action_icons_def.concat([{name:"show_more_rows_icon",title:"To minimize track height, not all feature rows are displayed. Click to display more rows.",css_class:"exclamation",on_click_fn:function(ab){$(".tooltip").remove();ab.slotters[ab.view.resolution_px_b].max_rows*=2;ab.request_draw({clear_tile_cache:true})},hide:true}]),copy:function(ab){var ac=this.to_dict();o(ac,{data_manager:this.data_manager});var ad=new this.constructor(this.view,ab,ac);ad.change_mode(this.mode);ad.enabled=this.enabled;return ad},set_filters_manager:function(ab){this.filters_manager=ab;this.header_div.after(this.filters_manager.parent_div)},to_dict:function(){return{track_type:this.get_type(),dataset:{id:this.dataset.id,hda_ldda:this.dataset.get("hda_ldda")},prefs:this.config.to_key_value_dict(),mode:this.mode,filters:this.filters_manager.to_dict(),tool_state:(this.tool?this.tool.state_dict():{})}},set_min_max:function(){var ab=this;return $.getJSON(ab.dataset.url(),{data_type:"data",stats:true,chrom:ab.view.chrom,low:0,high:ab.view.max_high,hda_ldda:ab.dataset.get("hda_ldda")},function(ac){var ae=ac.data;if(isNaN(parseFloat(ab.config.get_value("min_value")))||isNaN(parseFloat(ab.config.get_value("max_value")))){var ad=ae.min,af=ae.max;ad=Math.floor(Math.min(0,Math.max(ad,ae.mean-2*ae.sd)));af=Math.ceil(Math.max(0,Math.min(af,ae.mean+2*ae.sd)));ab.config.set_value("min_value",ad);ab.config.set_value("max_value",af)}})},change_mode:function(ac){var ab=this;ab.mode=ac;ab.config.set_value("mode",ac);if(ac==="Auto"){this.data_manager.clear()}ab.request_draw({clear_tile_cache:true});this.action_icons.mode_icon.attr("title","Set display mode (now: "+ab.mode+")");return ab},update_icons:function(){var ab=this;if(ab.filters_available){ab.action_icons.filters_icon.show()}else{ab.action_icons.filters_icon.hide()}if(ab.tool){ab.action_icons.tools_icon.show();ab.action_icons.param_space_viz_icon.show()}else{ab.action_icons.tools_icon.hide();ab.action_icons.param_space_viz_icon.hide()}},_gen_tile_cache_key:function(ac,ab){return ac+"_"+ab},request_draw:function(ab){if(ab&&ab.clear_tile_cache){this.tile_cache.clear()}this.view.request_redraw(ab,this)},before_draw:function(){this.max_height_px=0},_draw:function(ap){if(!this.can_draw()){return}var am=ap&&ap.clear_after,ak=this.view.low,af=this.view.high,ai=af-ak,ac=this.view.container.width(),ao=this.view.resolution_px_b,ae=1/ao;if(this.is_overview){ak=this.view.max_low;af=this.view.max_high;ao=ac/(view.max_high-view.max_low);ae=1/ao}this.before_draw();this.tiles_div.children().addClass("remove");var ab=Math.floor(ak/(ae*Q)),aj,al,ag,ah=[],an=[];while((ab*Q*ae)<af){aj=Math.floor(ab*Q*ae);al=new w.GenomeRegion({chrom:this.view.chrom,start:aj,end:Math.min(aj+Math.ceil(Q*ae),this.view.max_high)});ag=this.draw_helper(al,ao,ap);ah.push(ag);$.when(ag).then(function(aq){an.push(aq)});ab+=1}if(!am){this.tiles_div.children(".remove").removeClass("remove").remove()}var ad=this;$.when.apply($,ah).then(function(){ad.tiles_div.children(".remove").remove();an=aa.filter(an,function(aq){return aq!==null});if(an.length!==0){ad.postdraw_actions(an,ac,ao,am)}})},_add_yaxis_label:function(ae,ag){var ac=this,af=(ae==="max"?"top":"bottom"),ah=(ae==="max"?"max":"min"),ab=(ae==="max"?"max_value":"min_value"),ad=this.container_div.find(".yaxislabel."+af);ag=ag||function(){ac.request_draw({clear_tile_cache:true})};if(ad.length!==0){ad.text(ac.config.get_value(ab))}else{ad=$("<div/>").text(ac.config.get_value(ab)).make_text_editable({num_cols:12,on_finish:function(ai){$(".tooltip").remove();ac.config.set_value(ab,ai);ag()},help_text:"Set "+ah+" value"}).addClass("yaxislabel "+af).css("color",this.config.get_value("label_color"));this.container_div.prepend(ad)}},postdraw_actions:function(ae,af,ah,ab){var ad=aa.filter(ae,function(ai){return(ai instanceof K)});if(ad.length>0){this.max_height_px=0;var ac=this;aa.each(ae,function(ai){if(!(ai instanceof K)){ai.html_elt.remove();ac.draw_helper(ai.region,ah,{force:true,mode:"Coverage"})}});ac._add_yaxis_label("max")}else{this.container_div.find(".yaxislabel").remove();var ag=aa.find(ae,function(ai){return ai.has_icons});if(ag){aa.each(ae,function(ai){if(!ai.has_icons){ai.html_elt.css("padding-top",D)}})}}},get_mode:function(ab){return this.mode},update_auto_mode:function(ab){},_get_drawables:function(){return[this]},draw_helper:function(ak,am,an){if(!an){an={}}var ac=an.force,ah=an.mode||this.mode,ae=1/am,ad=this,af=this._get_drawables(),al=this._gen_tile_cache_key(am,ak),ag=function(ao){return(ao&&"track" in ao)};var ai=(ac?undefined:ad.tile_cache.get_elt(al));if(ai){if(ag(ai)){ad.show_tile(ai,am)}return ai}if(an.data_fetch===false){return null}var aj=function(){var ao=(aa.find(A,function(aq){return aq===ah})?"Coverage":ah);var ap=aa.map(af,function(aq){return aq.data_manager.get_data(ak,ao,ae,ad.data_url_extra_params)});if(view.reference_track){ap.push(view.reference_track.data_manager.get_data(ak,ah,ae,view.reference_track.data_url_extra_params))}return ap};var ab=$.Deferred();ad.tile_cache.set_elt(al,ab);$.when.apply($,aj()).then(function(){var ao=aj(),au=ao,aA;if(aa.find(ao,function(aC){return j.is_deferred(aC)})){ad.tile_cache.set_elt(al,undefined);$.when(ad.draw_helper(ak,am,an)).then(function(aC){ab.resolve(aC)});return}if(view.reference_track){aA=view.reference_track.data_manager.subset_entry(ao.pop(),ak)}var av=[],ar=[];aa.each(af,function(aF,aC){var aE=aF.mode,aD=au[aC];if(aE==="Auto"){aE=aF.get_mode(aD);aF.update_auto_mode(aE)}av.push(aE);ar.push(aF.get_canvas_height(aD,aE,am,ap))});var at=ad.view.canvas_manager.new_canvas(),aw=ak.get("start"),aB=ak.get("end"),aq=0,ap=Math.ceil((aB-aw)*am)+ad.left_offset,ay=aa.max(ar),ax;at.width=ap;at.height=(an.height||ay);var az=at.getContext("2d");az.translate(ad.left_offset,0);if(af.length>1){az.globalAlpha=0.5;az.globalCompositeOperation="source-over"}aa.each(af,function(aD,aC){ax=aD.draw_tile(au[aC],az,av[aC],ak,am,aA)});if(ax!==undefined){ad.tile_cache.set_elt(al,ax);ad.show_tile(ax,am)}ab.resolve(ax)});return ab},get_canvas_height:function(ab,ad,ae,ac){return this.visible_height_px},_draw_line_track_tile:function(ab,ad,ag,af,ah){var ae=ad.canvas,ac=new J.LinePainter(ab.data,af.get("start"),af.get("end"),this.config.to_key_value_dict(),ag);ac.draw(ad,ae.width,ae.height,ah);return new K(this,af,ah,ae,ab.data)},draw_tile:function(ab,ac,af,ae,ag,ad){},show_tile:function(ad,ag){var ac=this,ab=ad.html_elt;ad.predisplay_actions();var af=(ad.low-(this.is_overview?this.view.max_low:this.view.low))*ag;if(this.left_offset){af-=this.left_offset}ab.css("left",af);if(ab.hasClass("remove")){ab.removeClass("remove")}else{this.tiles_div.append(ab)}ab.css("height","auto");this.max_height_px=Math.max(this.max_height_px,ab.height()-2);ab.parent().children().css("height",this.max_height_px+"px");var ae=this.max_height_px;if(this.visible_height_px!==0){ae=Math.min(this.max_height_px,this.visible_height_px)}this.tiles_div.css("height",ae+"px")},tool_region_and_parameters_str:function(ae){var ab=this,ad=(ae!==undefined?ae.toString():"all"),ac=aa.values(ab.tool.get_inputs_dict()).join(", ");return" - region=["+ad+"], parameters=["+ac+"]"},data_and_mode_compatible:function(ab,ac){if(ac==="Auto"){return true}else{if(ac==="Coverage"){return ab.dataset_type==="bigwig"}else{if(ab.dataset_type==="bigwig"||ab.extra_info==="no_detail"){return false}else{return true}}}},can_subset:function(ab){if(ab.message||ab.extra_info==="no_detail"){return false}else{if(ab.dataset_type==="bigwig"){return(ab.data[1][0]-ab.data[0][0]===1)}}return true},init_for_tool_data:function(){this.data_manager.set("data_type","raw_data");this.data_query_wait=1000;this.dataset_check_type="state"}});var V=function(ac,ab){var ad={resize:false};f.call(this,ac,ab,ad);this.container_div.addClass("label-track")};o(V.prototype,f.prototype,{build_header_div:function(){},init:function(){this.enabled=true},predraw_init:function(){},_draw:function(af){var ad=this.view,ae=ad.high-ad.low,ai=Math.floor(Math.pow(10,Math.floor(Math.log(ae)/Math.log(10)))),ab=Math.floor(ad.low/ai)*ai,ag=this.view.container.width(),ac=$("<div/>").addClass("label-container");while(ab<ad.high){var ah=(ab-ad.low)/ae*ag;ac.append($("<div/>").addClass("label").text(commatize(ab)).css({left:ah}));ab+=ai}this.content_div.children(":first").remove();this.content_div.append(ac)}});var e=function(ac,ab,af){L.call(this,ac,ab,af);this.drawables=[];if("drawables" in af){var ae;for(var ad=0;ad<af.drawables.length;ad++){ae=af.drawables[ad];this.drawables[ad]=n(ae,ac,null);if(ae.left_offset>this.left_offset){this.left_offset=ae.left_offset}}this.enabled=true}aa.each(this.drawables,function(ag){if(ag instanceof c||ag instanceof S){ag.change_mode("Coverage")}});this.update_icons();this.obj_type="CompositeTrack"};o(e.prototype,L.prototype,{display_modes:A,config_params:aa.union(p.prototype.config_params,[{key:"min_value",label:"Min Value",type:"float",default_value:undefined},{key:"max_value",label:"Max Value",type:"float",default_value:undefined},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:30,hidden:true}]),action_icons_def:[{name:"composite_icon",title:"Show individual tracks",css_class:"layers-stack",on_click_fn:function(ab){$(".tooltip").remove();ab.show_group()}}].concat(L.prototype.action_icons_def),to_dict:y.prototype.to_dict,add_drawable:y.prototype.add_drawable,unpack_drawables:y.prototype.unpack_drawables,config_onchange:function(){this.set_name(this.config.get_value("name"));this.request_draw({clear_tile_cache:true})},on_resize:function(){var ab=this.visible_height_px;aa.each(this.drawables,function(ac){ac.visible_height_px=ab});f.prototype.on_resize.call(this)},change_mode:function(ab){L.prototype.change_mode.call(this,ab);for(var ac=0;ac<this.drawables.length;ac++){this.drawables[ac].change_mode(ab)}},init:function(){var ad=[];for(var ac=0;ac<this.drawables.length;ac++){ad.push(this.drawables[ac].init())}var ab=this;$.when.apply($,ad).then(function(){ab.enabled=true;ab.request_draw()})},update_icons:function(){this.action_icons.filters_icon.hide();this.action_icons.tools_icon.hide();this.action_icons.param_space_viz_icon.hide()},can_draw:p.prototype.can_draw,_get_drawables:function(){return this.drawables},show_group:function(){var ae=new N(this.view,this.container,{name:this.config.get_value("name")}),ab;for(var ad=0;ad<this.drawables.length;ad++){ab=this.drawables[ad];ab.update_icons();ae.add_drawable(ab);ab.container=ae;ae.content_div.append(ab.container_div)}var ac=this.container.replace_drawable(this,ae,true);ae.request_draw({clear_tile_cache:true})},before_draw:function(){var ac=aa.min(aa.map(this.drawables,function(ad){return ad.config.get_value("min_value")})),ab=aa.max(aa.map(this.drawables,function(ad){return ad.config.get_value("max_value")}));this.config.set_value("min_value",ac);this.config.set_value("max_value",ab);aa.each(this.drawables,function(ad){ad.config.set_value("min_value",ac);ad.config.set_value("max_value",ab)})},update_all_min_max:function(){var ac=this,ab=this.config.get_value("min_value"),ad=this.config.get_value("max_value");aa.each(this.drawables,function(ae){ae.config.set_value("min_value",ab);ae.config.set_value("max_value",ad)});this.request_draw({clear_tile_cache:true})},postdraw_actions:function(ah,ab,ak,ag){var af=-1,ad;for(ad=0;ad<ah.length;ad++){var ai=ah[ad].html_elt.find("canvas").height();if(ai>af){af=ai}}for(ad=0;ad<ah.length;ad++){var ae=ah[ad];if(ae.html_elt.find("canvas").height()!==af){this.draw_helper(ae.region,ak,{force:true,height:af});ae.html_elt.remove()}}var ac=this,aj=function(){ac.update_all_min_max()};this._add_yaxis_label("min",aj);this._add_yaxis_label("max",aj)}});var B=function(ab){L.call(this,ab,{content_div:ab.top_labeltrack},{resize:false});this.left_offset=ab.canvas_manager.char_width_px;this.container_div.addClass("reference-track");this.data_url=galaxy_config.root+"api/genomes/"+this.view.dbkey;this.data_url_extra_params={reference:true};this.data_manager=new w.GenomeReferenceDataManager({data_url:this.data_url,can_subset:this.can_subset});this.hide_contents()};o(B.prototype,p.prototype,L.prototype,{config_params:aa.union(p.prototype.config_params,[{key:"height",type:"int",default_value:13,hidden:true}]),build_header_div:function(){},init:function(){this.data_manager.clear();this.enabled=true},predraw_init:function(){},can_draw:p.prototype.can_draw,draw_helper:function(ac,ad,ab){if(ad>this.view.canvas_manager.char_width_px){this.tiles_div.show();return L.prototype.draw_helper.call(this,ac,ad,ab)}else{this.tiles_div.hide();return null}},can_subset:function(ab){return true},draw_tile:function(ad,aj,ae,ag,ak){var ac=this.data_manager.subset_entry(ad,ag),ai=ac.data;var ab=aj.canvas;aj.font=aj.canvas.manager.default_font;aj.textAlign="center";for(var af=0,ah=ai.length;af<ah;af++){aj.fillStyle=this.view.get_base_color(ai[af]);aj.fillText(ai[af],Math.floor(af*ak),10)}return new b(this,ag,ak,ab,ac)}});var g=function(ac,ab,ad){this.mode="Histogram";L.call(this,ac,ab,ad)};o(g.prototype,p.prototype,L.prototype,{display_modes:A,config_params:aa.union(p.prototype.config_params,[{key:"color",label:"Color",type:"color"},{key:"min_value",label:"Min Value",type:"float",default_value:undefined},{key:"max_value",label:"Max Value",type:"float",default_value:undefined},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:30,hidden:true}]),config_onchange:function(){this.set_name(this.config.get_value("name"));this.request_draw({clear_tile_cache:true})},before_draw:function(){},draw_tile:function(ab,ac,ae,ad,af){return this._draw_line_track_tile(ab,ac,ae,ad,af)},can_subset:function(ab){return(ab.data[1][0]-ab.data[0][0]===1)},postdraw_actions:function(ac,ad,ae,ab){this._add_yaxis_label("max");this._add_yaxis_label("min")}});var r=function(ac,ab,ad){this.mode="Heatmap";L.call(this,ac,ab,ad)};o(r.prototype,p.prototype,L.prototype,{display_modes:["Heatmap"],config_params:aa.union(p.prototype.config_params,[{key:"pos_color",label:"Positive Color",type:"color",default_value:"#FF8C00"},{key:"neg_color",label:"Negative Color",type:"color",default_value:"#4169E1"},{key:"min_value",label:"Min Value",type:"float",default_value:-1},{key:"max_value",label:"Max Value",type:"float",default_value:1},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:500,hidden:true}]),config_onchange:function(){this.set_name(this.config.get_value("name"));this.request_draw({clear_tile_cache:true})},draw_tile:function(ab,ad,ag,af,ah){var ae=ad.canvas,ac=new J.DiagonalHeatmapPainter(ab.data,af.get("start"),af.get("end"),this.config.to_key_value_dict(),ag);ac.draw(ad,ae.width,ae.height,ah);return new b(this,af,ah,ae,ab.data)}});var c=function(ac,ab,ad){L.call(this,ac,ab,ad);this.container_div.addClass("feature-track");this.summary_draw_height=30;this.slotters={};this.start_end_dct={};this.left_offset=200;this.set_painter_from_config()};o(c.prototype,p.prototype,L.prototype,{display_modes:["Auto","Coverage","Dense","Squish","Pack"],config_params:aa.union(p.prototype.config_params,[{key:"block_color",label:"Block color",type:"color"},{key:"reverse_strand_color",label:"Antisense strand color",type:"color"},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true,help:"Show the number of items in each bin when drawing summary histogram"},{key:"min_value",label:"Histogram minimum",type:"float",default_value:null,help:"clear value to set automatically"},{key:"max_value",label:"Histogram maximum",type:"float",default_value:null,help:"clear value to set automatically"},{key:"connector_style",label:"Connector style",type:"select",default_value:"fishbones",options:[{label:"Line with arrows",value:"fishbone"},{label:"Arcs",value:"arcs"}]},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:0,hidden:true}]),config_onchange:function(){this.set_name(this.config.get_value("name"));this.set_painter_from_config();this.request_draw({clear_tile_cache:true})},set_painter_from_config:function(){if(this.config.get_value("connector_style")==="arcs"){this.painter=J.ArcLinkedFeaturePainter}else{this.painter=J.LinkedFeaturePainter}},postdraw_actions:function(an,ae,ap,am){L.prototype.postdraw_actions.call(this,an,ae,ap,am);var ag=this,ah,al=aa.filter(an,function(aq){return(aq instanceof K)});if(al.length===0){var ab={};aa.each(aa.pluck(an,"incomplete_features"),function(aq){aa.each(aq,function(ar){ab[ar[0]]=ar})});var ao=this;aa.each(an,function(aq){ao.draw_tile({data:aa.values(ab)},aq.canvas.getContext("2d"),aq.mode,aq.region,ap,aq.seq_data,true)})}if(ag.filters_manager){var af=ag.filters_manager.filters,aj;for(aj=0;aj<af.length;aj++){af[aj].update_ui_elt()}var ai=false,ak,ad;for(ah=0;ah<an.length;ah++){if(an[ah].data.length){ak=an[ah].data[0];for(aj=0;aj<af.length;aj++){ad=af[aj];if(ad.applies_to(ak)&&ad.min!==ad.max){ai=true;break}}}}if(ag.filters_available!==ai){ag.filters_available=ai;if(!ag.filters_available){ag.filters_manager.hide()}ag.update_icons()}}if(an[0] instanceof M){var ac=true;for(ah=0;ah<an.length;ah++){if(!an[ah].all_slotted){ac=false;break}}if(!ac){this.action_icons.show_more_rows_icon.show()}else{this.action_icons.show_more_rows_icon.hide()}}else{this.action_icons.show_more_rows_icon.hide()}},update_auto_mode:function(ab){if(this.mode==="Auto"){if(ab==="no_detail"){ab="feature spans"}this.action_icons.mode_icon.attr("title","Set display mode (now: Auto/"+ab+")")}},incremental_slots:function(af,ab,ae){var ac=this.view.canvas_manager.dummy_context,ad=this.slotters[af];if(!ad||(ad.mode!==ae)){ad=new (s.FeatureSlotter)(af,ae,z,function(ag){return ac.measureText(ag)});this.slotters[af]=ad}return ad.slot_features(ab)},get_mode:function(ab){if(ab.extra_info==="no_detail"||this.is_overview){mode="no_detail"}else{if(this.view.high-this.view.low>G){mode="Squish"}else{mode="Pack"}}return mode},get_canvas_height:function(ab,af,ag,ac){if(af==="Coverage"||ab.dataset_type==="bigwig"){return this.summary_draw_height}else{var ae=this.incremental_slots(ag,ab.data,af);var ad=new (this.painter)(null,null,null,this.config.to_key_value_dict(),af);return Math.max(this.min_height_px,ad.get_required_height(ae,ac))}},draw_tile:function(am,ar,ap,af,aj,ae,an){var aq=this,ad=ar.canvas,ay=af.get("start"),ac=af.get("end"),ag=this.left_offset;if(am.dataset_type==="bigwig"){return this._draw_line_track_tile(am,ar,ap,af,aj)}var ai=[],ao=this.slotters[aj].slots;all_slotted=true;if(am.data){var ak=this.filters_manager.filters;for(var at=0,av=am.data.length;at<av;at++){var ah=am.data[at];var au=false;var al;for(var ax=0,aC=ak.length;ax<aC;ax++){al=ak[ax];al.update_attrs(ah);if(!al.keep(ah)){au=true;break}}if(!au){ai.push(ah);if(!(ah[0] in ao)){all_slotted=false}}}}var aB=(this.filters_manager.alpha_filter?new C(this.filters_manager.alpha_filter):null),az=(this.filters_manager.height_filter?new C(this.filters_manager.height_filter):null),aA=new (this.painter)(ai,ay,ac,this.config.to_key_value_dict(),ap,aB,az,ae,function(aD){return aq.view.get_base_color(aD)});var aw=null;ar.fillStyle=this.config.get_value("block_color");ar.font=ar.canvas.manager.default_font;ar.textAlign="right";if(am.data){var ab=aA.draw(ar,ad.width,ad.height,aj,ao);aw=ab.feature_mapper;incomplete_features=ab.incomplete_features;aw.translation=-ag}if(!an){return new M(aq,af,aj,ad,am.data,ap,am.message,all_slotted,aw,incomplete_features,ae)}}});var Y=function(ac,ab,ad){L.call(this,ac,ab,ad);this.painter=J.VariantPainter;this.summary_draw_height=30;this.left_offset=30};o(Y.prototype,p.prototype,L.prototype,{display_modes:["Auto","Coverage","Dense","Squish","Pack"],config_params:aa.union(p.prototype.config_params,[{key:"color",label:"Histogram color",type:"color"},{key:"show_sample_data",label:"Show sample data",type:"bool",default_value:true},{key:"show_labels",label:"Show summary and sample labels",type:"bool",default_value:true},{key:"summary_height",label:"Locus summary height",type:"float",default_value:20},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:0,hidden:true}]),config_onchange:function(){this.set_name(this.config.get_value("name"));this.request_draw({clear_tile_cache:true})},draw_tile:function(ab,ae,ag,af,ah){if(ab.dataset_type==="bigwig"){return this._draw_line_track_tile(ab,ae,"Histogram",af,ah)}else{var ad=this.view,ac=new (this.painter)(ab.data,af.get("start"),af.get("end"),this.config.to_key_value_dict(),ag,function(ai){return ad.get_base_color(ai)});ac.draw(ae,ae.canvas.width,ae.canvas.height,ah);return new b(this,af,ah,ae.canvas,ab.data)}},get_canvas_height:function(ab,af,ag,ad){if(ab.dataset_type==="bigwig"){return this.summary_draw_height}else{var ac=(this.dataset.get_metadata("sample_names")?this.dataset.get_metadata("sample_names").length:0);if(ac===0&&ab.data.length!==0){ac=ab.data[0][7].match(/,/g);if(ac===null){ac=1}else{ac=ac.length+1}}var ae=new (this.painter)(null,null,null,this.config.to_key_value_dict(),af);return ae.get_required_height(ac)}},predraw_init:function(){var ab=[f.prototype.predraw_init.call(this)];if(!this.dataset.get_metadata("sample_names")){ab.push(this.dataset.fetch())}return ab},postdraw_actions:function(af,ag,ai,ac){L.prototype.postdraw_actions.call(this,af,ag,ai,ac);var ae=aa.filter(af,function(aj){return(aj instanceof K)});var ad=this.dataset.get_metadata("sample_names");if(ae.length===0&&this.config.get_value("show_labels")&&ad&&ad.length>1){var ab;if(this.container_div.find(".yaxislabel.variant").length===0){ab=this.config.get_value("summary_height")/2;this.tiles_div.prepend($("<div/>").text("Summary").addClass("yaxislabel variant top").css({"font-size":ab+"px",top:(this.config.get_value("summary_height")-ab)/2+"px"}));if(this.config.get_value("show_sample_data")){var ah=ad.join("<br/>");this.tiles_div.prepend($("<div/>").html(ah).addClass("yaxislabel variant top sample").css({top:this.config.get_value("summary_height")}))}}ab=(this.mode==="Squish"?5:10)+"px";$(this.tiles_div).find(".sample").css({"font-size":ab,"line-height":ab});$(this.tiles_div).find(".yaxislabel").css("color",this.config.get_value("label_color"))}else{this.container_div.find(".yaxislabel.variant").remove()}}});var S=function(ac,ab,ad){c.call(this,ac,ab,ad);this.painter=J.ReadPainter;this.update_icons()};o(S.prototype,p.prototype,L.prototype,c.prototype,{config_params:aa.union(p.prototype.config_params,[{key:"block_color",label:"Block and sense strand color",type:"color",default_value:"#DDDDDD"},{key:"reverse_strand_color",label:"Antisense strand color",type:"color",default_value:"#AAAAAA"},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_differences",label:"Show differences only",type:"bool",default_value:true},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"min_value",label:"Histogram minimum",type:"float",default_value:null,help:"clear value to set automatically"},{key:"max_value",label:"Histogram maximum",type:"float",default_value:null,help:"clear value to set automatically"},{key:"height",type:"int",default_value:0,hidden:true}]),config_onchange:function(){this.set_name(this.config.get_value("name"));this.request_draw({clear_tile_cache:true})}});var d={CompositeTrack:e,DrawableGroup:N,DiagonalHeatmapTrack:r,FeatureTrack:c,LineTrack:g,ReadTrack:S,VariantTrack:Y,VcfTrack:Y};var n=function(ad,ac,ab){if("copy" in ad){return ad.copy(ab)}else{var ae=ad.obj_type;if(!ae){ae=ad.track_type}return new d[ae](ac,ab,ad)}};return{TracksterView:X,DrawableGroup:N,LineTrack:g,FeatureTrack:c,DiagonalHeatmapTrack:r,ReadTrack:S,VariantTrack:Y,CompositeTrack:e,object_from_template:n}});
\ No newline at end of file
+define(["libs/underscore","viz/visualization","viz/trackster/util","viz/trackster/slotting","viz/trackster/painters","viz/trackster/filters","mvc/data","mvc/tools","utils/config"],function(aa,w,j,s,J,h,W,P,R){var o=aa.extend;var l={};var i=function(ab,ac){l[ab.attr("id")]=ac};var k=function(ab,ac,ae,ad){ae=".group";l[ab.attr("id")]=ad;ab.bind("drag",{handle:"."+ac,relative:true},function(am,an){var al=$(this),aq=$(this).parent(),ai=aq.children(".track,.group"),ak=l[$(this).attr("id")],ah,ag,ao,af,aj;ag=$(this).parents(ae);if(ag.length!==0){ao=ag.position().top;af=ao+ag.outerHeight();var ap=l[ag.attr("id")];if(an.offsetY<ao){$(this).insertBefore(ag);ap.remove_drawable(ak);ap.container.add_drawable_before(ak,ap);return}else{if(an.offsetY>af){$(this).insertAfter(ag);ap.remove_drawable(ak);ap.container.add_drawable(ak);return}}}ag=null;for(aj=0;aj<ai.length;aj++){ah=$(ai.get(aj));ao=ah.position().top;af=ao+ah.outerHeight();if(ah.is(ae)&&this!==ah.get(0)&&an.offsetY>=ao&&an.offsetY<=af){if(an.offsetY-ao<af-an.offsetY){ah.find(".content-div").prepend(this)}else{ah.find(".content-div").append(this)}if(ak.container){ak.container.remove_drawable(ak)}l[ah.attr("id")].add_drawable(ak);return}}for(aj=0;aj<ai.length;aj++){ah=$(ai.get(aj));if(an.offsetY<ah.position().top&&!(ah.hasClass("reference-track")||ah.hasClass("intro"))){break}}if(aj===ai.length){if(this!==ai.get(aj-1)){aq.append(this);l[aq.attr("id")].move_drawable(ak,aj)}}else{if(this!==ai.get(aj)){$(this).insertBefore(ai.get(aj));l[aq.attr("id")].move_drawable(ak,(an.deltaY>0?aj-1:aj))}}}).bind("dragstart",function(){$(this).addClass("dragging")}).bind("dragend",function(){$(this).removeClass("dragging")})};var D=20,z=100,G=12000,Q=400,I=5000,v=100,m="Cannot display dataset due to an error. ",H="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",E="No data for this chrom/contig.",u="Preparing data. This can take a while for a large dataset. If the visualization is saved and closed, preparation will continue in the background.",x="Tool cannot be rerun: ",a="Loading data...",T="Ready for display",O=10,F=20,A=["Histogram","Line","Filled","Intensity"];function U(ac,ab){if(!ab){ab=0}var ad=Math.pow(10,ab);return Math.round(ac*ad)/ad}var p=function(ac,ab,ae){if(!p.id_counter){p.id_counter=0}this.id=p.id_counter++;this.view=ac;this.container=ab;this.drag_handle_class=ae.drag_handle_class;this.is_overview=false;this.action_icons={};this.config=R.ConfigSettingCollection.from_models_and_saved_values(this.config_params,ae.prefs);if(!this.config.get_value("name")){this.config.set_value("name",ae.name)}if(this.config_onchange){this.config.on("change",this.config_onchange,this)}this.container_div=this.build_container_div();this.header_div=this.build_header_div();if(this.header_div){this.container_div.append(this.header_div);this.icons_div=$("<div/>").addClass("track-icons").hide().appendTo(this.header_div);this.build_action_icons(this.action_icons_def);this.header_div.append($("<div style='clear: both'/>"));this.header_div.dblclick(function(af){af.stopPropagation()});var ad=this;this.container_div.hover(function(){ad.icons_div.show()},function(){ad.icons_div.hide()});$("<div style='clear: both'/>").appendTo(this.container_div)}};p.prototype.action_icons_def=[{name:"toggle_icon",title:"Hide/show content",css_class:"toggle",on_click_fn:function(ab){if(ab.config.get_value("content_visible")){ab.action_icons.toggle_icon.addClass("toggle-expand").removeClass("toggle");ab.hide_contents();ab.config.set_value("content_visible",false)}else{ab.action_icons.toggle_icon.addClass("toggle").removeClass("toggle-expand");ab.config.set_value("content_visible",true);ab.show_contents()}}},{name:"settings_icon",title:"Edit settings",css_class:"gear",on_click_fn:function(ac){var ab=new R.ConfigSettingCollectionView({collection:ac.config});ab.render_in_modal("Configure Track")}},{name:"remove_icon",title:"Remove",css_class:"remove-icon",on_click_fn:function(ab){$(".tooltip").remove();ab.remove()}}];o(p.prototype,{config_params:[{key:"name",label:"Name",type:"text",default_value:""},{key:"content_visible",type:"bool",default_value:true,hidden:true}],config_onchange:function(){},init:function(){},changed:function(){this.view.changed()},can_draw:function(){if(this.enabled&&this.config.get_value("content_visible")){return true}return false},request_draw:function(){},_draw:function(ab){},to_dict:function(){},set_name:function(ab){this.old_name=this.config.get_value("name");this.config.set_value("name",ab);this.name_div.text(ab)},revert_name:function(){if(this.old_name){this.config.set_value("name",this.old_name);this.name_div.text(this.old_name)}},remove:function(){this.changed();this.container.remove_drawable(this);var ab=this.view;this.container_div.hide(0,function(){$(this).remove();ab.update_intro_div()})},build_container_div:function(){},build_header_div:function(){},add_action_icon:function(ac,ah,ag,af,ab,ae){var ad=this;this.action_icons[ac]=$("<a/>").attr("title",ah).addClass("icon-button").addClass(ag).tooltip().click(function(){af(ad)}).appendTo(this.icons_div);if(ae){this.action_icons[ac].hide()}},build_action_icons:function(ab){var ad;for(var ac=0;ac<ab.length;ac++){ad=ab[ac];this.add_action_icon(ad.name,ad.title,ad.css_class,ad.on_click_fn,ad.prepend,ad.hide)}},update_icons:function(){},hide_contents:function(){},show_contents:function(){},get_drawables:function(){}});var y=function(ac,ab,ad){p.call(this,ac,ab,ad);this.obj_type=ad.obj_type;this.drawables=[]};o(y.prototype,p.prototype,{unpack_drawables:function(ad){this.drawables=[];var ac;for(var ab=0;ab<ad.length;ab++){ac=n(ad[ab],this.view,this);this.add_drawable(ac)}},init:function(){for(var ab=0;ab<this.drawables.length;ab++){this.drawables[ab].init()}},_draw:function(ab){for(var ac=0;ac<this.drawables.length;ac++){this.drawables[ac]._draw(ab)}},to_dict:function(){var ac=[];for(var ab=0;ab<this.drawables.length;ab++){ac.push(this.drawables[ab].to_dict())}return{prefs:this.config.to_key_value_dict(),obj_type:this.obj_type,drawables:ac}},add_drawable:function(ab){this.drawables.push(ab);ab.container=this;this.changed()},add_drawable_before:function(ad,ab){this.changed();var ac=this.drawables.indexOf(ab);if(ac!==-1){this.drawables.splice(ac,0,ad);return true}return false},replace_drawable:function(ad,ab,ac){var ae=this.drawables.indexOf(ad);if(ae!==-1){this.drawables[ae]=ab;if(ac){ad.container_div.replaceWith(ab.container_div)}this.changed()}return ae},remove_drawable:function(ac){var ab=this.drawables.indexOf(ac);if(ab!==-1){this.drawables.splice(ab,1);ac.container=null;this.changed();return true}return false},move_drawable:function(ac,ad){var ab=this.drawables.indexOf(ac);if(ab!==-1){this.drawables.splice(ab,1);this.drawables.splice(ad,0,ac);this.changed();return true}return false},get_drawables:function(){return this.drawables},get_tracks:function(ae){var ab=this.drawables.slice(0),ac=[],ad;while(ab.length!==0){ad=ab.shift();if(ad instanceof ae){ac.push(ad)}else{if(ad.drawables){ab=ab.concat(ad.drawables)}}}return ac}});var N=function(ac,ab,ae){o(ae,{obj_type:"DrawableGroup",drag_handle_class:"group-handle"});y.call(this,ac,ab,ae);this.content_div=$("<div/>").addClass("content-div").attr("id","group_"+this.id+"_content_div").appendTo(this.container_div);i(this.container_div,this);i(this.content_div,this);k(this.container_div,this.drag_handle_class,".group",this);this.filters_manager=new h.FiltersManager(this);this.header_div.after(this.filters_manager.parent_div);this.saved_filters_managers=[];if("drawables" in ae){this.unpack_drawables(ae.drawables)}if("filters" in ae){var ad=this.filters_manager;this.filters_manager=new h.FiltersManager(this,ae.filters);ad.parent_div.replaceWith(this.filters_manager.parent_div);if(ae.filters.visible){this.setup_multitrack_filtering()}}};o(N.prototype,p.prototype,y.prototype,{action_icons_def:[p.prototype.action_icons_def[0],p.prototype.action_icons_def[1],{name:"composite_icon",title:"Show composite track",css_class:"layers-stack",on_click_fn:function(ab){$(".tooltip").remove();ab.show_composite_track()}},{name:"filters_icon",title:"Filters",css_class:"filters-icon",on_click_fn:function(ab){if(ab.filters_manager.visible()){ab.filters_manager.clear_filters();ab._restore_filter_managers()}else{ab.setup_multitrack_filtering();ab.request_draw({clear_tile_cache:true})}ab.filters_manager.toggle()}},p.prototype.action_icons_def[2]],build_container_div:function(){var ab=$("<div/>").addClass("group").attr("id","group_"+this.id);if(this.container){this.container.content_div.append(ab)}return ab},build_header_div:function(){var ab=$("<div/>").addClass("track-header");ab.append($("<div/>").addClass(this.drag_handle_class));this.name_div=$("<div/>").addClass("track-name").text(this.config.get_value("name")).appendTo(ab);return ab},hide_contents:function(){this.tiles_div.hide()},show_contents:function(){this.tiles_div.show();this.request_draw()},update_icons:function(){var ad=this.drawables.length;if(ad===0){this.action_icons.composite_icon.hide();this.action_icons.filters_icon.hide()}else{if(ad===1){if(this.drawables[0] instanceof e){this.action_icons.composite_icon.show()}this.action_icons.filters_icon.hide()}else{var ak,aj,ah,an=true,af=this.drawables[0].get_type(),ab=0;for(ak=0;ak<ad;ak++){ah=this.drawables[ak];if(ah.get_type()!==af){can_composite=false;break}if(ah instanceof c){ab++}}if(an&&this.drawables[0] instanceof g){this.action_icons.composite_icon.show()}else{this.action_icons.composite_icon.hide();$(".tooltip").remove()}if(ab>1&&ab===this.drawables.length){var ao={},ac;ah=this.drawables[0];for(aj=0;aj<ah.filters_manager.filters.length;aj++){ac=ah.filters_manager.filters[aj];ao[ac.name]=[ac]}for(ak=1;ak<this.drawables.length;ak++){ah=this.drawables[ak];for(aj=0;aj<ah.filters_manager.filters.length;aj++){ac=ah.filters_manager.filters[aj];if(ac.name in ao){ao[ac.name].push(ac)}}}this.filters_manager.remove_all();var ae,ag,ai,al;for(var am in ao){ae=ao[am];if(ae.length===ab){ag=new h.NumberFilter({name:ae[0].name,index:ae[0].index});this.filters_manager.add_filter(ag)}}if(this.filters_manager.filters.length>0){this.action_icons.filters_icon.show()}else{this.action_icons.filters_icon.hide()}}else{this.action_icons.filters_icon.hide()}}}},_restore_filter_managers:function(){for(var ab=0;ab<this.drawables.length;ab++){this.drawables[ab].filters_manager=this.saved_filters_managers[ab]}this.saved_filters_managers=[]},setup_multitrack_filtering:function(){if(this.filters_manager.filters.length>0){this.saved_filters_managers=[];for(var ab=0;ab<this.drawables.length;ab++){drawable=this.drawables[ab];this.saved_filters_managers.push(drawable.filters_manager);drawable.filters_manager=this.filters_manager}}this.filters_manager.init_filters()},show_composite_track:function(){var ac=new e(this.view,this.view,{name:this.config.get_value("name"),drawables:this.drawables});var ab=this.container.replace_drawable(this,ac,true);ac.request_draw()},add_drawable:function(ab){y.prototype.add_drawable.call(this,ab);this.update_icons()},remove_drawable:function(ab){y.prototype.remove_drawable.call(this,ab);this.update_icons()},to_dict:function(){if(this.filters_manager.visible()){this._restore_filter_managers()}var ab=o(y.prototype.to_dict.call(this),{filters:this.filters_manager.to_dict()});if(this.filters_manager.visible()){this.setup_multitrack_filtering()}return ab},request_draw:function(ab){aa.each(this.drawables,function(ac){ac.request_draw(ab)})}});var X=Backbone.View.extend({initialize:function(ab){o(ab,{obj_type:"View"});y.call(this,"View",ab.container,ab);this.chrom=null;this.vis_id=ab.vis_id;this.dbkey=ab.dbkey;this.label_tracks=[];this.tracks_to_be_redrawn=[];this.max_low=0;this.max_high=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.load_chroms_deferred=null;this.render();this.canvas_manager=new w.CanvasManager(this.container.get(0).ownerDocument);this.reset();this.config=R.ConfigSettingCollection.from_models_and_saved_values([{key:"name",label:"Name",type:"text",default_value:""},{key:"a_color",label:"A Color",type:"color",default_value:"#FF0000"},{key:"c_color",label:"C Color",type:"color",default_value:"#00FF00"},{key:"g_color",label:"G Color",type:"color",default_value:"#0000FF"},{key:"t_color",label:"T Color",type:"color",default_value:"#FF00FF"},{key:"n_color",label:"N Color",type:"color",default_value:"#AAAAAA"}],{name:ab.name})},render:function(){this.requested_redraw=false;var ad=this.container,ab=this;this.top_container=$("<div/>").addClass("top-container").appendTo(ad);this.browser_content_div=$("<div/>").addClass("content").appendTo(ad);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(ad);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);this.viewport_container=$("<div/>").addClass("viewport-container").attr("id","viewport-container").appendTo(this.browser_content_div);this.content_div=this.viewport_container;i(this.viewport_container,ab);this.intro_div=$("<div/>").addClass("intro").appendTo(this.viewport_container).hide();var ae=$("<div/>").text("Add Datasets to Visualization").addClass("action-button").appendTo(this.intro_div).click(function(){w.select_datasets(galaxy_config.root+"visualization/list_current_history_datasets",galaxy_config.root+"api/datasets",{"f-dbkey":ab.dbkey},function(af){aa.each(af,function(ag){ab.add_drawable(n(ag,ab,ab))})})});this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("trackster-nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("trackster-nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.bottom_container);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_close=$("<a/>").attr("title","Close overview").addClass("icon-button overview-close tooltip").hide().appendTo(this.overview_viewport);this.overview_highlight=$("<div/>").addClass("overview-highlight").hide().appendTo(this.overview_viewport);this.overview_box_background=$("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_select=$("<select/>").attr({name:"chrom"}).addClass("chrom-nav").append("<option value=''>Loading</option>").appendTo(this.nav_controls);var ac=function(af){if(af.type==="focusout"||(af.keyCode||af.which)===13||(af.keyCode||af.which)===27){if((af.keyCode||af.which)!==27){ab.go_to($(this).val())}$(this).hide();$(this).val("");ab.location_span.show();ab.chrom_select.show()}af.stopPropagation()};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",ac).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").attr("title","Click to change location").tooltip({placement:"bottom"}).appendTo(this.nav_controls);this.location_span.click(function(){ab.location_span.hide();ab.chrom_select.hide();ab.nav_input.val(ab.chrom+":"+ab.low+"-"+ab.high);ab.nav_input.css("display","inline-block");ab.nav_input.select();ab.nav_input.focus();ab.nav_input.autocomplete({source:function(ah,af){var ai=[],ag=$.map(ab.get_tracks(c),function(aj){return aj.data_manager.search_features(ah.term).success(function(ak){ai=ai.concat(ak)})});$.when.apply($,ag).done(function(){af($.map(ai,function(aj){return{label:aj[0],value:aj[1]}}))})}})});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.nav_controls)}this.zo_link=$("<a/>").attr("id","zoom-out").attr("title","Zoom out").tooltip({placement:"bottom"}).click(function(){ab.zoom_out()}).appendTo(this.nav_controls);this.zi_link=$("<a/>").attr("id","zoom-in").attr("title","Zoom in").tooltip({placement:"bottom"}).click(function(){ab.zoom_in()}).appendTo(this.nav_controls);this.load_chroms_deferred=this.load_chroms({low:0});this.chrom_select.bind("change",function(){ab.change_chrom(ab.chrom_select.val())});this.browser_content_div.click(function(af){$(this).find("input").trigger("blur")});this.browser_content_div.bind("dblclick",function(af){ab.zoom_in(af.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(af,ag){this.current_x=ag.offsetX}).bind("drag",function(af,ah){var ai=ah.offsetX-this.current_x;this.current_x=ah.offsetX;var ag=Math.round(ai/ab.viewport_container.width()*(ab.max_high-ab.max_low));ab.move_delta(-ag)});this.overview_close.click(function(){ab.reset_overview()});this.viewport_container.bind("draginit",function(af,ag){if(af.clientX>ab.viewport_container.width()-16){return false}}).bind("dragstart",function(af,ag){ag.original_low=ab.low;ag.current_height=af.clientY;ag.current_x=ag.offsetX}).bind("drag",function(ah,aj){var af=$(this);var ak=aj.offsetX-aj.current_x;var ag=af.scrollTop()-(ah.clientY-aj.current_height);af.scrollTop(ag);aj.current_height=ah.clientY;aj.current_x=aj.offsetX;var ai=Math.round(ak/ab.viewport_container.width()*(ab.high-ab.low));ab.move_delta(ai)}).bind("mousewheel",function(ah,aj,ag,af){if(ag){ag*=50;var ai=Math.round(-ag/ab.viewport_container.width()*(ab.high-ab.low));ab.move_delta(ai)}});this.top_labeltrack.bind("dragstart",function(af,ag){return $("<div/>").addClass("zoom-area").css("height",ab.browser_content_div.height()+ab.top_labeltrack.height()+ab.nav_labeltrack.height()+1).appendTo($(this))}).bind("drag",function(aj,ak){$(ak.proxy).css({left:Math.min(aj.pageX,ak.startX)-ab.container.offset().left,width:Math.abs(aj.pageX-ak.startX)});var ag=Math.min(aj.pageX,ak.startX)-ab.container.offset().left,af=Math.max(aj.pageX,ak.startX)-ab.container.offset().left,ai=(ab.high-ab.low),ah=ab.viewport_container.width();ab.update_location(Math.round(ag/ah*ai)+ab.low,Math.round(af/ah*ai)+ab.low)}).bind("dragend",function(ak,al){var ag=Math.min(ak.pageX,al.startX),af=Math.max(ak.pageX,al.startX),ai=(ab.high-ab.low),ah=ab.viewport_container.width(),aj=ab.low;ab.low=Math.round(ag/ah*ai)+aj;ab.high=Math.round(af/ah*ai)+aj;$(al.proxy).remove();ab.request_redraw()});this.add_label_track(new V(this,{content_div:this.top_labeltrack}));this.add_label_track(new V(this,{content_div:this.nav_labeltrack}));$(window).bind("resize",function(){if(this.resize_timer){clearTimeout(this.resize_timer)}this.resize_timer=setTimeout(function(){ab.resize_window()},500)});$(document).bind("redraw",function(){ab.redraw()});this.reset();$(window).trigger("resize")},get_base_color:function(ab){return this.config.get_value(ab.toLowerCase()+"_color")||this.config.get_value("n_color")}});o(X.prototype,y.prototype,{changed:function(){this.has_changes=true},update_intro_div:function(){if(this.drawables.length===0){this.intro_div.show()}else{this.intro_div.hide()}},trigger_navigate:function(ac,ae,ab,af){if(this.timer){clearTimeout(this.timer)}if(af){var ad=this;this.timer=setTimeout(function(){ad.trigger("navigate",ac+":"+ae+"-"+ab)},500)}else{view.trigger("navigate",ac+":"+ae+"-"+ab)}},update_location:function(ab,ad){this.location_span.text(commatize(ab)+" - "+commatize(ad));this.nav_input.val(this.chrom+":"+commatize(ab)+"-"+commatize(ad));var ac=view.chrom_select.val();if(ac!==""){this.trigger_navigate(ac,view.low,view.high,true)}},load_chroms:function(ad){ad.num=v;var ab=this,ac=$.Deferred();$.ajax({url:galaxy_config.root+"api/genomes/"+this.dbkey,data:ad,dataType:"json",success:function(af){if(af.chrom_info.length===0){return}if(af.reference){var ag=new B(ab);ab.add_label_track(ag);ab.reference_track=ag}ab.chrom_data=af.chrom_info;var aj='<option value="">Select Chrom/Contig</option>';for(var ai=0,ae=ab.chrom_data.length;ai<ae;ai++){var ah=ab.chrom_data[ai].chrom;aj+='<option value="'+ah+'">'+ah+"</option>"}if(af.prev_chroms){aj+='<option value="previous">Previous '+v+"</option>"}if(af.next_chroms){aj+='<option value="next">Next '+v+"</option>"}ab.chrom_select.html(aj);ab.chrom_start_index=af.start_index;ac.resolve(af.chrom_info)},error:function(){alert("Could not load chroms for this dbkey: "+ab.dbkey)}});return ac},change_chrom:function(ag,ac,ai){var ad=this;if(!ad.chrom_data){ad.load_chroms_deferred.then(function(){ad.change_chrom(ag,ac,ai)});return}if(!ag||ag==="None"){return}if(ag==="previous"){ad.load_chroms({low:this.chrom_start_index-v});return}if(ag==="next"){ad.load_chroms({low:this.chrom_start_index+v});return}var ah=$.grep(ad.chrom_data,function(aj,ak){return aj.chrom===ag})[0];if(ah===undefined){ad.load_chroms({chrom:ag},function(){ad.change_chrom(ag,ac,ai)});return}else{if(ag!==ad.chrom){ad.chrom=ag;ad.chrom_select.val(ad.chrom);ad.max_high=ah.len-1;ad.reset();for(var af=0,ab=ad.drawables.length;af<ab;af++){var ae=ad.drawables[af];if(ae.init){ae.init()}}if(ad.reference_track){ad.reference_track.init()}}if(ac===undefined&&ai===undefined){ad.low=0;ad.high=ad.max_high}else{ad.low=(ac!==undefined?Math.max(ac,0):0);if(ai===undefined){ad.low=Math.max(ad.low-15,0);ad.high=ad.low+30}else{ad.high=Math.min(ai,ad.max_high)}}ad.reset_overview();ad.request_redraw()}},go_to:function(af){af=af.replace(/,/g,"");af=af.replace(/:|\-/g," ");var ac=af.split(/\s+/),ae=ac[0],ad=(ac[1]?parseInt(ac[1],10):undefined),ab=(ac[2]?parseInt(ac[2],10):undefined);this.change_chrom(ae,ad,ab)},move_fraction:function(ad){var ab=this;var ac=ab.high-ab.low;this.move_delta(ad*ac)},move_delta:function(ae){var ab=this;var ad=ab.high-ab.low;if(ab.low-ae<ab.max_low){ab.low=ab.max_low;ab.high=ab.max_low+ad}else{if(ab.high-ae>ab.max_high){ab.high=ab.max_high;ab.low=ab.max_high-ad}else{ab.high-=ae;ab.low-=ae}}ab.request_redraw({data_fetch:false});if(this.redraw_on_move_fn){clearTimeout(this.redraw_on_move_fn)}this.redraw_on_move_fn=setTimeout(function(){ab.request_redraw()},200);var ac=ab.chrom_select.val();this.trigger_navigate(ac,ab.low,ab.high,true)},add_drawable:function(ab){y.prototype.add_drawable.call(this,ab);ab.init();this.changed();this.update_intro_div()},add_label_track:function(ab){ab.view=this;ab.init();this.label_tracks.push(ab)},remove_drawable:function(ad,ac){y.prototype.remove_drawable.call(this,ad);if(ac){var ab=this;ad.container_div.hide(0,function(){$(this).remove();ab.update_intro_div()})}},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},request_redraw:function(ac,ad){var ab=this,ae=(ad?[ad]:ab.drawables);aa.each(ae,function(af){var ag=aa.find(ab.tracks_to_be_redrawn,function(ah){return ah[0]===af});if(ag){ag[1]=ac}else{ab.tracks_to_be_redrawn.push([af,ac])}});if(!this.requested_redraw){requestAnimationFrame(function(){ab._redraw()});this.requested_redraw=true}},_redraw:function(){this.requested_redraw=false;var ab=this.low,af=this.high;if(ab<this.max_low){ab=this.max_low}if(af>this.max_high){af=this.max_high}var ac=this.high-this.low;if(this.high!==0&&ac<this.min_separation){af=ab+this.min_separation}this.low=Math.floor(ab);this.high=Math.ceil(af);this.update_location(this.low,this.high);this.resolution_px_b=this.viewport_container.width()/(this.high-this.low);var ae=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var ag=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var ad=13;this.overview_box.css({left:ae,width:Math.max(ad,ag)}).show();if(ag<ad){this.overview_box.css("left",ae-(ad-ag)/2)}if(this.overview_highlight){this.overview_highlight.css({left:ae,width:ag})}aa.each(this.tracks_to_be_redrawn,function(aj){var ah=aj[0],ai=aj[1];if(ah){ah._draw(ai)}});this.tracks_to_be_redrawn=[];aa.each(this.label_tracks,function(ah){ah._draw()})},zoom_in:function(ac,ad){if(this.max_high===0||this.high-this.low<=this.min_separation){return}var ae=this.high-this.low,af=ae/2+this.low,ab=(ae/this.zoom_factor)/2;if(ac){af=ac/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(af-ab);this.high=Math.round(af+ab);this.changed();this.request_redraw()},zoom_out:function(){if(this.max_high===0){return}var ac=this.high-this.low,ad=ac/2+this.low,ab=(ac*this.zoom_factor)/2;this.low=Math.round(ad-ab);this.high=Math.round(ad+ab);this.changed();this.request_redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.request_redraw()},set_overview:function(ad){if(this.overview_drawable){if(this.overview_drawable.dataset.id===ad.dataset.id){return}this.overview_viewport.find(".track").remove()}var ac=ad.copy({content_div:this.overview_viewport}),ab=this;ac.header_div.hide();ac.is_overview=true;ab.overview_drawable=ac;this.overview_drawable.postdraw_actions=function(){ab.overview_highlight.show().height(ab.overview_drawable.content_div.height());ab.overview_viewport.height(ab.overview_drawable.content_div.height()+ab.overview_box.outerHeight());ab.overview_close.show();ab.resize_window()};ab.overview_drawable.request_draw();this.changed()},reset_overview:function(){$(".tooltip").remove();this.overview_viewport.find(".track-tile").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide();view.resize_window();view.overview_drawable=null}});var q=P.Tool.extend({defaults:{track:null},initialize:function(ab){P.Tool.prototype.initialize.call(this,ab);var ac=true;if(ab.tool_state!==undefined&&ab.tool_state.hidden!==undefined){ac=ab.tool_state.hidden}this.set("hidden",ac);this.remove_inputs(["data","hidden_data","conditional"])},state_dict:function(ab){return aa.extend(this.get_inputs_dict(),{hidden:!this.is_visible()})}});var t=Backbone.View.extend({events:{"change :input":"update_value"},render:function(){var ad=this.$el.addClass("param-row"),ae=this.model;var ab=$("<div>").addClass("param-label").text(ae.get("label")).appendTo(ad);var ac=$("<div/>").addClass("param-input").html(ae.get("html")).appendTo(ad);ac.find(":input").val(ae.get("value"));$("<div style='clear: both;'/>").appendTo(ad)},update_value:function(ab){this.model.set_value($(ab.target).val())}});var Z=Backbone.View.extend({initialize:function(ab){this.model.on("change:hidden",this.set_visible,this)},render:function(){var ac=this;tool=this.model,parent_div=this.$el.addClass("dynamic-tool").hide();parent_div.bind("drag",function(ag){ag.stopPropagation()}).click(function(ag){ag.stopPropagation()}).bind("dblclick",function(ag){ag.stopPropagation()}).keydown(function(ag){ag.stopPropagation()});var ad=$("<div class='tool-name'>").appendTo(parent_div).text(tool.get("name"));tool.get("inputs").each(function(ah){var ag=new t({model:ah});ag.render();parent_div.append(ag.$el)});parent_div.find("input").click(function(){$(this).select()});var ae=$("<div>").addClass("param-row").appendTo(parent_div);var af=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(ae);var ab=$("<input type='submit'>").attr("value","Run on visible region").appendTo(ae);ab.click(function(){ac.run_on_region()});af.click(function(){ac.run_on_dataset()});if(tool.is_visible()){this.$el.show()}},set_visible:function(){if(this.model.is_visible()){this.$el.show()}else{this.$el.hide()}},update_params:function(){for(var ab=0;ab<this.params.length;ab++){this.params[ab].update_value()}},run_on_dataset:function(){var ab=this.model;this.run({target_dataset_id:this.model.get("track").dataset.id,action:"rerun",tool_id:ab.id},null,function(ac){Galaxy.modal.show({title:ab.get("name")+" is Running",body:ab.get("name")+" is running on the complete dataset. Tool outputs are in dataset's history.",buttons:{Close:function(){Galaxy.modal.hide()}}})})},run_on_region:function(){var ac=this.model.get("track"),af=this.model,ah=new w.GenomeRegion({chrom:ac.view.chrom,start:ac.view.low,end:ac.view.high}),ai={target_dataset_id:ac.dataset.id,action:"rerun",tool_id:af.id,regions:[ah.toJSON()]},ag=ac,ak=af.get("name")+ag.tool_region_and_parameters_str(ah),ab;if(ag.container===view){var aj=new N(view,view,{name:ac.config.get_value("name")});var ae=ag.container.replace_drawable(ag,aj,false);aj.container_div.insertBefore(ag.view.content_div.children()[ae]);aj.add_drawable(ag);ag.container_div.appendTo(aj.content_div);ab=aj}else{ab=ag.container}var ad=new ag.constructor(view,ab,{name:ak,hda_ldda:"hda"});ad.init_for_tool_data();ad.change_mode(ag.mode);ad.set_filters_manager(ag.filters_manager.copy(ad));ad.update_icons();ab.add_drawable(ad);ad.tiles_div.text("Starting job.");this.run(ai,ad,function(al){ad.set_dataset(new W.Dataset(al));ad.tiles_div.text("Running job.");ad.init()})},run:function(ab,ad,ae){ab.inputs=this.model.get_inputs_dict();var ac=new j.ServerStateDeferred({ajax_settings:{url:galaxy_config.root+"api/tools",data:JSON.stringify(ab),dataType:"json",contentType:"application/json",type:"POST"},interval:2000,success_fn:function(af){return af!=="pending"}});$.when(ac.go()).then(function(af){if(af==="no converter"){ad.container_div.addClass("error");ad.content_div.text(H)}else{if(af.error){ad.container_div.addClass("error");ad.content_div.text(x+af.message)}else{ae(af)}}})}});var C=function(ab,ac){J.Scaler.call(this,ac);this.filter=ab};C.prototype.gen_val=function(ab){if(this.filter.high===Number.MAX_VALUE||this.filter.low===-Number.MAX_VALUE||this.filter.low===this.filter.high){return this.default_val}return((parseFloat(ab[this.filter.index])-this.filter.low)/(this.filter.high-this.filter.low))};var b=function(ab,ae,af,ac,ad){this.track=ab;this.region=ae;this.low=ae.get("start");this.high=ae.get("end");this.w_scale=af;this.canvas=ac;this.html_elt=$("<div class='track-tile'/>").append(ac);this.data=ad;this.stale=false};b.prototype.predisplay_actions=function(){};var K=function(ab,ae,af,ac,ad){b.call(this,ab,ae,af,ac,ad)};K.prototype.predisplay_actions=function(){};var M=function(ad,ai,ak,ac,af,ag,al,ab,ah,ae,aj){b.call(this,ad,ai,ak,ac,af);this.mode=ag;this.all_slotted=ab;this.feature_mapper=ah;this.has_icons=false;this.incomplete_features=ae;this.seq_data=aj};o(M.prototype,b.prototype);M.prototype.predisplay_actions=function(){var ac=this,ab={};if(ac.mode!=="Pack"){return}$(this.html_elt).hover(function(){this.hovered=true;$(this).mousemove()},function(){this.hovered=false;$(this).parents(".track-content").children(".overlay").children(".feature-popup").remove()}).mousemove(function(an){if(!this.hovered){return}var ai=$(this).offset(),am=an.pageX-ai.left,al=an.pageY-ai.top,ar=ac.feature_mapper.get_feature_data(am,al),aj=(ar?ar[0]:null);$(this).parents(".track-content").children(".overlay").children(".feature-popup").each(function(){if(!aj||$(this).attr("id")!==aj.toString()){$(this).remove()}});if(ar){var ae=ab[aj];if(!ae){var ao={name:ar[3],start:ar[1],end:ar[2],strand:ar[4]},ah=ac.track.filters_manager.filters,ag;for(var ak=0;ak<ah.length;ak++){ag=ah[ak];ao[ag.name]=ar[ag.index]}ae=$("<div/>").attr("id",aj).addClass("feature-popup");var at=$("<table/>"),aq,ap,au;for(aq in ao){ap=ao[aq];au=$("<tr/>").appendTo(at);$("<th/>").appendTo(au).text(aq);$("<td/>").attr("align","left").appendTo(au).text(typeof(ap)==="number"?U(ap,2):ap)}ae.append($("<div class='feature-popup-inner'>").append(at));ab[aj]=ae}ae.appendTo($(this).parents(".track-content").children(".overlay"));var af=am+parseInt(ac.html_elt.css("left"),10)-ae.width()/2,ad=al+parseInt(ac.html_elt.css("top"),10)+7;ae.css("left",af+"px").css("top",ad+"px")}else{if(!an.isPropagationStopped()){an.stopPropagation();$(this).siblings().each(function(){$(this).trigger(an)})}}}).mouseleave(function(){$(this).parents(".track-content").children(".overlay").children(".feature-popup").remove()})};var f=function(ac,ab,ad){o(ad,{drag_handle_class:"draghandle"});p.call(this,ac,ab,ad);this.dataset=null;if(ad.dataset){this.dataset=(ad.dataset instanceof Backbone.Model?ad.dataset:new W.Dataset(ad.dataset))}this.dataset_check_type="converted_datasets_state";this.data_url_extra_params={};this.data_query_wait=("data_query_wait" in ad?ad.data_query_wait:I);this.data_manager=("data_manager" in ad?ad.data_manager:new w.GenomeDataManager({dataset:this.dataset,genome:new w.Genome({key:ac.dbkey,chroms_info:{chrom_info:ac.chrom_data}}),data_mode_compatible:this.data_and_mode_compatible,can_subset:this.can_subset}));this.min_height_px=16;this.max_height_px=800;this.visible_height_px=this.config.get_value("height");this.content_div=$("<div class='track-content'>").appendTo(this.container_div);if(this.container){this.container.content_div.append(this.container_div);if(!("resize" in ad)||ad.resize){this.add_resize_handle()}}};o(f.prototype,p.prototype,{action_icons_def:[{name:"mode_icon",title:"Set display mode",css_class:"chevron-expand",on_click_fn:function(){}},p.prototype.action_icons_def[0],{name:"overview_icon",title:"Set as overview",css_class:"application-dock-270",on_click_fn:function(ab){ab.view.set_overview(ab)}},p.prototype.action_icons_def[1],{name:"filters_icon",title:"Filters",css_class:"ui-slider-050",on_click_fn:function(ab){if(ab.filters_manager.visible()){ab.filters_manager.clear_filters()}else{ab.filters_manager.init_filters()}ab.filters_manager.toggle()}},{name:"tools_icon",title:"Tool",css_class:"hammer",on_click_fn:function(ab){ab.tool.toggle();if(ab.tool.is_visible()){ab.set_name(ab.config.get_value("name")+ab.tool_region_and_parameters_str())}else{ab.revert_name()}$(".tooltip").remove()}},{name:"param_space_viz_icon",title:"Tool parameter space visualization",css_class:"arrow-split",on_click_fn:function(ab){var ae='<strong>Tool</strong>: <%= track.tool.get("name") %><br/><strong>Dataset</strong>: <%= track.config.get_value("name") %><br/><strong>Region(s)</strong>: <select name="regions"><option value="cur">current viewing area</option><option value="bookmarks">bookmarks</option><option value="both">current viewing area and bookmarks</option></select>',ad=aa.template(ae,{track:ab});var ag=function(){Galaxy.modal.hide();$(window).unbind("keypress.check_enter_esc")},ac=function(){var ai=$('select[name="regions"] option:selected').val(),ak,ah=new w.GenomeRegion({chrom:view.chrom,start:view.low,end:view.high}),aj=aa.map($(".bookmark"),function(al){return new w.GenomeRegion({from_str:$(al).children(".position").text()})});if(ai==="cur"){ak=[ah]}else{if(ai==="bookmarks"){ak=aj}else{ak=[ah].concat(aj)}}Galaxy.modal.hide();window.location.href=galaxy_config.root+"visualization/sweepster?"+$.param({dataset_id:ab.dataset.id,hda_ldda:ab.dataset.get("hda_ldda"),regions:JSON.stringify(new Backbone.Collection(ak).toJSON())})},af=function(ah){if((ah.keyCode||ah.which)===27){ag()}else{if((ah.keyCode||ah.which)===13){ac()}}};Galaxy.modal.show({title:"Visualize tool parameter space and output from different parameter settings?",body:ad,buttons:{No:ag,Yes:ac}})}},p.prototype.action_icons_def[2]],can_draw:function(){return this.dataset&&p.prototype.can_draw.call(this)},build_container_div:function(){return $("<div/>").addClass("track").attr("id","track_"+this.id)},build_header_div:function(){var ab=$("<div class='track-header'/>");if(this.view.editor){this.drag_div=$("<div/>").addClass(this.drag_handle_class).appendTo(ab)}this.name_div=$("<div/>").addClass("track-name").appendTo(ab).text(this.config.get_value("name")).attr("id",this.config.get_value("name").replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase());return ab},set_dataset:function(ab){this.dataset=ab;this.data_manager.set("dataset",ab)},on_resize:function(){this.request_draw({clear_tile_cache:true})},add_resize_handle:function(){var ab=this;var ae=false;var ad=false;var ac=$("<div class='track-resize'>");$(ab.container_div).hover(function(){if(ab.config.get_value("content_visible")){ae=true;ac.show()}},function(){ae=false;if(!ad){ac.hide()}});ac.hide().bind("dragstart",function(af,ag){ad=true;ag.original_height=$(ab.content_div).height()}).bind("drag",function(ag,ah){var af=Math.min(Math.max(ah.original_height+ah.deltaY,ab.min_height_px),ab.max_height_px);$(ab.tiles_div).css("height",af);ab.visible_height_px=(ab.max_height_px===af?0:af);ab.on_resize()}).bind("dragend",function(af,ag){ab.tile_cache.clear();ad=false;if(!ae){ac.hide()}ab.config.set_value("height",ab.visible_height_px);ab.changed()}).appendTo(ab.container_div)},set_display_modes:function(ae,ah){this.display_modes=ae;this.mode=(ah?ah:(this.config&&this.config.get_value("mode")?this.config.get_value("mode"):this.display_modes[0]));this.action_icons.mode_icon.attr("title","Set display mode (now: "+this.mode+")");var ac=this,af={};for(var ad=0,ab=ac.display_modes.length;ad<ab;ad++){var ag=ac.display_modes[ad];af[ag]=function(ai){return function(){ac.change_mode(ai);ac.icons_div.show();ac.container_div.mouseleave(function(){ac.icons_div.hide()})}}(ag)}make_popupmenu(this.action_icons.mode_icon,af)},build_action_icons:function(){p.prototype.build_action_icons.call(this,this.action_icons_def);if(this.display_modes!==undefined){this.set_display_modes(this.display_modes)}},hide_contents:function(){this.tiles_div.hide();this.container_div.find(".yaxislabel, .track-resize").hide()},show_contents:function(){this.tiles_div.show();this.container_div.find(".yaxislabel, .track-resize").show();this.request_draw()},get_type:function(){if(this instanceof V){return"LabelTrack"}else{if(this instanceof B){return"ReferenceTrack"}else{if(this instanceof g){return"LineTrack"}else{if(this instanceof S){return"ReadTrack"}else{if(this instanceof Y){return"VariantTrack"}else{if(this instanceof e){return"CompositeTrack"}else{if(this instanceof c){return"FeatureTrack"}}}}}}}return""},show_message:function(ab){this.tiles_div.remove();return $("<span/>").addClass("message").html(ab).appendTo(this.content_div)},init:function(ad){var ac=this;ac.enabled=false;ac.tile_cache.clear();ac.data_manager.clear();ac.content_div.children().remove();ac.container_div.removeClass("nodata error pending");ac.tiles_div=$("<div/>").addClass("tiles").appendTo(ac.content_div);if(!ac.dataset.id){return}var ab=$.Deferred(),ae={hda_ldda:ac.dataset.get("hda_ldda"),data_type:this.dataset_check_type,chrom:ac.view.chrom,retry:ad};$.getJSON(this.dataset.url(),ae,function(af){if(!af||af==="error"||af.kind==="error"){ac.container_div.addClass("error");var ag=ac.show_message(m);if(af.message){ag.append($("<a href='javascript:void(0);'></a>").text("View error").click(function(){Galaxy.modal.show({title:"Trackster Error",body:"<pre>"+af.message+"</pre>",buttons:{Close:function(){Galaxy.modal.hide()}}})}));ag.append($("<span/>").text(" "));ag.append($("<a href='javascript:void(0);'></a>").text("Try again").click(function(){ac.init(true)}))}}else{if(af==="no converter"){ac.container_div.addClass("error");ac.show_message(H)}else{if(af==="no data"||(af.data!==undefined&&(af.data===null||af.data.length===0))){ac.container_div.addClass("nodata");ac.show_message(E)}else{if(af==="pending"){ac.container_div.addClass("pending");ac.show_message(u);setTimeout(function(){ac.init()},ac.data_query_wait)}else{if(af==="data"||af.status==="data"){if(af.valid_chroms){ac.valid_chroms=af.valid_chroms;ac.update_icons()}ac.tiles_div.text(T);if(ac.view.chrom){ac.tiles_div.text("");ac.tiles_div.css("height",ac.visible_height_px+"px");ac.enabled=true;$.when.apply($,ac.predraw_init()).done(function(){ab.resolve();ac.container_div.removeClass("nodata error pending");ac.request_draw()})}else{ab.resolve()}}}}}}});this.update_icons();return ab},predraw_init:function(){var ab=this;return $.getJSON(ab.dataset.url(),{data_type:"data",stats:true,chrom:ab.view.chrom,low:0,high:ab.view.max_high,hda_ldda:ab.dataset.get("hda_ldda")},function(ac){var ae=ac.data;if(ae&&ae.min&&ae.max){var ad=ae.min,af=ae.max;ad=Math.floor(Math.min(0,Math.max(ad,ae.mean-2*ae.sd)));af=Math.ceil(Math.max(0,Math.min(af,ae.mean+2*ae.sd)));ab.config.set_default_value("min_value",ad);ab.config.set_default_value("max_value",af);ab.config.set_value("min_value",ad);ab.config.set_value("max_value",af)}})},get_drawables:function(){return this}});var L=function(ad,ac,af){f.call(this,ad,ac,af);var ab=this;k(ab.container_div,ab.drag_handle_class,".group",ab);this.filters_manager=new h.FiltersManager(this,("filters" in af?af.filters:null));this.data_manager.set("filters_manager",this.filters_manager);this.filters_available=false;this.tool=(af.tool?new q(aa.extend(af.tool,{track:this,tool_state:af.tool_state})):null);this.tile_cache=new w.Cache(O);this.left_offset=0;if(this.header_div){this.set_filters_manager(this.filters_manager);if(this.tool){var ae=new Z({model:this.tool});ae.render();this.dynamic_tool_div=ae.$el;this.header_div.after(this.dynamic_tool_div)}}this.tiles_div=$("<div/>").addClass("tiles").appendTo(this.content_div);if(!this.config.get_value("content_visible")){this.tiles_div.hide()}this.overlay_div=$("<div/>").addClass("overlay").appendTo(this.content_div);if(af.mode){this.change_mode(af.mode)}};o(L.prototype,p.prototype,f.prototype,{action_icons_def:f.prototype.action_icons_def.concat([{name:"show_more_rows_icon",title:"To minimize track height, not all feature rows are displayed. Click to display more rows.",css_class:"exclamation",on_click_fn:function(ab){$(".tooltip").remove();ab.slotters[ab.view.resolution_px_b].max_rows*=2;ab.request_draw({clear_tile_cache:true})},hide:true}]),copy:function(ab){var ac=this.to_dict();o(ac,{data_manager:this.data_manager});var ad=new this.constructor(this.view,ab,ac);ad.change_mode(this.mode);ad.enabled=this.enabled;return ad},set_filters_manager:function(ab){this.filters_manager=ab;this.header_div.after(this.filters_manager.parent_div)},to_dict:function(){return{track_type:this.get_type(),dataset:{id:this.dataset.id,hda_ldda:this.dataset.get("hda_ldda")},prefs:this.config.to_key_value_dict(),mode:this.mode,filters:this.filters_manager.to_dict(),tool_state:(this.tool?this.tool.state_dict():{})}},set_min_max:function(){var ab=this;return $.getJSON(ab.dataset.url(),{data_type:"data",stats:true,chrom:ab.view.chrom,low:0,high:ab.view.max_high,hda_ldda:ab.dataset.get("hda_ldda")},function(ac){var ae=ac.data;if(isNaN(parseFloat(ab.config.get_value("min_value")))||isNaN(parseFloat(ab.config.get_value("max_value")))){var ad=ae.min,af=ae.max;ad=Math.floor(Math.min(0,Math.max(ad,ae.mean-2*ae.sd)));af=Math.ceil(Math.max(0,Math.min(af,ae.mean+2*ae.sd)));ab.config.set_value("min_value",ad);ab.config.set_value("max_value",af)}})},change_mode:function(ac){var ab=this;ab.mode=ac;ab.config.set_value("mode",ac);if(ac==="Auto"){this.data_manager.clear()}ab.request_draw({clear_tile_cache:true});this.action_icons.mode_icon.attr("title","Set display mode (now: "+ab.mode+")");return ab},update_icons:function(){var ab=this;if(ab.filters_available){ab.action_icons.filters_icon.show()}else{ab.action_icons.filters_icon.hide()}if(ab.tool){ab.action_icons.tools_icon.show();ab.action_icons.param_space_viz_icon.show()}else{ab.action_icons.tools_icon.hide();ab.action_icons.param_space_viz_icon.hide()}},_gen_tile_cache_key:function(ac,ab){return ac+"_"+ab},request_draw:function(ab){if(ab&&ab.clear_tile_cache){this.tile_cache.clear()}this.view.request_redraw(ab,this)},before_draw:function(){this.max_height_px=0},_draw:function(ap){if(!this.can_draw()){return}var am=ap&&ap.clear_after,ak=this.view.low,af=this.view.high,ai=af-ak,ac=this.view.container.width(),ao=this.view.resolution_px_b,ae=1/ao;if(this.is_overview){ak=this.view.max_low;af=this.view.max_high;ao=ac/(view.max_high-view.max_low);ae=1/ao}this.before_draw();this.tiles_div.children().addClass("remove");var ab=Math.floor(ak/(ae*Q)),aj,al,ag,ah=[],an=[];while((ab*Q*ae)<af){aj=Math.floor(ab*Q*ae);al=new w.GenomeRegion({chrom:this.view.chrom,start:aj,end:Math.min(aj+Math.ceil(Q*ae),this.view.max_high)});ag=this.draw_helper(al,ao,ap);ah.push(ag);$.when(ag).then(function(aq){an.push(aq)});ab+=1}if(!am){this.tiles_div.children(".remove").removeClass("remove").remove()}var ad=this;$.when.apply($,ah).then(function(){ad.tiles_div.children(".remove").remove();an=aa.filter(an,function(aq){return aq!==null});if(an.length!==0){ad.postdraw_actions(an,ac,ao,am)}})},_add_yaxis_label:function(ae,ag){var ac=this,af=(ae==="max"?"top":"bottom"),ah=(ae==="max"?"max":"min"),ab=(ae==="max"?"max_value":"min_value"),ad=this.container_div.find(".yaxislabel."+af);ag=ag||function(){ac.request_draw({clear_tile_cache:true})};if(ad.length!==0){ad.text(ac.config.get_value(ab))}else{ad=$("<div/>").text(ac.config.get_value(ab)).make_text_editable({num_cols:12,on_finish:function(ai){$(".tooltip").remove();ac.config.set_value(ab,ai);ag()},help_text:"Set "+ah+" value"}).addClass("yaxislabel "+af).css("color",this.config.get_value("label_color"));this.container_div.prepend(ad)}},postdraw_actions:function(ae,af,ah,ab){var ad=aa.filter(ae,function(ai){return(ai instanceof K)});if(ad.length>0){this.max_height_px=0;var ac=this;aa.each(ae,function(ai){if(!(ai instanceof K)){ai.html_elt.remove();ac.draw_helper(ai.region,ah,{force:true,mode:"Coverage"})}});ac._add_yaxis_label("max")}else{this.container_div.find(".yaxislabel").remove();var ag=aa.find(ae,function(ai){return ai.has_icons});if(ag){aa.each(ae,function(ai){if(!ai.has_icons){ai.html_elt.css("padding-top",D)}})}}},get_mode:function(ab){return this.mode},update_auto_mode:function(ab){},_get_drawables:function(){return[this]},draw_helper:function(ak,am,an){if(!an){an={}}var ac=an.force,ah=an.mode||this.mode,ae=1/am,ad=this,af=this._get_drawables(),al=this._gen_tile_cache_key(am,ak),ag=function(ao){return(ao&&"track" in ao)};var ai=(ac?undefined:ad.tile_cache.get_elt(al));if(ai){if(ag(ai)){ad.show_tile(ai,am)}return ai}if(an.data_fetch===false){return null}var aj=function(){var ao=(aa.find(A,function(aq){return aq===ah})?"Coverage":ah);var ap=aa.map(af,function(aq){return aq.data_manager.get_data(ak,ao,ae,ad.data_url_extra_params)});if(view.reference_track){ap.push(view.reference_track.data_manager.get_data(ak,ah,ae,view.reference_track.data_url_extra_params))}return ap};var ab=$.Deferred();ad.tile_cache.set_elt(al,ab);$.when.apply($,aj()).then(function(){var ao=aj(),au=ao,aA;if(aa.find(ao,function(aC){return j.is_deferred(aC)})){ad.tile_cache.set_elt(al,undefined);$.when(ad.draw_helper(ak,am,an)).then(function(aC){ab.resolve(aC)});return}if(view.reference_track){aA=view.reference_track.data_manager.subset_entry(ao.pop(),ak)}var av=[],ar=[];aa.each(af,function(aF,aC){var aE=aF.mode,aD=au[aC];if(aE==="Auto"){aE=aF.get_mode(aD);aF.update_auto_mode(aE)}av.push(aE);ar.push(aF.get_canvas_height(aD,aE,am,ap))});var at=ad.view.canvas_manager.new_canvas(),aw=ak.get("start"),aB=ak.get("end"),aq=0,ap=Math.ceil((aB-aw)*am)+ad.left_offset,ay=aa.max(ar),ax;at.width=ap;at.height=(an.height||ay);var az=at.getContext("2d");az.translate(ad.left_offset,0);if(af.length>1){az.globalAlpha=0.5;az.globalCompositeOperation="source-over"}aa.each(af,function(aD,aC){ax=aD.draw_tile(au[aC],az,av[aC],ak,am,aA)});if(ax!==undefined){ad.tile_cache.set_elt(al,ax);ad.show_tile(ax,am)}ab.resolve(ax)});return ab},get_canvas_height:function(ab,ad,ae,ac){return this.visible_height_px},_draw_line_track_tile:function(ab,ad,ag,af,ah){var ae=ad.canvas,ac=new J.LinePainter(ab.data,af.get("start"),af.get("end"),this.config.to_key_value_dict(),ag);ac.draw(ad,ae.width,ae.height,ah);return new K(this,af,ah,ae,ab.data)},draw_tile:function(ab,ac,af,ae,ag,ad){},show_tile:function(ad,ag){var ac=this,ab=ad.html_elt;ad.predisplay_actions();var af=(ad.low-(this.is_overview?this.view.max_low:this.view.low))*ag;if(this.left_offset){af-=this.left_offset}ab.css("left",af);if(ab.hasClass("remove")){ab.removeClass("remove")}else{this.tiles_div.append(ab)}ab.css("height","auto");this.max_height_px=Math.max(this.max_height_px,ab.height()-2);ab.parent().children().css("height",this.max_height_px+"px");var ae=this.max_height_px;if(this.visible_height_px!==0){ae=Math.min(this.max_height_px,this.visible_height_px)}this.tiles_div.css("height",ae+"px")},tool_region_and_parameters_str:function(ae){var ab=this,ad=(ae!==undefined?ae.toString():"all"),ac=aa.values(ab.tool.get_inputs_dict()).join(", ");return" - region=["+ad+"], parameters=["+ac+"]"},data_and_mode_compatible:function(ab,ac){if(ac==="Auto"){return true}else{if(ac==="Coverage"){return ab.dataset_type==="bigwig"}else{if(ab.dataset_type==="bigwig"||ab.extra_info==="no_detail"){return false}else{return true}}}},can_subset:function(ab){if(ab.message||ab.extra_info==="no_detail"){return false}else{if(ab.dataset_type==="bigwig"){return(ab.data[1][0]-ab.data[0][0]===1)}}return true},init_for_tool_data:function(){this.data_manager.set("data_type","raw_data");this.data_query_wait=1000;this.dataset_check_type="state"}});var V=function(ac,ab){var ad={resize:false};f.call(this,ac,ab,ad);this.container_div.addClass("label-track")};o(V.prototype,f.prototype,{build_header_div:function(){},init:function(){this.enabled=true},predraw_init:function(){},_draw:function(af){var ad=this.view,ae=ad.high-ad.low,ai=Math.floor(Math.pow(10,Math.floor(Math.log(ae)/Math.log(10)))),ab=Math.floor(ad.low/ai)*ai,ag=this.view.container.width(),ac=$("<div/>").addClass("label-container");while(ab<ad.high){var ah=(ab-ad.low)/ae*ag;ac.append($("<div/>").addClass("label").text(commatize(ab)).css({left:ah}));ab+=ai}this.content_div.children(":first").remove();this.content_div.append(ac)}});var e=function(ac,ab,af){L.call(this,ac,ab,af);this.drawables=[];if("drawables" in af){var ae;for(var ad=0;ad<af.drawables.length;ad++){ae=af.drawables[ad];this.drawables[ad]=n(ae,ac,null);if(ae.left_offset>this.left_offset){this.left_offset=ae.left_offset}}this.enabled=true}aa.each(this.drawables,function(ag){if(ag instanceof c||ag instanceof S){ag.change_mode("Coverage")}});this.update_icons();this.obj_type="CompositeTrack"};o(e.prototype,L.prototype,{display_modes:A,config_params:aa.union(p.prototype.config_params,[{key:"min_value",label:"Min Value",type:"float",default_value:undefined},{key:"max_value",label:"Max Value",type:"float",default_value:undefined},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:30,hidden:true}]),action_icons_def:[{name:"composite_icon",title:"Show individual tracks",css_class:"layers-stack",on_click_fn:function(ab){$(".tooltip").remove();ab.show_group()}}].concat(L.prototype.action_icons_def),to_dict:y.prototype.to_dict,add_drawable:y.prototype.add_drawable,unpack_drawables:y.prototype.unpack_drawables,config_onchange:function(){this.set_name(this.config.get_value("name"));this.request_draw({clear_tile_cache:true})},on_resize:function(){var ab=this.visible_height_px;aa.each(this.drawables,function(ac){ac.visible_height_px=ab});f.prototype.on_resize.call(this)},change_mode:function(ab){L.prototype.change_mode.call(this,ab);for(var ac=0;ac<this.drawables.length;ac++){this.drawables[ac].change_mode(ab)}},init:function(){var ad=[];for(var ac=0;ac<this.drawables.length;ac++){ad.push(this.drawables[ac].init())}var ab=this;$.when.apply($,ad).then(function(){ab.enabled=true;ab.request_draw()})},update_icons:function(){this.action_icons.filters_icon.hide();this.action_icons.tools_icon.hide();this.action_icons.param_space_viz_icon.hide()},can_draw:p.prototype.can_draw,_get_drawables:function(){return this.drawables},show_group:function(){var ae=new N(this.view,this.container,{name:this.config.get_value("name")}),ab;for(var ad=0;ad<this.drawables.length;ad++){ab=this.drawables[ad];ab.update_icons();ae.add_drawable(ab);ab.container=ae;ae.content_div.append(ab.container_div)}var ac=this.container.replace_drawable(this,ae,true);ae.request_draw({clear_tile_cache:true})},before_draw:function(){var ac=aa.min(aa.map(this.drawables,function(ad){return ad.config.get_value("min_value")})),ab=aa.max(aa.map(this.drawables,function(ad){return ad.config.get_value("max_value")}));this.config.set_value("min_value",ac);this.config.set_value("max_value",ab);aa.each(this.drawables,function(ad){ad.config.set_value("min_value",ac);ad.config.set_value("max_value",ab)})},update_all_min_max:function(){var ac=this,ab=this.config.get_value("min_value"),ad=this.config.get_value("max_value");aa.each(this.drawables,function(ae){ae.config.set_value("min_value",ab);ae.config.set_value("max_value",ad)});this.request_draw({clear_tile_cache:true})},postdraw_actions:function(ah,ab,ak,ag){var af=-1,ad;for(ad=0;ad<ah.length;ad++){var ai=ah[ad].html_elt.find("canvas").height();if(ai>af){af=ai}}for(ad=0;ad<ah.length;ad++){var ae=ah[ad];if(ae.html_elt.find("canvas").height()!==af){this.draw_helper(ae.region,ak,{force:true,height:af});ae.html_elt.remove()}}var ac=this,aj=function(){ac.update_all_min_max()};this._add_yaxis_label("min",aj);this._add_yaxis_label("max",aj)}});var B=function(ab){L.call(this,ab,{content_div:ab.top_labeltrack},{resize:false});this.left_offset=ab.canvas_manager.char_width_px;this.container_div.addClass("reference-track");this.data_url=galaxy_config.root+"api/genomes/"+this.view.dbkey;this.data_url_extra_params={reference:true};this.data_manager=new w.GenomeReferenceDataManager({data_url:this.data_url,can_subset:this.can_subset});this.hide_contents()};o(B.prototype,p.prototype,L.prototype,{config_params:aa.union(p.prototype.config_params,[{key:"height",type:"int",default_value:13,hidden:true}]),build_header_div:function(){},init:function(){this.data_manager.clear();this.enabled=true},predraw_init:function(){},can_draw:p.prototype.can_draw,draw_helper:function(ac,ad,ab){if(ad>this.view.canvas_manager.char_width_px){this.tiles_div.show();return L.prototype.draw_helper.call(this,ac,ad,ab)}else{this.tiles_div.hide();return null}},can_subset:function(ab){return true},draw_tile:function(ad,aj,ae,ag,ak){var ac=this.data_manager.subset_entry(ad,ag),ai=ac.data;var ab=aj.canvas;aj.font=aj.canvas.manager.default_font;aj.textAlign="center";for(var af=0,ah=ai.length;af<ah;af++){aj.fillStyle=this.view.get_base_color(ai[af]);aj.fillText(ai[af],Math.floor(af*ak),10)}return new b(this,ag,ak,ab,ac)}});var g=function(ac,ab,ad){this.mode="Histogram";L.call(this,ac,ab,ad)};o(g.prototype,p.prototype,L.prototype,{display_modes:A,config_params:aa.union(p.prototype.config_params,[{key:"color",label:"Color",type:"color"},{key:"min_value",label:"Min Value",type:"float",default_value:undefined},{key:"max_value",label:"Max Value",type:"float",default_value:undefined},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:30,hidden:true}]),config_onchange:function(){this.set_name(this.config.get_value("name"));this.request_draw({clear_tile_cache:true})},before_draw:function(){},draw_tile:function(ab,ac,ae,ad,af){return this._draw_line_track_tile(ab,ac,ae,ad,af)},can_subset:function(ab){return(ab.data[1][0]-ab.data[0][0]===1)},postdraw_actions:function(ac,ad,ae,ab){this._add_yaxis_label("max");this._add_yaxis_label("min")}});var r=function(ac,ab,ad){this.mode="Heatmap";L.call(this,ac,ab,ad)};o(r.prototype,p.prototype,L.prototype,{display_modes:["Heatmap"],config_params:aa.union(p.prototype.config_params,[{key:"pos_color",label:"Positive Color",type:"color",default_value:"#FF8C00"},{key:"neg_color",label:"Negative Color",type:"color",default_value:"#4169E1"},{key:"min_value",label:"Min Value",type:"float",default_value:-1},{key:"max_value",label:"Max Value",type:"float",default_value:1},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:500,hidden:true}]),config_onchange:function(){this.set_name(this.config.get_value("name"));this.request_draw({clear_tile_cache:true})},draw_tile:function(ab,ad,ag,af,ah){var ae=ad.canvas,ac=new J.DiagonalHeatmapPainter(ab.data,af.get("start"),af.get("end"),this.config.to_key_value_dict(),ag);ac.draw(ad,ae.width,ae.height,ah);return new b(this,af,ah,ae,ab.data)}});var c=function(ac,ab,ad){L.call(this,ac,ab,ad);this.container_div.addClass("feature-track");this.summary_draw_height=30;this.slotters={};this.start_end_dct={};this.left_offset=200;this.set_painter_from_config()};o(c.prototype,p.prototype,L.prototype,{display_modes:["Auto","Coverage","Dense","Squish","Pack"],config_params:aa.union(p.prototype.config_params,[{key:"block_color",label:"Block color",type:"color"},{key:"reverse_strand_color",label:"Antisense strand color",type:"color"},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true,help:"Show the number of items in each bin when drawing summary histogram"},{key:"min_value",label:"Histogram minimum",type:"float",default_value:null,help:"clear value to set automatically"},{key:"max_value",label:"Histogram maximum",type:"float",default_value:null,help:"clear value to set automatically"},{key:"connector_style",label:"Connector style",type:"select",default_value:"fishbones",options:[{label:"Line with arrows",value:"fishbone"},{label:"Arcs",value:"arcs"}]},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:0,hidden:true}]),config_onchange:function(){this.set_name(this.config.get_value("name"));this.set_painter_from_config();this.request_draw({clear_tile_cache:true})},set_painter_from_config:function(){if(this.config.get_value("connector_style")==="arcs"){this.painter=J.ArcLinkedFeaturePainter}else{this.painter=J.LinkedFeaturePainter}},postdraw_actions:function(an,ae,ap,am){L.prototype.postdraw_actions.call(this,an,ae,ap,am);var ag=this,ah,al=aa.filter(an,function(aq){return(aq instanceof K)});if(al.length===0){var ab={};aa.each(aa.pluck(an,"incomplete_features"),function(aq){aa.each(aq,function(ar){ab[ar[0]]=ar})});var ao=this;aa.each(an,function(aq){ao.draw_tile({data:aa.values(ab)},aq.canvas.getContext("2d"),aq.mode,aq.region,ap,aq.seq_data,true)})}if(ag.filters_manager){var af=ag.filters_manager.filters,aj;for(aj=0;aj<af.length;aj++){af[aj].update_ui_elt()}var ai=false,ak,ad;for(ah=0;ah<an.length;ah++){if(an[ah].data.length){ak=an[ah].data[0];for(aj=0;aj<af.length;aj++){ad=af[aj];if(ad.applies_to(ak)&&ad.min!==ad.max){ai=true;break}}}}if(ag.filters_available!==ai){ag.filters_available=ai;if(!ag.filters_available){ag.filters_manager.hide()}ag.update_icons()}}if(an[0] instanceof M){var ac=true;for(ah=0;ah<an.length;ah++){if(!an[ah].all_slotted){ac=false;break}}if(!ac){this.action_icons.show_more_rows_icon.show()}else{this.action_icons.show_more_rows_icon.hide()}}else{this.action_icons.show_more_rows_icon.hide()}},update_auto_mode:function(ab){if(this.mode==="Auto"){if(ab==="no_detail"){ab="feature spans"}this.action_icons.mode_icon.attr("title","Set display mode (now: Auto/"+ab+")")}},incremental_slots:function(af,ab,ae){var ac=this.view.canvas_manager.dummy_context,ad=this.slotters[af];if(!ad||(ad.mode!==ae)){ad=new (s.FeatureSlotter)(af,ae,z,function(ag){return ac.measureText(ag)});this.slotters[af]=ad}return ad.slot_features(ab)},get_mode:function(ab){if(ab.extra_info==="no_detail"||this.is_overview){mode="no_detail"}else{if(this.view.high-this.view.low>G){mode="Squish"}else{mode="Pack"}}return mode},get_canvas_height:function(ab,af,ag,ac){if(af==="Coverage"||ab.dataset_type==="bigwig"){return this.summary_draw_height}else{var ae=this.incremental_slots(ag,ab.data,af);var ad=new (this.painter)(null,null,null,this.config.to_key_value_dict(),af);return Math.max(this.min_height_px,ad.get_required_height(ae,ac))}},draw_tile:function(am,ar,ap,af,aj,ae,an){var aq=this,ad=ar.canvas,ay=af.get("start"),ac=af.get("end"),ag=this.left_offset;if(am.dataset_type==="bigwig"){return this._draw_line_track_tile(am,ar,ap,af,aj)}var ai=[],ao=this.slotters[aj].slots;all_slotted=true;if(am.data){var ak=this.filters_manager.filters;for(var at=0,av=am.data.length;at<av;at++){var ah=am.data[at];var au=false;var al;for(var ax=0,aC=ak.length;ax<aC;ax++){al=ak[ax];al.update_attrs(ah);if(!al.keep(ah)){au=true;break}}if(!au){ai.push(ah);if(!(ah[0] in ao)){all_slotted=false}}}}var aB=(this.filters_manager.alpha_filter?new C(this.filters_manager.alpha_filter):null),az=(this.filters_manager.height_filter?new C(this.filters_manager.height_filter):null),aA=new (this.painter)(ai,ay,ac,this.config.to_key_value_dict(),ap,aB,az,ae,function(aD){return aq.view.get_base_color(aD)});var aw=null;ar.fillStyle=this.config.get_value("block_color");ar.font=ar.canvas.manager.default_font;ar.textAlign="right";if(am.data){var ab=aA.draw(ar,ad.width,ad.height,aj,ao);aw=ab.feature_mapper;incomplete_features=ab.incomplete_features;aw.translation=-ag}if(!an){return new M(aq,af,aj,ad,am.data,ap,am.message,all_slotted,aw,incomplete_features,ae)}}});var Y=function(ac,ab,ad){L.call(this,ac,ab,ad);this.painter=J.VariantPainter;this.summary_draw_height=30;this.left_offset=30};o(Y.prototype,p.prototype,L.prototype,{display_modes:["Auto","Coverage","Dense","Squish","Pack"],config_params:aa.union(p.prototype.config_params,[{key:"color",label:"Histogram color",type:"color"},{key:"show_sample_data",label:"Show sample data",type:"bool",default_value:true},{key:"show_labels",label:"Show summary and sample labels",type:"bool",default_value:true},{key:"summary_height",label:"Locus summary height",type:"float",default_value:20},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:0,hidden:true}]),config_onchange:function(){this.set_name(this.config.get_value("name"));this.request_draw({clear_tile_cache:true})},draw_tile:function(ab,ae,ag,af,ah){if(ab.dataset_type==="bigwig"){return this._draw_line_track_tile(ab,ae,"Histogram",af,ah)}else{var ad=this.view,ac=new (this.painter)(ab.data,af.get("start"),af.get("end"),this.config.to_key_value_dict(),ag,function(ai){return ad.get_base_color(ai)});ac.draw(ae,ae.canvas.width,ae.canvas.height,ah);return new b(this,af,ah,ae.canvas,ab.data)}},get_canvas_height:function(ab,af,ag,ad){if(ab.dataset_type==="bigwig"){return this.summary_draw_height}else{var ac=(this.dataset.get_metadata("sample_names")?this.dataset.get_metadata("sample_names").length:0);if(ac===0&&ab.data.length!==0){ac=ab.data[0][7].match(/,/g);if(ac===null){ac=1}else{ac=ac.length+1}}var ae=new (this.painter)(null,null,null,this.config.to_key_value_dict(),af);return ae.get_required_height(ac)}},predraw_init:function(){var ab=[f.prototype.predraw_init.call(this)];if(!this.dataset.get_metadata("sample_names")){ab.push(this.dataset.fetch())}return ab},postdraw_actions:function(af,ag,ai,ac){L.prototype.postdraw_actions.call(this,af,ag,ai,ac);var ae=aa.filter(af,function(aj){return(aj instanceof K)});var ad=this.dataset.get_metadata("sample_names");if(ae.length===0&&this.config.get_value("show_labels")&&ad&&ad.length>1){var ab;if(this.container_div.find(".yaxislabel.variant").length===0){ab=this.config.get_value("summary_height")/2;this.tiles_div.prepend($("<div/>").text("Summary").addClass("yaxislabel variant top").css({"font-size":ab+"px",top:(this.config.get_value("summary_height")-ab)/2+"px"}));if(this.config.get_value("show_sample_data")){var ah=ad.join("<br/>");this.tiles_div.prepend($("<div/>").html(ah).addClass("yaxislabel variant top sample").css({top:this.config.get_value("summary_height")}))}}ab=(this.mode==="Squish"?5:10)+"px";$(this.tiles_div).find(".sample").css({"font-size":ab,"line-height":ab});$(this.tiles_div).find(".yaxislabel").css("color",this.config.get_value("label_color"))}else{this.container_div.find(".yaxislabel.variant").remove()}}});var S=function(ac,ab,ad){c.call(this,ac,ab,ad);this.painter=J.ReadPainter;this.update_icons()};o(S.prototype,p.prototype,L.prototype,c.prototype,{config_params:aa.union(p.prototype.config_params,[{key:"block_color",label:"Histogram color",type:"color"},{key:"detail_block_color",label:"Sense strand block color",type:"color",default_value:"#AAAAAA"},{key:"reverse_strand_color",label:"Antisense strand block color",type:"color",default_value:"#DDDDDD"},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_differences",label:"Show differences only",type:"bool",default_value:true},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"min_value",label:"Histogram minimum",type:"float",default_value:null,help:"clear value to set automatically"},{key:"max_value",label:"Histogram maximum",type:"float",default_value:null,help:"clear value to set automatically"},{key:"height",type:"int",default_value:0,hidden:true}]),config_onchange:function(){this.set_name(this.config.get_value("name"));this.request_draw({clear_tile_cache:true})}});var d={CompositeTrack:e,DrawableGroup:N,DiagonalHeatmapTrack:r,FeatureTrack:c,LineTrack:g,ReadTrack:S,VariantTrack:Y,VcfTrack:Y};var n=function(ad,ac,ab){if("copy" in ad){return ad.copy(ab)}else{var ae=ad.obj_type;if(!ae){ae=ad.track_type}return new d[ae](ac,ab,ad)}};return{TracksterView:X,DrawableGroup:N,LineTrack:g,FeatureTrack:c,DiagonalHeatmapTrack:r,ReadTrack:S,VariantTrack:Y,CompositeTrack:e,object_from_template:n}});
\ No newline at end of file
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: dannon: Add mock, poster eggs. Both may go away depending on which way bioblend goes w/ deps, but it keeps things working for now.
by commits-noreply@bitbucket.org 23 Apr '14
by commits-noreply@bitbucket.org 23 Apr '14
23 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/51643642564f/
Changeset: 51643642564f
User: dannon
Date: 2014-04-23 23:07:39
Summary: Add mock, poster eggs. Both may go away depending on which way bioblend goes w/ deps, but it keeps things working for now.
Affected #: 1 file
diff -r 299e9c8d29c5cd0b1603c38e6d805ecb33b1a58f -r 51643642564f214f09c2eff32307360f5e09dfaf eggs.ini
--- a/eggs.ini
+++ b/eggs.ini
@@ -46,6 +46,7 @@
kombu = 3.0.12
lrucache = 0.2
Mako = 0.4.1
+mock = 1.0.1
nose = 0.11.1
NoseHTML = 0.4.1
NoseTestDiff = 0.1
@@ -54,6 +55,7 @@
Paste = 1.7.5.1
PasteDeploy = 1.5.0
pexpect = 2.4
+poster = 0.8.1
python_openid = 2.2.5
python_daemon = 1.5.5
pytz = 2013.9
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: davebgx: Twill test framework cleanup. Fix functional tests for history functions.
by commits-noreply@bitbucket.org 23 Apr '14
by commits-noreply@bitbucket.org 23 Apr '14
23 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/299e9c8d29c5/
Changeset: 299e9c8d29c5
User: davebgx
Date: 2014-04-23 22:46:14
Summary: Twill test framework cleanup. Fix functional tests for history functions.
Affected #: 6 files
diff -r 0bc0fd94aaa4e7c1ede3e291b6c58544c83fc786 -r 299e9c8d29c5cd0b1603c38e6d805ecb33b1a58f test/base/twilltestcase.py
--- a/test/base/twilltestcase.py
+++ b/test/base/twilltestcase.py
@@ -14,6 +14,7 @@
import urllib
import zipfile
+from urlparse import urlparse
from galaxy.web import security
from galaxy.web.framework.helpers import iff
from galaxy.util.json import from_json_string
@@ -63,7 +64,6 @@
os.makedirs(self.keepOutdir)
except:
pass
- self.home()
# Functions associated with files
def files_diff( self, file1, file2, attributes=None ):
@@ -232,7 +232,6 @@
tc.config("readonly_controls_writeable", 1)
tc.fv( "tool_form", "NAME", name )
tc.submit( "runtool_btn" )
- self.home()
except AssertionError, err:
errmsg = "Uploading file resulted in the following exception. Make sure the file (%s) exists. " % filename
errmsg += str( err )
@@ -251,13 +250,12 @@
def upload_url_paste( self, url_paste, ftype='auto', dbkey='unspecified (?)' ):
"""Pasted data in the upload utility"""
- self.visit_page( "tool_runner/index?tool_id=upload1" )
+ self.visit_url( "/tool_runner/index?tool_id=upload1" )
try:
self.refresh_form( "file_type", ftype ) #Refresh, to support composite files
tc.fv( "tool_form", "dbkey", dbkey )
tc.fv( "tool_form", "url_paste", url_paste )
tc.submit( "runtool_btn" )
- self.home()
except Exception, e:
errmsg = "Problem executing upload utility using url_paste: %s" % str( e )
raise AssertionError( errmsg )
@@ -271,8 +269,8 @@
# Wait for upload processing to finish (TODO: this should be done in each test case instead)
self.wait()
- def json_from_url( self, url ):
- self.visit_url( url )
+ def json_from_url( self, url, params={} ):
+ self.visit_url( url, params )
return from_json_string( self.last_page() )
# Functions associated with histories
@@ -283,8 +281,8 @@
params = dict()
if show_deleted is not None:
params[ 'deleted' ] = show_deleted
- api_url = '/api/histories/%s/contents?%s' % ( encoded_history_id, urllib.urlencode( params ) )
- json_data = self.json_from_url( api_url )
+ api_url = '/api/histories/%s/contents' % encoded_history_id
+ json_data = self.json_from_url( api_url, params=params )
if show_deleted is not None:
hdas = []
for hda in json_data:
@@ -296,8 +294,8 @@
json_data = hdas
if show_details:
params[ 'details' ] = ','.join( [ hda[ 'id' ] for hda in json_data ] )
- api_url = '/api/histories/%s/contents?%s' % ( encoded_history_id, urllib.urlencode( params ) )
- json_data = self.json_from_url( api_url )
+ api_url = '/api/histories/%s/contents' % encoded_history_id
+ json_data = self.json_from_url( api_url, params=params )
log.debug( 'detailed url: %s' % api_url )
log.debug( 'detailed json data: %s' % json_data )
return json_data
@@ -314,19 +312,18 @@
def check_history_for_errors( self ):
"""Raises an exception if there are errors in a history"""
- self.home()
- self.visit_page( "history" )
+ self.visit_url( "/history" )
page = self.last_page()
if page.find( 'error' ) > -1:
raise AssertionError( 'Errors in the history for user %s' % self.user )
def check_history_for_string( self, patt, show_deleted=False ):
"""Breaks patt on whitespace and searches for each element seperately in the history"""
- self.home()
if show_deleted:
- self.visit_page( "history?show_deleted=True" )
+ params = dict( show_deleted=True )
+ self.visit_url( "/history", params )
else:
- self.visit_page( "history" )
+ self.visit_url( "/history" )
for subpatt in patt.split():
try:
tc.find( subpatt )
@@ -334,22 +331,19 @@
fname = self.write_temp_file( tc.browser.get_html() )
errmsg = "no match to '%s'\npage content written to '%s'" % ( subpatt, fname )
raise AssertionError( errmsg )
- self.home()
def check_history_for_exact_string( self, string, show_deleted=False ):
"""Looks for exact match to 'string' in history page"""
- self.home()
if show_deleted:
- self.visit_page( "history?show_deleted=True" )
+ self.visit_url( "/history?show_deleted=True" )
else:
- self.visit_page( "history" )
+ self.visit_url( "/history" )
try:
tc.find( string )
except:
fname = self.write_temp_file( tc.browser.get_html() )
errmsg = "no match to '%s'\npage content written to '%s'" % ( string, fname )
raise AssertionError( errmsg )
- self.home()
def check_history_json( self, check_fn, show_deleted=None ):
"""
@@ -368,8 +362,6 @@
errmsg = ( "json could not be read\npage content written to '%s'" % ( fname ) )
raise AssertionError( errmsg )
- self.home()
-
def is_history_empty( self ):
"""
Uses history page JSON to determine whether this history is empty
@@ -404,20 +396,15 @@
history_list = self.get_histories_as_data_list()
self.assertTrue( history_list )
num_deleted = len( id.split( ',' ) )
- self.home()
- self.visit_page( "history/list?operation=delete&id=%s" % ( id ) )
-
+ self.visit_url( "/history/list?operation=delete&id=%s" % ( id ) )
check_str = 'Deleted %d %s' % ( num_deleted, iff( num_deleted != 1, "histories", "history" ) )
self.check_page_for_string( check_str )
- self.home()
def delete_current_history( self, strings_displayed=[] ):
"""Deletes the current history"""
- self.home()
- self.visit_page( "history/delete_current" )
+ self.visit_url( "/history/delete_current" )
for check_str in strings_displayed:
self.check_page_for_string( check_str )
- self.home()
def get_histories_as_data_list( self ):
"""Returns the data elements of all histories"""
@@ -433,24 +420,21 @@
def history_as_xml_tree( self, show_deleted=False ):
"""Returns a parsed xml object of a history"""
- self.home()
- self.visit_page( 'history?as_xml=True&show_deleted=%s' % show_deleted )
+ self.visit_url( '/history?as_xml=True&show_deleted=%s' % show_deleted )
xml = self.last_page()
tree = ElementTree.fromstring(xml)
return tree
def histories_as_xml_tree( self ):
"""Returns a parsed xml object of all histories"""
- self.home()
- self.visit_page( 'history/list_as_xml' )
+ self.visit_url( '/history/list_as_xml' )
xml = self.last_page()
tree = ElementTree.fromstring(xml)
return tree
def history_options( self, user=False, active_datasets=False, activatable_datasets=False, histories_shared_by_others=False ):
"""Mimics user clicking on history options link"""
- self.home()
- self.visit_page( "root/history_options" )
+ self.visit_url( "/root/history_options" )
if user:
self.check_page_for_string( 'Previously</a> stored histories' )
if active_datasets:
@@ -465,35 +449,28 @@
self.check_page_for_string( 'Show deleted</a> datasets in current history' )
self.check_page_for_string( 'Rename</a> current history' )
self.check_page_for_string( 'Delete</a> current history' )
- self.home()
def new_history( self, name=None ):
"""Creates a new, empty history"""
- self.home()
if name:
self.visit_url( "%s/history_new?name=%s" % ( self.url, name ) )
else:
self.visit_url( "%s/history_new" % self.url )
self.check_page_for_string( 'New history created' )
assert self.is_history_empty(), 'Creating new history did not result in an empty history.'
- self.home()
def rename_history( self, id, old_name, new_name ):
"""Rename an existing history"""
- self.home()
- self.visit_page( "history/rename?id=%s&name=%s" % ( id, new_name ) )
+ self.visit_url( "/history/rename", params=dict( id=id, name=new_name ) )
check_str = 'History: %s renamed to: %s' % ( old_name, urllib.unquote( new_name ) )
self.check_page_for_string( check_str )
- self.home()
def set_history( self ):
"""Sets the history (stores the cookies for this run)"""
if self.history_id:
- self.home()
- self.visit_page( "history?id=%s" % self.history_id )
+ self.visit_url( "/history", params=dict( id=self.history_id ) )
else:
self.new_history()
- self.home()
def share_current_history( self, email, strings_displayed=[], strings_displayed_after_submit=[],
action='', action_strings_displayed=[], action_strings_displayed_after_submit=[] ):
@@ -514,7 +491,6 @@
tc.submit( "share_restricted_button" )
for check_str in action_strings_displayed_after_submit:
self.check_page_for_string( check_str )
- self.home()
def share_histories_with_users( self, ids, emails, strings_displayed=[], strings_displayed_after_submit=[],
action=None, action_strings_displayed=[] ):
@@ -533,97 +509,70 @@
for check_str in action_strings_displayed:
self.check_page_for_string( check_str )
- self.home()
def unshare_history( self, history_id, user_id, strings_displayed=[] ):
"""Unshare a history that has been shared with another user"""
- self.visit_url( "%s/history/list?id=%s&operation=share+or+publish" % ( self.url, history_id ) )
+ self.visit_url( "/history/sharing", params=dict( id=history_id ) )
for check_str in strings_displayed:
self.check_page_for_string( check_str )
- self.visit_url( "%s/history/sharing?unshare_user=%s&id=%s" % ( self.url, user_id, history_id ) )
- self.home()
+ self.visit_url( "/history/sharing", params=dict( unshare_user=user_id, id=history_id ) )
def switch_history( self, id='', name='' ):
"""Switches to a history in the current list of histories"""
- self.visit_url( "%s/history/list?operation=switch&id=%s" % ( self.url, id ) )
+ params = dict( operation='switch', id=id )
+ self.visit_url( "/history/list", params )
if name:
self.check_history_for_exact_string( name )
- self.home()
def view_stored_active_histories( self, strings_displayed=[] ):
- self.home()
- self.visit_page( "history/list" )
+ self.visit_url( "/history/list" )
self.check_page_for_string( 'Saved Histories' )
self.check_page_for_string( 'operation=Rename' )
self.check_page_for_string( 'operation=Switch' )
self.check_page_for_string( 'operation=Delete' )
for check_str in strings_displayed:
self.check_page_for_string( check_str )
- self.home()
def view_stored_deleted_histories( self, strings_displayed=[] ):
- self.home()
- self.visit_page( "history/list?f-deleted=True" )
+ self.visit_url( "/history/list?f-deleted=True" )
self.check_page_for_string( 'Saved Histories' )
self.check_page_for_string( 'operation=Undelete' )
for check_str in strings_displayed:
self.check_page_for_string( check_str )
- self.home()
def view_shared_histories( self, strings_displayed=[] ):
- self.home()
- self.visit_page( "history/list_shared" )
+ self.visit_url( "/history/list_shared" )
for check_str in strings_displayed:
self.check_page_for_string( check_str )
- self.home()
def copy_history( self, history_id, copy_choice, strings_displayed=[], strings_displayed_after_submit=[] ):
- self.home()
- self.visit_page( "history/copy?id=%s" % history_id )
+ self.visit_url( "/history/copy?id=%s" % history_id )
for check_str in strings_displayed:
self.check_page_for_string( check_str )
tc.fv( '1', 'copy_choice', copy_choice )
tc.submit( 'copy_choice_button' )
for check_str in strings_displayed_after_submit:
self.check_page_for_string( check_str )
- self.home()
def make_accessible_via_link( self, history_id, strings_displayed=[], strings_displayed_after_submit=[] ):
- self.home()
- self.visit_page( "history/list?operation=share+or+publish&id=%s" % history_id )
- for check_str in strings_displayed:
- self.check_page_for_string( check_str )
# twill barfs on this form, possibly because it contains no fields, but not sure.
# In any case, we have to mimic the form submission
- self.home()
- self.visit_page( 'history/sharing?id=%s&make_accessible_via_link=True' % history_id )
- for check_str in strings_displayed_after_submit:
- self.check_page_for_string( check_str )
- self.home()
+ self.visit_url( '/history/sharing', dict( id=history_id, make_accessible_via_link=True ) )
+ self.check_for_strings( strings_displayed=strings_displayed_after_submit )
def disable_access_via_link( self, history_id, strings_displayed=[], strings_displayed_after_submit=[] ):
- self.home()
- self.visit_page( "history/list?operation=share+or+publish&id=%s" % history_id )
- for check_str in strings_displayed:
- self.check_page_for_string( check_str )
# twill barfs on this form, possibly because it contains no fields, but not sure.
# In any case, we have to mimic the form submission
- self.home()
- self.visit_page( 'history/sharing?id=%s&disable_link_access=True' % history_id )
- for check_str in strings_displayed_after_submit:
- self.check_page_for_string( check_str )
- self.home()
+ self.visit_url( '/history/sharing', dict( id=history_id, disable_link_access=True ) )
+ self.check_for_strings( strings_displayed=strings_displayed_after_submit )
def import_history_via_url( self, history_id, email, strings_displayed_after_submit=[] ):
- self.home()
- self.visit_page( "history/imp?&id=%s" % history_id )
- for check_str in strings_displayed_after_submit:
- self.check_page_for_string( check_str )
- self.home()
+ self.visit_url( "/history/imp", params=dict( id=history_id ) )
+ self.check_for_strings( strings_displayed=strings_displayed_after_submit )
# Functions associated with datasets (history items) and meta data
def _get_job_stream_output( self, hda_id, stream, format ):
- self.visit_page( "datasets/%s/%s" % ( self.security.encode_id( hda_id ), stream ) )
+ self.visit_url( "/datasets/%s/%s" % ( self.security.encode_id( hda_id ), stream ) )
output = self.last_page()
return self._format_stream( output, stream, format )
@@ -657,7 +606,7 @@
elem = data_list[-1]
hid = int( elem.get('hid') )
self.assertTrue( hid )
- self.visit_page( "dataset/edit?hid=%s" % hid )
+ self.visit_url( "/dataset/edit?hid=%s" % hid )
for subpatt in patt.split():
tc.find(subpatt)
@@ -686,19 +635,16 @@
self.visit_url( '%s/datasets/%s/display/' % ( self.url, self.security.encode_id( hda_id ) ) )
for check_str in strings_displayed:
self.check_page_for_string( check_str )
- self.home()
def view_history( self, history_id, strings_displayed=[] ):
"""Displays a history for viewing"""
self.visit_url( '%s/history/view?id=%s' % ( self.url, self.security.encode_id( history_id ) ) )
for check_str in strings_displayed:
self.check_page_for_string( check_str )
- self.home()
def edit_hda_attribute_info( self, hda_id, new_name='', new_info='', new_dbkey='', new_startcol='',
strings_displayed=[], strings_not_displayed=[] ):
"""Edit history_dataset_association attribute information"""
- self.home()
self.visit_url( "%s/datasets/%s/edit" % ( self.url, self.security.encode_id( hda_id ) ) )
submit_required = False
self.check_page_for_string( 'Edit Attributes' )
@@ -725,7 +671,6 @@
raise AssertionError( "String (%s) incorrectly displayed on Edit Attributes page." % check_str )
except:
pass
- self.home()
def check_hda_attribute_info( self, hda_id, strings_displayed=[] ):
"""Edit history_dataset_association attribute information"""
@@ -734,7 +679,6 @@
def auto_detect_metadata( self, hda_id ):
"""Auto-detect history_dataset_association metadata"""
- self.home()
self.visit_url( "%s/datasets/%s/edit" % ( self.url, self.security.encode_id( hda_id ) ) )
self.check_page_for_string( 'This will inspect the dataset and attempt' )
tc.fv( 'auto_detect', 'detect', 'Auto-detect' )
@@ -745,28 +689,23 @@
except AssertionError:
self.check_page_for_string( 'Attributes updated' )
#self.check_page_for_string( 'Attributes updated' )
- self.home()
def convert_format( self, hda_id, target_type ):
"""Convert format of history_dataset_association"""
- self.home()
self.visit_url( "%s/datasets/%s/edit" % ( self.url, self.security.encode_id( hda_id ) ) )
self.check_page_for_string( 'This will inspect the dataset and attempt' )
tc.fv( 'convert_data', 'target_type', target_type )
tc.submit( 'convert_data' )
self.check_page_for_string( 'The file conversion of Convert BED to GFF on data' )
self.wait() # wait for the format convert tool to finish before returning
- self.home()
def change_datatype( self, hda_id, datatype ):
"""Change format of history_dataset_association"""
- self.home()
self.visit_url( "%s/datasets/%s/edit" % ( self.url, self.security.encode_id( hda_id ) ) )
self.check_page_for_string( 'This will change the datatype of the existing dataset but' )
tc.fv( 'change_datatype', 'datatype', datatype )
tc.submit( 'change' )
self.check_page_for_string( 'Changed the type of dataset' )
- self.home()
def copy_history_item( self, source_dataset_id=None, target_history_id=None, all_target_history_ids=[],
deleted_history_ids=[] ):
@@ -774,7 +713,6 @@
Copy 1 history_dataset_association to 1 history (Limited by twill since it doesn't support multiple
field names, such as checkboxes
"""
- self.home()
self.visit_url( "%s/dataset/copy_datasets?source_dataset_ids=%s" % ( self.url, source_dataset_id ) )
self.check_page_for_string( 'Source History:' )
# Make sure all of users active histories are displayed
@@ -792,7 +730,6 @@
tc.submit( 'do_copy' )
check_str = '1 dataset copied to 1 history'
self.check_page_for_string( check_str )
- self.home()
def get_hids_in_history( self ):
"""Returns the list of hid values for items in a history"""
@@ -915,11 +852,10 @@
def __default_dataset_fetcher( self ):
def fetcher( hda_id, filename=None ):
if filename is None:
- page_url = "display?encoded_id=%s" % hda_id
- self.home() # I assume this is not needed.
+ page_url = "/display?encoded_id=%s" % hda_id
else:
- page_url = "datasets/%s/display/%s" % ( hda_id, filename )
- self.visit_page( page_url )
+ page_url = "/datasets/%s/display/%s" % ( hda_id, filename )
+ self.visit_url( page_url )
data = self.last_page()
return data
@@ -1019,7 +955,8 @@
def create( self, cntrller='user', email='test(a)bx.psu.edu', password='testuser', username='admin-user', redirect='' ):
# HACK: don't use panels because late_javascripts() messes up the twill browser and it
# can't find form fields (and hence user can't be logged in).
- self.visit_url( "%s/user/create?cntrller=%s&use_panels=False" % ( self.url, cntrller ) )
+ params = dict( cntrller=cntrller, use_panels=False )
+ self.visit_url( "/user/create", params )
tc.fv( 'registration', 'email', email )
tc.fv( 'registration', 'redirect', redirect )
tc.fv( 'registration', 'password', password )
@@ -1095,7 +1032,6 @@
tc.submit( "edit_user_info_button" )
for check_str in strings_displayed_after_submit:
self.check_page_for_string( check_str )
- self.home()
def user_set_default_permissions( self, cntrller='user', permissions_out=[], permissions_in=[], role_id='2' ):
# role.id = 2 is Private Role for test2(a)bx.psu.edu
@@ -1112,7 +1048,6 @@
url = "%s&%s=%s" % ( url, key, str( role_id ) )
self.visit_url( "%s/%s" % ( self.url, url ) )
self.check_page_for_string( 'Default new history permissions have been changed.' )
- self.home()
def history_set_default_permissions( self, permissions_out=[], permissions_in=[], role_id=3 ): # role.id = 3 is Private Role for test3(a)bx.psu.edu
# NOTE: Twill has a bug that requires the ~/user/permissions page to contain at least 1 option value
@@ -1126,10 +1061,8 @@
for pi in permissions_in:
key = '%s_in' % pi
url = "%s&%s=%s" % ( url, key, str( role_id ) )
- self.home()
self.visit_url( "%s/%s" % ( self.url, url ) )
self.check_page_for_string( 'Default history permissions have been changed.' )
- self.home()
def login( self, email='test(a)bx.psu.edu', password='testuser', username='admin-user', redirect='' ):
# test(a)bx.psu.edu is configured as an admin user
@@ -1139,14 +1072,12 @@
# The acount has previously been created, so just login.
# HACK: don't use panels because late_javascripts() messes up the twill browser and it
# can't find form fields (and hence user can't be logged in).
- self.visit_url( "%s/user/login?use_panels=False" % self.url )
+ self.visit_url( "/user/login?use_panels=False" )
self.submit_form( 1, 'login_button', email=email, redirect=redirect, password=password )
def logout( self ):
- self.home()
- self.visit_page( "user/logout" )
+ self.visit_url( "%s/user/logout" % self.url )
self.check_page_for_string( "You have been logged out" )
- self.home()
# Functions associated with browsers, cookies, HTML forms and page visits
@@ -1208,9 +1139,6 @@
"""Clears a form"""
tc.formclear(str(form))
- def home( self ):
- self.visit_url( self.url )
-
def last_page( self ):
return tc.browser.get_html()
@@ -1383,16 +1311,30 @@
# Submit for refresh
tc.submit( '___refresh_grouping___' )
- def visit_page( self, page ):
- # tc.go("./%s" % page)
- if not page.startswith( "/" ):
- page = "/" + page
- tc.go( self.url + page )
- tc.code( 200 )
-
- def visit_url( self, url ):
- tc.go("%s" % url)
- tc.code( 200 )
+ def visit_url( self, url, params=None, checkbox_params=None, allowed_codes=[ 200 ] ):
+ if params is None:
+ params = dict()
+ parsed_url = urlparse( url )
+ if len( parsed_url.netloc ) == 0:
+ url = 'http://%s:%s%s' % ( self.host, self.port, parsed_url.path )
+ else:
+ url = '%s://%s%s' % ( parsed_url.scheme, parsed_url.netloc, parsed_url.path )
+ if parsed_url.query:
+ for query_parameter in parsed_url.query.split( '&' ):
+ key, value = query_parameter.split( '=' )
+ params[ key ] = value
+ if params:
+ url += '?%s' % urllib.urlencode( params )
+ if checkbox_params is not None:
+ if params or parsed_url.query:
+ url += '&%s&%s' % ( urllib.urlencode( checkbox_params ), urllib.urlencode( checkbox_params ) )
+ else:
+ url += '?%s&%s' % ( urllib.urlencode( checkbox_params ), urllib.urlencode( checkbox_params ) )
+ new_url = tc.go( url )
+ return_code = tc.browser.get_code()
+ assert return_code in allowed_codes, 'Invalid HTTP return code %s, allowed codes: %s' % \
+ ( return_code, ', '.join( str( code ) for code in allowed_codes ) )
+ return new_url
"""Functions associated with Galaxy tools"""
def run_tool( self, tool_id, repeat_name=None, **kwd ):
@@ -1412,9 +1354,9 @@
def run_ucsc_main( self, track_params, output_params ):
"""Gets Data From UCSC"""
tool_id = "ucsc_table_direct1"
- track_string = urllib.urlencode( track_params )
galaxy_url = urllib.quote_plus( "%s/tool_runner/index?" % self.url )
- self.visit_url( "http://genome.ucsc.edu/cgi-bin/hgTables?GALAXY_URL=%s&hgta_compressType=non…" % ( galaxy_url, tool_id, track_string ) )
+ track_params.update( dict( GALAXY_URL=galaxy_url, hgta_compressType='none', tool_id=tool_id ) )
+ self.visit_url( "http://genome.ucsc.edu/cgi-bin/hgTables", params=track_params )
tc.fv( "mainForm", "hgta_doTopSubmit", "get output" )
self.submit_form( button="get output" )
tc.fv( 2, "hgta_doGalaxyQuery", "Send query to Galaxy" )
@@ -1486,41 +1428,32 @@
def reset_password_as_admin( self, user_id, password='testreset' ):
"""Reset a user password"""
- self.home()
self.visit_url( "%s/admin/reset_user_password?id=%s" % ( self.url, user_id ) )
tc.fv( "1", "password", password )
tc.fv( "1", "confirm", password )
tc.submit( "reset_user_password_button" )
self.check_page_for_string( "Passwords reset for 1 user." )
- self.home()
def mark_user_deleted( self, user_id, email='' ):
"""Mark a user as deleted"""
- self.home()
self.visit_url( "%s/admin/users?operation=delete&id=%s" % ( self.url, user_id ) )
check_str = "Deleted 1 users"
self.check_page_for_string( check_str )
- self.home()
def undelete_user( self, user_id, email='' ):
"""Undelete a user"""
- self.home()
self.visit_url( "%s/admin/users?operation=undelete&id=%s" % ( self.url, user_id ) )
check_str = "Undeleted 1 users"
self.check_page_for_string( check_str )
- self.home()
def purge_user( self, user_id, email ):
"""Purge a user account"""
- self.home()
self.visit_url( "%s/admin/users?operation=purge&id=%s" % ( self.url, user_id ) )
check_str = "Purged 1 users"
self.check_page_for_string( check_str )
- self.home()
def manage_roles_and_groups_for_user( self, user_id, in_role_ids=[], out_role_ids=[],
in_group_ids=[], out_group_ids=[], strings_displayed=[] ):
- self.home()
url = "%s/admin/manage_roles_and_groups_for_user?id=%s" % ( self.url, user_id )
if in_role_ids:
url += "&in_roles=%s" % ','.join( in_role_ids )
@@ -1535,7 +1468,6 @@
self.visit_url( url )
for check_str in strings_displayed:
self.check_page_for_string( check_str )
- self.home()
# Tests associated with roles
def browse_roles( self, strings_displayed=[] ):
@@ -1552,16 +1484,17 @@
private_role='',
strings_displayed=[] ):
"""Create a new role"""
- url = "%s/admin/roles?operation=create&create_role_button=Save&name=%s&description=%s" % \
- ( self.url, name.replace( ' ', '+' ), description.replace( ' ', '+' ) )
+ url = "/admin/roles"
+ url_params = dict( operation='create', create_role_button='Save', name=name, description=description )
if in_user_ids:
- url += "&in_users=%s" % ','.join( in_user_ids )
+ url_params[ 'in_users' ] = ','.join( in_user_ids )
if in_group_ids:
- url += "&in_groups=%s" % ','.join( in_group_ids )
+ url_params[ 'in_groups' ] = ','.join( in_group_ids )
if create_group_for_role == 'yes':
- url += '&create_group_for_role=yes&create_group_for_role=yes'
- self.home()
- self.visit_url( url )
+ checkbox_params = dict( create_group_for_role='yes' )
+ else:
+ checkbox_params = None
+ self.visit_url( url, url_params, checkbox_params=checkbox_params )
for check_str in strings_displayed:
self.check_page_for_string( check_str )
if private_role:
@@ -1573,47 +1506,36 @@
except AssertionError:
# Reaching here is the behavior we want since no private roles should be displayed
pass
- self.home()
self.visit_url( "%s/admin/roles" % self.url )
self.check_page_for_string( name )
- self.home()
def rename_role( self, role_id, name='Role One Renamed', description='This is Role One Re-described' ):
"""Rename a role"""
- self.home()
self.visit_url( "%s/admin/roles?operation=rename&id=%s" % ( self.url, role_id ) )
self.check_page_for_string( 'Change role name and description' )
tc.fv( "1", "name", name )
tc.fv( "1", "description", description )
tc.submit( "rename_role_button" )
- self.home()
def mark_role_deleted( self, role_id, role_name ):
"""Mark a role as deleted"""
- self.home()
self.visit_url( "%s/admin/roles?operation=delete&id=%s" % ( self.url, role_id ) )
check_str = "Deleted 1 roles: %s" % role_name
self.check_page_for_string( check_str )
- self.home()
def undelete_role( self, role_id, role_name ):
"""Undelete an existing role"""
- self.home()
self.visit_url( "%s/admin/roles?operation=undelete&id=%s" % ( self.url, role_id ) )
check_str = "Undeleted 1 roles: %s" % role_name
self.check_page_for_string( check_str )
- self.home()
def purge_role( self, role_id, role_name ):
"""Purge an existing role"""
- self.home()
self.visit_url( "%s/admin/roles?operation=purge&id=%s" % ( self.url, role_id ) )
check_str = "Purged 1 roles: %s" % role_name
self.check_page_for_string( check_str )
- self.home()
def associate_users_and_groups_with_role( self, role_id, role_name, user_ids=[], group_ids=[] ):
- self.home()
url = "%s/admin/role?id=%s&role_members_edit_button=Save" % ( self.url, role_id )
if user_ids:
url += "&in_users=%s" % ','.join( user_ids )
@@ -1622,26 +1544,25 @@
self.visit_url( url )
check_str = "Role '%s' has been updated with %d associated users and %d associated groups" % ( role_name, len( user_ids ), len( group_ids ) )
self.check_page_for_string( check_str )
- self.home()
# Tests associated with groups
def create_group( self, name='Group One', in_user_ids=[], in_role_ids=[], create_role_for_group='', strings_displayed=[] ):
"""Create a new group"""
- url = "%s/admin/groups?operation=create&create_group_button=Save&name=%s" % ( self.url, name.replace( ' ', '+' ) )
+ url = "/admin/groups"
+ params = dict( operation='create', create_group_button='Save', name=name )
if in_user_ids:
- url += "&in_users=%s" % ','.join( in_user_ids )
+ params [ 'in_users' ] = ','.join( in_user_ids )
if in_role_ids:
- url += "&in_roles=%s" % ','.join( in_role_ids )
+ params[ 'in_roles' ] = ','.join( in_role_ids )
if create_role_for_group == 'yes':
- url += '&create_role_for_group=yes&create_role_for_group=yes'
- self.home()
- self.visit_url( url )
+ checkbox_params = dict( create_role_for_group='yes' )
+ else:
+ checkbox_params = None
+ self.visit_url( url, params=params, checkbox_params=checkbox_params )
for check_str in strings_displayed:
self.check_page_for_string( check_str )
- self.home()
- self.visit_url( "%s/admin/groups" % self.url )
+ self.visit_url( "/admin/groups" )
self.check_page_for_string( name )
- self.home()
def browse_groups( self, strings_displayed=[] ):
self.visit_url( '%s/admin/groups' % self.url )
@@ -1650,15 +1571,12 @@
def rename_group( self, group_id, name='Group One Renamed' ):
"""Rename a group"""
- self.home()
self.visit_url( "%s/admin/groups?operation=rename&id=%s" % ( self.url, group_id ) )
self.check_page_for_string( 'Change group name' )
tc.fv( "1", "name", name )
tc.submit( "rename_group_button" )
- self.home()
def associate_users_and_roles_with_group( self, group_id, group_name, user_ids=[], role_ids=[] ):
- self.home()
url = "%s/admin/manage_users_and_roles_for_group?id=%s&group_roles_users_edit_button=Save" % ( self.url, group_id )
if user_ids:
url += "&in_users=%s" % ','.join( user_ids )
@@ -1667,31 +1585,24 @@
self.visit_url( url )
check_str = "Group '%s' has been updated with %d associated roles and %d associated users" % ( group_name, len( role_ids ), len( user_ids ) )
self.check_page_for_string( check_str )
- self.home()
def mark_group_deleted( self, group_id, group_name ):
"""Mark a group as deleted"""
- self.home()
self.visit_url( "%s/admin/groups?operation=delete&id=%s" % ( self.url, group_id ) )
check_str = "Deleted 1 groups: %s" % group_name
self.check_page_for_string( check_str )
- self.home()
def undelete_group( self, group_id, group_name ):
"""Undelete an existing group"""
- self.home()
self.visit_url( "%s/admin/groups?operation=undelete&id=%s" % ( self.url, group_id ) )
check_str = "Undeleted 1 groups: %s" % group_name
self.check_page_for_string( check_str )
- self.home()
def purge_group( self, group_id, group_name ):
"""Purge an existing group"""
- self.home()
self.visit_url( "%s/admin/groups?operation=purge&id=%s" % ( self.url, group_id ) )
check_str = "Purged 1 groups: %s" % group_name
self.check_page_for_string( check_str )
- self.home()
# Form stuff
def create_form( self, name, description, form_type, field_type='TextField', form_layout_name='',
@@ -1743,12 +1654,10 @@
tc.submit( "save_changes_button" )
for check_str in strings_displayed_after_submit:
self.check_page_for_string( check_str )
- self.home()
def edit_form( self, id, form_type='', new_form_name='', new_form_desc='', field_dicts=[], field_index=0,
strings_displayed=[], strings_not_displayed=[], strings_displayed_after_submit=[] ):
"""Edit form details; name and description"""
- self.home()
self.visit_url( "%s/forms/edit_form_definition?id=%s" % ( self.url, id ) )
for check_str in strings_displayed:
self.check_page_for_string( check_str )
@@ -1784,10 +1693,9 @@
tc.submit( "save_changes_button" )
for check_str in strings_displayed_after_submit:
self.check_page_for_string( check_str )
- self.home()
+
def view_form( self, id, form_type='', form_name='', form_desc='', form_layout_name='', field_dicts=[] ):
'''View form details'''
- self.home()
self.visit_url( "%s/forms/view_latest_form_definition?id=%s" % ( self.url, id ) )
#self.check_page_for_string( form_type )
self.check_page_for_string( form_name )
@@ -1800,15 +1708,13 @@
if field_dict[ 'type' ].lower() == 'selectfield':
for option_index, option in enumerate( field_dict[ 'selectlist' ] ):
self.check_page_for_string( option )
- self.home()
+
def mark_form_deleted( self, form_id ):
"""Mark a form_definition as deleted"""
- self.home()
url = "%s/forms/delete_form_definition?id=%s" % ( self.url, form_id )
self.visit_url( url )
check_str = "1 forms have been deleted."
self.check_page_for_string( check_str )
- self.home()
# External services stuff
def reload_external_service( self, external_service_type_id, strings_displayed=[], strings_displayed_after_submit=[] ):
@@ -1819,6 +1725,7 @@
tc.submit( "reload_external_service_type_button" )
for check_str in strings_displayed_after_submit:
self.check_page_for_string( check_str )
+
def create_external_service( self, name, description, version, external_service_type_id, field_values={}, strings_displayed=[], strings_displayed_after_submit=[] ):
self.visit_url( '%s/external_service/create_external_service' % self.url )
for check_str in strings_displayed:
@@ -1832,10 +1739,12 @@
tc.submit( "create_external_service_button" )
for check_str in strings_displayed_after_submit:
self.check_page_for_string( check_str )
+
def view_external_service( self, external_service_id, strings_displayed=[] ):
self.visit_url( '%s/external_service/view_external_service?id=%s' % ( self.url, external_service_id ) )
for check_str in strings_displayed:
self.check_page_for_string( check_str )
+
def edit_external_service( self, external_service_id, field_values={}, strings_displayed=[], strings_displayed_after_submit=[] ):
self.visit_url( '%s/external_service/edit_external_service?id=%s' % ( self.url, external_service_id ) )
for check_str in strings_displayed:
@@ -1852,7 +1761,6 @@
for check_str in strings_displayed:
self.check_page_for_string( check_str )
def create_request_type( self, name, desc, request_form_id, sample_form_id, states, strings_displayed=[], strings_displayed_after_submit=[] ):
- self.home()
self.visit_url( "%s/request_type/create_request_type" % self.url )
for check_str in strings_displayed:
self.check_page_for_string( check_str )
@@ -1876,14 +1784,11 @@
for pi in permissions_in:
key = '%s_in' % pi
url = "%s&%s=%s" % ( url, key, role_ids_str )
- self.home()
self.visit_url( "%s/%s" % ( self.url, url ) )
check_str = "Permissions updated for request type '%s'" % request_type_name
self.check_page_for_string( check_str )
- self.home()
def view_request_type( self, request_type_id, request_type_name, sample_states, strings_displayed=[] ):
'''View request_type details'''
- self.home()
self.visit_url( "%s/request_type/view_request_type?id=%s" % ( self.url, request_type_id ) )
self.check_page_for_string( '"%s" request type' % request_type_name )
for name, desc in sample_states:
@@ -1926,7 +1831,6 @@
tc.submit( "create_request_button" )
for check_str in strings_displayed_after_submit:
self.check_page_for_string( check_str )
- self.home()
def view_request( self, cntrller, request_id, strings_displayed=[], strings_displayed_count=[], strings_not_displayed=[] ):
self.visit_url( "%s/%s/browse_requests?operation=view_request&id=%s" % ( self.url, cntrller, request_id ) )
self.check_page( strings_displayed, strings_displayed_count, strings_not_displayed )
@@ -2121,7 +2025,6 @@
for check_str, count in strings_displayed_count:
self.check_string_count_in_page( check_str, count )
def add_user_address( self, user_id, address_dict ):
- self.home()
self.visit_url( "%s/user/new_address?cntrller=user&user_id=%s" % ( self.url, user_id ) )
self.check_page_for_string( 'Add new address' )
for field_name, value in address_dict.items():
@@ -2137,7 +2040,6 @@
dis-inherit your template, call the manage_library_template_inheritance() below immediately after you call this
method in your test code. Templates added to Requesttype objects are always inherited to samples.
"""
- self.home()
if item_type == 'library':
url = "%s/library_common/add_template?cntrller=%s&item_type=%s&form_type=%s&library_id=%s" % \
( self.url, cntrller, item_type, form_type, library_id )
@@ -2155,10 +2057,9 @@
tc.fv( "select_template", "inheritable", '1' )
tc.submit( "add_template_button" )
self.check_page_for_string = 'A template based on the form "%s" has been added to this' % form_name
- self.home()
+
def manage_library_template_inheritance( self, cntrller, item_type, library_id, folder_id=None, ldda_id=None, inheritable=True ):
# If inheritable is True, the item is currently inheritable.
- self.home()
if item_type == 'library':
url = "%s/library_common/manage_template_inheritance?cntrller=%s&item_type=%s&library_id=%s" % \
( self.url, cntrller, item_type, library_id )
@@ -2173,7 +2074,7 @@
self.check_page_for_string = 'will no longer be inherited to contained folders and datasets'
else:
self.check_page_for_string = 'will now be inherited to contained folders and datasets'
- self.home()
+
def browse_libraries_admin( self, deleted=False, strings_displayed=[], strings_not_displayed=[] ):
self.visit_url( '%s/library_admin/browse_libraries?sort=name&f-description=All&f-name=All&f-deleted=%s' % ( self.url, str( deleted ) ) )
for check_str in strings_displayed:
@@ -2214,7 +2115,7 @@
tc.submit( "create_library_button" )
check_str = "The new library named '%s' has been created" % name
self.check_page_for_string( check_str )
- self.home()
+
def edit_template( self, cntrller, item_type, form_type, library_id, field_type, field_label_1, field_helptext_1, field_default_1,
folder_id='', ldda_id='', action='add_field' ):
"""Edit the form fields defining a library template"""
@@ -2251,7 +2152,7 @@
# Set the template field value
tc.fv( "edit_info", field_name, field_value )
tc.submit( 'edit_info_button' )
- self.home()
+
def library_permissions( self, library_id, library_name, role_ids_str, permissions_in, permissions_out, cntrller='library_admin' ):
# role_ids_str must be a comma-separated string of role ids
url = "library_common/library_permissions?id=%s&cntrller=%s&update_roles_button=Save" % ( library_id, cntrller )
@@ -2261,11 +2162,10 @@
for pi in permissions_in:
key = '%s_in' % pi
url = "%s&%s=%s" % ( url, key, role_ids_str )
- self.home()
self.visit_url( "%s/%s" % ( self.url, url ) )
check_str = "Permissions updated for library '%s'." % library_name
self.check_page_for_string( check_str )
- self.home()
+
def make_library_item_public( self, library_id, id, cntrller='library_admin', item_type='library',
contents=False, library_name='', folder_name='', ldda_name='' ):
url = "%s/library_common/make_library_item_public?cntrller=%s&library_id=%s&item_type=%s&id=%s&contents=%s" % \
@@ -2293,7 +2193,7 @@
tc.submit( "new_folder_button" )
check_str = "The new folder named '%s' has been added to the data library." % name
self.check_page_for_string( check_str )
- self.home()
+
def folder_info( self, cntrller, folder_id, library_id, name='', new_name='', description='', template_refresh_field_name='1_field_name',
template_refresh_field_contents='', template_fields=[], strings_displayed=[], strings_not_displayed=[],
strings_displayed_after_submit=[], strings_not_displayed_after_submit=[] ):
@@ -2331,7 +2231,6 @@
raise AssertionError( "String (%s) incorrectly displayed." % check_str )
except:
pass
- self.home()
# Library dataset stuff
def upload_library_dataset( self, cntrller, library_id, folder_id, filename='', server_dir='', replace_id='',
@@ -2342,29 +2241,29 @@
"""Add datasets to library using any upload_option"""
# NOTE: due to the library_wait() method call at the end of this method, no tests should be done
# for strings_displayed_after_submit.
- url = "%s/library_common/upload_library_dataset?cntrller=%s&library_id=%s&folder_id=%s" % \
- ( self.url, cntrller, library_id, folder_id )
+ params = dict( cntrller=cntrller, library_id=library_id, folder_id=folder_id )
+ url = "%s/library_common/upload_library_dataset" % self.url
if replace_id:
# If we're uploading a new version of a library dataset, we have to include the replace_id param in the
# request because the form field named replace_id will not be displayed on the upload form if we dont.
- url += "&replace_id=%s" % replace_id
- self.visit_url( url )
+ params[ 'replace_id' ] = replace_id
+ self.visit_url( url, params=params )
if template_refresh_field_contents:
# A template containing an AddressField is displayed on the upload form, so we need to refresh the form
# with the received template_refresh_field_contents.
self.refresh_form( template_refresh_field_name, template_refresh_field_contents )
for tup in template_fields:
tc.fv( "1", tup[0], tup[1] )
- tc.fv( "1", "library_id", library_id )
- tc.fv( "1", "folder_id", folder_id )
- tc.fv( "1", "show_deleted", show_deleted )
- tc.fv( "1", "ldda_message", ldda_message )
- tc.fv( "1", "file_type", file_type )
- tc.fv( "1", "dbkey", dbkey )
+ tc.fv( "upload_library_dataset", "library_id", library_id )
+ tc.fv( "upload_library_dataset", "folder_id", folder_id )
+ tc.fv( "upload_library_dataset", "show_deleted", show_deleted )
+ tc.fv( "upload_library_dataset", "ldda_message", ldda_message )
+ tc.fv( "upload_library_dataset", "file_type", file_type )
+ tc.fv( "upload_library_dataset", "dbkey", dbkey )
if space_to_tab:
- tc.fv( "1", "space_to_tab", space_to_tab )
+ tc.fv( "upload_library_dataset", "space_to_tab", space_to_tab )
for role_id in roles:
- tc.fv( "1", "roles", role_id )
+ tc.fv( "upload_library_dataset", "roles", role_id )
# Refresh the form by selecting the upload_option - we do this here to ensure
# all previously entered form contents are retained.
self.refresh_form( 'upload_option', upload_option )
@@ -2380,21 +2279,21 @@
tc.submit( 'add_history_datasets_to_library_button' )
else:
if upload_option in [ 'upload_paths', 'upload_directory' ]:
- tc.fv( "1", "link_data_only", link_data_only )
+ tc.fv( "upload_library_dataset", "link_data_only", link_data_only )
if upload_option == 'upload_paths':
- tc.fv( "1", "filesystem_paths", filesystem_paths )
+ tc.fv( "upload_library_dataset", "filesystem_paths", filesystem_paths )
if upload_option == 'upload_directory' and server_dir:
- tc.fv( "1", "server_dir", server_dir )
+ tc.fv( "upload_library_dataset", "server_dir", server_dir )
if upload_option == 'upload_file':
if filename:
filename = self.get_filename( filename )
- tc.formfile( "1", "files_0|file_data", filename )
+ tc.formfile( "upload_library_dataset", "files_0|file_data", filename )
for check_str in strings_displayed:
self.check_page_for_string( check_str )
tc.submit( "runtool_btn" )
# Give the files some time to finish uploading
self.library_wait( library_id )
- self.home()
+
def ldda_permissions( self, cntrller, library_id, folder_id, id, role_ids_str,
permissions_in=[], permissions_out=[], strings_displayed=[], ldda_name='' ):
# role_ids_str must be a comma-separated string of role ids
@@ -2413,7 +2312,7 @@
strings_displayed = [ "Permissions updated for dataset '%s'." % ldda_name ]
for check_str in strings_displayed:
self.check_page_for_string( check_str )
- self.home()
+
def ldda_info( self, cntrller, library_id, folder_id, ldda_id, strings_displayed=[], strings_not_displayed=[] ):
"""View library_dataset_dataset_association information"""
self.visit_url( "%s/library_common/ldda_info?cntrller=%s&library_id=%s&folder_id=%s&id=%s" % \
@@ -2426,7 +2325,7 @@
raise AssertionError( "String (%s) should not have been displayed on ldda info page." % check_str )
except:
pass
- self.home()
+
def ldda_edit_info( self, cntrller, library_id, folder_id, ldda_id, ldda_name, new_ldda_name='', template_refresh_field_name='1_field_name',
template_refresh_field_contents='', template_fields=[], strings_displayed=[], strings_not_displayed=[] ):
"""Edit library_dataset_dataset_association information, optionally template element information"""
@@ -2458,7 +2357,7 @@
raise AssertionError( "String (%s) should not have been displayed on ldda Edit Attributes page." % check_str )
except:
pass
- self.home()
+
def act_on_multiple_datasets( self, cntrller, library_id, do_action, ldda_ids='', strings_displayed=[] ):
# Can't use the ~/library_admin/libraries form as twill barfs on it so we'll simulate the form submission
# by going directly to the form action
@@ -2474,7 +2373,6 @@
for check_str in strings_displayed:
self.check_page_for_string( check_str )
def download_archive_of_library_files( self, cntrller, library_id, ldda_ids, format ):
- self.home()
# Here it would be ideal to have twill set form values and submit the form, but
# twill barfs on that due to the recently introduced page wrappers around the contents
# of the browse_library.mako template which enable panel layout when visiting the
@@ -2494,7 +2392,6 @@
self.visit_url( url )
tc.code( 200 )
archive = self.write_temp_file( self.last_page(), suffix='.' + format )
- self.home()
return archive
def check_archive_contents( self, archive, lddas ):
def get_ldda_path( ldda ):
@@ -2542,7 +2439,6 @@
def move_library_item( self, cntrller, item_type, item_id, source_library_id, make_target_current,
target_library_id=None, target_folder_id=None, strings_displayed=[], strings_displayed_after_submit=[] ):
- self.home()
params = dict( cntrller=cntrller,
item_type=item_type,
item_id=item_id,
@@ -2552,7 +2448,7 @@
params[ 'target_library_id' ] = target_library_id
if target_folder_id is not None:
params[ 'target_folder_id' ] = target_folder_id
- self.visit_url( "%s/library_common/move_library_item?%s" % ( self.url, urllib.urlencode( params ) ) )
+ self.visit_url( "%s/library_common/move_library_item" % self.url, params=params )
if target_library_id:
self.refresh_form( 'target_library_id', target_library_id, form_name='move_library_item' )
if target_folder_id:
@@ -2562,39 +2458,36 @@
tc.submit( 'move_library_item_button' )
for check_str in strings_displayed_after_submit:
self.check_page_for_string( check_str )
- self.home()
def delete_library_item( self, cntrller, library_id, item_id, item_name, item_type='library_dataset' ):
"""Mark a library item as deleted"""
- self.home()
- self.visit_url( "%s/library_common/delete_library_item?cntrller=%s&library_id=%s&item_id=%s&item_type=%s" \
- % ( self.url, cntrller, library_id, item_id, item_type ) )
+ params = dict( cntrller=cntrller, library_id=library_id, item_id=item_id, item_type=item_type )
+ self.visit_url( "/library_common/delete_library_item", params )
if item_type == 'library_dataset':
item_desc = 'Dataset'
else:
item_desc = item_type.capitalize()
check_str = "marked deleted"
- self.check_page_for_string( check_str )
- self.home()
+ self.check_for_strings( strings_displayed=[ item_desc, check_str ] )
+
def undelete_library_item( self, cntrller, library_id, item_id, item_name, item_type='library_dataset' ):
"""Mark a library item as deleted"""
- self.home()
- self.visit_url( "%s/library_common/undelete_library_item?cntrller=%s&library_id=%s&item_id=%s&item_type=%s" \
- % ( self.url, cntrller, library_id, item_id, item_type ) )
+ params = dict( cntrller=cntrller, library_id=library_id, item_id=item_id, item_type=item_type )
+ self.visit_url( "/library_common/undelete_library_item", params )
if item_type == 'library_dataset':
item_desc = 'Dataset'
else:
item_desc = item_type.capitalize()
check_str = "marked undeleted"
- self.check_page_for_string( check_str )
- self.home()
+ self.check_for_strings( strings_displayed=[ item_desc, check_str ] )
+
def purge_library( self, library_id, library_name ):
"""Purge a library"""
- self.home()
- self.visit_url( "%s/library_admin/purge_library?id=%s" % ( self.url, library_id ) )
+ params = dict( id=library_id )
+ self.visit_url( "/library_admin/purge_library", params )
check_str = "Library '%s' and all of its contents have been purged" % library_name
self.check_page_for_string( check_str )
- self.home()
+
def library_wait( self, library_id, cntrller='library_admin', maxiter=90 ):
"""Waits for the tools to finish"""
count = 0
diff -r 0bc0fd94aaa4e7c1ede3e291b6c58544c83fc786 -r 299e9c8d29c5cd0b1603c38e6d805ecb33b1a58f test/functional/test_admin_features.py
--- a/test/functional/test_admin_features.py
+++ b/test/functional/test_admin_features.py
@@ -232,7 +232,6 @@
# Rename the group
rename = "Group One's been Renamed"
self.rename_group( self.security.encode_id( group_one.id ), name=rename, )
- self.home()
self.visit_url( '%s/admin/groups' % self.url )
self.check_page_for_string( rename )
# Reset the group back to the original name
@@ -365,7 +364,6 @@
def test_065_mark_role_deleted( self ):
"""Testing marking a role as deleted"""
# Logged in as admin_user
- self.home()
self.browse_roles( strings_displayed=[ role_two.name ] )
self.mark_role_deleted( self.security.encode_id( role_two.id ), role_two.name )
refresh( role_two )
diff -r 0bc0fd94aaa4e7c1ede3e291b6c58544c83fc786 -r 299e9c8d29c5cd0b1603c38e6d805ecb33b1a58f test/functional/test_history_functions.py
--- a/test/functional/test_history_functions.py
+++ b/test/functional/test_history_functions.py
@@ -1,4 +1,3 @@
-import urllib
import galaxy.model
from galaxy.model.orm import *
from base.test_db_util import sa_session
@@ -109,7 +108,7 @@
.first()
assert history1 is not None, "Problem retrieving history1 from database"
self.upload_file( '1.bed', dbkey='hg18' )
- self.new_history( name=urllib.quote( 'history2' ) )
+ self.new_history( name='history2' )
global history2
history2 = sa_session.query( galaxy.model.History ) \
.filter( and_( galaxy.model.History.table.c.deleted == False,
@@ -158,7 +157,7 @@
assert history3 is not None, "Problem retrieving history3 from database"
if history3.deleted:
raise AssertionError( "History id %d deleted when it should not be" % latest_history.id )
- self.rename_history( self.security.encode_id( history3.id ), history3.name, new_name=urllib.quote( 'history 3' ) )
+ self.rename_history( self.security.encode_id( history3.id ), history3.name, new_name='history 3' )
sa_session.refresh( history3 )
def test_015_history_list( self ):
@@ -348,7 +347,7 @@
.order_by( desc( galaxy.model.History.table.c.create_time ) ) \
.first()
assert history4 is not None, "Problem retrieving history4 from database"
- self.rename_history( self.security.encode_id( history4.id ), history4.name, new_name=urllib.quote( 'history 4' ) )
+ self.rename_history( self.security.encode_id( history4.id ), history4.name, new_name='history 4' )
sa_session.refresh( history4 )
# Galaxy's new history sharing code does not yet support sharing multiple histories; when support for sharing multiple histories is added,
# this test will be uncommented and updated.
@@ -383,7 +382,7 @@
.order_by( desc( galaxy.model.History.table.c.create_time ) ) \
.first()
assert history5 is not None, "Problem retrieving history5 from database"
- self.rename_history( self.security.encode_id( history5.id ), history5.name, new_name=urllib.quote( 'history 5' ) )
+ self.rename_history( self.security.encode_id( history5.id ), history5.name, new_name='history 5' )
# Current history is history5
sa_session.refresh( history5 )
# Due to the limitations of twill ( not functional with the permissions forms ), we're forced
@@ -547,7 +546,7 @@
# Make sure the history was unshared correctly
self.logout()
self.login( email=regular_user2.email )
- self.visit_page( "root/history_options" )
+ self.visit_url( "/root/history_options" )
try:
self.check_page_for_string( 'List</a> histories shared with you by others' )
raise AssertionError( "history5 still shared with regular_user2 after unsharing it with that user." )
@@ -695,7 +694,7 @@
# Make sure the histories were unshared correctly
self.logout()
self.login( email=regular_user2.email )
- self.visit_page( "root/history_options" )
+ self.visit_url( "/root/history_options" )
try:
self.check_page_for_string( 'List</a> histories shared with you by others' )
raise AssertionError( "history5 still shared with regular_user2 after unshaing it with that user." )
@@ -704,7 +703,7 @@
self.logout()
self.login( email=regular_user3.email )
- self.visit_page( "root/history_options" )
+ self.visit_url( "/root/history_options" )
try:
self.check_page_for_string( 'List</a> histories shared with you by others' )
raise AssertionError( "history5 still shared with regular_user3 after unshaing it with that user." )
@@ -724,7 +723,7 @@
# Logged in as admin_user
# create a new history and upload a new hda (1.bed) into it
- self.new_history( name=urllib.quote( 'show hide deleted datasets' ) )
+ self.new_history( name='show hide deleted datasets' )
latest_history = (
sa_session.query( galaxy.model.History )
.filter( and_( galaxy.model.History.table.c.deleted == False,
@@ -739,7 +738,6 @@
.first() )
# delete that item and make sure the history is not empty
- self.home()
log.info( 'deleting last hda' )
self.delete_history_item( str( latest_hda.id ) )
# check the number of items returned from the api
@@ -776,13 +774,12 @@
assert latest_history is not None, "Problem retrieving latest_history from database"
self.rename_history( self.security.encode_id( latest_history.id ),
- latest_history.name, new_name=urllib.quote( 'delete undelete history items' ) )
+ latest_history.name, new_name='delete undelete history items' )
# Add a new history item
self.upload_file( '1.bed', dbkey='hg15' )
latest_hda = sa_session.query( galaxy.model.HistoryDatasetAssociation ) \
.order_by( desc( galaxy.model.HistoryDatasetAssociation.table.c.create_time ) ) \
.first()
- self.home()
self.visit_url( "%s/history/?show_deleted=False" % self.url )
self.check_page_for_string( '1.bed' )
self.check_page_for_string( 'hg15' )
@@ -798,7 +795,6 @@
pass
# Undelete the history item
self.undelete_history_item( str( latest_hda.id ) )
- self.home()
self.visit_url( "%s/history/?show_deleted=False" % self.url )
self.check_page_for_string( '1.bed' )
self.check_page_for_string( 'hg15' )
@@ -807,7 +803,7 @@
def test_080_copying_history_items_between_histories( self ):
"""Testing copying history items between histories"""
# logged in as admin_user
- self.new_history( name=urllib.quote( 'copy history items' ) )
+ self.new_history( name='copy history items' )
history6 = sa_session.query( galaxy.model.History ) \
.filter( and_( galaxy.model.History.table.c.deleted == False,
galaxy.model.History.table.c.user_id == admin_user.id ) ) \
@@ -836,7 +832,7 @@
if len( history6.datasets ) != 2:
raise AssertionError( "Copying hda1 to the current history failed, history 6 has %d datasets, but should have 2" % len( history6.datasets ) )
# Test copying 1 hda to another history
- self.new_history( name=urllib.quote( 'copy history items - 2' ) )
+ self.new_history( name='copy history items - 2' )
history7 = sa_session.query( galaxy.model.History ) \
.filter( and_( galaxy.model.History.table.c.deleted == False,
galaxy.model.History.table.c.user_id == admin_user.id ) ) \
diff -r 0bc0fd94aaa4e7c1ede3e291b6c58544c83fc786 -r 299e9c8d29c5cd0b1603c38e6d805ecb33b1a58f test/functional/test_metadata_editing.py
--- a/test/functional/test_metadata_editing.py
+++ b/test/functional/test_metadata_editing.py
@@ -27,7 +27,6 @@
latest_hda = sa_session.query( galaxy.model.HistoryDatasetAssociation ) \
.order_by( desc( galaxy.model.HistoryDatasetAssociation.table.c.create_time ) ) \
.first()
- self.home()
# Due to twill not being able to handle the permissions forms, we'll eliminate
# DefaultHistoryPermissions prior to uploading a dataset so that the permission
# form will not be displayed on ted edit attributes page.
diff -r 0bc0fd94aaa4e7c1ede3e291b6c58544c83fc786 -r 299e9c8d29c5cd0b1603c38e6d805ecb33b1a58f test/install_and_test_tool_shed_repositories/base/twilltestcase.py
--- a/test/install_and_test_tool_shed_repositories/base/twilltestcase.py
+++ b/test/install_and_test_tool_shed_repositories/base/twilltestcase.py
@@ -39,7 +39,6 @@
# TODO: Figure out a way to alter these attributes during tests.
self.galaxy_tool_dependency_dir = os.environ.get( 'GALAXY_INSTALL_TEST_TOOL_DEPENDENCY_DIR' )
self.shed_tools_dict = {}
- self.home()
def initiate_installation_process( self, install_tool_dependencies=False, install_repository_dependencies=True, no_changes=True,
new_tool_panel_section_label=None ):
diff -r 0bc0fd94aaa4e7c1ede3e291b6c58544c83fc786 -r 299e9c8d29c5cd0b1603c38e6d805ecb33b1a58f test/tool_shed/base/twilltestcase.py
--- a/test/tool_shed/base/twilltestcase.py
+++ b/test/tool_shed/base/twilltestcase.py
@@ -61,7 +61,6 @@
# TODO: Figure out a way to alter these attributes during tests.
self.galaxy_tool_dependency_dir = os.environ.get( 'GALAXY_TEST_TOOL_DEPENDENCY_DIR' )
self.shed_tools_dict = {}
- self.home()
def add_repository_review_component( self, **kwd ):
url = '/repository_review/create_component?operation=create'
@@ -597,10 +596,8 @@
self.submit_form( '1', 'login_button', email=email, redirect=redirect, password=password )
def galaxy_logout( self ):
- self.home()
self.visit_galaxy_url( "/user/logout" )
self.check_page_for_string( "You have been logged out" )
- self.home()
def generate_complex_dependency_xml( self, filename, filepath, repository_tuples, package, version ):
file_path = os.path.join( filepath, filename )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: Jeremy Goecks: Fix divide-by-0 resulting from mean depth of 0 in bai data provider.
by commits-noreply@bitbucket.org 23 Apr '14
by commits-noreply@bitbucket.org 23 Apr '14
23 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/0bc0fd94aaa4/
Changeset: 0bc0fd94aaa4
User: Jeremy Goecks
Date: 2014-04-23 22:31:23
Summary: Fix divide-by-0 resulting from mean depth of 0 in bai data provider.
Affected #: 1 file
diff -r b2cf571d0b63948a7252fc703200b854f964bad6 -r 0bc0fd94aaa4e7c1ede3e291b6c58544c83fc786 lib/galaxy/visualization/data_providers/genome.py
--- a/lib/galaxy/visualization/data_providers/genome.py
+++ b/lib/galaxy/visualization/data_providers/genome.py
@@ -972,7 +972,7 @@
return { 'data': [], 'message': None, 'max_low': start, 'max_high': start }
read_len = len( first_read.seq )
- num_reads = ( end - start ) * mean_depth / float ( read_len )
+ num_reads = max( ( end - start ) * mean_depth / float ( read_len ), 1 )
threshold = float( max_vals )/ num_reads
iterator = itertools.chain( iter( [ first_read ] ), iterator )
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: carlfeberhard: UI, History: first pass at making display_structured a bit more useful and clean up the styling; CSS: move hda styling out of history scope
by commits-noreply@bitbucket.org 23 Apr '14
by commits-noreply@bitbucket.org 23 Apr '14
23 Apr '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/b2cf571d0b63/
Changeset: b2cf571d0b63
User: carlfeberhard
Date: 2014-04-23 21:25:25
Summary: UI, History: first pass at making display_structured a bit more useful and clean up the styling; CSS: move hda styling out of history scope
Affected #: 5 files
diff -r 54695d3fa468250b1ee13a90facc753dc3d9831d -r b2cf571d0b63948a7252fc703200b854f964bad6 lib/galaxy/webapps/galaxy/controllers/history.py
--- a/lib/galaxy/webapps/galaxy/controllers/history.py
+++ b/lib/galaxy/webapps/galaxy/controllers/history.py
@@ -502,7 +502,7 @@
# Sort items by age
items.sort( key=( lambda x: x[0].create_time ), reverse=True )
#
- return trans.fill_template( "history/display_structured.mako", items=items )
+ return trans.fill_template( "history/display_structured.mako", items=items, history=history )
@web.expose
def delete_hidden_datasets( self, trans ):
diff -r 54695d3fa468250b1ee13a90facc753dc3d9831d -r b2cf571d0b63948a7252fc703200b854f964bad6 static/style/blue/base.css
--- a/static/style/blue/base.css
+++ b/static/style/blue/base.css
@@ -1621,50 +1621,50 @@
.search-input .search-clear,.search-input .search-loading{position:relative;display:inline-block;float:right;margin-top:-23px;margin-right:4px;font-size:1.4em;line-height:23px;color:grey}
.search-input .search-clear:hover{color:#303030}
#history-refresh-button,#history-options-button{display:inline-block;height:22px;width:22px;text-align:center;line-height:19px;font-size:1.2em;padding:0px}
-.history-panel .dataset{border:1px solid #bfbfbf}.history-panel .dataset .vertical-spacing{margin-bottom:8px}
-.history-panel .dataset .info-section{border-radius:3px;border:1px solid rgba(153,153,153,0.30000000000000004);padding:4px}
-.history-panel .dataset .dataset-padding{padding:6px 10px 6px 8px}
-.history-panel .dataset [class$=messagesmall]{margin:6px 10px 2px 8px;font-size:90%}
-.history-panel .dataset .help-text{font-weight:normal;color:#555}
-.history-panel .dataset .dataset-selector{float:left;display:none;width:32px;height:32px;margin:0 0 -6px 0;padding:8px 0 2px 7px;font-size:80%;color:#333;cursor:pointer;vertical-align:middle}
-.history-panel .dataset .dataset-selector:hover{color:maroon}
-.history-panel .dataset .dataset-title-bar{cursor:pointer;outline:none;padding:6px 10px 6px 8px}
-.history-panel .dataset .dataset-title-bar .dataset-title{display:inline;font-weight:bold;text-decoration:underline;word-wrap:break-word;word-break:break-all;line-height:16px}
-.history-panel .dataset .dataset-primary-actions{display:inline-block;float:right;margin:6px 10px 0}.history-panel .dataset .dataset-primary-actions .icon-btn:not(:last-child){margin:0px;border-radius:0px;border-right:none}
-.history-panel .dataset .dataset-primary-actions .icon-btn:first-child{margin-right:0px;border-top-left-radius:3px;border-bottom-left-radius:3px}
-.history-panel .dataset .dataset-primary-actions .icon-btn:last-child{margin-left:0px;border-radius:0px 3px 3px 0px}
-.history-panel .dataset .dataset-primary-actions .icon-btn:only-child{margin:0px;border-radius:3px}
-.history-panel .dataset .dataset-primary-actions .icon-btn{margin-left:2px}
-.history-panel .dataset .dataset-body{display:none;padding:0 10px 6px 8px}.history-panel .dataset .dataset-body [class$=messagesmall]{margin:0px 0px 8px 0px}
-.history-panel .dataset .dataset-body label{margin:0px;padding:0px;font-weight:normal}
-.history-panel .dataset .dataset-body .prompt{font-weight:normal;color:#555}
-.history-panel .dataset .dataset-body .prompt:after{content:':';margin-right:4px}
-.history-panel .dataset .dataset-body .dataset-summary{margin-bottom:8px}.history-panel .dataset .dataset-body .dataset-summary .dataset-blurb{margin-bottom:2px}
-.history-panel .dataset .dataset-body .dataset-summary .dataset-datatype,.history-panel .dataset .dataset-body .dataset-summary .dataset-dbkey{display:inline}.history-panel .dataset .dataset-body .dataset-summary .dataset-datatype .value,.history-panel .dataset .dataset-body .dataset-summary .dataset-dbkey .value{font-weight:bold}
-.history-panel .dataset .dataset-body .dataset-summary .dataset-datatype .value:after{content:',';font-weight:normal;color:#555;margin-right:4px}
-.history-panel .dataset .dataset-body .dataset-summary .dataset-dbkey:after{content:' ';display:block;margin-bottom:8px}
-.history-panel .dataset .dataset-body .dataset-summary .dataset-info{border-radius:3px;border:1px solid rgba(153,153,153,0.30000000000000004);padding:4px;overflow:auto}.history-panel .dataset .dataset-body .dataset-summary .dataset-info .value{white-space:pre-line}
-.history-panel .dataset .dataset-body .dataset-summary .job-error-text{border-radius:3px;border:1px solid rgba(153,153,153,0.30000000000000004);padding:4px;overflow:auto;white-space:pre}
-.history-panel .dataset .dataset-body .dataset-actions .left{display:inline-block;float:left}.history-panel .dataset .dataset-body .dataset-actions .left .icon-btn:not(:last-child){margin:0px;border-radius:0px;border-right:none}
-.history-panel .dataset .dataset-body .dataset-actions .left .icon-btn:first-child{margin-right:0px;border-top-left-radius:3px;border-bottom-left-radius:3px}
-.history-panel .dataset .dataset-body .dataset-actions .left .icon-btn:last-child{margin-left:0px;border-radius:0px 3px 3px 0px}
-.history-panel .dataset .dataset-body .dataset-actions .left .icon-btn:only-child{margin:0px;border-radius:3px}
-.history-panel .dataset .dataset-body .dataset-actions .left .icon-btn{margin-right:2px}
-.history-panel .dataset .dataset-body .dataset-actions .left:not(:empty){margin-bottom:8px}
-.history-panel .dataset .dataset-body .dataset-actions .right{display:inline-block;float:right}.history-panel .dataset .dataset-body .dataset-actions .right .icon-btn:not(:last-child){margin:0px;border-radius:0px;border-right:none}
-.history-panel .dataset .dataset-body .dataset-actions .right .icon-btn:first-child{margin-right:0px;border-top-left-radius:3px;border-bottom-left-radius:3px}
-.history-panel .dataset .dataset-body .dataset-actions .right .icon-btn:last-child{margin-left:0px;border-radius:0px 3px 3px 0px}
-.history-panel .dataset .dataset-body .dataset-actions .right .icon-btn:only-child{margin:0px;border-radius:3px}
-.history-panel .dataset .dataset-body .dataset-actions .right .icon-btn{margin-left:2px}
-.history-panel .dataset .dataset-body .tags-display{display:none;margin-bottom:8px}.history-panel .dataset .dataset-body .tags-display .select2-container{min-width:0px}.history-panel .dataset .dataset-body .tags-display .select2-container .select2-choices{border-radius:3px}
-.history-panel .dataset .dataset-body .annotation-display{display:none;margin-bottom:8px}.history-panel .dataset .dataset-body .annotation-display .annotation{border-radius:3px;border:1px solid rgba(153,153,153,0.30000000000000004);padding:4px;white-space:pre-line}
-.history-panel .dataset .dataset-body .annotation-display .annotation:empty{height:22px}
-.history-panel .dataset .dataset-body .annotation-display .annotation:empty:after{position:relative;top:-4px;font-size:10px;font-style:italic;color:grey;content:'Click here to edit annotation'}
-.history-panel .dataset .dataset-body .annotation-display textarea{margin:0px 0px 2px 0px;display:block;border-radius:3px;width:100%}
-.history-panel .dataset .dataset-body .dataset-display-applications .display-application:last-child{margin-bottom:8px}
-.history-panel .dataset .dataset-body .dataset-peek{margin-bottom:8px}.history-panel .dataset .dataset-body .dataset-peek pre.peek{width:100%;margin:0px;border-radius:3px;background:white;color:black;font-size:10px;overflow:auto}.history-panel .dataset .dataset-body .dataset-peek pre.peek th{color:white;background:#5f6990}
-.history-panel .dataset .dataset-body .dataset-peek pre.peek table,.history-panel .dataset .dataset-body .dataset-peek pre.peek th,.history-panel .dataset .dataset-body .dataset-peek pre.peek tr,.history-panel .dataset .dataset-body .dataset-peek pre.peek td{font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:10px}
-.history-panel .dataset .state-icon{font-family:FontAwesome;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:inline-block;margin-right:4px;vertical-align:middle;width:16px;height:16px;line-height:16px;text-align:center;font-size:16px}
+.hda.dataset{border:1px solid #bfbfbf}.hda.dataset .vertical-spacing{margin-bottom:8px}
+.hda.dataset .info-section{border-radius:3px;border:1px solid rgba(153,153,153,0.30000000000000004);padding:4px}
+.hda.dataset .dataset-padding{padding:6px 10px 6px 8px}
+.hda.dataset [class$=messagesmall]{margin:6px 10px 2px 8px;font-size:90%}
+.hda.dataset .help-text{font-weight:normal;color:#555}
+.hda.dataset .dataset-selector{float:left;display:none;width:32px;height:32px;margin:0 0 -6px 0;padding:8px 0 2px 7px;font-size:80%;color:#333;cursor:pointer;vertical-align:middle}
+.hda.dataset .dataset-selector:hover{color:maroon}
+.hda.dataset .dataset-title-bar{cursor:pointer;outline:none;padding:6px 10px 6px 8px}
+.hda.dataset .dataset-title-bar .dataset-title{display:inline;font-weight:bold;text-decoration:underline;word-wrap:break-word;word-break:break-all;line-height:16px}
+.hda.dataset .dataset-primary-actions{display:inline-block;float:right;margin:6px 10px 0}.hda.dataset .dataset-primary-actions .icon-btn:not(:last-child){margin:0px;border-radius:0px;border-right:none}
+.hda.dataset .dataset-primary-actions .icon-btn:first-child{margin-right:0px;border-top-left-radius:3px;border-bottom-left-radius:3px}
+.hda.dataset .dataset-primary-actions .icon-btn:last-child{margin-left:0px;border-radius:0px 3px 3px 0px}
+.hda.dataset .dataset-primary-actions .icon-btn:only-child{margin:0px;border-radius:3px}
+.hda.dataset .dataset-primary-actions .icon-btn{margin-left:2px}
+.hda.dataset .dataset-body{display:none;padding:0 10px 6px 8px}.hda.dataset .dataset-body [class$=messagesmall]{margin:0px 0px 8px 0px}
+.hda.dataset .dataset-body label{margin:0px;padding:0px;font-weight:normal}
+.hda.dataset .dataset-body .prompt{font-weight:normal;color:#555}
+.hda.dataset .dataset-body .prompt:after{content:':';margin-right:4px}
+.hda.dataset .dataset-body .dataset-summary{margin-bottom:8px}.hda.dataset .dataset-body .dataset-summary .dataset-blurb{margin-bottom:2px}
+.hda.dataset .dataset-body .dataset-summary .dataset-datatype,.hda.dataset .dataset-body .dataset-summary .dataset-dbkey{display:inline}.hda.dataset .dataset-body .dataset-summary .dataset-datatype .value,.hda.dataset .dataset-body .dataset-summary .dataset-dbkey .value{font-weight:bold}
+.hda.dataset .dataset-body .dataset-summary .dataset-datatype .value:after{content:',';font-weight:normal;color:#555;margin-right:4px}
+.hda.dataset .dataset-body .dataset-summary .dataset-dbkey:after{content:' ';display:block;margin-bottom:8px}
+.hda.dataset .dataset-body .dataset-summary .dataset-info{border-radius:3px;border:1px solid rgba(153,153,153,0.30000000000000004);padding:4px;overflow:auto}.hda.dataset .dataset-body .dataset-summary .dataset-info .value{white-space:pre-line}
+.hda.dataset .dataset-body .dataset-summary .job-error-text{border-radius:3px;border:1px solid rgba(153,153,153,0.30000000000000004);padding:4px;overflow:auto;white-space:pre}
+.hda.dataset .dataset-body .dataset-actions .left{display:inline-block;float:left}.hda.dataset .dataset-body .dataset-actions .left .icon-btn:not(:last-child){margin:0px;border-radius:0px;border-right:none}
+.hda.dataset .dataset-body .dataset-actions .left .icon-btn:first-child{margin-right:0px;border-top-left-radius:3px;border-bottom-left-radius:3px}
+.hda.dataset .dataset-body .dataset-actions .left .icon-btn:last-child{margin-left:0px;border-radius:0px 3px 3px 0px}
+.hda.dataset .dataset-body .dataset-actions .left .icon-btn:only-child{margin:0px;border-radius:3px}
+.hda.dataset .dataset-body .dataset-actions .left .icon-btn{margin-right:2px}
+.hda.dataset .dataset-body .dataset-actions .left:not(:empty){margin-bottom:8px}
+.hda.dataset .dataset-body .dataset-actions .right{display:inline-block;float:right}.hda.dataset .dataset-body .dataset-actions .right .icon-btn:not(:last-child){margin:0px;border-radius:0px;border-right:none}
+.hda.dataset .dataset-body .dataset-actions .right .icon-btn:first-child{margin-right:0px;border-top-left-radius:3px;border-bottom-left-radius:3px}
+.hda.dataset .dataset-body .dataset-actions .right .icon-btn:last-child{margin-left:0px;border-radius:0px 3px 3px 0px}
+.hda.dataset .dataset-body .dataset-actions .right .icon-btn:only-child{margin:0px;border-radius:3px}
+.hda.dataset .dataset-body .dataset-actions .right .icon-btn{margin-left:2px}
+.hda.dataset .dataset-body .tags-display{display:none;margin-bottom:8px}.hda.dataset .dataset-body .tags-display .select2-container{min-width:0px}.hda.dataset .dataset-body .tags-display .select2-container .select2-choices{border-radius:3px}
+.hda.dataset .dataset-body .annotation-display{display:none;margin-bottom:8px}.hda.dataset .dataset-body .annotation-display .annotation{border-radius:3px;border:1px solid rgba(153,153,153,0.30000000000000004);padding:4px;white-space:pre-line}
+.hda.dataset .dataset-body .annotation-display .annotation:empty{height:22px}
+.hda.dataset .dataset-body .annotation-display .annotation:empty:after{position:relative;top:-4px;font-size:10px;font-style:italic;color:grey;content:'Click here to edit annotation'}
+.hda.dataset .dataset-body .annotation-display textarea{margin:0px 0px 2px 0px;display:block;border-radius:3px;width:100%}
+.hda.dataset .dataset-body .dataset-display-applications .display-application:last-child{margin-bottom:8px}
+.hda.dataset .dataset-body .dataset-peek{margin-bottom:8px}.hda.dataset .dataset-body .dataset-peek pre.peek{width:100%;margin:0px;border-radius:3px;background:white;color:black;font-size:10px;overflow:auto}.hda.dataset .dataset-body .dataset-peek pre.peek th{color:white;background:#5f6990}
+.hda.dataset .dataset-body .dataset-peek pre.peek table,.hda.dataset .dataset-body .dataset-peek pre.peek th,.hda.dataset .dataset-body .dataset-peek pre.peek tr,.hda.dataset .dataset-body .dataset-peek pre.peek td{font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:10px}
+.hda.dataset .state-icon{font-family:FontAwesome;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:inline-block;margin-right:4px;vertical-align:middle;width:16px;height:16px;line-height:16px;text-align:center;font-size:16px}
.state-icon-error{background-color:white;border-radius:8px}.state-icon-error:before{font-size:20px;line-height:16px;color:red;content:"\f057"}
.history-panel [class$="messagesmall"]{margin:0px}
.history-panel .editable-text{border:solid transparent 1px}
diff -r 54695d3fa468250b1ee13a90facc753dc3d9831d -r b2cf571d0b63948a7252fc703200b854f964bad6 static/style/src/less/history.less
--- a/static/style/src/less/history.less
+++ b/static/style/src/less/history.less
@@ -125,254 +125,251 @@
// ---------------------------------------------------------------------------- datasets
-//TODO: scope to history panels until embedded item .dataset is changed
-.history-panel {
- .dataset {
- border: 1px solid @border-default-color;
+.hda.dataset {
+ border: 1px solid @border-default-color;
- // body mixins
- @vertical-gap: 8px;
- .vertical-spacing {
- margin-bottom: @vertical-gap;
+ // body mixins
+ @vertical-gap: 8px;
+ .vertical-spacing {
+ margin-bottom: @vertical-gap;
+ }
+ .info-section {
+ border-radius: 3px;
+ border: 1px solid fadeout( @layout-border-color, 70% );
+ //background-color: fadeout( white, 60% );
+ padding: 4px;
+ }
+ @spacing-top : 6px;
+ @spacing-right : 10px;
+ @spacing-bottom : 6px;
+ @spacing-left : 8px;
+ .dataset-padding {
+ padding: @spacing-top @spacing-right @spacing-bottom @spacing-left;
+ }
+
+ [class$=messagesmall] {
+ margin: @spacing-top @spacing-right ( @spacing-bottom - 4 ) @spacing-left;
+ font-size: 90%;
+ }
+
+ .help-text {
+ font-weight: normal;
+ // font-style: italic;
+ // font-size: 90%;
+ color: #555;
+ }
+
+ .dataset-selector {
+ float: left;
+ // always initially hidden and zero width
+ display: none;
+ width: 32px;
+ height: 32px;
+ //HACK: neg. on the bottom due to padding-bottom in title-bar - very tweakish
+ margin: 0px 0px -( @spacing-bottom ) 0px;
+ padding: ( @spacing-top + 2 ) 0px 2px ( @spacing-left - 1 );
+ font-size: 80%;
+ color: @btn-default-color;
+ cursor: pointer;
+ vertical-align: middle;
+ }
+ .dataset-selector:hover {
+ color: maroon;
+ }
+
+ .dataset-title-bar {
+ cursor: pointer;
+ outline: none;
+ .dataset-padding;
+
+ .dataset-state-icon {
}
- .info-section {
- border-radius: 3px;
- border: 1px solid fadeout( @layout-border-color, 70% );
- //background-color: fadeout( white, 60% );
- padding: 4px;
+ .dataset-title {
+ display: inline;
+ font-weight: bold;
+ text-decoration: underline;
+ word-wrap: break-word;
+ word-break: break-all;
+ line-height: 16px;
}
- @spacing-top : 6px;
- @spacing-right : 10px;
- @spacing-bottom : 6px;
- @spacing-left : 8px;
- .dataset-padding {
- padding: @spacing-top @spacing-right @spacing-bottom @spacing-left;
+ }
+
+ .dataset-primary-actions {
+ .icon-btn-group();
+ float: right;
+ margin: @spacing-top @spacing-right 0;
+ .icon-btn {
+ margin-left: @icon-btn-margin;
+ }
+ }
+
+ .dataset-body {
+ display: none;
+ // background-color: fadeout( white, 70% );
+ //.dataset-padding;
+ padding: 0px @spacing-right @spacing-bottom @spacing-left;
+
+ [class$=messagesmall] {
+ margin: 0px 0px 8px 0px;
}
- [class$=messagesmall] {
- margin: @spacing-top @spacing-right ( @spacing-bottom - 4 ) @spacing-left;
- font-size: 90%;
+ label {
+ margin: 0px;
+ padding: 0px;
+ font-weight: normal;
+ }
+ .prompt {
+ .help-text;
+ }
+ .prompt:after {
+ content: ':';
+ margin-right: 4px;
}
- .help-text {
- font-weight: normal;
- // font-style: italic;
- // font-size: 90%;
- color: #555;
- }
-
- .dataset-selector {
- float: left;
- // always initially hidden and zero width
- display: none;
- width: 32px;
- height: 32px;
- //HACK: neg. on the bottom due to padding-bottom in title-bar - very tweakish
- margin: 0px 0px -( @spacing-bottom ) 0px;
- padding: ( @spacing-top + 2 ) 0px 2px ( @spacing-left - 1 );
- font-size: 80%;
- color: @btn-default-color;
- cursor: pointer;
- vertical-align: middle;
- }
- .dataset-selector:hover {
- color: maroon;
- }
-
- .dataset-title-bar {
- cursor: pointer;
- outline: none;
- .dataset-padding;
-
- .dataset-state-icon {
+ .dataset-summary {
+ .dataset-blurb {
+ margin-bottom: 2px;
}
- .dataset-title {
+ .dataset-datatype, .dataset-dbkey {
display: inline;
- font-weight: bold;
- text-decoration: underline;
- word-wrap: break-word;
- word-break: break-all;
- line-height: 16px;
+ .value {
+ font-weight: bold;
+ }
}
- }
-
- .dataset-primary-actions {
- .icon-btn-group();
- float: right;
- margin: @spacing-top @spacing-right 0;
- .icon-btn {
- margin-left: @icon-btn-margin;
- }
- }
-
- .dataset-body {
- display: none;
- // background-color: fadeout( white, 70% );
- //.dataset-padding;
- padding: 0px @spacing-right @spacing-bottom @spacing-left;
-
- [class$=messagesmall] {
- margin: 0px 0px 8px 0px;
- }
-
- label {
- margin: 0px;
- padding: 0px;
- font-weight: normal;
- }
- .prompt {
+ .dataset-datatype .value:after {
+ content: ',';
.help-text;
- }
- .prompt:after {
- content: ':';
margin-right: 4px;
}
-
- .dataset-summary {
- .dataset-blurb {
- margin-bottom: 2px;
- }
- .dataset-datatype, .dataset-dbkey {
- display: inline;
- .value {
- font-weight: bold;
- }
- }
- .dataset-datatype .value:after {
- content: ',';
- .help-text;
- margin-right: 4px;
- }
- .dataset-dbkey:after {
- content: ' ';
- display: block;
- .vertical-spacing;
- }
- .dataset-info {
- .info-section;
- overflow: auto;
- .value {
- white-space: pre-line;
- }
- }
-
- .job-error-text {
- .info-section;
- overflow: auto;
- white-space: pre;
- }
-
- // handle the last vertical gap in the parent as summary is used in other states as well (w/o info)
+ .dataset-dbkey:after {
+ content: ' ';
+ display: block;
.vertical-spacing;
}
-
- .dataset-actions {
- .left {
- .icon-btn-group();
- float: left;
- .icon-btn {
- margin-right: @icon-btn-margin;
- }
- //.icon-btn-group {
- // margin-right: @icon-btn-margin;
- // .icon-btn {
- // margin-right: 0;
- // }
- //}
- &:not(:empty) {
- // can't use :empty on dataset-actions - will always have left & right, so
- // add gap to left (more likely to have children)
- .vertical-spacing;
- }
- }
- .right {
- .icon-btn-group();
- float: right;
- .icon-btn {
- margin-left: @icon-btn-margin;
- }
+ .dataset-info {
+ .info-section;
+ overflow: auto;
+ .value {
+ white-space: pre-line;
}
}
- //TODO: move these out
- .tags-display {
- display: none;
- .vertical-spacing;
- .select2-container {
- min-width: 0px;
- .select2-choices {
- border-radius: 3px;
- }
- }
- }
- .annotation-display {
- display: none;
- .vertical-spacing;
- .annotation {
- .info-section;
- white-space: pre-line;
- }
- .annotation:empty {
- height: @icon-btn-size;
- }
- // fake placeholder for editable text annotation
- .annotation:empty:after {
- position: relative;
- top: -4px;
- font-size: 10px;
- font-style: italic;
- color: grey;
- content : 'Click here to edit annotation';
- }
- textarea {
- margin: 0px 0px 2px 0px;
- display: block;
- border-radius: 3px;
- width: 100%;
- }
+ .job-error-text {
+ .info-section;
+ overflow: auto;
+ white-space: pre;
}
- .dataset-display-applications {
- .display-application:last-child {
+ // handle the last vertical gap in the parent as summary is used in other states as well (w/o info)
+ .vertical-spacing;
+ }
+
+ .dataset-actions {
+ .left {
+ .icon-btn-group();
+ float: left;
+ .icon-btn {
+ margin-right: @icon-btn-margin;
+ }
+ //.icon-btn-group {
+ // margin-right: @icon-btn-margin;
+ // .icon-btn {
+ // margin-right: 0;
+ // }
+ //}
+ &:not(:empty) {
+ // can't use :empty on dataset-actions - will always have left & right, so
+ // add gap to left (more likely to have children)
.vertical-spacing;
}
}
-
- .dataset-peek {
- .vertical-spacing;
- pre.peek {
- width: 100%;
- margin: 0px;
- border-radius: 3px;
- background: white;
- color: black;
- font-size: 10px;
- overflow: auto;
- th {
- color: white;
- background: @panel-primary-heading-bg;
- }
- table, th, tr, td {
- font-family: @font-family-monospace;
- font-size: 10px;
- }
+ .right {
+ .icon-btn-group();
+ float: right;
+ .icon-btn {
+ margin-left: @icon-btn-margin;
}
}
}
+ //TODO: move these out
+ .tags-display {
+ display: none;
+ .vertical-spacing;
+ .select2-container {
+ min-width: 0px;
+ .select2-choices {
+ border-radius: 3px;
+ }
+ }
+ }
+ .annotation-display {
+ display: none;
+ .vertical-spacing;
+ .annotation {
+ .info-section;
+ white-space: pre-line;
+ }
+ .annotation:empty {
+ height: @icon-btn-size;
+ }
+ // fake placeholder for editable text annotation
+ .annotation:empty:after {
+ position: relative;
+ top: -4px;
+ font-size: 10px;
+ font-style: italic;
+ color: grey;
+ content : 'Click here to edit annotation';
+ }
+ textarea {
+ margin: 0px 0px 2px 0px;
+ display: block;
+ border-radius: 3px;
+ width: 100%;
+ }
+ }
+
+ .dataset-display-applications {
+ .display-application:last-child {
+ .vertical-spacing;
+ }
+ }
+
+ .dataset-peek {
+ .vertical-spacing;
+ pre.peek {
+ width: 100%;
+ margin: 0px;
+ border-radius: 3px;
+ background: white;
+ color: black;
+ font-size: 10px;
+ overflow: auto;
+ th {
+ color: white;
+ background: @panel-primary-heading-bg;
+ }
+ table, th, tr, td {
+ font-family: @font-family-monospace;
+ font-size: 10px;
+ }
+ }
+ }
}
- .dataset .state-icon {
- .fa-icon;
- display: inline-block;
- margin-right: 4px;
- vertical-align: middle;
- width: 16px;
- height: 16px;
- line-height: 16px;
- text-align: center;
- font-size: 16px;
- }
+}
+
+.hda.dataset .state-icon {
+ .fa-icon;
+ display: inline-block;
+ margin-right: 4px;
+ vertical-align: middle;
+ width: 16px;
+ height: 16px;
+ line-height: 16px;
+ text-align: center;
+ font-size: 16px;
}
.state-icon-error {
diff -r 54695d3fa468250b1ee13a90facc753dc3d9831d -r b2cf571d0b63948a7252fc703200b854f964bad6 templates/webapps/galaxy/history/display_structured.mako
--- a/templates/webapps/galaxy/history/display_structured.mako
+++ b/templates/webapps/galaxy/history/display_structured.mako
@@ -1,83 +1,167 @@
<%inherit file="/base.mako"/>
-<%namespace file="/root/history_common.mako" import="render_dataset" />
+<%namespace file="/show_params.mako" name="show_params" />
+## ----------------------------------------------------------------------------
+<%def name="title()">${ history.name } | ${ _( 'Structure' ) }</%def><%def name="stylesheets()">
${parent.stylesheets()}
- ${h.css( "history" )}
<style type="text/css">
body {
- background: white;
padding: 5px;
}
-
+ body > .workflow, body > .toolForm {
+ /*width : 80%;*/
+ margin-bottom : 8px;
+ /*margin-left : auto;*/
+ /*margin-right : auto;*/
+ }
+ .bold {
+ font-weight: bold;
+ }
+ .light {
+ font-weight: lighter;
+ color: grey;
+ }
+ .right-aligned {
+ text-align: right;
+ }
+
.clickable {
cursor: pointer;
}
-
+
.workflow {
border: solid gray 1px;
- margin: 5px 0;
- border-left-width: 5px;
}
-
.workflow > .header {
background: lightgray;
padding: 5px 10px;
-
- font-weight: bold;
}
-
+ .workflow > .light {
+ color: gray;
+ }
.workflow > .body {
border-top: solid gray 1px;
- padding: 5px;
}
-
+ .workflow > .body > .toolForm {
+ border: 0px;
+ }
+
div.toolForm {
- margin: 5px 0;
- border-left-width: 5px;
+ border-width : 1px;
+ border-radius : 0px;
}
- div.toolFormBody {
- padding: 5px 5px;
+ .toolForm > .header {
+ background-color: #EBD9B2;
+ padding: 5px 10px;
}
+ .workflow div.toolForm:not(:first-child) .header {
+ border-top: 1px solid #D6B161;
+ }
+ div.toolFormTitle {
+ padding: 0px 0px 4px 0px;
+ margin: 0px 0px 4px 0px;
+ border: 0px;
+ background-color: transparent;
+ border-bottom: 1px solid #D6B161;
+ }
+ /* down from EBD9B2 --> 90743A */
+ .toolFormTitle > .light {
+ color: #90743A;
+ }
+ .toolForm em {
+ color: #90743A;
+ }
+
+ .job-inputs {
+ margin: 0px 6px 0px 6px;
+ text-align: left;
+ }
+ .job-inputs td:nth-child(1) {
+ text-align: right;
+ font-weight: lighter;
+ color: #90743A;
+ }
+ .job-inputs td:nth-child(1):after {
+ content : ':'
+ }
+ .job-inputs td:nth-child(2) {
+ padding-left: 4px;
+ }
+ .job-inputs em {
+ }
+
+ .job-inputs-show {
+ float: right;
+ }
+
+ .dataset.hda {
+ min-height : 37px;
+ border-width: 0px 0px 1px 0px;
+ }
+ .toolFormBody > .dataset.hda:last-child {
+ border-bottom-width: 0px;
+ }
+ .dataset.hda:first-child {
+ border-top: 1px solid #D6B161;
+ }
+ .dataset.hda .dataset-title-bar {
+ padding-top: 8px;
+ padding-left: 10px;
+ }
+
</style></%def><%def name="javascripts()">
+<%
+ self.js_app = 'display-structured'
+
+ controller = trans.webapp.controllers[ 'history' ]
+ hda_dicts = []
+ id_hda_dict_map = {}
+ for hda in history.active_datasets:
+ hda_dict = controller.get_hda_dict( trans, hda )
+ id_hda_dict_map[ hda_dict[ 'id' ] ] = hda_dict
+ hda_dicts.append( hda_dict )
+%>
${parent.javascripts()}
+
+ ## load edit views for each of the hdas
<script type="text/javascript">
+ define( 'display-structured', function(){
+ require([ 'mvc/dataset/hda-edit' ], function( hdaEdit ){
+ var hdaModel = require( 'mvc/dataset/hda-model' ),
+ hdaJSON = ${ h.to_json_string( hda_dicts, indent=( 2 if trans.debug else 0 ) ) };
+
+ window.hdas = hdaJSON.map( function( hda ){
+ return new hdaEdit.HDAEditView({
+ model : new hdaModel.HistoryDatasetAssociation( hda ),
+ el : $( '#hda-' + hda.id ),
+ linkTarget : '_self',
+ purgeAllowed : Galaxy.config.allow_user_dataset_purge,
+ logger : Galaxy.logger
+ }).render( false );
+ });
+ });
+ });
+
$(function(){
-
- $(".workflow, .tool").each( function() {
- var body = $(this).children( ".body" );
- $(this).children( ".header" ).click( function() {
+ $( ".workflow, .tool" ).each( function(){
+ var body = $( this ).children( ".body" );
+ $( this ).children( ".header" ).click( function(){
body.toggle();
}).addClass( "clickable" );
- // body.hide();
});
-
- $(".historyItem").each( function() {
- var id = this.id;
- var body = $(this).children( "div.historyItemBody" );
- var peek = body.find( "pre.peek" )
- $(this).children( ".historyItemTitleBar" ).find( ".historyItemTitle" ).wrap( "<a href='#'></a>" ).click( function() {
- if ( body.is(":visible") ) {
- // Hiding stuff here
- if ( $.browser.mozilla ) { peek.css( "overflow", "hidden" ) }
- body.slideUp( "fast" );
- } else {
- // Showing stuff here
- body.slideDown( "fast", function() {
- if ( $.browser.mozilla ) { peek.css( "overflow", "auto" ); }
- });
- }
- return false;
- });
- body.hide();
- });
- });
+ //$( ".job-inputs-show" ).click( function( ev ){
+ // ev.stopPropagation();
+ // $( this ).parent().siblings( '.job-inputs' ).toggle();
+ //});
+ });
</script></%def>
+## ----------------------------------------------------------------------------
<%def name="render_item( entity, children )"><%
entity_name = entity.__class__.__name__
@@ -91,42 +175,68 @@
</%def><%def name="render_item_hda( hda, children )">
- ${render_dataset( hda, hda.hid, display_structured=True )}
+## render hdas as a id'd stub for js to fill later
+ <% id = trans.security.encode_id( hda.id ) %>
+ <div id="hda-${id}" class="dataset hda state-${hda.state}"></div></%def><%def name="render_item_job( job, children )">
-
+## render a job (as a toolForm) and its children (hdas)
<div class="tool toolForm"><%
tool = trans.app.toolbox.get_tool( job.tool_id )
if tool:
tool_name = tool.name
+ tool_desc = tool.description
else:
- tool_name = "Unknown tool with id '%s'" % job.tool_id
+ tool_name = "Unknown tool with id '%s'" % job.tool_id
+ tool_desc = ''
+
+ params_object = None
+ try:
+ params_object = job.get_param_values( trans.app, ignore_errors=True )
+ except Exception, exc:
+ pass
%>
- <div class="header toolFormTitle">Tool: ${tool_name}</div>
+ <div class="header">
+ <div class="toolFormTitle">
+ <span class="bold">${tool_name}</span>
+ <span class="light">- ${tool_desc}</span>
+ ##<a class="job-inputs-show" href="javascript:void(0)">${ _( "parameters" )}</a>
+ </div>
+ %if tool and params_object:
+ <table class="job-inputs">
+ ${ show_params.inputs_recursive( tool.inputs, params_object, depth=1 ) }
+ </table>
+ %else:
+ <em>(${ _( 'No parameter data available' ) })</em>
+ %endif
+ </div><div class="body toolFormBody">
%for e, c in reversed( children ):
${render_item( e, c )}
%endfor
</div></div>
-
</%def><%def name="render_item_wf( wf, children )">
-
+## render a workflow and its children (jobs/toolForms)
<div class="workflow">
- <div class="header">Workflow: ${wf.workflow.name}</div>
+ <div class="header">
+ <span class="bold">${wf.workflow.name}</span>
+ <span class="light">- Workflow</span>
+ </div><div class="body">
%for e, c in reversed( children ):
${render_item( e, c )}
%endfor
</div></div>
-
</%def>
+## ----------------------------------------------------------------------------
+## render all items from a dictionary prov. by history/display_structured
%for entity, children in items:
${render_item( entity, children )}
-%endfor
\ No newline at end of file
+%endfor
diff -r 54695d3fa468250b1ee13a90facc753dc3d9831d -r b2cf571d0b63948a7252fc703200b854f964bad6 templates/webapps/galaxy/history/view.mako
--- a/templates/webapps/galaxy/history/view.mako
+++ b/templates/webapps/galaxy/history/view.mako
@@ -18,9 +18,6 @@
%></%def>
-<%def name="center_panel()">
-</%def>
-
## ----------------------------------------------------------------------------
<%def name="body()">
${center_panel()}
@@ -70,12 +67,6 @@
<%def name="javascripts()">
${parent.javascripts()}
-%if not use_panels:
-<script type="text/javascript">
-window.Galaxy = {};
-</script>
-%endif
-
</%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