!! Compability break for previous versions !!

Data directory stucture change, to migrate:
create `./data/backgrounds` and `./data/bundles/`
move everything from `.data` to `.data/bundles`
move backgrounds from bundles to `./data/backgrounds`
---
Admin socket interface changed to use namespaces
Background images are now shared between bundles
route /admin points now to overview of screens
route created for /admin/display/:id
This commit is contained in:
Reaby committed 2019-07-18 13:50:29 +03:00
1 parent 494bec1d59
commit 7e7227316d
40 files changed
+164 -210

No files matched your search

+74 -91
View File
@@ -1,33 +1,31 @@
let fs = require("fs");
let config = require("../config.js");
let cli = require('./cli.js');
let config = require(`../config.js`);
let cli = require(`./cli.js`);
/**
* @module infoscreen3/admin
* @class
*
*/
class admin {
/**
*
* @param sharedIO
* @param dispatcher
* @param screenViews
* @param screenView
* @param displayId
* @param bundleManager
*/
constructor(sharedIO, dispatcher, screenViews, bundleManager) {
cli.info("Starting admin socket interface");
constructor(sharedIO, dispatcher, screenView, displayId, bundleManager) {
/**
* @typedef {object} previewInstance
* @typedef {string[]} previewInstance
* @property {string} adminId is string from admin socket.Id
* @property {object} preview, pure previews socket
*
* @type {previewInstance[]}
* @type {object}
*/
let previewInstances = [];
let io = sharedIO.of("/admin");
let io = sharedIO.of("/admin-" + displayId);
this.io = io;
this.displayId = displayId;
this.dispatcher = dispatcher;
this.bundleManager = bundleManager;
@@ -94,31 +92,31 @@ class admin {
// toggle time
socket.on('controls.time.toggle', function (data) {
let view = getView(data.displayId);
let view = getView();
let bool = !view.serverOptions.displayTime;
view.getBundle().bundleData.displayTime = bool;
view.serverOptions.displayTime = bool;
view.io.emit("callback.time", bool);
updateDashboard(io, data.displayId);
updateDashboard(io);
});
socket.on('controls.previous', function (data) {
let view = getView(data.displayId);
let view = getView();
view.serverOptions.loopIndex -= 2;
view.mainLoop();
});
socket.on('controls.play', function (data) {
getServerOptions(data.displayId).loop = true;
getView(data.displayId).mainLoop();
updateDashboard(io, data.displayId);
getServerOptions().loop = true;
getView().mainLoop();
updateDashboard(io);
});
socket.on('controls.startStream', function (data) {
let view = getView(data.displayId);
let serverOptions = getServerOptions(data.displayId);
let view = getView();
let serverOptions = getServerOptions();
if (serverOptions.isStreaming === false) {
serverOptions.loop = false;
@@ -133,27 +131,27 @@ class admin {
cli.success("stop stream");
}
view.io.emit("callbackLoad", view.getSlideData());
updateDashboard(io, data.displayId);
updateDashboard(io);
});
socket.on('controls.pause', function (data) {
let view = getView(data.displayId);
let view = getView();
view.clearTimers();
getServerOptions(data.displayId).loop = false;
updateDashboard(io, data.displayId);
getServerOptions().loop = false;
updateDashboard(io);
});
socket.on('controls.next', function (data) {
getView(data.displayId).mainLoop();
getView().mainLoop();
});
socket.on('controls.blackout', function (data) {
let view = getView(data.displayId);
let view = getView();
view.serverOptions.blackout = view.serverOptions.blackout === false;
view.io.emit("callback.blackout", {serverOptions: view.serverOptions});
updateDashboard(io, data.displayId);
updateDashboard(io);
});
socket.on("controls.preview", function (data) {
@@ -179,19 +177,19 @@ class admin {
});
socket.on("controls.skipTo", function (data) {
let bundleSettings = getView(data.displayId).getBundle();
let bundleSettings = getView().getBundle();
let slides = bundleSettings.enabledSlides;
let idx = slides.indexOf(data.fileName);
if (idx >= 0) {
getServerOptions(data.displayId).loopIndex = idx;
getServerOptions().loopIndex = idx;
}
getView(data.displayId).mainLoop();
getView().mainLoop();
});
socket.on('controls.toggle', function (data) {
let fileName = data.fileName;
let bundleSettings = getView(data.displayId).getBundle();
let bundleSettings = getView().getBundle();
let idx = bundleSettings.disabledSlides.indexOf(fileName);
if (idx > -1) {
@@ -200,7 +198,7 @@ class admin {
bundleSettings.setSlideStatus(fileName, false);
}
updateDashboard(socket, data.displayId);
updateDashboard(socket);
});
// override
@@ -212,7 +210,7 @@ class admin {
}
dispatcher.emit("all.override", data);
} else {
let view = getView(parseInt(data.displayId));
let view = getView();
view.overrideSlide(data.json, data.png, data.duration);
view.displayCurrentSlide();
}
@@ -222,28 +220,23 @@ class admin {
});
socket.on('admin.setBundle', function (data) {
let view = getView(data.displayId);
let view = getView();
view.changeBundle(data.bundle);
view.displayCurrentSlide();
updateDashboard(io, data.displayId);
updateDashboard(io);
});
socket.on('admin.dashboard.sync', function (data) {
syncDashboard(socket, data.displayId);
updateDashboard(socket, data.displayId);
});
socket.on('admin.setDisplay', function (data) {
syncDashboard(socket, data.display);
updateDashboard(socket, data.display);
socket.on('admin.dashboard.sync', function () {
syncDashboard(socket);
updateDashboard(socket);
});
socket.on('admin.listSlides', function (data) {
updateDashboard(socket, data.displayId);
updateDashboard(socket);
});
socket.on('admin.listBundles', function (data) {
updateDashboard(socket, data.displayId);
updateDashboard(socket);
});
@@ -257,7 +250,7 @@ class admin {
}
// calculate next slide order for all displays which has the bundle selected
for (let display of screenViews) {
for (let display of screenView) {
if (display.serverOptions.currentBundle === data.bundleName) {
for (let slide of bundle.allSlides) {
// calculate new index for next slide;
@@ -288,24 +281,23 @@ class admin {
cli.info("@ create Bundle");
try {
if (!fs.existsSync("data/" + data.dir)) {
fs.mkdirSync("data/" + data.dir);
fs.mkdirSync("data/" + data.dir + "/backgrounds");
fs.mkdirSync("data/" + data.dir + "/images");
fs.mkdirSync("data/" + data.dir + "/render");
fs.mkdirSync("data/" + data.dir + "/slides");
if (!fs.existsSync("data/bundles" + data.dir)) {
fs.mkdirSync("data/bundles/" + data.dir);
fs.mkdirSync("data/bundles/" + data.dir + "/images");
fs.mkdirSync("data/bundles/" + data.dir + "/render");
fs.mkdirSync("data/bundles/" + data.dir + "/slides");
var tempData = JSON.parse(fs.readFileSync("templates/bundle/bundle.json").toString());
let tempData = JSON.parse(fs.readFileSync("templates/bundle/bundle.json").toString());
tempData.displayName = data.bundle;
fs.writeFileSync("data/" + data.dir + "/bundle.json", JSON.stringify(tempData));
fs.writeFileSync("data/bundles/" + data.dir + "/bundle.json", JSON.stringify(tempData));
fs.copyFileSync("templates/bundle/slides.json", "data/" + data.dir + "/slides.json");
fs.copyFileSync("templates/bundle/backgrounds/bg.jpg", "data/" + data.dir + "/backgrounds/bg.jpg");
fs.copyFileSync("templates/bundle/slides.json", "data/bundles/" + data.dir + "/slides.json");
fs.copyFileSync("templates/bundle/backgrounds/bg.jpg", "data/bundles/" + data.dir + "/backgrounds/bg.jpg");
bundleManager.getBundle(data.dir);
syncDashboard(io, data.displayId);
syncDashboard(io);
} else {
socket.emit("callback.error", "Error: bundle already exists.");
syncDashboard(io, data.displayId);
syncDashboard(io);
}
} catch (err) {
cli.error(err, "Error while creating new bundle");
@@ -333,7 +325,6 @@ class admin {
filename = uuidv4();
}
var duration = null;
if (data.duration === "") {
data.duration = null;
}
@@ -405,13 +396,13 @@ class admin {
/** change transition **/
socket.on('admin.setTransition', function (data) {
var transition = data.transition;
let transition = data.transition;
if (data.transition === "null") {
transition = null;
}
getServerOptions(data.displayId).transition = transition;
updateDashboard(io, data.displayId);
getServerOptions().transition = transition;
updateDashboard(io);
});
socket.on('edit.save', function (data) {
@@ -421,20 +412,20 @@ class admin {
filename = uuidv4();
}
var duration = data.duration;
if (data.duration == "") {
let duration = data.duration;
if (data.duration === "") {
duration = null;
}
var transition = data.transition;
if (data.transition == "") {
let transition = data.transition;
if (data.transition === "") {
transition = null;
}
try {
fs.writeFileSync("./data/" + data.bundleName + "/render/" + filename + ".png", data.png.replace(/^data:image\/png;base64,/, ""), "base64");
fs.writeFileSync("./data/" + data.bundleName + "/slides/" + filename, JSON.stringify(data.json));
fs.writeFileSync("./data/bundles/" + data.bundleName + "/render/" + filename + ".png", data.png.replace(/^data:image\/png;base64,/, ""), "base64");
fs.writeFileSync("./data/bundles/" + data.bundleName + "/slides/" + filename, JSON.stringify(data.json));
let bundle = self.bundleManager.getBundle(data.bundleName);
@@ -488,7 +479,7 @@ class admin {
let replace = "^data:" + data.type + ";base64,";
let re = new RegExp(replace, "g");
fs.writeFileSync("./data/" + data.bundleName + "/images/" + filename + ext, data.imageData.replace(re, ""), "base64");
fs.writeFileSync(".data/bundles/" + data.bundleName + "/images/" + filename + ext, data.imageData.replace(re, ""), "base64");
cli.success("upload of " + filename + ext);
socket.emit("callback.edit.updateFileList", {});
} catch (err) {
@@ -500,7 +491,7 @@ class admin {
socket.on('edit.deleteImage', function (data) {
try {
fs.unlinkSync("./data/" + data.bundleName + "/images/" + data.name);
fs.unlinkSync(".data/bundles/" + data.bundleName + "/images/" + data.name);
cli.success("delete " + data.name);
socket.emit("callback.edit.updateFileList", {});
} catch (err) {
@@ -516,12 +507,9 @@ class admin {
/**
* @param {object} socket
* @param {number|string} displayId
*/
function updateDashboard(socket, displayId) {
displayId = parseInt(displayId);
let view = getView(displayId);
function updateDashboard(socket) {
let view = getView();
let serverOptions = view.serverOptions;
let bundleSettings = view.getBundle();
@@ -540,11 +528,9 @@ class admin {
});
}
function syncDashboard(socket, displayId) {
displayId = parseInt(displayId);
function syncDashboard(socket) {
previewInstances.push({adminId: socket.id, preview: {}, currentView: {}});
let serverOptions = getView(displayId).serverOptions;
let serverOptions = getView().serverOptions;
let bundleDirs = self.bundleManager.getBundleInfos();
@@ -582,27 +568,24 @@ class admin {
}
/**
* @param {number} displayId
* @return infoscreen3/display.serverOptions
*/
function getServerOptions(displayId) {
return getView(displayId).serverOptions;
function getServerOptions() {
return getView().serverOptions;
}
/**
*
* @param displayId
* @return display
*/
function getView(displayId) {
try {
return screenViews[parseInt(displayId)];
} catch (err) {
throw "display not found";
}
function getView() {
return screenView;
}
}
} // admin
/**
* @type {admin}
*/
module.exports = admin;
View File
Whitespace-only changes.
+10 -6
View File
@@ -2,14 +2,14 @@ let cli = require("./cli.js");
let fs = require("fs");
/**
*
* @module infoscreen3/bundle
*/
class bundleClass {
constructor(name, data, slides) {
this.name = name;
this.bundleData = data;
this.bundleData['bundleName']= this.name;
this.bundleData['bundleName'] = this.name;
this.allSlides = slides;
this.enabledSlides = [];
this.disabledSlides = [];
@@ -28,7 +28,7 @@ class bundleClass {
getSlideJsonFile(fileName) {
try {
return fs.readFileSync("./data/" + this.name + "/slides/" + fileName).toString();
return fs.readFileSync("./data/bundles/" + this.name + "/slides/" + fileName).toString();
} catch (err) {
return "{}";
}
@@ -56,7 +56,7 @@ class bundleClass {
}
if (slide.uuid === uuid) {
if (slide.type === "slide") {
let path = "./data/" + this.name;
let path = "./data/bundles/" + this.name;
try {
if (fs.existsSync(path + "/render/" + uuid + ".png")) {
fs.unlinkSync(path + "/render/" + uuid + ".png");
@@ -127,8 +127,8 @@ class bundleClass {
save() {
this.sync();
try {
fs.writeFileSync("./data/" + this.name + "/slides.json", this.toJson());
fs.writeFileSync("./data/" + this.name + "/bundle.json", JSON.stringify(this.bundleData, null, "\t"));
fs.writeFileSync("./data/bundles/" + this.name + "/slides.json", this.toJson());
fs.writeFileSync("./data/bundles/" + this.name + "/bundle.json", JSON.stringify(this.bundleData, null, "\t"));
} catch (e) {
cli.error("error while saving file:", e);
}
@@ -162,4 +162,8 @@ function sortByProperty(property) {
}
}
/**
*
* @type {bundleClass}
*/
module.exports = bundleClass;
+8 -8
View File
@@ -1,8 +1,8 @@
"use strict";
const bundle = require('./bundle.js');
const bundle = require(`./bundle.js`);
let fs = require("fs");
let cli = require("./cli.js");
let cli = require(`./cli.js`);
/**
* @module infoscreen3/bundleManager
@@ -18,12 +18,12 @@ class bundleManager {
*/
syncBundles() {
this.bundles = {};
let dirs = getDirectories("./data");
let dirs = getDirectories("./data/bundles/");
dirs.sort();
for (let name of dirs) {
let data = getJson("./data/" + name + "/bundle.json");
let slides = getJson("./data/" + name + "/slides.json");
let data = getJson("./data/bundles/" + name + "/bundle.json");
let slides = getJson("./data/bundles/" + name + "/slides.json");
this.bundles[name] = new bundle(name, data, slides);
}
@@ -40,8 +40,8 @@ class bundleManager {
} else {
try {
cli.info(name + " not in bundles, trying to load from fs...");
let data = getJson("./data/" + name + "/bundle.json");
let slides = getJson("./data/" + name + "/slides.json");
let data = getJson("./data/bundles/" + name + "/bundle.json");
let slides = getJson("./data/bundles/" + name + "/slides.json");
this.bundles[name] = new bundle(name, data, slides);
cli.success(name + " load");
return this.bundles[name];
@@ -81,7 +81,7 @@ function getDirectories(path) {
/**
* helper function to load and parse json to array
* @param file
* @return {any}
* @return {object}
*/
function getJson(file) {
return JSON.parse(fs.readFileSync(file).toString());
+11 -6
View File
@@ -1,11 +1,10 @@
let fs = require("fs");
let path = require("path");
let cli = require("./cli.js");
let bundleManager = require('./bundleManager.js');
let cli = require(`./cli.js`);
let bundleManager = require(`./bundleManager.js`);
/**
* handles one display instance
* @module infoscreen/display
*/
class display {
@@ -14,13 +13,17 @@ class display {
* @param {object} dispatcher - dispatcher
* @param {object} meta - reads from config.displays
* @param {number} displayId - this display instances id
* @param {object} bundleManager
* @param {module:infoscreen3/bundleManager} bundleManager
*/
constructor(sharedIO, dispatcher, meta, displayId, bundleManager) {
cli.info("Starting display with id " + displayId + " ...");
/** @property {Array} timeoutId - holds setTimeout id's for mainLoop */
this.timeoutId = [];
/**
* @type {bundleManager|module:infoscreen3/bundleManager}
*/
this.bundleManager = bundleManager;
let self = this;
@@ -154,7 +157,7 @@ class display {
}
/**
* @returns {bundle}
* @return {bundle}
*/
getBundle() {
return this.bundleManager.getBundle(this.serverOptions.currentBundle);
@@ -244,5 +247,7 @@ class display {
}
}
/** @exports display */
/**
* @type {display}
*/
module.exports = display;
+17 -10
View File
@@ -1,19 +1,24 @@
let availableDisplays = require("../config.js").displays;
let display = require("./display.js");
let admin = require("./admin.js");
let cli = require('./cli.js');
let _bundleManager = require('./bundleManager.js');
let availableDisplays = require(`../config.js`).displays;
let display = require(`./display.js`);
let admin = require(`./admin.js`);
let cli = require(`./cli.js`);
let _bundleManager = require(`./bundleManager.js`);
let chalk = require('chalk');
let fs = require('fs');
/**
*
* @type {display[]}
*/
let screenView = [];
/** @type {admin[]} */
let adminView = [];
/**
* @exports websocket
* @param server
* @param app
* @param io
* @param dispatcher
* @return {{screenView: display[], adminView: admin[], bundleManager: bundleManager}}
*/
module.exports = function (server, app, io, dispatcher) {
console.log(chalk.green(">> ") + "InfoScreen3" + chalk.green("<<"));
@@ -50,15 +55,17 @@ module.exports = function (server, app, io, dispatcher) {
let bundleManager = new _bundleManager();
cli.info("Starting websocket backends...");
cli.info("Starting websocket backend...");
let screenId = 0;
for (let metadata of availableDisplays) {
screenView.push(new display(io, dispatcher, metadata, screenId, bundleManager));
let view = new display(io, dispatcher, metadata, screenId, bundleManager);
screenView.push(view);
adminView.push(new admin(io, dispatcher, view, screenId, bundleManager));
screenId += 1;
}
let adminView = new admin(io, dispatcher, screenView, bundleManager);
io.of("/lobby").on("connection", function (socket) {
cli.info("WS/" + socket.conn.remoteAddress + " connect");