Merge pull request #1120 from Pita/feature/settings-admin
Modify Server Settings in /admin/settingspull/1126/merge
commit
b6a331b9ec
|
@ -16,6 +16,11 @@
|
||||||
{ "name": "admin", "hooks": { "expressCreateServer": "ep_etherpad-lite/node/hooks/express/admin:expressCreateServer" } },
|
{ "name": "admin", "hooks": { "expressCreateServer": "ep_etherpad-lite/node/hooks/express/admin:expressCreateServer" } },
|
||||||
{ "name": "adminplugins", "hooks": {
|
{ "name": "adminplugins", "hooks": {
|
||||||
"expressCreateServer": "ep_etherpad-lite/node/hooks/express/adminplugins:expressCreateServer",
|
"expressCreateServer": "ep_etherpad-lite/node/hooks/express/adminplugins:expressCreateServer",
|
||||||
"socketio": "ep_etherpad-lite/node/hooks/express/adminplugins:socketio" } }
|
"socketio": "ep_etherpad-lite/node/hooks/express/adminplugins:socketio" }
|
||||||
|
},
|
||||||
|
{ "name": "adminsettings", "hooks": {
|
||||||
|
"expressCreateServer": "ep_etherpad-lite/node/hooks/express/adminsettings:expressCreateServer",
|
||||||
|
"socketio": "ep_etherpad-lite/node/hooks/express/adminsettings:socketio" }
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
var path = require('path');
|
||||||
|
var eejs = require('ep_etherpad-lite/node/eejs');
|
||||||
|
var installer = require('ep_etherpad-lite/static/js/pluginfw/installer');
|
||||||
|
var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks");
|
||||||
|
var fs = require('fs');
|
||||||
|
|
||||||
|
exports.expressCreateServer = function (hook_name, args, cb) {
|
||||||
|
args.app.get('/admin/settings', function(req, res) {
|
||||||
|
|
||||||
|
var render_args = {
|
||||||
|
settings: "",
|
||||||
|
search_results: {},
|
||||||
|
errors: []
|
||||||
|
};
|
||||||
|
|
||||||
|
res.send( eejs.require("ep_etherpad-lite/templates/admin/settings.html", render_args) );
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.socketio = function (hook_name, args, cb) {
|
||||||
|
var io = args.io.of("/settings");
|
||||||
|
io.on('connection', function (socket) {
|
||||||
|
if (!socket.handshake.session.user || !socket.handshake.session.user.is_admin) return;
|
||||||
|
|
||||||
|
socket.on("load", function (query) {
|
||||||
|
fs.readFile('settings.json', 'utf8', function (err,data) {
|
||||||
|
if (err) {
|
||||||
|
return console.log(err);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
socket.emit("settings", {results: data});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on("saveSettings", function (settings) {
|
||||||
|
fs.writeFile('settings.json', settings, function (err) {
|
||||||
|
if (err) throw err;
|
||||||
|
socket.emit("saveprogress", "saved");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on("restartServer", function () {
|
||||||
|
console.log("Admin request to restart server through a socket on /admin/settings");
|
||||||
|
hooks.aCallAll("restartServer", {}, function () {});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
|
@ -120,3 +120,11 @@ td, th {
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
.settings {
|
||||||
|
margin-top:10px;
|
||||||
|
width:100%;
|
||||||
|
min-height:600px;
|
||||||
|
}
|
||||||
|
#response{
|
||||||
|
display:inline;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*! JSON.minify()
|
||||||
|
v0.1 (c) Kyle Simpson
|
||||||
|
MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function(global){
|
||||||
|
if (typeof global.JSON == "undefined" || !global.JSON) {
|
||||||
|
global.JSON = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
global.JSON.minify = function(json) {
|
||||||
|
|
||||||
|
var tokenizer = /"|(\/\*)|(\*\/)|(\/\/)|\n|\r/g,
|
||||||
|
in_string = false,
|
||||||
|
in_multiline_comment = false,
|
||||||
|
in_singleline_comment = false,
|
||||||
|
tmp, tmp2, new_str = [], ns = 0, from = 0, lc, rc
|
||||||
|
;
|
||||||
|
|
||||||
|
tokenizer.lastIndex = 0;
|
||||||
|
|
||||||
|
while (tmp = tokenizer.exec(json)) {
|
||||||
|
lc = RegExp.leftContext;
|
||||||
|
rc = RegExp.rightContext;
|
||||||
|
if (!in_multiline_comment && !in_singleline_comment) {
|
||||||
|
tmp2 = lc.substring(from);
|
||||||
|
if (!in_string) {
|
||||||
|
tmp2 = tmp2.replace(/(\n|\r|\s)*/g,"");
|
||||||
|
}
|
||||||
|
new_str[ns++] = tmp2;
|
||||||
|
}
|
||||||
|
from = tokenizer.lastIndex;
|
||||||
|
|
||||||
|
if (tmp[0] == "\"" && !in_multiline_comment && !in_singleline_comment) {
|
||||||
|
tmp2 = lc.match(/(\\)*$/);
|
||||||
|
if (!in_string || !tmp2 || (tmp2[0].length % 2) == 0) { // start of string with ", or unescaped " character found to end string
|
||||||
|
in_string = !in_string;
|
||||||
|
}
|
||||||
|
from--; // include " character in next catch
|
||||||
|
rc = json.substring(from);
|
||||||
|
}
|
||||||
|
else if (tmp[0] == "/*" && !in_string && !in_multiline_comment && !in_singleline_comment) {
|
||||||
|
in_multiline_comment = true;
|
||||||
|
}
|
||||||
|
else if (tmp[0] == "*/" && !in_string && in_multiline_comment && !in_singleline_comment) {
|
||||||
|
in_multiline_comment = false;
|
||||||
|
}
|
||||||
|
else if (tmp[0] == "//" && !in_string && !in_multiline_comment && !in_singleline_comment) {
|
||||||
|
in_singleline_comment = true;
|
||||||
|
}
|
||||||
|
else if ((tmp[0] == "\n" || tmp[0] == "\r") && !in_string && !in_multiline_comment && in_singleline_comment) {
|
||||||
|
in_singleline_comment = false;
|
||||||
|
}
|
||||||
|
else if (!in_multiline_comment && !in_singleline_comment && !(/\n|\r|\s/.test(tmp[0]))) {
|
||||||
|
new_str[ns++] = tmp[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new_str[ns++] = rc;
|
||||||
|
return new_str.join("");
|
||||||
|
};
|
||||||
|
})(this);
|
|
@ -0,0 +1,68 @@
|
||||||
|
$(document).ready(function () {
|
||||||
|
var socket,
|
||||||
|
loc = document.location,
|
||||||
|
port = loc.port == "" ? (loc.protocol == "https:" ? 443 : 80) : loc.port,
|
||||||
|
url = loc.protocol + "//" + loc.hostname + ":" + port + "/",
|
||||||
|
pathComponents = location.pathname.split('/'),
|
||||||
|
// Strip admin/plugins
|
||||||
|
baseURL = pathComponents.slice(0,pathComponents.length-2).join('/') + '/',
|
||||||
|
resource = baseURL.substring(1) + "socket.io";
|
||||||
|
|
||||||
|
//connect
|
||||||
|
socket = io.connect(url, {resource : resource}).of("/settings");
|
||||||
|
|
||||||
|
socket.on('settings', function (settings) {
|
||||||
|
|
||||||
|
/* Check to make sure the JSON is clean before proceeding */
|
||||||
|
if(isJSONClean(settings.results))
|
||||||
|
{
|
||||||
|
$('.settings').append(settings.results);
|
||||||
|
$('.settings').focus();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
alert("YOUR JSON IS BAD AND YOU SHOULD FEEL BAD");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* When the admin clicks save Settings check the JSON then send the JSON back to the server */
|
||||||
|
$('#saveSettings').on('click', function(){
|
||||||
|
var editedSettings = $('.settings').val();
|
||||||
|
if(isJSONClean(editedSettings)){
|
||||||
|
// JSON is clean so emit it to the server
|
||||||
|
socket.emit("saveSettings", $('.settings').val());
|
||||||
|
}else{
|
||||||
|
alert("YOUR JSON IS BAD AND YOU SHOULD FEEL BAD")
|
||||||
|
$('.settings').focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* Tell Etherpad Server to restart */
|
||||||
|
$('#restartEtherpad').on('click', function(){
|
||||||
|
socket.emit("restartServer");
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('saveprogress', function(progress){
|
||||||
|
$('#response').show();
|
||||||
|
$('#response').text(progress);
|
||||||
|
$('#response').fadeOut('slow');
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.emit("load"); // Load the JSON from the server
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function isJSONClean(data){
|
||||||
|
var cleanSettings = JSON.minify(data);
|
||||||
|
try{
|
||||||
|
var response = jQuery.parseJSON(cleanSettings);
|
||||||
|
}
|
||||||
|
catch(e){
|
||||||
|
return false; // the JSON failed to be parsed
|
||||||
|
}
|
||||||
|
if(typeof response !== 'object'){
|
||||||
|
return false;
|
||||||
|
}else{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Settings manager</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
|
||||||
|
<link rel="stylesheet" href="../static/css/admin.css">
|
||||||
|
<script src="../static/js/jquery.js"></script>
|
||||||
|
<script src="../socket.io/socket.io.js"></script>
|
||||||
|
<script src="../static/js/admin/minify.json.js"></script>
|
||||||
|
<script src="../static/js/admin/settings.js"></script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="wrapper">
|
||||||
|
|
||||||
|
<% if (errors.length) { %>
|
||||||
|
<div class="errors">
|
||||||
|
<% errors.forEach(function (item) { %>
|
||||||
|
<div class="error"><%= item.toString() %></div>
|
||||||
|
<% }) %>
|
||||||
|
</div>
|
||||||
|
<% } %>
|
||||||
|
|
||||||
|
|
||||||
|
<h1>Etherpad Lite Settings</h1>
|
||||||
|
<a href=''>Example production settings template</a>
|
||||||
|
<a href=''>Example development settings template</a>
|
||||||
|
<textarea class="settings"></textarea>
|
||||||
|
<input type="button" class="settingsButton" id="saveSettings" value="Save Settings">
|
||||||
|
<input type="button" class="settingsButton" id="restartEtherpad" value="Restart Etherpad">
|
||||||
|
<div id="response"></div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue