From 0549a4fec7c8128b0bcb67639ca9baa2ce2d2322 Mon Sep 17 00:00:00 2001 From: Marcel Klehr Date: Sat, 26 Jan 2013 22:13:28 +0100 Subject: [PATCH 1/2] Add checkUpdates endpoinnt for /admin/plugins --- src/node/hooks/express/adminplugins.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/node/hooks/express/adminplugins.js b/src/node/hooks/express/adminplugins.js index 97a0d602f..7e221cf1e 100644 --- a/src/node/hooks/express/adminplugins.js +++ b/src/node/hooks/express/adminplugins.js @@ -2,6 +2,9 @@ var path = require('path'); var eejs = require('ep_etherpad-lite/node/eejs'); var installer = require('ep_etherpad-lite/static/js/pluginfw/installer'); var plugins = require('ep_etherpad-lite/static/js/pluginfw/plugins'); +var _ = require('underscore'); +var semver = require('semver'); +var async = require('async'); exports.expressCreateServer = function (hook_name, args, cb) { args.app.get('/admin/plugins', function(req, res) { @@ -25,8 +28,26 @@ exports.socketio = function (hook_name, args, cb) { if (!socket.handshake.session.user || !socket.handshake.session.user.is_admin) return; socket.on("load", function (query) { + // send currently installed plugins socket.emit("installed-results", {results: plugins.plugins}); + socket.emit("progress", {progress:1}); }); + + socket.on("checkUpdates", function() { + socket.emit("progress", {progress:0, message:'Checking for plugin updates...'}); + // Check plugins for updates + installer.search({offset: 0, pattern: '', limit: 500}, /*useCache:*/true, function(data) { // hacky + if (!data.results) return; + var updatable = _(plugins.plugins).keys().filter(function(plugin) { + if(!data.results[plugin]) return false; + var latestVersion = data.results[plugin]['dist-tags'].latest + var currentVersion = plugins.plugins[plugin].package.version + return semver.gt(latestVersion, currentVersion) + }); + socket.emit("updatable", {updatable: updatable}); + socket.emit("progress", {progress:1}); + }); + }) socket.on("search", function (query) { socket.emit("progress", {progress:0, message:'Fetching results...'}); From 541aeb3a984ef3d884dfb6aeb4f6a41740bc63c1 Mon Sep 17 00:00:00 2001 From: Marcel Klehr Date: Sat, 26 Jan 2013 22:15:19 +0100 Subject: [PATCH 2/2] /admin/plugins: Display an update button for all plugins that are outdated --- src/static/css/admin.css | 2 +- src/static/js/admin/plugins.js | 43 ++++++++++++++++++++++++++-------- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/static/css/admin.css b/src/static/css/admin.css index 0d9471268..0edf4bcd6 100644 --- a/src/static/css/admin.css +++ b/src/static/css/admin.css @@ -82,7 +82,7 @@ input[type="button"] { padding: 4px 6px; margin: 0; } -input[type="button"].do-install, input[type="button"].do-uninstall { +table input[type="button"] { float: right; width: 100px; } diff --git a/src/static/js/admin/plugins.js b/src/static/js/admin/plugins.js index ed38fc4e7..a973875ce 100644 --- a/src/static/js/admin/plugins.js +++ b/src/static/js/admin/plugins.js @@ -22,6 +22,7 @@ $(document).ready(function () { var search = function () { socket.emit("search", $('.search-results').data('query')); + tasks++; } function updateHandlers() { @@ -40,16 +41,18 @@ $(document).ready(function () { search(); }); - $(".do-install").unbind('click').click(function (e) { + $(".do-install, .do-update").unbind('click').click(function (e) { var row = $(e.target).closest("tr"); doUpdate = true; socket.emit("install", row.find(".name").text()); + tasks++; }); $(".do-uninstall").unbind('click').click(function (e) { var row = $(e.target).closest("tr"); doUpdate = true; socket.emit("uninstall", row.find(".name").text()); + tasks++; }); $(".do-prev-page").unbind('click').click(function (e) { @@ -72,11 +75,9 @@ $(document).ready(function () { updateHandlers(); + var tasks = 0; socket.on('progress', function (data) { - if (data.progress > 0 && $('#progress').data('progress') > data.progress) return; - $("#progress").show(); - $('#progress').data('progress', data.progress); var message = "Unknown status"; @@ -90,7 +91,12 @@ $(document).ready(function () { $("#progress .message").html(message); if (data.progress >= 1) { - $("#progress").hide(); + tasks--; + if (tasks <= 0) { + // Hide the activity indicator once all tasks are done + $("#progress").hide(); + tasks = 0; + } if (data.error) { alert('An error occurred: '+data.error+' -- the server log might know more...'); @@ -98,6 +104,7 @@ $(document).ready(function () { if (doUpdate) { doUpdate = false; socket.emit("load"); + tasks++; } } } @@ -121,9 +128,7 @@ $(document).ready(function () { for (plugin_name in data.results) { var plugin = data.results[plugin_name]; var row = widget.find(".template tr").clone(); - var version = '0.0.0'; - // hack to access "versions" property of the npm package object - for (version in data.results[plugin_name].versions) break; + for (attr in plugin) { if(attr == "name"){ // Hack to rewrite URLS into name row.find(".name").html(""+plugin[attr]+""); @@ -131,7 +136,7 @@ $(document).ready(function () { row.find("." + attr).html(plugin[attr]); } } - row.find(".version").html(version); + row.find(".version").html( data.results[plugin_name]['dist-tags'].latest ); widget.find(".results").append(row); } @@ -141,6 +146,7 @@ $(document).ready(function () { socket.on('installed-results', function (data) { $("#installed-plugins *").remove(); + for (plugin_name in data.results) { if (plugin_name == "ep_etherpad-lite") continue; // Hack... var plugin = data.results[plugin_name]; @@ -156,9 +162,26 @@ $(document).ready(function () { $("#installed-plugins").append(row); } updateHandlers(); + + socket.emit('checkUpdates'); + tasks++; }); + + socket.on('updatable', function(data) { + $('#installed-plugins>tr').each(function(i,tr) { + var pluginName = $(tr).find('.name').text() + + if (data.updatable.indexOf(pluginName) >= 0) { + var actions = $(tr).find('.actions') + actions.append('') + actions.css('width', 200) + } + }) + updateHandlers(); + }) socket.emit("load"); + tasks++; + search(); - });