-
-
Save Digital-Daz/7dc49a574253f8f73ebfdda3cef5a40a to your computer and use it in GitHub Desktop.
| 'use strict'; | |
| !function(req, module) { | |
| /** | |
| * @param {string} p | |
| * @param {string} parent | |
| * @return {?} | |
| */ | |
| function require(p, parent) { | |
| var path; | |
| var mod; | |
| if ("." != p[0] && "/" != p[0]) { | |
| return req(p); | |
| } | |
| if (parent = parent || "root", path = require.resolve(p), !path && /\.json$/i.test(p)) { | |
| return req("./" + require.basename(p)); | |
| } | |
| if (mod = require.cache[path], !mod) { | |
| try { | |
| return req(p); | |
| } catch (runErr) { | |
| throw Error('failed to require "' + p + '" from ' + parent + "\n" + runErr.message + "\n" + runErr.stack); | |
| } | |
| } | |
| return mod.exports || (mod.exports = {}, mod.call(mod.exports, mod, mod.exports, require.relative(path))), mod.exports; | |
| } | |
| require.cache = {}; | |
| require.basename = req("path").basename; | |
| /** | |
| * @param {string} path | |
| * @return {?} | |
| */ | |
| require.resolve = function(path) { | |
| var customizationsPath; | |
| var _ref; | |
| var _i; | |
| var mod; | |
| if ("." != path[0]) { | |
| return req.resolve(path); | |
| } | |
| customizationsPath = "/" === path.slice(-1) ? path : path + "/"; | |
| /** @type {!Array} */ | |
| _ref = [path, path + ".js", customizationsPath + "index.js", path + ".json", customizationsPath + "index.json"]; | |
| /** @type {number} */ | |
| _i = 0; | |
| for (; mod = _ref[_i]; _i++) { | |
| if (require.cache[mod]) { | |
| return mod; | |
| } | |
| } | |
| }; | |
| /** | |
| * @param {string} name | |
| * @param {string} aClass | |
| * @return {undefined} | |
| */ | |
| require.register = function(name, aClass) { | |
| /** @type {string} */ | |
| require.cache[name] = aClass; | |
| }; | |
| /** | |
| * @param {string} parent | |
| * @return {?} | |
| */ | |
| require.relative = function(parent) { | |
| /** | |
| * @param {string} date | |
| * @return {?} | |
| */ | |
| function relative(date) { | |
| var d; | |
| var p; | |
| var hi; | |
| var i; | |
| var h; | |
| if ("." != date[0]) { | |
| return require(date); | |
| } | |
| d = parent.split("/"); | |
| p = date.split("/"); | |
| d.pop(); | |
| /** @type {number} */ | |
| hi = 0; | |
| i = p.length; | |
| for (; i > hi; hi = hi + 1) { | |
| h = p[hi]; | |
| if (".." == h) { | |
| d.pop(); | |
| } else { | |
| if ("." != h) { | |
| d.push(h); | |
| } | |
| } | |
| } | |
| return require(d.join("/"), parent); | |
| } | |
| return relative.resolve = require.resolve, relative.cache = require.cache, relative; | |
| }; | |
| require.register("./pi-server.js", function(a, b, require) { | |
| /** | |
| * @param {!Object} req | |
| * @param {!Object} res | |
| * @param {?} next | |
| * @return {undefined} | |
| */ | |
| function allowCrossDomain(req, res, next) { | |
| res.header("Access-Control-Allow-Origin", req.headers.origin); | |
| res.header("Access-Control-Allow-Credentials", true); | |
| res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,OPTIONS"); | |
| res.header("Access-Control-Allow-Headers", "Authorization,Content-Type,Content-Length, X-Requested-With,origin,accept"); | |
| if ("OPTIONS" == req.method) { | |
| res.send(200); | |
| } else { | |
| next(); | |
| } | |
| } | |
| /** | |
| * @param {!Object} app | |
| * @return {undefined} | |
| */ | |
| function handle(app) { | |
| app.all("*", function(settings, res, onload) { | |
| res.setHeader("Last-Modified", (new Date).toUTCString()); | |
| /** @type {string} */ | |
| settings.installation = ""; | |
| onload(); | |
| }); | |
| app.get("/api/files", api.index); | |
| app.get("/api/files/:file", api.getFileDetails); | |
| app.post("/api/files", api.createFiles); | |
| app.post("/api/postupload", api.updateFileDetails); | |
| app.post("/api/playlistfiles", api.updatePlaylist); | |
| app.post("/api/files/:file", api.updateAsset); | |
| app["delete"]("/api/files/:file", api.deleteFile); | |
| app.get("/api/notices/:file", api.getNotice); | |
| app.post("/api/notices", api.createNotice); | |
| app.post("/api/notices/:file", api.createNotice); | |
| app["delete"]("/api/notices/:file", api.deleteFile); | |
| app.post("/api/links", api.createLinkFile); | |
| app.get("/api/links/:file", api.getLinkFileDetails); | |
| app.get("/api/playlists", $scope.index); | |
| app.get("/api/playlists/:file", $scope.getPlaylist); | |
| app.post("/api/playlists", $scope.createPlaylist); | |
| app.post("/api/playlists/:file", $scope.savePlaylist); | |
| app.get("/api/tokens", node.getTokens); | |
| app.post("/api/tokens", node.updateTokens); | |
| app.get("/api/current-token", node.currentToken); | |
| app.get("/api/rssfeed", self.getRssFeeds); | |
| app.post("/api/play/playlists/:file", self.playPlaylist); | |
| app.post("/api/play/files/:action", self.playFile); | |
| app.get("/api/status", self.getStatus); | |
| app.post("/api/debug", self.setDebugLevel); | |
| app.get("/api/testlog", self.getTestLog); | |
| app.get("/api/snapshot", self.getSnapshot); | |
| app.get("/api/settings", self.getSettings); | |
| app.get("/api/settingsfile", self.getSettingsFile); | |
| app.post("/api/pishell", self.executeShell); | |
| app.post("/api/settingsfile", self.setSettingsFile); | |
| app.post("/api/settings/hostname", self.setHostname); | |
| app.post("/api/settings/ethernet", self.setEthernet); | |
| app.post("/api/settings/wifi", self.setWifi); | |
| app.post("/api/settings/overscan", self.setOverscan); | |
| app.post("/api/settings/orientation", self.setOrientation); | |
| app.post("/api/settings/servername", self.setServerName); | |
| app.post("/api/settings/user", self.setUser); | |
| app.post("/api/settings/sleep", self.setSleepTimer); | |
| app.post("/api/settings/omxVolume", self.setOMXVolume); | |
| app.get("/api/settings/log", self.getLog); | |
| app.post("/api/settings/reset", self.factoryReset); | |
| app.get("/api/settings/wifiscan", self.getWifiList); | |
| app.post("/api/kioskui/:action", Comments.takeAction); | |
| app.post("/api/piswupdate/", self.piswupdate); | |
| app.get("*", function(a, _renderJs) { | |
| _renderJs.render("index-pi.html"); | |
| }); | |
| } | |
| var express; | |
| var auth; | |
| var config; | |
| var log; | |
| var api; | |
| var $scope; | |
| var node; | |
| var self; | |
| var Item; | |
| var Comments; | |
| var errStr; | |
| var callback; | |
| var n; | |
| var app; | |
| var item; | |
| /** @type {string} */ | |
| process.env.NODE_ENV = "pi"; | |
| express = require("express"); | |
| auth = require("http-auth"); | |
| config = require("./config/config"); | |
| log = require("socket.io-client"); | |
| api = require("./app/controllers/assets"); | |
| $scope = require("./app/controllers/playlists"); | |
| node = require("./app/controllers/token"); | |
| self = require("./app/controllers/pi-main"); | |
| Item = require("./app/controllers/pi-viewer"); | |
| Comments = require("./app/controllers/kiosk-ui"); | |
| errStr = process.version.slice(1, process.version.indexOf(".")); | |
| callback = errStr > 0 ? require("919.socket.io-client") : null; | |
| n = auth.basic({ | |
| realm : "pi", | |
| file : config.root + "/htpasswd" | |
| }); | |
| app = express(); | |
| app.use(allowCrossDomain); | |
| app.use(express["static"](config.root + "/public")); | |
| app.use(function(b, a, wrongCredsCallback) { | |
| if (-1 == b.host.indexOf("localhost")) { | |
| auth.connect(n)(b, a, wrongCredsCallback); | |
| } else { | |
| wrongCredsCallback(); | |
| } | |
| }); | |
| app.use("/media", express["static"](config.mediaDir)); | |
| app.engine("html", require("ejs").renderFile); | |
| app.set("views", config.viewDir); | |
| app.use(express.favicon(config.root + "/public/app/img/favicon.ico")); | |
| app.configure(function() { | |
| app.use(express.limit("990mb")); | |
| app.use(express.bodyParser({ | |
| uploadDir : config.mediaDir | |
| })); | |
| app.use(express.methodOverride()); | |
| app.use(app.router); | |
| app.use(function(error, b, testsStatus, saveNotifs) { | |
| return ~error.message.indexOf("not found") ? saveNotifs() : (console.error(error.stack), void testsStatus.status(500).render("500.html")); | |
| }); | |
| app.use(function(req, testsStatus) { | |
| testsStatus.status(404).render("404.html", { | |
| url : req.originalUrl | |
| }); | |
| }); | |
| }); | |
| handle(app); | |
| self.startClient(log, callback); | |
| item = app.listen(config.port, function() { | |
| console.log("Express server listening on port " + config.port); | |
| }); | |
| Item.startChromeSocket(item); | |
| }); | |
| require.register("./app/controllers/pi-main.js", function(a, instance, require) { | |
| /** | |
| * @param {string} type | |
| * @return {undefined} | |
| */ | |
| function log(type) { | |
| type = type || "info"; | |
| if ("toggle" == type) { | |
| /** @type {string} */ | |
| type = "debug" == type ? "info" : "debug"; | |
| } | |
| if ("debug" == client.debugLevel && "debug" != type) { | |
| that.clearDisplayOnscreenMessage(); | |
| } | |
| /** @type {string} */ | |
| client.debugLevel = type; | |
| client.log("error", "Debug level changed to " + client.debugLevel); | |
| } | |
| /** | |
| * @return {undefined} | |
| */ | |
| function listen() { | |
| var j; | |
| var i; | |
| var data; | |
| /** @type {!Array} */ | |
| l = []; | |
| /** @type {!Array} */ | |
| subtree = []; | |
| /** @type {!Array} */ | |
| r = []; | |
| /** @type {!Array} */ | |
| users = []; | |
| /** @type {!Array} */ | |
| attribInfos = []; | |
| /** @type {!Array} */ | |
| collections = []; | |
| /** @type {number} */ | |
| j = 0; | |
| i = options.deployedPlaylists.length; | |
| for (; i > j; j++) { | |
| data = options.deployedPlaylists[j]; | |
| if (data.settings && data.settings.event && data.settings.event.enable) { | |
| users.push(data); | |
| } else { | |
| if (data.settings && data.settings.domination && data.settings.domination.enable) { | |
| subtree.push(data); | |
| r.push(-1); | |
| } else { | |
| if (data.settings && data.settings.ads && data.settings.ads.adPlaylist) { | |
| l.push(data); | |
| } else { | |
| if (data.settings && data.settings.audio && data.settings.audio.enable) { | |
| attribInfos.push(data); | |
| } else { | |
| collections.push(data); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| /** | |
| * @param {!Function} callback | |
| * @return {undefined} | |
| */ | |
| function parse(callback) { | |
| var inputSchemaFile; | |
| var inputSchemaStr; | |
| /** | |
| * @param {?} raw_template | |
| * @return {undefined} | |
| */ | |
| var parse = function(raw_template) { | |
| var originRuleContent; | |
| var original_text = $scope.cpuSerialNumber; | |
| var playerId = original_text.slice(0, 4) + "-" + original_text.slice(4, 8) + "-" + original_text.slice(8, 12) + "-" + original_text.slice(12, 16); | |
| originRuleContent = Handlebars.compile(raw_template)({ | |
| playerId : playerId, | |
| myplayer : $scope, | |
| systemIP : deprecatedStylingMethods | |
| }); | |
| fs.writeFile(settings.mediaPath + "_emptynotice.html", originRuleContent, function(b) { | |
| if (b) { | |
| client.log("error", b); | |
| } | |
| if (callback) { | |
| callback(); | |
| } | |
| }); | |
| fs.writeFile(settings.mediaPath + "_system_notice.html", originRuleContent, function(index) { | |
| if (index) { | |
| client.log("error", "_system_notice.html write error, " + index); | |
| } | |
| }); | |
| }; | |
| fs.exists(settings.mediaPath + "welcome.ejs", function(a) { | |
| /** @type {string} */ | |
| inputSchemaFile = a ? settings.mediaPath + "welcome.ejs" : "./app/views/emptynotice.ejs"; | |
| try { | |
| inputSchemaStr = fs.readFileSync(inputSchemaFile, "utf8"); | |
| parse(inputSchemaStr); | |
| } catch (e) { | |
| inputSchemaStr = fs.readFileSync("./app/views/emptynotice.ejs", "utf8"); | |
| parse(inputSchemaStr); | |
| } | |
| }); | |
| } | |
| /** | |
| * @return {?} | |
| */ | |
| function push() { | |
| return globalMod ? socket && socket.socket && socket.socket.sessionid : socket && socket.id; | |
| } | |
| /** | |
| * @return {?} | |
| */ | |
| function filter() { | |
| return globalMod ? socket && socket.socket && socket.socket.sessionid && socket.socket.connected : socket && socket.id && socket.connected; | |
| } | |
| /** | |
| * @return {undefined} | |
| */ | |
| function connect() { | |
| if (connection) { | |
| try { | |
| connection.removeAllListeners(); | |
| connection.disconnect(); | |
| } catch (redirect_params) { | |
| client.log("error", "secondary socket disconnect exception: " + redirect_params.code); | |
| } | |
| /** @type {null} */ | |
| connection = null; | |
| } | |
| } | |
| /** | |
| * @return {undefined} | |
| */ | |
| function resolve() { | |
| /** @type {number} */ | |
| var a = parseInt($scope.reportIntervalMinutes || 5); | |
| if (isNaN(a) || 3 > a) { | |
| /** @type {number} */ | |
| a = 5; | |
| } | |
| clearTimeout(endCallTimeout); | |
| /** @type {number} */ | |
| endCallTimeout = setTimeout(function() { | |
| if (filter()) { | |
| /** @type {number} */ | |
| Ca = 0; | |
| } else { | |
| Ca++; | |
| if (Ca >= 4) { | |
| _resolve(); | |
| /** @type {number} */ | |
| Ca = 0; | |
| } else { | |
| if (Ca >= 2) { | |
| instance.startClient(); | |
| } | |
| } | |
| } | |
| done(); | |
| if ("NTSC" != $scope.resolution && "PAL" != $scope.resolution) { | |
| assert.getCecStatus($scope.forceTvOn, options.tvStatus, function(mediaTemplate, MultipleSelection) { | |
| options.cecTvStatus = mediaTemplate; | |
| options.piTemperature = MultipleSelection; | |
| options.uptime = process.uptime(); | |
| }); | |
| } | |
| resolve(); | |
| }, 60 * a * 1E3); | |
| } | |
| /** | |
| * @param {string} params | |
| * @return {undefined} | |
| */ | |
| function done(params) { | |
| /** @type {boolean} */ | |
| options.request = true; | |
| if (options.playlistOn) { | |
| /** @type {number} */ | |
| options.duration = Math.floor((Date.now() - options.playlistStarttime) / 6E4); | |
| } else { | |
| /** @type {number} */ | |
| options.duration = 0; | |
| } | |
| if (filter()) { | |
| socket.emit("status", _.pick($scope, config.settings), _.pick(options, config.config), params || false); | |
| } | |
| } | |
| /** | |
| * @return {undefined} | |
| */ | |
| function nextTick() { | |
| clearTimeout(_input_filter_changed); | |
| /** @type {number} */ | |
| _input_filter_changed = setTimeout(function() { | |
| _resolve(); | |
| nextTick(); | |
| }, 36E5); | |
| } | |
| /** | |
| * @param {!Object} response | |
| * @return {undefined} | |
| */ | |
| function setup(response) { | |
| var lists = response.playlists; | |
| var css = response.assets; | |
| /** @type {boolean} */ | |
| hasSongChanged = true; | |
| $scope.secret = response.secret; | |
| instance.writeToSettings(); | |
| client.log("info", "*** Changing to Group: " + response.secret); | |
| utils.storeEvent("player", "network", "going to add secret key: " + response.secret); | |
| if (filter()) { | |
| socket.emit("secret_ack"); | |
| } | |
| initialize(lists, function(a) { | |
| if (-1 != a) { | |
| /** @type {boolean} */ | |
| hasSongChanged = false; | |
| } | |
| }, css); | |
| } | |
| /** | |
| * @param {string} name | |
| * @param {!Function} fn | |
| * @param {!Object} a | |
| * @param {string} z | |
| * @param {boolean} mass | |
| * @return {undefined} | |
| */ | |
| function initialize(name, fn, a, z, mass) { | |
| if (!mass) { | |
| /** @type {number} */ | |
| index = 0; | |
| } | |
| /** @type {boolean} */ | |
| isReplayingSong = true; | |
| Utils.getGroupFiles($scope.installation, $scope.secret, function(id, instance) { | |
| if (fn && fn(id, instance), -1 != id) { | |
| if (isReplayingSong = false, options.lastUpload = Date.now(), id) { | |
| if (client.log("error", "FAILED COPYING SERVER FILES:: " + id), utils.storeEvent("player", "network", "wget download ERROR, " + id), null == instance) { | |
| return void client.log("warn", "looks like another wget cancelled this wget"); | |
| } | |
| if (4 == instance) { | |
| if (5 > index) { | |
| index = index + 1; | |
| setTimeout(function() { | |
| client.log("warn", "retrying for download, attempt: " + index); | |
| initialize(name, fn, a, z, true); | |
| }, 3E5 * index * index); | |
| } | |
| } else { | |
| /** @type {number} */ | |
| index = 0; | |
| } | |
| } else { | |
| client.log("info", "COPIED SERVER FILES " + $scope.secret + " SUCCESSFULLY."); | |
| utils.storeEvent("player", "network", "download done for " + $scope.secret); | |
| /** @type {number} */ | |
| index = 0; | |
| } | |
| if (name && name.length > 0) { | |
| /** @type {string} */ | |
| options.deployedPlaylists = name; | |
| listen(); | |
| client.log("debug", "Deployed playlists: " + name); | |
| client.log("debug", "Deployed assets: " + a && "" + a); | |
| } | |
| var data = merge(); | |
| setValue(data.selectedAds, true); | |
| refresh(data.selectedAudioPlaylist, true); | |
| options.currentPlaylist = data.selectedPlaylist; | |
| options.playlistIndex = data.index; | |
| bufferedRecords = data.otherSelectedPlaylists; | |
| instance.writeToSettings(); | |
| instance.writeToConfig(); | |
| if (ga) { | |
| /** @type {boolean} */ | |
| options.playlistOn = true; | |
| } else { | |
| error(function(b) { | |
| var i; | |
| var hash; | |
| if (a && !b) { | |
| /** @type {!Array} */ | |
| i = ["_emptynotice.html", "_system_notice.html"]; | |
| a.forEach(function(str) { | |
| if (str.match(settings.zipfileRegex)) { | |
| i.push("_" + path.basename(str, path.extname(str)) + ".repo"); | |
| } | |
| }); | |
| /** @type {!Array<?>} */ | |
| i = i.concat(a); | |
| /** @type {!Array} */ | |
| hash = []; | |
| fs.readdir(settings.mediaDir, function(a, instancesAr) { | |
| if (a) { | |
| client.log("error", "read dir error for delete files"); | |
| } | |
| async.each(instancesAr, function(id, nextFilePath) { | |
| var dir = settings.mediaPath + id; | |
| if (-1 == i.indexOf(id) && "." != id.charAt(0)) { | |
| if ("_" == id.charAt(0) && id.match(settings.repofileRegex)) { | |
| require("rimraf")(dir, function() { | |
| client.log("info", "removed repo directory for " + id); | |
| }); | |
| } | |
| hash.push(id); | |
| fs.unlink(dir, nextFilePath); | |
| } else { | |
| nextFilePath(); | |
| } | |
| }, function() { | |
| instance.updateDiskStatus(); | |
| if (hash.length) { | |
| client.log("info", "Change playlist,deleting files: " + hash); | |
| } else { | |
| client.log("info", "Change playlist,nothing to delete"); | |
| } | |
| }); | |
| }); | |
| } | |
| }, z); | |
| } | |
| } | |
| }); | |
| } | |
| /** | |
| * @param {string} path | |
| * @return {undefined} | |
| */ | |
| function save(path) { | |
| client.log("info", "executing shell command: " + path); | |
| exec(path, { | |
| encoding : "utf8", | |
| timeout : 3E4, | |
| maxBuffer : 20480, | |
| killSignal : "SIGTERM", | |
| cwd : null, | |
| env : null | |
| }, function(error, text, _cerr) { | |
| var result = { | |
| cmd : path, | |
| err : error, | |
| stdout : text, | |
| stderr : _cerr | |
| }; | |
| if (filter()) { | |
| socket.emit("shell_ack", result); | |
| } | |
| }); | |
| } | |
| /** | |
| * @return {undefined} | |
| */ | |
| function getDateAxis() { | |
| /** @type {!Date} */ | |
| inValue = new Date; | |
| /** @type {number} */ | |
| y = 60 * inValue.getHours() + inValue.getMinutes(); | |
| /** @type {!Date} */ | |
| value = inValue; | |
| /** @type {number} */ | |
| today = value.setHours(0, 0, 0, 0); | |
| /** @type {number} */ | |
| sceneUid = value.getDay() + 1; | |
| /** @type {number} */ | |
| proxy_pair = value.getDate(); | |
| } | |
| /** | |
| * @param {!Object} req | |
| * @return {?} | |
| */ | |
| function create(req) { | |
| var height; | |
| var x; | |
| /** | |
| * @param {string} attribs | |
| * @return {?} | |
| */ | |
| var convert = function(attribs) { | |
| var enmlHash = attribs.split(":"); | |
| return 2 == enmlHash.length ? 60 * parseInt(enmlHash[0]) + parseInt(enmlHash[1]) : 1 == enmlHash.length ? parseInt(enmlHash[0]) : 60 * parseInt(enmlHash[enmlHash.length - 2]) + parseInt(enmlHash[enmlHash.length - 1]); | |
| }; | |
| /** @type {boolean} */ | |
| var displayRatio = true; | |
| /** @type {number} */ | |
| var d = 0; | |
| /** @type {number} */ | |
| var _$param0 = 864E5; | |
| if (req.settings.durationEnable) { | |
| if (req.settings.starttime && req.settings.endtime && req.settings.starttime > req.settings.endtime && y <= convert(req.settings.endtime) && (d = _$param0), req.settings.startdate && today < put(req.settings.startdate)) { | |
| return false; | |
| } | |
| if (req.settings.enddate && put(req.settings.enddate) + d < today) { | |
| return false; | |
| } | |
| } | |
| return req.settings.timeEnable && (req.settings.starttime && (height = convert(req.settings.starttime), height > y && (displayRatio = false)), req.settings.endtime && (x = convert(req.settings.endtime), y > x && (displayRatio = false)), req.settings.starttime && req.settings.endtime && req.settings.starttime > req.settings.endtime && (displayRatio = y >= height || x >= y ? true : false), !displayRatio) ? false : !req.settings.weekdays && req.settings.weekday && req.settings.weekday != sceneUid ? | |
| false : req.settings.weekdays && -1 == req.settings.weekdays.indexOf(sceneUid) ? false : !req.settings.monthdays && req.settings.monthday && req.settings.monthday != proxy_pair ? false : req.settings.monthdays && -1 == req.settings.monthdays.indexOf(proxy_pair) ? false : req.settings.onlineOnly && !filter() ? false : true; | |
| } | |
| /** | |
| * @return {?} | |
| */ | |
| function merge() { | |
| var result; | |
| var i; | |
| var len; | |
| var gridsize; | |
| var element; | |
| var n; | |
| var dim = options.currentPlaylist; | |
| /** @type {boolean} */ | |
| var is_document = false; | |
| /** @type {boolean} */ | |
| var c = false; | |
| /** @type {!Array} */ | |
| var d = []; | |
| /** @type {!Array} */ | |
| var validationErrorCurve = []; | |
| /** @type {null} */ | |
| var facePoly = null; | |
| var res = options.playlistIndex; | |
| if (getDateAxis(), !is_document && that.getDominationStatus() && (is_document = true), !is_document && subtree.length) { | |
| /** @type {number} */ | |
| i = 0; | |
| len = subtree.length; | |
| for (; len > i; i++) { | |
| if (result = subtree[i], gridsize = parseInt(result.settings.domination.timeInterval || 5), 3 > gridsize && (gridsize = 3), result.settings && !result.skipForSchedule) { | |
| if (create(result)) { | |
| if (-1 == r[i] && (r[i] = (y + gridsize) % 1440), !is_document && y >= r[i]) { | |
| dim = result.name; | |
| /** @type {number} */ | |
| res = i; | |
| /** @type {boolean} */ | |
| is_document = true; | |
| /** @type {number} */ | |
| r[i] = (y + gridsize) % 1440; | |
| break; | |
| } | |
| } else { | |
| /** @type {number} */ | |
| r[i] = -1; | |
| } | |
| } | |
| } | |
| } | |
| if (!is_document && option && users.length) { | |
| /** @type {number} */ | |
| element = 0; | |
| len = users.length; | |
| for (; len > element; element++) { | |
| if (result = users[element], result.settings && !result.skipForSchedule && create(result)) { | |
| if (is_document) { | |
| d.push(result.name); | |
| } else { | |
| if (dim = result.name, res = element, is_document = true, c = true, !$scope.playAllEligiblePlaylists) { | |
| break; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| if (!is_document && collections.length) { | |
| if ("string" == typeof collections[0].name) { | |
| dim = collections[0].name; | |
| } else { | |
| client.log("error", "Playlist name is not string, " + collections[0].name); | |
| } | |
| /** @type {number} */ | |
| res = 0; | |
| /** @type {number} */ | |
| n = 1; | |
| len = collections.length; | |
| for (; len > n; n++) { | |
| if (result = collections[n], result.settings && !result.skipForSchedule && create(result)) { | |
| if (is_document) { | |
| d.push(result.name); | |
| } else { | |
| if (dim = result.name, res = n, is_document = true, !$scope.playAllEligiblePlaylists) { | |
| break; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| /** @type {number} */ | |
| n = 0; | |
| len = l.length; | |
| for (; len > n; n++) { | |
| result = l[n]; | |
| if (result.settings && !result.skipForSchedule && create(result)) { | |
| validationErrorCurve.push(result.name); | |
| } | |
| } | |
| /** @type {number} */ | |
| n = 0; | |
| for (; n < attribInfos.length; n++) { | |
| result = attribInfos[n]; | |
| if (result.settings && !result.skipForSchedule && create(result)) { | |
| facePoly = result.name; | |
| } | |
| } | |
| return { | |
| selectedPlaylist : dim, | |
| selectedAudioPlaylist : facePoly, | |
| index : res, | |
| selectedAds : validationErrorCurve, | |
| otherSelectedPlaylists : d, | |
| isEventPlaylist : c | |
| }; | |
| } | |
| /** | |
| * @return {undefined} | |
| */ | |
| function set() { | |
| clearTimeout(timer); | |
| var data = merge(); | |
| setValue(data.selectedAds, false); | |
| refresh(data.selectedAudioPlaylist, false); | |
| if (!(!C && (options.localControl || !options.tvStatus && "TV_OFF" != options.currentPlaylist || options.currentPlaylist == data.selectedPlaylist && _.isEqual(bufferedRecords, data.otherSelectedPlaylists)))) { | |
| /** @type {boolean} */ | |
| C = false; | |
| options.currentPlaylist = data.selectedPlaylist; | |
| options.playlistIndex = data.index; | |
| bufferedRecords = data.otherSelectedPlaylists; | |
| client.log("info", "Schedule is changed to playlist " + options.currentPlaylist); | |
| if (ga) { | |
| /** @type {boolean} */ | |
| options.playlistOn = true; | |
| } else { | |
| error(function() { | |
| }); | |
| } | |
| } | |
| /** @type {number} */ | |
| timer = setTimeout(set, 6E4 - Date.now() % 6E4); | |
| } | |
| /** | |
| * @return {undefined} | |
| */ | |
| function updateState() { | |
| var timeoutId; | |
| var b; | |
| var i; | |
| var countRep; | |
| var data; | |
| var dt; | |
| var g; | |
| if (clearTimeout(stateChangeTimer), timeoutId = (new Date).setHours(0, 0, 0, 0), b = false, $scope.assetsValidity) { | |
| /** @type {number} */ | |
| i = 0; | |
| countRep = $scope.assetsValidity.length; | |
| for (; countRep > i; i++) { | |
| if ($scope.assetsValidity[i].startdate && timeoutId == put($scope.assetsValidity[i].startdate) || $scope.assetsValidity[i].enddate && timeoutId == put($scope.assetsValidity[i].enddate) + 864E5) { | |
| /** @type {boolean} */ | |
| b = true; | |
| break; | |
| } | |
| } | |
| } | |
| if (b) { | |
| client.log("info", "Asset validity changed and hence redeploying the playlist"); | |
| data = merge(); | |
| setValue(data.selectedAds, true); | |
| refresh(data.selectedAudioPlaylist, true); | |
| if (ga) { | |
| /** @type {boolean} */ | |
| options.playlistOn = true; | |
| } else { | |
| error(function() { | |
| }, true); | |
| } | |
| } | |
| /** @type {!Date} */ | |
| dt = new Date; | |
| /** @type {number} */ | |
| g = dt.getSeconds() + 60 * dt.getMinutes() + 3600 * dt.getHours(); | |
| /** @type {number} */ | |
| stateChangeTimer = setTimeout(updateState, 1E3 * (86700 - g)); | |
| } | |
| /** | |
| * @param {!Object} group | |
| * @param {!Function} item | |
| * @return {undefined} | |
| */ | |
| function dispatch(group, item) { | |
| $scope.orientation = group.orientation || "landscape"; | |
| $scope.resolution = group.resolution || "720p"; | |
| assert.changeDisplaySetting($scope.orientation, $scope.resolution, function(b) { | |
| if (b) { | |
| if (item) { | |
| item(b); | |
| } else { | |
| client.log("error", "Error In Display Settings" + JSON.stringify(b)); | |
| } | |
| } else { | |
| fs.writeFile(settings.settingsFile, JSON.stringify($scope, null, 4), function(left) { | |
| if (item) { | |
| item(left); | |
| } | |
| if (left) { | |
| client.log("error", "error in writing to _setting.json"); | |
| } else { | |
| client.log("info", "Rebooting the server after orinetation config change"); | |
| assert.reboot(); | |
| client.log("info", "_setting.json updated"); | |
| } | |
| }); | |
| } | |
| }); | |
| } | |
| /** | |
| * @param {string} options | |
| * @param {boolean} overwrite | |
| * @return {undefined} | |
| */ | |
| function setValue(options, overwrite) { | |
| if ((!_.isEqual(options, expectation) || overwrite) && (that.stopAds(), expectation = options, expectation && 0 != expectation.length)) { | |
| /** @type {!Array} */ | |
| var child = []; | |
| async.eachSeries(expectation, function(index, saveNotifs) { | |
| fs.readFile(settings.mediaPath + "__" + index + ".json", function(canCreateDiscussions, element) { | |
| if (canCreateDiscussions) { | |
| client.log("error", "Playlist read error: " + index); | |
| } else { | |
| try { | |
| /** @type {*} */ | |
| var res = JSON.parse(element); | |
| if (res.settings && res.settings.ads && res.settings.ads.adPlaylist) { | |
| update(res.assets); | |
| if (res.assets && res.assets.length) { | |
| child.push({ | |
| files : res.assets, | |
| interval : res.settings.ads.adInterval, | |
| adCount : res.settings.ads.adCount, | |
| noMainPlay : res.settings.ads.noMainPlay | |
| }); | |
| } | |
| } else { | |
| client.log("error", "error no setting for advertisement playlist " + index); | |
| } | |
| } catch (g) { | |
| client.log("error", "error parsing advertisement playlist " + index); | |
| } | |
| } | |
| saveNotifs(); | |
| }); | |
| }, function() { | |
| if (child.length) { | |
| that.startAds(child); | |
| } | |
| }); | |
| } | |
| } | |
| /** | |
| * @param {string} d | |
| * @param {boolean} v | |
| * @return {?} | |
| */ | |
| function refresh(d, v) { | |
| if (!d) { | |
| return void that.stopLoungeMusic(); | |
| } | |
| if (!_.isEqual(d, id) || v) { | |
| if ("NTSC" == $scope.resolution || "PAL" == $scope.resolution) { | |
| return client.log("error", " **** Can not play lounge music in Composite video(NTSC or PAL) configurations ****"), void that.stopLoungeMusic(); | |
| } | |
| /** @type {string} */ | |
| id = d; | |
| fs.readFile(settings.mediaPath + "__" + id + ".json", function(index, b) { | |
| var state; | |
| var files; | |
| if (index) { | |
| client.log("error", "Playlist read error: " + id + ";" + index); | |
| that.stopLoungeMusic(); | |
| } else { | |
| try { | |
| /** @type {*} */ | |
| state = JSON.parse(b); | |
| } catch (d) { | |
| client.log("error", "error parsing audio playlist " + id); | |
| that.stopLoungeMusic(); | |
| } | |
| files = state.assets.filter(function(options) { | |
| return options && options.filename && options.filename.match(settings.audioRegex); | |
| }); | |
| update(files); | |
| if (files.length) { | |
| that.startLoungeMusic(files, state.settings.audio.random, state.settings.audio.volume, state.settings.audio.hdmi); | |
| } else { | |
| client.log("error", " **** No MP3 files present to Play the lounge music****"); | |
| that.stopLoungeMusic(); | |
| } | |
| } | |
| }); | |
| } | |
| } | |
| /** | |
| * @param {!Object} user | |
| * @return {undefined} | |
| */ | |
| function command(user) { | |
| var enmlHash; | |
| if (user && user.enable) { | |
| if (user.ontime) { | |
| enmlHash = user.ontime.split(":"); | |
| if (2 == enmlHash.length) { | |
| /** @type {number} */ | |
| b = 60 * parseInt(enmlHash[0]) + parseInt(enmlHash[1]); | |
| } else { | |
| if (1 == enmlHash.length) { | |
| /** @type {number} */ | |
| b = parseInt(enmlHash[0]); | |
| } | |
| } | |
| } | |
| if (user.offtime) { | |
| enmlHash = user.offtime.split(":"); | |
| if (2 == enmlHash.length) { | |
| /** @type {number} */ | |
| c = 60 * parseInt(enmlHash[0]) + parseInt(enmlHash[1]); | |
| } else { | |
| if (1 == enmlHash.length) { | |
| /** @type {number} */ | |
| c = parseInt(enmlHash[0]); | |
| } | |
| } | |
| } | |
| } else { | |
| /** @type {null} */ | |
| b = null; | |
| /** @type {null} */ | |
| c = null; | |
| } | |
| if (user && user.enable && b) { | |
| stop(); | |
| } else { | |
| if (stop_timer) { | |
| clearTimeout(stop_timer); | |
| reset(); | |
| } | |
| } | |
| } | |
| /** | |
| * @return {undefined} | |
| */ | |
| function stop() { | |
| var inValue; | |
| var t; | |
| /** @type {boolean} */ | |
| var userData = false; | |
| clearTimeout(stop_timer); | |
| /** @type {!Date} */ | |
| inValue = new Date; | |
| /** @type {number} */ | |
| t = 60 * inValue.getHours() + inValue.getMinutes(); | |
| /** @type {boolean} */ | |
| userData = c > b ? t > c || b > t : t > c && b > t; | |
| if (userData) { | |
| on(); | |
| } else { | |
| if ("TV_OFF" != options.currentPlaylist) { | |
| reset(); | |
| } | |
| } | |
| /** @type {number} */ | |
| stop_timer = setTimeout(stop, 3E5); | |
| } | |
| /** | |
| * @return {?} | |
| */ | |
| function reset() { | |
| /** | |
| * @return {undefined} | |
| */ | |
| var remove = function() { | |
| end(); | |
| that.pauseOpenVg(false); | |
| that.setDisplayClock($scope.showClock, $scope.emergencyMessage); | |
| init(true, options.currentPlaylist, function() { | |
| done(); | |
| }); | |
| }; | |
| return options.tvStatus ? void that.pauseOpenVg(false) : (options.tvStatus = true, void("NTSC" != $scope.resolution && "PAL" != $scope.resolution ? assert.tvOn(function() { | |
| remove(); | |
| }) : remove())); | |
| } | |
| /** | |
| * @return {undefined} | |
| */ | |
| function on() { | |
| if (options.tvStatus) { | |
| /** @type {boolean} */ | |
| options.tvStatus = false; | |
| that.pauseOpenVg(true); | |
| that.removeLogo(); | |
| init(false, options.currentPlaylist, function() { | |
| if ("NTSC" != $scope.resolution && "PAL" != $scope.resolution) { | |
| assert.tvOff(); | |
| } | |
| done(); | |
| }); | |
| } | |
| } | |
| /** | |
| * @return {undefined} | |
| */ | |
| function end() { | |
| if ("NTSC" != $scope.resolution && "PAL" != $scope.resolution) { | |
| /** @type {number} */ | |
| var name = "720p" == $scope.resolution ? 1200 : 1840; | |
| /** @type {number} */ | |
| var src = name; | |
| /** @type {number} */ | |
| var oldEditRowIndex = 10; | |
| /** @type {(null|string)} */ | |
| var value = fs.existsSync(settings.root + "/public/app/img/logo.png") ? settings.root + "/public/app/img/logo.png" : null; | |
| if ($scope.logo) { | |
| value = $scope.logo; | |
| src = $scope.logox || name; | |
| oldEditRowIndex = $scope.logoy || 10; | |
| } | |
| that.setLogo(value, src, oldEditRowIndex, !$scope.logo); | |
| } | |
| } | |
| /** | |
| * @param {!Object} a | |
| * @return {undefined} | |
| */ | |
| function run(a) { | |
| var wrongDefinition; | |
| var created; | |
| var e; | |
| var extension; | |
| if (a.enable) { | |
| /** @type {!Date} */ | |
| created = new Date(a.time); | |
| created.setTime(created.getTime() + 60 * created.getTimezoneOffset() * 1E3); | |
| /** @type {number} */ | |
| e = created.getHours(); | |
| /** @type {number} */ | |
| extension = created.getMinutes(); | |
| /** @type {string} */ | |
| wrongDefinition = 'echo "' + extension + " " + e + ' * * * /sbin/reboot" | sudo crontab -'; | |
| } else { | |
| /** @type {string} */ | |
| wrongDefinition = "sudo crontab - r"; | |
| } | |
| exec(wrongDefinition, function(matchProperty, canCreateDiscussions, id) { | |
| if (matchProperty || id) { | |
| client.log("error", "Error in setting/deleting cron job; " + matchProperty + ";" + id); | |
| } else { | |
| if (a.enable) { | |
| client.log("info", "*** Cron job for reboot set at " + e + ":" + extension); | |
| } | |
| } | |
| }); | |
| } | |
| var config; | |
| var status; | |
| var projectResample; | |
| var updateConnz; | |
| var restore; | |
| var put; | |
| var update; | |
| var init; | |
| var error; | |
| var check; | |
| var callback; | |
| var load; | |
| var render; | |
| var params; | |
| var fetchAllProducts; | |
| var ga; | |
| var paintNodesTimeout; | |
| var slideFirst; | |
| var testPageTranslation; | |
| var la; | |
| var start; | |
| var socket; | |
| var connection; | |
| var io; | |
| var output; | |
| var globalMod; | |
| var editPost; | |
| var moderates; | |
| var ua; | |
| var beforeZero; | |
| var afterZero; | |
| var xa; | |
| var endCallTimeout; | |
| var Ca; | |
| var _resolve; | |
| var _input_filter_changed; | |
| var index; | |
| var renderTemplate; | |
| var inValue; | |
| var y; | |
| var value; | |
| var today; | |
| var sceneUid; | |
| var proxy_pair; | |
| var timer; | |
| var stateChangeTimer; | |
| var stop_timer; | |
| var b; | |
| var c; | |
| var kb; | |
| var exec = require("child_process").exec; | |
| var fs = (require("os"), require("fs")); | |
| var path = require("path"); | |
| var async = require("async"); | |
| var _ = require("lodash"); | |
| var Handlebars = require("ejs"); | |
| var settings = require("../../config/config"); | |
| var data = require("./package.json"); | |
| var that = require("./pi-viewer"); | |
| var Utils = require("./pi-wget"); | |
| var utils = require("./pi-events"); | |
| var globalDisclaimer = require("./kiosk-ui"); | |
| var self = require("../others/restware"); | |
| var client = require("../others/logger"); | |
| var assert = require("../others/system-info"); | |
| var util = require("../others/rss-service"); | |
| var s = settings; | |
| var options = { | |
| playlistOn : false, | |
| localControl : false, | |
| currentPlaylist : null, | |
| deployedPlaylists : null, | |
| playlistIndex : 0, | |
| playlistStarttime : null, | |
| groupTicker : {}, | |
| diskSpaceUsed : null, | |
| diskSpaceAvailable : null, | |
| duration : null, | |
| tvStatus : true, | |
| cecTvStatus : true, | |
| licensed : false | |
| }; | |
| var $scope = { | |
| cpuSerialNumber : "unknown", | |
| ethMac : null, | |
| wifiMac : null, | |
| myIpAddress : "", | |
| secret : "", | |
| installation : "", | |
| orientation : "", | |
| resolution : "", | |
| omxVolume : 100, | |
| dns : { | |
| primary : "8.8.4.4", | |
| secondary : "8.8.8.8" | |
| }, | |
| assetsValidity : [] | |
| }; | |
| var result = { | |
| user : null, | |
| password : null | |
| }; | |
| /** @type {boolean} */ | |
| var maxReconnectTryTimes = false; | |
| /** @type {string} */ | |
| var d = ""; | |
| /** @type {!Array} */ | |
| var deprecatedStylingMethods = []; | |
| /** @type {boolean} */ | |
| var hasSongChanged = false; | |
| /** @type {boolean} */ | |
| var C = false; | |
| /** @type {boolean} */ | |
| var isReplayingSong = false; | |
| /** @type {!Array} */ | |
| var collections = []; | |
| /** @type {!Array} */ | |
| var l = []; | |
| /** @type {!Array} */ | |
| var attribInfos = []; | |
| /** @type {!Array} */ | |
| var users = []; | |
| /** @type {!Array} */ | |
| var subtree = []; | |
| /** @type {!Array} */ | |
| var r = []; | |
| /** @type {!Array} */ | |
| var bufferedRecords = []; | |
| /** @type {!Array} */ | |
| var expectation = []; | |
| /** @type {null} */ | |
| var id = null; | |
| /** @type {boolean} */ | |
| var option = false; | |
| /** @type {string} */ | |
| var predictionFileName = settings.root + "/config/temp_iface.txt"; | |
| /** @type {string} */ | |
| var bazPath = settings.root + "/config/temp_wifi.txt"; | |
| /** @type {string} */ | |
| var element = ""; | |
| if (data.config_server) { | |
| element = data.config_server.trim().replace(/^http(s?):\/\//i, "").split(":")[0]; | |
| } | |
| that.setConfigServer(element); | |
| config = { | |
| settings : ["version", "platform_version", "cpuSerialNumber", "myIpAddress", "localName", "ethMac", "wifiMac"], | |
| config : ["playlistOn", "currentPlaylist", "playlistStarttime", "diskSpaceUsed", "diskSpaceAvailable", "lastUpload", "wgetBytes", "wgetSpeed", "syncInProgress", "duration", "tvStatus", "request", "licensed", "cecTvStatus", "piTemperature", "uptime"] | |
| }; | |
| /** @type {string} */ | |
| status = "stopped"; | |
| /** @type {boolean} */ | |
| projectResample = false; | |
| /** | |
| * @return {undefined} | |
| */ | |
| updateConnz = function() { | |
| /** @type {string} */ | |
| d = ""; | |
| deprecatedStylingMethods = assert.getIp(); | |
| deprecatedStylingMethods.forEach(function(dropPoint) { | |
| d = d + (dropPoint.ip + " "); | |
| }); | |
| /** @type {string} */ | |
| $scope.myIpAddress = d; | |
| }; | |
| updateConnz(); | |
| /** | |
| * @param {!Function} callback | |
| * @return {undefined} | |
| */ | |
| restore = function(callback) { | |
| exec("/bin/bash misc/nwdiag.sh", function(b, c) { | |
| client.log("info", c); | |
| try { | |
| /** @type {*} */ | |
| $scope.nwinfo = JSON.parse(c); | |
| } catch (e) { | |
| } | |
| if (callback) { | |
| callback(); | |
| } | |
| }); | |
| }; | |
| /** | |
| * @param {?} value | |
| * @return {?} | |
| */ | |
| put = function(value) { | |
| /** @type {!Date} */ | |
| var date = new Date(value); | |
| return date.setTime(date.getTime() + 60 * date.getTimezoneOffset() * 1E3), date.getTime(); | |
| }; | |
| /** | |
| * @param {!Array} data | |
| * @return {undefined} | |
| */ | |
| update = function(data) { | |
| /** @type {number} */ | |
| var key = (new Date).setHours(0, 0, 0, 0); | |
| if ($scope.assetsValidity) { | |
| $scope.assetsValidity.forEach(function(self) { | |
| if (self.startdate && key < put(self.startdate) || self.enddate && key > put(self.enddate)) { | |
| /** @type {number} */ | |
| var i = data.length - 1; | |
| for (; i >= 0; i--) { | |
| if (data[i].filename == self.name) { | |
| client.log("info", "Removing " + self.name + " for validity"); | |
| data.splice(i, 1); | |
| } | |
| } | |
| } | |
| }); | |
| } | |
| }; | |
| /** @type {function(!Array): undefined} */ | |
| instance.filterValidAssets = update; | |
| /** | |
| * @param {boolean} msg | |
| * @param {string} url | |
| * @param {!Function} template | |
| * @param {string} data | |
| * @return {?} | |
| */ | |
| init = function(msg, url, template, data) { | |
| var i; | |
| var obj; | |
| var result; | |
| var item; | |
| var q; | |
| /** | |
| * @param {string} id | |
| * @param {string} hash | |
| * @return {?} | |
| */ | |
| var init = function(id, hash) { | |
| return id ? (options.playlistOn = false, client.log("error", "start Playlist error: " + id), utils.storeEvent("player", "error", "start Playlist error: " + id), template(id)) : (hash != options.currentPlaylist && (client.log("info", "*** currentPlaylist name changed from " + options.currentPlaylist + " to " + hash), options.currentPlaylist = hash), options.playlistStarttime = Date.now(), instance.writeToConfig(), options.duration = 0, client.log("info", "*** Changing Playlist *** to " + options.currentPlaylist), | |
| utils.storeEvent("player", "playlist", "Changed playlist to " + options.currentPlaylist), template(null, options)); | |
| }; | |
| return msg ? "TV_OFF" == url ? (on(), projectResample = true, instance.writeToConfig(), template(null, options)) : (projectResample && (projectResample = false, reset()), options.playlistOn ? (i = "Already playing started", client.log("error", i), utils.storeEvent("player", "error", i), template(i)) : options.tvStatus ? (options.playlistOn = true, options.currentPlaylist = url || settings.defaultPlaylist, void async.series([function(exec) { | |
| fs.readFile(settings.mediaPath + "__" + options.currentPlaylist + ".json", "utf8", function(filesWildcard, sanitized) { | |
| if (filesWildcard || !sanitized) { | |
| exec("There seems to be no such playlist file: " + options.currentPlaylist + ";error=" + filesWildcard); | |
| } else { | |
| try { | |
| /** @type {*} */ | |
| obj = JSON.parse(sanitized); | |
| result = obj.assets; | |
| /** @type {null} */ | |
| item = null; | |
| exec(); | |
| } catch (redirect_params) { | |
| exec("Playlist JSON parse error: " + options.currentPlaylist + ";error=" + redirect_params.code); | |
| } | |
| } | |
| }); | |
| }, function(unsafeTermFn) { | |
| /** @type {null} */ | |
| var List = null; | |
| if ($scope.combineDefaultPlaylist && options.currentPlaylist != options.deployedPlaylists[0].name && "TV_OFF" != options.deployedPlaylists[0].name) { | |
| fs.readFile(settings.mediaPath + "__" + options.deployedPlaylists[0].name + ".json", "utf8", function(error, data) { | |
| if (error || !data) { | |
| client.log("error", " *** error in reading playlist *** " + options.deployedPlaylists[0].name + ";" + error); | |
| } else { | |
| try { | |
| List = JSON.parse(data).assets; | |
| } catch (extension) { | |
| client.log("error", " *** error in combining default playlist *** " + extension); | |
| } | |
| if (List && List.length > 0) { | |
| result = List.concat(result); | |
| } | |
| } | |
| unsafeTermFn(); | |
| }); | |
| } else { | |
| unsafeTermFn(); | |
| } | |
| }, function(unsafeTermFn) { | |
| /** @type {number} */ | |
| var N = 1; | |
| if ($scope.playAllEligiblePlaylists) { | |
| async.eachSeries(bufferedRecords, function(tabbed_panel_id, saveNotifs) { | |
| if ("TV_OFF" == tabbed_panel_id) { | |
| return saveNotifs(); | |
| } | |
| /** @type {null} */ | |
| var arr = null; | |
| fs.readFile(settings.mediaPath + "__" + tabbed_panel_id + ".json", "utf8", function(error, data) { | |
| if (error || !data) { | |
| client.log("error", " *** error in reading playlist *** " + tabbed_panel_id + ";" + error); | |
| } else { | |
| try { | |
| arr = JSON.parse(data).assets; | |
| } catch (extension) { | |
| client.log("error", " *** error in combining default playlist *** " + extension); | |
| } | |
| if (arr && arr.length > 0) { | |
| if ($scope.alternateContent) { | |
| /** @type {number} */ | |
| var i = 0; | |
| var len = arr.length; | |
| for (; len > i; i++) { | |
| result.splice((i + 1) * N + i, 0, arr[i]); | |
| } | |
| N++; | |
| } else { | |
| result = result.concat(arr); | |
| } | |
| } | |
| } | |
| saveNotifs(); | |
| }); | |
| }, function() { | |
| unsafeTermFn(); | |
| }); | |
| } else { | |
| unsafeTermFn(); | |
| } | |
| }, function(unsafeTermFn) { | |
| var j; | |
| var text; | |
| var i; | |
| if ($scope.shuffleContent) { | |
| /** @type {number} */ | |
| i = result.length - 1; | |
| for (; i >= 0; i--) { | |
| /** @type {number} */ | |
| j = Math.floor(Math.random() * (i + 1)); | |
| text = result[j]; | |
| result[j] = result[i]; | |
| result[i] = text; | |
| } | |
| } | |
| unsafeTermFn(); | |
| }, function(unsafeTermFn) { | |
| if (obj.settings && obj.settings.ticker && obj.settings.ticker.enable) { | |
| item = obj.settings.ticker; | |
| } else { | |
| if (options.groupTicker && options.groupTicker.enable) { | |
| item = options.groupTicker; | |
| } | |
| } | |
| if (item) { | |
| item.isRssFeed = item.rss && item.rss.enable; | |
| item.rssLink = item.rss && item.rss.link; | |
| item.rssEncodeAsBinary = item.rss && item.rss.encodeAsBinary; | |
| item.useDescription = item.rss && item.rss.useDescription; | |
| /** @type {boolean} */ | |
| item.disabled = false; | |
| if (item.messages) { | |
| item.messages = item.messages.replace(/__cpuid__/g, $scope.cpuSerialNumber.slice(0, 4) + "-" + $scope.cpuSerialNumber.slice(4, 8) + "-" + $scope.cpuSerialNumber.slice(8, 12) + "-" + $scope.cpuSerialNumber.slice(12, 16)); | |
| item.messages = item.messages.replace(/__ipaddress__/g, $scope.myIpAddress || "NA"); | |
| item.messages = item.messages.replace(/__connectionstatus__/g, $scope.connectionStatus || "NA"); | |
| } | |
| } | |
| unsafeTermFn(); | |
| }, function(unsafeTermFn) { | |
| update(result); | |
| globalDisclaimer.hideUi(); | |
| if (data && $scope.loadPlaylistOnCompletion) { | |
| that.startPlaySync(result, item, obj.layout || "1", obj.videoWindow, obj.zoneVideoWindow, obj.templateName, init, 0, obj.settings && obj.settings.domination && obj.settings.domination.enable, options.currentPlaylist); | |
| } else { | |
| that.startPlay(result, item, obj.layout || "1", obj.videoWindow, obj.zoneVideoWindow, obj.templateName, init, 0, obj.settings && obj.settings.domination && obj.settings.domination.enable, options.currentPlaylist); | |
| } | |
| unsafeTermFn(); | |
| }], function(fontface) { | |
| if (fontface) { | |
| that.startPlay([{ | |
| filename : "_emptynotice.html", | |
| duration : 30 | |
| }], null, "1"); | |
| init(fontface); | |
| } | |
| })) : (i = "TV is OFF, skipping playlist play", client.log("error", i), utils.storeEvent("player", "error", i), template(i))) : (options.playlistOn || client.log("debug", "playlist stop, already playing stopped"), options.playlistOn = false, q = that.stopPlay(), options.playlistStarttime = null, options.duration = Math.floor((Date.now() - options.playlistStarttime) / 6e4), instance.writeToConfig(), template(null, options)); | |
| }; | |
| /** | |
| * @param {!Function} f | |
| * @param {string} done | |
| * @return {undefined} | |
| */ | |
| error = function(f, done) { | |
| /** | |
| * @return {undefined} | |
| */ | |
| var success = function() { | |
| init(true, options.currentPlaylist, function(widthCtrl, b) { | |
| done(); | |
| f(widthCtrl, b); | |
| }, done); | |
| }; | |
| /** @type {boolean} */ | |
| options.playlistOn = false; | |
| success(); | |
| }; | |
| /** | |
| * @return {?} | |
| */ | |
| instance.getSettingsData = function() { | |
| return { | |
| name : $scope.name || $scope.localName, | |
| myIpAddress : $scope.myIpAddress.trim(), | |
| cpuSerialNumber : $scope.cpuSerialNumber, | |
| secret : $scope.secret | |
| }; | |
| }; | |
| /** | |
| * @return {undefined} | |
| */ | |
| instance.writeToSettings = function() { | |
| try { | |
| fs.writeFileSync(settings.settingsFile, JSON.stringify($scope, null, 4)); | |
| exec("sync"); | |
| } catch (extension) { | |
| client.log("error", "*** Settings File write Error ***" + extension); | |
| } | |
| }; | |
| /** | |
| * @param {!Object} query | |
| * @param {boolean} options | |
| * @return {undefined} | |
| */ | |
| instance.writeToConfig = function(query, options) { | |
| if (query) { | |
| var k; | |
| for (k in query) { | |
| options[k] = query[k]; | |
| } | |
| } | |
| if (!options) { | |
| try { | |
| fs.writeFileSync(settings.poweronConfig, JSON.stringify(options, null, 4)); | |
| exec("sync"); | |
| } catch (extension) { | |
| client.log("error", "*** Settings File write Error ***" + extension); | |
| } | |
| } | |
| }; | |
| /** | |
| * @param {?} saveNotifs | |
| * @return {undefined} | |
| */ | |
| instance.updateDiskStatus = function(saveNotifs) { | |
| exec("df -h /").stdout.on("data", function(commaParam) { | |
| if (commaParam) { | |
| var parts = commaParam.replace(/\s{2,}/g, " ").split(" "); | |
| options.diskSpaceUsed = parts[parts.length - 2]; | |
| options.diskSpaceAvailable = parts[parts.length - 3]; | |
| } | |
| }).on("close", function() { | |
| if (saveNotifs) { | |
| saveNotifs(); | |
| } | |
| }); | |
| }; | |
| /** | |
| * @param {string} res | |
| * @param {string} type | |
| * @return {undefined} | |
| */ | |
| instance.playFile = function(res, type) { | |
| switch(client.log("info", "action: " + res.params.action + ", file: " + res.query.file), res.params.action) { | |
| case "play": | |
| if (res.query.file) { | |
| /** @type {string} */ | |
| status = "playing"; | |
| that.playFile(res.query.file, function() { | |
| /** @type {string} */ | |
| status = "stopped"; | |
| }, res.query.duration); | |
| self.sendSuccess(type, "Started playing file", { | |
| status : status | |
| }); | |
| } else { | |
| self.sendSuccess(type, "Nothing to play", { | |
| status : status | |
| }); | |
| } | |
| break; | |
| case "stop": | |
| if ("stopped" == status) { | |
| self.sendSuccess(type, "already stopped", { | |
| status : status | |
| }); | |
| } else { | |
| /** @type {string} */ | |
| status = "stopped"; | |
| that.stopFile(); | |
| self.sendSuccess(type, "file stopped", { | |
| status : status | |
| }); | |
| } | |
| break; | |
| case "pause": | |
| if ("stopped" == status) { | |
| /** @type {string} */ | |
| res.params.action = "play"; | |
| instance.playFile(res, type); | |
| } else { | |
| if ("playing" == status) { | |
| /** @type {string} */ | |
| status = "paused"; | |
| } else { | |
| if ("paused" == status) { | |
| /** @type {string} */ | |
| status = "playing"; | |
| } | |
| } | |
| that.pauseFile(); | |
| self.sendSuccess(type, "pause reply", { | |
| status : status | |
| }); | |
| } | |
| break; | |
| default: | |
| self.sendSuccess(type, "sending current status of playFile", { | |
| status : status | |
| }); | |
| } | |
| }; | |
| /** | |
| * @param {!Object} req | |
| * @param {!Object} res | |
| * @return {undefined} | |
| */ | |
| instance.playPlaylist = function(req, res) { | |
| if (req.body.play) { | |
| /** @type {boolean} */ | |
| options.playlistOn = false; | |
| /** @type {boolean} */ | |
| options.localControl = true; | |
| init(true, req.params.file, function(callback, data) { | |
| return callback ? self.sendError(res, "Already playing started") : self.sendSuccess(res, "Started playlist", data); | |
| }); | |
| } else { | |
| if (req.body.stop) { | |
| /** @type {boolean} */ | |
| options.localControl = false; | |
| init(false, req.params.file, function(err, response) { | |
| return err ? self.sendError(res, err) : self.sendSuccess(res, "Stopped playlist", response); | |
| }); | |
| } | |
| } | |
| }; | |
| /** | |
| * @param {!Request} result | |
| * @param {!Object} error | |
| * @return {undefined} | |
| */ | |
| instance.getRssFeeds = function(result, error) { | |
| var options = result.query.link; | |
| var msg = result.query["encode-as-binary"]; | |
| var s = result.query.feedlimit; | |
| /** @type {boolean} */ | |
| var f = false; | |
| util.getFeeds(options, msg, function(err, response) { | |
| return f ? void 0 : (f = true, err ? self.sendError(error, "Feed fetch error, " + err) : self.sendSuccess(error, "Feed results", response)); | |
| }, s); | |
| }; | |
| /** | |
| * @param {?} q | |
| * @param {!Object} res | |
| * @return {?} | |
| */ | |
| instance.getStatus = function(q, res) { | |
| var data = {}; | |
| return options.playlistOn ? options.duration = options.playlistStarttime : options.duration = 0, data = { | |
| diskSpaceUsed : options.diskSpaceUsed, | |
| diskSpaceAvailable : options.diskSpaceAvailable, | |
| playlistOn : options.playlistOn, | |
| duration : options.duration, | |
| tvStatus : options.tvStatus, | |
| cecTvStatus : options.cecTvStatus, | |
| currentPlaylist : options.currentPlaylist, | |
| currentPlayingFile : that.getCurrentPlayingFile(), | |
| cpuSerialNumber : $scope.cpuSerialNumber, | |
| playlistsDeployed : options.deployedPlaylists && options.deployedPlaylists.map(function(a) { | |
| return a.name; | |
| }), | |
| currentDebugLevel : client.debugLevel | |
| }, self.sendSuccess(res, "Status Check", data); | |
| }; | |
| /** | |
| * @param {!Object} status | |
| * @param {!Object} err | |
| * @return {?} | |
| */ | |
| instance.setDebugLevel = function(status, err) { | |
| return log(status.body.level), self.sendSuccess(err, "Debug level set", client.debugLevel); | |
| }; | |
| /** | |
| * @param {!Function} key | |
| * @return {undefined} | |
| */ | |
| check = function(key) { | |
| key = key || function() { | |
| }; | |
| exec("screenshot 50", { | |
| encoding : "base64", | |
| timeout : 3E4, | |
| maxBuffer : 512E4, | |
| killSignal : "SIGTERM", | |
| cwd : null, | |
| env : null | |
| }, key); | |
| }; | |
| /** | |
| * @param {?} collectionName | |
| * @param {!Object} res | |
| * @return {undefined} | |
| */ | |
| instance.getSnapshot = function(collectionName, res) { | |
| check(function(msg, instancesTypes, err) { | |
| if (msg) { | |
| self.sendError(res, "Error in connection", msg); | |
| } else { | |
| if (err) { | |
| self.sendError(res, "Error in taking snapshot", err); | |
| } else { | |
| self.sendSuccess(res, "snapshot", { | |
| data : instancesTypes, | |
| lastTaken : Date.now() | |
| }); | |
| } | |
| } | |
| }); | |
| }; | |
| /** | |
| * @param {!Object} event | |
| * @param {!Object} message | |
| * @return {undefined} | |
| */ | |
| instance.executeShell = function(event, message) { | |
| var cmd = event.body.cmd; | |
| exec(cmd, { | |
| encoding : "utf8", | |
| timeout : 3E4, | |
| maxBuffer : 20480, | |
| killSignal : "SIGTERM", | |
| cwd : null, | |
| env : null | |
| }, function(error, text, _cerr) { | |
| var result = { | |
| cmd : cmd, | |
| err : error, | |
| stdout : text, | |
| stderr : _cerr | |
| }; | |
| self.sendSuccess(message, "shell_ack", result); | |
| }); | |
| }; | |
| /** | |
| * @param {?} replyToken | |
| * @param {!Object} message | |
| * @return {?} | |
| */ | |
| instance.getTestLog = function(replyToken, message) { | |
| return self.sendSuccess(message, "Test Log", client.getTestLog()); | |
| }; | |
| /** | |
| * @param {!Function} callback | |
| * @return {undefined} | |
| */ | |
| callback = function(callback) { | |
| var arr; | |
| var i; | |
| var l; | |
| fs.readFile(settings.ifacePath, "utf8", function(err, domains) { | |
| if (!err && domains) { | |
| arr = domains.split("\n"); | |
| /** @type {number} */ | |
| i = 0; | |
| l = arr.length; | |
| for (; l > i && !arr[i].match(/^\s*iface\s*eth0\s*inet\s*[a-zA-Z]+/gi); i++) { | |
| } | |
| } | |
| if (err || i == arr.length) { | |
| fs.readFile(settings.dhcpcdFile, "utf8", function(err, domains) { | |
| if (!err && domains) { | |
| arr = domains.split("\n"); | |
| /** @type {number} */ | |
| i = 0; | |
| l = arr.length; | |
| for (; l > i && !arr[i].match(/^\s*interface\s*eth0/i); i++) { | |
| } | |
| } else { | |
| console.log("file read error: " + err); | |
| } | |
| if (err || i == arr.length) { | |
| callback(null, { | |
| lines : arr, | |
| pos : -1, | |
| mode : "dhcpcd" | |
| }); | |
| } else { | |
| callback(null, { | |
| lines : arr, | |
| pos : i, | |
| mode : "dhcpcd" | |
| }); | |
| } | |
| }); | |
| } else { | |
| callback(null, { | |
| lines : arr, | |
| pos : i, | |
| mode : "interfaces" | |
| }); | |
| } | |
| }); | |
| }; | |
| /** | |
| * @param {!Function} cb | |
| * @return {undefined} | |
| */ | |
| load = function(cb) { | |
| var theseCookies; | |
| var c; | |
| exec("sudo cat " + settings.bootConfigPath, function(canCreateDiscussions, clusterShardData, fallbackReleases) { | |
| if (null !== canCreateDiscussions) { | |
| cb(fallbackReleases, null); | |
| } else { | |
| theseCookies = clusterShardData.split("\n"); | |
| /** @type {number} */ | |
| var i = 0; | |
| for (; i < theseCookies.length; i++) { | |
| if (theseCookies[i].match(/disable_overscan/)) { | |
| /** @type {boolean} */ | |
| c = "1" == theseCookies[i].split("=").pop() ? true : false; | |
| } else { | |
| if (theseCookies[i].match(/overscan_left/)) { | |
| break; | |
| } | |
| } | |
| } | |
| cb(null, { | |
| txtdata : theseCookies, | |
| position : i, | |
| overscan_flag : c | |
| }); | |
| } | |
| }); | |
| }; | |
| /** | |
| * @param {?} val | |
| * @param {!Object} message | |
| * @return {undefined} | |
| */ | |
| instance.getSettings = function(val, message) { | |
| var self; | |
| /** @type {boolean} */ | |
| var c = false; | |
| /** @type {boolean} */ | |
| var g = false; | |
| /** | |
| * @return {?} | |
| */ | |
| var parse = function() { | |
| var eCfgEl = assert.getIp(true); | |
| var isoDateString = eCfgEl.filter(function(verifiedEvent) { | |
| return "eth0" == verifiedEvent.type; | |
| }); | |
| return isoDateString; | |
| }; | |
| async.series([function(saveNotifs) { | |
| callback(function(notifications, p) { | |
| if (notifications) { | |
| saveNotifs(notifications); | |
| } else { | |
| /** @type {!Object} */ | |
| self = p; | |
| /** @type {boolean} */ | |
| c = "dhcpcd" == p.mode; | |
| saveNotifs(); | |
| } | |
| }); | |
| }, function(callback) { | |
| var data; | |
| var k; | |
| var dest; | |
| var assignmentUrl; | |
| var address; | |
| var arr; | |
| if (c) { | |
| if (-1 == self.pos) { | |
| data = parse(); | |
| $scope.ipsettings = { | |
| type : "dhcpcd", | |
| mode : "DHCP", | |
| address : data.length ? data[0].ip : null, | |
| netmask : "please enter in CIDR notation, e.g. 24 for 255.255.255.0", | |
| gateway : null | |
| }; | |
| } else { | |
| /** @type {boolean} */ | |
| g = true; | |
| $scope.ipsettings = { | |
| type : "dhcpcd", | |
| mode : "Static", | |
| netmask : "please enter in CIDR notation, e.g. 24 for 255.255.255.0" | |
| }; | |
| $scope.dns = { | |
| primary : "8.8.4.4", | |
| secondary : "8.8.8.8" | |
| }; | |
| self.pos++; | |
| for (; self.pos < self.lines.length && self.lines[self.pos].match(/^\s*static/i);) { | |
| switch(k = self.lines[self.pos].slice(self.lines[self.pos].indexOf("static ") + 7).split("="), dest = k[0] ? k[0].trim() : null, assignmentUrl = k[1] ? k[1].trim() : null, dest) { | |
| case "ip_address": | |
| address = assignmentUrl.split("/"); | |
| $scope.ipsettings.address = address[0]; | |
| $scope.ipsettings.netmask = address[1]; | |
| break; | |
| case "routers": | |
| $scope.ipsettings.gateway = assignmentUrl; | |
| break; | |
| case "domain_name_servers": | |
| arr = assignmentUrl.split(" "); | |
| if (arr[0]) { | |
| $scope.dns.primary = arr[0]; | |
| } | |
| if (arr[1]) { | |
| $scope.dns.secondary = arr[1]; | |
| } | |
| } | |
| self.pos++; | |
| } | |
| } | |
| callback(); | |
| } else { | |
| if (-1 != self.lines[self.pos].indexOf("dhcp")) { | |
| data = parse(); | |
| $scope.ipsettings = { | |
| mode : "DHCP", | |
| address : data.length ? data[0].ip : null, | |
| netmask : null, | |
| gateway : null | |
| }; | |
| } else { | |
| /** @type {boolean} */ | |
| g = true; | |
| $scope.ipsettings = { | |
| mode : "Static", | |
| address : self.lines[self.pos + 1].split(" ").pop(), | |
| netmask : self.lines[self.pos + 2].split(" ").pop(), | |
| gateway : self.lines[self.pos + 3].split(" ").pop() | |
| }; | |
| } | |
| $scope.ipsettings.netmask = $scope.ipsettings.netmask || "255.255.255.0"; | |
| callback(); | |
| } | |
| }, function(saveNotifs) { | |
| var b; | |
| $scope.wifi = {}; | |
| exec("sudo cat " + settings.wifiPath, function(canCreateDiscussions, clusterShardData) { | |
| if (canCreateDiscussions) { | |
| saveNotifs(); | |
| } else { | |
| b = clusterShardData.split("\n"); | |
| /** @type {number} */ | |
| var i = 0; | |
| for (; i < b.length && !b[i].match(/network\S+/gi); i++) { | |
| } | |
| if (i < b.length) { | |
| if (b[i + 2].match(/key_mgmt\S+/gi)) { | |
| $scope.wifi = { | |
| ssid : b[i + 1].split('"')[1], | |
| pass : null, | |
| ip : null, | |
| open : true | |
| }; | |
| } else { | |
| $scope.wifi = { | |
| ssid : b[i + 1].split('"')[1], | |
| pass : b[i + 2].split('"')[1], | |
| ip : null, | |
| open : false | |
| }; | |
| } | |
| } | |
| saveNotifs(); | |
| } | |
| }); | |
| }, function(saveNotifs) { | |
| exec('grep -q "^denyinterfaces wlan0" /etc/dhcpcd.conf', function(b) { | |
| if (b) { | |
| /** @type {string} */ | |
| $scope.wifi.apmode = "NO"; | |
| } else { | |
| /** @type {string} */ | |
| $scope.wifi.apmode = "AP"; | |
| } | |
| saveNotifs(); | |
| }); | |
| }, function(callback) { | |
| var eCfgEl; | |
| var data; | |
| if ($scope.wifi.ssid) { | |
| eCfgEl = assert.getIp(true); | |
| data = eCfgEl.filter(function(verifiedEvent) { | |
| return "wlan0" == verifiedEvent.type; | |
| }); | |
| $scope.wifi.ip = data.length ? data[0].ip : null; | |
| } | |
| callback(); | |
| }, function(saveNotifs) { | |
| load(function(notifications, i) { | |
| if (notifications) { | |
| client.log("warn", "Error in reading config.txt"); | |
| saveNotifs(notifications); | |
| } else { | |
| var d = i.txtdata; | |
| var x = i.position; | |
| $scope.overscan = { | |
| horizontal : parseInt(d[x].split("=").pop(), 10), | |
| vertical : parseInt(d[x + 2].split("=").pop(), 10), | |
| disable_overscan : i.overscan_flag | |
| }; | |
| saveNotifs(); | |
| } | |
| }); | |
| }, function(callback) { | |
| if (result.user) { | |
| callback(); | |
| } else { | |
| fs.readFile(settings.root + "/htpasswd", "utf8", function(cmp, t) { | |
| if (!cmp && t) { | |
| var pair = t.split(":"); | |
| result.user = pair[0]; | |
| } | |
| callback(); | |
| }); | |
| } | |
| }, function(callback) { | |
| if ($scope.wifi.ip || $scope.ipsettings.address) { | |
| if (g) { | |
| if (c) { | |
| callback(); | |
| } else { | |
| $scope.dns = { | |
| primary : null, | |
| secondary : null | |
| }; | |
| exec("cat " + settings.ifacePath + " | grep 'dns-nameservers' | tr -d '[a-z][=-=][\n][\t]'", function(b, clusterShardData) { | |
| if (!b) { | |
| var eCfgEl = clusterShardData.split(" "); | |
| eCfgEl = eCfgEl.filter(function(a) { | |
| return a; | |
| }); | |
| $scope.dns = { | |
| primary : eCfgEl[0] || "8.8.4.4", | |
| secondary : eCfgEl[1] || "8.8.8.8" | |
| }; | |
| callback(); | |
| } | |
| }); | |
| } | |
| } else { | |
| exec("cat /etc/resolv.conf.head | grep 'nameserver' | tr -d '[:blank][a-z][=-=][\t]'", function(b, a) { | |
| if (!b || !a) { | |
| var eCfgEl = a.split("\n"); | |
| eCfgEl = eCfgEl.filter(function(a) { | |
| return a; | |
| }); | |
| $scope.dns = { | |
| primary : eCfgEl[0] || "8.8.4.4", | |
| secondary : eCfgEl[1] || "8.8.8.8" | |
| }; | |
| callback(); | |
| } | |
| }); | |
| } | |
| } else { | |
| callback(); | |
| } | |
| }], function() { | |
| return self.sendSuccess(message, "Settings", { | |
| name : $scope.name, | |
| localName : $scope.localName, | |
| note : $scope.note, | |
| version : $scope.version, | |
| platform_version : $scope.platform_version, | |
| currentVersion : $scope.currentVersion, | |
| ipsettings : $scope.ipsettings, | |
| wifi : $scope.wifi, | |
| overscan : $scope.overscan, | |
| orientation : $scope.orientation, | |
| resolution : $scope.resolution, | |
| omxVolume : $scope.omxVolume, | |
| user : { | |
| name : result.user | |
| }, | |
| server : { | |
| config : data.config_server, | |
| media : data.media_server | |
| }, | |
| sleep : $scope.sleep, | |
| reboot : $scope.reboot, | |
| dns : $scope.dns | |
| }); | |
| }); | |
| }; | |
| /** | |
| * @param {!Object} obj | |
| * @param {!Object} state | |
| * @param {?} template | |
| * @return {?} | |
| */ | |
| render = function(obj, state, template) { | |
| var data; | |
| var filesWildcard; | |
| /** @type {boolean} */ | |
| var showingAlertTitle = "dhcpcd" == state.mode; | |
| if (showingAlertTitle) { | |
| if ((!obj.netmask || isNaN(parseInt(obj.netmask)) || parseInt(obj.netmask) > 32) && (obj.netmask = 24), data = ["interface eth0", "\tstatic ip_address=" + obj.address + "/" + obj.netmask, "\tstatic routers=" + obj.gateway, "\tstatic domain_name_servers=" + $scope.dns.primary + " " + $scope.dns.secondary + "\n"], -1 == state.pos) { | |
| if ("DHCP" == obj.mode) { | |
| return template(); | |
| } | |
| state.lines = state.lines.concat(data); | |
| } else { | |
| state.lines.splice(state.pos, 1); | |
| for (; state.pos < state.lines.length && state.lines[state.pos].match(/\s*static/i);) { | |
| state.lines.splice(state.pos, 1); | |
| } | |
| if ("Static" == obj.mode) { | |
| state.lines = state.lines.concat(data); | |
| } | |
| } | |
| } else { | |
| if (-1 != state.lines[state.pos].indexOf("dhcp")) { | |
| if ("DHCP" == obj.mode) { | |
| return template(); | |
| } | |
| state.lines.splice(state.pos, 1, "iface eth0 inet static"); | |
| state.lines.splice(state.pos + 1, 0, "\taddress " + obj.address, "\tnetmask " + obj.netmask, "\tgateway " + obj.gateway, "\tdns-nameservers " + $scope.dns.primary + " " + $scope.dns.secondary); | |
| } else { | |
| if ("Static" == obj.mode) { | |
| state.lines.splice(state.pos + 1, 4); | |
| state.lines.splice(state.pos + 1, 0, "\taddress " + obj.address, "\tnetmask " + obj.netmask, "\tgateway " + obj.gateway, "\tdns-nameservers " + $scope.dns.primary + " " + $scope.dns.secondary); | |
| } else { | |
| state.lines.splice(state.pos + 1, 4); | |
| state.lines.splice(state.pos, 1, "iface eth0 inet dhcp"); | |
| } | |
| } | |
| } | |
| filesWildcard = showingAlertTitle ? settings.dhcpcdFile : settings.ifacePath; | |
| fs.writeFile(predictionFileName, state.lines.join("\n"), function(error_func) { | |
| if (error_func) { | |
| template({ | |
| msg : "Interfaces temp file error", | |
| error : error_func | |
| }); | |
| } else { | |
| exec("sudo mv -f " + predictionFileName + " " + filesWildcard, function(error_func) { | |
| if (error_func) { | |
| template({ | |
| msg : "mv temp to Interfaces error: ", | |
| error : error_func | |
| }); | |
| } else { | |
| template(); | |
| } | |
| }); | |
| } | |
| }); | |
| }; | |
| /** | |
| * @param {!Object} data | |
| * @param {!Object} params | |
| * @return {?} | |
| */ | |
| instance.setHostname = function(data, params) { | |
| return $scope.localName = data.body.localName, $scope.note = data.body.note, instance.writeToSettings(), assert.registerHostnameChange($scope.localName), self.sendSuccess(params, "Name change in progress", $scope); | |
| }; | |
| /** | |
| * @param {!Object} entry | |
| * @param {!Object} res | |
| * @return {undefined} | |
| */ | |
| instance.setEthernet = function(entry, res) { | |
| /** @type {null} */ | |
| var data = null; | |
| /** @type {boolean} */ | |
| var showingAlertTitle = false; | |
| async.series([function(saveNotifs) { | |
| callback(function(notifications, tmp) { | |
| if (notifications) { | |
| saveNotifs(notifications); | |
| } else { | |
| /** @type {boolean} */ | |
| showingAlertTitle = "dhcpcd" == tmp.mode; | |
| /** @type {!Object} */ | |
| data = tmp; | |
| saveNotifs(); | |
| } | |
| }); | |
| }, function(callback) { | |
| var b = showingAlertTitle ? settings.dhcpcdFile : settings.ifacePath; | |
| exec("sudo cp " + b + " " + b + ".bak", function(error_func) { | |
| if (null !== error_func) { | |
| callback({ | |
| msg : "cp interfaces to .bak error: ", | |
| error : error_func | |
| }); | |
| } else { | |
| callback(); | |
| } | |
| }); | |
| }, function(b) { | |
| var endColors = entry.body.dns; | |
| $scope.dns.primary = endColors.primary || "8.8.4.4"; | |
| $scope.dns.secondary = endColors.secondary || "8.8.8.8"; | |
| if (entry.body && entry.body.ipsettings && "DHCP" == entry.body.ipsettings.mode && entry.body.editDns) { | |
| assert.updateDnsEntry($scope.dns, b); | |
| } else { | |
| b(); | |
| } | |
| }, function(loaded) { | |
| render(entry.body.ipsettings, data, loaded); | |
| }], function(callback) { | |
| return callback ? self.sendError(res, "Error in updating Network settings: ", callback) : (self.sendSuccess(res, "Network settings saved", $scope), client.log("info", "Rebooting the server after network config change"), assert.reboot(), void 0); | |
| }); | |
| }; | |
| /** | |
| * @param {!Object} content | |
| * @param {!Object} res | |
| * @return {undefined} | |
| */ | |
| instance.setWifi = function(content, res) { | |
| var line; | |
| /** @type {boolean} */ | |
| var noaccum = false; | |
| /** @type {boolean} */ | |
| var isValidReq = false; | |
| /** @type {boolean} */ | |
| var opt_newBuffer = false; | |
| if (content.body.wifi.ssid) { | |
| /** @type {string} */ | |
| content.body.wifi.apmode = "NO"; | |
| /** @type {boolean} */ | |
| isValidReq = true; | |
| } else { | |
| if ("AP" == content.body.wifi.apmode) { | |
| /** @type {boolean} */ | |
| opt_newBuffer = true; | |
| } | |
| } | |
| async.series([function(reject) { | |
| return isValidReq ? void exec("sudo cp /etc/wpa_supplicant/wpa_supplicant.conf /etc/wpa_supplicant/wpa_supplicant.conf.bak", function(error_func) { | |
| if (null !== error_func) { | |
| reject({ | |
| msg : "cp wpa_supplicant.conf to .bak error: ", | |
| error : error_func | |
| }); | |
| } else { | |
| reject(); | |
| } | |
| }) : reject(); | |
| }, function(reject) { | |
| return isValidReq ? void exec("sudo cat " + settings.wifiPath, function(b, clusterShardData) { | |
| if (null !== b) { | |
| reject(err); | |
| } | |
| if (clusterShardData) { | |
| line = clusterShardData.split("\n"); | |
| reject(); | |
| } | |
| }) : reject(); | |
| }, function(callback) { | |
| if (!isValidReq) { | |
| return callback(); | |
| } | |
| /** @type {number} */ | |
| var i = 0; | |
| for (; i < line.length; i++) { | |
| if (line[i].match(/network\S+/gi)) { | |
| if (content.body.wifi.open) { | |
| line.splice(i + 1, 2, 'ssid="' + content.body.wifi.ssid + '"', "key_mgmt=NONE"); | |
| } else { | |
| line.splice(i + 1, 2, 'ssid="' + content.body.wifi.ssid + '"', 'psk="' + content.body.wifi.pass + '"'); | |
| } | |
| break; | |
| } | |
| } | |
| if (!(i < line.length)) { | |
| if (content.body.wifi.open) { | |
| line.push("network={", 'ssid="' + content.body.wifi.ssid + '"', "key_mgmt=NONE", "}"); | |
| } else { | |
| line.push("network={", 'ssid="' + content.body.wifi.ssid + '"', 'psk="' + content.body.wifi.pass + '"', "}"); | |
| } | |
| } | |
| fs.writeFile(bazPath, line.join("\n"), function(position) { | |
| return position ? position : void exec("sudo mv -f " + bazPath + " " + settings.wifiPath, function(error_func) { | |
| if (error_func) { | |
| callback({ | |
| msg : "mv wifi temp to wpa_supplicant.conf error: ", | |
| error : error_func | |
| }); | |
| } else { | |
| callback(); | |
| } | |
| }); | |
| }); | |
| }, function(saveNotifs) { | |
| exec('grep -q "^denyinterfaces wlan0" /etc/dhcpcd.conf', function(b) { | |
| if (!b || opt_newBuffer) { | |
| /** @type {boolean} */ | |
| noaccum = true; | |
| } | |
| saveNotifs(); | |
| }); | |
| }, function(saveNotifs) { | |
| /** @type {string} */ | |
| var range = opt_newBuffer ? "--enable-access-point" : "--disable-access-point"; | |
| exec(settings.systemScript + range, function(id, c, dataId) { | |
| if (id || dataId) { | |
| client.log("error", "wifi mode change error : " + id); | |
| } else { | |
| client.log("info", c); | |
| } | |
| saveNotifs(); | |
| }); | |
| }], function(err) { | |
| return err ? (client.log("error", err), self.sendError(res, "Wifi update error: ", err)) : ($scope.wifi = content.body.wifi, void(noaccum ? (self.sendSuccess(res, "Wifi update successfull", $scope), assert.reboot()) : callback(function(a, aReport) { | |
| var wrongDefinition; | |
| /** @type {string} */ | |
| wrongDefinition = a || "dhcpcd" == aReport.mode ? "sudo ifconfig wlan0 down;sudo ifconfig wlan0 up;" : "sudo ifdown --force wlan0; sudo ifup wlan0;"; | |
| exec(wrongDefinition, function(err) { | |
| return err ? (client.log("error", "ifdown/up error"), self.sendError(res, "Wifi update error: ", err)) : (updateConnz(), self.sendSuccess(res, "Wifi update successfull", $scope), void restore(parse)); | |
| }); | |
| }))); | |
| }); | |
| }; | |
| /** | |
| * @param {!Object} p2 | |
| * @param {!Object} res | |
| * @return {undefined} | |
| */ | |
| instance.setOverscan = function(p2, res) { | |
| var scrollbarLength = p2.body.overscan; | |
| self.sendSuccess(res, "new changes are being written", $scope); | |
| client.log("info", "Rebooting the server after overscan config change"); | |
| if (p2.body.overscan.disable_overscan) { | |
| exec('sudo sed -i -e "s/.*disable_overscan.*/disable_overscan=1/" -e "s/.*overscan_left.*/#overscan_left="' + scrollbarLength.horizontal + '/ -e "s/.*overscan_right.*/#overscan_right="' + scrollbarLength.horizontal + '/ -e "s/.*overscan_top.*/#overscan_top="' + scrollbarLength.vertical + '/ -e "s/.*overscan_bottom.*/#overscan_bottom="' + scrollbarLength.vertical + "/ " + settings.bootConfigPath).on("close", function() { | |
| assert.reboot(); | |
| }); | |
| } else { | |
| exec('sudo sed -i -e "s/.*disable_overscan.*/disable_overscan=0/" -e "s/.*overscan_left.*/overscan_left="' + scrollbarLength.horizontal + '/ -e "s/.*overscan_right.*/overscan_right="' + scrollbarLength.horizontal + '/ -e "s/.*overscan_top.*/overscan_top="' + scrollbarLength.vertical + '/ -e "s/.*overscan_bottom.*/overscan_bottom="' + scrollbarLength.vertical + "/ " + settings.bootConfigPath).on("close", function() { | |
| assert.reboot(); | |
| }); | |
| } | |
| }; | |
| /** | |
| * @param {!Object} action | |
| * @param {!Object} error | |
| * @return {?} | |
| */ | |
| instance.setOrientation = function(action, error) { | |
| return action.body.orientation == $scope.orientation && action.body.resolution == $scope.resolution ? self.sendSuccess(error, "Settings Saved", $scope) : void dispatch(action.body, function(err) { | |
| return err ? self.sendError(error, "Settings write error", err) : self.sendSuccess(error, "Settings Saved and Reboot", $scope); | |
| }); | |
| }; | |
| /** | |
| * @param {!Object} value | |
| * @param {!Object} message | |
| * @return {undefined} | |
| */ | |
| instance.setServerName = function(value, message) { | |
| if (value.body.server.config != data.config_server || value.body.server.media != data.media_server) { | |
| data.config_server = value.body.server.config; | |
| data.media_server = value.body.server.media; | |
| fs.writeFile(settings.pkgJson, JSON.stringify(data, null, 4), function(callback) { | |
| return callback ? self.sendError(message, "Error in changing server name", callback) : (self.sendSuccess(message, "New server name saved", $scope), client.log("info", "Exiting the node process after server name change"), process.exit(0), void 0); | |
| }); | |
| } else { | |
| self.sendSuccess(message, "New server name saved", $scope); | |
| } | |
| }; | |
| /** | |
| * @param {!Object} req | |
| * @param {!Object} res | |
| * @return {undefined} | |
| */ | |
| instance.setUser = function(req, res) { | |
| var currentFileData = require("apache-md5")(req.body.user.newpasswd); | |
| try { | |
| fs.writeFileSync(settings.root + "/htpasswd", req.body.user.name + ":" + currentFileData); | |
| self.sendSuccess(res, "password changed successfully", $scope); | |
| console.log("*** Username/Password changed ****"); | |
| client.log("info", "Exiting the node process after user name/password change"); | |
| process.exit(0); | |
| } catch (err) { | |
| client.log("error", "*** htpasswd file write error ***"); | |
| self.sendError(res, "Error in saving user settings", err); | |
| } | |
| }; | |
| /** | |
| * @param {!Object} node | |
| * @param {!Object} res | |
| * @return {?} | |
| */ | |
| instance.setSleepTimer = function(node, res) { | |
| return $scope.sleep = node.body.sleep, command($scope.sleep), instance.writeToSettings(), self.sendSuccess(res, "time set ", $scope); | |
| }; | |
| /** | |
| * @param {!Object} status | |
| * @param {!Object} message | |
| * @return {?} | |
| */ | |
| instance.setOMXVolume = function(status, message) { | |
| return $scope.omxVolume = status.body.omxVolume, that.setOMXVolume($scope.omxVolume), instance.writeToSettings(), self.sendSuccess(message, "omxplayer volume set success", $scope); | |
| }; | |
| /** | |
| * @param {!Request} req | |
| * @param {!Object} res | |
| * @return {?} | |
| */ | |
| instance.getLog = function(req, res) { | |
| var logPath; | |
| var asset = req.query.file; | |
| return asset ? (logPath = path.join(__dirname, "..", asset), void fs.stat(logPath, function(callback, postBody) { | |
| return callback ? self.sendError(res, "File is not present") : void fs.readFile(logPath, "utf8", function(callback, sysinfo) { | |
| return callback ? self.sendError(res, "File data read error") : (res.writeHead(200, { | |
| "Content-Type" : "text/plain", | |
| "Content-Length" : postBody.size, | |
| "Content-Disposition" : asset | |
| }), void res.end(sysinfo)); | |
| }); | |
| })) : self.sendError(res, "Filename is not supplied"); | |
| }; | |
| /** @type {!Array} */ | |
| params = ["secret", "installation", "orientation", "resolution", "omxVolume", "overscan", "animationEnable", "animationType", "enableLog", "reportIntervalMinutes", "systemMessagesHide", "forceTvOn", "hideWelcomeNotice", "signageBackgroundColor", "imageLetterboxed", "resizeAssets", "videoKeepAspect", "urlReloadDisable", "timeToStopVideo", "showClock", "loadPlaylistOnCompletion", "combineDefaultPlaylist", "playAllEligiblePlaylists", "shuffleContent", "alternateContent", "logo", "logox", "logoy", | |
| "TZ"]; | |
| /** | |
| * @param {?} replyToken | |
| * @param {!Object} message | |
| * @return {?} | |
| */ | |
| instance.getSettingsFile = function(replyToken, message) { | |
| return self.sendSuccess(message, "Sending config and setting files", _.pick($scope, params)); | |
| }; | |
| /** | |
| * @param {!Object} res | |
| * @param {!Object} file | |
| * @return {undefined} | |
| */ | |
| instance.setSettingsFile = function(res, file) { | |
| $scope = _.extend($scope, _.pick(res.body, params)); | |
| instance.writeToSettings(); | |
| self.sendSuccess(file, "settings updated and node restarted"); | |
| setTimeout(function() { | |
| process.exit(0); | |
| }, 100); | |
| }; | |
| /** | |
| * @param {?} name | |
| * @param {!Object} res | |
| * @return {undefined} | |
| */ | |
| instance.getWifiList = function(name, res) { | |
| /** @type {!Array} */ | |
| var pipelets = []; | |
| /** @type {!Array} */ | |
| var files = []; | |
| exec('sudo iwlist wlan0 scan | grep "ESSID:" |cut -d ":" -f 2', function(value, clusterShardData, v) { | |
| return value ? self.sendError(res, "No Access Point Found", value) : v ? self.sendError(res, "wifi read err", v) : (pipelets = clusterShardData.split("\n"), pipelets.forEach(function(a) { | |
| if (a) { | |
| a = a.replace(/"/g, ""); | |
| if (a && -1 == files.indexOf(a)) { | |
| files.push(a); | |
| } | |
| } | |
| }), self.sendSuccess(res, "wifi list", files)); | |
| }); | |
| }; | |
| /** | |
| * @param {!Function} name | |
| * @param {!Object} res | |
| * @return {undefined} | |
| */ | |
| instance.factoryReset = function(name, res) { | |
| assert.factoryReset(function(a) { | |
| if (a) { | |
| self.sendError(res, "Error in factory reset"); | |
| } else { | |
| self.sendSuccess(res, "Factory reset in Progress"); | |
| } | |
| }); | |
| }; | |
| /** | |
| * @param {number} sortOption | |
| * @param {boolean} orderOption | |
| * @return {?} | |
| */ | |
| fetchAllProducts = function(sortOption, orderOption) { | |
| return sortOption ? orderOption ? 1 : 2 : 0; | |
| }; | |
| /** @type {boolean} */ | |
| ga = true; | |
| /** @type {null} */ | |
| paintNodesTimeout = null; | |
| /** @type {boolean} */ | |
| slideFirst = false; | |
| /** | |
| * @return {undefined} | |
| */ | |
| testPageTranslation = function() { | |
| if (options.playlistOn) { | |
| /** @type {boolean} */ | |
| options.playlistOn = false; | |
| init(true, options.currentPlaylist, function() { | |
| }); | |
| } | |
| set(); | |
| }; | |
| that.browserEmitter.once("loaded", function() { | |
| client.log("debug", "Browser loaded event at pi-main"); | |
| /** @type {boolean} */ | |
| slideFirst = true; | |
| if (paintNodesTimeout) { | |
| clearTimeout(paintNodesTimeout); | |
| setTimeout(function() { | |
| /** @type {boolean} */ | |
| ga = false; | |
| testPageTranslation(); | |
| }, 1E4); | |
| } | |
| }); | |
| async.series([function(saveNotifs) { | |
| fs.readFile(settings.poweronConfig, "utf8", function(id, resdata) { | |
| if (id) { | |
| return client.log("warn", "there seems to be no _config.json file: " + id), utils.storeEvent("player", "error", "there seems to be no _config.json file: " + id), saveNotifs(); | |
| } | |
| try { | |
| /** @type {*} */ | |
| var value = JSON.parse(resdata); | |
| } catch (e) { | |
| fs.unlink(settings.poweronConfig); | |
| } | |
| return value ? (options = value, options.playlistStarttime = null, options.playlistIndex = 0, options.tvStatus = true, options.uptime = null, options.localControl = false, options.deployedPlaylists && listen(), saveNotifs()) : (client.log("error", "Unable to JSON parse _config.json file"), utils.storeEvent("player", "error", "Unable to JSON parse _config.json file"), saveNotifs()); | |
| }); | |
| }, instance.updateDiskStatus, function(fn) { | |
| fs.readFile(settings.settingsFile, "utf8", function(b, body) { | |
| if (!b) { | |
| try { | |
| /** @type {*} */ | |
| $scope = JSON.parse(body); | |
| } catch (d) { | |
| } | |
| } | |
| $scope.hideWelcomeNotice = $scope.hideWelcomeNotice || false; | |
| $scope.installation = $scope.installation || "admin"; | |
| $scope.myIpAddress = d; | |
| $scope.orientation = $scope.orientation || "landscape"; | |
| $scope.resolution = $scope.resolution || "720p"; | |
| $scope.sleep = $scope.sleep || { | |
| enable : false, | |
| ontime : null, | |
| offtime : null | |
| }; | |
| $scope.reboot = $scope.reboot || { | |
| enable : false, | |
| time : null | |
| }; | |
| that.setResolution($scope.resolution); | |
| that.setOrientation($scope.orientation); | |
| if (!options.localControl && $scope.secret && d) { | |
| initialize(); | |
| } | |
| if ($scope.hideWelcomeNotice) { | |
| fn(); | |
| } else { | |
| restore(fn); | |
| } | |
| }); | |
| }, function(saveNotifs) { | |
| exec("cat /proc/cpuinfo |grep Serial|awk '{print $3 }'").stdout.on("data", function(extension) { | |
| client.log("info", "cpu serial number: " + extension); | |
| $scope.cpuSerialNumber = extension.slice(0, extension.length - 1); | |
| require("../others/license-utils").checkForLicense($scope.installation, $scope.cpuSerialNumber, function(extension) { | |
| if (!("ttk" != $scope.installation && "admin" != $scope.installation || "pisignage.com" != element)) { | |
| /** @type {boolean} */ | |
| extension = true; | |
| } | |
| that.setLicense(extension); | |
| /** @type {boolean} */ | |
| options.licensed = extension; | |
| client.log("info", "license status: " + extension); | |
| }, element); | |
| }).on("close", function() { | |
| saveNotifs(); | |
| }); | |
| }, function(saveNotifs) { | |
| /** | |
| * @param {string} message | |
| * @return {undefined} | |
| */ | |
| var b = function(message) { | |
| var pendingFileHashes = message.split("\n"); | |
| if (pendingFileHashes[0]) { | |
| $scope.ethMac = pendingFileHashes[0]; | |
| } else { | |
| delete $scope.ethMac; | |
| } | |
| if (pendingFileHashes[1]) { | |
| $scope.wifiMac = pendingFileHashes[1]; | |
| } else { | |
| delete $scope.wifiMac; | |
| } | |
| client.log("info", "MAC Address : " + $scope.ethMac + " " + $scope.wifiMac); | |
| }; | |
| exec("ifconfig | awk '/ether/{print $2}'", function(canCreateDiscussions, e) { | |
| if (e) { | |
| b(e); | |
| saveNotifs(); | |
| } else { | |
| exec("sudo ifconfig | awk '/HWaddr/{print $5}'", function(canCreateDiscussions, mediaError, index) { | |
| if (mediaError) { | |
| b(mediaError); | |
| } else { | |
| client.log("error", "MAC Address query error: " + index); | |
| } | |
| saveNotifs(); | |
| }); | |
| } | |
| }); | |
| }, function(saveNotifs) { | |
| $scope.version = data.version; | |
| $scope.platform_version = data.platform_version; | |
| $scope.animationEnable = $scope.animationEnable || false; | |
| $scope.animationType = $scope.animationType || null; | |
| $scope.enableLog = $scope.enableLog || false; | |
| $scope.reportIntervalMinutes = $scope.reportIntervalMinutes || 5; | |
| that.setAssetLogs($scope.enableLog); | |
| that.setYoutubeDl($scope.enableYoutubeDl); | |
| that.setMpv($scope.enableMpv); | |
| that.setAnimationStatus($scope.animationEnable, $scope.animationType, true); | |
| $scope.systemMessagesHide = $scope.systemMessagesHide || false; | |
| that.setSystemMessagesHide($scope.systemMessagesHide, true); | |
| $scope.forceTvOn = $scope.forceTvOn || false; | |
| $scope.signageBackgroundColor = $scope.signageBackgroundColor || "#000"; | |
| that.setBackgroundColor($scope.signageBackgroundColor, true); | |
| $scope.imageLetterboxed = $scope.imageLetterboxed || false; | |
| $scope.resizeAssets = $scope.resizeAssets || false; | |
| that.setImageResize(fetchAllProducts($scope.resizeAssets, $scope.imageLetterboxed), true); | |
| $scope.videoKeepAspect = $scope.videoKeepAspect || false; | |
| that.setVideoKeepAspect($scope.videoKeepAspect, true); | |
| $scope.sleep = $scope.sleep || { | |
| enable : false, | |
| ontime : null, | |
| offtime : null | |
| }; | |
| $scope.reboot = $scope.reboot || { | |
| enable : false, | |
| time : null | |
| }; | |
| run($scope.reboot); | |
| end(); | |
| command($scope.sleep); | |
| $scope.urlReloadDisable = $scope.urlReloadDisable || false; | |
| that.setUrlReloadDisable($scope.urlReloadDisable, true); | |
| $scope.server = data.config_server; | |
| /** @type {string} */ | |
| $scope.connectionStatus = "Waiting"; | |
| /** @type {number} */ | |
| $scope.omxVolume = parseInt($scope.omxVolume || 0 == $scope.omxVolume ? $scope.omxVolume : 100, 10); | |
| that.setOMXVolume($scope.omxVolume); | |
| $scope.timeToStopVideo = $scope.timeToStopVideo || 0; | |
| that.setTimeToStopVideo($scope.timeToStopVideo); | |
| $scope.kioskUi = $scope.kioskUi || { | |
| enable : false | |
| }; | |
| globalDisclaimer.setupUi($scope.kioskUi); | |
| $scope.showClock = $scope.showClock || { | |
| enable : false | |
| }; | |
| $scope.emergencyMessage = $scope.emergencyMessage || { | |
| enable : false, | |
| msg : "", | |
| hPos : "middle", | |
| vPos : "middle" | |
| }; | |
| that.setDisplayClock($scope.showClock, $scope.emergencyMessage, true); | |
| saveNotifs(); | |
| }, function(saveNotifs) { | |
| exec("sudo kill $(pidof python omx.py)", function() { | |
| saveNotifs(); | |
| if ("NTSC" == $scope.resolution || "PAL" == $scope.resolution) { | |
| exec('sudo sed -i -e "s/hdmi/local/" /home/pi/omx.py'); | |
| } | |
| }); | |
| }, function(saveNotifs) { | |
| exec("sudo pkill omxplayer", function() { | |
| saveNotifs(); | |
| }); | |
| }], function() { | |
| client.testLog("config_file", options); | |
| client.testLog("settings_file", $scope); | |
| instance.writeToSettings(); | |
| utils.startLog(); | |
| client.log("debug", "Initialization done"); | |
| if (!$scope.hideWelcomeNotice) { | |
| parse(function() { | |
| that.startPlay([{ | |
| filename : "_emptynotice.html", | |
| duration : 30 | |
| }], null, "1"); | |
| }); | |
| } | |
| /** @type {number} */ | |
| paintNodesTimeout = setTimeout(function() { | |
| /** @type {boolean} */ | |
| ga = false; | |
| testPageTranslation(); | |
| }, slideFirst ? 1E4 : 3E4); | |
| /** @type {boolean} */ | |
| maxReconnectTryTimes = true; | |
| instance.startClient(); | |
| updateState(); | |
| }); | |
| /** @type {boolean} */ | |
| la = false; | |
| /** | |
| * @param {string} id | |
| * @return {?} | |
| */ | |
| start = function(id) { | |
| var maxLength; | |
| var spawn; | |
| var outFD; | |
| var errFD; | |
| var ps; | |
| return client.log("info", "**** Updating pi software ****"), la ? void client.log("info", "**** Ignoring pi update second click ****") : (id || (id = "pi-image.zip"), maxLength = process.version.slice(1, process.version.indexOf(".")), maxLength > 0 && (id = id.slice(0, id.lastIndexOf(".")) + "-v6.zip"), utils.storeEvent("player", "other", "swupdate: " + id), la = true, fs.chmodSync("misc/upgrade.sh", "755"), spawn = require("child_process").spawn, outFD = fs.openSync("/home/pi/forever.log", | |
| "a"), errFD = fs.openSync("/home/pi/forever.log", "a"), ps = spawn("misc/upgrade.sh", [data.config_server + "/releases/" + id, id], { | |
| detached : true, | |
| stdio : ["ignore", outFD, errFD] | |
| }), client.testLog("upgrade", id), void ps.unref()); | |
| }; | |
| /** @type {null} */ | |
| socket = null; | |
| /** @type {boolean} */ | |
| globalMod = false; | |
| /** @type {boolean} */ | |
| editPost = false; | |
| /** @type {boolean} */ | |
| moderates = false; | |
| /** @type {boolean} */ | |
| ua = false; | |
| /** @type {boolean} */ | |
| beforeZero = false; | |
| /** @type {boolean} */ | |
| afterZero = true; | |
| /** @type {number} */ | |
| xa = 4; | |
| /** | |
| * @param {boolean} n | |
| * @param {boolean} m | |
| * @return {undefined} | |
| */ | |
| instance.startClient = function(n, m) { | |
| var g; | |
| var url; | |
| if (n && (io = n), m ? output = m : n && (output = n, globalMod = true), io && maxReconnectTryTimes) { | |
| if (socket) { | |
| try { | |
| socket.removeAllListeners(); | |
| socket.disconnect(); | |
| } catch (redirect_params) { | |
| client.log("error", "socket disconnect exception: " + redirect_params.code); | |
| } | |
| } | |
| connect(); | |
| if (moderates) { | |
| /** @type {boolean} */ | |
| globalMod = false; | |
| } else { | |
| if (editPost) { | |
| /** @type {boolean} */ | |
| globalMod = true; | |
| } | |
| } | |
| /** @type {boolean} */ | |
| ua = false; | |
| if (globalMod) { | |
| socket = output.connect(data.config_server, { | |
| "force new connection" : true | |
| }); | |
| } else { | |
| url = /^(https?|wss?):\/\//.test(data.config_server) ? data.config_server : "https://" + data.config_server; | |
| socket = io(url, { | |
| path : "/newsocket.io", | |
| rejectUnauthorized : false | |
| }); | |
| connection = output.connect(data.config_server, { | |
| "force new connection" : true | |
| }); | |
| connection.on("connect", function() { | |
| /** @type {boolean} */ | |
| editPost = true; | |
| client.log("info", "socket.io works with 0.9.19"); | |
| if (ua) { | |
| instance.startClient(); | |
| } else { | |
| connect(); | |
| } | |
| }); | |
| } | |
| client.log("info", "starting socketio to " + data.config_server + "with ver: " + (globalMod ? "0.9.19" : "new")); | |
| socket.on("connect", function() { | |
| if (globalMod) { | |
| /** @type {boolean} */ | |
| editPost = true; | |
| } else { | |
| /** @type {boolean} */ | |
| moderates = true; | |
| } | |
| /** @type {boolean} */ | |
| beforeZero = true; | |
| /** @type {boolean} */ | |
| afterZero = false; | |
| client.log("info", "socket.io: connected to server " + push() + "with ver: " + (globalMod ? "0.9.19" : "new")); | |
| done(); | |
| /** @type {string} */ | |
| $scope.connectionStatus = "Connected"; | |
| if (xa) { | |
| xa--; | |
| if (0 == deprecatedStylingMethods.length) { | |
| updateConnz(); | |
| restore(parse); | |
| } else { | |
| parse(); | |
| } | |
| } | |
| client.testLog("socket", "connected"); | |
| }); | |
| socket.on("reconnect", function() { | |
| }); | |
| socket.on("reconnect_attempt", function() { | |
| }); | |
| socket.on("reconnect_failed", function(origErr) { | |
| if (beforeZero || afterZero) { | |
| client.log("error", "socket.io: reconnect failed event: " + origErr.message); | |
| } | |
| /** @type {boolean} */ | |
| afterZero = false; | |
| }); | |
| socket.on("reconnect_error", function() { | |
| }); | |
| socket.on("connect_error", function(origErr) { | |
| if (beforeZero || afterZero) { | |
| client.log("error", "socket.io: connect error event: " + origErr.message); | |
| } | |
| /** @type {boolean} */ | |
| beforeZero = false; | |
| /** @type {boolean} */ | |
| afterZero = false; | |
| /** @type {boolean} */ | |
| ua = true; | |
| if (!(globalMod || moderates || !editPost)) { | |
| instance.startClient(); | |
| } | |
| }); | |
| socket.on("connect_timeout", function() { | |
| if (beforeZero || afterZero) { | |
| client.log("error", "socket.io: connect timeout event"); | |
| } | |
| /** @type {boolean} */ | |
| beforeZero = false; | |
| /** @type {boolean} */ | |
| afterZero = false; | |
| }); | |
| socket.on("connect_failed", function() { | |
| if (beforeZero || afterZero) { | |
| client.log("error", "socket.io: connect failed event" + push()); | |
| } | |
| /** @type {boolean} */ | |
| beforeZero = false; | |
| /** @type {boolean} */ | |
| afterZero = false; | |
| }); | |
| socket.on("error", function(index) { | |
| client.log("error", "socket.io: error event" + push() + ";" + index); | |
| /** @type {boolean} */ | |
| beforeZero = false; | |
| }); | |
| socket.on("disconnect", function(index) { | |
| client.log("error", "socket.io: disconnect event" + push() + ";" + index); | |
| /** @type {boolean} */ | |
| beforeZero = false; | |
| /** @type {string} */ | |
| $scope.connectionStatus = "Disconnected"; | |
| if (xa) { | |
| xa--; | |
| parse(); | |
| } | |
| if ("io server disconnect" === index) { | |
| socket.connect(); | |
| } | |
| }); | |
| socket.on("status", function() { | |
| done(); | |
| }); | |
| socket.on("shell", function(eventsJsonPath) { | |
| save(eventsJsonPath); | |
| }); | |
| socket.on("config", function(data) { | |
| var g; | |
| var h; | |
| var currentFileData; | |
| var event; | |
| /** | |
| * @param {string} i | |
| * @return {?} | |
| */ | |
| var parse = function(i) { | |
| return void 0 !== data[i] && data[i] != $scope[i] ? (client.log("info", "changed settings for " + i + " from " + $scope[i] + " to " + data[i]), $scope[i] = data[i], h = true, true) : false; | |
| }; | |
| /** @type {boolean} */ | |
| beforeZero = true; | |
| nextTick(); | |
| if (data.currentTime && data.currentTime - Date.now() > 12E4) { | |
| client.log("info", "adjusting the time to server time " + (new Date(data.currentTime)).toLocaleString()); | |
| exec("sudo date -s @" + ~~(data.currentTime / 1E3), function(a, b, c) { | |
| if (a) { | |
| console.log(a); | |
| console.log(c); | |
| console.log(b); | |
| } | |
| }); | |
| } | |
| /** @type {boolean} */ | |
| g = false; | |
| /** @type {boolean} */ | |
| h = false; | |
| if (data.installation && data.secret && (data.installation != $scope.installation || data.secret != $scope.secret)) { | |
| /** @type {boolean} */ | |
| g = true; | |
| } | |
| if (parse("name")) { | |
| assert.registerHostnameChange(data.name); | |
| } | |
| $scope.currentVersion = data.currentVersion; | |
| $scope.assets = data.assets; | |
| $scope.loadPlaylistOnCompletion = data.loadPlaylistOnCompletion || false; | |
| if (data.installation) { | |
| $scope.installation = data.installation; | |
| if (!(!data.authCredentials || result.user == data.authCredentials.user && result.password == data.authCredentials.password)) { | |
| result.user = data.authCredentials.user; | |
| result.password = data.authCredentials.password; | |
| fs.writeFileSync("/home/pi/.wgetrc", "user = " + result.user + "\npassword = " + result.password); | |
| currentFileData = require("apache-md5")(data.authCredentials.password); | |
| fs.writeFileSync(s.root + "/htpasswd", data.authCredentials.user + ":" + currentFileData); | |
| } | |
| } | |
| if (!(void 0 === data.animationEnable || data.animationEnable == $scope.animationEnable && data.animationType == $scope.animationType)) { | |
| if (data.animationEnable) { | |
| /** @type {boolean} */ | |
| $scope.animationEnable = true; | |
| $scope.animationType = data.animationType; | |
| that.setAnimationStatus($scope.animationEnable, $scope.animationType); | |
| } else { | |
| /** @type {boolean} */ | |
| $scope.animationEnable = false; | |
| /** @type {null} */ | |
| $scope.animationType = null; | |
| that.setAnimationStatus(false, null, null); | |
| } | |
| /** @type {boolean} */ | |
| h = true; | |
| } | |
| if (parse("sshPassword")) { | |
| assert.changeSshPassword($scope.sshPassword); | |
| } | |
| if (parse("signageBackgroundColor")) { | |
| that.setBackgroundColor($scope.signageBackgroundColor); | |
| } | |
| event = parse("imageLetterboxed"); | |
| if (parse("resizeAssets") || event) { | |
| that.setImageResize(fetchAllProducts($scope.resizeAssets, $scope.imageLetterboxed)); | |
| } | |
| if (parse("videoKeepAspect")) { | |
| that.setVideoKeepAspect($scope.videoKeepAspect); | |
| } | |
| if (parse("systemMessagesHide")) { | |
| that.setSystemMessagesHide($scope.systemMessagesHide); | |
| } | |
| parse("forceTvOn"); | |
| parse("hideWelcomeNotice"); | |
| if (parse("omxVolume")) { | |
| that.setOMXVolume($scope.omxVolume); | |
| } | |
| if (parse("timeToStopVideo")) { | |
| that.setTimeToStopVideo($scope.timeToStopVideo); | |
| } | |
| if (parse("enableLog")) { | |
| that.setAssetLogs($scope.enableLog); | |
| } | |
| parse("reportIntervalMinutes"); | |
| if (parse("enableYoutubeDl")) { | |
| that.setYoutubeDl($scope.enableYoutubeDl); | |
| } | |
| if (parse("enableMpv")) { | |
| that.setMpv($scope.enableMpv); | |
| } | |
| parse("combineDefaultPlaylist"); | |
| parse("playAllEligiblePlaylists"); | |
| parse("shuffleContent"); | |
| parse("alternateContent"); | |
| if (parse("urlReloadDisable")) { | |
| that.setUrlReloadDisable($scope.urlReloadDisable); | |
| } | |
| if (data.logo && (data.logo != $scope.logo || !$scope.logo) || !data.logo && $scope.logo || data.logox != $scope.logox || data.logoy != $scope.logoy) { | |
| $scope.logo = data.logo; | |
| $scope.logox = data.logox; | |
| $scope.logoy = data.logoy; | |
| end(); | |
| /** @type {boolean} */ | |
| h = true; | |
| } | |
| if (data.orientation && $scope.orientation && data.orientation != $scope.orientation || data.resolution && $scope.resolution && data.resolution != $scope.resolution) { | |
| dispatch(data); | |
| } | |
| if (!(!data.sleep || $scope.sleep && data.sleep.enable == $scope.sleep.enable && data.sleep.ontime == $scope.sleep.ontime && data.sleep.offtime == $scope.sleep.offtime)) { | |
| $scope.sleep = data.sleep; | |
| command($scope.sleep); | |
| /** @type {boolean} */ | |
| h = true; | |
| } | |
| if (!(!data.reboot || $scope.reboot && data.reboot.enable == $scope.reboot.enable && data.reboot.time == $scope.reboot.time)) { | |
| $scope.reboot = data.reboot; | |
| run($scope.reboot); | |
| /** @type {boolean} */ | |
| h = true; | |
| } | |
| if (!(!data.showClock || $scope.showClock && _.isEqual(data.showClock, $scope.showClock))) { | |
| $scope.showClock = data.showClock; | |
| that.setDisplayClock($scope.showClock, $scope.emergencyMessage); | |
| /** @type {boolean} */ | |
| h = true; | |
| } | |
| if (!(!data.kioskUi || $scope.kioskUi && _.isEqual(data.kioskUi, $scope.kioskUi))) { | |
| $scope.kioskUi = data.kioskUi; | |
| globalDisclaimer.setupUi($scope.kioskUi); | |
| /** @type {boolean} */ | |
| h = true; | |
| } | |
| if (!(!data.emergencyMessage || $scope.emergencyMessage && _.isEqual(data.emergencyMessage, $scope.emergencyMessage))) { | |
| $scope.emergencyMessage = data.emergencyMessage; | |
| that.setDisplayClock($scope.showClock, $scope.emergencyMessage); | |
| if ($scope.emergencyMessage.enable) { | |
| assert.getCecStatus(true, true, function(mediaTemplate) { | |
| options.cecTvStatus = mediaTemplate; | |
| }); | |
| } | |
| /** @type {boolean} */ | |
| h = true; | |
| } | |
| if (data.TZ && $scope.TZ != data.TZ) { | |
| $scope.TZ = data.TZ; | |
| exec("sed -i \"s|.*TZ=.*|TZ='" + data.TZ + "'; export TZ|\" /home/pi/.bash_profile").on("close", function() { | |
| client.log("info", "Timezone changed to " + data.TZ); | |
| instance.writeToSettings(); | |
| exec("source /home/pi/.bashrc"); | |
| }); | |
| } | |
| options.groupTicker = data.groupTicker; | |
| if (g) { | |
| /** @type {boolean} */ | |
| options.localControl = false; | |
| require("../others/license-utils").checkForLicense($scope.installation, $scope.cpuSerialNumber, function(extension) { | |
| if (!("ttk" != $scope.installation && "admin" != $scope.installation || "pisignage.com" != element)) { | |
| /** @type {boolean} */ | |
| extension = true; | |
| } | |
| that.setLicense(extension); | |
| /** @type {boolean} */ | |
| options.licensed = extension; | |
| client.log("info", "license status: " + extension); | |
| }, element); | |
| setup(data); | |
| } else { | |
| if (!hasSongChanged && !isReplayingSong && data.playlists && data.playlists.length > 0 && (parseInt(data.lastDeployed) > options.lastUpload || !options.localControl && !_.isEqual(data.playlists, options.deployedPlaylists))) { | |
| /** @type {boolean} */ | |
| options.localControl = false; | |
| client.log("info", "*** Downloading files,Group deploy time: " + (new Date(parseInt(data.lastDeployed))).toLocaleString() + ", Player upload time: " + (new Date(options.lastUpload)).toLocaleString()); | |
| $scope.assetsValidity = data.assetsValidity; | |
| initialize(data.playlists, null, data.assets, true); | |
| } | |
| } | |
| if (h) { | |
| instance.writeToSettings(); | |
| } | |
| }); | |
| socket.on("sync", function(name, result, mediaTemplate, groupsChanged, status, force, data, temp, fn, pirates) { | |
| client.log("info", "*** sync initiated at server: " + (new Date).toLocaleString()); | |
| utils.storeEvent("player", "network", "sync initiated from server"); | |
| /** @type {boolean} */ | |
| options.localControl = false; | |
| options.groupTicker = mediaTemplate; | |
| /** @type {!Object} */ | |
| $scope.assets = result; | |
| /** @type {string} */ | |
| $scope.assetsValidity = pirates; | |
| $scope.logo = groupsChanged || null; | |
| $scope.logox = status || 10; | |
| $scope.logoy = force || 10; | |
| $scope.combineDefaultPlaylist = data || false; | |
| $scope.loadPlaylistOnCompletion = fn || false; | |
| that.setOMXVolume(temp); | |
| done(true); | |
| initialize(name, function(a) { | |
| if (-1 != a) { | |
| end(); | |
| } | |
| }, result, true); | |
| }); | |
| socket.on("restart", function() { | |
| if (!g) { | |
| /** @type {boolean} */ | |
| g = true; | |
| client.log("info", "**** Restarting the playlist ****"); | |
| error(function() { | |
| /** @type {boolean} */ | |
| g = false; | |
| }); | |
| } | |
| }); | |
| socket.on("swupdate", function(b) { | |
| start(b); | |
| }); | |
| socket.on("snapshot", function() { | |
| check(function(a, instancesTypes) { | |
| if (filter()) { | |
| socket.emit("snapshot", { | |
| playerInfo : $scope, | |
| data : instancesTypes | |
| }); | |
| } | |
| }); | |
| }); | |
| socket.on("cmd", function(a, event) { | |
| switch(a) { | |
| case "debuglevel": | |
| log(event.level); | |
| break; | |
| case "tvpower": | |
| if (event.off) { | |
| on(); | |
| } else { | |
| reset(); | |
| } | |
| } | |
| }); | |
| socket.on("upload_ack", function(a) { | |
| if (-1 == a.indexOf("forever_out")) { | |
| utils.deleteLog(a); | |
| } | |
| }); | |
| socket.on("license", function(a, b) { | |
| client.log("info", "License download request for " + a + " with id : " + b + " received"); | |
| fs.unlink(settings.root + "/../license_" + b + ".txt", function() { | |
| process.exit(0); | |
| }); | |
| }); | |
| resolve(); | |
| } | |
| }; | |
| /** @type {number} */ | |
| Ca = 0; | |
| /** | |
| * @return {undefined} | |
| */ | |
| _resolve = function() { | |
| assert.wlanReboot(function() { | |
| instance.startClient(); | |
| }); | |
| }; | |
| /** | |
| * @param {string} obj | |
| * @param {?} data | |
| * @return {undefined} | |
| */ | |
| instance.uploadLog = function(obj, data) { | |
| if (filter()) { | |
| socket.emit("upload", $scope.cpuSerialNumber, obj, data); | |
| client.testLog("upload", obj); | |
| } | |
| }; | |
| /** | |
| * @return {?} | |
| */ | |
| instance.statusLog = function() { | |
| var points = { | |
| connected : filter(), | |
| tvUptime : options.cecTvStatus | |
| }; | |
| return options.currentPlaylist && (points["playlist_" + options.currentPlaylist.replace(/[^a-zA-Z0-9]/g, "_")] = 1), points; | |
| }; | |
| /** @type {number} */ | |
| index = 0; | |
| /** | |
| * @param {?} replyToken | |
| * @param {!Object} message | |
| * @return {?} | |
| */ | |
| instance.piswupdate = function(replyToken, message) { | |
| return start(), self.sendSuccess(message, "Player will update the software & reboot"); | |
| }; | |
| /** | |
| * @param {?} url | |
| * @param {?} article | |
| * @param {string} id | |
| * @param {?} done | |
| * @return {undefined} | |
| */ | |
| renderTemplate = function(url, article, id, done) { | |
| var originRuleContent; | |
| fs.readFile(url, "utf8", function(passwordUpdateErr, FeedbackTemplate) { | |
| if (passwordUpdateErr) { | |
| done(passwordUpdateErr); | |
| } else { | |
| originRuleContent = Handlebars.compile(FeedbackTemplate)({ | |
| pageData : article | |
| }); | |
| fs.writeFile(id, originRuleContent, function(passwordUpdateErr) { | |
| if (passwordUpdateErr) { | |
| done(passwordUpdateErr); | |
| } else { | |
| client.log("info", "Created: " + id); | |
| done(); | |
| } | |
| }); | |
| } | |
| }); | |
| }; | |
| /** @type {null} */ | |
| stop_timer = null; | |
| /** @type {boolean} */ | |
| kb = false; | |
| process.on("SIGUSR2", function() { | |
| /** | |
| * @return {undefined} | |
| */ | |
| var init = function() { | |
| var data = merge(); | |
| options.currentPlaylist = data.selectedPlaylist; | |
| options.playlistIndex = data.index; | |
| bufferedRecords = data.otherSelectedPlaylists; | |
| error(function() { | |
| if (data.isEventPlaylist && users[data.index].settings.event && users[data.index].settings.event.duration) { | |
| setTimeout(function() { | |
| /** @type {boolean} */ | |
| option = false; | |
| /** @type {boolean} */ | |
| kb = false; | |
| init(); | |
| }, 1E3 * users[data.index].settings.event.duration); | |
| } else { | |
| /** @type {boolean} */ | |
| kb = false; | |
| } | |
| }); | |
| }; | |
| return kb ? void client.log("info", "SIGUSR2 event, skipping due to debounce") : (client.log("info", "SIGUSR2 event, scheduling event playlist"), kb = true, void(users.length > 0 ? (option = !option, init()) : (client.log("info", "no event playlist available, continuing to play normal playlist"), globalDisclaimer.showUi()))); | |
| }).on("exit", function() { | |
| client.log("debug", "Exiting node process for restart"); | |
| process.kill(process.pid, "SIGTERM"); | |
| }); | |
| /** | |
| * @return {undefined} | |
| */ | |
| instance.uploadForeverLog = function() { | |
| }; | |
| }); | |
| require.register("./app/controllers/pi-viewer.js", function(a, self, require) { | |
| /** | |
| * @param {!Function} fn | |
| * @return {undefined} | |
| */ | |
| function expect(fn) { | |
| exec(opts.systemScript + "--clean-chrome-session", function(pseudoType, canCreateDiscussions, type) { | |
| if (pseudoType || type) { | |
| console.log("error", "Error in changing restore session flag" + pseudoType + " " + type); | |
| } | |
| fn(); | |
| }); | |
| } | |
| /** | |
| * @return {undefined} | |
| */ | |
| function selectReportingCycle() { | |
| /** @type {boolean} */ | |
| v = true; | |
| clearTimeout(endCallTimeout); | |
| } | |
| /** | |
| * @return {?} | |
| */ | |
| function test() { | |
| var dest; | |
| var rotateToDirection; | |
| var karmaArguments; | |
| var val; | |
| if (r = false, v = false, child) { | |
| if (args) { | |
| return void exec("killall -s 9 chromium-browser", function() { | |
| console.log("info", "killing previous chrome browser, " + (child && child.pid)); | |
| }); | |
| } | |
| console.log("info", "killing previous uzbl:" + child.pid); | |
| child.kill(); | |
| } | |
| /** @type {boolean} */ | |
| selItem = true; | |
| if (key.indexOf("custom") >= 0) { | |
| rotateToDirection = fs.existsSync(opts.mediaPath + dir); | |
| dest = rotateToDirection ? opts.mediaPath + dir : opts.root + "/templates/custom_layout.html"; | |
| } else { | |
| /** @type {string} */ | |
| dest = opts.root + "/templates/" + key + ".html"; | |
| } | |
| /** @type {!Array} */ | |
| karmaArguments = ["--allow-file-access-from-files", "--disable-session-crashed-bubble", "--disable-infobars", "--disable-notifications", "--disable-device-discovery-notifications", "--disable-quic", "--disable-features=TranslateUI", "--disable-popup-blocking", "--disable-web-security", "--user-data-dir=/home/pi/.config/chromium/Default", "--enable-fast-unload", "--enable-tcp-fast-open", "--noerrdialogs", "--no-first-run", "--proxy-auto-detect", "--start-fullscreen", "--start-maximized ", "--disk-cache-size=30000000", | |
| "--kiosk", "--kiosk-printing", "--disable-pinch", "--overscroll-history-navigation=0", dest]; | |
| child = args ? spawn("chromium-browser", karmaArguments, { | |
| stdio : "pipe" | |
| }) : "v0.9.0" == timerIndex ? spawn("uzbl", ["--geometry=maximized", "-c", "-", dest, "-p"], { | |
| stdio : "pipe" | |
| }) : spawn("uzbl", ["-g", "maximized", "-c", "-", "--uri", dest, "-p"], { | |
| stdio : "pipe" | |
| }); | |
| console.log("info", "Browser loading " + dest + "; Running as PID " + child.pid); | |
| child.on("error", function(step_name) { | |
| console.log("error", "browser spawn error: " + step_name); | |
| }); | |
| if (child) { | |
| child.once("exit", function(a, step_name) { | |
| /** @type {null} */ | |
| child = null; | |
| console.log("info", "browser stopped with code " + a + " and signal " + step_name); | |
| if (args) { | |
| expect(function() { | |
| test(); | |
| }); | |
| } | |
| }); | |
| child.stdout.on("data", function(val) { | |
| var rawStr; | |
| var validationVM; | |
| if (!args) { | |
| rawStr = val.toString("utf8"); | |
| validationVM = v; | |
| if (app) { | |
| if (0 == app.indexOf("uri") && rawStr.indexOf("LOAD_FINISH") >= 0) { | |
| selectReportingCycle(); | |
| } | |
| if (0 != app.indexOf("uri") && rawStr.indexOf("COMMAND_EXECUTED") >= 0) { | |
| selectReportingCycle(); | |
| } | |
| } | |
| } | |
| }); | |
| child.stderr.on("data", function(val) { | |
| console.log("info", "browser stderr: " + val.toString("utf8")); | |
| }); | |
| child.stdin.on("error", function(step_name) { | |
| console.log("info", "browser stdin error: " + step_name); | |
| }); | |
| if (args) { | |
| if (data.currentTicker) { | |
| get(data.currentTicker); | |
| } | |
| type(); | |
| } else { | |
| /** @type {string} */ | |
| val = fromContext ? "/misc/uzblrc-v2" : "/misc/uzblrc"; | |
| child.stdin.write(fs.readFileSync(opts.root + val) + "\n", function(step_name) { | |
| if (step_name) { | |
| console.log("error", "uzbl command callback error: " + step_name); | |
| } | |
| selectReportingCycle(); | |
| next(child); | |
| if (data.currentTicker) { | |
| get(data.currentTicker); | |
| } | |
| type(); | |
| }); | |
| } | |
| } | |
| } | |
| /** | |
| * @param {number} types | |
| * @return {undefined} | |
| */ | |
| function type(types) { | |
| /** @type {boolean} */ | |
| opt_newBuffer = true; | |
| types = types || 0; | |
| error("js window.setInitialParameters(" + whatToScale + ',"' + colour + '",' + validationVM + "," + types + "," + optionUsed2 + ',"' + hPosPropUnused + '",' + (showingAlertTitle ? false : settings.showClock) + ")"); | |
| } | |
| /** | |
| * @param {string} s | |
| * @return {?} | |
| */ | |
| function error(s) { | |
| if (s && results.push(s), 0 == results.length) { | |
| return void console.log("info", "Browser: No command to issue"); | |
| } | |
| if (!v) { | |
| return clearTimeout(timeout), void(timeout = setTimeout(error, 500)); | |
| } | |
| if (v = false, child) { | |
| try { | |
| app = results[0]; | |
| if (args) { | |
| /** @type {number} */ | |
| endCallTimeout = setTimeout(function() { | |
| console.log("error", "Chrome: no completion event: " + app); | |
| test(); | |
| exit(); | |
| }, 1E4); | |
| uploadFile(results[0]); | |
| } else { | |
| /** @type {number} */ | |
| endCallTimeout = setTimeout(function() { | |
| /** @type {boolean} */ | |
| v = true; | |
| console.log("error", "uzbl: no completion event: " + app); | |
| }, 3E3); | |
| if (fromContext && 0 == results[0].indexOf("js")) { | |
| /** @type {string} */ | |
| results[0] = "js page string '" + results[0].slice(3) + "'"; | |
| } | |
| child.stdin.write(results[0] + "\n", function(step_name) { | |
| if (step_name) { | |
| console.log("error", "uzbl command callback error: " + step_name); | |
| } | |
| }); | |
| } | |
| } catch (redirect_params) { | |
| console.log("error", "browser stdin write exception: " + redirect_params.code); | |
| } | |
| } else { | |
| console.log("warn", "No browser instance, restarting the browser"); | |
| test(); | |
| } | |
| results.shift(); | |
| if (0 == results.length) { | |
| clearTimeout(timeout); | |
| /** @type {null} */ | |
| timeout = null; | |
| } else { | |
| error(); | |
| } | |
| } | |
| /** | |
| * @param {boolean} parameters | |
| * @return {undefined} | |
| */ | |
| function spawnPio(parameters) { | |
| clearTimeout(_input_filter_changed); | |
| if (parameters && !args) { | |
| /** @type {number} */ | |
| _input_filter_changed = setTimeout(function() { | |
| exec("ps aux |grep uzbl-core|awk '{print $4 }'").stdout.on("data", function(id_local) { | |
| /** @type {boolean} */ | |
| zb = parseInt(id_local) > 70; | |
| }).on("close", function() { | |
| spawnPio(true); | |
| }); | |
| }, 6E5); | |
| } | |
| } | |
| /** | |
| * @param {!Object} s | |
| * @param {!Function} callback | |
| * @return {undefined} | |
| */ | |
| function next(s, callback) { | |
| if (!callback) { | |
| /** | |
| * @return {undefined} | |
| */ | |
| callback = function() { | |
| }; | |
| } | |
| /** @type {!Array} */ | |
| var tagOneVMs = []; | |
| /** @type {!Array} */ | |
| var req = []; | |
| h.series([function(saveNotifs) { | |
| fs.readFile("/home/pi/.local/share/uzbl/cookies.txt", "utf8", function(isRoot, compact) { | |
| if (!(isRoot || !compact)) { | |
| tagOneVMs = tagOneVMs.concat(compact.split("\n")); | |
| } | |
| saveNotifs(); | |
| }); | |
| }, function(saveNotifs) { | |
| fs.readFile("/home/pi/.local/share/uzbl/session-cookies.txt", "utf8", function(isRoot, compact) { | |
| if (!(isRoot || !compact)) { | |
| tagOneVMs = tagOneVMs.concat(compact.split("\n")); | |
| } | |
| saveNotifs(); | |
| }); | |
| }, function(objCallback) { | |
| var b; | |
| var aDraggedText; | |
| var baud_rate; | |
| var b_field; | |
| var last_bin; | |
| var sender; | |
| var i; | |
| tagOneVMs.forEach(function(clusterShardData) { | |
| if (clusterShardData) { | |
| b = clusterShardData.split("\t"); | |
| if (b[0] && b[6]) { | |
| aDraggedText = b[0].replace(/^#HttpOnly_/i, ""); | |
| baud_rate = b[2]; | |
| /** @type {string} */ | |
| sender = b[3].match(/TRUE/i) ? "https" : "http"; | |
| i = b[4]; | |
| b_field = b[5]; | |
| last_bin = b[6]; | |
| req.push("cookie add " + aDraggedText + " " + baud_rate + " " + b_field + " " + last_bin + " " + sender + " " + i); | |
| } | |
| } | |
| }); | |
| console.log(req); | |
| objCallback(); | |
| }], function() { | |
| if (s && req.length) { | |
| /** @type {string} */ | |
| var c = req.join("\n") + "\n"; | |
| s.stdin.write(c, function(step_name) { | |
| if (step_name) { | |
| console.log("error", "error in writing session cookie data: '" + step_name); | |
| } else { | |
| console.log("info", "**** browser cookie added ****"); | |
| console.log("info", c); | |
| } | |
| callback(); | |
| }); | |
| } else { | |
| callback(); | |
| } | |
| }); | |
| } | |
| /** | |
| * @return {undefined} | |
| */ | |
| function generate() { | |
| var f; | |
| var rotateToDirection; | |
| /** @type {number} */ | |
| var thing = 0; | |
| clearTimeout(paintNodesTimeout); | |
| if ("landscape" == orientation && key.indexOf("p") >= 0) { | |
| /** @type {number} */ | |
| thing = -1 == key.indexOf("270") ? 90 : 270; | |
| } | |
| if (key.indexOf("custom") >= 0) { | |
| rotateToDirection = fs.existsSync(opts.mediaPath + dir); | |
| f = rotateToDirection ? opts.mediaPath + dir : opts.root + "/templates/custom_layout.html"; | |
| } else { | |
| /** @type {string} */ | |
| f = opts.root + "/templates/" + key + ".html"; | |
| } | |
| error("uri " + f); | |
| type(thing); | |
| } | |
| /** | |
| * @return {undefined} | |
| */ | |
| function pause() { | |
| clearTimeout(paintNodesTimeout); | |
| error("js window.clearZoneAll()"); | |
| if (server) { | |
| server.kill(); | |
| } | |
| } | |
| /** | |
| * @return {undefined} | |
| */ | |
| function compile() { | |
| clearTimeout(paintNodesTimeout); | |
| error('js window.clearZone("main")'); | |
| if (server) { | |
| server.kill(); | |
| } | |
| } | |
| /** | |
| * @param {string} idx | |
| * @return {undefined} | |
| */ | |
| function get4Parity(idx) { | |
| error('js window.clearZone("' + idx + '")'); | |
| } | |
| /** | |
| * @param {string} url | |
| * @return {?} | |
| */ | |
| function fetch(url) { | |
| /** @type {string} */ | |
| var b = encodeURIComponent(url); | |
| /** @type {string} */ | |
| var arr = b.replace(/%25([0-9a-f]{2})/i, "%$1"); | |
| return arr; | |
| } | |
| /** | |
| * @param {string} port | |
| * @param {!Function} callback | |
| * @param {boolean} filepath | |
| * @param {number} d | |
| * @param {string} event | |
| * @param {number} arg | |
| * @return {undefined} | |
| */ | |
| function create(port, callback, filepath, d, event, arg) { | |
| var list; | |
| var buffer; | |
| var t; | |
| var r; | |
| var firstLevel1Element; | |
| var worstItem; | |
| var res; | |
| var val; | |
| var basename = handle_static(filepath); | |
| compile(); | |
| if (args) { | |
| list = basename.split("+"); | |
| buffer = list[0].split("x"); | |
| t = buffer[0]; | |
| r = buffer[1]; | |
| firstLevel1Element = list[1]; | |
| worstItem = list[2]; | |
| if (d) { | |
| /** @type {number} */ | |
| t = t / d; | |
| /** @type {number} */ | |
| r = r / d; | |
| } | |
| /** @type {!Array} */ | |
| res = ["--allow-file-access-from-files", "--disable-session-crashed-bubble", "--disable-infobars", "--disable-notifications", "--disable-device-discovery-notifications", "--disable-quic", "--disable-features=TranslateUI", "--disable-popup-blocking", "--noerrdialogs", "--no-first-run", "--disable-pinch", "--overscroll-history-navigation=0", "--kiosk-printing", "--user-data-dir=/home/pi/.config/chromium/weblink", "--window-size=" + t + "," + r, "--window-position=" + firstLevel1Element + "," + | |
| worstItem]; | |
| if (!validationVM) { | |
| res.push("--incognito"); | |
| } | |
| if (filepath && name % 2 == 0) { | |
| res.push("--kiosk"); | |
| } | |
| if (d) { | |
| res.push("--force-device-scale-factor=" + d); | |
| } | |
| res.push("--app=" + port); | |
| server = spawn("chromium-browser", res); | |
| if (event) { | |
| /** @type {number} */ | |
| arg = arg && !isNaN(parseInt(arg)) ? 1E3 * parseInt(arg) : 1E4; | |
| setTimeout(function() { | |
| event.split(",").forEach(function(clusterShardData) { | |
| var filteredContent = clusterShardData.split("+"); | |
| if (filteredContent.length > 1) { | |
| assert.keyTap(filteredContent[filteredContent.length - 1], filteredContent.slice(0, -1)); | |
| } else { | |
| if (1 == filteredContent.length) { | |
| assert.keyTap(filteredContent[0]); | |
| } | |
| } | |
| }); | |
| console.log("sending keys to browser: " + event.split(",")); | |
| }, arg); | |
| } | |
| server.on("error", function(spofHosts) { | |
| console.log("error: " + spofHosts); | |
| }); | |
| } else { | |
| server = "v0.9.0" == timerIndex ? spawn("uzbl", ["--geometry=" + basename, port, "-c", "-", "-p"], { | |
| stdio : "pipe" | |
| }) : spawn("uzbl", ["-g", basename, "--uri", port, "-c", "-", "-p"], { | |
| stdio : "pipe" | |
| }); | |
| /** @type {string} */ | |
| val = fromContext ? "/misc/uzblrc-v2" : "/misc/uzblrc"; | |
| server.stdin.write(fs.readFileSync(opts.root + val) + "\n", function(step_name) { | |
| if (step_name) { | |
| console.log("error", "uzbl command callback error: " + step_name); | |
| } | |
| next(server); | |
| }); | |
| } | |
| server.once("exit", function() { | |
| }); | |
| } | |
| /** | |
| * @return {undefined} | |
| */ | |
| function killAll() { | |
| if (server) { | |
| server.kill(); | |
| /** @type {null} */ | |
| server = null; | |
| } | |
| } | |
| /** | |
| * @param {number} index | |
| * @return {undefined} | |
| */ | |
| function success(index) { | |
| if ("1080p" == autoReview) { | |
| index = index + 2; | |
| } | |
| if ("landscape" == orientation && key.indexOf("p") >= 0) { | |
| /** @type {number} */ | |
| currentY = -1 == key.indexOf("270") ? 90 : 270; | |
| index = index + 4; | |
| } else { | |
| /** @type {number} */ | |
| currentY = 0; | |
| } | |
| /** @type {number} */ | |
| name = index; | |
| l = tail ? tail : styles[key][index]; | |
| $scope.getDisplayProperties(function(a, boardNameToTest) { | |
| if (boardNameToTest && boardNameToTest.indexOf("NTSC") >= 0) { | |
| /** @type {string} */ | |
| leave = firstAvailCol; | |
| /** @type {string} */ | |
| l = firstAvailCol; | |
| } else { | |
| if (boardNameToTest && boardNameToTest.indexOf("PAL") >= 0) { | |
| /** @type {string} */ | |
| leave = tmpA; | |
| /** @type {string} */ | |
| l = tmpA; | |
| } | |
| } | |
| }); | |
| } | |
| /** | |
| * @return {undefined} | |
| */ | |
| function toggleRecovery() { | |
| if (ongoingMessage) { | |
| success(0); | |
| if (child && !selItem) { | |
| /** @type {boolean} */ | |
| selItem = true; | |
| error("js window.clearTicker()"); | |
| } | |
| /** @type {boolean} */ | |
| settings.tickerEnable = false; | |
| log(); | |
| } else { | |
| get(" "); | |
| } | |
| } | |
| /** | |
| * @param {string} value | |
| * @return {undefined} | |
| */ | |
| function get(value) { | |
| /** @type {string} */ | |
| var type = data.behavior || "slide"; | |
| /** @type {number} */ | |
| var divaInstance = data.textSpeed || 3; | |
| if (!ongoingMessage) { | |
| /** @type {string} */ | |
| type = "scroll"; | |
| if ("slide" != type) { | |
| value = value + change; | |
| } | |
| } | |
| if (0 == type.indexOf("openvg")) { | |
| success(0); | |
| /** @type {boolean} */ | |
| settings.tickerEnable = true; | |
| settings.tickerX = data.tickerX; | |
| settings.tickerY = data.tickerY; | |
| settings.tickerWidth = data.tickerWidth; | |
| /** @type {number} */ | |
| settings.tickerSpeed = divaInstance; | |
| /** @type {number} */ | |
| settings.tickerDir = "left" == type.replace(/openvg_/, "") ? 0 : 1; | |
| settings.tickerFontSize = data.tickerFontSize; | |
| /** @type {string} */ | |
| settings.tickerText = value; | |
| if (child && !selItem) { | |
| /** @type {boolean} */ | |
| selItem = true; | |
| error("js window.clearTicker()"); | |
| } | |
| } else { | |
| /** @type {boolean} */ | |
| selItem = false; | |
| /** @type {boolean} */ | |
| settings.tickerEnable = false; | |
| success(1); | |
| error('js window.setTicker("' + fetch(value) + '","' + type + '","' + divaInstance + '")'); | |
| } | |
| log(); | |
| } | |
| /** | |
| * @param {string} type | |
| * @param {number} name | |
| * @return {undefined} | |
| */ | |
| function f(type, name) { | |
| /** | |
| * @param {number} depth | |
| * @return {undefined} | |
| */ | |
| var test = function(depth) { | |
| if (depth) { | |
| /** @type {number} */ | |
| input_filter_changed = setTimeout(function() { | |
| if (depth > 0) { | |
| f(type, depth - 1); | |
| } | |
| }, 1e3); | |
| } | |
| }; | |
| clearTimeout(input_filter_changed); | |
| /** @type {number} */ | |
| settings.eMsgCmd = auto; | |
| /** @type {string} */ | |
| settings.eMsg = "Playing " + (name ? "(duration: " + name + " ) " : "") + type; | |
| /** @type {number} */ | |
| settings.eMsgHorizontal = chat; | |
| /** @type {number} */ | |
| settings.eMsgVertical = divaInstance; | |
| log(); | |
| test(name); | |
| } | |
| /** | |
| * @param {string} undefOnly | |
| * @return {undefined} | |
| */ | |
| function extend(undefOnly) { | |
| error('js window.changeTickerStyle("' + undefOnly + '")'); | |
| } | |
| /** | |
| * @param {boolean} obj | |
| * @return {?} | |
| */ | |
| function join(obj) { | |
| if (tail && !wrapped || leave || !obj) { | |
| return l; | |
| } | |
| /** @type {string} */ | |
| var i = "1"; | |
| return key.indexOf("p270") >= 0 ? i = "2ap270" : key.indexOf("p") >= 0 && (i = "2ap"), styles[i][name]; | |
| } | |
| /** | |
| * @return {?} | |
| */ | |
| function on() { | |
| return leave ? "local" : options.playing ? "hdmi" : "both"; | |
| } | |
| /** | |
| * @param {string} width | |
| * @param {!Function} cb | |
| * @param {boolean} args | |
| * @param {number} n | |
| * @param {?} event | |
| * @param {!Object} fn | |
| * @return {undefined} | |
| */ | |
| function start(width, cb, args, n, event, fn) { | |
| var path; | |
| var m; | |
| var c; | |
| var p; | |
| var className = field; | |
| /** @type {boolean} */ | |
| var j = false; | |
| /** @type {string} */ | |
| var GITHUB_API_SERVER = cover ? "mpv" : "omx"; | |
| var url = join(args); | |
| if (cover) { | |
| /** @type {!Array} */ | |
| path = ["mpv", "--video-rotate=" + currentY, "--geometry=" + extname(url), "--volume=" + attributeName]; | |
| if (Array.isArray(width)) { | |
| /** @type {!Array<?>} */ | |
| path = path.concat(width); | |
| } else { | |
| path.push(width); | |
| } | |
| } else { | |
| /** @type {!Array} */ | |
| path = ["omxplayer", "--orientation", currentY, "--win", url, "--vol", a, "--no-osd", "-o", on(), width]; | |
| } | |
| if (rightIndicator) { | |
| if (cover) { | |
| path.push("--keepaspect"); | |
| } else { | |
| path.push("--aspect-mode", "letterbox"); | |
| } | |
| } else { | |
| if (cover) { | |
| path.push("--no-keepaspect"); | |
| } | |
| } | |
| if (event) { | |
| if (cover) { | |
| path.push("--mute"); | |
| } else { | |
| path.push("-n", "-1"); | |
| } | |
| } else { | |
| forEach(); | |
| /** @type {string} */ | |
| value = width; | |
| /** @type {boolean} */ | |
| productBuilt = false; | |
| /** @type {boolean} */ | |
| j = true; | |
| } | |
| if (n) { | |
| /** @type {number} */ | |
| m = parseInt(n / 3600); | |
| /** @type {number} */ | |
| c = parseInt((n - 60 * m) / 60); | |
| /** @type {number} */ | |
| p = n - 60 * (60 * m + c); | |
| if (10 > m) { | |
| /** @type {string} */ | |
| m = "0" + m; | |
| } | |
| if (10 > c) { | |
| /** @type {string} */ | |
| c = "0" + c; | |
| } | |
| if (10 > p) { | |
| /** @type {string} */ | |
| p = "0" + p; | |
| } | |
| if (cover) { | |
| path.push("--start=+" + m + ":" + c + ":" + p); | |
| } else { | |
| path.push("--pos", m + ":" + c + ":" + p); | |
| } | |
| } | |
| if (!(inputWin || addChar || !(1 == list.length && list[0].filename && list[0].filename.match(opts.videoRegex) || cover && fn))) { | |
| if (cover && fn && list.length > 1) { | |
| path.push("--loop-playlist"); | |
| } else { | |
| path.push("--loop"); | |
| } | |
| setTimeout(function() { | |
| clearTimeout(openTimeout); | |
| }, 0); | |
| } | |
| node = spawn("sudo", path, { | |
| stdio : "pipe" | |
| }); | |
| node.once("exit", function(a, step_name) { | |
| console.log("debug", "omx exit event with code " + a + "," + step_name); | |
| if (j) { | |
| /** @type {boolean} */ | |
| productBuilt = true; | |
| /** @type {string} */ | |
| value = ""; | |
| } | |
| if (cb) { | |
| clearTimeout(openTimeout); | |
| cb(className); | |
| } | |
| }); | |
| node.stdout.on("data", function() { | |
| }); | |
| node.stderr.on("data", function() { | |
| }); | |
| node.stdin.on("error", function(gistId) { | |
| console.log("error", GITHUB_API_SERVER + " process stdin error: " + gistId + "*********************"); | |
| }); | |
| } | |
| /** | |
| * @param {string} key | |
| * @param {!Object} command | |
| * @return {undefined} | |
| */ | |
| function fn(key, command) { | |
| if (command = command || node, map[key] && command && command.stdin) { | |
| try { | |
| command.stdin.write(map[key], function(b) { | |
| if (b) { | |
| console.log("error", "omxplayer command callback error: " + b + "," + key); | |
| } | |
| }); | |
| } catch (timerIndex) { | |
| console.log("error", "omxplayer stdin write exception: " + timerIndex); | |
| } | |
| } else { | |
| console.log("error", "No omxplayer instance or omxplayer command not found: " + key); | |
| } | |
| } | |
| /** | |
| * @param {string} main | |
| * @param {!Function} name | |
| * @param {boolean} stack | |
| * @param {boolean} options | |
| * @param {number} cb | |
| * @param {?} buffer | |
| * @param {!Object} callback | |
| * @return {?} | |
| */ | |
| function add(main, name, stack, options, cb, buffer, callback) { | |
| return options ? pause() : compile(), isFunction(node) ? (console.log("error", "need to kill omxProcess to start another"), stack ? (node.stdin.pause(), resolve(node.pid, function() { | |
| setTimeout(function() { | |
| start(main, name, options, cb, buffer, callback); | |
| }, 250); | |
| }), true) : false) : (start(main, name, options, cb, buffer, callback), true); | |
| } | |
| /** | |
| * @return {?} | |
| */ | |
| function complete() { | |
| return isFunction(node) ? (node.stdin.pause(), resolve(node.pid), true) : false; | |
| } | |
| /** | |
| * @param {string} data | |
| * @param {string} cb | |
| * @return {?} | |
| */ | |
| function cleanup(data, cb) { | |
| var n = field; | |
| /** @type {boolean} */ | |
| var e = false; | |
| /** @type {!Array} */ | |
| var args = ["omxplayer", "--vol", a, "--no-osd", "--audio_fifo", "30", "--audio_queue", "0.6", "--threshold", "2", "--timeout", "30", "-o", on(), data]; | |
| return productBuilt ? (forEach(), value = data, productBuilt = false, e = true, cb || args.push("--loop"), isFunction(p) && (p.stdin.pause(), resolve(p.pid)), p = spawn("sudo", args, { | |
| stdio : "pipe" | |
| }), p.once("exit", function() { | |
| clearTimeout(token); | |
| if (e) { | |
| /** @type {string} */ | |
| value = ""; | |
| /** @type {boolean} */ | |
| productBuilt = true; | |
| } | |
| if (cb) { | |
| cb(n); | |
| } | |
| }), void p.stdin.on("error", function(a) { | |
| console.log("error", "audio omxProcess stdin error: " + a + "*********************"); | |
| })) : void console.log("warn", "Audio channel is not free " + data); | |
| } | |
| /** | |
| * @return {?} | |
| */ | |
| function forEach() { | |
| return value = "", isFunction(p) ? (p.stdin.pause(), resolve(p.pid), true) : false; | |
| } | |
| /** | |
| * @param {string} i | |
| * @param {!Object} msg | |
| * @param {!Function} fn | |
| * @param {!Function} data | |
| * @return {?} | |
| */ | |
| function handler(i, msg, fn, data) { | |
| /** | |
| * @param {number} a | |
| * @return {undefined} | |
| */ | |
| function ok(a) { | |
| if (!(tabIndexAttr || 143 == a)) { | |
| /** @type {boolean} */ | |
| tabIndexAttr = true; | |
| fn(val); | |
| } | |
| } | |
| var filePath; | |
| var args; | |
| var tabIndexAttr; | |
| var val = def[i]; | |
| /** @type {boolean} */ | |
| var g = false; | |
| /** @type {boolean} */ | |
| var values = fn ? false : true; | |
| return fn = fn || function() { | |
| }, -1 == sides.indexOf(i) ? fn() : (filePath = -1 == i.indexOf("zone") ? deps[i] || defaults[i][key][name] : deps[i]) ? (args = cover ? ["mpv", "--video-rotate=" + currentY, "--geometry=" + extname(filePath), "--volume=" + attributeName, "--rpi-layer=5", msg] : ["omxplayer", "--orientation", currentY, "--win", filePath, "--vol", a, "--no-osd", "-o", on(), "--layer", "5", msg], rightIndicator ? cover ? args.push("--keepaspect") : args.push("--aspect-mode", "letterbox") : cover && args.push("--no-keepaspect"), | |
| data || !productBuilt ? cover ? args.push("--mute") : args.push("-n", "-1") : (forEach(), productBuilt = false, g = true, value = msg), values && args.push("--loop"), isFunction(plugins[i]) && (plugins[i].stdin.pause(), resolve(plugins[i].pid)), plugins[i] = spawn("sudo", args, { | |
| stdio : "pipe" | |
| }), get4Parity(i), plugins[i].stdin.setEncoding("utf-8"), plugins[i].stdin.on("error", function() { | |
| }), plugins[i].stdout.on("data", function() { | |
| }), plugins[i].stderr.on("data", function() { | |
| }), plugins[i].on("exit", function(a) { | |
| if (g) { | |
| /** @type {boolean} */ | |
| productBuilt = true; | |
| /** @type {string} */ | |
| value = ""; | |
| } | |
| ok(a); | |
| }), plugins[i].on("error", function(b) { | |
| console.log("info", "error event for " + i + " with code " + b + "," + val); | |
| }), void(tabIndexAttr = false)) : fn(); | |
| } | |
| /** | |
| * @param {string} name | |
| * @param {!Function} a | |
| * @return {undefined} | |
| */ | |
| function clear(name, a) { | |
| a = a || function() { | |
| }; | |
| /** @type {boolean} */ | |
| var c = false; | |
| /** | |
| * @return {undefined} | |
| */ | |
| var callback = function() { | |
| if (!c) { | |
| /** @type {boolean} */ | |
| c = true; | |
| a(); | |
| } | |
| }; | |
| if (isFunction(plugins[name])) { | |
| plugins[name].stdin.pause(); | |
| resolve(plugins[name].pid, callback); | |
| } else { | |
| callback(); | |
| } | |
| } | |
| /** | |
| * @param {string} res | |
| * @return {?} | |
| */ | |
| function transform(res) { | |
| var event = require("./pi-main").getSettingsData(); | |
| return res && (res = res.replace(/__cpuid__/g, event.cpuSerialNumber || "NA"), res = res.replace(/__ipaddress__/g, event.myIpAddress || "NA"), res = res.replace(/__playername__/g, event.name || "NA"), res = res.replace(/__group__/g, event.secret || "NA")), res; | |
| } | |
| /** | |
| * @param {string} name | |
| * @param {!Function} cb | |
| * @return {undefined} | |
| */ | |
| function write(name, cb) { | |
| fs.readFile(name, "utf8", function(canCreateDiscussions, pStringValue) { | |
| if (canCreateDiscussions) { | |
| console.log("error", "error in reading URL file " + name); | |
| cb("error in reading URL file"); | |
| } else { | |
| try { | |
| /** @type {*} */ | |
| var data = JSON.parse(pStringValue); | |
| data.link = transform(data.link); | |
| cb(null, data); | |
| } catch (f) { | |
| console.log("error", "error in parsing URL file " + name); | |
| cb("error in parsing URL file"); | |
| } | |
| } | |
| }); | |
| } | |
| /** | |
| * @param {!Object} name | |
| * @param {!Function} cb | |
| * @param {number} s | |
| * @return {undefined} | |
| */ | |
| function load(name, cb, s) { | |
| /** | |
| * @return {undefined} | |
| */ | |
| function init() { | |
| if (ps) { | |
| assert.keyTap("down"); | |
| /** @type {number} */ | |
| fail = setTimeout(init, s); | |
| } | |
| } | |
| var fail; | |
| var value; | |
| var pk; | |
| /** @type {number} */ | |
| s = 1E3 * s; | |
| value = field; | |
| /** @type {!Array} */ | |
| pk = ["-s"]; | |
| pk.push(name); | |
| exit(); | |
| ps = spawn("evince", pk, { | |
| stdio : "pipe" | |
| }); | |
| if (ps) { | |
| console.log("info", "evince process spawned " + pk); | |
| } | |
| ps.stdin.setEncoding("utf-8"); | |
| ps.once("exit", function() { | |
| clearTimeout(fail); | |
| if (cb) { | |
| cb(value); | |
| } | |
| }); | |
| ps.stdin.on("error", function(a) { | |
| console.log("error", "evinceProcess stdin error: " + a + "*********************"); | |
| }); | |
| if (s) { | |
| /** @type {number} */ | |
| fail = setTimeout(init, s); | |
| } | |
| } | |
| /** | |
| * @return {undefined} | |
| */ | |
| function exit() { | |
| clearTimeout(_nTimeoutID); | |
| if (ps) { | |
| ps.kill(); | |
| /** @type {null} */ | |
| ps = null; | |
| } | |
| } | |
| /** | |
| * @return {?} | |
| */ | |
| function parse() { | |
| var data = { | |
| filepath : [opts.mediaPath + (list[i] && list[i].filename)], | |
| duration : parseInt(list[i].duration || 300), | |
| loopAll : 0 == i | |
| }; | |
| var index = i; | |
| for (; index < list.length - 1 && (index = (index + 1) % list.length, list[index] && list[index].filename && list[index].filename.match(opts.videoRegex));) { | |
| data.filepath.push(opts.mediaPath + list[index].filename); | |
| data.duration += parseInt(list[index].duration || 300); | |
| /** @type {number} */ | |
| i = index; | |
| } | |
| return data.loopAll = data.loopAll && i == list.length - 1, data.filepath.length > 1 && console.log("info", "merged videos for play: " + data.filepath), data; | |
| } | |
| /** | |
| * @param {string} i | |
| * @param {string} file | |
| * @param {number} data | |
| * @param {!Function} done | |
| * @param {!Function} cb | |
| * @param {boolean} anti | |
| * @param {!Function} callback | |
| * @param {!Function} log | |
| * @param {boolean} options | |
| * @return {?} | |
| */ | |
| function run(i, file, data, done, cb, anti, callback, log, options) { | |
| var p; | |
| var x = def[i]; | |
| /** | |
| * @param {!Object} e | |
| * @return {undefined} | |
| */ | |
| var check = function(e) { | |
| if (value == e) { | |
| if (done) { | |
| done(x); | |
| } | |
| } else { | |
| if (cb) { | |
| handler(i, e, done); | |
| } else { | |
| handler(i, e, null); | |
| setTimeout(function() { | |
| if (done) { | |
| done(x); | |
| } | |
| }, 1E3); | |
| } | |
| } | |
| }; | |
| /** | |
| * @return {undefined} | |
| */ | |
| var doProcessPlay = function() { | |
| if (done) { | |
| data = data || 10; | |
| clearTimeout(timeouts[i]); | |
| /** @type {number} */ | |
| timeouts[i] = setTimeout(function() { | |
| clear(i); | |
| done(x); | |
| }, 1E3 * data); | |
| } | |
| log(); | |
| }; | |
| /** @type {null} */ | |
| var res = null; | |
| /** @type {null} */ | |
| var type = null; | |
| /** @type {null} */ | |
| var typeInformation = null; | |
| if (file) { | |
| if (file.match(opts.mediaRss) || file.match(opts.localFolderRegex)) { | |
| if (!(result[file] && result[file].feeds && result[file].feeds.length)) { | |
| return console.log("error", "feed is empty " + file), void doProcessPlay(); | |
| } | |
| res = result[file]; | |
| if (result[file].duration) { | |
| /** @type {number} */ | |
| data = parseInt(result[file].duration); | |
| } | |
| file = res.feeds[res.subIndex].piSignageLink; | |
| /** @type {string} */ | |
| p = file; | |
| type = res.feeds[res.subIndex].piSignageType; | |
| typeInformation = res.feeds[res.subIndex].piSignageBanner; | |
| if (res.feeds[res.subIndex].piSignageDuration) { | |
| /** @type {number} */ | |
| data = parseInt(res.feeds[res.subIndex].piSignageDuration); | |
| console.log("debug", "Duration of play changed to mrss duration: " + data); | |
| } | |
| /** @type {number} */ | |
| res.subIndex = (res.subIndex + 1) % res.feeds.length; | |
| data = data || 10; | |
| } else { | |
| p = file.indexOf("://") >= 0 || 0 == file.indexOf("\\") || 0 == file.indexOf("/") ? file : opts.mediaPath + file; | |
| } | |
| } else { | |
| /** @type {string} */ | |
| file = "smiley-face.png"; | |
| /** @type {string} */ | |
| p = opts.defaultTemplateDir + file; | |
| } | |
| console.log("debug", "playing next file in subZone: " + i + ";" + p + ";" + x + ";" + type); | |
| if (file.match(opts.videoRegex) || "video" === type) { | |
| if (options) { | |
| clear(i); | |
| } else { | |
| handler(i, p, done, cb); | |
| } | |
| /** @type {number} */ | |
| data = 300; | |
| } else { | |
| if (file.match(opts.audioRegex)) { | |
| if (productBuilt) { | |
| check(p); | |
| } else { | |
| if (done) { | |
| done(x); | |
| } | |
| console.log("warn", "audio channel is not free to play " + file); | |
| } | |
| } else { | |
| if (file.match(opts.imageRegex) || "image" === type || "text" === type) { | |
| if ("text" === type) { | |
| callback(i, "text", typeInformation); | |
| } else { | |
| if (typeInformation) { | |
| callback(i, "image-text", p, typeInformation); | |
| } else { | |
| callback(i, "image", p); | |
| } | |
| } | |
| } else { | |
| if (file.match(opts.noticeRegex) || "weblink" === type) { | |
| callback(i, "iframe", p); | |
| } else { | |
| if (file.match(opts.pdffileRegex) && args) { | |
| callback(i, "pdf", p); | |
| } else { | |
| if (file.match(opts.zipfileRegex)) { | |
| callback(i, "iframe", "http://localhost:8000/media/_" + file.replace(/(.zip|.gz|.bz2)/g, ".repo") + "/index.html"); | |
| } else { | |
| if (file.match(opts.radioFileRegex)) { | |
| write(p, function(a, instruction) { | |
| if (!a) { | |
| if (productBuilt) { | |
| check(instruction.link); | |
| } else { | |
| if (done) { | |
| done(x); | |
| } | |
| console.log("warn", "audio channel is not free to play " + file); | |
| } | |
| } | |
| }); | |
| } else { | |
| if (file.match(opts.omxStreamRegex)) { | |
| write(p, function(b, instance) { | |
| if (!b) { | |
| handler(i, instance.link, cb); | |
| /** @type {number} */ | |
| data = 300; | |
| } | |
| }); | |
| } else { | |
| if (file.match(opts.linkURL)) { | |
| log(true); | |
| write(p, function(b, result) { | |
| if (!b) { | |
| callback(i, "iframe", result.link); | |
| } | |
| log(); | |
| }); | |
| } else { | |
| if (file.match(opts.txtFileRegex)) { | |
| log(true); | |
| write(p, function(b, data) { | |
| if (!b) { | |
| data.message = transform(data.message); | |
| callback(i, "text", data.message, data.style); | |
| } | |
| log(); | |
| }); | |
| } else { | |
| if (file.match(opts.nestedPlaylist) && !anti) { | |
| if (cb) { | |
| /** @type {boolean} */ | |
| item_queue[i] = true; | |
| console.log("info", "running independent playlist " + file + " for zone: " + i); | |
| } | |
| execute(i, file, options); | |
| } else { | |
| console.log("error", "File type not supported, for file " + file); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| doProcessPlay(); | |
| } | |
| /** | |
| * @param {string} key | |
| * @param {!Function} start | |
| * @return {undefined} | |
| */ | |
| function send(key, start) { | |
| clearTimeout(timeouts[key]); | |
| /** @type {number} */ | |
| def[key] = (def[key] + 1) % 256; | |
| clear(key, start); | |
| } | |
| /** | |
| * @param {string} i | |
| * @param {string} name | |
| * @param {boolean} done | |
| * @return {undefined} | |
| */ | |
| function execute(i, name, done) { | |
| /** | |
| * @param {number} args | |
| * @return {undefined} | |
| */ | |
| function restart(args) { | |
| run(i, null, args || 4, finish, false, true, callback, log, done); | |
| } | |
| /** | |
| * @param {!Object} config | |
| * @return {undefined} | |
| */ | |
| function complete(config) { | |
| var data; | |
| if (config && config.filename) { | |
| config.option = config.option || {}; | |
| data = config.duration || 10; | |
| if (config.filename.match(opts.videoRegex) || config.filename.match(opts.audioRegex)) { | |
| data = 5 > data ? 8 : data + 3; | |
| } | |
| /** @type {number} */ | |
| def[i] = (def[i] + 1) % 256; | |
| run(i, config.filename, data, finish, config.option.main, true, callback, log, done); | |
| } else { | |
| restart(); | |
| } | |
| } | |
| /** | |
| * @param {string} text | |
| * @return {undefined} | |
| */ | |
| function finish(text) { | |
| if (text == def[i]) { | |
| clearTimeout(timeouts[i]); | |
| if (assets[f] && result[assets[f].filename] && result[assets[f].filename].subIndex) { | |
| console.log("debug", "using the same index with subIndex " + result[assets[f].filename].subIndex); | |
| } else { | |
| /** @type {number} */ | |
| f = (f + 1) % assets.length; | |
| } | |
| complete(assets[f]); | |
| } else { | |
| console.log("warn", "skipping nested cbIndex for " + i + "," + text + "," + def[i]); | |
| } | |
| } | |
| var config = {}; | |
| /** @type {number} */ | |
| var lastReportId = 0; | |
| /** @type {number} */ | |
| var h = 0; | |
| /** | |
| * @param {?} file | |
| * @param {string} string | |
| * @param {string} text | |
| * @param {?} sourceLineNum | |
| * @return {undefined} | |
| */ | |
| var callback = function(file, string, text, sourceLineNum) { | |
| h++; | |
| config[file] = { | |
| contentType : string, | |
| contentPath : "text" === string ? text : encodeURI(text) | |
| }; | |
| if (sourceLineNum) { | |
| config[file].contentOption = sourceLineNum; | |
| } | |
| }; | |
| /** | |
| * @param {number} report | |
| * @return {?} | |
| */ | |
| var log = function(report) { | |
| return report ? lastReportId++ : lastReportId ? lastReportId-- : void(h && error('js window.setZones("' + fetch(JSON.stringify(config)) + '")')); | |
| }; | |
| /** @type {number} */ | |
| var f = 0; | |
| /** @type {!Array} */ | |
| var assets = []; | |
| fs.readFile(opts.mediaPath + name, "utf8", function(er, data) { | |
| if (er || !data) { | |
| console.log("error", "error in reading playlist file " + name); | |
| restart(); | |
| log(); | |
| } else { | |
| try { | |
| assets = JSON.parse(data).assets; | |
| } catch (f) { | |
| return console.log("error", "error parsing playlist file " + name), restart(), void log(); | |
| } | |
| require("./pi-main").filterValidAssets(assets); | |
| console.log("debug", "calling subDisplayNext from main for " + i); | |
| assets.forEach(function(data) { | |
| if (data.filename.match(opts.mediaRss)) { | |
| request(data.filename, true); | |
| } | |
| if (data.filename.match(opts.localFolderRegex)) { | |
| save(data.filename, true); | |
| } | |
| }); | |
| complete(assets[f]); | |
| } | |
| }); | |
| } | |
| /** | |
| * @param {string} file | |
| * @param {number} value | |
| * @param {!Function} cb | |
| * @param {string} data | |
| * @param {boolean} path | |
| * @param {!Object} options | |
| * @param {!Object} h | |
| * @return {?} | |
| */ | |
| function callback(file, value, cb, data, path, options, h) { | |
| var e; | |
| var name; | |
| var parsed; | |
| var data; | |
| var type; | |
| var v; | |
| var duration; | |
| var selector; | |
| var config = {}; | |
| /** @type {number} */ | |
| var i = 0; | |
| /** @type {number} */ | |
| var l = 0; | |
| /** | |
| * @param {number} retries | |
| * @param {!Function} cb | |
| * @return {undefined} | |
| */ | |
| var process = function(retries, cb) { | |
| clearTimeout(paintNodesTimeout); | |
| /** @type {number} */ | |
| paintNodesTimeout = setTimeout(function() { | |
| cb(e); | |
| }, 1E3 * retries); | |
| }; | |
| /** | |
| * @param {string} map | |
| * @param {number} hash | |
| * @return {undefined} | |
| */ | |
| var check = function(map, hash) { | |
| if (value == map) { | |
| cb(e); | |
| } else { | |
| if (options.main) { | |
| /** @type {number} */ | |
| var j = 1E3 * (hash + 10); | |
| cleanup(map, cb); | |
| clearTimeout(token); | |
| /** @type {number} */ | |
| token = setTimeout(function() { | |
| console.log("warn", "Audio watchdog Timeout expired, killing audio process: " + file + "," + j); | |
| forEach(); | |
| }, j); | |
| } else { | |
| cleanup(map, null); | |
| setTimeout(function() { | |
| cb(e); | |
| }, 1E3); | |
| } | |
| } | |
| }; | |
| /** | |
| * @param {string} file | |
| * @param {string} type | |
| * @param {string} text | |
| * @param {!Object} result | |
| * @return {undefined} | |
| */ | |
| var callback = function(file, type, text, result) { | |
| l++; | |
| config[file] = { | |
| contentType : type, | |
| contentPath : "text" === type ? text : encodeURI(text) | |
| }; | |
| if (result) { | |
| /** @type {!Object} */ | |
| config[file].contentOption = result; | |
| } | |
| }; | |
| /** | |
| * @param {boolean} closed | |
| * @return {?} | |
| */ | |
| var update = function(closed) { | |
| return closed ? i++ : i ? i-- : (path ? config.fullscreen = true : config.fullscreen = false, void error('js window.setZones("' + fetch(JSON.stringify(config)) + '")')); | |
| }; | |
| if (cb = cb || function() { | |
| }, options = options || {}, productBuilt = true, field = (field + 1) % 256, e = field, value || (value = 10), 2 > value && (value = 2), h) { | |
| switch(h) { | |
| case "cors": | |
| create(file, cb, path); | |
| break; | |
| default: | |
| callback("main", "iframe", file); | |
| } | |
| return update(), clearTimeout(paintNodesTimeout), 10 > value && (value = 10), void(paintNodesTimeout = setTimeout(function() { | |
| killAll(); | |
| cb(e); | |
| }, 1E3 * value)); | |
| } | |
| if (parsed = {}, data = null, type = null, v = null, file.match(opts.mediaRss) || file.match(opts.localFolderRegex)) { | |
| if (!(result[file] && result[file].feeds && result[file].feeds.length)) { | |
| return console.log("error", "feed is empty " + file), cb(e); | |
| } | |
| data = result[file]; | |
| if (result[file].duration) { | |
| /** @type {number} */ | |
| value = parseInt(result[file].duration); | |
| } | |
| file = data.feeds[data.subIndex].piSignageLink; | |
| /** @type {string} */ | |
| name = file; | |
| type = data.feeds[data.subIndex].piSignageType; | |
| v = data.feeds[data.subIndex].piSignageBanner; | |
| if (data.feeds[data.subIndex].piSignageDuration) { | |
| /** @type {number} */ | |
| value = parseInt(data.feeds[data.subIndex].piSignageDuration); | |
| console.log("debug", "Duration of play changed to mrss duration: " + value); | |
| } | |
| /** @type {number} */ | |
| data.subIndex = (data.subIndex + 1) % data.feeds.length; | |
| } else { | |
| if (file.indexOf("://") >= 0 || 0 == file.indexOf("\\") || 0 == file.indexOf("/")) { | |
| /** @type {string} */ | |
| name = file; | |
| } else { | |
| name = opts.mediaPath + file; | |
| try { | |
| if (!fs.existsSync(name)) { | |
| return cb(e); | |
| } | |
| } catch (timerIndex) { | |
| return console.log("error", "file check error with existsSync: " + timerIndex), cb(e); | |
| } | |
| } | |
| } | |
| if (v && ongoingMessage) { | |
| toggleRecovery(); | |
| } else { | |
| if (data.currentTicker && !settings.tickerEnable && selItem) { | |
| get(data.currentTicker); | |
| } | |
| } | |
| /** @type {string} */ | |
| waitImportedItem = file; | |
| console.log("debug", "playing next file: " + file + " time = " + value + ";" + field + ";" + input_dir + ";" + type); | |
| if ("debug" == console.debugLevel) { | |
| f(file, value); | |
| } | |
| if (_x$4) { | |
| d.storeEvent("file", "play", file + "/" + value); | |
| } | |
| d.logFilePlay(file); | |
| if (file.match(opts.videoRegex) || "video" === type) { | |
| /** @type {number} */ | |
| duration = 3E5; | |
| /** @type {number} */ | |
| selector = 0; | |
| if (value && 10 != value) { | |
| /** @type {number} */ | |
| duration = 1E3 * (value + 10); | |
| } | |
| if (lastTrackInfoUrl && !screenSmallerThanEditor) { | |
| builtinEnabled = value; | |
| /** @type {number} */ | |
| duration = 1E3 * lastTrackInfoUrl; | |
| /** @type {number} */ | |
| selector = input_dir * lastTrackInfoUrl; | |
| input_dir = input_dir + 1; | |
| if (input_dir * lastTrackInfoUrl > builtinEnabled) { | |
| /** @type {number} */ | |
| input_dir = 0; | |
| } | |
| } else { | |
| if (!(!cover || screenSmallerThanEditor || adjustHeight || data)) { | |
| parsed = parse(); | |
| name = parsed.filepath; | |
| /** @type {number} */ | |
| duration = 1E3 * (parsed.duration + 10); | |
| } | |
| } | |
| add(name, cb, true, path, selector, options.main, parsed.loopAll); | |
| clearTimeout(openTimeout); | |
| /** @type {number} */ | |
| openTimeout = setTimeout(function() { | |
| console.log("warn", "watchdog Timeout expired, killing video process: " + file + "," + duration); | |
| complete(); | |
| }, duration); | |
| } else { | |
| if (file.match(opts.audioRegex)) { | |
| check(name, value); | |
| } else { | |
| if (file.match(opts.imageRegex) || "image" === type || "text" === type) { | |
| if ("text" === type) { | |
| callback("main", "text", v); | |
| } else { | |
| if (v) { | |
| callback("main", "image-text", name, v); | |
| } else { | |
| callback("main", "image", name); | |
| } | |
| } | |
| process(value, cb); | |
| } else { | |
| if (file.match(opts.noticeRegex) || "weblink" == type) { | |
| callback("main", "iframe", name); | |
| process(value, cb); | |
| } else { | |
| if (file.match(opts.pdffileRegex) && args) { | |
| if (query && options.main) { | |
| if (r) { | |
| load(name, cb, options.subduration); | |
| /** @type {number} */ | |
| _nTimeoutID = setTimeout(function() { | |
| exit(); | |
| }, 1E3 * value); | |
| } else { | |
| cb(e); | |
| } | |
| } else { | |
| callback("main", "pdf", name); | |
| process(value, cb); | |
| } | |
| } else { | |
| if (file.match(opts.zipfileRegex)) { | |
| if (10 > value) { | |
| /** @type {number} */ | |
| value = 10; | |
| } | |
| callback("main", "iframe", "http://localhost:8000/media/_" + file.replace(/(.zip|.gz|.bz2)/g, ".repo") + "/index.html"); | |
| process(value, cb); | |
| } else { | |
| if (file.match(opts.radioFileRegex)) { | |
| if (10 > value) { | |
| /** @type {number} */ | |
| value = 10; | |
| } | |
| write(name, function(a, instruction) { | |
| if (a) { | |
| cb(e); | |
| } else { | |
| check(instruction.link, value); | |
| } | |
| }); | |
| } else { | |
| if (file.match(opts.liveStreamRegex) || file.match(opts.omxStreamRegex)) { | |
| write(name, function(canCreateDiscussions, data) { | |
| if (canCreateDiscussions) { | |
| cb(e); | |
| } else { | |
| if (0 == data.link.indexOf("rtsp://") || 0 == data.link.indexOf("udp://") || file.match(opts.omxStreamRegex)) { | |
| add(data.link, cb, true, path, 0, options.main); | |
| } else { | |
| check(data.link, cb, path, options.main); | |
| } | |
| clearTimeout(_frameTimeout); | |
| value = value || 60; | |
| if (10 > value) { | |
| /** @type {number} */ | |
| value = 10; | |
| } | |
| /** @type {number} */ | |
| _frameTimeout = setTimeout(function() { | |
| console.log("debug", "watchdog Timeout expired, killing liveStream process: " + file + "," + value); | |
| finish(); | |
| }, 1E3 * value); | |
| } | |
| }); | |
| } else { | |
| if (file.match(opts.linkURL) || file.match(opts.CORSLink) || file.match(opts.txtFileRegex)) { | |
| if (10 > value) { | |
| /** @type {number} */ | |
| value = 10; | |
| } | |
| update(true); | |
| write(name, function(canCreateDiscussions, data) { | |
| if (canCreateDiscussions) { | |
| cb(e); | |
| } else { | |
| data.link = transform(data.link); | |
| if (file.match(opts.linkURL)) { | |
| callback("main", "iframe", data.link); | |
| } else { | |
| if (file.match(opts.CORSLink)) { | |
| create(data.link, cb, path, data.zoom, data.keystrokes, data.keyDelay); | |
| } else { | |
| if (file.match(opts.txtFileRegex)) { | |
| data.message = transform(data.message); | |
| callback("main", "text", data.message, data.style); | |
| } | |
| } | |
| } | |
| update(); | |
| clearTimeout(paintNodesTimeout); | |
| /** @type {number} */ | |
| paintNodesTimeout = setTimeout(function() { | |
| killAll(); | |
| cb(e); | |
| }, 1E3 * value); | |
| } | |
| }); | |
| } else { | |
| console.log("error", "File type not supported, for file " + file); | |
| cb(e); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| lesson[key].forEach(function(i) { | |
| var name = data && data[i]; | |
| /** | |
| * @param {string} object | |
| * @return {undefined} | |
| */ | |
| var dispatch = function(object) { | |
| var config = {}; | |
| /** @type {number} */ | |
| var b = 0; | |
| /** @type {number} */ | |
| l = 0; | |
| /** | |
| * @param {string} file | |
| * @param {string} type | |
| * @param {string} text | |
| * @param {!Object} result | |
| * @return {undefined} | |
| */ | |
| callback = function(file, type, text, result) { | |
| l++; | |
| config[file] = { | |
| contentType : type, | |
| contentPath : "text" === type ? text : encodeURI(text) | |
| }; | |
| if (result) { | |
| /** @type {!Object} */ | |
| config[file].contentOption = result; | |
| } | |
| }; | |
| /** | |
| * @param {boolean} a | |
| * @return {?} | |
| */ | |
| update = function(a) { | |
| return a ? b++ : b ? b-- : void(l && error('js window.setZones("' + fetch(JSON.stringify(config)) + '")')); | |
| }; | |
| if (object == def[i]) { | |
| clearTimeout(timeouts[i]); | |
| func(callback, update, dispatch); | |
| } else { | |
| console.log("warn", "skipping rss cbIndex for " + i + "," + object + "," + def[i]); | |
| } | |
| }; | |
| /** | |
| * @param {!Function} done | |
| * @param {!Function} err | |
| * @param {!Function} callback | |
| * @return {undefined} | |
| */ | |
| var func = function(done, err, callback) { | |
| /** @type {number} */ | |
| def[i] = (def[i] + 1) % 256; | |
| run(i, name, 0, callback, options[i], false, done, err, path); | |
| }; | |
| if (!item_queue[i]) { | |
| if (name || path) { | |
| update(true); | |
| send(i, function() { | |
| /** @type {null} */ | |
| var arg3 = null; | |
| if (name) { | |
| if (name.match(opts.mediaRss) || name.match(opts.localFolderRegex)) { | |
| /** @type {function(string): undefined} */ | |
| arg3 = dispatch; | |
| } | |
| func(callback, update, arg3); | |
| } else { | |
| update(); | |
| } | |
| }); | |
| } | |
| } | |
| }); | |
| update(); | |
| } | |
| /** | |
| * @param {string} url | |
| * @param {!Function} cb | |
| * @param {boolean} dir | |
| * @param {boolean} f | |
| * @return {undefined} | |
| */ | |
| function check(url, cb, dir, f) { | |
| var path; | |
| var o; | |
| var cmd; | |
| var id = field; | |
| complete(); | |
| forEach(); | |
| /** @type {string} */ | |
| value = url; | |
| path = join(dir); | |
| o = f ? -6E3 : a; | |
| if (closest_arc) { | |
| /** @type {string} */ | |
| cmd = cover ? "sudo mpv --volume=" + attributeName + (f ? " --mute" : "") + " --video-rotate=" + currentY + " --geometry=" + extname(path) + " $(youtube-dl -ciw -g --format best '" + url + "')" : "sudo omxplayer --vol " + o + " -o " + on() + " --orientation " + currentY + " --win '" + path + "' $(youtube-dl -ciw -g --format best '" + url + "')"; | |
| proc = exec(cmd, { | |
| maxBuffer : 25E6 | |
| }, function(step_name) { | |
| if (step_name) { | |
| console.log("debug", "error on tvProcess exit: " + step_name); | |
| } | |
| }); | |
| } else { | |
| proc = spawn("livestreamer", [url, "best", "--player", "omxplayer --vol " + o + " -o " + on() + " --orientation " + currentY + ' --win "' + path + '"', "--fifo", "--player-no-close"]); | |
| } | |
| proc.stdout.on("data", function(val) { | |
| var resxml = val.toString("utf8"); | |
| if (resxml.indexOf("Starting") >= 0) { | |
| if (dir) { | |
| pause(); | |
| } else { | |
| compile(); | |
| } | |
| } | |
| if (resxml.indexOf("This plugin does not support protected videos") > 0) { | |
| finish(); | |
| } | |
| }); | |
| proc.stderr.on("data", function(val) { | |
| var username = val.toString("utf8"); | |
| if (-1 == username.indexOf("Dropped:") && -1 == username.indexOf("Cache:")) { | |
| console.log("info", "livestreamer/ydl error " + username); | |
| } | |
| }); | |
| proc.once("exit", function(a, step_name) { | |
| if (field == id) { | |
| if (dir) { | |
| pause(); | |
| } else { | |
| compile(); | |
| } | |
| } | |
| clearTimeout(_frameTimeout); | |
| /** @type {string} */ | |
| value = ""; | |
| console.log("debug", "youtube-dl exit : " + a + ";" + step_name); | |
| if (cb) { | |
| cb(id); | |
| } | |
| }); | |
| } | |
| /** | |
| * @return {undefined} | |
| */ | |
| function finish() { | |
| if (isFunction(proc)) { | |
| proc.stdin.pause(); | |
| resolve(proc.pid); | |
| } | |
| complete(); | |
| } | |
| /** | |
| * @param {number} index | |
| * @param {number} value | |
| * @param {string} context | |
| * @return {undefined} | |
| */ | |
| function update(index, value, context) { | |
| var x; | |
| /** @type {number} */ | |
| var __sockfile = parseInt(2E3 * Math.log(options.volume / 100) / Math.LN10); | |
| /** @type {!Array} */ | |
| var args = ["omxplayer", "--vol", __sockfile, "--no-osd", "-o", context ? "both" : "local"]; | |
| /** @type {number} */ | |
| var h = Date.now(); | |
| args.push(opts.mediaPath + options.files[index].filename); | |
| x = options.playRandom ? Math.floor(1E4 * Math.random()) : index + 1; | |
| /** @type {number} */ | |
| x = x % options.files.length; | |
| options.process = spawn("sudo", args, { | |
| stdio : "pipe" | |
| }); | |
| options.process.stdin.on("error", function(a) { | |
| console.log("error", "lounge music omxProcess stdin error: " + a + "*********************"); | |
| }); | |
| options.process.once("exit", function() { | |
| if (options.playing && value == id) { | |
| if (Date.now() - h < 1E3) { | |
| setTimeout(function() { | |
| if (options.playing && value == id) { | |
| update(x, value, context); | |
| } | |
| }, 2E3); | |
| } else { | |
| update(x, value, context); | |
| } | |
| } | |
| }); | |
| } | |
| /** | |
| * @param {string} a | |
| * @return {?} | |
| */ | |
| function log(a) { | |
| /** | |
| * @param {!Array} that | |
| * @param {!Array} str | |
| * @return {?} | |
| */ | |
| function f(that, str) { | |
| if (that.length !== str.length) { | |
| return false; | |
| } | |
| /** @type {number} */ | |
| var i = 0; | |
| for (; i < that.length; i++) { | |
| if (that[i] !== str[i]) { | |
| return false; | |
| } | |
| } | |
| return true; | |
| } | |
| /** | |
| * @param {?} options | |
| * @return {?} | |
| */ | |
| function check(options) { | |
| /** @type {string} */ | |
| var s = ""; | |
| return s = s + options.eMsgCmd, s = s + (options.showClock ? " " + options.clockPosition : " " + mapping), s = s + (" " + (options.tickerEnable ? resolved : body)), options.eMsgCmd === auto && (s = s + (" " + options.eMsg.trim().length + " " + options.eMsgHorizontal + " " + options.eMsgVertical)), options.showClock && (s = s + (" " + options.clockFormat)), options.tickerEnable && (s = s + (" " + options.tickerText.trim().length + " " + options.tickerX + " " + options.tickerY + " " + options.tickerWidth + | |
| " " + options.tickerSpeed + " " + options.tickerDir + " " + options.tickerFontSize)), options.eMsgCmd === auto && (s = s + (" " + options.eMsg.trim())), options.tickerEnable && (s = s + (" " + options.tickerText.trim())), s; | |
| } | |
| /** @type {!Array} */ | |
| var path = []; | |
| /** @type {string} */ | |
| var c = ""; | |
| /** @type {boolean} */ | |
| var o = false; | |
| return a ? (n && n.stdin.write("" + a), void(j = [])) : void(P || (settings.eMsgCmd === auto ? (path.push(settings.eMsgCmd), path.push(settings.eMsg), path.push(settings.eMsgHorizontal), path.push(settings.eMsgVertical)) : path.push(png), settings.showClock ? (path.push(settings.clockPosition), path.push(settings.clockFormat)) : path.push(mapping), settings.tickerEnable ? (path.push(resolved), path.push(settings.tickerX), path.push(settings.tickerY), path.push(settings.tickerWidth), path.push(settings.tickerSpeed), | |
| path.push(settings.tickerDir), path.push(settings.tickerFontSize), path.push(settings.tickerText)) : path.push(body), n || (o = true, n = spawn("openvg_display")), n && o && (o = false, console.log("info", "Spawned openvg_display process: " + n.pid + " -> " + path), n.on("error", function() { | |
| console.log("error", "Failed to spawn openvg_display"); | |
| }), n.stdout.on("data", function(data) { | |
| console.log("info", data + ""); | |
| }), n.stderr.on("data", function(gameFolder) { | |
| console.log("error", "openvg_error: " + (gameFolder + "")); | |
| }), n.on("exit", function(a, step_name) { | |
| console.log("error", "openvg_display process terminated due to receipt of signal " + step_name); | |
| /** @type {null} */ | |
| n = null; | |
| /** @type {!Array} */ | |
| j = []; | |
| })), n && !f(j, path) && (j = path.slice(0), c = check(settings), n.stdin.write(c)))); | |
| } | |
| /** | |
| * @param {number} url | |
| * @param {number} index | |
| * @return {undefined} | |
| */ | |
| function end(url, index) { | |
| var data = state[url]; | |
| /** @type {number} */ | |
| data.currentAdCount = 0; | |
| /** @type {number} */ | |
| data.timer = setTimeout(function() { | |
| if (data.adReady = true, !pattern) { | |
| /** @type {number} */ | |
| var a = parseInt(data.files[data.index].duration); | |
| /** @type {boolean} */ | |
| screenSmallerThanEditor = true; | |
| callback(data.files[data.index].filename, a, render, data.files[data.index], data.files[data.index].fullscreen, data.files[data.index].option); | |
| /** @type {number} */ | |
| data.index = (data.index + 1) % data.files.length; | |
| } | |
| }, data.interval + 1E3 * index); | |
| console.testLog("advt", "" + data.files); | |
| } | |
| /** | |
| * @param {boolean} options | |
| * @return {?} | |
| */ | |
| function initialize(options) { | |
| return clearTimeout(data.feedGetTimer), options ? void $.getFeeds(options, data.rssEncodeAsBinary, function(b, connectionConfigs) { | |
| if (b) { | |
| return void(err || docs.length || get("RSS feed currently not available")); | |
| } | |
| if (connectionConfigs && connectionConfigs.length && (docs = connectionConfigs.map(function(messages) { | |
| return data.useDescription ? messages.description : messages.title; | |
| })), docs && 0 != docs.length || (docs = ["No feed available"]), "slide" == data.behavior) { | |
| data.messages = docs; | |
| if (!ongoingMessage) { | |
| data.messages.push(change); | |
| } | |
| activateAnnotator(); | |
| } else { | |
| var d = docs.join(" | "); | |
| data.currentTicker = d; | |
| get(d); | |
| } | |
| if (data.isRssFeed) { | |
| /** @type {number} */ | |
| data.feedGetTimer = setTimeout(function() { | |
| initialize(options); | |
| }, 6E5); | |
| } | |
| }) : void get("RSS Link details not available"); | |
| } | |
| /** | |
| * @param {string} fname | |
| * @return {?} | |
| */ | |
| function getFileExt(fname) { | |
| /** @type {!Array} */ | |
| var types = ["mp4", "mpg4", "mpeg4"]; | |
| /** @type {!Array} */ | |
| var supported_image_types = ["jpeg", "jpg", "png"]; | |
| /** @type {string} */ | |
| var type = ""; | |
| return -1 !== fname.indexOf(".") && (type = fname.split(".").pop()), -1 !== types.indexOf(type) ? "video" : -1 !== supported_image_types.indexOf(type) ? "image" : ""; | |
| } | |
| /** | |
| * @param {string} i | |
| * @param {boolean} options | |
| * @return {undefined} | |
| */ | |
| function request(i, options) { | |
| write(opts.mediaPath + i, function(step_name, item) { | |
| if (step_name) { | |
| console.log("error", "Error reading file " + i + ";" + step_name); | |
| } else { | |
| if (options && result[i] && result[i].enable) { | |
| return; | |
| } | |
| result[i] = {}; | |
| /** @type {boolean} */ | |
| result[i].enable = true; | |
| /** @type {string} */ | |
| result[i].name = i; | |
| /** @type {string} */ | |
| result[i].type = "mrss"; | |
| result[i].link = item.link; | |
| result[i].hideTitle = item.hideTitle; | |
| result[i].duration = item.duration; | |
| result[i].numberOfItems = item.numberOfItems || 10; | |
| /** @type {number} */ | |
| result[i].subIndex = 0; | |
| console.log("debug", "Starting mrss feeds: "); | |
| console.log("debug", result[i]); | |
| init(result[i]); | |
| } | |
| }); | |
| } | |
| /** | |
| * @param {!Object} options | |
| * @return {undefined} | |
| */ | |
| function init(options) { | |
| clearTimeout(options.feedGetTimer); | |
| $.getFeeds(options.link, false, function(b, data) { | |
| var i; | |
| var item; | |
| var res; | |
| var fileExt; | |
| if (b || !Array.isArray(data) || 0 == data.length) { | |
| console.log("error", "Failed to retrieve feeds from " + options.link); | |
| } else { | |
| console.log("debug", "Received mrss feeds: "); | |
| console.log("debug", data && data[0]); | |
| /** @type {string} */ | |
| options.feeds = data; | |
| /** @type {number} */ | |
| i = options.feeds.length - 1; | |
| for (; i >= 0; i--) { | |
| item = options.feeds[i]; | |
| if (0 == options.hideTitle.indexOf("only")) { | |
| /** @type {string} */ | |
| item.piSignageType = "text"; | |
| } else { | |
| if (item.enclosures && Array.isArray(item.enclosures) && item.enclosures[0] && item.enclosures[0].url) { | |
| res = item.enclosures[0]; | |
| if (res.type) { | |
| fileExt = -1 !== res.type.indexOf("/") ? res.type.split("/")[0] : res.type; | |
| fileExt = fileExt.toLowerCase(); | |
| } else { | |
| fileExt = getFileExt(res.url); | |
| } | |
| item.piSignageType = fileExt; | |
| item.piSignageLink = res.url; | |
| } else { | |
| if (item.image && item.image.url) { | |
| /** @type {string} */ | |
| item.piSignageType = "image"; | |
| item.piSignageLink = item.image.url; | |
| } else { | |
| if (item["rss:fullimage"]) { | |
| /** @type {string} */ | |
| item.piSignageType = "image"; | |
| item.piSignageLink = item["rss:fullimage"]["#"]; | |
| } else { | |
| if (item["rss:storyimage"]) { | |
| /** @type {string} */ | |
| item.piSignageType = "image"; | |
| item.piSignageLink = item["rss:storyimage"]["#"]; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| if (options.hideTitle.indexOf("title") >= 0) { | |
| item.piSignageBanner = item.title || ""; | |
| } else { | |
| if (options.hideTitle.indexOf("description") >= 0) { | |
| item.piSignageBanner = item.description || ""; | |
| } | |
| } | |
| if (item["media:content"] && item["media:content"]["@"] && item["media:content"]["@"].duration) { | |
| item.piSignageDuration = item["media:content"]["@"].duration; | |
| } | |
| if (item.piSignageBanner && !item.piSignageLink) { | |
| /** @type {string} */ | |
| item.piSignageType = "text"; | |
| /** @type {string} */ | |
| item.piSignageLink = options.name + "_" + i + ".txt"; | |
| } else { | |
| if (!(item.piSignageBanner || item.piSignageLink)) { | |
| if (item.link) { | |
| /** @type {string} */ | |
| item.piSignageType = "weblink"; | |
| item.piSignageLink = item.link; | |
| } else { | |
| console.log("error", "No info available in the feed, removing " + ("" + item).slice(0, 50)); | |
| options.feeds.splice(i, 1); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| if (options.enable) { | |
| /** @type {number} */ | |
| options.feedGetTimer = setTimeout(function() { | |
| init(options); | |
| }, 6e5); | |
| } | |
| }, options.numberOfItems); | |
| } | |
| /** | |
| * @param {string} key | |
| * @param {boolean} options | |
| * @return {undefined} | |
| */ | |
| function save(key, options) { | |
| write(opts.mediaPath + key, function(step_name, media) { | |
| if (step_name) { | |
| console.log("error", "Error reading file " + key + ";" + step_name); | |
| } else { | |
| if (options && result[key] && result[key].enable) { | |
| return; | |
| } | |
| result[key] = {}; | |
| /** @type {boolean} */ | |
| result[key].enable = true; | |
| /** @type {string} */ | |
| result[key].type = "local"; | |
| result[key].link = media.link; | |
| result[key].duration = media.duration; | |
| result[key].numberOfItems = media.numberOfItems || 10; | |
| /** @type {number} */ | |
| result[key].subIndex = 0; | |
| console.log("debug", "Starting local folder fetch "); | |
| console.log("debug", result[key]); | |
| loop(result[key]); | |
| } | |
| }); | |
| } | |
| /** | |
| * @param {!Object} self | |
| * @return {undefined} | |
| */ | |
| function loop(self) { | |
| clearTimeout(self.feedGetTimer); | |
| fs.stat(self.link, function(err, stat) { | |
| if (err || !stat) { | |
| console.log("error", "local folder/file read error: " + self.link + ";" + err); | |
| } else { | |
| if (stat.isDirectory()) { | |
| fs.readdir(self.link, function(step_name, buildInTemplates) { | |
| return step_name || !buildInTemplates ? void console.log("error", "local folder read error: " + self.link + ";" + step_name) : (self.feeds = buildInTemplates.map(function(id_article) { | |
| return { | |
| piSignageLink : self.link + "/" + id_article | |
| }; | |
| }), console.log("debug", "Received folder contents: "), void console.log("debug", self.feeds)); | |
| }); | |
| } else { | |
| /** @type {!Array} */ | |
| self.feeds = [{ | |
| piSignageLink : self.link + "/" + file | |
| }]; | |
| console.log("debug", "Received folder contents: "); | |
| console.log("debug", self.feeds); | |
| } | |
| } | |
| if (self.enable) { | |
| /** @type {number} */ | |
| self.feedGetTimer = setTimeout(function() { | |
| loop(self); | |
| }, 6e5); | |
| } | |
| }); | |
| } | |
| /** | |
| * @return {undefined} | |
| */ | |
| function loadData() { | |
| Object.keys(result).forEach(function(name) { | |
| var request = result[name]; | |
| if (request) { | |
| /** @type {boolean} */ | |
| request.enable = false; | |
| clearTimeout(request.feedGetTimer); | |
| /** @type {null} */ | |
| result[name] = null; | |
| } | |
| }); | |
| } | |
| /** | |
| * @return {undefined} | |
| */ | |
| function open() { | |
| clearTimeout(data.feedChangeTimer); | |
| var a = data.messages[data.msgIndex]; | |
| data.currentTicker = a; | |
| get(a); | |
| /** @type {number} */ | |
| data.msgIndex = (data.msgIndex + 1) % data.messages.length; | |
| if (!data.disabled) { | |
| /** @type {number} */ | |
| data.feedChangeTimer = setTimeout(open, data.feedDelay); | |
| } | |
| } | |
| /** | |
| * @return {undefined} | |
| */ | |
| function activateAnnotator() { | |
| /** @type {number} */ | |
| data.msgIndex = 0; | |
| /** @type {boolean} */ | |
| data.disabled = false; | |
| open(); | |
| } | |
| /** | |
| * @return {undefined} | |
| */ | |
| function _clearAdvanceTimeout() { | |
| /** @type {boolean} */ | |
| data.isRssFeed = false; | |
| clearTimeout(data.feedGetTimer); | |
| /** @type {boolean} */ | |
| data.disabled = true; | |
| clearTimeout(data.feedChangeTimer); | |
| /** @type {null} */ | |
| data.currentTicker = null; | |
| } | |
| /** | |
| * @param {string} data | |
| * @return {undefined} | |
| */ | |
| function uploadFile(data) { | |
| if (socket && 1 == socket.readyState) { | |
| socket.send(data, function(canCreateDiscussions) { | |
| if (canCreateDiscussions) { | |
| console.log("error", "Could not send message to chrome : " + canCreateDiscussions + ";" + data); | |
| } | |
| }); | |
| } else { | |
| console.log("error", "Can not send message to chrome : " + data); | |
| } | |
| } | |
| var child; | |
| var n; | |
| var endCallTimeout; | |
| var app; | |
| var timerIndex; | |
| var ps; | |
| var _nTimeoutID; | |
| var node; | |
| var p; | |
| var openTimeout; | |
| var token; | |
| var _frameTimeout; | |
| var paintNodesTimeout; | |
| var click_timeout_id; | |
| var ruid; | |
| var maxlength; | |
| var selItem; | |
| var tail; | |
| var wrapped; | |
| var l; | |
| var name; | |
| var proc; | |
| var timeout; | |
| var _input_filter_changed; | |
| var zb; | |
| var extname; | |
| var handle_static; | |
| var server; | |
| var input_filter_changed; | |
| var render; | |
| var stop; | |
| var id; | |
| var docs; | |
| var socket; | |
| var c; | |
| var build; | |
| var spawn = require("child_process").spawn; | |
| var exec = require("child_process").exec; | |
| var fs = require("fs"); | |
| var h = (require("path"), require("async")); | |
| var console = require("../others/logger"); | |
| var $scope = require("../others/system-info"); | |
| var assert = require("robotjs"); | |
| var _ensureTrailingSlash = require("ps-tree"); | |
| /** | |
| * @param {?} version | |
| * @param {!Function} callback | |
| * @return {undefined} | |
| */ | |
| var resolve = function(version, callback) { | |
| _ensureTrailingSlash(version, function(canCreateDiscussions, buildInTemplates) { | |
| spawn("sudo", ["kill", "-9", version].concat(buildInTemplates.map(function(p) { | |
| return p.PID; | |
| }))); | |
| if (callback) { | |
| callback(); | |
| } | |
| }); | |
| }; | |
| /** | |
| * @param {!Object} child | |
| * @return {?} | |
| */ | |
| var isFunction = function(child) { | |
| return child && null === child.exitCode && null === child.signalCode ? true : false; | |
| }; | |
| /** @type {number} */ | |
| var chat = 0; | |
| /** @type {number} */ | |
| var sortValue = 1; | |
| /** @type {number} */ | |
| var Infinity = 2; | |
| /** @type {number} */ | |
| var _ = 0; | |
| /** @type {number} */ | |
| var y = 1; | |
| /** @type {number} */ | |
| var divaInstance = 2; | |
| /** @type {number} */ | |
| var auto = 0; | |
| /** @type {number} */ | |
| var png = 1; | |
| /** @type {number} */ | |
| var body = 0; | |
| /** @type {number} */ | |
| var resolved = 1; | |
| /** @type {number} */ | |
| var mapping = 0; | |
| /** @type {number} */ | |
| var pt = 1; | |
| /** @type {number} */ | |
| var dev = 2; | |
| /** @type {number} */ | |
| var ac_save = 0; | |
| /** @type {number} */ | |
| var loadingDelay = 1; | |
| /** @type {number} */ | |
| var valueProgess = 80; | |
| var opts = require("../../config/config"); | |
| var d = require("./pi-events"); | |
| var $ = require("../others/rss-service"); | |
| /** @type {string} */ | |
| var autoReview = "720p"; | |
| /** @type {string} */ | |
| var orientation = "landscape"; | |
| /** @type {boolean} */ | |
| var ongoingMessage = true; | |
| /** @type {string} */ | |
| var change = " *** Please add the license file ***"; | |
| /** @type {!Array} */ | |
| var j = []; | |
| /** @type {boolean} */ | |
| var P = false; | |
| /** @type {boolean} */ | |
| var r = false; | |
| /** @type {boolean} */ | |
| var v = false; | |
| /** @type {boolean} */ | |
| var opt_newBuffer = false; | |
| /** @type {!Array} */ | |
| var results = []; | |
| /** @type {boolean} */ | |
| var fromContext = false; | |
| /** @type {boolean} */ | |
| var args = false; | |
| /** @type {boolean} */ | |
| var showingAlertTitle = false; | |
| /** @type {boolean} */ | |
| var query = false; | |
| /** @type {null} */ | |
| var url = null; | |
| var plugins = {}; | |
| /** @type {string} */ | |
| var value = ""; | |
| /** @type {boolean} */ | |
| var productBuilt = true; | |
| /** @type {number} */ | |
| var currentY = 0; | |
| var timeouts = {}; | |
| var item_queue = {}; | |
| /** @type {null} */ | |
| var subject = null; | |
| /** @type {boolean} */ | |
| var pattern = false; | |
| /** @type {boolean} */ | |
| var originalPattern = false; | |
| /** @type {boolean} */ | |
| var adjustHeight = false; | |
| /** @type {!Array} */ | |
| var list = []; | |
| /** @type {number} */ | |
| var i = 0; | |
| /** @type {number} */ | |
| var alpha = 0; | |
| /** @type {number} */ | |
| var concurency = 0; | |
| /** @type {number} */ | |
| var field = 0; | |
| var def = { | |
| side : 0, | |
| bottom : 0, | |
| zone4 : 0, | |
| zone5 : 0, | |
| zone6 : 0 | |
| }; | |
| /** @type {string} */ | |
| var key = "1"; | |
| /** @type {string} */ | |
| var dir = "custom_layout.html"; | |
| var data = { | |
| currentTicker : null, | |
| behavior : "slide", | |
| feedDelay : 1E4, | |
| disabled : false, | |
| isRssFeed : false, | |
| rssLink : null, | |
| rssEncodeAsBinary : false, | |
| feedGetTimer : null, | |
| feedChangeTimer : null, | |
| messages : [], | |
| msgIndex : 0, | |
| textSpeed : 3 | |
| }; | |
| var deps = {}; | |
| /** @type {boolean} */ | |
| var whatToScale = false; | |
| /** @type {string} */ | |
| var hPosPropUnused = "right"; | |
| /** @type {boolean} */ | |
| var err = false; | |
| /** @type {string} */ | |
| var colour = "#000"; | |
| /** @type {boolean} */ | |
| var validationVM = false; | |
| /** @type {number} */ | |
| var optionUsed2 = 2; | |
| /** @type {boolean} */ | |
| var rightIndicator = false; | |
| /** @type {null} */ | |
| var waitImportedItem = null; | |
| var result = {}; | |
| /** @type {boolean} */ | |
| var addChar = false; | |
| var settings = { | |
| showClock : false, | |
| eMsgCmd : png | |
| }; | |
| var options = { | |
| process : null, | |
| playing : false, | |
| files : [], | |
| playRandom : false, | |
| volume : 90 | |
| }; | |
| /** @type {boolean} */ | |
| var _x$4 = false; | |
| /** @type {boolean} */ | |
| var closest_arc = false; | |
| /** @type {boolean} */ | |
| var cover = false; | |
| /** @type {boolean} */ | |
| var item = false; | |
| /** @type {!Array} */ | |
| var values = []; | |
| /** @type {!Array} */ | |
| var state = []; | |
| /** @type {boolean} */ | |
| var inputWin = false; | |
| /** @type {boolean} */ | |
| var screenSmallerThanEditor = false; | |
| var map = { | |
| pause : "p", | |
| quit : "q" | |
| }; | |
| /** @type {number} */ | |
| var a = 0; | |
| /** @type {number} */ | |
| var attributeName = 100; | |
| /** @type {number} */ | |
| var lastTrackInfoUrl = 0; | |
| /** @type {number} */ | |
| var input_dir = 0; | |
| /** @type {number} */ | |
| var builtinEnabled = 0; | |
| /** @type {!Array} */ | |
| var urlHosts = ["1", "2a", "2b", "2c", "2d", "3a", "3b", "3c", "3d", "4a", "4b", "4c", "4d", "2ap", "2bp", "2ap270", "2bp270", "custom", "customp", "customp270"]; | |
| var styles = { | |
| 1 : ["0 0 1280 720", "0 0 1280 660", "0 0 1920 1080", "0 0 1920 1020"], | |
| "2a" : ["320 0 1280 720", "320 0 1280 660", "480 0 1920 1080", "480 0 1920 1020"], | |
| "2b" : ["0 0 960 720", "0 0 960 660", "0 0 1440 1080", "0 0 1440 1020"], | |
| "2c" : ["0 0 640 720", "0 0 640 660", "0 0 960 1080", "0 0 960 1020"], | |
| "2d" : ["640 0 1280 720", "640 0 1280 660", "960 0 1920 1080", "960 0 1920 1020"], | |
| "3a" : ["320 0 1280 540", "320 0 1280 540", "480 0 1920 810", "480 0 1920 810"], | |
| "3b" : ["0 0 960 540", "0 0 960 540", "0 0 1440 810", "0 0 1440 810"], | |
| "3c" : ["320 180 1280 720", "320 180 1280 660", "480 270 1920 1080", "480 270 1920 1020"], | |
| "3d" : ["0 180 960 720", "0 180 960 660", "0 270 1440 1080", "0 270 1440 1020"], | |
| "4a" : ["320 0 1280 540", "320 0 1280 540", "480 0 1920 810", "480 0 1920 810"], | |
| "4b" : ["0 0 960 540", "0 0 960 540", "0 0 1440 810", "0 0 1440 810"], | |
| "4c" : ["320 180 1280 720", "320 180 1280 660", "480 270 1920 1080", "480 270 1920 1020"], | |
| "4d" : ["0 180 960 720", "0 180 960 660", "0 270 1440 1080", "0 270 1440 1020"], | |
| "2ap" : ["0 0 720 1280", "0 0 720 1200", "0 0 1080 1920", "0 0 1080 1840", "0 0 1280 720", "60 0 1280 720", "0 0 1920 1080", "60 0 1920 1080"], | |
| "2bp" : ["0 0 720 540", "0 0 720 540", "0 0 1080 810", "0 0 1080 810", "740 0 1281 720", "740 0 1281 720", "1110 0 1921 1080", "1110 0 1921 1080"], | |
| "2ap270" : ["0 0 720 1280", "0 0 720 1200", "0 0 1080 1920", "0 0 1080 1840", "0 0 1280 720", "0 0 1220 720", "0 0 1920 1080", "0 0 1840 1080"], | |
| "2bp270" : ["0 0 720 540", "0 0 720 540", "0 0 1080 810", "0 0 1080 810", "0 0 541 720", "0 0 541 720", "0 0 811 1080", "0 0 811 1080"], | |
| custom : ["0 0 1280 720", "0 0 1280 660", "0 0 1920 1080", "0 0 1920 1020"], | |
| customp : ["0 0 720 1280", "0 0 720 1200", "0 0 1080 1920", "0 0 1080 1840", "0 0 1280 720", "60 0 1280 720", "0 0 1920 1080", "60 0 1920 1080"], | |
| customp270 : ["0 0 720 1280", "0 0 720 1200", "0 0 1080 1920", "0 0 1080 1840", "0 0 1280 720", "60 0 1280 720", "0 0 1920 1080", "60 0 1920 1080"] | |
| }; | |
| var defaults = { | |
| side : { | |
| 1 : [null, null, null, null], | |
| "2a" : ["0 0 320 720", "0 0 320 660", "0 0 480 1080", "0 0 480 1020"], | |
| "2b" : ["960 0 1280 720", "960 0 1280 660", "1440 0 1920 1080", "1440 0 1920 1020"], | |
| "2c" : ["640 0 1280 720", "640 0 1280 660", "960 0 1920 1080", "960 0 1920 1020"], | |
| "2d" : ["0 0 640 720", "0 0 640 660", "0 0 960 1080", "0 0 960 1020"], | |
| "3a" : ["0 0 320 540", "0 0 320 540", "0 0 480 810", "0 0 480 810"], | |
| "3b" : ["960 0 1280 540", "960 0 1280 540", "1440 0 1920 810", "1440 0 1920 810"], | |
| "3c" : ["0 180 320 720", "0 180 320 660", "0 270 480 1080", "0 270 480 1020"], | |
| "3d" : ["960 180 1280 720", "960 180 1280 660", "1440 270 1920 1080", "1440 270 1920 1020"], | |
| "4a" : ["0 0 320 720", "0 0 320 660", "0 0 480 1080", "0 0 480 1020"], | |
| "4b" : ["960 0 1280 720", "960 0 1280 660", "1440 0 1920 1080", "1440 0 1920 1020"], | |
| "4c" : ["0 0 320 720", "0 0 320 660", "0 0 480 1080", "0 0 480 1020"], | |
| "4d" : ["960 0 1280 720", "960 0 1280 660", "1440 0 1920 1080", "1440 0 1920 1020"], | |
| "2ap" : [null, null, null, null, null, null, null, null], | |
| "2bp" : [null, null, null, null, null, null], | |
| "2ap270" : [null, null, null, null, null, null, null, null], | |
| "2bp270" : [null, null, null, null, null, null, null, null], | |
| custom : [null, null, null, null, null, null, null, null], | |
| customp : [null, null, null, null, null, null, null, null], | |
| customp270 : [null, null, null, null, null, null, null, null] | |
| }, | |
| bottom : { | |
| 1 : [null, null, null, null], | |
| "2a" : [null, null, null, null], | |
| "2b" : [null, null, null, null], | |
| "2c" : [null, null, null, null], | |
| "2d" : [null, null, null, null], | |
| "3a" : ["0 540 1280 720", "0 540 1280 660", "0 810 1920 1080", "0 810 1920 1020"], | |
| "3b" : ["0 540 1280 720", "0 540 1280 660", "0 810 1920 1080", "0 810 1920 1020"], | |
| "3c" : ["0 0 1280 180", "0 0 1280 180", "0 0 1920 270", "0 0 1920 270"], | |
| "3d" : ["0 0 1280 180", "0 0 1280 180", "0 0 1920 270", "0 0 1920 270"], | |
| "4a" : ["320 540 1280 720", "320 540 1280 660", "480 810 1920 1080", "480 810 1920 1020"], | |
| "4b" : ["0 540 960 720", "0 540 960 660", "0 810 1440 1080", "0 810 1440 1020"], | |
| "4c" : ["320 0 1280 180", "320 0 1280 180", "480 0 1920 270", "480 0 1920 270"], | |
| "4d" : ["0 0 960 180", "0 0 960 180", "0 0 1440 270", "0 0 1440 270"], | |
| "2ap" : [null, null, null, null, null, null, null, null], | |
| "2bp" : ["0 540 720 1280", "0 540 720 1200", "0 810 1080 1920", "0 810 1080 1840", "0 0 740 720", "0 0 740 660", "0 0 1110 1080", "0 0 1110 1020"], | |
| "2ap270" : [null, null, null, null, null, null, null, null], | |
| "2bp270" : ["0 540 720 1280", "0 540 720 1200", "0 810 1080 1920", "0 810 1080 1840", "540 0 1280 720", "540 0 1280 660", "810 0 1920 1080", "810 0 1280 1060"], | |
| custom : [null, null, null, null, null, null, null, null], | |
| customp : [null, null, null, null, null, null, null, null], | |
| customp270 : [null, null, null, null, null, null, null, null] | |
| } | |
| }; | |
| /** @type {string} */ | |
| var firstAvailCol = "0 0 720 480"; | |
| /** @type {string} */ | |
| var tmpA = "0 0 720 576"; | |
| /** @type {null} */ | |
| var leave = null; | |
| var lesson = { | |
| 1 : [], | |
| "2a" : ["side"], | |
| "2b" : ["side"], | |
| "2c" : ["side"], | |
| "2d" : ["side"], | |
| "3a" : ["side", "bottom"], | |
| "3b" : ["side", "bottom"], | |
| "3c" : ["side", "bottom"], | |
| "3d" : ["side", "bottom"], | |
| "4a" : ["side", "bottom"], | |
| "4b" : ["side", "bottom"], | |
| "4c" : ["side", "bottom"], | |
| "4d" : ["side", "bottom"], | |
| "2ap" : [], | |
| "2bp" : ["bottom"], | |
| "2ap270" : [], | |
| "2bp270" : ["bottom"], | |
| custom : ["side", "bottom", "zone4", "zone5", "zone6"], | |
| customp : ["side", "bottom", "zone4", "zone5", "zone6"], | |
| customp270 : ["side", "bottom", "zone4", "zone5", "zone6"] | |
| }; | |
| /** @type {!Array} */ | |
| var sides = ["side", "bottom", "zone4"]; | |
| try { | |
| fs.unlinkSync("/home/pi/.cache/uzbl/event_daemon.pid"); | |
| fs.unlinkSync("/home/pi/.cache/uzbl/event_daemon"); | |
| } catch (rb) { | |
| } | |
| h.series([function(saveNotifs) { | |
| exec("sudo pkill pngview", function() { | |
| saveNotifs(); | |
| }); | |
| }, function(saveNotifs) { | |
| exec("sudo pkill openvg_display", function() { | |
| saveNotifs(); | |
| }); | |
| }, function(saveNotifs) { | |
| exec("sudo pkill evince", function() { | |
| saveNotifs(); | |
| }); | |
| }, function(saveNotifs) { | |
| exec("sudo pkill mpv", function() { | |
| saveNotifs(); | |
| }); | |
| }, function(saveNotifs) { | |
| exec("killall -s 9 chromium-browser", function() { | |
| saveNotifs(); | |
| }); | |
| }, function(saveNotifs) { | |
| exec("sudo pkill uzbl", function() { | |
| saveNotifs(); | |
| }); | |
| }, function(saveNotifs) { | |
| exec("uzbl --version").stdout.on("data", function(boardNameToTest) { | |
| /** @type {boolean} */ | |
| fromContext = -1 == boardNameToTest.indexOf("228bc38") ? true : false; | |
| console.log("info", "Based on commit value uzbl is " + (fromContext ? "new" : "old")); | |
| /** @type {string} */ | |
| timerIndex = boardNameToTest.indexOf("228bc38") >= 0 ? "228bc38" : boardNameToTest.indexOf("35db169") >= 0 ? "35db169" : boardNameToTest.indexOf("v0.9.0") >= 0 ? "v0.9.0" : "unknown"; | |
| console.log("info", "uzbl version is " + timerIndex); | |
| }).on("close", function() { | |
| saveNotifs(); | |
| }); | |
| }, function(saveNotifs) { | |
| exec("which chromium-browser", function(isPrevType, step_name, isCurrentType) { | |
| if (isPrevType || isCurrentType) { | |
| console.log("warn", "Chromium is *not* available"); | |
| /** @type {boolean} */ | |
| args = false; | |
| } else { | |
| console.log("info", "Chromium is available at " + step_name); | |
| /** @type {boolean} */ | |
| args = true; | |
| self.startChromeSocket(); | |
| } | |
| saveNotifs(); | |
| }); | |
| }, function(saveNotifs) { | |
| exec("which openvg_display", function(isPrevType, step_name, isCurrentType) { | |
| if (isPrevType || isCurrentType) { | |
| console.log("warn", "Openvg is *not* available"); | |
| /** @type {boolean} */ | |
| showingAlertTitle = false; | |
| } else { | |
| console.log("info", "Openvg is available at " + step_name); | |
| /** @type {boolean} */ | |
| showingAlertTitle = true; | |
| } | |
| saveNotifs(); | |
| }); | |
| }, function(saveNotifs) { | |
| exec("which evince", function(isPrevType, step_name, isCurrentType) { | |
| if (isPrevType || isCurrentType) { | |
| console.log("warn", "evince pdf reader is *not* available"); | |
| /** @type {boolean} */ | |
| query = false; | |
| } else { | |
| console.log("info", "evince pdf reader is available at " + step_name); | |
| /** @type {boolean} */ | |
| query = true; | |
| } | |
| saveNotifs(); | |
| }); | |
| }, function(a) { | |
| if (args) { | |
| $scope.changeHostname(a); | |
| } else { | |
| a(); | |
| } | |
| }, function(stringify) { | |
| if (args) { | |
| expect(stringify); | |
| } else { | |
| stringify(); | |
| } | |
| }], function() { | |
| test(); | |
| }); | |
| /** | |
| * @param {string} nextElement | |
| * @return {undefined} | |
| */ | |
| self.setConfigServer = function(nextElement) { | |
| /** @type {!Array} */ | |
| var array = ["displayer.com.my", "signs.everywherelocalmedia.com", "berryscreen.conmed.net", "elevatesigns.com", "satavision.vpalvelin.com", "goaclick.com.au", "cityadpro.cat", "signage.dsmediaplay.com", "signage.poboinc.com", "pisign.rplink.net", "livesignagelite.nec.com.sg", "signprohub.com", "lktsignage.com", "signage-network.app"]; | |
| /** @type {string} */ | |
| change = array.indexOf(nextElement) >= 0 ? " *** Please add the license, contact info@" + nextElement + " ***" : " *** This player is powered by pisignage.com ***"; | |
| }; | |
| /** | |
| * @param {string} path | |
| * @return {?} | |
| */ | |
| extname = function(path) { | |
| var b = path.split(" "); | |
| /** @type {number} */ | |
| var scaledGridCellHeight = b[2] - b[0]; | |
| /** @type {number} */ | |
| var px = b[3] - b[1]; | |
| var e = b[0]; | |
| var roundedSizeOffset = b[1]; | |
| return scaledGridCellHeight + "x" + px + "+" + e + "+" + roundedSizeOffset; | |
| }; | |
| /** | |
| * @param {boolean} filepath | |
| * @return {?} | |
| */ | |
| handle_static = function(filepath) { | |
| var file; | |
| var ext; | |
| return file = join(filepath), ext = extname(file); | |
| }; | |
| /** @type {null} */ | |
| server = null; | |
| /** | |
| * @return {undefined} | |
| */ | |
| self.clearDisplayOnscreenMessage = function() { | |
| clearTimeout(input_filter_changed); | |
| /** @type {number} */ | |
| settings.eMsgCmd = png; | |
| log(); | |
| }; | |
| /** | |
| * @param {?} value | |
| * @return {?} | |
| */ | |
| render = function(value) { | |
| var e; | |
| var applications; | |
| var options; | |
| var x; | |
| var j; | |
| var data; | |
| var disabled; | |
| var connectNumber; | |
| /** @type {null} */ | |
| var text = null; | |
| var d = {}; | |
| if (field != value) { | |
| return void console.log("warn", "*** skipping callback: " + +value + "," + field); | |
| } | |
| if (inputWin && !addChar) { | |
| /** @type {number} */ | |
| x = 0; | |
| j = state.length; | |
| for (; j > x; x++) { | |
| if (data = state[x], data.adReady) { | |
| if (data.currentAdCount >= data.adCount) { | |
| /** @type {boolean} */ | |
| data.adReady = false; | |
| end(x, 0); | |
| continue; | |
| } | |
| if (!data.noMainPlay && data.files[data.index] && data.files[data.index].filename) { | |
| text = data.files[data.index].filename; | |
| /** @type {boolean} */ | |
| screenSmallerThanEditor = true; | |
| } | |
| lesson[key].forEach(function(checkname) { | |
| d[checkname] = data.files[data.index][checkname] || null; | |
| }); | |
| /** @type {number} */ | |
| e = parseInt(data.files[data.index].duration); | |
| applications = data.files[data.index].fullscreen; | |
| options = data.files[data.index].option; | |
| /** @type {number} */ | |
| data.index = (data.index + 1) % data.files.length; | |
| data.currentAdCount += 1; | |
| break; | |
| } | |
| } | |
| } | |
| if (pattern && !text && (disabled = false, screenSmallerThanEditor = false, list[i] && result[list[i].filename] && result[list[i].filename].subIndex && (console.log("debug", "using the same nextFileIndex with subIndex " + result[list[i].filename].subIndex), disabled = true), list[i] && list[i].filename.match(opts.videoRegex) && lastTrackInfoUrl && input_dir && (console.log("debug", "using the same nextFileIndex with videoChunk " + input_dir), disabled = true), disabled || (i = (i + 1) % list.length), | |
| text = list[i] && list[i].filename, e = parseInt(list[i].duration), lesson[key].forEach(function(p) { | |
| if (!d[p]) { | |
| d[p] = list[i][p]; | |
| } | |
| }), applications = list[i].fullscreen, options = list[i].option, item && 0 == i && values.length)) { | |
| return item = false, addChar && (values[7] = alpha), self.startPlay.apply(this, values), void console.log("info", "playlist change called"); | |
| } | |
| if (text) { | |
| if (zb && (generate(), data.currentTicker && get(data.currentTicker), zb = false, console.log("info", "reloaded url to flush memory leaks")), 0 == i && !disabled) { | |
| if (connectNumber = Date.now(), 1E3 > connectNumber - concurency) { | |
| return console.log("error", "Playlist duration is less than 1 second, delaying for a second"), void setTimeout(function() { | |
| /** @type {number} */ | |
| concurency = Date.now(); | |
| callback(text, e, render, d, applications, options); | |
| }, 5E3); | |
| } | |
| /** @type {number} */ | |
| concurency = connectNumber; | |
| } | |
| callback(text, e, render, d, applications, options); | |
| } | |
| }; | |
| /** | |
| * @param {!Function} t1 | |
| * @return {undefined} | |
| */ | |
| stop = function(t1) { | |
| complete(); | |
| forEach(); | |
| finish(); | |
| clearTimeout(click_timeout_id); | |
| clearTimeout(openTimeout); | |
| clearTimeout(token); | |
| clearTimeout(_frameTimeout); | |
| clearTimeout(paintNodesTimeout); | |
| clearTimeout(input_filter_changed); | |
| sides.forEach(function(key) { | |
| clear(key); | |
| }); | |
| lesson.custom.forEach(function(n) { | |
| /** @type {boolean} */ | |
| item_queue[n] = false; | |
| }); | |
| Object.keys(timeouts).forEach(function(pushAss) { | |
| send(pushAss); | |
| }); | |
| killAll(); | |
| spawnPio(false); | |
| _clearAdvanceTimeout(); | |
| loadData(); | |
| self.pauseAds(); | |
| exec("sudo pkill omx", function() { | |
| exec("sudo pkill livestreamer", function() { | |
| if (t1) { | |
| setTimeout(t1, 100); | |
| } | |
| }); | |
| }); | |
| }; | |
| /** | |
| * @return {undefined} | |
| */ | |
| self.startPlaySync = function() { | |
| console.log("info", "playlist change request received"); | |
| if (1 != list.length || inputWin) { | |
| /** @type {!Arguments} */ | |
| values = arguments; | |
| /** @type {boolean} */ | |
| item = true; | |
| } else { | |
| console.log("info", "calling change playlist immediate since a single video in loop being played"); | |
| self.startPlay.apply(this, arguments); | |
| } | |
| }; | |
| /** | |
| * @param {string} path | |
| * @param {!Object} item | |
| * @param {string} url | |
| * @param {!Object} options | |
| * @param {string} value | |
| * @param {string} n | |
| * @param {!Function} fn | |
| * @param {number} idx | |
| * @param {boolean} status | |
| * @param {?} changes | |
| * @return {?} | |
| */ | |
| self.startPlay = function(path, item, url, options, value, n, fn, idx, status, changes) { | |
| if (status ? (item = true, addChar = true, alpha = i) : (values = arguments, addChar = false), fn = fn || function() { | |
| }, -1 == urlHosts.indexOf(url)) { | |
| return fn("Layout not supported"); | |
| } | |
| if (orientation.indexOf("portrait") >= 0 && -1 == url.indexOf("custom")) { | |
| switch(url) { | |
| case "1": | |
| /** @type {string} */ | |
| url = "2ap"; | |
| break; | |
| default: | |
| url = url.replace("270", ""); | |
| } | |
| } | |
| /** @type {number} */ | |
| field = (field + 1) % 256; | |
| stop(function() { | |
| var l; | |
| var m; | |
| var ifModifiedSince; | |
| var lastModified; | |
| var itemPath; | |
| return pattern = true, adjustHeight = false, url && (key = url), ruid = options, maxlength = value, n && (dir = n), tail = null, options && (l = parseInt(options.xoffset) || 0, m = parseInt(options.yoffset) || 0, ifModifiedSince = parseInt(options.length), lastModified = parseInt(options.width), ifModifiedSince && lastModified && ifModifiedSince >= 100 && lastModified >= 100 && (tail = l + " " + m + " " + (l + ifModifiedSince) + " " + (m + lastModified)), wrapped = options.mainzoneOnly || | |
| false), sides.forEach(function(name) { | |
| var id; | |
| var p; | |
| var u; | |
| var l; | |
| /** @type {null} */ | |
| var options = null; | |
| if (value && value[name]) { | |
| options = value[name]; | |
| } | |
| if (options) { | |
| /** @type {number} */ | |
| id = parseInt(options.xoffset) || 0; | |
| /** @type {number} */ | |
| p = parseInt(options.yoffset) || 0; | |
| /** @type {number} */ | |
| u = parseInt(options.length); | |
| /** @type {number} */ | |
| l = parseInt(options.width); | |
| if (u && l) { | |
| /** @type {string} */ | |
| deps[name] = id + " " + p + " " + (id + u) + " " + (p + l); | |
| } | |
| } else { | |
| /** @type {null} */ | |
| deps[name] = null; | |
| } | |
| }), generate(), spawnPio(true), i = idx ? idx : 0, input_dir = 0, itemPath = path ? path.length : 0, 0 == itemPath ? (err || get("Playlist is empty and hence can not play"), pattern = false, fn("No files to Play")) : (list = path, list.forEach(function(_ref) { | |
| var file = _ref.filename; | |
| if (file && file.match(opts.mediaRss)) { | |
| request(file); | |
| } | |
| if (file && file.match(opts.localFolderRegex)) { | |
| save(file); | |
| } | |
| lesson[key].forEach(function(index) { | |
| file = _ref[index]; | |
| if (file) { | |
| if (file.match(opts.mediaRss)) { | |
| request(file); | |
| } | |
| if (file.match(opts.localFolderRegex)) { | |
| save(file); | |
| } | |
| } | |
| }); | |
| }), screenSmallerThanEditor = false, item && (data.behavior = item.behavior || "slide", data.textSpeed = item.textSpeed || 3), success(item && !item.disabled && 0 != data.behavior.indexOf("openvg") || !ongoingMessage ? 1 : 0), callback(list[i].filename, parseInt(list[i].duration), render, list[i], list[i].fullscreen, list[i].option), self.startAds(), item && !item.disabled ? (data.isRssFeed = item.isRssFeed, data.rssLink = item.rssLink, data.rssEncodeAsBinary = item.rssEncodeAsBinary, data.useDescription = | |
| item.useDescription, data.feedDelay = 1E3 * (item.feedDelay || 10), data.tickerFontSize = item.tickerFontSize || 28, data.tickerWidth = item.tickerWidth || 0, data.tickerX = item.tickerX || 0, data.tickerY = item.tickerY || 0, item.style && (data.style = item.style, extend(data.style)), data.isRssFeed ? initialize(item.rssLink) : (item.messages = item.messages || "", "slide" == data.behavior ? (data.messages = item.messages.split("\n"), ongoingMessage || data.messages.push(change), activateAnnotator()) : | |
| (item.messages = item.messages.replace(/\n/g, " | "), data.currentTicker = item.messages, data.messages[0] = item.messages, get(item.messages)))) : toggleRecovery(), console.testLog("start_play", url, item, "" + path), void fn(null, changes)); | |
| }); | |
| }; | |
| /** | |
| * @param {!Function} type | |
| * @return {undefined} | |
| */ | |
| self.stopPlay = function(type) { | |
| /** @type {boolean} */ | |
| pattern = false; | |
| /** @type {!Array} */ | |
| values = []; | |
| pause(); | |
| toggleRecovery(); | |
| console.testLog("stop_play"); | |
| stop(type); | |
| }; | |
| /** | |
| * @param {!Function} type | |
| * @return {undefined} | |
| */ | |
| self.showKioskUi = function(type) { | |
| type = type || function() { | |
| }; | |
| if (!adjustHeight) { | |
| originalPattern = pattern; | |
| } | |
| /** @type {number} */ | |
| field = (field + 1) % 256; | |
| /** @type {boolean} */ | |
| adjustHeight = true; | |
| self.stopPlay(type); | |
| }; | |
| /** | |
| * @return {undefined} | |
| */ | |
| self.stopKioskUi = function() { | |
| self.stopFile(); | |
| }; | |
| /** | |
| * @param {string} filename | |
| * @param {string} path | |
| * @param {number} id | |
| * @param {string} index | |
| * @return {undefined} | |
| */ | |
| self.playFile = function(filename, path, id, index) { | |
| var data = {}; | |
| /** @type {null} */ | |
| var remainDecreaseNum = null; | |
| if (!adjustHeight) { | |
| originalPattern = pattern; | |
| } | |
| if (filename.match(opts.audioRegex)) { | |
| /** @type {boolean} */ | |
| data.main = true; | |
| } else { | |
| /** @type {boolean} */ | |
| data.main = false; | |
| } | |
| if (/(rtsp|http|https):\/\//.test(filename)) { | |
| /** @type {string} */ | |
| remainDecreaseNum = "cors"; | |
| } | |
| /** @type {number} */ | |
| field = (field + 1) % 256; | |
| /** @type {boolean} */ | |
| adjustHeight = true; | |
| clearTimeout(click_timeout_id); | |
| self.stopPlay(function() { | |
| /** @type {number} */ | |
| click_timeout_id = setTimeout(function() { | |
| /** @type {boolean} */ | |
| pattern = true; | |
| /** @type {boolean} */ | |
| screenSmallerThanEditor = false; | |
| console.log("info", "playFile " + filename); | |
| callback(filename, id || 3600, function(a) { | |
| return field != a ? void console.log("warn", "*** skipping callback in playFile: " + a + "," + field) : (index || self.stopFile(), void(path && path())); | |
| }, null, true, data, remainDecreaseNum); | |
| }, 1E3); | |
| }); | |
| }; | |
| /** | |
| * @return {undefined} | |
| */ | |
| self.pauseFile = function() { | |
| if (node) { | |
| fn("pause", node); | |
| } | |
| if (p) { | |
| fn("pause", p); | |
| } | |
| }; | |
| /** | |
| * @return {undefined} | |
| */ | |
| self.stopFile = function() { | |
| if (adjustHeight) { | |
| /** @type {boolean} */ | |
| adjustHeight = false; | |
| clearTimeout(click_timeout_id); | |
| self.stopPlay(function() { | |
| /** @type {number} */ | |
| click_timeout_id = setTimeout(function() { | |
| pattern = originalPattern; | |
| if (pattern) { | |
| self.startPlay(list, data, key, ruid, maxlength, dir, null, i); | |
| } | |
| }, 1E3); | |
| }); | |
| } | |
| }; | |
| /** | |
| * @param {string} message | |
| * @param {number} title | |
| * @return {undefined} | |
| */ | |
| self.showProgress = function(message, title) { | |
| if (v && !err) { | |
| /** @type {string} */ | |
| var path = " "; | |
| if (message) { | |
| /** @type {string} */ | |
| path = message + " Bytes Downloaded, Current Speed " + title + " Bytes/sec"; | |
| } | |
| get("Download in Progress: " + path); | |
| } | |
| }; | |
| /** | |
| * @return {undefined} | |
| */ | |
| self.showNormalTicker = function() { | |
| if (data.currentTicker) { | |
| get(data.currentTicker); | |
| } else { | |
| toggleRecovery(); | |
| } | |
| }; | |
| /** | |
| * @param {!Array} defaultValue | |
| * @return {undefined} | |
| */ | |
| self.startAds = function(defaultValue) { | |
| if (defaultValue) { | |
| /** @type {!Array} */ | |
| state = []; | |
| defaultValue.forEach(function(result) { | |
| var files = result.files; | |
| var inlineCount = result.interval; | |
| var _pher = result.noMainPlay; | |
| if (files) { | |
| state.push({ | |
| files : files, | |
| interval : inlineCount && inlineCount > 5 ? 1E3 * inlineCount : 5E3, | |
| adCount : parseInt(result.adCount || 1), | |
| noMainPlay : _pher | |
| }); | |
| } | |
| }); | |
| } | |
| if (state.length) { | |
| /** @type {boolean} */ | |
| inputWin = true; | |
| state.forEach(function(schedule, a) { | |
| /** @type {number} */ | |
| schedule.index = 0; | |
| /** @type {boolean} */ | |
| schedule.adReady = false; | |
| clearTimeout(schedule.timer); | |
| end(a, 0); | |
| }); | |
| } else { | |
| /** @type {boolean} */ | |
| inputWin = false; | |
| self.stopAds(); | |
| } | |
| }; | |
| /** | |
| * @return {undefined} | |
| */ | |
| self.pauseAds = function() { | |
| /** @type {boolean} */ | |
| inputWin = false; | |
| state.forEach(function(Statistics) { | |
| /** @type {boolean} */ | |
| Statistics.adReady = false; | |
| clearTimeout(Statistics.timer); | |
| }); | |
| }; | |
| /** | |
| * @return {undefined} | |
| */ | |
| self.stopAds = function() { | |
| self.pauseAds(); | |
| /** @type {!Array} */ | |
| state = []; | |
| }; | |
| /** @type {number} */ | |
| id = 0; | |
| /** | |
| * @param {!Object} data | |
| * @param {string} model | |
| * @param {number} method | |
| * @param {string} context | |
| * @return {undefined} | |
| */ | |
| self.startLoungeMusic = function(data, model, method, context) { | |
| /** @type {!Object} */ | |
| options.files = data; | |
| options.playRandom = model || false; | |
| options.volume = method || 100; | |
| /** @type {boolean} */ | |
| options.playing = true; | |
| id = id + 1; | |
| if (isFunction(options.process)) { | |
| options.process.stdin.pause(); | |
| resolve(options.process.pid, function() { | |
| setTimeout(function() { | |
| update(0, id, context); | |
| }, 3E3); | |
| }); | |
| } else { | |
| update(0, id, context); | |
| } | |
| }; | |
| /** | |
| * @return {undefined} | |
| */ | |
| self.stopLoungeMusic = function() { | |
| if (options.playing) { | |
| /** @type {boolean} */ | |
| options.playing = false; | |
| if (isFunction(options.process)) { | |
| options.process.stdin.pause(); | |
| resolve(options.process.pid, function() { | |
| }); | |
| } | |
| } | |
| }; | |
| /** | |
| * @param {string} data | |
| * @return {undefined} | |
| */ | |
| self.setResolution = function(data) { | |
| /** @type {string} */ | |
| autoReview = data; | |
| console.log("info", "resolution changed to " + data); | |
| }; | |
| /** | |
| * @param {string} val | |
| * @return {undefined} | |
| */ | |
| self.setOrientation = function(val) { | |
| /** @type {string} */ | |
| orientation = val; | |
| console.log("info", "orientation set to : " + val); | |
| }; | |
| /** | |
| * @param {string} message | |
| * @return {undefined} | |
| */ | |
| self.setLicense = function(message) { | |
| message = message || false; | |
| /** @type {string} */ | |
| ongoingMessage = message; | |
| console.testLog("license_status", message); | |
| }; | |
| /** | |
| * @param {boolean} width | |
| * @param {string} left | |
| * @param {string} top | |
| * @return {undefined} | |
| */ | |
| self.setAnimationStatus = function(width, left, top) { | |
| /** @type {boolean} */ | |
| whatToScale = width; | |
| /** @type {string} */ | |
| hPosPropUnused = left; | |
| if (!args && "fade" == hPosPropUnused || !hPosPropUnused) { | |
| /** @type {string} */ | |
| hPosPropUnused = "right"; | |
| } | |
| if (!top || opt_newBuffer) { | |
| error("js window.enablePiAnimation(" + whatToScale + ',"' + hPosPropUnused + '")'); | |
| } | |
| }; | |
| /** | |
| * @param {boolean} result | |
| * @return {undefined} | |
| */ | |
| self.setSystemMessagesHide = function(result) { | |
| /** @type {boolean} */ | |
| err = result; | |
| }; | |
| /** | |
| * @param {!Object} component | |
| * @param {!Object} root | |
| * @param {boolean} allRoots | |
| * @return {?} | |
| */ | |
| self.setDisplayClock = function(component, root, allRoots) { | |
| return settings.showClock = component.enable, component.enable && (settings.clockPosition = "top" == component.position ? pt : dev, settings.clockFormat = "24" == component.format ? ac_save : loadingDelay), showingAlertTitle ? (settings.eMsgCmd = root && root.enable && root.msg ? auto : png, settings.eMsgCmd === auto && (settings.eMsg = root.msg || "", settings.eMsgHorizontal = "left" == root.hPos ? chat : "right" == root.hPos ? Infinity : sortValue, settings.eMsgVertical = "top" == root.vPos ? | |
| _ : "bottom" == root.vPos ? divaInstance : y), void log()) : void((!allRoots || opt_newBuffer) && error("js window.setClock(" + settings.showClock + ")")); | |
| }; | |
| /** | |
| * @param {string} col | |
| * @param {boolean} b | |
| * @return {undefined} | |
| */ | |
| self.setBackgroundColor = function(col, b) { | |
| /** @type {string} */ | |
| colour = col; | |
| if (!b || opt_newBuffer) { | |
| error('js window.setBackgroundColor("' + colour + '")'); | |
| } | |
| }; | |
| /** | |
| * @param {string} a | |
| * @param {boolean} b | |
| * @return {undefined} | |
| */ | |
| self.setImageResize = function(a, b) { | |
| /** @type {string} */ | |
| optionUsed2 = a; | |
| if (!b || opt_newBuffer) { | |
| error("js window.fitImageToDiv(" + optionUsed2 + ")"); | |
| } | |
| }; | |
| /** | |
| * @param {boolean} $mmConfig | |
| * @return {undefined} | |
| */ | |
| self.setVideoKeepAspect = function($mmConfig) { | |
| /** @type {boolean} */ | |
| rightIndicator = $mmConfig; | |
| }; | |
| /** | |
| * @param {number} value | |
| * @return {undefined} | |
| */ | |
| self.setOMXVolume = function(value) { | |
| if (1 > value) { | |
| /** @type {number} */ | |
| value = 1; | |
| } else { | |
| if (value > 100) { | |
| /** @type {number} */ | |
| value = 100; | |
| } | |
| } | |
| /** @type {number} */ | |
| a = parseInt(2e3 * Math.log(value / 100) / Math.LN10); | |
| /** @type {number} */ | |
| attributeName = value; | |
| }; | |
| /** | |
| * @param {number} trackInfoUrl | |
| * @return {undefined} | |
| */ | |
| self.setTimeToStopVideo = function(trackInfoUrl) { | |
| /** @type {number} */ | |
| lastTrackInfoUrl = trackInfoUrl; | |
| }; | |
| /** | |
| * @param {string} val | |
| * @param {number} url | |
| * @param {number} src | |
| * @param {string} i | |
| * @return {undefined} | |
| */ | |
| self.setLogo = function(val, url, src, i) { | |
| if (val) { | |
| self.removeLogo(); | |
| i = i || false; | |
| var yCoord = i ? val : opts.mediaPath + val; | |
| subject = spawn("pngview", ["-x", url, "-y", src, yCoord], { | |
| stdio : "pipe" | |
| }); | |
| subject.on("error", function(step_name) { | |
| console.log("error", "pngview spawn error: " + step_name); | |
| }); | |
| } else { | |
| self.removeLogo(); | |
| } | |
| }; | |
| /** | |
| * @return {undefined} | |
| */ | |
| self.removeLogo = function() { | |
| if (isFunction(subject)) { | |
| subject.kill(); | |
| } | |
| }; | |
| /** | |
| * @param {boolean} a | |
| * @return {undefined} | |
| */ | |
| self.setAssetLogs = function(a) { | |
| /** @type {boolean} */ | |
| _x$4 = a; | |
| }; | |
| /** | |
| * @param {boolean} a | |
| * @return {undefined} | |
| */ | |
| self.setYoutubeDl = function(a) { | |
| /** @type {boolean} */ | |
| closest_arc = a; | |
| if (closest_arc) { | |
| exec("which youtube-dl", function(a, extension, b) { | |
| if (a || b) { | |
| console.log("warn", "youtube-dl is *not* available"); | |
| /** @type {boolean} */ | |
| closest_arc = false; | |
| } else { | |
| console.log("info", "youtube-dl is available at " + extension); | |
| /** @type {boolean} */ | |
| closest_arc = extension.length > 3 ? true : false; | |
| } | |
| }); | |
| } | |
| }; | |
| /** | |
| * @param {!Object} contain | |
| * @return {undefined} | |
| */ | |
| self.setMpv = function(contain) { | |
| /** @type {!Object} */ | |
| cover = contain; | |
| if (cover) { | |
| exec("which mpv", function(a, extension, b) { | |
| if (a || b) { | |
| console.log("warn", "mpv is *not* available"); | |
| /** @type {boolean} */ | |
| cover = false; | |
| } else { | |
| console.log("info", "mpv is available at " + extension); | |
| /** @type {boolean} */ | |
| cover = extension.length > 3 ? true : false; | |
| } | |
| }); | |
| } | |
| }; | |
| /** | |
| * @param {boolean} v | |
| * @param {boolean} b | |
| * @return {undefined} | |
| */ | |
| self.setUrlReloadDisable = function(v, b) { | |
| /** @type {boolean} */ | |
| validationVM = v; | |
| if (!b || opt_newBuffer) { | |
| error("js window.setUrlReloadDisable(" + validationVM + ")"); | |
| } | |
| }; | |
| /** | |
| * @return {?} | |
| */ | |
| self.getCurrentPlayingFile = function() { | |
| return waitImportedItem; | |
| }; | |
| /** | |
| * @return {?} | |
| */ | |
| self.getDominationStatus = function() { | |
| return addChar; | |
| }; | |
| /** @type {!Array} */ | |
| docs = []; | |
| /** | |
| * @param {boolean} isIron | |
| * @return {undefined} | |
| */ | |
| self.pauseOpenVg = function(isIron) { | |
| if (isIron) { | |
| /** @type {boolean} */ | |
| P = true; | |
| log(valueProgess); | |
| } else { | |
| /** @type {boolean} */ | |
| P = false; | |
| } | |
| }; | |
| /** @type {null} */ | |
| socket = null; | |
| c = new (require("events").EventEmitter); | |
| self.browserEmitter = c; | |
| /** | |
| * @param {string} value | |
| * @return {undefined} | |
| */ | |
| build = function(value) { | |
| var _dataset; | |
| /** @type {null} */ | |
| var e = null; | |
| /** @type {string} */ | |
| socket = value; | |
| /** @type {number} */ | |
| _dataset = 0; | |
| socket.on("message", function(f) { | |
| try { | |
| /** @type {*} */ | |
| e = JSON.parse(f); | |
| } catch (d) { | |
| return void console.log("error", "unable to parse message from chrome socket, " + f); | |
| } | |
| if (!e || !e.type) { | |
| return void console.log("error", "no data from chrome socket, " + f); | |
| } | |
| switch(e.type) { | |
| case "LOAD_FINISH": | |
| console.log("info", "Chrome loaded page " + e.data.slice(0, 50) + ";" + e.data2); | |
| c.emit("loaded", e.data); | |
| if (e.data2 && e.data2 != _dataset) { | |
| selectReportingCycle(); | |
| _dataset = e.data2; | |
| } | |
| if (!e.data2) { | |
| selectReportingCycle(); | |
| } | |
| break; | |
| case "COMMAND_EXECUTED": | |
| if (app && 0 == app.indexOf("js")) { | |
| selectReportingCycle(); | |
| } | |
| break; | |
| case "BROWSER_PAGE_ERROR": | |
| if (e.data) { | |
| console.log("error", "Browser Page Error : " + e.data.message); | |
| } | |
| break; | |
| default: | |
| console.log("error", "unknown message from browser : " + e.type); | |
| } | |
| }); | |
| }; | |
| /** | |
| * @param {string} link | |
| * @return {undefined} | |
| */ | |
| self.startChromeSocket = function(link) { | |
| if (link && (url = link), url && args) { | |
| var tcpServer = (new require("ws")).Server({ | |
| server : url, | |
| perMessageDeflate : false, | |
| verifyClient : function(info) { | |
| return info.req.headers.host && -1 !== info.req.headers.host.indexOf("127.0.0.1") ? true : false; | |
| } | |
| }); | |
| console.log("info", "Starting websocket"); | |
| tcpServer.on("connection", function(version) { | |
| /** @type {boolean} */ | |
| r = true; | |
| build(version); | |
| }); | |
| tcpServer.on("error", function(step_name) { | |
| console.log("error", "socket error " + step_name); | |
| }); | |
| tcpServer.on("close", function() { | |
| console.log("info", "socket closed"); | |
| }); | |
| } | |
| }; | |
| }); | |
| require.register("./app/controllers/pi-wget.js", function(a, b, require) { | |
| var ps; | |
| var spawn = require("child_process").spawn; | |
| var fs = require("fs"); | |
| var res = require("../others/logger"); | |
| var ui = require("./pi-viewer"); | |
| var TagHourlyStat = require("./pi-main"); | |
| var EffectChain = require("../others/extract-zip"); | |
| var config = require("../../config/config"); | |
| var CheckDailyStat = require("./package.json"); | |
| /** @type {number} */ | |
| var seconds = 0; | |
| /** | |
| * @param {string} index | |
| * @param {!Function} type | |
| * @param {!Function} _ | |
| * @return {?} | |
| */ | |
| b.getGroupFiles = function(index, type, _) { | |
| var timer; | |
| var products; | |
| var args; | |
| var show; | |
| var minutes; | |
| var data; | |
| var list; | |
| return type ? (_ = _ || function() { | |
| }, args = ["-rNnHd", "--no-parent", "-t", "20", "--waitretry", "60", "--retry-connrefused", "--no-cache"], args.push("-R"), args.push(type), args.push(CheckDailyStat.media_server + "/sync_folders/" + index + "/" + type), seconds > 0 && (res.log("info", "killing previous wget:" + ps.pid), ps.kill()), seconds++, ps = spawn("wget", args, { | |
| cwd : config.mediaDir, | |
| stdio : "pipe" | |
| }), products = ps, res.log("info", "Spawning wget " + args + "; Running as PID " + ps.pid), ps.on("error", function(len) { | |
| res.log("error", "wget spawn error: " + len); | |
| }), show = 0, minutes = 0, list = function() { | |
| TagHourlyStat.writeToConfig({ | |
| syncInProgress : true, | |
| wgetBytes : data, | |
| wgetSpeed : show | |
| }, true); | |
| ui.showProgress(data, show); | |
| /** @type {number} */ | |
| timer = setTimeout(list, 3E4); | |
| }, list(), ps.stdout.on("data", function(len) { | |
| res.log("info", "" + len); | |
| }), ps.stderr.on("data", function(value) { | |
| var i; | |
| var newcells; | |
| /** @type {string} */ | |
| var str = "" + value; | |
| /** @type {(Array<string>|null)} */ | |
| var loadedAddons = str.match(/%/g); | |
| if (loadedAddons) { | |
| minutes = minutes + 50 * loadedAddons.length; | |
| data = minutes > 1E3 ? (minutes / 1E3).toFixed(2) + "M" : minutes.toFixed(2) + "K"; | |
| /** @type {number} */ | |
| i = str.indexOf("%"); | |
| /** @type {(Array<string>|null)} */ | |
| newcells = str.slice(i + 1).trim().match(/[\w.]+/); | |
| if (newcells && newcells.length > 0) { | |
| /** @type {string} */ | |
| show = newcells[0]; | |
| } | |
| } | |
| }), ps.stdin.on("error", function(len) { | |
| res.log("info", "wget stdin error: " + len); | |
| }), void ps.on("exit", function(type, b) { | |
| return res.log("info", "wget stopped with code " + type + " and signal " + b + "; downloadInProgressCount: " + seconds), clearTimeout(timer), products = null, seconds--, seconds > 0 ? _(-1) : (ps = null, show = 0, ui.showNormalTicker(), TagHourlyStat.writeToConfig({ | |
| syncInProgress : false | |
| }, true), void fs.unlink(config.mediaPath + "robots.txt", function() { | |
| EffectChain.extractStart(); | |
| if (0 !== type) { | |
| _("wget process exited with code " + type, type); | |
| } else { | |
| _(); | |
| } | |
| })); | |
| })) : _("There is no group to fetch"); | |
| }; | |
| }); | |
| require.register("./app/controllers/pi-events.js", function(a, proxy, require) { | |
| var test; | |
| var iter; | |
| var fs = require("fs"); | |
| var path = require("path"); | |
| var async = require("async"); | |
| var self = require("./pi-main"); | |
| var dispatcher = require("../others/logger"); | |
| var app = require("../../config/config"); | |
| var result = { | |
| category : "player", | |
| ts : 0, | |
| log : { | |
| playerUptime : 0, | |
| tvUptime : 0 | |
| } | |
| }; | |
| /** @type {number} */ | |
| var n = .25; | |
| /** | |
| * @param {number} object | |
| * @return {undefined} | |
| */ | |
| var add = function(object) { | |
| fs.readdir(app.logsDir, function(id, currentMembers) { | |
| return id ? void dispatcher.log("error", "read error for logs directory," + id) : void async.eachSeries(currentMembers, function(file, saveNotifs) { | |
| if (file.slice(0, file.indexOf(".")) < object) { | |
| fs.readFile(path.join(app.logsDir, file), "utf8", function(a, signedAuthToken) { | |
| if (signedAuthToken) { | |
| self.uploadLog(file, signedAuthToken); | |
| } | |
| saveNotifs(); | |
| }); | |
| } else { | |
| saveNotifs(); | |
| } | |
| }, function() { | |
| self.uploadForeverLog(); | |
| }); | |
| }); | |
| }; | |
| /** | |
| * @param {string} key | |
| * @return {undefined} | |
| */ | |
| proxy.deleteLog = function(key) { | |
| fs.unlink(path.join(app.logsDir, key)); | |
| }; | |
| /** | |
| * @param {string} type | |
| * @param {string} name | |
| * @param {string} msg | |
| * @return {undefined} | |
| */ | |
| proxy.storeEvent = function(type, name, msg) { | |
| var item = { | |
| category : type, | |
| ts : Date.now(), | |
| type : name, | |
| description : msg | |
| }; | |
| var dumpFile = path.join(app.logsDir, (new Date).setMinutes(0, 0, 0) + ".events"); | |
| fs.appendFile(dumpFile, JSON.stringify(item) + "\n"); | |
| }; | |
| /** | |
| * @return {undefined} | |
| */ | |
| test = function() { | |
| var svrComps; | |
| var i; | |
| /** @type {number} */ | |
| var now = (new Date).setMinutes(0, 0, 0); | |
| if (add(now), svrComps = self.statusLog(), now > result.ts) { | |
| /** @type {number} */ | |
| result.ts = now; | |
| result.log = {}; | |
| /** @type {number} */ | |
| result.log.playerUptime = n; | |
| for (i in svrComps) { | |
| if (svrComps[i]) { | |
| /** @type {number} */ | |
| result.log[i] = n; | |
| } | |
| } | |
| } else { | |
| result.log.playerUptime += n; | |
| for (i in svrComps) { | |
| if (svrComps[i]) { | |
| result.log[i] = (result.log[i] || 0) + n; | |
| } | |
| } | |
| } | |
| }; | |
| /** | |
| * @return {undefined} | |
| */ | |
| iter = function() { | |
| fs.writeFile(path.join(app.logsDir, result.ts + ".log"), JSON.stringify(result, null, 4), function() { | |
| test(); | |
| }); | |
| setTimeout(iter, 36E5 * n); | |
| }; | |
| /** | |
| * @param {string} name | |
| * @return {undefined} | |
| */ | |
| proxy.logFilePlay = function(name) { | |
| name = name.replace(/[^a-zA-Z0-9]/g, "_"); | |
| if (result.ts) { | |
| result.log[name] = (result.log[name] || 0) + 1; | |
| } | |
| }; | |
| /** | |
| * @return {undefined} | |
| */ | |
| proxy.startLog = function() { | |
| test(); | |
| setTimeout(iter, 36E5 * n); | |
| }; | |
| }); | |
| require.register("./app/controllers/assets.js", function(a, self, require) { | |
| var loadUserFromApiKey; | |
| var mongoose; | |
| var Integrations; | |
| var config = require("../../config/config"); | |
| var console = require("../others/restware"); | |
| var fs = require("fs"); | |
| var assert = require("path"); | |
| var async = require("async"); | |
| var exec = require("child_process").exec; | |
| var ejs = require("ejs"); | |
| var Jmol = (require("lodash"), require("../others/file-util")); | |
| var client = require("../others/logger"); | |
| if ("pi" == config.env) { | |
| loadUserFromApiKey = require("./pi-main"); | |
| } else { | |
| loadUserFromApiKey = require("./server-main"); | |
| mongoose = require("mongoose"); | |
| Integrations = mongoose.model("Asset"); | |
| } | |
| /** | |
| * @param {!Object} req | |
| * @param {!Object} res | |
| * @return {undefined} | |
| */ | |
| self.index = function(req, res) { | |
| var url; | |
| var k = req.installation; | |
| /** @type {null} */ | |
| var b = null; | |
| var result = { | |
| sizes : { | |
| total : 0, | |
| used : 0 | |
| }, | |
| files : null, | |
| dbdata : null, | |
| systemAssets : config.systemAssets | |
| }; | |
| if (req.query.installation) { | |
| k = req.query.installation; | |
| } | |
| if (req.query.label) { | |
| b = req.query.label; | |
| } | |
| url = assert.join(config.mediaDir, k); | |
| async.series([function(hasClass) { | |
| if ("pi" != config.env) { | |
| exec("du -ms " + url, function(canCreateDiscussions, release) { | |
| /** @type {number} */ | |
| var version = parseInt(release); | |
| /** @type {number} */ | |
| result.sizes.used = version; | |
| require("mongoose").model("User").findOne({ | |
| username : req.installation | |
| }, function(a, b) { | |
| if (!a && b) { | |
| result.sizes.total = b.serverLicenses * config.spacePerLicense + (b.storageSpace || 0); | |
| result.sizes.total = result.sizes.total > 300 ? result.sizes.total : 300; | |
| } | |
| hasClass(); | |
| }); | |
| }); | |
| } else { | |
| hasClass(); | |
| } | |
| }, function(saveNotifs) { | |
| fs.readdir(url, function(notifications, swimlanes) { | |
| if (notifications) { | |
| saveNotifs(notifications); | |
| } else { | |
| var data = swimlanes.filter(function(hashComponent) { | |
| return "_" != hashComponent.charAt(0) && "." != hashComponent.charAt(0); | |
| }); | |
| result.files = data; | |
| saveNotifs(); | |
| } | |
| }); | |
| }, function(hasClass) { | |
| if ("pi" != config.env) { | |
| Integrations.find({ | |
| installation : k | |
| }, function(b, a) { | |
| if (!b && a) { | |
| /** @type {string} */ | |
| result.dbdata = a; | |
| } | |
| hasClass(); | |
| }); | |
| } else { | |
| hasClass(); | |
| } | |
| }, function(callback) { | |
| var c; | |
| var d; | |
| var optionUsed3; | |
| var id; | |
| var j; | |
| var i; | |
| var existingProxyIndex; | |
| if ("pi" == config.env) { | |
| return callback(); | |
| } | |
| if (c = false, d = null, optionUsed3 = false, req.collaboratorRights && req.collaboratorRights.groupIds && req.collaboratorRights.groupIds.length && (req.collaboratorRights.asset.restrictAdmin ? (c = true, d = req.collaboratorRights.groupIds) : req.collaboratorRights.asset.restrict && (d = req.collaboratorRights.groupIds, c = false)), (b || d) && result.dbdata) { | |
| /** @type {number} */ | |
| id = 0; | |
| j = result.dbdata.length; | |
| for (; j > id; id++) { | |
| if (result.dbdata[id].groupIds && result.dbdata[id].groupIds.length) { | |
| /** @type {boolean} */ | |
| optionUsed3 = false; | |
| /** @type {number} */ | |
| i = 0; | |
| for (; i < d.length; i++) { | |
| if (result.dbdata[id].groupIds.indexOf(d[i]) >= 0) { | |
| /** @type {boolean} */ | |
| optionUsed3 = true; | |
| break; | |
| } | |
| } | |
| } else { | |
| /** @type {boolean} */ | |
| optionUsed3 = c; | |
| } | |
| if (b && result.dbdata[id].labels && result.dbdata[id].labels.length) { | |
| /** @type {boolean} */ | |
| optionUsed3 = result.dbdata[id].labels.indexOf(b) >= 0; | |
| } | |
| if (!optionUsed3) { | |
| existingProxyIndex = result.files.indexOf(result.dbdata[id].name); | |
| if (existingProxyIndex >= 0) { | |
| result.files.splice(existingProxyIndex, 1); | |
| } | |
| } | |
| } | |
| callback(); | |
| } else { | |
| callback(); | |
| } | |
| }], function(err) { | |
| return err ? console.sendError(res, "Error reading media directory: " + err) : console.sendSuccess(res, "Sending media directory files: ", result); | |
| }); | |
| }; | |
| /** | |
| * @param {!Object} req | |
| * @param {!Object} res | |
| * @return {undefined} | |
| */ | |
| self.createFiles = function(req, res) { | |
| /** | |
| * @param {?} index | |
| * @param {?} callback | |
| * @return {?} | |
| */ | |
| function create(index, callback) { | |
| var file = req.files[index]; | |
| var filename = file.originalname || file.name; | |
| return filename ? (filename = filename.replace(config.filenameRegex, ""), filename.match(config.zipfileRegex) && (filename = filename.replace(/ /g, "")), filename.match(config.brandRegex) && (filename = filename.toLowerCase()), void fs.rename(file.path, assert.join(url, filename), function(line) { | |
| if (line) { | |
| client.log("error", "file rename error:" + line); | |
| callback(line); | |
| } else { | |
| if (filename.match(config.zipfileRegex)) { | |
| items.push(filename); | |
| } | |
| if (filename.match(/^custom_layout.*html$/i)) { | |
| Jmol.modifyHTML(url, filename); | |
| } | |
| data.push({ | |
| name : filename, | |
| size : file.size, | |
| type : file.mimetype || file.type | |
| }); | |
| callback(); | |
| } | |
| })) : void client.log("error", { | |
| error : "invalid file name ", | |
| msg : file | |
| }); | |
| } | |
| var url = assert.join(config.mediaDir, req.installation); | |
| /** @type {!Array<string>} */ | |
| var addedlist = Object.keys(req.files); | |
| /** @type {!Array} */ | |
| var data = []; | |
| /** @type {!Array} */ | |
| var items = []; | |
| async.series([function(read) { | |
| return "pi" == config.env ? read() : void exec("du -ms " + url, function(length, images) { | |
| var dim; | |
| /** @type {number} */ | |
| var normalized_images = parseInt(images); | |
| return length ? read() : void require("mongoose").model("User").findOne({ | |
| username : req.installation | |
| }, function(err, size) { | |
| return err || !size ? read() : (dim = size.serverLicenses * config.spacePerLicense + (size.storageSpace || 0), dim = dim > 300 ? dim : 300, !isNaN(normalized_images) && normalized_images > dim ? void async.each(addedlist, function(i, cb_) { | |
| console.log("deleting " + req.files[i].path); | |
| fs.unlink(req.files[i].path, cb_); | |
| }, function() { | |
| return read("Exceeded Storage Limit for the installation, please purchase more storage"); | |
| }) : read()); | |
| }); | |
| }); | |
| }, function(exec) { | |
| async.each(addedlist, create, function(filesWildcard) { | |
| return loadUserFromApiKey.writeToConfig({ | |
| lastUpload : Date.now() | |
| }), loadUserFromApiKey.updateDiskStatus(), filesWildcard ? (console.log(data), exec("File rename error " + filesWildcard)) : ("pi" == config.env && items.length > 0 && require("../others/extract-zip").extractStart(items), exec()); | |
| }); | |
| }], function(msg) { | |
| if (msg) { | |
| console.sendError(res, msg); | |
| } else { | |
| console.sendSuccess(res, " Successfully uploaded files", data); | |
| } | |
| }); | |
| }; | |
| /** | |
| * @param {?} req | |
| * @param {!Object} res | |
| * @return {?} | |
| */ | |
| self.updateFileDetails = function(req, res) { | |
| return "pi" == config.env ? console.sendSuccess(res, "File Upload Successful") : void require("./server-assets").storeDetails(req, res); | |
| }; | |
| /** | |
| * @param {!Object} req | |
| * @param {!Object} res | |
| * @return {undefined} | |
| */ | |
| self.getFileDetails = function(req, res) { | |
| var file = req.params.file; | |
| var dir = assert.join(config.mediaDir, req.installation); | |
| fs.stat(assert.join(dir, file), function(err, stats) { | |
| if (err) { | |
| return console.sendError(res, "file stat error", err); | |
| } | |
| var type; | |
| return type = file.match(config.imageRegex) ? "image" : file.match(config.videoRegex) ? "video" : file.match(config.audioRegex) ? "audio" : file.match(config.noticeRegex) ? "notice" : file.match(config.pdffileRegex) ? "pdf" : file.match(config.htmlRegex) ? "html" : file.match(config.liveStreamRegex) || file.match(config.linkUrlRegex) ? "link" : file.match(config.gcalRegex) ? "gcal" : file.match(config.txtFileRegex) ? "text" : file.match(config.radioFileRegex) ? "radio" : "other", "pi" == | |
| config.env ? console.sendSuccess(res, "Sending file details", { | |
| name : file, | |
| size : ~~(stats.size / 1E3) + " KB", | |
| ctime : stats.ctime, | |
| type : type, | |
| path : "/media/" + file | |
| }) : void Integrations.findOne({ | |
| name : file, | |
| installation : req.installation | |
| }, function(canCreateDiscussions, dbdata) { | |
| return console.sendSuccess(res, "Sending file details", { | |
| name : file, | |
| size : ~~(stats.size / 1E3) + " KB", | |
| ctime : stats.ctime, | |
| path : "/media/" + req.installation + "/" + file, | |
| type : type, | |
| dbdata : dbdata | |
| }); | |
| }); | |
| }); | |
| }; | |
| /** | |
| * @param {!Object} req | |
| * @param {!Object} res | |
| * @return {undefined} | |
| */ | |
| self.deleteFile = function(req, res) { | |
| var directory = assert.join(config.mediaDir, req.installation); | |
| var filename = req.params.file; | |
| /** @type {null} */ | |
| var blobName = null; | |
| /** @type {null} */ | |
| var to = null; | |
| if (filename.match(config.noticeRegex) && 0 != filename.indexOf("custom_layout")) { | |
| /** @type {string} */ | |
| blobName = "_" + assert.basename(filename, ".html") + ".json"; | |
| } | |
| async.series([function(originListener) { | |
| fs.unlink(assert.join(directory, filename), function(e) { | |
| return e ? originListener(e) : (loadUserFromApiKey.updateDiskStatus(), void originListener()); | |
| }); | |
| }, function(callback) { | |
| if ("pi" != config.env && (filename.match(config.videoRegex) || filename.match(config.imageRegex))) { | |
| Integrations.findOne({ | |
| name : filename, | |
| installation : req.installation | |
| }, function(a, configData) { | |
| if (configData && configData.thumbnail) { | |
| var alias = configData.thumbnail; | |
| alias = alias.replace("/media/_thumbnails/", ""); | |
| to = assert.join(config.thumbnailDir, alias); | |
| } | |
| callback(); | |
| }); | |
| } else { | |
| callback(); | |
| } | |
| }, function(callback) { | |
| if ("pi" != config.env) { | |
| Integrations.remove({ | |
| name : filename, | |
| installation : req.installation | |
| }, function(a) { | |
| if (a) { | |
| client.log("error", "unable to delete asset from db for :" + filename); | |
| } | |
| callback(); | |
| }); | |
| } else { | |
| callback(); | |
| } | |
| }, function(callback) { | |
| if (to) { | |
| fs.unlink(to, function(index) { | |
| if (index) { | |
| client.log("error", "unable to find/delete thumbnail: " + index); | |
| } | |
| callback(); | |
| }); | |
| } else { | |
| if (blobName) { | |
| fs.unlink(assert.join(directory, blobName), function() { | |
| callback(); | |
| }); | |
| } else { | |
| callback(); | |
| } | |
| } | |
| }], function(err) { | |
| return err ? console.sendError(res, "Unable to delete file", err) : console.sendSuccess(res, "Deleted file", filename); | |
| }); | |
| }; | |
| /** | |
| * @param {!Object} req | |
| * @param {!Object} res | |
| * @return {undefined} | |
| */ | |
| self.updateAsset = function(req, res) { | |
| var dir; | |
| var filename; | |
| var file; | |
| var language; | |
| var newFileName; | |
| if (req.body.newname) { | |
| dir = assert.join(config.mediaDir, req.installation); | |
| filename = req.params.file; | |
| file = req.body.newname; | |
| /** @type {null} */ | |
| language = null; | |
| /** @type {null} */ | |
| newFileName = null; | |
| if (filename.match(config.noticeRegex) && 0 != filename.indexOf("custom_layout")) { | |
| /** @type {string} */ | |
| language = "_" + filename.slice(0, filename.lastIndexOf(".")) + ".json"; | |
| /** @type {string} */ | |
| newFileName = "_" + file.slice(0, file.lastIndexOf(".")) + ".json"; | |
| } | |
| async.series([function(saveNotifs) { | |
| fs.rename(assert.join(dir, filename), assert.join(dir, file), function(notifications) { | |
| if (notifications) { | |
| client.log("error", "unable to rename " + filename + " for " + req.installation); | |
| } | |
| saveNotifs(notifications); | |
| }); | |
| }, function(saveNotifs) { | |
| if (language && newFileName) { | |
| fs.rename(assert.join(dir, language), assert.join(dir, newFileName), function(notifications) { | |
| if (notifications) { | |
| client.log("error", "JSON file Rename Error " + filename + " for " + req.installation); | |
| } | |
| saveNotifs(notifications); | |
| }); | |
| } else { | |
| saveNotifs(); | |
| } | |
| }, function(saveNotifs) { | |
| if ("pi" != config.env) { | |
| require("./server-assets").renameObject(req.installation, filename, file); | |
| } | |
| saveNotifs(); | |
| }], function(err) { | |
| return err ? console.sendError(res, "File rename error", err) : console.sendSuccess(res, " Successfully renamed file to", file); | |
| }); | |
| } else { | |
| if (req.body.dbdata && "pi" != config.env) { | |
| require("./server-assets").updateObject(req, res); | |
| } | |
| } | |
| }; | |
| /** | |
| * @param {!Object} req | |
| * @param {!Object} res | |
| * @return {undefined} | |
| */ | |
| self.createNotice = function(req, res) { | |
| var text; | |
| var data; | |
| var tempName; | |
| var worktree = assert.join(config.mediaDir, req.installation); | |
| var defaults = req.body.formdata; | |
| var a = { | |
| title : defaults.title, | |
| description : defaults.description, | |
| image : defaults.image || "", | |
| footer : defaults.footer || "" | |
| }; | |
| async.series([function(exec) { | |
| var chanlogpath = assert.join(worktree, "notice_template.ejs"); | |
| fs.exists(chanlogpath, function(module) { | |
| var reducerDefaults; | |
| reducerDefaults = module ? chanlogpath : config.defaultTemplate; | |
| fs.readFile(reducerDefaults, "utf8", function(filesWildcard, sectionAnchor) { | |
| if (filesWildcard) { | |
| exec("Error reading template file: " + filesWildcard); | |
| } else { | |
| text = sectionAnchor; | |
| exec(); | |
| } | |
| }); | |
| }); | |
| }, function(saveNotifs) { | |
| data = ejs.compile(text)(a); | |
| saveNotifs(); | |
| }, function(collector) { | |
| tempName = req.params.file ? assert.basename(req.params.file, ".html") : defaults.title.slice(0, 20).replace(/\W/g, "") + "_" + Math.floor(1E4 * Math.random()); | |
| fs.writeFile(assert.join(worktree, tempName + ".html"), data, "utf8", function(a) { | |
| if (a) { | |
| collector("Error writing html file: " + a); | |
| } else { | |
| fs.writeFile(assert.join(worktree, "_" + tempName + ".json"), JSON.stringify(a, null, 4), "utf8", function(a) { | |
| if (a) { | |
| collector("Error writing json file: " + a); | |
| } else { | |
| loadUserFromApiKey.writeToConfig({ | |
| lastUpload : Date.now() | |
| }); | |
| loadUserFromApiKey.updateDiskStatus(); | |
| collector(); | |
| } | |
| }); | |
| } | |
| }); | |
| }, function(wrongCredsCallback) { | |
| if ("pi" != config.env) { | |
| require("./server-assets").storeLinkDetails(tempName + ".html", "notice", req.installation, req.user, req.body.categories, req.collaboratorRights && req.collaboratorRights.groupIds && req.collaboratorRights.groupIds.length ? req.collaboratorRights.groupIds : null, wrongCredsCallback); | |
| } else { | |
| wrongCredsCallback(); | |
| } | |
| }], function(msg) { | |
| if (msg) { | |
| console.sendError(res, msg); | |
| } else { | |
| console.sendSuccess(res, "Notice File Saved", data); | |
| } | |
| }); | |
| }; | |
| /** | |
| * @param {!Object} req | |
| * @param {!Object} res | |
| * @return {undefined} | |
| */ | |
| self.getNotice = function(req, res) { | |
| var dir = assert.join(config.mediaDir, req.installation); | |
| var response = {}; | |
| async.series([function(_) { | |
| /** @type {string} */ | |
| var sample = "_" + assert.basename(req.params.file, ".html") + ".json"; | |
| fs.readFile(assert.join(dir, sample), "utf8", function(b, data) { | |
| return b ? _(b) : (response.data = data ? JSON.parse(data) : null, _()); | |
| }); | |
| }, function(saveNotifs) { | |
| if ("pi" != config.env) { | |
| Integrations.findOne({ | |
| name : req.params.file, | |
| installation : req.installation | |
| }, function(a, dbdata) { | |
| /** @type {string} */ | |
| response.dbdata = dbdata; | |
| saveNotifs(); | |
| }); | |
| } else { | |
| saveNotifs(); | |
| } | |
| }], function(err) { | |
| return err ? console.sendError(res, "JSON file read error", err) : console.sendSuccess(res, "Sending notice file details", response); | |
| }); | |
| }; | |
| /** | |
| * @param {!Object} req | |
| * @param {!Object} res | |
| * @return {undefined} | |
| */ | |
| self.zipPreview = function(req, res) { | |
| var indexHTMLPath = assert.join(config.mediaDir, req.installation, req.params.file); | |
| var version = req.params.file.replace(/(.zip|.gz|.bz2)/g, ""); | |
| var apexRestPath = assert.join(config.mediaDir, req.installation, "unzipped-" + version); | |
| /** @type {string} */ | |
| var text = "unzipped-" + version; | |
| fs.createReadStream(indexHTMLPath).pipe(require("unzip").Extract({ | |
| path : apexRestPath | |
| })); | |
| console.sendSuccess(res, "Sending zip file path", "/media/" + req.installation + "/" + text); | |
| }; | |
| /** | |
| * @param {?} name | |
| * @param {?} data | |
| * @param {?} cb | |
| * @return {undefined} | |
| */ | |
| self.createAssetFileFromContent = function(name, data, cb) { | |
| var predictionFileName = assert.resolve(config.mediaDir, name); | |
| fs.writeFile(predictionFileName, JSON.stringify(data, null, 4), cb); | |
| }; | |
| /** | |
| * @param {!Object} req | |
| * @param {!Object} res | |
| * @return {undefined} | |
| */ | |
| self.createLinkFile = function(req, res) { | |
| var type = assert.join(config.mediaPath, req.installation); | |
| var details = req.body.details; | |
| async.series([function(saveNotifs) { | |
| fs.writeFile(type + "/" + details.name + details.type, JSON.stringify(details, null, 4), "utf8", function(notifications) { | |
| saveNotifs(notifications); | |
| }); | |
| }, function(wrongCredsCallback) { | |
| if ("pi" != config.env) { | |
| require("./server-assets").storeLinkDetails(details.name + details.type, "link", req.installation, req.user, req.body.categories, req.collaboratorRights && req.collaboratorRights.groupIds && req.collaboratorRights.groupIds.length ? req.collaboratorRights.groupIds : null, wrongCredsCallback); | |
| } else { | |
| wrongCredsCallback(); | |
| } | |
| }], function(err) { | |
| return err ? console.sendError(res, "error in creating link file", err) : console.sendSuccess(res, "Link file created for the link as " + details.name + details.type); | |
| }); | |
| }; | |
| /** | |
| * @param {!Object} req | |
| * @param {!Object} res | |
| * @return {undefined} | |
| */ | |
| self.getLinkFileDetails = function(req, res) { | |
| var staticPrefix = assert.join(config.mediaPath, req.installation); | |
| var path = req.params.file; | |
| var retData = {}; | |
| async.series([function(saveNotifs) { | |
| fs.readFile(staticPrefix + "/" + path, "utf-8", function(notifications, data) { | |
| /** @type {string} */ | |
| retData.data = data; | |
| saveNotifs(notifications); | |
| }); | |
| }, function(saveNotifs) { | |
| if ("pi" != config.env) { | |
| Integrations.findOne({ | |
| name : path, | |
| installation : req.installation | |
| }, function(a, dbdata) { | |
| /** @type {string} */ | |
| retData.dbdata = dbdata; | |
| saveNotifs(); | |
| }); | |
| } else { | |
| saveNotifs(); | |
| } | |
| }], function(err) { | |
| return err ? console.sendError(res, "unable to read link file, error:" + err) : console.sendSuccess(res, "link file details", retData); | |
| }); | |
| }; | |
| /** | |
| * @param {!Object} req | |
| * @param {!Object} res | |
| * @return {?} | |
| */ | |
| self.updatePlaylist = function(req, res) { | |
| return "pi" == config.env ? console.sendSuccess(res, "I am pi") : (require("./server-assets").updatePlaylist(req.installation, req.body.playlist, req.body.assets), console.sendSuccess(res, "asset update has been queued")); | |
| }; | |
| /** | |
| * @param {!Object} req | |
| * @param {!Object} res | |
| * @return {?} | |
| */ | |
| self.createCustomTemplate = function(req, res) { | |
| var args; | |
| var path; | |
| var last_frame_text; | |
| var excludedName; | |
| var input; | |
| var layerClass; | |
| var value; | |
| var data; | |
| var pubChan; | |
| var $; | |
| return "pi" == config.env ? console.sendSuccess(res, "I am pi") : (args = ["main", "side", "bottom", "zone4", "zone5", "zone6"], path = req.body.filename || "custom_template.html", last_frame_text = req.body.html || "", excludedName = req.body.css || "", value = req.body.properties || null, data = {}, pubChan = assert.join(config.mediaPath, req.installation), path.match("^custom_layout") || (path = "custom_layout_" + path), path.match(".html$") || (path = path + ".html"), void async.series([function(exec) { | |
| fs.readFile("templates/screen-layout.html", { | |
| encoding : "utf-8" | |
| }, function(filesWildcard, data) { | |
| if (filesWildcard) { | |
| return exec("Error reading screen-layout: " + filesWildcard); | |
| } | |
| if ($ = require("cheerio").load(data), value) { | |
| $("#marquee").after('<div id="properties" style="display:none;"> </div>'); | |
| $("#properties").attr("data-properties", value); | |
| try { | |
| /** @type {*} */ | |
| data = JSON.parse(value); | |
| } catch (extension) { | |
| client.log("error", "Parsing error for custom template properties: " + extension); | |
| } | |
| /** @type {string} */ | |
| layerClass = ""; | |
| /** @type {string} */ | |
| input = ""; | |
| if (data.bgImage) { | |
| /** @type {string} */ | |
| input = input + '#full {background-image:url("' + data.bgImage + '")}'; | |
| } | |
| args.forEach(function(i) { | |
| if (data[i] && data[i].enable) { | |
| /** @type {string} */ | |
| input = input + "#" + i + " { position: absolute; top:" + data[i].y + "px; left: " + data[i].x + "px; width: " + data[i].w + "px; height: " + data[i].h + "px; }"; | |
| /** @type {string} */ | |
| layerClass = layerClass + '<div id="' + i + '" class="zone"> </div>'; | |
| } | |
| }); | |
| if (input) { | |
| $("head").append('<style id="customcss" type="text/css">' + input + "</style>"); | |
| } | |
| if (layerClass) { | |
| $("#full").append(layerClass); | |
| } | |
| } else { | |
| if (last_frame_text) { | |
| $("#full").append(last_frame_text); | |
| } | |
| } | |
| if (excludedName) { | |
| $("head").append('<style id="customcss2" type="text/css">' + excludedName + "</style>"); | |
| } | |
| exec(); | |
| }); | |
| }, function(saveNotifs) { | |
| fs.writeFile(pubChan + "/" + path, $.html(), "utf8", function(notifications) { | |
| saveNotifs(notifications); | |
| }); | |
| }, function(wrongCredsCallback) { | |
| if ("pi" != config.env) { | |
| require("./server-assets").storeLinkDetails(path, "html", req.installation, req.user, req.body.categories, req.collaboratorRights && req.collaboratorRights.groupIds && req.collaboratorRights.groupIds.length ? req.collaboratorRights.groupIds : null, wrongCredsCallback); | |
| } else { | |
| wrongCredsCallback(); | |
| } | |
| }], function(err) { | |
| return err ? console.sendError(res, "Error in creating custom template file", err) : console.sendSuccess(res, "Custom template file saved as " + path, { | |
| filename : path | |
| }); | |
| })); | |
| }; | |
| /** | |
| * @param {!Object} req | |
| * @param {!Object} res | |
| * @return {?} | |
| */ | |
| self.getCustomTemplate = function(req, res) { | |
| var uploadFolderPath; | |
| var filename; | |
| var $; | |
| var feature; | |
| return "pi" == config.env ? console.sendSuccess(res, "I am pi") : (uploadFolderPath = assert.join(config.mediaPath, req.installation), filename = req.params.file, filename.match("^custom_layout.*.html$") ? void fs.readFile(uploadFolderPath + "/" + filename, "utf-8", function(err, data) { | |
| return err ? console.sendError(res, "Error reading file: " + err) : ($ = require("cheerio").load(data), $("script").remove(), feature = $("#properties").data(), console.sendSuccess(res, "Custom template details", { | |
| properties : feature ? feature.properties : null, | |
| css : $("#customcss2").html(), | |
| html : $("#full").html(), | |
| srcDoc : $.html() | |
| })); | |
| }) : console.sendError(res, "Not a custom template file: " + filename)); | |
| }; | |
| }); | |
| require.register("./app/controllers/playlists.js", function(a, self, require) { | |
| var stex = require("../../config/config"); | |
| var server = require("../others/restware"); | |
| var fs = require("fs"); | |
| var path = require("path"); | |
| var async = require("async"); | |
| var utils = require("../others/logger"); | |
| /** @type {!Array} */ | |
| var hours = [{ | |
| name : "TV_OFF", | |
| settings : {}, | |
| assets : [], | |
| layout : "1", | |
| schedule : {} | |
| }]; | |
| /** | |
| * @param {string} a | |
| * @return {?} | |
| */ | |
| var k = function(a) { | |
| return "_" == a.charAt(0) && "_" == a.charAt(1) && ".json" == a.slice(-5); | |
| }; | |
| /** | |
| * @param {?} e | |
| * @param {string} name | |
| * @param {!Function} cb | |
| * @param {?} c | |
| * @return {undefined} | |
| */ | |
| self.newPlaylist = function(e, name, cb, c) { | |
| var filePath = path.join(stex.mediaDir, e, "__" + name + ".json"); | |
| var data = { | |
| name : name, | |
| settings : { | |
| ticker : { | |
| enable : false, | |
| behavior : "scroll", | |
| textSpeed : 3, | |
| rss : { | |
| enable : false, | |
| link : null, | |
| feedDelay : 10 | |
| } | |
| }, | |
| ads : { | |
| adPlaylist : false, | |
| adCount : 1, | |
| adInterval : 60 | |
| }, | |
| audio : { | |
| enable : false, | |
| random : false, | |
| volume : 50 | |
| } | |
| }, | |
| assets : [], | |
| layout : "1", | |
| templateName : "custom_layout.html", | |
| schedule : {} | |
| }; | |
| if (c) { | |
| data.groupIds = c; | |
| } | |
| fs.writeFile(filePath, JSON.stringify(data, null, 4), function(fallbackReleases) { | |
| cb(fallbackReleases, data); | |
| }); | |
| }; | |
| /** | |
| * @param {string} filePath | |
| * @param {boolean} req | |
| * @param {string} res | |
| * @param {!Function} callback | |
| * @return {undefined} | |
| */ | |
| self.getPlaylists = function(filePath, req, res, callback) { | |
| var realPath = path.join(stex.mediaDir, filePath); | |
| /** @type {boolean} */ | |
| var request = false; | |
| /** @type {boolean} */ | |
| var n = false; | |
| req = req || false; | |
| res = res || null; | |
| callback = callback || function() { | |
| }; | |
| fs.readdir(realPath, function(value, o) { | |
| var p; | |
| var c; | |
| var readFile; | |
| return value ? callback("directory read error: " + value) : (p = o.filter(k), c = [], readFile = function(file, cb) { | |
| var obj = { | |
| settings : {}, | |
| assets : [], | |
| name : path.basename(file, ".json").slice(2) | |
| }; | |
| if ("__TV_OFF.json" == file) { | |
| /** @type {boolean} */ | |
| n = true; | |
| } | |
| fs.readFile(path.join(realPath, file), "utf8", function(warn, externalOptions) { | |
| var options; | |
| var i; | |
| if (warn || !externalOptions) { | |
| c.push(obj); | |
| utils.log("error", "playlist file reading error for " + filePath + ";" + warn); | |
| } else { | |
| options = {}; | |
| try { | |
| /** @type {*} */ | |
| options = JSON.parse(externalOptions); | |
| } catch (j) { | |
| utils.log("error", "playlist index parsing error for " + filePath); | |
| } | |
| if (obj.settings = options.settings || {}, obj.assets = options.assets || [], obj.layout = options.layout || "1", obj.templateName = options.templateName || "custom_layout.html", obj.videoWindow = options.videoWindow || null, obj.zoneVideoWindow = options.zoneVideoWindow || {}, obj.schedule = options.schedule || {}, obj.labels = options.labels || [], obj.groupIds = options.groupIds, res) { | |
| if (options.groupIds && options.groupIds.length) { | |
| /** @type {boolean} */ | |
| request = false; | |
| /** @type {number} */ | |
| i = 0; | |
| for (; i < res.length; i++) { | |
| if (options.groupIds.indexOf(res[i]) >= 0) { | |
| /** @type {boolean} */ | |
| request = true; | |
| break; | |
| } | |
| } | |
| } else { | |
| request = req; | |
| } | |
| } else { | |
| /** @type {boolean} */ | |
| request = true; | |
| } | |
| if (request) { | |
| c.push(obj); | |
| } | |
| } | |
| cb(); | |
| }); | |
| }, async.each(p, readFile, function(value) { | |
| return value ? callback("playlist read error: " + value) : (n || (c = c.concat(hours)), callback(null, c)); | |
| }), void 0); | |
| }); | |
| }; | |
| /** | |
| * @param {!Object} req | |
| * @param {!Object} res | |
| * @return {undefined} | |
| */ | |
| self.index = function(req, res) { | |
| /** @type {boolean} */ | |
| var d = false; | |
| /** @type {null} */ | |
| var Hook$consumptionResolved = null; | |
| if (req.collaboratorRights && req.collaboratorRights.groupIds && req.collaboratorRights.groupIds.length) { | |
| if (req.collaboratorRights.asset.restrictAdmin) { | |
| /** @type {boolean} */ | |
| d = true; | |
| Hook$consumptionResolved = req.collaboratorRights.groupIds; | |
| } else { | |
| if (req.collaboratorRights.asset.restrict) { | |
| /** @type {boolean} */ | |
| d = false; | |
| Hook$consumptionResolved = req.collaboratorRights.groupIds; | |
| } | |
| } | |
| } | |
| self.getPlaylists(req.installation, d, Hook$consumptionResolved, function(err, response) { | |
| return err ? server.sendError(res, err) : server.sendSuccess(res, " Sending playlist list", response); | |
| }); | |
| }; | |
| /** | |
| * @param {!Object} req | |
| * @param {!Object} res | |
| * @return {?} | |
| */ | |
| self.getPlaylist = function(req, res) { | |
| var reducerDefaults; | |
| /** @type {boolean} */ | |
| var c = false; | |
| /** @type {null} */ | |
| var s = null; | |
| /** @type {boolean} */ | |
| var optionUsed3 = false; | |
| return req.collaboratorRights && req.collaboratorRights.groupIds && req.collaboratorRights.groupIds.length && (req.collaboratorRights.asset.restrictAdmin ? (c = true, s = req.collaboratorRights.groupIds) : req.collaboratorRights.asset.restrict && (c = false, s = req.collaboratorRights.groupIds)), "TV_OFF" == req.params.file ? server.sendError(res, "System Playlist, can not be edited") : (reducerDefaults = path.join(stex.mediaDir, req.installation, "__" + req.params.file + ".json"), void fs.readFile(reducerDefaults, | |
| "utf8", function(err, sort) { | |
| var options; | |
| var obj; | |
| var i; | |
| if (err) { | |
| return server.sendError(res, "playlist file read error", err); | |
| } | |
| if (options = { | |
| settings : {}, | |
| layout : "1", | |
| assets : [], | |
| videoWindow : null, | |
| zoneVideoWindow : {}, | |
| templateName : "custom_layout.html" | |
| }, sort) { | |
| obj = {}; | |
| try { | |
| /** @type {*} */ | |
| obj = JSON.parse(sort); | |
| } catch (l) { | |
| utils.log("error", "getPlaylist parsing error for " + req.installation); | |
| } | |
| if (options.settings = obj.settings || {}, options.assets = obj.assets || [], options.layout = obj.layout || "1", options.templateName = obj.templateName || "custom_layout.html", options.videoWindow = obj.videoWindow ? obj.videoWindow : null, options.zoneVideoWindow = obj.zoneVideoWindow ? obj.zoneVideoWindow : {}, options.schedule = obj.schedule || {}, options.groupIds = obj.groupIds, options.labels = obj.labels || [], s) { | |
| if (obj.groupIds && obj.groupIds.length) { | |
| /** @type {boolean} */ | |
| optionUsed3 = false; | |
| /** @type {number} */ | |
| i = 0; | |
| for (; i < s.length; i++) { | |
| if (obj.groupIds.indexOf(s[i]) >= 0) { | |
| /** @type {boolean} */ | |
| optionUsed3 = true; | |
| break; | |
| } | |
| } | |
| } else { | |
| optionUsed3 = c; | |
| } | |
| } else { | |
| /** @type {boolean} */ | |
| optionUsed3 = true; | |
| } | |
| if (!optionUsed3) { | |
| return server.sendError(res, "playlist file access denied"); | |
| } | |
| } | |
| return server.sendSuccess(res, " Sending playlist content", options); | |
| })); | |
| }; | |
| /** | |
| * @param {!Object} req | |
| * @param {!Object} res | |
| * @return {undefined} | |
| */ | |
| self.createPlaylist = function(req, res) { | |
| self.newPlaylist(req.installation, req.body.file, function(err) { | |
| if (err) { | |
| server.sendError(res, "Playlist write error", err); | |
| } else { | |
| server.sendSuccess(res, "Playlist Created: ", req.body.file); | |
| } | |
| }, req.collaboratorRights && req.collaboratorRights.groupIds && req.collaboratorRights.groupIds.length ? req.collaboratorRights.groupIds : null); | |
| }; | |
| /** | |
| * @param {!Object} req | |
| * @param {!Object} res | |
| * @return {undefined} | |
| */ | |
| self.savePlaylist = function(req, res) { | |
| var reducerDefaults = path.join(stex.mediaDir, req.installation, "__" + req.params.file + ".json"); | |
| fs.readFile(reducerDefaults, "utf8", function(err, data) { | |
| if (err && "ENOENT" == err.code && "TV_OFF" == req.params.file && (data = JSON.stringify(hours[0]), err = null), err) { | |
| server.sendError(res, "Playlist file read error", err); | |
| } else { | |
| var fileData = {}; | |
| /** @type {boolean} */ | |
| var k = false; | |
| if (fileData.version = 0, fileData.layout = "1", data) { | |
| try { | |
| /** @type {*} */ | |
| fileData = JSON.parse(data); | |
| } catch (l) { | |
| utils.log("error", "savePlaylist parsing error for " + req.installation); | |
| } | |
| /** @type {number} */ | |
| fileData.version = fileData.version || 0; | |
| } | |
| if (req.body.settings) { | |
| fileData.settings = req.body.settings; | |
| /** @type {boolean} */ | |
| k = true; | |
| } | |
| if (req.body.assets) { | |
| fileData.assets = req.body.assets; | |
| /** @type {boolean} */ | |
| k = true; | |
| } | |
| if (req.body.schedule) { | |
| fileData.schedule = req.body.schedule; | |
| /** @type {boolean} */ | |
| k = true; | |
| } | |
| if (req.body.layout) { | |
| fileData.layout = req.body.layout; | |
| fileData.templateName = req.body.templateName; | |
| fileData.videoWindow = req.body.videoWindow; | |
| fileData.zoneVideoWindow = req.body.zoneVideoWindow; | |
| /** @type {boolean} */ | |
| k = true; | |
| } | |
| if (req.body.labels) { | |
| fileData.labels = req.body.labels; | |
| /** @type {boolean} */ | |
| k = true; | |
| } | |
| fileData.groupIds = req.collaboratorRights && req.collaboratorRights.groupIds && req.collaboratorRights.groupIds.length ? req.collaboratorRights.groupIds : null; | |
| if (req.body.groupIds) { | |
| fileData.groupIds = (fileData.groupIds || []).concat(req.body.groupIds); | |
| /** @type {boolean} */ | |
| k = true; | |
| } | |
| if (k) { | |
| fileData.version += 1; | |
| fs.writeFile(reducerDefaults, JSON.stringify(fileData, null, 4), function(err) { | |
| if (err) { | |
| server.sendError(res, "Playlist save error", err); | |
| } else { | |
| server.sendSuccess(res, "Playlist Saved: ", fileData); | |
| } | |
| }); | |
| } else { | |
| server.sendSuccess(res, "Nothing to Update: ", fileData); | |
| } | |
| } | |
| }); | |
| }; | |
| }); | |
| require.register("./app/controllers/token.js", function(a, context, $) { | |
| /** | |
| * @return {undefined} | |
| */ | |
| function success() { | |
| /** @type {!Array} */ | |
| data.tokens = []; | |
| /** @type {number} */ | |
| data.currentTokenIndex = 0; | |
| /** @type {null} */ | |
| data.rollOverTime = null; | |
| /** @type {null} */ | |
| data.lifeTime = null; | |
| clearTimeout(_takingTooLongTimeout); | |
| clearTimeout(paintNodesTimeout); | |
| } | |
| /** | |
| * @return {undefined} | |
| */ | |
| function add() { | |
| setTimeout(function() { | |
| /** @type {number} */ | |
| data.currentTokenIndex = (data.currentTokenIndex + 1) % data.tokens.length; | |
| add(); | |
| }, 1e3 * data.rollOverTime); | |
| } | |
| /** | |
| * @return {undefined} | |
| */ | |
| function hidePlaceholder() { | |
| if (data.lifeTime) { | |
| setTimeout(success, 1e3 * data.lifeTime); | |
| } | |
| if (data.rollOverTime) { | |
| add(); | |
| } | |
| } | |
| var paintNodesTimeout; | |
| var _takingTooLongTimeout; | |
| var self = $("../others/restware"); | |
| var data = { | |
| tokens : [], | |
| currentTokenIndex : 0, | |
| rollOverTime : null, | |
| lifeTime : null, | |
| deleteOnShow : false | |
| }; | |
| /** | |
| * @param {!Object} that | |
| * @param {!Object} message | |
| * @return {?} | |
| */ | |
| context.updateTokens = function(that, message) { | |
| return success(), data.tokens = that.body.tokens, data.rollOverTime = that.body.rollOverTime, data.lifeTime = that.body.lifeTime, hidePlaceholder(), self.sendSuccess(message, "Tokens Saved", data); | |
| }; | |
| /** | |
| * @param {?} name | |
| * @param {!Object} res | |
| * @return {?} | |
| */ | |
| context.getTokens = function(name, res) { | |
| return self.sendSuccess(res, "Tokens", data); | |
| }; | |
| /** | |
| * @param {?} replyToken | |
| * @param {!Object} message | |
| * @return {?} | |
| */ | |
| context.currentToken = function(replyToken, message) { | |
| return self.sendSuccess(message, "Current Token", data.tokens[data.currentTokenIndex]); | |
| }; | |
| }); | |
| require.register("./app/controllers/kiosk-ui.js", function(a, testResults, require) { | |
| /** | |
| * @return {undefined} | |
| */ | |
| function getJSON() { | |
| clearTimeout(_takingTooLongTimeout); | |
| /** @type {number} */ | |
| _takingTooLongTimeout = setTimeout(function() { | |
| if (refresh) { | |
| DocumentManager.stopKioskUi(); | |
| } | |
| log(); | |
| }, _SERVICE_TAKING_TOO_LONG); | |
| } | |
| /** | |
| * @param {string} type | |
| * @param {number} maybeValue | |
| * @return {undefined} | |
| */ | |
| function config(type, maybeValue) { | |
| var BigNumber; | |
| /** @type {!Array} */ | |
| var cmd = ["--allow-file-access-from-files", "--disable-session-crashed-bubble", "--disable-infobars", "--disable-notifications", "--disable-device-discovery-notifications", "--disable-quic", "--disable-features=TranslateUI", "--disable-popup-blocking", "--noerrdialogs", "--no-first-run", "--start-fullscreen", "--start-maximized ", "--disable-pinch", "--overscroll-history-navigation=0", "--kiosk-printing", "--user-data-dir=/home/pi/.config/chromium/kiosk"]; | |
| cb(); | |
| cmd.push("--kiosk"); | |
| if (maybeValue) { | |
| /** @type {number} */ | |
| _SERVICE_TAKING_TOO_LONG = 1E3 * maybeValue; | |
| } | |
| if (type) { | |
| cmd.push("--app=" + type); | |
| } else { | |
| cmd.push("--app=http://localhost:8000/kiosk-ui/build/index.html"); | |
| } | |
| $.log("info", "Starting kiosk UI"); | |
| child = exec("chromium-browser", cmd); | |
| child.on("error", function(index) { | |
| $.log("error", "kiosk ui error: " + index); | |
| }); | |
| child.on("exit", function(a, index) { | |
| $.log("info", "kiosk ui exited with " + a + ";" + index); | |
| }); | |
| BigNumber = require("node-mouse"); | |
| n = new BigNumber; | |
| n.on("click", function() { | |
| testResults.showUi(); | |
| }); | |
| /** @type {boolean} */ | |
| refresh = true; | |
| setImmediate(done); | |
| } | |
| /** | |
| * @return {undefined} | |
| */ | |
| function done() { | |
| if (child && child.pid) { | |
| val("xdotool search --onlyvisible --pid " + child.pid, function(a, data) { | |
| if (data) { | |
| $.log("info", "kiosk UI id, " + data); | |
| /** @type {string} */ | |
| collection = data; | |
| log(); | |
| } else { | |
| setTimeout(done, 500); | |
| } | |
| }); | |
| } else { | |
| $.log("error", "kioskChrome pid is not present, fatal error"); | |
| } | |
| } | |
| /** | |
| * @param {!Function} logNode | |
| * @return {?} | |
| */ | |
| function log(logNode) { | |
| return logNode = logNode || function() { | |
| }, child ? void(collection ? val("xdotool windowminimize " + collection, function() { | |
| /** @type {boolean} */ | |
| refresh = false; | |
| logNode(); | |
| }) : logNode(true)) : logNode(true); | |
| } | |
| /** | |
| * @return {undefined} | |
| */ | |
| function cb() { | |
| if (child) { | |
| child.kill(); | |
| /** @type {null} */ | |
| child = null; | |
| } | |
| if (n) { | |
| /** @type {null} */ | |
| n = null; | |
| } | |
| } | |
| var _takingTooLongTimeout; | |
| var collection; | |
| var refresh; | |
| var n; | |
| var status; | |
| var exec = require("child_process").spawn; | |
| var val = require("child_process").exec; | |
| var DocumentManager = require("./pi-viewer"); | |
| var self = require("../others/restware"); | |
| var $ = require("../others/logger"); | |
| /** @type {null} */ | |
| var child = null; | |
| /** @type {number} */ | |
| var _SERVICE_TAKING_TOO_LONG = 3E4; | |
| /** | |
| * @param {!Function} $ | |
| * @return {?} | |
| */ | |
| testResults.showUi = function($) { | |
| return $ = $ || function() { | |
| }, child ? (getJSON(), void(collection && !refresh ? (refresh = true, DocumentManager.showKioskUi(function() { | |
| val("xdotool windowactivate " + collection, function() { | |
| $(); | |
| }); | |
| })) : $(true))) : $(true); | |
| }; | |
| /** @type {function(!Function): ?} */ | |
| testResults.hideUi = log; | |
| /** | |
| * @param {!Object} options | |
| * @return {?} | |
| */ | |
| testResults.setupUi = function(options) { | |
| var b = process.version.slice(1, process.version.indexOf(".")); | |
| return 0 == b ? void $.log("error", "Kiosk UI can not be supported in older images") : void(options.enable ? val("which xdotool", function(error, stdout, stderror) { | |
| if (error || stderror || !stdout || stdout.length <= 3) { | |
| $.log("warn", "xdotool is *not* available, kiosk ui is not started"); | |
| } else { | |
| config(options.url, options.timeout); | |
| } | |
| }) : cb()); | |
| }; | |
| /** @type {string} */ | |
| status = "stopped"; | |
| /** | |
| * @param {!Request} el | |
| * @param {!Object} res | |
| * @return {?} | |
| */ | |
| testResults.takeAction = function(el, res) { | |
| if (!child) { | |
| return self.sendError(res, "Kiosk ui not enabled"); | |
| } | |
| switch(el.params.action) { | |
| case "play": | |
| if (el.query.file) { | |
| /** @type {string} */ | |
| status = "playing"; | |
| log(function() { | |
| DocumentManager.playFile(el.query.file, function() { | |
| /** @type {string} */ | |
| status = "stopped"; | |
| testResults.showUi(); | |
| }, 300, true); | |
| }); | |
| self.sendSuccess(res, "Started playing file", { | |
| status : status | |
| }); | |
| } else { | |
| self.sendSuccess(res, "Nothing to play", { | |
| status : status | |
| }); | |
| } | |
| break; | |
| case "show": | |
| testResults.showUi(function() { | |
| self.sendSuccess(res, "Kiosk ui shown", {}); | |
| }); | |
| break; | |
| case "hide": | |
| if (refresh) { | |
| DocumentManager.stopKioskUi(); | |
| } | |
| log(function() { | |
| self.sendSuccess(res, "Kiosk ui hidden", {}); | |
| }); | |
| break; | |
| default: | |
| self.sendSuccess(res, "No action specified for kiosk ui", { | |
| status : status | |
| }); | |
| } | |
| }; | |
| }); | |
| require.register("./config/env/all.js", function(module, b, getBaseUri) { | |
| var path = getBaseUri("path"); | |
| var baseDir = process.cwd(); | |
| var dataDir = path.join(baseDir, "/data"); | |
| var dir = path.join(baseDir, "/../media"); | |
| var file = path.join(baseDir, "/misc"); | |
| module.exports = { | |
| root : baseDir, | |
| dataDir : dataDir, | |
| uploadDir : dir, | |
| licensesDirPath : path.join(dataDir, "/licenses/"), | |
| scriptDir : file, | |
| scriptDirPath : file + "/", | |
| systemScript : "/bin/bash " + file + "/system.sh ", | |
| syncDir : path.join(dataDir, "/sync_folders"), | |
| syncDirPath : path.join(dataDir, "/sync_folders/"), | |
| viewDir : path.join(baseDir, "/app/views"), | |
| mediaDir : dir, | |
| mediaPath : dir + "/", | |
| thumbnailDir : dir + "/_thumbnails", | |
| defaultPlaylist : "default", | |
| defaultTemplateDir : baseDir + "/templates/", | |
| defaultTemplate : baseDir + "/templates/t1_template.ejs", | |
| logFile : baseDir + "/../forever_out.log", | |
| logStoreDir : dir + "/_logs", | |
| mongo_options : { | |
| useMongoClient : true, | |
| keepAlive : true, | |
| reconnectTries : 30 | |
| }, | |
| session : { | |
| secret : "piSignage" | |
| }, | |
| pisignageDomain : "pisignage.com", | |
| filenameRegex : /[&\/\\#,+()$~%'":*?<>{}]/g, | |
| groupNameRegEx : /[&\/\\#,+()$~%'":*?<>{}\^]/g, | |
| videoRegex : /(mp4|mov|m4v|avi|webm|wmv|flv|mkv|mpg|mpeg|3gp)$/i, | |
| audioRegex : /(mp3|m4a|mp4a|aac)$/i, | |
| imageRegex : /(jpg|jpeg|png|gif|bmp)$/i, | |
| noticeRegex : /\.html$/, | |
| zipfileRegex : /(.zip|.gz|.bz2)$/i, | |
| repofileRegex : /\.repo$/i, | |
| liveStreamRegex : /\.tv$/i, | |
| omxStreamRegex : /\.stream$/i, | |
| pdffileRegex : /\.pdf$/i, | |
| txtFileRegex : /\.txt$/i, | |
| linkURL : /\.link$/i, | |
| CORSLink : /\.weblink$/i, | |
| localFolderRegex : /\.local$/i, | |
| mediaRss : /\.mrss$/i, | |
| radioFileRegex : /\.radio$/i, | |
| brandRegex : /^(brand_intro|brand_intro_portrait)\./i, | |
| nestedPlaylist : /^__/i, | |
| systemAssets : ["_system_notice.html"], | |
| spacePerLicense : 1024 | |
| }; | |
| }); | |
| require.register("./config/env/pi.js", function(config, b, weightFunc) { | |
| var d = weightFunc("path"); | |
| var i = process.cwd(); | |
| var g = (d.join(i, "/../media"), d.join(i, "/../logs")); | |
| config.exports = { | |
| env : "pi", | |
| https : false, | |
| port : process.env.PORT || 8E3, | |
| poweronConfig : i + "/config/_config.json", | |
| settingsFile : i + "/config/_settings.json", | |
| logsDir : g, | |
| scriptDir : i + "/misc", | |
| ifacePath : "/etc/network/interfaces", | |
| dhcpcdFile : "/etc/dhcpcd.conf", | |
| wifiPath : "/etc/wpa_supplicant/wpa_supplicant.conf", | |
| bootConfigPath : "/boot/config.txt", | |
| pkgJson : i + "/package.json" | |
| }; | |
| }); | |
| require.register("./config/config.js", function(mixin, b, require) { | |
| var _ = require("lodash"); | |
| mixin.exports = _.extend(require("./env/all.js"), require("./env/" + process.env.NODE_ENV + ".js") || {}); | |
| }); | |
| require.register("./app/others/restware.js", function(mixin) { | |
| /** | |
| * @param {!Object} obj | |
| * @param {string} name | |
| * @param {!Object} data | |
| * @return {?} | |
| */ | |
| var send = function(obj, name, data) { | |
| if (obj) { | |
| var out = {}; | |
| return out.stat_message = name, out.data = data, out.success = true, obj.contentType("json"), obj.json(out); | |
| } | |
| }; | |
| /** | |
| * @param {!Object} result | |
| * @param {string} msg | |
| * @param {string} err | |
| * @return {?} | |
| */ | |
| var callback = function(result, msg, err) { | |
| if (result) { | |
| var out = {}; | |
| /** @type {string} */ | |
| var errmsg = err ? "" + err : ""; | |
| return out.stat_message = msg + errmsg, out.success = false, result.contentType("json"), result.json(out); | |
| } | |
| }; | |
| mixin.exports = { | |
| sendSuccess : send, | |
| sendError : callback | |
| }; | |
| }); | |
| require.register("./app/others/extract-zip.js", function(a, b, require) { | |
| /** | |
| * @param {string} eventType | |
| * @param {string} path | |
| * @param {?} fallback | |
| * @return {undefined} | |
| */ | |
| function init(eventType, path, fallback) { | |
| /** | |
| * @param {!Object} result | |
| * @return {undefined} | |
| */ | |
| var link = function(result) { | |
| var c; | |
| var i; | |
| var length; | |
| if (result && -1 == result.indexOf("index.html")) { | |
| /** @type {boolean} */ | |
| c = false; | |
| /** @type {number} */ | |
| i = 0; | |
| length = result.length; | |
| for (; length > i; i++) { | |
| if (result[i].match(/\.html$/i)) { | |
| /** @type {boolean} */ | |
| c = true; | |
| break; | |
| } | |
| } | |
| if (c) { | |
| fs.symlink(path + "/" + result[i], path + "/index.html", function() { | |
| }); | |
| } | |
| } | |
| }; | |
| exec("unzip " + eventType + " -d " + path).on("exit", function() { | |
| fs.readdir(path, function(index, params) { | |
| if (index) { | |
| client.log("error", "extract File read dir error, " + index); | |
| fallback(); | |
| } else { | |
| params = params.filter(function(appletName) { | |
| return 0 != appletName.indexOf("__"); | |
| }); | |
| if (1 == params.length) { | |
| exec("mv " + path + "/" + params[0] + "/* " + path + "/").on("exit", function() { | |
| fallback(); | |
| fs.readdir(path, function(a, i) { | |
| if (!a) { | |
| link(i); | |
| } | |
| }); | |
| }); | |
| } else { | |
| link(params); | |
| fallback(); | |
| } | |
| } | |
| }); | |
| }); | |
| } | |
| var async = require("async"); | |
| var path = require("path"); | |
| var fs = require("fs"); | |
| var exec = require("child_process").exec; | |
| var settings = require("../../config/config"); | |
| var client = require("./logger"); | |
| /** | |
| * @param {!Array} _ | |
| * @param {string} value | |
| * @param {?} objCallback | |
| * @return {undefined} | |
| */ | |
| b.extractStart = function(_, value, objCallback) { | |
| /** | |
| * @param {!Array} obj | |
| * @return {undefined} | |
| */ | |
| var next = function(obj) { | |
| var data; | |
| var appName; | |
| var state; | |
| var val = settings.mediaPath; | |
| if (value) { | |
| /** @type {string} */ | |
| val = value + "/"; | |
| } | |
| async.eachSeries(obj, function(f, progress) { | |
| if (f.match(settings.zipfileRegex)) { | |
| state = path.basename(f, path.extname(f)); | |
| data = val + f; | |
| /** @type {string} */ | |
| appName = val + "_" + state + ".repo"; | |
| fs.exists(appName, function(a) { | |
| if (a) { | |
| exec("sudo rm -rf " + appName).on("exit", function() { | |
| init(data, appName, progress); | |
| }); | |
| } else { | |
| init(data, appName, progress); | |
| } | |
| }); | |
| } else { | |
| progress(); | |
| } | |
| }, function(index) { | |
| if (index) { | |
| client.log("error", "Error in extracting files : " + index); | |
| } | |
| if (objCallback) { | |
| objCallback(); | |
| } | |
| }); | |
| }; | |
| if (_) { | |
| next(_); | |
| } else { | |
| fs.readdir(settings.mediaDir, function(a, instrumented) { | |
| next(instrumented); | |
| }); | |
| } | |
| }; | |
| }); | |
| require.register("./app/others/license-utils.js", function(a, b, require) { | |
| var key; | |
| var c; | |
| var data; | |
| var exec = require("child_process").exec; | |
| var crypto = require("crypto"); | |
| /** @type {string} */ | |
| var name = "aes-192-cbc"; | |
| var fs = require("fs"); | |
| var check1 = require("./package.json"); | |
| /** @type {string} */ | |
| var SigningKey = "pisignageLangford"; | |
| var console = require("./logger"); | |
| var options = {}; | |
| /** @type {boolean} */ | |
| var error_files = false; | |
| /** @type {number} */ | |
| var p = 1; | |
| /** @type {string} */ | |
| var apichecks = "wget -T 120 -t 2 "; | |
| /** | |
| * @param {string} value | |
| * @param {string} name | |
| * @param {!Function} callback | |
| * @param {string} template | |
| * @return {?} | |
| */ | |
| b.checkForLicense = function(value, name, callback, template) { | |
| var cleanup; | |
| var run; | |
| return p = 1, value && name ? (key = crypto.createHmac("sha1", SigningKey).update(name).digest("hex"), cleanup = function(cleanupComplete) { | |
| exec(apichecks + check1.config_server + "/licenses/" + value + "/license_" + name + ".txt -O ../license_" + name + ".txt", function(a, canCreateDiscussions, step_name) { | |
| console.log("error", "license file wget result: " + step_name); | |
| if (a) { | |
| exec(apichecks + check1.config_server + "/licenses/" + template + "/license_" + name + ".txt -O ../license_" + name + ".txt", function(a, b, step_name) { | |
| console.log("warn", "license file wget result: " + step_name); | |
| cleanupComplete(); | |
| }); | |
| } else { | |
| cleanupComplete(); | |
| } | |
| }); | |
| }, run = function() { | |
| fs.readFile("/home/pi/license_" + name + ".txt", "utf8", function(step_name, val) { | |
| if (step_name) { | |
| console.log("warn", "license file not found: " + step_name); | |
| if (p) { | |
| cleanup(function() { | |
| p--; | |
| run(); | |
| }); | |
| } else { | |
| callback(false); | |
| } | |
| } else { | |
| try { | |
| c = crypto.createDecipher(name, key); | |
| data = c.update(val, "hex", "utf8"); | |
| data = data + c["final"]("utf8"); | |
| /** @type {*} */ | |
| options = JSON.parse(data); | |
| if (options.installation && value && value != options.installation) { | |
| /** @type {boolean} */ | |
| options.enabled = false; | |
| console.log("warn", "installation not matching, " + value + "&" + options.installation); | |
| } | |
| if (options.domain && template && template != options.domain) { | |
| /** @type {boolean} */ | |
| options.enabled = false; | |
| console.log("warn", "domain not matching, " + template); | |
| } | |
| if (options.validity && options.validity < Date.now()) { | |
| /** @type {boolean} */ | |
| options.enabled = false; | |
| console.log("warn", "license has expired " + (new Date(options.validity)).toDateString()); | |
| } | |
| if (options.enabled) { | |
| if (options.installation && options.domain) { | |
| /** @type {boolean} */ | |
| error_files = true; | |
| } | |
| callback(options.enabled, error_files); | |
| } else { | |
| if (p) { | |
| cleanup(function() { | |
| p--; | |
| run(); | |
| }); | |
| } else { | |
| callback(false); | |
| } | |
| } | |
| } catch (h) { | |
| console.log("error", "JSON Parse error license : " + name); | |
| if (p) { | |
| cleanup(function() { | |
| p--; | |
| run(); | |
| }); | |
| } else { | |
| callback(false); | |
| } | |
| } | |
| } | |
| }); | |
| }, void run()) : callback(false); | |
| }; | |
| }); | |
| require.register("./app/others/rss-service.js", function(a, appPostsFeed, require) { | |
| var FeedParser = require("feedparser"); | |
| var test = require("request"); | |
| var request = require("./logger"); | |
| /** | |
| * @param {string} url | |
| * @param {string} binary | |
| * @param {!Function} cb | |
| * @param {number} req | |
| * @return {?} | |
| */ | |
| appPostsFeed.getFeeds = function(url, binary, cb, req) { | |
| if (req = req || 100, !url) { | |
| return cb("link is empty"); | |
| } | |
| if (-1 == url.indexOf("://")) { | |
| /** @type {string} */ | |
| url = "http://" + url; | |
| } | |
| binary = binary || false; | |
| var request = test(url); | |
| var feedparser = new FeedParser({ | |
| feedUrl : url | |
| }); | |
| /** @type {!Array} */ | |
| var args = []; | |
| request.on("error", function(fallbackReleases) { | |
| return request.log("error", "**** request error , please check RSS feed URL " + url), cb(fallbackReleases); | |
| }); | |
| request.on("response", function(buffer) { | |
| var res = this; | |
| return buffer.setEncoding(binary ? "binary" : "utf8"), 200 != buffer.statusCode ? this.emit("error", Error("Bad status code, can't fetch feeds from given URL")) : void res.pipe(feedparser); | |
| }); | |
| feedparser.on("error", function(element) { | |
| return element && 0 === Object.keys(element).length ? request.log("warn", "**** feedparser error, empty object, skipping") : (request.log("error", "**** feedparser error, please check RSS feed URL " + url), request.log("error", element), cb(element)); | |
| }); | |
| feedparser.on("readable", function() { | |
| var c; | |
| var CoreDriverHandler = this; | |
| this.meta; | |
| for (; (c = CoreDriverHandler.read()) && (c.title && (c.title = c.title.replace(/'/g, "`")), c.description && (c.description = c.description.replace(/'/g, "`")), args.length < req);) { | |
| args.push(c); | |
| } | |
| }); | |
| feedparser.on("end", function() { | |
| return cb(null, args); | |
| }); | |
| }; | |
| }); | |
| require.register("./app/others/logger.js", function(a, $ionicIconConfig, require) { | |
| /** @type {!Object} */ | |
| var options = $ionicIconConfig; | |
| var message = require("util"); | |
| /** @type {!Array} */ | |
| var messages = []; | |
| /** @type {number} */ | |
| var MAX_MESSAGES = 1E3; | |
| /** @type {boolean} */ | |
| var h = false; | |
| /** @type {boolean} */ | |
| var i = true; | |
| /** @type {string} */ | |
| options.debugLevel = "info"; | |
| /** | |
| * @param {!Object} type | |
| * @param {string} value | |
| * @return {undefined} | |
| */ | |
| options.log = function(type, value) { | |
| /** @type {!Array} */ | |
| var levels = ["error", "warn", "info", "debug"]; | |
| if (levels.indexOf(type) <= levels.indexOf(options.debugLevel)) { | |
| if ("string" != typeof value) { | |
| /** @type {string} */ | |
| value = JSON.stringify(value, null, 4); | |
| } | |
| message.log(type + ": " + value); | |
| } | |
| }; | |
| /** | |
| * @param {string} name | |
| * @param {string} message | |
| * @param {!Object} details | |
| * @param {string} callback | |
| * @return {undefined} | |
| */ | |
| options.testLog = function(name, message, details, callback) { | |
| if (i) { | |
| if (h) { | |
| /** @type {boolean} */ | |
| h = false; | |
| /** @type {!Array} */ | |
| messages = []; | |
| } | |
| messages.push([name, message, details, callback]); | |
| if (messages.length > MAX_MESSAGES) { | |
| messages.splice(0, 1); | |
| } | |
| } | |
| }; | |
| /** | |
| * @return {?} | |
| */ | |
| options.getTestLog = function() { | |
| return h = true, messages; | |
| }; | |
| }); | |
| require.register("./app/others/system-info.js", function(a, api, require) { | |
| /** | |
| * @param {string} _ | |
| * @return {?} | |
| */ | |
| function next(_) { | |
| if (!_) { | |
| return void connection.log("error", "Script file name missing"); | |
| } | |
| /** @type {string} */ | |
| var filename = "/home/pi/" + _; | |
| fs.stat(filename, function(a, b) { | |
| if (!a && b && (!b || b.isFile())) { | |
| exec("python " + filename, function(data, index, state) { | |
| if (data || state) { | |
| connection.log("error", "Script error: " + data + " stderr: " + state); | |
| } | |
| connection.log("info", "Script output: " + index); | |
| }); | |
| } | |
| }); | |
| } | |
| var dest; | |
| var os = require("os"); | |
| var exec = require("child_process").exec; | |
| var async = require("async"); | |
| var fs = require("fs"); | |
| var TagHourlyStat = require("../../config/config"); | |
| var connection = require("./logger"); | |
| /** @type {boolean} */ | |
| var o = false; | |
| /** @type {null} */ | |
| var pane = null; | |
| /** | |
| * @param {string} a | |
| * @return {undefined} | |
| */ | |
| var connect = function(a) { | |
| exec('echo "ver 0" | cec-client -s -d 1', { | |
| timeout : 2E4 | |
| }, function(limit, groupVars, useDistinct) { | |
| if (a) { | |
| connection.log("info", "ces support: " + groupVars + ";" + useDistinct + ";" + limit); | |
| } | |
| if (limit || useDistinct || groupVars && -1 != groupVars.indexOf("unknown")) { | |
| if (o || a) { | |
| connection.log("info", "cec is NOT supported"); | |
| } | |
| /** @type {boolean} */ | |
| o = false; | |
| } else { | |
| if (!o || a) { | |
| connection.log("info", "cec IS supported"); | |
| } | |
| /** @type {boolean} */ | |
| o = true; | |
| } | |
| if (!o) { | |
| setTimeout(function() { | |
| connect(); | |
| }, 36E5); | |
| } | |
| }); | |
| }; | |
| connect(true); | |
| /** | |
| * @param {?} callback | |
| * @return {undefined} | |
| */ | |
| api.reboot = function(callback) { | |
| exec("sync;sudo reboot -p", function(line, exisObj, gmInstance) { | |
| if (null !== line) { | |
| connection.log("error", "Reboot error: " + line); | |
| } | |
| if (callback) { | |
| callback(line, exisObj, gmInstance); | |
| } | |
| }); | |
| }; | |
| /** | |
| * @return {undefined} | |
| */ | |
| api.shutdown = function() { | |
| exec("sudo shutdown -h now"); | |
| }; | |
| /** | |
| * @param {boolean} data | |
| * @return {?} | |
| */ | |
| api.getIp = function(data) { | |
| var key; | |
| /** @type {!Array} */ | |
| var errors = []; | |
| var b = os.networkInterfaces(); | |
| if (!data) { | |
| console.log(b); | |
| } | |
| for (key in b) { | |
| b[key].forEach(function(address) { | |
| if (address && !address.internal && "IPv4" == address.family) { | |
| errors.push({ | |
| type : key, | |
| ip : address.address | |
| }); | |
| } | |
| }); | |
| } | |
| return errors; | |
| }; | |
| /** | |
| * @param {!Function} saveNotifs | |
| * @return {undefined} | |
| */ | |
| api.wlanReboot = function(saveNotifs) { | |
| /** @type {string} */ | |
| var wrongDefinition = "sudo ifup wlan0"; | |
| /** @type {string} */ | |
| var soxCommand = "sudo ifdown --force wlan0"; | |
| async.series([function(saveNotifs) { | |
| exec('grep -q "^iface eth0 inet" /etc/network/interfaces', function(canCreateDiscussions) { | |
| if (canCreateDiscussions) { | |
| /** @type {string} */ | |
| wrongDefinition = "sudo ifconfig wlan0 up"; | |
| /** @type {string} */ | |
| soxCommand = "sudo ifconfig wlan0 down"; | |
| } | |
| saveNotifs(); | |
| }); | |
| }, function(saveNotifs) { | |
| exec("ifconfig wlan0", function(helpflag, range) { | |
| if (helpflag || !range) { | |
| saveNotifs("no wlan"); | |
| } else { | |
| if (range.indexOf("inet addr:") >= 0) { | |
| saveNotifs("no need"); | |
| } else { | |
| saveNotifs(); | |
| } | |
| } | |
| }); | |
| }, function(saveNotifs) { | |
| exec(soxCommand, function() { | |
| saveNotifs(); | |
| }); | |
| }, function(saveNotifs) { | |
| setTimeout(function() { | |
| saveNotifs(); | |
| }, 15E3); | |
| }, function(saveNotifs) { | |
| exec(wrongDefinition, function() { | |
| connection.log("warn", "Restarting wlan interface"); | |
| saveNotifs(); | |
| }); | |
| }, function(saveNotifs) { | |
| setTimeout(function() { | |
| saveNotifs(); | |
| }, 3E4); | |
| }], function() { | |
| saveNotifs(); | |
| }); | |
| }; | |
| /** | |
| * @return {undefined} | |
| */ | |
| api.tvOff = function() { | |
| api.getDisplayProperties(function() { | |
| connection.log("info", " **** turning tv off *****"); | |
| exec('echo "standby 0" | cec-client -s -d 1', { | |
| timeout : 2E4 | |
| }, function(index) { | |
| if (index) { | |
| connection.log("error", "CEC TV off : " + index); | |
| } | |
| }); | |
| setTimeout(function() { | |
| connection.log("info", " **** tvservice off *****"); | |
| exec("tvservice --off", function(a) { | |
| if (a) { | |
| console.log(a); | |
| } | |
| }); | |
| }, 3E4); | |
| next("TVoff.py"); | |
| }); | |
| }; | |
| /** | |
| * @param {!Function} saveNotifs | |
| * @return {undefined} | |
| */ | |
| api.tvOn = function(saveNotifs) { | |
| api.getDisplayProperties(function() { | |
| connection.log("info", " **** turning tv on *****"); | |
| exec("tvservice --preferred; sudo chvt 6; sudo chvt 7", function(b) { | |
| if (b) { | |
| console.log(b); | |
| } | |
| setTimeout(function() { | |
| connection.log("info", " **** cec-client on *****"); | |
| exec('echo "on 0" | cec-client -s -d 1', { | |
| timeout : 2E4 | |
| }, function() { | |
| exec('echo "as" | cec-client -s -d 1', { | |
| timeout : 2E4 | |
| }); | |
| }); | |
| if (saveNotifs) { | |
| saveNotifs(); | |
| } | |
| next("TVon.py"); | |
| setTimeout(function() { | |
| if (!o) { | |
| connect(); | |
| } | |
| }, 1E4); | |
| }, 3E4); | |
| }); | |
| }); | |
| }; | |
| /** | |
| * @param {!Function} $ | |
| * @return {?} | |
| */ | |
| api.getDisplayProperties = function($) { | |
| if (pane) { | |
| return $(null, pane); | |
| } | |
| var child = exec("tvservice -s"); | |
| /** @type {boolean} */ | |
| var caretPos = false; | |
| child.stdout.on("data", function(parent) { | |
| return pane = parent, caretPos = true, $(null, parent); | |
| }); | |
| child.stderr.on("data", function(input) { | |
| return console.log(input), caretPos = true, $(input, null); | |
| }); | |
| child.on("close", function() { | |
| return caretPos ? void 0 : $("No stdout or stderr", pane); | |
| }); | |
| }; | |
| /** | |
| * @param {string} leave | |
| * @param {string} i | |
| * @param {!Function} k | |
| * @param {string} a | |
| * @return {?} | |
| */ | |
| api.getCecStatus = function(leave, i, k, a) { | |
| var child; | |
| var worker; | |
| var chunk; | |
| /** | |
| * @param {boolean} val | |
| * @return {undefined} | |
| */ | |
| var g = function(val) { | |
| exec("/opt/vc/bin/vcgencmd measure_temp", { | |
| timeout : 2E4 | |
| }, function(b, headerPlusSegments) { | |
| k(val, headerPlusSegments.slice(5)); | |
| }); | |
| }; | |
| return a = a || false, o ? (child = exec('echo "pow 0" | cec-client -s -d 1', { | |
| timeout : 2E4 | |
| }), child.stdout.on("data", function(options) { | |
| /** @type {string} */ | |
| worker = options; | |
| }), child.stderr.on("data", function(child) { | |
| /** @type {string} */ | |
| chunk = child; | |
| }), void child.on("close", function() { | |
| var wrongDefinition; | |
| var j = !chunk && worker && -1 == worker.indexOf("unknown") && -1 == worker.indexOf("standby"); | |
| if (i == j || a || !leave) { | |
| if (i !== j) { | |
| connection.log("warn", "CEC status different than desired state, " + i + ";" + j + ";" + worker + ";" + chunk); | |
| } | |
| g(j); | |
| } else { | |
| connection.log("warn", "Sending CEC command to TV for correcting the TV state, " + i + ";" + j + ";" + worker + ";" + chunk); | |
| if (i) { | |
| /** @type {string} */ | |
| wrongDefinition = 'echo "on 0" | cec-client -s -d 1'; | |
| next("TVon.py"); | |
| } else { | |
| /** @type {string} */ | |
| wrongDefinition = 'echo "standby 0" | cec-client -s -d 1'; | |
| next("TVoff.py"); | |
| } | |
| exec(wrongDefinition, { | |
| timeout : 2E4 | |
| }, function() { | |
| setTimeout(function() { | |
| api.getCecStatus(leave, i, k, true); | |
| }, 3E3); | |
| }); | |
| } | |
| })) : g(true); | |
| }; | |
| /** | |
| * @param {string} m | |
| * @param {string} b | |
| * @param {!Function} prune | |
| * @return {undefined} | |
| */ | |
| api.changeDisplaySetting = function(m, b, prune) { | |
| exec(TagHourlyStat.systemScript + "--resolution " + b + " " + m, function(commit, b, chunk) { | |
| if (commit || chunk) { | |
| connection.log("error", "Error in Orientation Change , " + commit + " " + chunk); | |
| } else { | |
| connection.log("info", b); | |
| } | |
| if (prune) { | |
| prune(); | |
| } | |
| }); | |
| }; | |
| /** @type {string} */ | |
| dest = "/home/pi/hostname.link"; | |
| /** | |
| * @param {!Function} getArgument | |
| * @return {undefined} | |
| */ | |
| api.changeHostname = function(getArgument) { | |
| getArgument = getArgument || function() { | |
| }; | |
| fs.readlink(dest, function(isErr, chunk) { | |
| return isErr || !chunk || os.hostname() == chunk ? getArgument() : (exec(TagHourlyStat.systemScript + '--change-hostname="' + chunk + '"', function(commit, canCreateDiscussions, chunk) { | |
| if (commit || chunk) { | |
| connection.log("error", "Error in changing hostname, " + commit + " " + chunk); | |
| } else { | |
| connection.log("info", "Changed hostname to " + chunk); | |
| } | |
| getArgument(); | |
| }), void fs.unlink(dest, function(index) { | |
| if (index) { | |
| connection.log("warn", "Error deleting sym link of hostname use, " + index); | |
| } | |
| })); | |
| }); | |
| }; | |
| /** | |
| * @param {!Function} name | |
| * @param {!Function} keys | |
| * @return {?} | |
| */ | |
| api.registerHostnameChange = function(name, keys) { | |
| return keys = keys || function() { | |
| }, name ? (name = name.replace(/\s+/g, "-"), name = name.replace(/[^-0-9A-Za-z]/g, ""), name = name.replace(/^-/, ""), void fs.unlink(dest, function() { | |
| fs.symlink(name, dest, function(index) { | |
| if (index) { | |
| connection.log("error", "Error creating sym link for hostname use, " + index); | |
| } | |
| keys(); | |
| }); | |
| })) : keys(); | |
| }; | |
| /** | |
| * @param {!Function} reason | |
| * @return {undefined} | |
| */ | |
| api.factoryReset = function(reason) { | |
| var cp = exec(TagHourlyStat.systemScript + "--factory-reset"); | |
| cp.stdout.on("data", function(a) { | |
| connection.log("info", a); | |
| }); | |
| cp.stderr.on("data", function(index) { | |
| connection.log("error", "Error in Factory Reset " + index); | |
| }); | |
| cp.stdout.on("data", function() { | |
| connection.log("info", "Rebooting the player after factory reset"); | |
| }); | |
| cp.on("exit", function(value) { | |
| if (reason) { | |
| reason(value); | |
| } | |
| if (!value) { | |
| setTimeout(systemjs.reboot, 1E3); | |
| } | |
| }); | |
| }; | |
| /** | |
| * @param {!Object} options | |
| * @param {?} contextBuilder | |
| * @return {undefined} | |
| */ | |
| api.updateDnsEntry = function(options, contextBuilder) { | |
| exec(TagHourlyStat.systemScript + "--change-dns " + options.primary + " " + options.secondary, function(commit, canCreateDiscussions, chunk) { | |
| if (commit || chunk) { | |
| connection.log("error", "Error in changing DNS entry : " + commit + " Stderr : " + chunk); | |
| } | |
| if (contextBuilder) { | |
| contextBuilder(); | |
| } | |
| }); | |
| }; | |
| /** | |
| * @param {string} a | |
| * @return {undefined} | |
| */ | |
| api.changeSshPassword = function(a) { | |
| exec(TagHourlyStat.systemScript + '--change-ssh-password "' + a + '"', function(commit, b, chunk) { | |
| if (commit || chunk) { | |
| connection.log("info", "Change SSH password - err: " + commit + ",stderr: " + chunk); | |
| } else { | |
| connection.log("info", "Ssh password is changed"); | |
| } | |
| }); | |
| }; | |
| }); | |
| require.register("./app/others/file-util.js", function(a, b, require) { | |
| var fs = require("fs"); | |
| var sanitizeHtml = require("sanitize-html"); | |
| var test = require("./logger"); | |
| var path = require("path"); | |
| /** @type {string} */ | |
| var replacement = '\n<script src="../piSignagePro/templates/screen.min.js">\x3c/script>\n'; | |
| /** | |
| * @param {?} assetsDir | |
| * @param {?} templateName | |
| * @return {undefined} | |
| */ | |
| b.modifyHTML = function(assetsDir, templateName) { | |
| var i; | |
| var originRuleContent; | |
| var text; | |
| var templatePath; | |
| if (templateName) { | |
| templatePath = path.join(assetsDir, templateName); | |
| fs.readFile(templatePath, "utf8", function(fn, html) { | |
| return fn ? test.log("error", "custom_layout File Read Error", fn) : (text = sanitizeHtml(html, { | |
| allowedTags : ["!DOCTYPE", "html", "head", "meta", "title", "body", "h1", "h2", "h3", "h4", "h5", "h6", "blockquote", "p", "a", "ul", "ol", "nl", "li", "b", "i", "strong", "em", "strike", "code", "hr", "br", "div", "table", "thead", "caption", "tbody", "tr", "th", "td", "pre", "marquee", "style", "iframe", "link", "script", "img"], | |
| allowedAttributes : false | |
| }), text = html, i = text.lastIndexOf("</body>"), originRuleContent = text.slice(0, i) + replacement + text.slice(i), void fs.writeFile(templatePath, originRuleContent, function() { | |
| })); | |
| }); | |
| } | |
| }; | |
| }); | |
| module.exports = require("./pi-server.js"); | |
| }(require, module); |
What is it even for, I cannot even remember? It looks like some sort of video player.
I have no clue even why I have it here :)
It's for a digital signage solution called PiSignage (made for raspberry pis obviously). It requires a paid license so this source code is obfuscated when you download the image from their Github. I have literally been spending the last 2 weeks working on de-obfuscating it/searching for the original source code so I can extend the functionality, then I accidentally stumbled upon this gist while researching a completely unrelated error!
I guess I can always work with this :) if you ever happen to remember how/where you got this code, let me know! I'm very curious
That rings bells from a long time ago.
The fact that I out it in a gist though is significant, I obviously didn't want to lose it :)
However you managed to get it, I'm glad you held on to it!
So out of pure curiosity, how did you get this file? I have been trying to work with this service but I could only find the obfuscated file, having the original available is such a lifesaver