Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Webhooks improvements #5164

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 4 additions & 4 deletions client/galaxy/scripts/layout/menu.js
Expand Up @@ -105,11 +105,11 @@ var Collection = Backbone.Collection.extend({
//
// Webhooks
//
Webhooks.add({
url: "api/webhooks/masthead/all",
callback: function(webhooks) {
Webhooks.load({
type: "masthead",
callback: function (webhooks) {
$(document).ready(() => {
$.each(webhooks.models, (index, model) => {
webhooks.each(model => {
var webhook = model.toJSON();
if (webhook.activate) {
var obj = {
Expand Down
8 changes: 4 additions & 4 deletions client/galaxy/scripts/mvc/history/options-menu.js
Expand Up @@ -175,13 +175,13 @@ var menu = [
];

// Webhooks
Webhooks.add({
url: "api/webhooks/history-menu/all",
async: false, // (hypothetically) slows down the performance
Webhooks.load({
type: "history-menu",
async: false, // (hypothetically) slows down the performance
callback: function(webhooks) {
var webhooks_menu = [];

$.each(webhooks.models, (index, model) => {
webhooks.each((model) => {
var webhook = model.toJSON();
if (webhook.activate) {
webhooks_menu.push({
Expand Down
31 changes: 18 additions & 13 deletions client/galaxy/scripts/mvc/tool/tool-form-base.js
Expand Up @@ -5,6 +5,7 @@ import Utils from "utils/utils";
import Deferred from "utils/deferred";
import Ui from "mvc/ui/ui-misc";
import FormBase from "mvc/form/form-view";
import Webhooks from "mvc/webhooks";
import Citations from "components/Citations.vue";
import Vue from "libs/vue";
export default FormBase.extend({
Expand Down Expand Up @@ -199,19 +200,23 @@ export default FormBase.extend({
}

// add tool menu webhooks
$.getJSON("/api/webhooks/tool-menu/all", webhooks => {
_.each(webhooks, webhook => {
if (webhook.activate && webhook.config.function) {
menu_button.addMenu({
icon: webhook.config.icon,
title: webhook.config.title,
onclick: function() {
var func = new Function("options", webhook.config.function);
func(options);
}
});
}
});
Webhooks.load({
type: "tool-menu",
callback: function(webhooks) {
webhooks.each((model) => {
var webhook = model.toJSON();
if (webhook.activate && webhook.config.function) {
menu_button.addMenu({
icon: webhook.config.icon,
title: webhook.config.title,
onclick: function() {
var func = new Function("options", webhook.config.function);
func(options);
}
});
}
});
}
});

return {
Expand Down
2 changes: 1 addition & 1 deletion client/galaxy/scripts/mvc/tool/tool-form-composite.js
Expand Up @@ -560,7 +560,7 @@ var View = Backbone.View.extend({
if ($.isArray(response) && response.length > 0) {
self.$el.append($("<div/>", { id: "webhook-view" }));
var WebhookApp = new Webhooks.WebhookView({
urlRoot: `${Galaxy.root}api/webhooks/workflow`,
type: "workflow",
toolId: job_def.tool_id,
toolVersion: job_def.tool_version
});
Expand Down
2 changes: 1 addition & 1 deletion client/galaxy/scripts/mvc/tool/tool-form.js
Expand Up @@ -196,7 +196,7 @@ var View = Backbone.View.extend({
if (response.jobs && response.jobs.length > 0) {
self.$el.append($("<div/>", { id: "webhook-view" }));
var WebhookApp = new Webhooks.WebhookView({
urlRoot: `${Galaxy.root}api/webhooks/tool`,
type: "tool",
toolId: job_def.tool_id
});
}
Expand Down
112 changes: 61 additions & 51 deletions client/galaxy/scripts/mvc/webhooks.js
@@ -1,66 +1,76 @@
/**
Webhooks
**/
import Utils from 'utils/utils';

var WebhookModel = Backbone.Model.extend({
defaults: {
activate: false
}
});

var Webhooks = Backbone.Collection.extend({
model: WebhookModel
const Webhooks = Backbone.Collection.extend({
url: `${Galaxy.root}api/webhooks`
});

var WebhookView = Backbone.View.extend({
el: "#webhook-view",
const WebhookView = Backbone.View.extend({
el: '#webhook-view',

initialize: function(options) {
var me = this;
var toolId = options.toolId || "";
var toolVersion = options.toolVersion || "";
initialize: function (options) {
const toolId = options.toolId || '';
const toolVersion = options.toolVersion || '';

this.$el.attr("tool_id", toolId);
this.$el.attr("tool_version", toolVersion);
this.$el.attr('tool_id', toolId);
this.$el.attr('tool_version', toolVersion);

this.model = new WebhookModel();
this.model.urlRoot = options.urlRoot;
this.model.fetch({
success: function() {
me.render();
}
});
},
const webhooks = new Webhooks();
webhooks.fetch({
success: data => {
data.reset(filterType(data, options.type));

render: function() {
var webhook = this.model.toJSON();
if (data.length > 0) {
this.render(weightedRandomPick(data));
}
}
});
},

this.$el.html(`<div id="${webhook.name}"></div>`);
if (webhook.styles)
$("<style/>", { type: "text/css" })
.text(webhook.styles)
.appendTo("head");
if (webhook.script)
$("<script/>", { type: "text/javascript" })
.text(webhook.script)
.appendTo("head");
render: function (model) {
const webhook = model.toJSON();
this.$el.html(`<div id="${webhook.id}"></div>`);
Utils.appendScriptStyle(webhook);
return this;
}
});

return this;
const load = options => {
const webhooks = new Webhooks();
webhooks.fetch({
async: options.async !== undefined ? options.async : true,
success: data => {
if (options.type) {
data.reset(filterType(data, options.type));
}
options.callback(data);
}
});
});
};

var add = options => {
var webhooks = new Webhooks();
function filterType (data, type) {
return data.models.filter(item => item.get('type').indexOf(type) !== -1);
}

webhooks.url = Galaxy.root + options.url;
webhooks.fetch({
async: options.async ? options.async : true,
success: options.callback
});
};
function weightedRandomPick (data) {
const weights = data.pluck('weight');
const sum = weights.reduce((a, b) => a + b);

const normalizedWeightsMap = new Map();
weights.forEach((weight, index) => {
normalizedWeightsMap.set(index, parseFloat((weight / sum).toFixed(2)));
});

const table = [];
for (const [index, weight] of normalizedWeightsMap) {
for (let i = 0; i < weight * 100; i++) {
table.push(index);
}
}

return data.at(table[Math.floor(Math.random() * table.length)]);
}

export default {
Webhooks: Webhooks,
WebhookView: WebhookView,
add: add
WebhookView: WebhookView,
load: load
};
23 changes: 12 additions & 11 deletions client/galaxy/scripts/onload.js
Expand Up @@ -25,6 +25,8 @@ window.make_popup_menus = POPUPMENU.make_popup_menus;
import init_tag_click_function from "ui/autocom_tagging";
window.init_tag_click_function = init_tag_click_function;
import TOURS from "mvc/tours";
import Webhooks from "mvc/webhooks";
import Utils from "utils/utils";
import QUERY_STRING from "utils/query-string-parsing";
// console.debug( 'galaxy globals loaded' );

Expand Down Expand Up @@ -206,17 +208,16 @@ $(document).ready(() => {
function onloadWebhooks() {
if (Galaxy.root !== undefined) {
// Load all webhooks with the type 'onload'
$.getJSON(`${Galaxy.root}api/webhooks/onload/all`, webhooks => {
_.each(webhooks, webhook => {
if (webhook.activate && webhook.script) {
$("<script/>", { type: "text/javascript" })
.text(webhook.script)
.appendTo("head");
$("<style/>", { type: "text/css" })
.text(webhook.styles)
.appendTo("head");
}
});
Webhooks.load({
type: "onload",
callback: function (webhooks) {
webhooks.each(model => {
var webhook = model.toJSON();
if (webhook.activate && webhook.script) {
Utils.appendScriptStyle(webhook);
}
});
}
});
} else {
setTimeout(onloadWebhooks, 100);
Expand Down
@@ -1,4 +1,4 @@
name: searchover
id: searchover
type:
- masthead
activate: true
Expand Down
Expand Up @@ -38,7 +38,7 @@ $(document).ready(function() {
e.stopPropagation();
if ( $( '.search-screen-overlay' ).is( ':visible' ) ){
self.removeOverlay();
}
}
else {
self.clearSearchResults();
self.showOverlay();
Expand Down
@@ -1,4 +1,4 @@
name: tool_list
id: tool_list
type:
- masthead
activate: true
Expand All @@ -13,7 +13,7 @@ function: >
'be patient, this might take a moment.');
}, 1);

$.getJSON(Galaxy.root + "api/webhooks/tool_list/get_data", function(data) {
$.getJSON(Galaxy.root + "api/webhooks/tool_list/data", function(data) {
var popup = window.open('tool_list.html');
var html = '<!DOCTYPE html><body><h2>' +
'Create a Docker flavour of this instance:</h2>' +
Expand Down
@@ -1,4 +1,4 @@
name: tour_generator
id: tour_generator
type:
- onload
- tool-menu
Expand Down
Expand Up @@ -10,7 +10,7 @@ $(document).ready(function() {
$('#execute').attr('tour_id', 'execute');

Toastr.info('Tour generation might take some time.');
$.getJSON('/api/webhooks/tour_generator/get_data/', {
$.getJSON('/api/webhooks/tour_generator/data/', {
tool_id: me.toolId,
tool_version: me.toolVersion
}, function(obj) {
Expand Down
47 changes: 9 additions & 38 deletions lib/galaxy/webapps/galaxy/api/webhooks.py
Expand Up @@ -3,7 +3,6 @@
"""
import imp
import logging
import random

from galaxy.web import _future_expose_api_anonymous_and_sessionless as \
expose_api_anonymous_and_sessionless
Expand All @@ -17,7 +16,7 @@ def __init__(self, app):
super(WebhooksController, self).__init__(app)

@expose_api_anonymous_and_sessionless
def get_all(self, trans, **kwd):
def all_webhooks(self, trans, **kwd):
"""
*GET /api/webhooks/
Returns all webhooks
Expand All @@ -28,50 +27,22 @@ def get_all(self, trans, **kwd):
]

@expose_api_anonymous_and_sessionless
def get_random(self, trans, webhook_type, **kwd):
def webhook_data(self, trans, webhook_id, **kwd):
"""
*GET /api/webhooks/{webhook_type}
Returns a random webhook for a given type
"""
webhooks = [
webhook
for webhook in self.app.webhooks_registry.webhooks
if webhook_type in webhook.type and
webhook.activate is True
]
return random.choice(webhooks).to_dict() if webhooks else {}

@expose_api_anonymous_and_sessionless
def get_all_by_type(self, trans, webhook_type, **kwd):
"""
*GET /api/webhooks/{webhook_type}/all
Returns all webhooks for a given type
"""
return [
webhook.to_dict()
for webhook in self.app.webhooks_registry.webhooks
if webhook_type in webhook.type
]

@expose_api_anonymous_and_sessionless
def get_data(self, trans, webhook_name, **kwd):
"""
*GET /api/webhooks/{webhook_name}/get_data/{params}
*GET /api/webhooks/{webhook_id}/data/{params}
Returns the result of executing helper function
"""
params = {}

for key, value in kwd.items():
params[key] = value

webhook = [
webhook = (
webhook
for webhook in self.app.webhooks_registry.webhooks
if webhook.name == webhook_name
]
if webhook.id == webhook_id
).next()

return imp.load_source('helper', webhook[0].helper).main(
trans,
webhook[0],
params,
) if webhook and webhook[0].helper != '' else {}
return imp.load_source(webhook.path, webhook.helper).main(
trans, webhook, params,
) if webhook and webhook.helper != '' else {}