871 lines
22 KiB
JavaScript
871 lines
22 KiB
JavaScript
// vim:set noexpandtab:
|
|
/**************
|
|
SYSTEM INCLUDES
|
|
**************/
|
|
var http = require("http");
|
|
var reload = require("reload");
|
|
var sanitizer = require("sanitizer");
|
|
var compression = require("compression");
|
|
var express = require("express");
|
|
var conf = require("./config.js").server;
|
|
var headerBarUrl = require("./config.js").headerBarUrl;
|
|
var logoUrl = require("./config.js").logoUrl;
|
|
|
|
/**************
|
|
LOCAL INCLUDES
|
|
**************/
|
|
var rooms = require("./lib/rooms.js");
|
|
var data = require("./lib/data.js").db;
|
|
|
|
/**************
|
|
GLOBALS
|
|
**************/
|
|
//Map of sids to user_names
|
|
var sids_to_user_names = [];
|
|
|
|
/**************
|
|
SETUP EXPRESS
|
|
**************/
|
|
var app = express();
|
|
var router = express.Router();
|
|
|
|
app.use(compression());
|
|
app.use(conf.baseurl, router);
|
|
|
|
router.use(express.static(__dirname + "/node_modules"));
|
|
router.use(express.static(__dirname + "/client"));
|
|
|
|
var server = http.createServer(app);
|
|
|
|
// Reload code here
|
|
reload(app)
|
|
.then(function (reloadReturned) {
|
|
// reloadReturned is documented in the returns API in the README
|
|
|
|
// Reload started, start web server
|
|
server.listen(conf.port, function () {
|
|
console.log("Web server available on http://127.0.0.1:" + conf.port);
|
|
});
|
|
})
|
|
.catch(function (err) {
|
|
console.error(
|
|
"Reload could not start, could not start server/sample app",
|
|
err
|
|
);
|
|
});
|
|
|
|
/**************
|
|
SETUP Socket.IO
|
|
**************/
|
|
var io = require("socket.io")(server, {
|
|
path: conf.baseurl == "/" ? "" : conf.baseurl + "/socket.io",
|
|
cookie: false
|
|
});
|
|
|
|
/**************
|
|
ROUTES
|
|
**************/
|
|
router.get("/", function (req, res) {
|
|
//console.log(req.header('host'));
|
|
url = req.header("host") + req.baseUrl;
|
|
var connected = io.sockets.connected;
|
|
clientsCount = Object.keys(connected).length;
|
|
res.render("home.jade", {
|
|
url: url,
|
|
headerBarUrl: headerBarUrl,
|
|
logoUrl: logoUrl,
|
|
connected: clientsCount,
|
|
home: true,
|
|
});
|
|
});
|
|
|
|
router.get("/demo", function (req, res) {
|
|
url = req.header("host") + req.baseUrl;
|
|
res.render("index.jade", {
|
|
pageTitle: "Post-it - demo",
|
|
headerBarUrl: headerBarUrl,
|
|
logoUrl: logoUrl,
|
|
url: url,
|
|
demo: true,
|
|
});
|
|
});
|
|
|
|
router.get("/:id", function (req, res) {
|
|
url = req.header("host") + req.baseUrl;
|
|
res.render("index.jade", {
|
|
pageTitle: "Post-it - " + req.params.id,
|
|
headerBarUrl: headerBarUrl,
|
|
logoUrl: logoUrl,
|
|
url: url,
|
|
});
|
|
});
|
|
|
|
router.get("/stats", function (req, res) {
|
|
console.log("TODO: stats");
|
|
});
|
|
|
|
/**************
|
|
SOCKET.I0
|
|
**************/
|
|
//sanitizes text
|
|
function scrub(text) {
|
|
if (typeof text != "undefined" && text !== null) {
|
|
//clip the string if it is too long
|
|
if (text.length > 65535) {
|
|
text = text.substr(0, 65535);
|
|
}
|
|
|
|
return sanitizer.sanitize(text);
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
io.sockets.on("connection", function (client) {
|
|
client.on("message", function (message) {
|
|
//console.log(message.action + " -- " + sys.inspect(message.data) );
|
|
|
|
var clean_data = {};
|
|
var clean_message = {};
|
|
var message_out = {};
|
|
|
|
if (!message.action) return;
|
|
|
|
switch (message.action) {
|
|
case "initializeMe":
|
|
initClient(client);
|
|
break;
|
|
|
|
case "joinRoom":
|
|
joinRoom(client, message.data, function (clients) {
|
|
client.json.send({ action: "roomAccept", data: "" });
|
|
});
|
|
|
|
break;
|
|
|
|
case "moveCard":
|
|
//report to all other browsers
|
|
message_out = {
|
|
action: message.action,
|
|
data: {
|
|
id: scrub(message.data.id),
|
|
position: {
|
|
left: scrub(message.data.position.left),
|
|
top: scrub(message.data.position.top),
|
|
},
|
|
},
|
|
};
|
|
|
|
broadcastToRoom(client, message_out);
|
|
|
|
// console.log("-----" + message.data.id);
|
|
// console.log(JSON.stringify(message.data));
|
|
|
|
getRoom(client, function (room) {
|
|
db.cardSetXY(
|
|
room,
|
|
message.data.id,
|
|
message.data.position.left,
|
|
message.data.position.top
|
|
);
|
|
});
|
|
|
|
break;
|
|
|
|
case "createCard":
|
|
data = message.data;
|
|
clean_data = {};
|
|
clean_data.text = scrub(data.text);
|
|
clean_data.id = scrub(data.id);
|
|
clean_data.x = scrub(data.x);
|
|
clean_data.y = scrub(data.y);
|
|
clean_data.rot = scrub(data.rot);
|
|
clean_data.colour = scrub(data.colour);
|
|
|
|
getRoom(client, function (room) {
|
|
createCard(
|
|
room,
|
|
clean_data.id,
|
|
clean_data.text,
|
|
clean_data.x,
|
|
clean_data.y,
|
|
clean_data.rot,
|
|
clean_data.colour
|
|
);
|
|
});
|
|
|
|
message_out = {
|
|
action: "createCard",
|
|
data: clean_data,
|
|
};
|
|
|
|
//report to all other browsers
|
|
broadcastToRoom(client, message_out);
|
|
break;
|
|
|
|
case "editCard":
|
|
clean_data = {};
|
|
clean_data.value = scrub(message.data.value);
|
|
clean_data.id = scrub(message.data.id);
|
|
|
|
//send update to database
|
|
getRoom(client, function (room) {
|
|
db.cardEdit(room, clean_data.id, clean_data.value);
|
|
});
|
|
|
|
message_out = {
|
|
action: "editCard",
|
|
data: clean_data,
|
|
};
|
|
|
|
broadcastToRoom(client, message_out);
|
|
|
|
break;
|
|
|
|
case "deleteCard":
|
|
clean_message = {
|
|
action: "deleteCard",
|
|
data: { id: scrub(message.data.id) },
|
|
};
|
|
|
|
getRoom(client, function (room) {
|
|
db.deleteCard(room, clean_message.data.id);
|
|
});
|
|
|
|
//report to all other browsers
|
|
broadcastToRoom(client, clean_message);
|
|
|
|
break;
|
|
|
|
case "createColumn":
|
|
clean_message = { data: scrub(message.data) };
|
|
|
|
getRoom(client, function (room) {
|
|
db.createColumn(room, clean_message.data, function () {});
|
|
});
|
|
|
|
broadcastToRoom(client, clean_message);
|
|
|
|
break;
|
|
|
|
case "deleteColumn":
|
|
getRoom(client, function (room) {
|
|
db.deleteColumn(room);
|
|
});
|
|
broadcastToRoom(client, { action: "deleteColumn" });
|
|
|
|
break;
|
|
|
|
case "updateColumns":
|
|
var columns = message.data;
|
|
|
|
if (!(columns instanceof Array)) break;
|
|
|
|
var clean_columns = [];
|
|
|
|
for (var i in columns) {
|
|
clean_columns[i] = scrub(columns[i]);
|
|
}
|
|
getRoom(client, function (room) {
|
|
db.setColumns(room, clean_columns);
|
|
});
|
|
|
|
broadcastToRoom(client, {
|
|
action: "updateColumns",
|
|
data: clean_columns,
|
|
});
|
|
|
|
break;
|
|
|
|
case "changeTheme":
|
|
clean_message = {};
|
|
clean_message.data = scrub(message.data);
|
|
|
|
getRoom(client, function (room) {
|
|
db.setTheme(room, clean_message.data);
|
|
});
|
|
|
|
clean_message.action = "changeTheme";
|
|
|
|
broadcastToRoom(client, clean_message);
|
|
break;
|
|
|
|
case "setUserName":
|
|
clean_message = {};
|
|
|
|
clean_message.data = scrub(message.data);
|
|
|
|
setUserName(client, clean_message.data);
|
|
|
|
var msg = {};
|
|
msg.action = "nameChangeAnnounce";
|
|
msg.data = { sid: client.id, user_name: clean_message.data };
|
|
broadcastToRoom(client, msg);
|
|
break;
|
|
|
|
case "addSticker":
|
|
var cardId = scrub(message.data.cardId);
|
|
var stickerId = scrub(message.data.stickerId);
|
|
|
|
getRoom(client, function (room) {
|
|
db.addSticker(room, cardId, stickerId);
|
|
});
|
|
|
|
broadcastToRoom(client, {
|
|
action: "addSticker",
|
|
data: { cardId: cardId, stickerId: stickerId },
|
|
});
|
|
break;
|
|
|
|
case "setBoardSize":
|
|
var size = {};
|
|
size.width = scrub(message.data.width);
|
|
size.height = scrub(message.data.height);
|
|
|
|
getRoom(client, function (room) {
|
|
db.setBoardSize(room, size);
|
|
});
|
|
|
|
broadcastToRoom(client, { action: "setBoardSize", data: size });
|
|
break;
|
|
|
|
case "exportTxt":
|
|
exportBoard("txt", client, message.data);
|
|
break;
|
|
|
|
case "exportCsv":
|
|
exportBoard("csv", client, message.data);
|
|
break;
|
|
|
|
case "exportJson":
|
|
exportJson(client, message.data);
|
|
break;
|
|
|
|
case "importJson":
|
|
importJson(client, message.data);
|
|
break;
|
|
|
|
case "createRevision":
|
|
createRevision(client, message.data);
|
|
break;
|
|
|
|
case "deleteRevision":
|
|
deleteRevision(client, message.data);
|
|
break;
|
|
|
|
case "exportRevision":
|
|
exportRevision(client, message.data);
|
|
break;
|
|
|
|
default:
|
|
//console.log('unknown action');
|
|
break;
|
|
}
|
|
});
|
|
|
|
client.on("disconnect", function () {
|
|
leaveRoom(client);
|
|
});
|
|
|
|
//tell all others that someone has connected
|
|
//client.broadcast('someone has connected');
|
|
});
|
|
|
|
/**************
|
|
FUNCTIONS
|
|
**************/
|
|
function initClient(client) {
|
|
//console.log ('initClient Started');
|
|
getRoom(client, function (room) {
|
|
db.getAllCards(room, function (cards) {
|
|
client.json.send({
|
|
action: "initCards",
|
|
data: cards,
|
|
});
|
|
});
|
|
|
|
db.getAllColumns(room, function (columns) {
|
|
client.json.send({
|
|
action: "initColumns",
|
|
data: columns,
|
|
});
|
|
});
|
|
|
|
db.getRevisions(room, function (revisions) {
|
|
client.json.send({
|
|
action: "initRevisions",
|
|
data: revisions !== null ? Object.keys(revisions) : new Array(),
|
|
});
|
|
});
|
|
|
|
db.getTheme(room, function (theme) {
|
|
if (theme === null) theme = "bigcards";
|
|
|
|
client.json.send({
|
|
action: "changeTheme",
|
|
data: theme,
|
|
});
|
|
});
|
|
|
|
db.getBoardSize(room, function (size) {
|
|
if (size !== null) {
|
|
client.json.send({
|
|
action: "setBoardSize",
|
|
data: size,
|
|
});
|
|
}
|
|
});
|
|
|
|
roommates_clients = rooms.room_clients(room);
|
|
roommates = [];
|
|
|
|
var j = 0;
|
|
for (var i in roommates_clients) {
|
|
if (roommates_clients[i].id != client.id) {
|
|
roommates[j] = {
|
|
sid: roommates_clients[i].id,
|
|
user_name: sids_to_user_names[roommates_clients[i].id],
|
|
};
|
|
j++;
|
|
}
|
|
}
|
|
|
|
//console.log('initialusers: ' + roommates);
|
|
client.json.send({
|
|
action: "initialUsers",
|
|
data: roommates,
|
|
});
|
|
});
|
|
}
|
|
|
|
function joinRoom(client, room, successFunction) {
|
|
var msg = {};
|
|
msg.action = "join-announce";
|
|
msg.data = { sid: client.id, user_name: client.user_name };
|
|
|
|
rooms.add_to_room_and_announce(client, room, msg);
|
|
successFunction();
|
|
}
|
|
|
|
function leaveRoom(client) {
|
|
//console.log (client.id + ' just left');
|
|
var msg = {};
|
|
msg.action = "leave-announce";
|
|
msg.data = { sid: client.id };
|
|
rooms.remove_from_all_rooms_and_announce(client, msg);
|
|
|
|
delete sids_to_user_names[client.id];
|
|
}
|
|
|
|
function broadcastToRoom(client, message) {
|
|
rooms.broadcast_to_roommates(client, message);
|
|
}
|
|
|
|
//----------------CARD FUNCTIONS
|
|
function createCard(room, id, text, x, y, rot, colour) {
|
|
var card = {
|
|
id: id,
|
|
colour: colour,
|
|
rot: rot,
|
|
x: x,
|
|
y: y,
|
|
text: text,
|
|
sticker: null,
|
|
};
|
|
|
|
db.createCard(room, id, card);
|
|
}
|
|
|
|
function roundRand(max) {
|
|
return Math.floor(Math.random() * max);
|
|
}
|
|
|
|
//------------ROOM STUFF
|
|
// Get Room name for the given Session ID
|
|
function getRoom(client, callback) {
|
|
room = rooms.get_room(client);
|
|
//console.log( 'client: ' + client.id + " is in " + room);
|
|
callback(room);
|
|
}
|
|
|
|
function setUserName(client, name) {
|
|
client.user_name = name;
|
|
sids_to_user_names[client.id] = name;
|
|
//console.log('sids to user names: ');
|
|
console.dir(sids_to_user_names);
|
|
}
|
|
|
|
function cleanAndInitializeDemoRoom() {
|
|
// DUMMY DATA
|
|
db.clearRoom("/demo", function () {
|
|
db.createColumn("/demo", "Pas commencé");
|
|
db.createColumn("/demo", "Commencé");
|
|
db.createColumn("/demo", "En test");
|
|
db.createColumn("/demo", "Validation");
|
|
db.createColumn("/demo", "Terminé");
|
|
|
|
createCard(
|
|
"/demo",
|
|
"card1",
|
|
"Salut, c'est fun",
|
|
roundRand(600),
|
|
roundRand(300),
|
|
Math.random() * 10 - 5,
|
|
"yellow"
|
|
);
|
|
createCard(
|
|
"/demo",
|
|
"card2",
|
|
"Salut, c'est une nouvelle histoire.",
|
|
roundRand(600),
|
|
roundRand(300),
|
|
Math.random() * 10 - 5,
|
|
"white"
|
|
);
|
|
createCard(
|
|
"/demo",
|
|
"card3",
|
|
".",
|
|
roundRand(600),
|
|
roundRand(300),
|
|
Math.random() * 10 - 5,
|
|
"blue"
|
|
);
|
|
createCard(
|
|
"/demo",
|
|
"card4",
|
|
".",
|
|
roundRand(600),
|
|
roundRand(300),
|
|
Math.random() * 10 - 5,
|
|
"green"
|
|
);
|
|
|
|
createCard(
|
|
"/demo",
|
|
"card5",
|
|
"Salut, c'est fun",
|
|
roundRand(600),
|
|
roundRand(300),
|
|
Math.random() * 10 - 5,
|
|
"yellow"
|
|
);
|
|
createCard(
|
|
"/demo",
|
|
"card6",
|
|
"Salut, c'est un nouveau mémo.",
|
|
roundRand(600),
|
|
roundRand(300),
|
|
Math.random() * 10 - 5,
|
|
"yellow"
|
|
);
|
|
createCard(
|
|
"/demo",
|
|
"card7",
|
|
".",
|
|
roundRand(600),
|
|
roundRand(300),
|
|
Math.random() * 10 - 5,
|
|
"blue"
|
|
);
|
|
createCard(
|
|
"/demo",
|
|
"card8",
|
|
".",
|
|
roundRand(600),
|
|
roundRand(300),
|
|
Math.random() * 10 - 5,
|
|
"green"
|
|
);
|
|
});
|
|
}
|
|
|
|
// Export board in txt or csv
|
|
function exportBoard(format, client, data) {
|
|
var result = new Array();
|
|
getRoom(client, function (room) {
|
|
db.getAllCards(room, function (cards) {
|
|
db.getAllColumns(room, function (columns) {
|
|
var text = new Array();
|
|
var cols = {};
|
|
if (columns.length > 0) {
|
|
for (var i = 0; i < columns.length; i++) {
|
|
cols[columns[i]] = new Array();
|
|
for (var j = 0; j < cards.length; j++) {
|
|
if (i === 0) {
|
|
if (cards[j]["x"] < (i + 1) * data) {
|
|
cols[columns[i]].push(cards[j]);
|
|
}
|
|
} else if (i + 1 === columns.length) {
|
|
if (cards[j]["x"] >= i * data) {
|
|
cols[columns[i]].push(cards[j]);
|
|
}
|
|
} else if (
|
|
cards[j]["x"] >= i * data &&
|
|
cards[j]["x"] < (i + 1) * data
|
|
) {
|
|
cols[columns[i]].push(cards[j]);
|
|
}
|
|
}
|
|
cols[columns[i]].sort(function (a, b) {
|
|
if (a["y"] === b["y"]) {
|
|
return a["x"] - b["x"];
|
|
} else {
|
|
return a["y"] - b["y"];
|
|
}
|
|
});
|
|
}
|
|
if (format === "txt") {
|
|
for (var i = 0; i < columns.length; i++) {
|
|
if (i === 0) {
|
|
text.push("# " + columns[i]);
|
|
} else {
|
|
text.push("\n# " + columns[i]);
|
|
}
|
|
for (var j = 0; j < cols[columns[i]].length; j++) {
|
|
text.push("- " + cols[columns[i]][j]["text"]);
|
|
}
|
|
}
|
|
} else if (format === "csv") {
|
|
var max = 0;
|
|
var line = new Array();
|
|
var patt_vuln = new RegExp("^[=+-@]");
|
|
for (var i = 0; i < columns.length; i++) {
|
|
if (cols[columns[i]].length > max) {
|
|
max = cols[columns[i]].length;
|
|
}
|
|
var val = columns[i].replace(/"/g, '""');
|
|
if (patt_vuln.test(val)) {
|
|
// prevent CSV Formula Injection
|
|
var val = "'" + val;
|
|
}
|
|
line.push('"' + val + '"');
|
|
}
|
|
text.push(line.join(","));
|
|
for (var j = 0; j < max; j++) {
|
|
line = new Array();
|
|
for (var i = 0; i < columns.length; i++) {
|
|
var val =
|
|
cols[columns[i]][j] !== undefined
|
|
? cols[columns[i]][j]["text"].replace(/"/g, '""')
|
|
: "";
|
|
if (patt_vuln.test(val)) {
|
|
// prevent CSV Formula Injection
|
|
var val = "'" + val;
|
|
}
|
|
line.push('"' + val + '"');
|
|
}
|
|
text.push(line.join(","));
|
|
}
|
|
}
|
|
} else {
|
|
for (var j = 0; j < cards.length; j++) {
|
|
if (format === "txt") {
|
|
text.push("- " + cards[j]["text"]);
|
|
} else if (format === "csv") {
|
|
text.push('"' + cards[j]["text"].replace(/"/g, '""') + '"\n');
|
|
}
|
|
}
|
|
}
|
|
var result;
|
|
if (format === "txt" || format === "csv") {
|
|
result = text.join("\n");
|
|
} else if (format === "json") {
|
|
result = JSON.stringify(cols);
|
|
}
|
|
client.json.send({
|
|
action: "export",
|
|
data: {
|
|
filename: room.replace("/", "") + "." + format,
|
|
text: result,
|
|
},
|
|
});
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
// Export board in json, suitable for import
|
|
function exportJson(client, data) {
|
|
var result = new Array();
|
|
getRoom(client, function (room) {
|
|
db.getAllCards(room, function (cards) {
|
|
db.getAllColumns(room, function (columns) {
|
|
db.getTheme(room, function (theme) {
|
|
db.getBoardSize(room, function (size) {
|
|
if (theme === null) theme = "bigcards";
|
|
if (size === null)
|
|
size = { width: data.width, height: data.height };
|
|
result = JSON.stringify({
|
|
cards: cards,
|
|
columns: columns,
|
|
theme: theme,
|
|
size: size,
|
|
});
|
|
client.json.send({
|
|
action: "export",
|
|
data: {
|
|
filename: room.replace("/", "") + ".json",
|
|
text: result,
|
|
},
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
// Import board from json
|
|
function importJson(client, data) {
|
|
getRoom(client, function (room) {
|
|
db.clearRoom(room, function () {
|
|
db.getAllCards(room, function (cards) {
|
|
for (var i = 0; i < cards.length; i++) {
|
|
db.deleteCard(room, cards[i].id);
|
|
}
|
|
|
|
cards = data.cards;
|
|
var cards2 = new Array();
|
|
for (var i = 0; i < cards.length; i++) {
|
|
var card = cards[i];
|
|
if (
|
|
card.id !== undefined &&
|
|
card.colour !== undefined &&
|
|
card.rot !== undefined &&
|
|
card.x !== undefined &&
|
|
card.y !== undefined &&
|
|
card.text !== undefined &&
|
|
card.sticker !== undefined
|
|
) {
|
|
var c = {
|
|
id: card.id,
|
|
colour: card.colour,
|
|
rot: card.rot,
|
|
x: card.x,
|
|
y: card.y,
|
|
text: scrub(card.text),
|
|
sticker: card.sticker,
|
|
};
|
|
db.createCard(room, c.id, c);
|
|
cards2.push(c);
|
|
}
|
|
}
|
|
var msg = { action: "initCards", data: cards2 };
|
|
broadcastToRoom(client, msg);
|
|
client.json.send(msg);
|
|
});
|
|
|
|
db.getAllColumns(room, function (columns) {
|
|
for (var i = 0; i < columns.length; i++) {
|
|
db.deleteColumn(room);
|
|
}
|
|
|
|
columns = data.columns;
|
|
var columns2 = new Array();
|
|
for (var i = 0; i < columns.length; i++) {
|
|
var column = scrub(columns[i]);
|
|
if (typeof column === "string") {
|
|
db.createColumn(room, column);
|
|
columns2.push(column);
|
|
}
|
|
}
|
|
msg = { action: "initColumns", data: columns2 };
|
|
broadcastToRoom(client, msg);
|
|
client.json.send(msg);
|
|
});
|
|
|
|
var size = data.size;
|
|
if (size.width !== undefined && size.height !== undefined) {
|
|
size = { width: scrub(size.width), height: scrub(size.height) };
|
|
db.setBoardSize(room, size);
|
|
msg = { action: "setBoardSize", data: size };
|
|
broadcastToRoom(client, msg);
|
|
client.json.send(msg);
|
|
}
|
|
|
|
data.theme = scrub(data.theme);
|
|
if (data.theme === "smallcards" || data.theme === "bigcards") {
|
|
db.setTheme(room, data.theme);
|
|
msg = { action: "changeTheme", data: data.theme };
|
|
broadcastToRoom(client, msg);
|
|
client.json.send(msg);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
//
|
|
|
|
function createRevision(client, data) {
|
|
var result = new Array();
|
|
getRoom(client, function (room) {
|
|
db.getAllCards(room, function (cards) {
|
|
db.getAllColumns(room, function (columns) {
|
|
db.getTheme(room, function (theme) {
|
|
db.getBoardSize(room, function (size) {
|
|
if (theme === null) theme = "bigcards";
|
|
if (size === null)
|
|
size = { width: data.width, height: data.height };
|
|
result = {
|
|
cards: cards,
|
|
columns: columns,
|
|
theme: theme,
|
|
size: size,
|
|
};
|
|
var timestamp = Date.now();
|
|
db.getRevisions(room, function (revisions) {
|
|
if (revisions === null) revisions = {};
|
|
revisions[timestamp + ""] = result;
|
|
db.setRevisions(room, revisions);
|
|
msg = { action: "addRevision", data: timestamp };
|
|
broadcastToRoom(client, msg);
|
|
client.json.send(msg);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
function deleteRevision(client, timestamp) {
|
|
getRoom(client, function (room) {
|
|
db.getRevisions(room, function (revisions) {
|
|
if (revisions !== null && revisions[timestamp + ""] !== undefined) {
|
|
delete revisions[timestamp + ""];
|
|
db.setRevisions(room, revisions);
|
|
}
|
|
msg = { action: "deleteRevision", data: timestamp };
|
|
broadcastToRoom(client, msg);
|
|
client.json.send(msg);
|
|
});
|
|
});
|
|
}
|
|
|
|
function exportRevision(client, timestamp) {
|
|
getRoom(client, function (room) {
|
|
db.getRevisions(room, function (revisions) {
|
|
if (revisions !== null && revisions[timestamp + ""] !== undefined) {
|
|
client.json.send({
|
|
action: "export",
|
|
data: {
|
|
filename: room.replace("/", "") + "-" + timestamp + ".json",
|
|
text: JSON.stringify(revisions[timestamp + ""]),
|
|
},
|
|
});
|
|
} else {
|
|
client.json.send({
|
|
action: "message",
|
|
data: "Unable to find revision " + timestamp + ".",
|
|
});
|
|
}
|
|
});
|
|
});
|
|
}
|
|
/**************
|
|
SETUP DATABASE ON FIRST RUN
|
|
**************/
|
|
// (runs only once on startup)
|
|
var db = new data(function () {
|
|
cleanAndInitializeDemoRoom();
|
|
});
|