diff options
-rw-r--r-- | src/ep.json | 4 | ||||
-rw-r--r-- | src/node/hooks/express/adminplugins.js | 34 | ||||
-rw-r--r-- | src/static/js/pluginfw/installer.js | 45 | ||||
-rw-r--r-- | src/templates/admin/plugins.html | 86 |
4 files changed, 167 insertions, 2 deletions
diff --git a/src/ep.json b/src/ep.json index 59cbf3aa..a4242890 100644 --- a/src/ep.json +++ b/src/ep.json @@ -8,7 +8,7 @@ { "name": "apicalls", "hooks": { "expressCreateServer": "ep_etherpad-lite/node/hooks/express/apicalls:expressCreateServer" } }, { "name": "importexport", "hooks": { "expressCreateServer": "ep_etherpad-lite/node/hooks/express/importexport:expressCreateServer" } }, { "name": "errorhandling", "hooks": { "expressCreateServer": "ep_etherpad-lite/node/hooks/express/errorhandling:expressCreateServer" } }, - { "name": "socketio", "hooks": { "expressCreateServer": "ep_etherpad-lite/node/hooks/express/socketio:expressCreateServer" } } - + { "name": "socketio", "hooks": { "expressCreateServer": "ep_etherpad-lite/node/hooks/express/socketio:expressCreateServer" } }, + { "name": "adminplugins", "hooks": { "expressCreateServer": "ep_etherpad-lite/node/hooks/express/adminplugins:expressCreateServer" } } ] } diff --git a/src/node/hooks/express/adminplugins.js b/src/node/hooks/express/adminplugins.js new file mode 100644 index 00000000..a3fbc2af --- /dev/null +++ b/src/node/hooks/express/adminplugins.js @@ -0,0 +1,34 @@ +var path = require('path'); +var eejs = require('ep_etherpad-lite/node/eejs'); +var installer = require('ep_etherpad-lite/static/js/pluginfw/installer'); + +exports.expressCreateServer = function (hook_name, args, cb) { + args.app.get('/admin/plugins', function(req, res) { + var plugins = require("ep_etherpad-lite/static/js/pluginfw/plugins"); + var render_args = { + plugins: plugins.plugins, + query: req.query, + search_results: {}, + errors: [], + }; + + var render = function () { + res.send(eejs.require( + "ep_etherpad-lite/templates/admin/plugins.html", + render_args), {}); + }; + + if (req.query.search && req.query.search != "") { + installer.search(req.query.search, function (er, data) { + if (er) { + render_args.errors.push(er); + return render(); + } + render_args.search_results = data; + render(); + }); + } else { + render(); + } + }); +}
\ No newline at end of file diff --git a/src/static/js/pluginfw/installer.js b/src/static/js/pluginfw/installer.js new file mode 100644 index 00000000..3ba7f458 --- /dev/null +++ b/src/static/js/pluginfw/installer.js @@ -0,0 +1,45 @@ +var plugins = require("ep_etherpad-lite/static/js/pluginfw/plugins"); +var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks"); +var npm = require("npm"); +var registry = require("npm/lib/utils/npm-registry-client/index.js"); + +exports.uninstall = function(plugin_name, cb) { + npm.load({}, function (er) { + if (er) return cb(er) + npm.commands.uninstall([plugin_name], function (er) { + if (er) return cb(er); + hooks.aCallAll("pluginUninstall", {plugin_name: plugin_name}, function (er) { + cb(er); + }); + }) + }) +} + +exports.install = function(plugin_name, cb) { + npm.load({}, function (er) { + if (er) return cb(er) + npm.commands.install([plugin_name], function (er) { + if (er) return cb(er); + hooks.aCallAll("pluginInstall", {plugin_name: plugin_name}, function (er) { + cb(er); + }); + }); + }) +} + +exports.search = function(pattern, cb) { + npm.load({}, function (er) { + registry.get( + "/-/all", null, 600, false, true, + function (er, data) { + if (er) return cb(er); + var res = {}; + for (key in data) { + if (/*key.indexOf(plugins.prefix) == 0 &&*/ key.indexOf(pattern) != -1) + res[key] = data[key]; + } + cb(null, res); + } + ); + }); +} diff --git a/src/templates/admin/plugins.html b/src/templates/admin/plugins.html new file mode 100644 index 00000000..2b40d33c --- /dev/null +++ b/src/templates/admin/plugins.html @@ -0,0 +1,86 @@ +<html> + <head> + <title>Plugin manager</title> + <style> + table { + border-collapse: collapse; + } + td, th { + border: 1px solid black; + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + padding-bottom: 2px; + } + </style> + </head> + <body> + <% if (errors.length) { %> + <div class="errors"> + <% errors.forEach(function (item) { %> + <div class="error"><%= item.toString() %></div> + <% }) %> + </div> + <% } %> + + + <h1>Installed plugins</h1> + <table> + <thead> + <tr> + <th>Name</th> + <th>Description</th> + <td></td> + </tr> + </thead> + <tbody> + <% for (var plugin_name in plugins) { %> + <% var plugin = plugins[plugin_name]; %> + <tr> + <td><%= plugin.package.name %></td> + <td><%= plugin.package.description %></td> + <td> + <form method="post"> + <input type="hidden" name="uninstall_plugin" value="<%= plugin.package.name %>"> + <input type="submit" value="U"> + </form> + </td> + </tr> + <% } %> + </tbody> + </table> + + + + <h1>Search for plugins to install</h1> + <form> + <input type="text" name="search" value="<%= query.search %>"><input type="submit"> + </form> + <table> + <thead> + <tr> + <th>Name</th> + <th>Description</th> + <td></td> + </tr> + </thead> + <tbody> + <% for (var plugin_name in search_results) { %> + <% var plugin = search_results[plugin_name]; %> + <tr> + <td><%= plugin.name %></td> + <td><%= plugin.description %></td> + <td> + <form method="post"> + <input type="hidden" name="install_plugin" value="<%= plugin.name %>"> + <input type="submit" value="I"> + </form> + </td> + </tr> + <% } %> + </tbody> + </table> + + + </body> +</html> |