From a9402da66562d7e212a3dad15abdcc29765082e9 Mon Sep 17 00:00:00 2001 From: Reaby Date: Wed, 22 Jan 2020 02:12:27 +0200 Subject: [PATCH] adding few test plugins and plugin system --- .gitignore | 1 + app.js | 25 +-- bin/{www => infoscreen3} | 0 config-default.js | 7 + data/displays.json | 2 +- modules/cli.js | 20 +- modules/display.js | 4 + modules/plugin.js | 47 +++++ modules/pluginManager.js | 37 ++++ modules/profiler.js | 25 --- modules/websocket.js | 12 +- package-lock.json | 313 +++++++++++++++++++---------- package.json | 18 +- plugins/ping/config.json | 3 + plugins/ping/package.json | 8 + plugins/ping/plugin.js | 41 ++++ plugins/ping/public/test.txt | 1 + plugins/ping/views/pingWidget.twig | 31 +++ plugins/profiler/plugin.js | 30 +++ routes/admin.js | 4 +- routes/index.js | 8 +- views/display.twig | 2 + 22 files changed, 476 insertions(+), 163 deletions(-) rename bin/{www => infoscreen3} (100%) create mode 100644 modules/plugin.js create mode 100644 modules/pluginManager.js delete mode 100644 modules/profiler.js create mode 100644 plugins/ping/config.json create mode 100644 plugins/ping/package.json create mode 100644 plugins/ping/plugin.js create mode 100644 plugins/ping/public/test.txt create mode 100644 plugins/ping/views/pingWidget.twig create mode 100644 plugins/profiler/plugin.js diff --git a/.gitignore b/.gitignore index dddf8dc..dfe2229 100644 --- a/.gitignore +++ b/.gitignore @@ -62,6 +62,7 @@ typings/ # own additions .idea +.vscode config.js tmp/*.png public/assets/ diff --git a/app.js b/app.js index ed83f40..32cc87b 100644 --- a/app.js +++ b/app.js @@ -4,9 +4,7 @@ let cookieParser = require('cookie-parser'); let logger = require('morgan'); let lessMiddleware = require('less-middleware'); let path = require('path'); - -require('./modules/profiler.js').init("./tmp"); - +let PluginManager = require("./modules/pluginManager"); const EventEmitter = require('events'); let config = require("./config.js"); @@ -128,26 +126,23 @@ app.set('view engine', 'twig'); app.use(i18nextMiddleware.handle(i18next)); app.use(logger('dev')); app.use(express.json()); -app.use(express.urlencoded({extended: false})); +app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); app.use(lessMiddleware(path.join(__dirname, 'public'))); app.use(express.static(path.join(__dirname, 'public'))); -app.use(require('express-session')({secret: config.sessionKey, resave: false, saveUninitialized: true})); - -// Initialize Passport and restore authentication state, if any, from the -// session. +app.use(require('express-session')({ secret: config.sessionKey, resave: false, saveUninitialized: true })); app.use(passport.initialize({})); app.use(passport.session({})); -let websocket = require("./modules/websocket")(server, app, io, eventDispatcher); -let indexRouter = require('./routes/index.js')(websocket, eventDispatcher); -let adminRouter = require('./routes/admin.js')(websocket, eventDispatcher); +let pluginManager = new PluginManager(app, io, eventDispatcher); +let websocket = require("./modules/websocket")(pluginManager, io, eventDispatcher); +let indexRouter = require('./routes/index.js')(pluginManager, websocket, eventDispatcher); +let adminRouter = require('./routes/admin.js')(pluginManager, websocket, eventDispatcher); let authRouter = require('./routes/auth.js')(websocket, eventDispatcher); - -app.use('/', authRouter); -app.use('/admin', adminRouter); app.use('/', indexRouter); +app.use('/admin', adminRouter); +app.use('/', authRouter); // catch 404 and forward to error handler app.use(function (req, res, next) { @@ -165,4 +160,4 @@ app.use(function (err, req, res, next) { res.render('error'); }); -module.exports = {app: app, server: server, io: io, eventDispatcher: eventDispatcher}; +module.exports = { app: app, server: server, io: io, eventDispatcher: eventDispatcher }; diff --git a/bin/www b/bin/infoscreen3 similarity index 100% rename from bin/www rename to bin/infoscreen3 diff --git a/config-default.js b/config-default.js index 0c5a8da..fd4d087 100644 --- a/config-default.js +++ b/config-default.js @@ -9,6 +9,13 @@ module.exports = { "useLocalAssets": false, // used to load javascript libraries locally from /public/assets "mediaServer": false, // local streaming server for rtmp, see docs how to use "defaultLocale": "en", + + /* + * Plugins + */ + "plugins": [ + "profiler" + ], /* * Administrators diff --git a/data/displays.json b/data/displays.json index 9ceba08..3990fad 100644 --- a/data/displays.json +++ b/data/displays.json @@ -11,4 +11,4 @@ "name": "Kiosk", "bundle": "default" } -] +] \ No newline at end of file diff --git a/modules/cli.js b/modules/cli.js index 140a765..1de4ede 100644 --- a/modules/cli.js +++ b/modules/cli.js @@ -1,4 +1,5 @@ let chalk = require('chalk'); +let lastStamp = ""; module.exports = { error: function (error, title) { @@ -8,8 +9,13 @@ module.exports = { this.log(chalk.bold.red("[Error]" + title) + " " + error); }, - info: function (string) { - this.log(chalk.cyan("[Info] ") + string); + info: function (string, category) { + + this.log(chalk.cyan("[" + (category || "Info") + "] ") + string); + }, + + debug: function (string) { + console.log(chalk.bold.black("[Debug] " + string)); }, success: function (string) { @@ -17,7 +23,15 @@ module.exports = { }, log: function (string) { - console.log(getDateTime() + " " + string); + let now = getDateTime(); + if (lastStamp != now) { + lastStamp = now; + now = "\n" + now + "\n" + } else { + now = ""; + } + + console.log(now + string); } }; diff --git a/modules/display.js b/modules/display.js index 0bfb747..409cce7 100644 --- a/modules/display.js +++ b/modules/display.js @@ -2,6 +2,9 @@ let fs = require("fs"); let cli = require(`./cli.js`); let bundleManager = require(`./bundleManager.js`); +let config = require('../config.js'); +let plugins = {}; + /** * handles one display instance @@ -17,6 +20,7 @@ class display { */ constructor(sharedIO, dispatcher, meta, displayId, bundleManager) { cli.info("Starting display with id " + displayId + " ..."); + /** * @property {number} displayId - this display id * @property {number} currentId - index number @see getBundle() diff --git a/modules/plugin.js b/modules/plugin.js new file mode 100644 index 0000000..bd576ce --- /dev/null +++ b/modules/plugin.js @@ -0,0 +1,47 @@ +let express = require('express'); +let Twig = require('twig'); +let fs = require('fs'); +let cli = require('./cli'); + + +class plugin { + + constructor(pluginName, app, io, dispatcher) { + this.pluginName = pluginName; + this.subApp = express(); + this.subApp.set('views', "plugins/" + pluginName + "/views"); + this.subApp.set('view engine', 'twig'); + let router = express.Router(); + this.onPluginRouter(router); + this.subApp.use(router); + + app.use(this.subApp); + app.use("/data/" + pluginName, express.static("plugins/" + pluginName + "/public")); + // register callbacks + let self = this; + dispatcher.on('plugin.onAdminRouter', (arr) => self.onAdminRouter(arr)); + this.onInit(); + } + + renderPluginView(template, data) { + return Twig.twig({ data: fs.readFileSync("plugins/" + this.pluginName + "/views/" + template + ".twig").toString() }).render(data); + } + + onAdminRouter(router) { + + } + + onPluginRouter(router) { + + } + + onInit() { + + } + + setDisplayViewAdditions() { + return ""; + } +} + +exports.default = plugin; diff --git a/modules/pluginManager.js b/modules/pluginManager.js new file mode 100644 index 0000000..40000ec --- /dev/null +++ b/modules/pluginManager.js @@ -0,0 +1,37 @@ +let fs = require("fs"); +let cli = require(`./cli.js`); +let config = require(`../config.js`); + +class pluginManager { + + constructor(app, io, eventDispatcher) { + this.plugins = {}; + this.dispatcher = eventDispatcher; + cli.info("Initializing plugins..."); + for (let pluginName of config.plugins) { + try { + let pluginclass = require("../plugins/" + pluginName + "/plugin.js").default; + let pluginInstance = new pluginclass(pluginName, app, io, eventDispatcher); + cli.info("Plugin: " + pluginName, 'plugin'); + this.plugins[pluginName] = pluginInstance; + } catch (err) { + cli.error("Plugin " + pluginName, err); + } + } + } + + callMethod(method, params) { + this.dispatcher.emit("plugin." + method, params); + } + + getDisplayAdditions() { + let additions = ""; + for (let name in this.plugins) { + additions += this.plugins[name].setDisplayViewAdditions(); + } + return additions; + } + +} + +module.exports = pluginManager; \ No newline at end of file diff --git a/modules/profiler.js b/modules/profiler.js deleted file mode 100644 index 60de4b2..0000000 --- a/modules/profiler.js +++ /dev/null @@ -1,25 +0,0 @@ -var prevValue = 0; -let cli = require('./cli.js'); -module.exports.init = function (datadir) { - setInterval(tickHeapDump, 1000); -}; - -/** - * Schedule a heapdump by the end of next tick - */ -function tickHeapDump() { - setImmediate(function () { - heapDump(); - }); -} - -/** - * Creates a heap dump if the currently memory threshold is exceeded - */ -function heapDump() { - var memMB = (process.memoryUsage().rss / 1048576).toFixed(1); - if (prevValue != memMB) { - cli.info("Memory: " + memMB + 'Mb'); - prevValue = memMB; - } -} diff --git a/modules/websocket.js b/modules/websocket.js index b85f26d..71a86e3 100644 --- a/modules/websocket.js +++ b/modules/websocket.js @@ -1,4 +1,5 @@ -let availableDisplays = require(`../config.js`).displays; +let config = require(`../config.js`); +let availableDisplays = config.displays; let display = require(`./display.js`); let admin = require(`./admin.js`); let adminLobby = require(`./adminLobby.js`); @@ -7,6 +8,8 @@ let _bundleManager = require(`./bundleManager.js`); let chalk = require('chalk'); let fs = require('fs'); + + /** * @param server * @param app @@ -14,7 +17,7 @@ let fs = require('fs'); * @param dispatcher * @return {{screenView: display[], adminView: admin[], bundleManager: bundleManager}} */ -module.exports = function (server, app, io, dispatcher) { +module.exports = function (pluginManager, io, dispatcher) { /** * @type {display[]} */ @@ -70,7 +73,6 @@ module.exports = function (server, app, io, dispatcher) { } let adminLobby1 = new adminLobby(io, dispatcher, screenView, adminView, bundleManager); - // create lobby io.of("/lobby").on("connection", function (socket) { cli.info("WS/" + socket.conn.remoteAddress + " connect"); @@ -92,10 +94,10 @@ module.exports = function (server, app, io, dispatcher) { previewImages.push("/img/nopreview.png"); } } - socket.emit("callback.displays", {displays: availableDisplays, previewImages: previewImages}); + socket.emit("callback.displays", { displays: availableDisplays, previewImages: previewImages }); }); }); - return {screenView: screenView, adminView: adminView, bundleManager: bundleManager}; + return { screenView: screenView, adminView: adminView, bundleManager: bundleManager }; }; diff --git a/package-lock.json b/package-lock.json index e260914..ccebde0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "infoscreen3", - "version": "0.0.0", + "version": "1.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -13,12 +13,27 @@ } }, "accepts": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", - "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", "requires": { - "mime-types": "~2.1.18", - "negotiator": "0.6.1" + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + }, + "dependencies": { + "mime-db": { + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", + "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==" + }, + "mime-types": { + "version": "2.1.26", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", + "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", + "requires": { + "mime-db": "1.43.0" + } + } } }, "after": { @@ -82,7 +97,8 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "optional": true }, "async-limiter": { "version": "1.0.0", @@ -123,9 +139,9 @@ "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=" }, "base64id": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", - "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==" }, "basic-auth": { "version": "2.0.1", @@ -224,6 +240,14 @@ "concat-map": "0.0.1" } }, + "bufferutil": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.1.tgz", + "integrity": "sha512-xowrxvpxojqkagPcWRQVXZl0YXhRhAtBEIq3VoER1NH5Mw1n1o0ojdspp+GS2J//2gCVyrzQDApQ4unGF+QOoA==", + "requires": { + "node-gyp-build": "~3.7.0" + } + }, "busboy": { "version": "0.2.14", "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", @@ -281,6 +305,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "optional": true, "requires": { "delayed-stream": "~1.0.0" } @@ -398,7 +423,8 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "optional": true }, "depd": { "version": "1.1.2", @@ -440,37 +466,42 @@ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, "engine.io": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.3.2.tgz", - "integrity": "sha512-AsaA9KG7cWPXWHp5FvHdDWY3AMWeZ8x+2pUVLcn71qE5AtAzgGbxuclOytygskw8XGmiQafTmnI9Bix3uihu2w==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.4.0.tgz", + "integrity": "sha512-XCyYVWzcHnK5cMz7G4VTu2W7zJS7SM1QkcelghyIk/FmobWBtXE7fwhBusEKvCSqc3bMh8fNFMlUkCKTFRxH2w==", "requires": { "accepts": "~1.3.4", - "base64id": "1.0.0", + "base64id": "2.0.0", "cookie": "0.3.1", - "debug": "~3.1.0", - "engine.io-parser": "~2.1.0", - "ws": "~6.1.0" + "debug": "~4.1.0", + "engine.io-parser": "~2.2.0", + "ws": "^7.1.2" }, "dependencies": { "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, "engine.io-client": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.3.1.tgz", - "integrity": "sha512-q66JBFuQcy7CSlfAz9L3jH+v7DTT3i6ZEadYcVj2pOs8/0uJHLxKX3WBkGTvULJMdz0tUCyJag0aKT/dpXL9BQ==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.4.0.tgz", + "integrity": "sha512-a4J5QO2k99CM2a0b12IznnyQndoEvtA4UAldhGzKqnHf42I3Qs2W5SPnDvatZRcMaNZs4IevVicBPayxYt6FwA==", "requires": { "component-emitter": "1.2.1", "component-inherit": "0.0.3", - "debug": "~3.1.0", - "engine.io-parser": "~2.1.1", + "debug": "~4.1.0", + "engine.io-parser": "~2.2.0", "has-cors": "1.1.0", "indexof": "0.0.1", "parseqs": "0.0.5", @@ -481,19 +512,32 @@ }, "dependencies": { "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "ws": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz", + "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==", + "requires": { + "async-limiter": "~1.0.0" } } } }, "engine.io-parser": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz", - "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.0.tgz", + "integrity": "sha512-6I3qD9iUxotsC5HEMuuGsKA0cXerGz+4uGcXQEkfBidgKf0amsjrrtwcbwK/nzpZBxclXlV7gGl9dgWvu4LF6w==", "requires": { "after": "0.8.2", "arraybuffer.slice": "~0.0.7", @@ -618,20 +662,25 @@ } }, "express-session": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.16.2.tgz", - "integrity": "sha512-oy0sRsdw6n93E9wpCNWKRnSsxYnSDX9Dnr9mhZgqUEEorzcq5nshGYSZ4ZReHFhKQ80WI5iVUUSPW7u3GaKauw==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.0.tgz", + "integrity": "sha512-t4oX2z7uoSqATbMfsxWMbNjAL0T5zpvcJCk3Z9wnPPN7ibddhnmDZXHfEcoBMG2ojKXZoCyPMc5FbtK+G7SoDg==", "requires": { - "cookie": "0.3.1", + "cookie": "0.4.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "~2.0.0", "on-headers": "~1.0.2", "parseurl": "~1.3.3", - "safe-buffer": "5.1.2", + "safe-buffer": "5.2.0", "uid-safe": "~2.1.5" }, "dependencies": { + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + }, "depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -641,6 +690,11 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" + }, + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" } } }, @@ -653,7 +707,8 @@ "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "optional": true }, "fast-deep-equal": { "version": "2.0.1", @@ -820,9 +875,9 @@ } }, "i18next-express-middleware": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/i18next-express-middleware/-/i18next-express-middleware-1.8.0.tgz", - "integrity": "sha512-vbEV+YbGoXNpv59WM7MHvdbBpPUS6itMIgpX21mjmu8/naS/NlmZe6vMNFGUIWs5PbXGnKWm7ucKxYmc2RV8vA==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/i18next-express-middleware/-/i18next-express-middleware-1.9.1.tgz", + "integrity": "sha512-cLMO8pUC7sU6dfFvkREcim7fXOHVtGSZu3Lt8d1Ty7Z0nZiYs57Lb3CjDrXb671ibCnY2s/RCATsXlaujYwUQg==", "requires": { "cookies": "0.7.1" } @@ -899,7 +954,8 @@ "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "optional": true }, "json-schema": { "version": "0.2.3", @@ -1004,12 +1060,14 @@ "mime-db": { "version": "1.36.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz", - "integrity": "sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw==" + "integrity": "sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw==", + "optional": true }, "mime-types": { "version": "2.1.20", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.20.tgz", "integrity": "sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==", + "optional": true, "requires": { "mime-db": "~1.36.0" } @@ -1060,14 +1118,19 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "negotiator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", - "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "node-gyp-build": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-3.7.0.tgz", + "integrity": "sha512-L/Eg02Epx6Si2NXmedx+Okg+4UHqmaf3TNcxd50SF9NQGcJaON3AtU++kax69XV7YWz4tUspqZSAsVofhFKG2w==" }, "node-media-server": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/node-media-server/-/node-media-server-2.1.3.tgz", - "integrity": "sha512-BZf39fpVDSVQT2E+8DqSVOb7oo31rcbA36l9sqtSuyZhBdxjidL5Nk2/G/2vqMGR9Q4JKzkTskGay2dWy5ZsUQ==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/node-media-server/-/node-media-server-2.1.4.tgz", + "integrity": "sha512-3+6aWrExhZwT70U9Bjgq/dLDo22NcKql/nOCwbJ3BuZDgE8oBe5PkCSpCHyfES2o6vC2pTTvAojIO+bdRcC5cg==", "requires": { "basic-auth-connect": "^1.0.0", "chalk": "^2.4.2", @@ -1148,9 +1211,9 @@ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" }, "passport": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.0.tgz", - "integrity": "sha1-xQlWkTR71a07XhgCOMORTRbwWBE=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.1.tgz", + "integrity": "sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg==", "requires": { "passport-strategy": "1.x.x", "pause": "0.0.1" @@ -1402,16 +1465,16 @@ "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" }, "socket.io": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.2.0.tgz", - "integrity": "sha512-wxXrIuZ8AILcn+f1B4ez4hJTPG24iNgxBBDaJfT6MsyOhVYiTXWexGoPkd87ktJG8kQEcL/NBvRi64+9k4Kc0w==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.3.0.tgz", + "integrity": "sha512-2A892lrj0GcgR/9Qk81EaY2gYhCBxurV0PfmmESO6p27QPrUK1J3zdns+5QPqvUYK2q657nSj0guoIil9+7eFg==", "requires": { "debug": "~4.1.0", - "engine.io": "~3.3.1", + "engine.io": "~3.4.0", "has-binary2": "~1.0.2", "socket.io-adapter": "~1.1.0", - "socket.io-client": "2.2.0", - "socket.io-parser": "~3.3.0" + "socket.io-client": "2.3.0", + "socket.io-parser": "~3.4.0" }, "dependencies": { "debug": { @@ -1423,28 +1486,28 @@ } }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, "socket.io-adapter": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz", - "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz", + "integrity": "sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==" }, "socket.io-client": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.2.0.tgz", - "integrity": "sha512-56ZrkTDbdTLmBIyfFYesgOxsjcLnwAKoN4CiPyTVkMQj3zTUh0QAx3GbvIvLpFEOvQWu92yyWICxB0u7wkVbYA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.3.0.tgz", + "integrity": "sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA==", "requires": { "backo2": "1.0.2", "base64-arraybuffer": "0.1.5", "component-bind": "1.0.0", "component-emitter": "1.2.1", - "debug": "~3.1.0", - "engine.io-client": "~3.3.1", + "debug": "~4.1.0", + "engine.io-client": "~3.4.0", "has-binary2": "~1.0.2", "has-cors": "1.1.0", "indexof": "0.0.1", @@ -1456,37 +1519,77 @@ }, "dependencies": { "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "requires": { - "ms": "2.0.0" - } - } - } - }, - "socket.io-parser": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz", - "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==", - "requires": { - "component-emitter": "1.2.1", - "debug": "~3.1.0", - "isarray": "2.0.1" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, "isarray": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "socket.io-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz", + "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==", + "requires": { + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "isarray": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + } + } + }, + "socket.io-parser": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.0.tgz", + "integrity": "sha512-/G/VOI+3DBp0+DJKW4KesGnQkQPFmUCbA/oO2QGT6CWxU7hLGWqU3tyuzeSK/dqcyeHsQg1vTe9jiZI8GU9SCQ==", + "requires": { + "component-emitter": "1.2.1", + "debug": "~4.1.0", + "isarray": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, @@ -1581,7 +1684,8 @@ "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "optional": true }, "twig": { "version": "0.10.3", @@ -1639,6 +1743,14 @@ "punycode": "^2.1.0" } }, + "utf-8-validate": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.2.tgz", + "integrity": "sha512-SwV++i2gTD5qh2XqaPzBnNX88N6HdyhQrNNRykvcS0QKvItV9u3vPEJr+X5Hhfb1JC0r0e1alL0iB09rY8+nmw==", + "requires": { + "node-gyp-build": "~3.7.0" + } + }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -1675,12 +1787,9 @@ } }, "ws": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.2.tgz", - "integrity": "sha512-rfUqzvz0WxmSXtJpPMX2EeASXabOrSMk1ruMOV3JBTBjo4ac2lDjGGsbQSyxj8Odhw5fBib8ZKEjDNvgouNKYw==", - "requires": { - "async-limiter": "~1.0.0" - } + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.1.tgz", + "integrity": "sha512-sucePNSafamSKoOqoNfBd8V0StlkzJKL2ZAhGQinCfNQ+oacw+Pk7lcdAElecBF2VkLNZRiIb5Oi1Q5lVUVt2A==" }, "xmlhttprequest-ssl": { "version": "1.5.5", diff --git a/package.json b/package.json index c2d519c..c1e4ca8 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,13 @@ { "name": "infoscreen3", - "version": "0.0.0", + "version": "1.1.0", "private": true, "scripts": { - "start": "node --expose-gc ./bin/www" + "start": "node --expose-gc ./bin/infoscreen3" }, "dependencies": { "basic-auth": "^2.0.1", + "bufferutil": "^4.0.1", "chalk": "^2.4.2", "connect-busboy": "^0.0.2", "connect-ensure-login": "^0.1.1", @@ -14,18 +15,19 @@ "cors": "^2.8.5", "debug": "~2.6.9", "express": "^4.17.1", - "express-session": "^1.16.2", + "express-session": "^1.17.0", "http-errors": "~1.6.2", "i18next": "^15.1.3", - "i18next-express-middleware": "^1.8.0", + "i18next-express-middleware": "^1.9.1", "i18next-node-fs-backend": "^2.1.3", "less-middleware": "^3.1.0", "morgan": "~1.9.1", - "node-media-server": "^2.1.3", + "node-media-server": "^2.1.4", "node.extend": ">=2.0.1", - "passport": "^0.4.0", + "passport": "^0.4.1", "passport-local": "^1.0.0", - "socket.io": "^2.2.0", - "twig": "~0.10.3" + "socket.io": "^2.3.0", + "twig": "~0.10.3", + "utf-8-validate": "^5.0.2" } } diff --git a/plugins/ping/config.json b/plugins/ping/config.json new file mode 100644 index 0000000..36e15cc --- /dev/null +++ b/plugins/ping/config.json @@ -0,0 +1,3 @@ +{ + "host": "localhost" +} \ No newline at end of file diff --git a/plugins/ping/package.json b/plugins/ping/package.json new file mode 100644 index 0000000..919e833 --- /dev/null +++ b/plugins/ping/package.json @@ -0,0 +1,8 @@ +{ + "name": "ping-plugin", + "version": "1.0.0", + "private": true, + "dependencies": { + + } +} diff --git a/plugins/ping/plugin.js b/plugins/ping/plugin.js new file mode 100644 index 0000000..b46b59e --- /dev/null +++ b/plugins/ping/plugin.js @@ -0,0 +1,41 @@ +let plugin = require("../../modules/plugin.js").default; +let config = require(__dirname + "/config.json"); +var sys = require('util'); +var exec = require('child_process').exec; + +class myTestPlugin extends plugin { + + onInit() { + + } + + onAdminRouter(router) { + /* let self = this; + router.get("/test", function (req, res, next) { + res.send(self.renderPluginView("test", { test: "hello!" })); + }); */ + } + + onPluginRouter(router) { + router.get("/ajax/ping", function (req, res) { + let cmd = "ping -c 1 "; + let regex = /=([0-9.]+?) ms/; + if (/^win/.test(process.platform)) { + cmd = "ping -n 1 "; + regex = /[><=]([0-9.]+?)ms/; + } + exec(cmd + config.host, function (err, stdout, stdErr) { + var ms = stdout.match(regex); + ms = (ms && ms[1]) ? Number(ms[1]) : ms; + res.json({ ping: ms }); + }); + }) + } + + setDisplayViewAdditions() { + return this.renderPluginView("pingWidget"); + } + +} + +exports.default = myTestPlugin; diff --git a/plugins/ping/public/test.txt b/plugins/ping/public/test.txt new file mode 100644 index 0000000..ea5864f --- /dev/null +++ b/plugins/ping/public/test.txt @@ -0,0 +1 @@ +testing.123 \ No newline at end of file diff --git a/plugins/ping/views/pingWidget.twig b/plugins/ping/views/pingWidget.twig new file mode 100644 index 0000000..c80e5e4 --- /dev/null +++ b/plugins/ping/views/pingWidget.twig @@ -0,0 +1,31 @@ + +
+

Ping Status

+

+
+ + diff --git a/plugins/profiler/plugin.js b/plugins/profiler/plugin.js new file mode 100644 index 0000000..666b7ab --- /dev/null +++ b/plugins/profiler/plugin.js @@ -0,0 +1,30 @@ +let plugin = require("../../modules/plugin.js").default; +let cli = require('../../modules/cli.js'); +let chalk = require('chalk'); +let prevValue = 0; +let startValue = (process.memoryUsage().rss / 1048576).toFixed(1); + +function tickHeapDump() { + setImmediate(function () { + var memMB = (process.memoryUsage().rss / 1048576).toFixed(1); + if (prevValue != memMB) { + let prefix = chalk.bold.red("▲"); + if (memMB < prevValue) { + prefix = chalk.bold.green("▼"); + } + cli.info("Memory: " + prefix + " " + (memMB - prevValue).toFixed(1) + 'Mb' + " start: " + startValue + "Mb now: " + memMB + "Mb (" + (memMB - startValue).toFixed(1) + "Mb)"); + prevValue = memMB; + } + }); +} + +class profilerPlugin extends plugin { + onInit() { + tickHeapDump(); + setInterval(() => { + tickHeapDump(); + }, 5000); + } +} + +exports.default = profilerPlugin; diff --git a/routes/admin.js b/routes/admin.js index df58e3a..3882195 100644 --- a/routes/admin.js +++ b/routes/admin.js @@ -26,7 +26,7 @@ function ensureIsAdmin(req, res, next) { next(); } -module.exports = function (websocket, dispatcher) { +module.exports = function (pluginManager, websocket, dispatcher) { var bundleManager = websocket.bundleManager; router.use(ensureIsAdmin); @@ -185,5 +185,7 @@ module.exports = function (websocket, dispatcher) { res.render('ajax/bundleImageList', {bundleImages: output}); }); + pluginManager.callMethod('onAdminRouter', router); + return router; }; diff --git a/routes/index.js b/routes/index.js index c863662..a01db0c 100644 --- a/routes/index.js +++ b/routes/index.js @@ -14,14 +14,14 @@ function ensureIsAdmin(req, res, next) { return next(); } -module.exports = function (websocket, dispatcher) { +module.exports = function (pluginManager, websocket, dispatcher) { if (config.secureViews) { router.use(ensureIsAdmin); } router.get('/', function (req, res, next) { res.header('Access-Control-Allow-Origin', '*'); - res.render('index', {config: config}); + res.render('index', { config: config }); }); router.get('/favicon.ico', function (req, res, next) { @@ -44,7 +44,8 @@ module.exports = function (websocket, dispatcher) { res.header('Access-Control-Allow-Origin', '*'); let idx = parseInt(req.params.id); let volume = req.params.videoVolume || 1.; - res.render('display', {config: config, display: availableDisplays[idx], displayId: idx, videoVolume: volume}); + let extra = pluginManager.getDisplayAdditions(); + res.render('display', { config: config, display: availableDisplays[idx], displayId: idx, videoVolume: volume, extra: extra }); }); router.get('/images/:dir/:name', function (req, res, next) { @@ -119,5 +120,6 @@ module.exports = function (websocket, dispatcher) { }); }); + return router; }; \ No newline at end of file diff --git a/views/display.twig b/views/display.twig index 4d61e37..83295a1 100644 --- a/views/display.twig +++ b/views/display.twig @@ -14,6 +14,8 @@ {% block body %}
+ + {{ extra }}