Merge remote-tracking branch 'upstream/dev' into dev_unittest_bugfix

This commit is contained in:
Sergey Golitsynskiy
2019-07-15 16:18:13 -04:00
21 changed files with 52 additions and 1739 deletions
-3
View File
@@ -139,9 +139,6 @@ jobs:
<<: *set_workdir
steps:
- *restore_repo_cache
- run: sudo apt-get update
# For uwsgi
- run: sudo apt-get install -y libpython3.5-dev
- *install_tox
- run: tox -e py35-first_startup
validate_test_tools:
-80
View File
@@ -1,80 +0,0 @@
import Backbone from "backbone";
import { getGalaxyInstance } from "app";
import mod_shed_list_view from "mvc/toolshed/shed-list-view";
import mod_categories_view from "mvc/toolshed/categories-view";
import mod_repositories_view from "mvc/toolshed/repositories-view";
import mod_repository_view from "mvc/toolshed/repository-view";
import mod_repoqueue_view from "mvc/toolshed/repository-queue-view";
import mod_repo_status_view from "mvc/toolshed/repo-status-view";
import mod_workflows_view from "mvc/toolshed/workflows-view";
var AdminToolshedRouter = Backbone.Router.extend({
routes: {
"": "toolsheds",
sheds: "toolsheds",
queue: "queue",
workflows: "workflows",
"status/r/:repositories": "status",
status: "status",
"categories/s/:tool_shed": "categories",
"category/s/:tool_shed/c/:category_id/k/:sort_key/p/:page/t/:sort_order": "repositories",
"repository/s/:tool_shed/r/:repository_id": "repository"
}
});
var GalaxyAdminToolshedApp = Backbone.View.extend({
app_config: {
known_views: ["toolsheds", "queue", "status", "categories", "repositories", "repository"]
},
initialize: function() {
const Galaxy = getGalaxyInstance();
Galaxy.admintoolshedapp = this;
this.admin_toolshed_router = new AdminToolshedRouter();
this.admin_toolshed_router.on("route:queue", () => {
Galaxy.admintoolshedapp.adminRepoQueueView = new mod_repoqueue_view.RepoQueueView();
});
this.admin_toolshed_router.on("route:toolsheds", () => {
Galaxy.admintoolshedapp.adminShedListView = new mod_shed_list_view.ShedListView();
});
this.admin_toolshed_router.on("route:categories", tool_shed => {
Galaxy.admintoolshedapp.adminShedCategoriesView = new mod_categories_view.CategoryView({
tool_shed: tool_shed.replace(/\//g, "%2f")
});
});
this.admin_toolshed_router.on(
"route:repositories",
(tool_shed, category_id, sort_key = "name", page = 1, sort_order = "asc") => {
Galaxy.admintoolshedapp.adminShedCategoryView = new mod_repositories_view.Category({
tool_shed: tool_shed.replace(/\//g, "%2f"),
category_id: category_id,
page: page,
sort_order: sort_order,
sort_key: sort_key
});
}
);
this.admin_toolshed_router.on("route:repository", (tool_shed, repository_id) => {
Galaxy.admintoolshedapp.adminRepositoryView = new mod_repository_view.RepoDetails({
tool_shed: tool_shed.replace(/\//g, "%2f"),
repository_id: repository_id
});
});
this.admin_toolshed_router.on("route:status", repositories => {
Galaxy.admintoolshedapp.adminRepoStatusView = new mod_repo_status_view.RepoStatus({
repositories: repositories.split("|")
});
});
this.admin_toolshed_router.on("route:workflows", () => {
Galaxy.admintoolshedapp.adminWorkflowsView = new mod_workflows_view.Workflows();
});
Backbone.history.start({ pushState: false });
}
});
export default {
GalaxyApp: GalaxyAdminToolshedApp
};
-5
View File
@@ -17,7 +17,6 @@ import Circster from "viz/circster";
export { PhylovizView as phyloviz } from "viz/phyloviz";
export { SweepsterVisualization, SweepsterVisualizationView } from "viz/sweepster";
import GalaxyLibrary from "galaxy.library";
import AdminToolshed from "admin.toolshed";
export { default as pages } from "galaxy.pages";
export { createTabularDatasetChunkedView } from "mvc/dataset/data";
import { HistoryCollection } from "mvc/history/history-model";
@@ -36,10 +35,6 @@ export { default as IES } from "galaxy.interactive_environments";
export { Toast } from "ui/toast"; // TODO: remove when external consumers are updated/gone (IES right now)
export function adminToolshed(options) {
new AdminToolshed.GalaxyApp(options);
}
export function trackster(options) {
new TracksterUIView(options);
}
@@ -1,98 +0,0 @@
import _ from "underscore";
import $ from "jquery";
import Backbone from "backbone";
import { getAppRoot } from "onload/loadConfig";
import toolshed_model from "mvc/toolshed/toolshed-model";
import toolshed_util from "mvc/toolshed/util";
import "libs/jquery/jquery-ui";
var ToolShedCategories = Backbone.View.extend({
el: "#center",
initialize: function(options) {
this.options = _.defaults(this.options || options, this.defaults);
this.model = new toolshed_model.Categories();
this.model.url = `${this.model.url}?tool_shed_url=${this.options.tool_shed}`;
this.model.tool_shed = options.tool_shed.replace(/\//g, "%2f");
this.model.fetch();
this.listenTo(this.model, "sync", this.render);
},
render: function(options) {
const category_list_template = this.templateCategoryList();
this.options = _.extend(this.options, options);
this.options.categories = this.model.models;
this.options.queue = toolshed_util.queueLength();
this.$el.html(category_list_template(this.options));
this.bindEvents();
$("#center").css("overflow", "auto");
},
bindEvents: function() {
$("#search_box").autocomplete({
source: (request, response) => {
var shed_url = this.model.tool_shed.replace(/%2f/g, "/");
var base_url = `${getAppRoot()}api/tool_shed/search`;
var params = {
term: request.term,
tool_shed_url: shed_url
};
$.post(base_url, params, data => {
console.log(data);
var result_list = toolshed_util.shedParser(data);
response(result_list);
});
},
minLength: 3,
select: (event, ui) => {
var tsr_id = ui.item.value;
var new_route = `repository/s/${this.model.tool_shed}/r/${tsr_id}`;
Backbone.history.navigate(new_route, {
trigger: true,
replace: true
});
}
});
},
templateCategoryList: function() {
return _.template(
`<div class='shed-style-container'>
<div class='header'>
<h2>Categories in <%= tool_shed.replace(/%2f/g, '/') %></h2>
<span><a href='#/queue'>Repository Queue (<%= queue %>)</a></span>
<span style='clear:both; '></span>
</div>
<div id='standard-search' style='height: 2em; margin: 1em;'>
<span class='ui-widget' >
<input class='search-box-input' id='search_box' data-shedurl='<%= tool_shed.replace(/%2f/g, '/') %>' name='search' placeholder='Search repositories' size='30' type='text' />
</span>
</div>
<div style='clear: both; margin-top: 1em;'>
<table class='grid'>
<thead id='grid-table-header'>
<tr>
<th>Name</th>
<th>Description</th>
<th>Repositories</th>
</tr>
</thead>
<% _.each(categories, function(category) { %>
<tr>
<td>
<a href='#/category/s/<%= tool_shed %>/c/<%= category.get('id') %>/k/name/p/1/t/asc'><%= category.get('name') %></a>
</td>
<td><%= category.get('description') %></td>
<td><%= category.get('repositories') %></td>
</tr>
<% }); %>
</table>
</div>
</div>`
);
}
});
export default {
CategoryView: ToolShedCategories
};
@@ -1,132 +0,0 @@
import $ from "jquery";
import Backbone from "backbone";
import _ from "underscore";
import _l from "utils/localization";
import toolshed_model from "mvc/toolshed/toolshed-model";
import toolshed_util from "mvc/toolshed/util";
var ToolShedRepoStatusView = Backbone.View.extend({
el: "#center",
initialize: function(options) {
this.options = _.defaults(this.options || [{}], options, this.defaults);
this.model = new toolshed_model.RepoStatus();
this.listenTo(this.model, "sync", this.render);
this.model.url += `?repositories=${this.options.repositories.join("|")}`;
this.model.fetch();
this.timer = window.setInterval(() => {
var terminal_states = ["installed", "error"];
var all_done = true;
_.some(this.model.models, repository => {
var repo_status = repository.get("status").toLowerCase();
if (terminal_states.indexOf(repo_status) === -1) {
all_done = false;
return true;
}
});
if (all_done) {
window.clearInterval(this.timer);
} else {
this.model.fetch();
}
}, 2000);
},
close: function() {
window.clearInterval(this.timer);
},
render: function(options) {
this.options = _.extend(this.options, options);
var repo_status_template = this.templateRepoStatus();
this.$el.html(
repo_status_template({
title: _l("Repository Status"),
repositories: this.model.models,
queue: toolshed_util.queueLength()
})
);
$("#center").css("overflow", "auto");
},
templateRepoStatus: function() {
return _.template(
`<div class="unified-panel-header" id="panel_header" unselectable="on">
<div class="unified-panel-header-inner"><%= title %>
<a class="ml-auto" href="#/queue">Repository Queue (<%= queue %>)</a>
</div>
</div>
<style type="text/css">
.state-color-new,
.state-color-deactivated,
.state-color-uninstalled { border-color:#bfbfbf; background:#eee }
.state-color-cloning,
.state-color-setting-tool-versions,
.state-color-installing-repository-dependencies,
.state-color-installing-tool-dependencies,
.state-color-loading-proprietary-datatypes { border-color:#AAAA66; background:#FFFFCC }
.state-color-installed { border-color:#20b520; background:#b0f1b0 }
.state-color-error { border-color:#dd1b15; background:#f9c7c5 }
</style>
<table id="grid-table" class="grid">
<thead id="grid-table-header">
<tr>
<th id="null-header">Name<span class="sort-arrow"></span></th>
<th id="null-header">Description<span class="sort-arrow"></span></th>
<th id="null-header">Owner<span class="sort-arrow"></span></th>
<th id="null-header">Revision<span class="sort-arrow"></span></th>
<th id="null-header">Installation Status<span class="sort-arrow"></span></th>
</tr>
</thead>
<tbody id="grid-table-body">
<% _.each(repositories, function(repository) { %>
<tr>
<td>
<div id="" class="">
<label id="repo-name-<%= repository.get("id") %>" for="<%= repository.get("id") %>">
<%= repository.get("name") %>
</label>
</div>
</td>
<td>
<div id="" class="">
<label id="repo-desc-<%= repository.get("id") %>" for="<%= repository.get("id") %>">
<%= repository.get("description") %>
</label>
</div>
</td>
<td>
<div id="" class="">
<label id="repo-user-<%= repository.get("id") %>" for="<%= repository.get("id") %>">
<%= repository.get("owner") %>
</label>
</div>
</td>
<td>
<div id="" class="">
<label id="repo-changeset-<%= repository.get("id") %>" for="<%= repository.get("id") %>">
<%= repository.get("changeset_revision") %>
</label>
</div>
</td>
<td>
<div id="" class="">
<label id="RepositoryStatus-<%= repository.get("id") %>" for="<%= repository.get("id") %>">
<div class="repo-status count-box state-color-<%= repository.get("status").toLowerCase().replace(/ /g, "-") %>" id="RepositoryStatus-<%= repository.get("id") %>">
<%= repository.get("status") %>
</div>
</label>
</div>
</td>
</tr>
<% }); %>
</tbody>
<tfoot id="grid-table-footer"></tfoot>
</table>`
);
}
});
export default {
RepoStatus: ToolShedRepoStatusView
};
@@ -1,222 +0,0 @@
import _ from "underscore";
import $ from "jquery";
import Backbone from "backbone";
import { getAppRoot } from "onload/loadConfig";
import toolshed_model from "mvc/toolshed/toolshed-model";
import toolshed_util from "mvc/toolshed/util";
import "libs/jquery/jquery-ui";
var ToolShedCategoryContentsView = Backbone.View.extend({
el: "#center",
initialize: function(params) {
this.params = params;
this.model = new toolshed_model.CategoryCollection();
this.listenTo(this.model, "sync", this.render);
var shed = params.tool_shed.replace(/\//g, "%2f");
this.model.url += `?tool_shed_url=${shed}`;
this.model.url += `&category_id=${params.category_id}`;
this.model.url += `&sort_key=${params.sort_key}`;
this.model.url += `&sort_order=${params.sort_order}`;
this.model.url += `&page=${params.page}`;
this.model.tool_shed = shed;
this.model.category = params.category_id;
this.model.fetch();
},
render: function(options) {
this.options = _.defaults(this.options || {}, options);
var category_contents_template = this.templateCategoryContents();
var page_navigation_template = this.templatePageNavigation();
var sorting = {
class: { owner: "fa-sort", description: "fa-sort", name: "fa-sort" },
direction: { owner: "asc", description: "asc", name: "asc" }
};
sorting.class[this.params.sort_key] = this.params.sort_order == "desc" ? "fa-sort-down" : "fa-sort-up";
sorting.direction[this.params.sort_key] = this.params.sort_order == "asc" ? "desc" : "asc";
var previous_page = Math.max(this.params.page - 1, 1);
var pages = parseInt(this.model.models[0].get("repository_count") % 25) + 1;
var next_page = Math.min(parseInt(this.params.page) + 1, pages);
var pagination_params = {
page: this.params.page,
next: next_page,
previous: previous_page,
pages: pages
};
if (pages > 5) {
var page = parseInt(this.params.page);
var page_slice = Array();
var slice_start = Math.max(page - 2, 2);
var i = slice_start;
var slice_end = Math.min(Math.min(page + 2, slice_start + 4), pages);
for (i = slice_start; i <= slice_end; i++) {
page_slice.push(i);
}
pagination_params["page_slice"] = page_slice;
}
this.$el.html(
category_contents_template({
page_navigation: page_navigation_template(pagination_params),
category: this.model.models[0],
tool_shed: this.model.tool_shed,
queue: toolshed_util.queueLength(),
sorting: sorting,
page: this.params.page
})
);
$("#center").css("overflow", "auto");
this.bindEvents();
},
bindEvents: function() {
$("#search_box").autocomplete({
source: (request, response) => {
var shed_url = this.model.tool_shed.replace(/%2f/g, "/");
var base_url = `${getAppRoot()}api/tool_shed/search`;
var params = {
term: request.term,
tool_shed_url: shed_url
};
$.post(base_url, params, data => {
var result_list = toolshed_util.shedParser(data);
response(result_list);
});
},
minLength: 3,
select: (event, ui) => {
var tsr_id = ui.item.value;
var new_route = `repository/s/${this.model.tool_shed}/r/${tsr_id}`;
Backbone.history.navigate(new_route, {
trigger: true,
replace: true
});
}
});
$(".fa-fw").on("click", ev => {
var parameters = {};
parameters.field = $(ev.target).attr("data-field");
parameters.direction = $(ev.target).attr("data-direction");
var new_route = `category/s/${this.model.tool_shed}/c/${this.model.category}/k/${parameters.field}/p/${
this.params.page
}/t/${parameters.direction}`;
Backbone.history.navigate(new_route, {
trigger: true,
replace: true
});
});
$(".pagenav").on("click", ev => {
var page = $(ev.target).attr("data-page");
var new_route = `category/s/${this.model.tool_shed}/c/${this.model.category}/k/${
this.params.sort_key
}/p/${page}/t/${this.params.sort_order}`;
Backbone.history.navigate(new_route, {
trigger: true,
replace: true
});
});
},
templatePageNavigation: function() {
return _.template(
`<div class="navigation">
<% if (page != 1) { %>
<a data-page="1" class="pagenav fa fa-fast-backward" />
<a data-page="<%= previous %>" class="pagenav fa fa-step-backward" />
<% } else { %>
<a data-page="1" class="pagenav-inactive fa fa-fast-backward" />
<a data-page="<%= previous %>" class="pagenav-inactive fa fa-step-backward" />
<% } %>
<% if (pages > 5) { %>
<% if (page != 1) { %>
<a data-page="1" class="pagenav fa"><a>1</a>
<% if (page != 2) { %>
<a class="fa">&hellip;</a>
<% } %>
<% } else { %>
<a data-page="1" class="pagenav-inactive fa"><a>1</a>
<% } %>
<% _.each(page_slice, function(i) { %>
<% if (i == page) { %>
<a data-page="<%= i %>" class="fa"><strong><%= i %></strong></a>
<% } else { %>
<a data-page="<%= i %>" class="pagenav fa"><%= i %></a>
<% } %>
<% }); %>
<% var last_pages = [pages - 2, pages - 1, pages]; %>
<% if (last_pages.indexOf(parseInt(page)) == -1) { %>
<a class="fa">&hellip;</a>
<a data-page="<%= pages %>" class="pagenav fa"><%= pages %></a>
<% } %>
<% } else { %>
<% for (i = 1; i <= pages; i++) { %>
<% if (i == page) { %>
<a data-page="<%= i %>" class="fa"><strong><%= i %></strong></a>
<% } else { %>
<a data-page="<%= i %>" class="pagenav fa"><%= i %></a>
<% } %>
<% } %>
<% } %>
<% if (page < pages) { %>
<a data-page="<%= next %>" class="pagenav fa fa-step-forward" />
<a data-page="<%= pages %>" class="pagenav fa fa-fast-forward" />
<% } else { %>
<a data-page="<%= next %>" class="pagenav-inactive fa fa-step-forward" />
<a data-page="<%= pages %>" class="pagenav-inactive fa fa-fast-forward" />
<% } %>
</div>`
);
},
templateCategoryContents: function() {
return _.template(
`<style type="text/css">
.ui-autocomplete { background-color: #fff; }
li.ui-menu-item { list-style-type: none; }
div.navigation { width: 100%; text-align: center; }
div.navigation a { margin-left: 0.5em; margin-right: 0.5em; display: inline; text-decoration: underline; }
a.pagenav-inactive { opacity: 0.5; }
</style>
<div class="unified-panel-header" id="panel_header" unselectable="on">
<div class="unified-panel-header-inner">Repositories in <%= category.get("name") %><a class="ml-auto" href="#/queue">Repository Queue (<%= queue %>)</a></div>
</div>
<div class="unified-panel-body" id="list_repositories">
<div id="standard-search" style="height: 2em; margin: 1em;">
<span class="ui-widget" >
<input class="search-box-input" id="search_box" name="search" data-shedurl="<%= tool_shed.replace(/%2f/g, "/") %>" placeholder="Search repositories by name or id" size="60" type="text" />
</span>
</div>
<% if (category.get('repository_count') > 25) { %>
<%= page_navigation %>
<% } %>
<div style="clear: both; margin-top: 1em;">
<table class="grid table-striped">
<thead id="grid-table-header">
<tr>
<th style="width: 10%;"><a class="fa fa-fw <%= sorting.class.owner %>" data-direction="<%= sorting.direction.owner %>" data-field="owner">Owner</a></th>
<th style="width: 15%;"><a class="fa fa-fw <%= sorting.class.name %>" data-direction="<%= sorting.direction.name %>" data-field="name">Name</a></th>
<th><a class="fa fa-fw <%= sorting.class.description %>" data-direction="<%= sorting.direction.description %>" data-field="description">Synopsis</a></th>
<th style="width: 10%;">Type</th>
</tr>
</thead>
<% _.each(category.get("repositories"), function(repository) { %>
<tr>
<td><%= repository.owner %></td>
<td>
<div style="float: left; margin-left: 1px;" class="menubutton split">
<a href="#/repository/s/<%= tool_shed %>/r/<%= repository.id %>"><%= repository.name %></a>
</div>
</td>
<td><%= repository.description %></td>
<td><%= repository.type %></td>
</tr>
<% }); %>
</table>
</div>
</div>`
);
}
});
export default {
Category: ToolShedCategoryContentsView
};
@@ -1,166 +0,0 @@
import _ from "underscore";
import $ from "jquery";
import Backbone from "backbone";
import { getAppRoot } from "onload/loadConfig";
import _l from "utils/localization";
import toolshed_model from "mvc/toolshed/toolshed-model";
import toolshed_util from "mvc/toolshed/util";
var View = Backbone.View.extend({
el: "#center",
defaults: [],
initialize: function(options) {
this.model = new toolshed_model.RepoQueue();
this.listenTo(this.model, "sync", this.render);
this.model.fetch();
this.render();
},
render: function(options) {
var repo_queue_template = this.templateRepoQueue();
var repositories = this.model.models;
this.$el.html(
repo_queue_template({
repositories: repositories,
queue: toolshed_util.queueLength()
})
);
$("#center").css("overflow", "auto");
this.bindEvents();
},
bindEvents: function() {
$(".install_one").on("click", ev => {
const repository_metadata = this.loadFromQueue($(ev.target).attr("data-repokey"));
this.installFromQueue(repository_metadata, $(ev.target).attr("data-repokey"));
});
$(".remove_one").on("click", ev => {
const queue_key = $(ev.target).attr("data-repokey");
const repo_queue = JSON.parse(window.localStorage.repositories);
if (repo_queue.hasOwnProperty(queue_key)) {
this.removeRow(repo_queue[queue_key].id);
delete repo_queue[queue_key];
}
window.localStorage.repositories = JSON.stringify(repo_queue);
});
$("#clear_queue").on("click", () => {
const repo_queue = JSON.parse(window.localStorage.repositories);
for (const key of Object.keys(repo_queue)) {
this.removeRow(repo_queue[key].id);
}
window.localStorage.repositories = "{}";
});
$("#from_workflow").on("click", () => {
Backbone.history.navigate("workflows", {
trigger: true,
replace: true
});
});
},
removeRow: function(row_id) {
$(`#queued_repository_${row_id}`).remove();
},
installFromQueue: function(repository_metadata, queue_key) {
var params = {};
params.install_tool_dependencies = repository_metadata.install_tool_dependencies;
params.install_repository_dependencies = repository_metadata.install_repository_dependencies;
params.install_resolver_dependencies = repository_metadata.install_resolver_dependencies;
params.tool_panel_section = repository_metadata.tool_panel_section;
params.shed_tool_conf = repository_metadata.shed_tool_conf;
params.repositories = JSON.stringify([
[repository_metadata.repository.id, repository_metadata.changeset_revision]
]);
params.tool_shed_repository_ids = JSON.stringify([repository_metadata.repository.id]);
params.tool_shed_url = queue_key.split("|")[0];
params.changeset = repository_metadata.changeset_revision;
var url = `${getAppRoot()}api/tool_shed_repositories/install?async=True`;
$(`#queued_repository_${repository_metadata.repository.id}`).remove();
if (window.localStorage.repositories) {
if (queue_key === undefined) {
queue_key = toolshed_util.queueKey(repository_metadata);
}
var repository_queue = JSON.parse(window.localStorage.repositories);
if (repository_queue.hasOwnProperty(queue_key)) {
delete repository_queue[queue_key];
window.localStorage.repositories = JSON.stringify(repository_queue);
}
}
$.post(url, params, data => {
var iri_params = JSON.parse(data);
var repositories = iri_params.repositories;
var new_route = `status/r/${repositories.join("|")}`;
$.post(`${getAppRoot()}admin_toolshed/install_repositories`, iri_params, data => {
console.log("Initializing repository installation succeeded");
});
Backbone.history.navigate(new_route, {
trigger: true,
replace: true
});
});
},
loadFromQueue: function(queue_key) {
var repository_queue = JSON.parse(window.localStorage.repositories);
if (repository_queue.hasOwnProperty(queue_key)) {
return repository_queue[queue_key];
}
return this.defaults;
},
templateRepoQueue: function() {
return _.template(
`<div class='shed-style-container'>
<h2>
${_l("Repository Queue")}
</h2>
<div class='tab-pane' id='panel_header' id='repository_queue'>
<table id='queued_repositories' class='grid' border='0' cellpadding='2' cellspacing='2' width='100%'>
<thead id='grid-table-header'>
<tr>
<th class='datasetRow'>Name</th>
<th class='datasetRow'>Owner</th>
<th class='datasetRow'>Revision</th>
<th class='datasetRow'>ToolShed</th>
<th class='datasetRow'>Install</th>
<th class='datasetRow'></th>
</tr>
</thead>
<tbody>
<% if (repositories.length > 0) { %>
<% _.each(repositories, function(repository) { %>
<tr id='queued_repository_<%= repository.get('id') %>'>
<td class='datasetRow'><%= repository.get('repository').name %></td>
<td class='datasetRow'><%= repository.get('repository').owner %></td>
<td class='datasetRow'><%= repository.get('changeset_revision') %></td>
<td class='datasetRow'><%= repository.get('tool_shed_url') %></td>
<td class='datasetRow'>
<input class='btn btn-primary install_one' data-repokey='<%= repository.get('queue_key') %>' type='submit' id='install_repository_<%= repository.get('id') %>' name='install_repository' value='Install now' />
</td>
<td class='datasetRow'>
<input class='btn btn-primary remove_one' data-repokey='<%= repository.get('queue_key') %>' type='submit' id='unqueue_repository_<%= repository.get('id') %>' name='unqueue_repository' value='Remove from queue' />
</td>
</tr>
<% }); %>
<% } else { %>
<tr><td colspan='6'>
${_l("No repositories in queue.")}
</td></tr>
<% } %>
</tbody>
</table>
<input type='button' class='btn btn-primary' id='from_workflow' value='Add from workflow' />
<input class='btn btn-primary' type='submit' id='clear_queue' name='clear_queue' value='Clear queue' />
</div>
</div>`
);
}
});
export default {
RepoQueueView: View
};
@@ -1,637 +0,0 @@
import _ from "underscore";
import $ from "jquery";
import Backbone from "backbone";
import { getAppRoot } from "onload/loadConfig";
import "libs/jquery/jstree";
import toolshed_model from "mvc/toolshed/toolshed-model";
import Utils from "utils/utils";
import Modal from "mvc/ui/ui-modal";
import FormView from "mvc/form/form-view";
import toolshed_util from "mvc/toolshed/util";
var ToolShedRepositoryView = Backbone.View.extend({
el: "#center",
initialize: function(params) {
this.options = _.defaults(this.options || {}, this.defaults);
this.model = new toolshed_model.RepositoryCollection();
this.listenTo(this.model, "sync", this.render);
var shed = params.tool_shed.replace(/\//g, "%2f");
this.model.url += `?tool_shed_url=${shed}&repository_id=${params.repository_id}`;
this.model.tool_shed_url = params.tool_shed.replace(/%2f/g, "/");
this.model.tool_shed = shed;
this.model.category = params.repository_id;
this.model.fetch();
},
render: function(options) {
var repo_details_template = this.templateRepoDetails();
var models = this.model.models[0];
this.options = {
repository: models.get("repository"),
tool_shed: this.model.tool_shed,
queue: toolshed_util.queueLength()
};
var changesets = Object.keys(this.options.repository.metadata).sort(function(a, b) {
return parseInt(a.split(":")[0] - b.split(":")[0]);
});
var ordered_metadata = {};
var unordered_metadata = this.options.repository.metadata;
changesets.forEach(function(key) {
ordered_metadata[key] = unordered_metadata[key];
});
this.options.repository.metadata = ordered_metadata;
this.options.current_changeset = this.options.current_changeset || changesets[changesets.length - 1];
this.options.current_metadata = this.options.repository.metadata[this.options.current_changeset];
this.options.current_metadata.tool_shed_url = this.model.tool_shed_url;
this.options.tools = this.options.current_metadata.tools;
this.options.repository_dependencies_template = this.templateRepoDependencies();
this.options.repository_dependency_template = this.templateRepoDependency();
this.options.tps_template_global_select = this.templateGlobalSectionSelect();
this.options.tps_template_global_create = this.templateGlobalSectionCreate();
this.options.tps_template_tool_select = this.templateToolSectionSelect();
this.options.tps_template_tool_create = this.templateToolSectionCreate();
this.options.panel_section_options = this.templatePanelSelectOptions();
this.options.tool_dependencies = models.get("tool_dependencies");
this.options.shed_tool_conf = this.templateShedToolConf({
shed_tool_confs: models.get("shed_conf")
});
this.options.panel_section_dict = models.get("panel_section_dict");
this.options.api_url = `${getAppRoot()}api/tool_shed_repositories/install?async=True`;
this.options = _.extend(this.options, options);
this.$el.html(repo_details_template(this.options));
this.checkInstalled(this.options.current_metadata);
this.bindEvents();
$("#center").css("overflow", "auto");
},
bindEvents: function() {
$("#changeset").on("change", () => {
this.options.current_changeset = $("#changeset")
.find("option:selected")
.text();
this.options.current_metadata = this.options.repository.metadata[this.options.current_changeset];
this.checkInstalled(this.options.current_metadata);
this.reDraw(this.options);
});
$("#tool_panel_section_select").on("change", () => {
this.tpsSelection();
});
$("#install_repository").on("click", ev => {
ev.preventDefault();
var params = {};
params.repositories = JSON.stringify([
[
$("#install_repository").attr("data-tsrid"),
$("#changeset")
.find("option:selected")
.val()
]
]);
params.tool_shed_repository_ids = JSON.stringify([$("#install_repository").attr("data-tsrid")]);
params.tool_shed_url = this.model.tool_shed_url;
params.install_tool_dependencies = $("#install_tool_dependencies").val();
params.install_repository_dependencies = $("#install_repository_dependencies").val();
params.install_resolver_dependencies = $("#install_resolver_dependencies").val();
params.tool_panel_section = JSON.stringify(this.panelSelect(params));
params.shed_tool_conf = $("select[name='shed_tool_conf']")
.find("option:selected")
.val();
params.changeset = $("#changeset")
.find("option:selected")
.val();
var url = $("#repository_installation").attr("action");
this.prepareInstall(params, url);
});
$("#queue_install").on("click", ev => {
this.options.current_changeset = $("#changeset")
.find("option:selected")
.text();
this.options.current_metadata = this.options.repository.metadata[this.options.current_changeset];
var repository_metadata = {};
_.each(Object.keys(this.options.current_metadata), key => {
if (!repository_metadata[key]) {
repository_metadata[key] = this.options.current_metadata[key];
}
});
repository_metadata.install_tool_dependencies = $("#install_tool_dependencies").val();
repository_metadata.install_repository_dependencies = $("#install_repository_dependencies").val();
repository_metadata.install_resolver_dependencies = $("#install_resolver_dependencies").val();
repository_metadata.tool_panel_section = JSON.stringify(this.panelSelect({}));
repository_metadata.shed_tool_conf = $("select[name='shed_tool_conf']")
.find("option:selected")
.val();
repository_metadata.tool_shed_url = this.model.tool_shed_url;
if (repository_metadata.tool_shed_url.substr(-1) == "/") {
repository_metadata.tool_shed_url = repository_metadata.tool_shed_url.substr(
0,
repository_metadata.tool_shed_url.length - 1
);
}
toolshed_util.addToQueue(repository_metadata);
this.checkInstalled(repository_metadata);
});
this.toolTPSSelectionEvents();
$(() => {
$("#repository_dependencies").jstree();
});
$(".tool_form").on("click", ev => {
var guid = $(ev.target).attr("data-guid");
var name = $(ev.target).attr("data-name");
var desc = $(ev.target).attr("data-desc");
var tool_shed_url = this.model.tool_shed_url;
var tsr_id = $("#repository_details").attr("data-tsrid");
var changeset = $("#changeset")
.find("option:selected")
.val();
var api_url = `${getAppRoot()}api/tool_shed/tool_json`;
var params = {
guid: guid,
tool_shed_url: tool_shed_url,
tsr_id: tsr_id,
changeset: changeset
};
$.get(api_url, params, data => {
var toolform = new FormView(data);
Utils.deepeach(data.inputs, input => {
if (input.type) {
if (["data", "data_collection"].indexOf(input.type) != -1) {
input.type = "hidden";
input.info = `Data input '${input.name}' (${Utils.textify(input.extensions)})`;
}
}
});
var modal = new Modal.View();
var modal_title = `<u>${name}</u> ${desc}`;
modal.show({
closing_events: true,
title: modal_title,
body: toolform.$el,
buttons: {
Close: function() {
modal.hide();
}
}
});
});
});
$(".select-tps-button").on("click", params => {
var changeset = this.selectedChangeset();
var guid = params.target.attributes.getNamedItem("data-toolguid");
this.showToolTPSSelect(guid, changeset);
});
$(".create-tps-button").on("click", params => {
var changeset = this.selectedChangeset();
var guid = params.target.attributes.getNamedItem("data-toolguid");
this.showToolTPSCreate(guid, changeset);
});
$(".global-select-tps-button").on("click", () => {
$("#tool_panel_section").replaceWith(this.options.tps_template_global_select(this.options));
this.propagateTPS();
this.bindEvents();
});
$(".global-create-tps-button").on("click", () => {
$("#tool_panel_section").replaceWith(this.options.tps_template_global_create());
this.bindEvents();
});
},
checkInstalled: function(metadata) {
var params = { name: metadata.name, owner: metadata.owner };
var already_installed = false;
$.get(`${getAppRoot()}api/tool_shed_repositories`, params, data => {
for (var index = 0; index < data.length; index++) {
var repository = data[index];
var installed = !repository.deleted && !repository.uninstalled;
var changeset_match =
repository.changeset_revision == metadata.changeset_revision ||
repository.installed_changeset_revision == metadata.changeset_revision;
if (
repository.name == metadata.repository.name &&
repository.owner == metadata.repository.owner &&
installed &&
changeset_match
) {
already_installed = true;
}
if (already_installed) {
$("#install_repository").prop("disabled", true);
$("#install_repository").val("This revision is already installed");
} else {
$("#install_repository").prop("disabled", false);
$("#install_repository").val("Install this revision");
}
}
if (this.repoQueued(metadata) || already_installed) {
$("#queue_install").hide();
$("#queue_install").val("This revision is already in the queue");
} else {
$("#queue_install").show();
$("#queue_install").val("Install this revision later");
}
});
},
panelSelect: function(params) {
var tool_panel_section = {};
if ($("#tool_panel_section_select").length) {
params.tool_panel_section_id = $("#tool_panel_section_select")
.find("option:selected")
.val();
} else {
params.new_tool_panel_section = $("#new_tool_panel_section").val();
}
$(".tool_panel_section_picker").each(function() {
var element_name = $(this).attr("name");
var tool_guid = $(this).attr("data-toolguid");
if (element_name === "tool_panel_section_id") {
tool_panel_section[tool_guid] = {
tool_panel_section: $(this)
.find("option:selected")
.val(),
action: "append"
};
} else {
tool_panel_section[tool_guid] = {
tool_panel_section: $(this).val(),
action: "create"
};
}
});
return tool_panel_section;
},
reDraw: function(options) {
this.$el.empty();
this.render(options);
},
repoQueued: function(metadata) {
if (!window.localStorage.repositories) {
return;
}
var queue_key = this.queueKey(metadata);
var queued_repos;
if (window.localStorage.repositories) {
queued_repos = JSON.parse(window.localStorage.repositories);
}
if (queued_repos && queued_repos.hasOwnProperty(queue_key)) {
return true;
}
return false;
},
queueKey: function(metadata) {
var shed_url = this.model.tool_shed_url;
// Make sure there is never a trailing slash on the shed URL.
if (shed_url.substr(-1) == "/") {
shed_url = shed_url.substr(0, shed_url.length - 1);
}
return `${shed_url}|${metadata.repository_id}|${metadata.changeset_revision}`;
},
tpsSelection: function() {
var new_tps = $("#tool_panel_section_select")
.find("option:selected")
.val();
$('.tool_panel_section_picker[default="active"]').each(function() {
$(this).val(new_tps);
});
},
prepareInstall: function(params, api_url) {
$.post(api_url, params, data => {
var iri_parameters = JSON.parse(data);
this.doInstall(iri_parameters);
});
},
doInstall: function(params) {
var controller_url = `${getAppRoot()}admin_toolshed/install_repositories`;
var repositories = params.repositories;
var new_route = `status/r/${repositories.join("|")}`;
$.post(controller_url, params, data => {
console.log("Initializing repository installation succeeded");
});
Backbone.history.navigate(new_route, {
trigger: true,
replace: true
});
},
selectedChangeset: function() {
return $("#changeset")
.find("option:selected")
.val();
},
showToolTPSCreate: function(guid, changeset) {
var metadata = this.options.current_metadata;
var tools = metadata.tools;
var tool = toolshed_util.toolByGuid(guid, changeset, tools);
var selector = "#tool_tps_" + tool.clean;
$(selector).empty();
$(selector).append(this.options.tps_template_tool_create({ tool: tool }));
$(".select-tps-button").click(ev => {
var changeset = this.selectedChangeset();
var guid = ev.target.attributes.getNamedItem("data-toolguid");
this.showToolTPSSelect(guid, changeset);
});
this.bindEvents();
},
showToolTPSSelect: function(guid, changeset) {
var metadata = this.options.current_metadata;
var tools = metadata.tools;
var tool = toolshed_util.toolByGuid(guid, changeset, tools);
var selector = "#tool_tps_" + tool.clean;
$(selector).empty();
$(selector).append(
this.options.tps_template_tool_select({
tool: tool,
panel_section_dict: this.options.panel_section_dict,
panel_section_options: this.options.panel_section_options
})
);
$(".create-tps-button").click(ev => {
var changeset = this.selectedChangeset();
var guid = ev.target.attributes.getNamedItem("data-toolguid");
this.showToolTPSCreate(guid, changeset);
});
this.bindEvents();
},
propagateTPS: function() {
$("#tool_panel_section_select").change(() => {
var new_tps = $("#tool_panel_section_select")
.find("option:selected")
.val();
$('.tool_panel_section_picker[default="active"]').each(obj => {
obj.val(new_tps);
});
});
this.toolTPSSelectionEvents();
},
toolTPSSelectionEvents: function() {
$(".tool_panel_section_picker").on("change", ev => {
const element = $(ev.target);
var new_value = element.find("option:selected").val();
var default_tps = $("#tool_panel_section_select")
.find("option:selected")
.val();
if (new_value == default_tps) {
element.attr("default", "active");
} else {
element.removeAttr("default");
}
});
},
templateRepoDetails: function() {
return _.template(
`<div class="unified-panel-header" id="panel_header" unselectable="on">
<div class="unified-panel-header-inner">Repository information for&nbsp;<strong><%= repository.name %></strong>&nbsp;from&nbsp;<strong><%= repository.owner %></strong><a class="ml-auto" href="#/queue">Repository Queue (<%= queue %>)</a></div>
</div>
<div class="unified-panel-body" id="repository_details" data-tsrid="<%= repository.id %>">
<form id="repository_installation" name="install_repository" method="post" action="<%= api_url %>">
<input type="hidden" id="repositories" name="<%= repository.id %>" value="ID" />
<input type="hidden" id="tool_shed_url" name="tool_shed_url" value="<%= tool_shed %>" />
<div class="toolForm">
<div class="toolFormTitle">Changeset</div>
<div class="toolFormBody changeset">
<select id="changeset" name="changeset" style="margin: 5px;">
<% _.each(Object.keys(repository.metadata), function(changeset) { %>
<% if (changeset == current_changeset) { var selected = "selected "; } else { var selected = ""; } %>
<option <%= selected %>value="<%= changeset.split(":")[1] %>"><%= changeset %></option>
<% }); %>
</select>
<input class="btn btn-primary preview-button" data-tsrid="<%= current_metadata.repository.id %>" type="submit" id="install_repository" name="install_repository" value="Install this revision now" />
<input class="btn btn-primary preview-button" type="button" id="queue_install" name="queue_install" value="Install this revision later" />
<div class="toolParamHelp" style="clear: both;">Please select a revision and review the settings below before installing.</div>
</div>
</div>
<%= shed_tool_conf %>
<% if (current_metadata.has_repository_dependencies) { %>
<div class="toolFormTitle">Repository dependencies for <strong id="current_changeset"><%= current_changeset %></strong></div>
<div class="toolFormBody">
<p id="install_repository_dependencies_checkbox">
<input type="checkbox" checked id="install_repository_dependencies" />
<label for="install_repository_dependencies">Install repository dependencies</label>
</p>
<% current_metadata.repository_dependency_template = repository_dependency_template; %>
<div class="tables container-table" id="repository_dependencies">
<div class="expandLink">
<a class="toggle_folder" data_target="repository_dependencies_table">
Repository dependencies &ndash; <em>installation of these additional repositories is required</em>
</a>
</div>
<%= repository_dependencies_template(current_metadata) %>
</div>
</div>
<% } %>
<% if (current_metadata.includes_tool_dependencies) { %>
<div class="toolFormTitle">Tool dependencies</div>
<div class="toolFormBody">
<p id="install_resolver_dependencies_checkbox">
<input type="checkbox" checked id="install_resolver_dependencies" />
<label for="install_resolver_dependencies">Install resolver dependencies</label>
</p>
<p id="install_tool_dependencies_checkbox">
<input type="checkbox" checked id="install_tool_dependencies" />
<label for="install_tool_dependencies">Install tool dependencies</label>
</p>
<div class="tables container-table" id="tool_dependencies">
<div class="expandLink">
<a class="toggle_folder" data_target="tool_dependencies_table">
Tool dependencies &ndash; <em>repository tools require handling of these dependencies</em>
</a>
</div>
<table class="tables container-table" id="tool_dependencies_table" border="0" cellpadding="2" cellspacing="2" width="100%">
<thead>
<tr style="display: table-row;" class="datasetRow" parent="0" id="libraryItem-rt-f9cad7b01a472135">
<th style="padding-left: 40px;">Name</th>
<th>Version</th>
<th>Type</th>
</tr>
</thead>
<tbody id="tool_deps">
<% _.each(tool_dependencies[current_changeset], function(dependency) { %>
<tr class="datasetRow tool_dependency_row" style="display: table-row;">
<td style="padding-left: 40px;">
<%= dependency.name %></td>
<td><%= dependency.version %></td>
<td><%= dependency.type %></td>
</tr>
<% }); %>
</tbody>
</table>
</div>
</div>
<% } %>
<% if (current_metadata.includes_tools_for_display_in_tool_panel) { %>
<div class="toolFormTitle">Tools &ndash; <em>click the name to preview the tool and use the pop-up menu to inspect all metadata</em></div>
<div class="toolFormBody">
<div class="tables container-table" id="tools_toggle">
<table class="tables container-table" id="valid_tools" border="0" cellpadding="2" cellspacing="2" width="100%">
<thead>
<tr style="display: table-row;" class="datasetRow" parent="0" id="libraryItem-rt-f9cad7b01a472135">
<th style="padding-left: 40px;">Name</th>
<th>Description</th>
<th>Version</th>
<th><%= tps_template_global_select({panel_section_dict: panel_section_dict, panel_section_options: panel_section_options}) %></tr>
</thead>
<tbody id="tools_in_repo">
<% _.each(current_metadata.tools, function(tool) { %>
<tr id="libraryItem-<%= tool.clean %>" class="tool_row" style="display: table-row;" style="width: 15%">
<td style="padding-left: 40px;">
<div id="tool-<%= tool.clean %>" class="menubutton split popup" style="float: left;">
<a class="tool_form view-info" data-toggle="modal" data-target="toolform_<%= tool.clean %>" data-clean="<%= tool.clean %>" data-guid="<%= tool.guid %>" data-name="<%= tool.name %>" data-desc="<%= tool.description %>"><%= tool["name"] %></a>
</div>
</td>
<td><%= tool.description %></td>
<td style="width: 15%"><%= tool.version %></td>
<td style="width: 35%" id="tool_tps_<%= tool.clean %>">
<%= tps_template_tool_select({tool: tool, panel_section_dict: panel_section_dict, panel_section_options: panel_section_options}) %>
</td>
</tr>
<% }); %>
</tbody>
</table>
</div>
</div>
<% } %>
</form>
</div>`
);
},
templateRepoDependencies: function() {
return _.template(
`<div class="toolFormTitle">Repository Dependencies</div>
<div class="toolFormBody tables container-table" id="repository_dependencies">
<ul>
<li>Repository installation requires the following
<% if (has_repository_dependencies) { %>
<% _.each(repository_dependencies, function(dependency) { %>
<% dependency.repository_dependency_template = repository_dependency_template; %>
<%= repository_dependency_template(dependency) %>
<% }); %>
<% } %>
</li>
</ul>
</div>`
);
},
templateRepoDependency: function() {
return _.template(
`<li id="metadata_<%= id %>" class="datasetRow repository_dependency_row">
Repository <b><%= repository.name %></b> revision <b><%= changeset_revision %></b> owned by <b><%= repository.owner %></b>
<% if (has_repository_dependencies) { %>
<ul class="child_dependencies">
<% _.each(repository_dependencies, function(dependency) { %>
<% dependency.repository_dependency_template = repository_dependency_template; %>
<%= repository_dependency_template(dependency) %>
<% }); %>
</ul>
<% } %>
</li>`
);
},
templateShedToolConf: function() {
return _.template(
`<div class="toolFormTitle">Shed tool configuration file:</div>
<div class="toolFormBody">
<div class="form-row">
<select name="shed_tool_conf">
<% _.each(shed_tool_confs.options, function(conf) { %>
<option value="<%= conf.value %>"><%= conf.label %></option>
<% }); %>
</select>
<div class="toolParamHelp" style="clear: both;">Select the file whose <b>tool_path</b> setting you want used for installing repositories.</div>
</div>
</div>`
);
},
// templateToolDependency: function(){
// return _.template(
// `<% if (has_repository_dependencies) { %>
// <% _.each(repository_dependencies, function(dependency) { %>
// <% if (dependency.includes_tool_dependencies) { %>
// <% dependency.tool_dependency_template = tool_dependency_template %>
// <%= tool_dependency_template(dependency) %>
// <% } %>
// <% }); %>
// <% } %>`
// );
// },
templateGlobalSectionCreate: function() {
return _.template(
`<div id="tool_panel_section">
<div class="form-row" id="new_tps">
<input id="new_tool_panel_section" name="new_tool_panel_section" type="textfield" value="" size="40"/>
<input class="btn btn-primary global-select-tps-button" type="button" id="select_existing" value="Select existing" />
<div class="toolParamHelp" style="clear: both;">
Add a new tool panel section to contain the installed tools (optional).
</div>
</div>
</div>`
);
},
templateGlobalSectionSelect: function() {
return _.template(
`<div id="tool_panel_section">
<div class="toolFormTitle">Tool Panel Section</div>
<div class="toolFormBody">
<div class="tab-pane" id="select_tps">
<select name="<%= name %>" id="<%= panel_section_dict.id %>">
<%= panel_section_options({sections: panel_section_dict.sections}) %>
</select>
<input class="btn btn-primary global-create-tps-button" type="button" id="create_new" value="Create new" />
<div class="toolParamHelp" style="clear: both;">
Select an existing tool panel section to contain the installed tools (optional).
</div>
</div>
</div>
</div>`
);
},
templateToolSectionCreate: function() {
return _.template(
`<div id="new_tps_<%= tool.clean %>" data-clean="<%= tool.clean %>" class="form-row">
<input data-toolguid="<%= tool.guid %>" class="tool_panel_section_picker" size="40" name="new_tool_panel_section" id="new_tool_panel_section_<%= tool.clean %>" type="text">
<input id="per_tool_select_<%= tool.clean %>" class="btn btn-primary select-tps-button" data-toolguid="<%= tool.guid %>" value="Select existing" id="select_existing_<%= tool.clean %>" type="button">
</div>`
);
},
templateToolSectionSelect: function() {
return _.template(
`<div id="select_tps_<%= tool.clean %>" data-clean="<%= tool.clean %>" class="tps_creator">
<select default="active" style="width: 30em;" data-toolguid="<%= tool.guid %>" class="tool_panel_section_picker" name="tool_panel_section_id" id="tool_panel_section_select_<%= tool.clean %>">
<%= panel_section_options({sections: panel_section_dict.sections}) %>
</select>
<input id="per_tool_create_<%= tool.clean %>" data-clean="<%= tool.clean %>" class="btn btn-primary create-tps-button" data-toolguid="<%= tool.guid %>" value="Create new" id="create_new_<%= tool.clean %>" type="button">
<div style="clear: both;" class="toolParamHelp"></div>
</div>`
);
},
templatePanelSelectOptions: function() {
return _.template(
`<% _.each(sections, function(section) { %>
<option value="<%= section.id %>"><%= section.name %></option>
<% }); %>`
);
}
});
export default {
RepoDetails: ToolShedRepositoryView
};
@@ -1,53 +0,0 @@
import Backbone from "backbone";
import $ from "jquery";
import _ from "underscore";
import _l from "utils/localization";
import toolshed_model from "mvc/toolshed/toolshed-model";
import toolshed_util from "mvc/toolshed/util";
var ShedListView = Backbone.View.extend({
initialize: function(options) {
this.options = _.defaults(this.options || {}, this.defaults);
this.model = new toolshed_model.ShedsCollection();
this.listenTo(this.model, "sync", this.render);
this.model.fetch();
},
el: "#center",
render: function(options) {
this.options = _.defaults(this.options || {}, options, this.defaults);
var toolshed_list_template = this.templateToolshedList();
this.$el.html(
toolshed_list_template({
title: _l("Configured Galaxy Tool Sheds"),
tool_sheds: this.model.models,
queue: toolshed_util.queueLength()
})
);
$("#center").css("overflow", "auto");
},
templateToolshedList: function() {
return _.template(
`<div class='shed-style-container'>
<div class='header'>
<h2>
${_l("Configured Tool Sheds")}
</h2>
<span><a href='#/queue'>Repository Queue (<%= queue %>)</a></span>
<div style='clear:both;'></div>
</div'>
<% _.each(tool_sheds, function(shed) { %>
<div>
<a href='#/categories/s/<%= shed.get('url') %>'><%= shed.get('name') %></a>
</div>
<% }); %>
</div>`
);
}
});
export default {
ShedListView: ShedListView
};
@@ -1,106 +0,0 @@
import _ from "underscore";
import Backbone from "backbone";
import { getAppRoot } from "onload/loadConfig";
var ToolShedModel = Backbone.Model.extend({
defaults: {
url: "https://toolshed.g2.bx.psu.edu/",
name: "Galaxy Main Tool Shed"
},
urlRoot: `${getAppRoot()}api/tool_shed`
});
var ToolShedsCollection = Backbone.Collection.extend({
url: `${getAppRoot()}api/tool_shed`,
model: ToolShedModel
});
var ToolShedCategoriesModel = Backbone.Model.extend({
defaults: [{}],
urlRoot: `${getAppRoot()}api/tool_shed/contents`
});
var ToolShedCategoriesCollection = Backbone.Collection.extend({
url: `${getAppRoot()}api/tool_shed/contents`,
model: ToolShedCategoriesModel
});
var ToolShedCategoryModel = Backbone.Model.extend({
defaults: [{}],
urlRoot: `${getAppRoot()}api/tool_shed/category`
});
var ToolShedCategoryCollection = Backbone.Collection.extend({
url: `${getAppRoot()}api/tool_shed/category`,
model: ToolShedCategoryModel
});
var ToolShedRepositoryModel = Backbone.Model.extend({
defaults: [{}],
urlRoot: `${getAppRoot()}api/tool_shed/repository`
});
var ToolShedRepositoryCollection = Backbone.Collection.extend({
url: `${getAppRoot()}api/tool_shed/repository`,
model: ToolShedRepositoryModel
});
var RepoQueueModel = Backbone.Model.extend({
url: "#"
});
var RepoQueueCollection = Backbone.Collection.extend({
url: "#",
model: RepoQueueModel,
fetch: function() {
var repositories = Array();
var repositories_enc;
if (window.localStorage.hasOwnProperty("repositories")) {
repositories_enc = JSON.parse(window.localStorage.repositories);
} else {
repositories_enc = [];
}
var queue_keys = Object.keys(repositories_enc);
_.each(queue_keys, key => {
var repo = repositories_enc[key];
repo.queue_key = key;
repositories.push(repo);
});
this.reset(repositories);
return Backbone.Collection.prototype.fetch.call(this);
}
});
var RepoStatusModel = Backbone.Model.extend({
defaults: [{}],
urlRoot: `${getAppRoot()}api/tool_shed/status`
});
var RepoStatusCollection = Backbone.Collection.extend({
url: `${getAppRoot()}api/tool_shed/status`,
model: RepoStatusModel
});
var WorkflowToolsModel = Backbone.Model.extend({
defaults: [{}],
urlRoot: `${getAppRoot()}api/workflows?missing_tools=True`
});
var WorkflowToolsCollection = Backbone.Collection.extend({
url: `${getAppRoot()}api/workflows?missing_tools=True`,
model: WorkflowToolsModel
});
export default {
ShedModel: ToolShedModel,
ShedsCollection: ToolShedsCollection,
Category: ToolShedCategoriesModel,
Categories: ToolShedCategoriesCollection,
CategoryModel: ToolShedCategoryModel,
CategoryCollection: ToolShedCategoryCollection,
RepositoryModel: ToolShedRepositoryModel,
RepositoryCollection: ToolShedRepositoryCollection,
RepoQueue: RepoQueueCollection,
RepoStatus: RepoStatusCollection,
WorkflowTools: WorkflowToolsCollection
};
@@ -1,65 +0,0 @@
import $ from "jquery";
import { getAppRoot } from "onload/loadConfig";
var searchShed = function(request, response) {
var shed_url = this.shed_url;
var base_url = `${getAppRoot()}api/tool_shed/search`;
$.get(base_url, { term: request.term, tool_shed_url: shed_url }, data => {
var result_list = this.shedParser(data);
response(result_list);
});
};
var shedParser = jsondata => {
var results = [];
var hits = jsondata.hits;
$.each(hits, hit => {
var record = hits[hit];
var label = `${record.repository.name} by ${record.repository.repo_owner_username}: ${
record.repository.description
}`;
var result = { value: record.repository.id, label: label };
results.push(result);
});
return results;
};
var addToQueue = metadata => {
if (metadata.tool_shed_url.substr(-1) == "/") {
metadata.tool_shed_url = metadata.tool_shed_url.substr(0, metadata.tool_shed_url.length - 1);
}
var key = `${metadata.tool_shed_url}|${metadata.repository_id}|${metadata.changeset_revision}`;
var queued_repos = {};
if (window.localStorage.repositories) {
queued_repos = JSON.parse(window.localStorage.repositories);
}
queued_repos[key] = metadata;
window.localStorage.repositories = JSON.stringify(queued_repos);
};
var queueLength = () => {
if (window.localStorage.hasOwnProperty("repositories")) {
var repo_queue = JSON.parse(window.localStorage.repositories);
return Object.keys(repo_queue).length;
} else {
return 0;
}
};
var toolByGuid = function(guid, changeset, tools) {
var returned_tool;
tools.forEach(function(tool) {
if (tool.guid == guid.value) {
returned_tool = tool;
}
});
return returned_tool;
};
export default {
searchShed: searchShed,
shedParser: shedParser,
addToQueue: addToQueue,
queueLength: queueLength,
toolByGuid: toolByGuid
};
@@ -1,133 +0,0 @@
import _ from "underscore";
import $ from "jquery";
import Backbone from "backbone";
import { getAppRoot } from "onload/loadConfig";
import _l from "utils/localization";
import toolshed_model from "mvc/toolshed/toolshed-model";
import toolshed_util from "mvc/toolshed/util";
var View = Backbone.View.extend({
el: "#center",
defaults: [{}],
initialize: function(options) {
this.model = new toolshed_model.WorkflowTools();
this.listenTo(this.model, "sync", this.render);
this.model.fetch();
this.render();
},
render: function(options) {
var workflows_missing_tools = this.templateWorkflows();
var workflows = this.model.models;
this.$el.html(
workflows_missing_tools({
title: _l("Workflows Missing Tools"),
workflows: workflows,
queue: toolshed_util.queueLength()
})
);
$("#center").css("overflow", "auto");
this.bindEvents();
},
bindEvents: function() {
var repository_id;
$(".show_wf_repo").on("click", ev => {
var tool_ids = $(ev.target).attr("data-toolids");
var toolshed = $(ev.target).attr("data-shed");
var api_url = `${getAppRoot()}api/tool_shed/repository`;
var params = { tool_ids: tool_ids };
$.get(api_url, params, data => {
repository_id = data.repository.id;
var new_route = `repository/s/${toolshed.replace(/:/g, "%3a").replace(/\//g, "%2f")}/r/${
data.repository.id
}`;
Backbone.history.navigate(new_route, {
trigger: true,
replace: true
});
});
});
$(".queue_wf_repo").on("click", ev => {
var elem = $(ev.target);
var tool_ids = elem.attr("data-toolids");
var toolshed = elem.attr("data-shed");
var api_url = `${getAppRoot()}api/tool_shed/repository`;
var params = { tool_ids: tool_ids };
$.get(api_url, params, data => {
repository_id = data.repository.id;
params = {
tool_shed_url: toolshed,
repository_id: repository_id
};
$.get(api_url, params, data => {
var changesets = Object.keys(data.repository.metadata);
var current_changeset = changesets[0];
var current_metadata = data.repository.metadata[current_changeset];
current_metadata.tool_shed_url = toolshed;
toolshed_util.addToQueue(current_metadata);
elem.remove();
});
});
});
$("#from_workflow").on("click", this.loadWorkflows);
},
templateWorkflows: function() {
_.template(
`<div class="unified-panel-header" id="panel_header" unselectable="on">
<div class="unified-panel-header-inner"><%= title %><a class="ml-auto" href="#/queue">Repository Queue (<%= queue %>)</a></div>
</div>
<style type="text/css">
.workflow_names, .workflow_tools { list-style-type: none; } ul.workflow_tools, ul.workflow_names { padding-left: 0px; }
</style>
<table id="workflows_missing_tools" class="grid" border="0" cellpadding="2" cellspacing="2" width="100%">
<thead id="grid-table-header">
<tr>
<th class="datasetRow">Workflows</th>
<th class="datasetRow">Tool IDs</th>
<th class="datasetRow">Shed</th>
<th class="datasetRow">Name</th>
<th class="datasetRow">Owner</th>
<th class="datasetRow">Actions</th>
</tr>
</thead>
<tbody>
<% _.each(workflows, function(workflow) { %>
<tr>
<td class="datasetRow">
<ul class="workflow_names">
<% _.each(workflow.get("workflows"), function(name) { %>
<li class="workflow_names"><%= name %></li>
<% }); %>
</ul>
</td>
<td class="datasetRow">
<ul class="workflow_tools">
<% _.each(workflow.get("tools"), function(tool) { %>
<li class="workflow_tools"><%= tool %></li>
<% }); %>
</ul>
</td>
<td class="datasetRow"><%= workflow.get("shed") %></td>
<td class="datasetRow"><%= workflow.get("repository") %></td>
<td class="datasetRow"><%= workflow.get("owner") %></td>
<td class="datasetRow">
<ul class="workflow_tools">
<li class="workflow_tools">
<input type="button" class="show_wf_repo btn btn-primary" data-shed="<%= workflow.get("shed") %>" data-owner="<%= workflow.get("owner") %>" data-repo="<%= workflow.get("repository") %>" data-toolids="<%= workflow.get("tools").join(",") %>" value="Show Repository" /></li>
</ul>
</td>
</tr>
<% }); %>
</ul>
</div>`
);
}
});
export default {
Workflows: View
};
+3 -1
View File
@@ -183,7 +183,9 @@ class UniverseApplication(config.ConfiguresGalaxyMixin):
if self.config.enable_oidc:
from galaxy.authnz import managers
self.authnz_manager = managers.AuthnzManager(self, self.config.oidc_config, self.config.oidc_backends_config)
self.authnz_manager = managers.AuthnzManager(self,
self.config.oidc_config,
self.config.oidc_backends_config)
self.sentry_client = None
if self.config.sentry_dsn:
+5 -1
View File
@@ -304,10 +304,14 @@ class AuthnzManager(object):
ca = CloudAuthz()
log.info("Requesting credentials using CloudAuthz with config id `{}` on be half of user `{}`.".format(
cloudauthz.id, user_id))
return ca.authorize(cloudauthz.provider, config)
credentials = ca.authorize(cloudauthz.provider, config)
return credentials
except CloudAuthzBaseException as e:
log.info(e)
raise exceptions.AuthenticationFailed(e)
except NotImplementedError as e:
log.info(e)
raise exceptions.RequestParameterInvalidException(e)
def get_cloud_access_credentials_in_file(self, new_file_path, cloudauthz, sa_session, user_id, request=None):
"""
@@ -68,7 +68,7 @@ bioblend = "*"
boto = "*"
kombu = "*"
psutil = "*"
pulsar-galaxy-lib = "*"
pulsar-galaxy-lib = "==0.12.1"
sqlalchemy-migrate = "*"
sqlparse = "*"
svgwrite = "*"
@@ -77,7 +77,7 @@ pyparsing = "*"
paramiko = "*"
python-genomespaceclient = "<2.0"
social_auth_core = {version = "==3.1.0+gx0", extras = ['openidconnect']}
cloudauthz = "<=0.4.0"
cloudauthz = "==0.6.0"
gxformat2 = "*"
[requires]
@@ -38,11 +38,11 @@ pygithub3==0.5.1 ; python_version < '3'
pygments==2.4.2
pyparsing==2.4.0
pytest-cov==2.7.1
pytest-html==1.20.0
pytest-html==1.21.1
pytest-metadata==1.8.0
pytest-postgresql==1.4.1
pytest-pythonpath==0.7.3
pytest==4.6.3
pytest==4.6.4
pytz==2019.1
pyyaml==5.1.1
recommonmark==0.5.0
@@ -50,14 +50,14 @@ requests==2.22.0
scandir==1.10.0 ; python_version < '3.5'
selenium==3.141.0
six==1.11.0
snowballstemmer==1.2.1
snowballstemmer==1.9.0
sphinx-markdown-tables==0.0.9
sphinx-rtd-theme==0.4.3
sphinx==1.8.5
sphinxcontrib-websupport==1.1.2
testfixtures==6.9.0
testfixtures==6.10.0
twill==0.9.1 ; python_version < '3'
typing==3.6.6 ; python_version < '3.5'
typing==3.7.4 ; python_version < '3.5'
urllib3==1.25.3 ; python_version == '2.7'
watchdog==0.9.0
wcwidth==0.1.7 ; sys_platform != 'win32'
@@ -21,7 +21,7 @@ azure-storage-common==1.4.2
azure-storage-nspkg==3.1.0
babel==2.7.0
bagit==1.6.4
bcrypt==3.1.6
bcrypt==3.1.7
bdbag==1.4.1
beaker==1.10.1
bioblend==0.12.0
@@ -29,8 +29,8 @@ bleach==3.1.0
boltons==19.1.0
boto3==1.9.114
boto==2.49.0
botocore==1.12.169
bx-python==0.8.2
botocore==1.12.180
bx-python==0.8.4
bz2file==0.98 ; python_version < '3.3'
cachecontrol==0.11.7
cachetools==3.1.1
@@ -39,7 +39,7 @@ cffi==1.12.3
chardet==3.0.4
cheetah3==3.2.3
cliff==2.15.0
cloudauthz==0.4.0
cloudauthz==0.6.0
cloudbridge==2.0.0
cmd2==0.8.9
contextlib2==0.5.5 ; python_version < '3.5'
@@ -64,7 +64,7 @@ galaxy-sequence-utils==1.1.3
google-api-python-client==1.7.8
google-auth-httplib2==0.0.3
google-auth==1.6.3
gxformat2==0.8.3
gxformat2==0.8.4
h5py==2.9.0
httplib2==0.13.0
idna==2.8
@@ -101,7 +101,7 @@ oauthlib==3.0.1
openstacksdk==0.17.0
os-client-config==1.32.0
os-service-types==1.7.0
osc-lib==1.12.1
osc-lib==1.13.0
oslo.config==6.10.0
oslo.context==2.22.1
oslo.i18n==3.23.1
@@ -109,13 +109,13 @@ oslo.log==3.44.0
oslo.serialization==2.29.1
oslo.utils==3.41.0
packaging==19.0
paramiko==2.5.0
paramiko==2.6.0
parsley==1.3
paste==3.0.8
pastedeploy==2.0.1
pastescript==3.1.0
pathlib2==2.3.2 ; python_version < '3'
pbr==5.3.0
pbr==5.3.1
prettytable==0.7.2
prov==1.5.1
psutil==5.6.3
@@ -168,15 +168,15 @@ six==1.11.0
social-auth-core[openidconnect]==3.1.0+gx0
sqlalchemy-migrate==0.12.0
sqlalchemy-utils==0.34.0
sqlalchemy==1.3.4
sqlalchemy==1.3.5
sqlparse==0.3.0
stevedore==1.30.1
subprocess32==3.5.4 ; python_version < '3.0'
svgwrite==1.2.1
svgwrite==1.3.1
tempita==0.5.2
tenacity==4.12.0
typing-extensions==3.7.2
typing==3.6.6 ; python_version < '3.5'
typing-extensions==3.7.4
typing==3.7.4 ; python_version < '3.5'
tzlocal==1.5.1
unicodecsv==0.14.1 ; python_version < '3.0'
uritemplate==3.0.0
@@ -188,4 +188,4 @@ wcwidth==0.1.7 ; sys_platform != 'win32'
webencodings==0.5.1
webob==1.8.5
whoosh==2.7.4
wrapt==1.11.1
wrapt==1.11.2
@@ -8,4 +8,4 @@ functools32==3.2.3.post2 ; python_version < '3.2'
mccabe==0.6.1
pycodestyle==2.5.0
pyflakes==2.1.1
typing==3.6.6 ; python_version < '3.5'
typing==3.7.4 ; python_version < '3.5'
+5 -2
View File
@@ -147,6 +147,9 @@ class CloudManager(sharable.SharableModelManager):
'os_project_domain_name': prj_domain_name,
'os_user_domain_name': user_domain_name}
connection = CloudProviderFactory().create_provider(ProviderList.OPENSTACK, config)
elif provider == "gcp":
config = {"gcp_service_creds_dict": credentials}
connection = CloudProviderFactory().create_provider(ProviderList.GCP, config)
else:
raise RequestParameterInvalidException("Unrecognized provider '{}'; the following are the supported "
"providers: {}.".format(provider, SUPPORTED_PROVIDERS.keys()))
@@ -340,8 +343,8 @@ class CloudManager(sharable.SharableModelManager):
try:
object_label = hda.name.replace(" ", "_")
args = {
# We encode ID here because it the tool wrapper assumes
# it receives an encoded ID and attempts decoding it.
# We encode ID here because the tool wrapper expects
# an encoded ID and attempts decoding it.
"authz_id": trans.security.encode_id(cloudauthz.id),
"bucket": bucket_name,
"object_label": object_label,
+18 -2
View File
@@ -78,6 +78,23 @@ class FolderManager(object):
folder = self.check_accessible(trans, folder)
return folder
def check_modifyable(self, trans, folder):
"""
Check whether the user can modify the folder (name and description).
:returns: the original folder
:rtype: LibraryFolder
:raises: AuthenticationRequired, InsufficientPermissionsException
"""
if not trans.user:
raise AuthenticationRequired("Must be logged in to manage Galaxy items.", type='error')
current_user_roles = trans.get_current_user_roles()
if not trans.app.security_agent.can_modify_library_item(current_user_roles, folder):
raise InsufficientPermissionsException("You don't have permissions to modify this folder.", type='error')
else:
return folder
def check_manageable(self, trans, folder):
"""
Check whether the user can manage the folder.
@@ -171,8 +188,7 @@ class FolderManager(object):
"""
changed = False
if not trans.user_is_admin:
if not self.check_manageable(trans, folder):
raise InsufficientPermissionsException("You do not have proper permission to update the library folder.")
folder = self.check_modifyable(trans, folder)
if folder.deleted is True:
raise ItemAccessibilityException("You cannot update a deleted library folder. Undelete it first.")
if name is not None and name != folder.name:
@@ -159,18 +159,6 @@ class AdminToolshed(AdminGalaxy):
message=message,
status=status)
@web.expose
@web.require_admin
def browse_toolsheds(self, trans, **kwd):
app = {
'jscript': "adminToolshed"
}
return trans.fill_template('galaxy.panels.mako',
config={
'title': 'Galaxy Tool Sheds',
'app': app,
'bundle': 'extended'})
@web.expose
@web.require_admin
def check_for_updates(self, trans, **kwd):