From 6af5c5259e420707cb1e43d3a67c7e7cd8bd5163 Mon Sep 17 00:00:00 2001 From: 2deep4real <denis.peters@udo.edu> Date: Fri, 21 Jul 2017 00:09:56 +0200 Subject: [PATCH] departures und clock angepasst --- js/Clock.js | 418 +++++++++++++++++++++++++++ js/worker/AJAX.js | 138 +++++++++ js/worker/AbstractWorker.js | 75 +++++ js/worker/DepartureWorker.js | 164 +++++++++++ js/worker/Worker.js | 60 ++++ js/worker/WorkerDeparture.js | 138 +++++++++ js/worker/check.js | 64 ++++ panels/clock/script.js | 348 +--------------------- panels/clock/style.less | 11 +- panels/clock/template.html | 6 +- panels/departure/cache/.gitignore | 1 - panels/departure/config/default.json | 2 +- panels/departure/config/oh14.json | 10 +- panels/departure/departures.php | 204 ------------- panels/departure/script.js | 190 ++++++------ 15 files changed, 1184 insertions(+), 645 deletions(-) create mode 100644 js/Clock.js create mode 100644 js/worker/AJAX.js create mode 100644 js/worker/AbstractWorker.js create mode 100644 js/worker/DepartureWorker.js create mode 100644 js/worker/Worker.js create mode 100644 js/worker/WorkerDeparture.js create mode 100644 js/worker/check.js delete mode 100755 panels/departure/cache/.gitignore delete mode 100755 panels/departure/departures.php diff --git a/js/Clock.js b/js/Clock.js new file mode 100644 index 0000000..a0ad43c --- /dev/null +++ b/js/Clock.js @@ -0,0 +1,418 @@ +function Clock(panel, config) { + this.canvas = panel[0].querySelector("canvas"); + this.pane = this.canvas.getContext("2d"); + this.bgCanvas = document.createElement("canvas"); + this.bgPane = this.canvas.getContext("2d"); + + this.monthNames = ["jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"]; + this.dayNames = ["so","mo","di","mi","do","fr","sa"]; + + this.data = { + panel: { + widht: 0, + height: 0 + }, + bounds: { + outer: { + x: 0, + y: 0, + widht: 0, + height: 0 + }, + inner: { + x: 0, + y: 0, + widht: 0, + height: 0 + } + }, + colors: { + background: "#000", + foreground: "#fff", + shaddow: "#333" + }, + fonts: { + fat: "time-fat", + medium: "time-medium" + }, + aClock: { + bgImage: "background.svg", + radius: 0, + center: { + x: 0, + y: 0 + }, + bounds: { + outer: { + x: 0, + y: 0, + widht: 0, + height: 0 + }, + inner: { + x: 0, + y: 0, + widht: 0, + height: 0 + } + } + }, + dClock: { + fonts: { + fat: "", + big: "", + small: "" + }, + bounds: { + outer: { + x: 0, + y: 0, + widht: 0, + height: 0 + }, + inner: { + x: 0, + y: 0, + widht: 0, + height: 0 + } + }, + positions: { + hour : { + x: 0, + y: 0, + }, + pulse : { + x: 0, + y: 0, + }, + minute : { + x: 0, + y: 0, + }, + second : { + x: 0, + y: 0, + } + } + }, + dDate: { + font: "", + bounds: { + outer: { + x: 0, + y: 0, + widht: 0, + height: 0 + }, + inner: { + x: 0, + y: 0, + widht: 0, + height: 0 + } + }, + position: { + x: 0, + y: 0 + } + } + }; + + this.resize = function(width, height) { + this.data.panel.width = width; + this.data.panel.height = height; + // canvas + this.canvas.width = this.data.panel.width; + this.canvas.height = this.data.panel.height; + this.pane = this.canvas.getContext("2d"); + // bgCanvas + this.bgCanvas.width = this.data.panel.width; + this.bgCanvas.height = this.data.panel.height; + this.bgPane = this.bgCanvas.getContext("2d"); + + // outer bounds + this.data.bounds.outer.x = 10; + this.data.bounds.outer.y = 10; + this.data.bounds.outer.width = width - 20; + this.data.bounds.outer.height = height - 20; + var ratio = this.data.bounds.outer.width / this.data.bounds.outer.height; + + if (ratio > 1.5) { + // widget + if (this.data.bounds.outer.height * 3 < this.data.bounds.outer.width) { + this.data.bounds.inner.height = this.data.bounds.outer.height; + this.data.bounds.inner.width = this.data.bounds.outer.height * 3; + } else { + this.data.bounds.inner.height = this.data.bounds.outer.width / 3; + this.data.bounds.inner.width = this.data.bounds.outer.width; + } + this.data.bounds.inner.x = this.data.bounds.outer.x + (this.data.bounds.outer.width - this.data.bounds.inner.width) / 2; + this.data.bounds.inner.y = this.data.bounds.outer.y + (this.data.bounds.outer.height - this.data.bounds.inner.height) / 2; + // dClock + this.data.dClock.bounds.outer.x = this.data.bounds.inner.x + this.data.bounds.inner.width * 0.4; + this.data.dClock.bounds.outer.y = this.data.bounds.inner.y; + this.data.dClock.bounds.outer.width = this.data.bounds.inner.width * 0.6; + this.data.dClock.bounds.outer.height = this.data.bounds.inner.height * 0.6; + // dDate + this.data.dDate.bounds.outer.x = this.data.bounds.inner.x + this.data.bounds.inner.width * 0.4; + this.data.dDate.bounds.outer.y = this.data.bounds.inner.y + this.data.bounds.inner.height * 0.6; + this.data.dDate.bounds.outer.width = this.data.bounds.inner.width * 0.6; + this.data.dDate.bounds.outer.height = this.data.bounds.inner.height * 0.4; + // aClock + this.data.aClock.bounds.outer.x = this.data.bounds.inner.x; + this.data.aClock.bounds.outer.y = this.data.bounds.inner.y; + this.data.aClock.bounds.outer.width = this.data.bounds.inner.width * 0.4; + this.data.aClock.bounds.outer.height = this.data.bounds.inner.height; + } else if (ratio < 1) { + // widget + if (this.data.bounds.outer.height * 0.7 < this.data.bounds.outer.width) { + this.data.bounds.inner.height = this.data.bounds.outer.height; + this.data.bounds.inner.width = this.data.bounds.outer.height * 0.7; + } else { + this.data.bounds.inner.height = this.data.bounds.outer.width / 0.7; + this.data.bounds.inner.width = this.data.bounds.outer.width; + } + this.data.bounds.inner.x = this.data.bounds.outer.x + (this.data.bounds.outer.width - this.data.bounds.inner.width) / 2; + this.data.bounds.inner.y = this.data.bounds.outer.y + (this.data.bounds.outer.height - this.data.bounds.inner.height) / 2; + // dClock + this.data.dClock.bounds.outer.x = this.data.bounds.inner.x; + this.data.dClock.bounds.outer.y = this.data.bounds.inner.y + this.data.bounds.inner.height * 0.7; + this.data.dClock.bounds.outer.width = this.data.bounds.inner.width; + this.data.dClock.bounds.outer.height = this.data.bounds.inner.height * 0.2; + // dDate + this.data.dDate.bounds.outer.x = this.data.bounds.inner.x; + this.data.dDate.bounds.outer.y = this.data.bounds.inner.y + this.data.bounds.inner.height * 0.9; + this.data.dDate.bounds.outer.width = this.data.bounds.inner.width; + this.data.dDate.bounds.outer.height = this.data.bounds.inner.height * 0.1; + // aClock + this.data.aClock.bounds.outer.x = this.data.bounds.inner.x; + this.data.aClock.bounds.outer.y = this.data.bounds.inner.y; + this.data.aClock.bounds.outer.width = this.data.bounds.inner.width; + this.data.aClock.bounds.outer.height = this.data.bounds.inner.height * 0.7; + } else { + // widget + if (this.data.bounds.outer.height * 2 < this.data.bounds.outer.width) { + this.data.bounds.inner.height = this.data.bounds.outer.height; + this.data.bounds.inner.width = this.data.bounds.outer.height * 2; + } else { + this.data.bounds.inner.height = this.data.bounds.outer.width / 2; + this.data.bounds.inner.width = this.data.bounds.outer.width; + } + this.data.bounds.inner.x = this.data.bounds.outer.x + (this.data.bounds.outer.width - this.data.bounds.inner.width) / 2; + this.data.bounds.inner.y = this.data.bounds.outer.y + (this.data.bounds.outer.height - this.data.bounds.inner.height) / 2; + // dClock + this.data.dClock.bounds.outer.x = this.data.bounds.inner.x + this.data.bounds.inner.width / 3; + this.data.dClock.bounds.outer.y = this.data.bounds.inner.y; + this.data.dClock.bounds.outer.width = this.data.bounds.inner.width - this.data.bounds.inner.width / 3; + this.data.dClock.bounds.outer.height = this.data.bounds.inner.height - this.data.bounds.inner.height / 3; + // dDate + this.data.dDate.bounds.outer.x = this.data.bounds.inner.x; + this.data.dDate.bounds.outer.y = this.data.bounds.inner.y + this.data.bounds.inner.height / 3 * 2; + this.data.dDate.bounds.outer.width = this.data.bounds.inner.width; + this.data.dDate.bounds.outer.height = this.data.bounds.inner.height / 3; + // aClock + this.data.aClock.bounds.outer.x = this.data.bounds.inner.x; + this.data.aClock.bounds.outer.y = this.data.bounds.inner.y; + this.data.aClock.bounds.outer.width = this.data.bounds.inner.width / 3; + this.data.aClock.bounds.outer.height = this.data.bounds.inner.height - + this.data.bounds.inner.height / 3; + } + resizeDClock(); + resizeDDate(); + resizeAClock(); + renderBG(); + } + + this.render = function() { + var + date = new Date(), + n = date.getMilliseconds(), + h = date.getHours(), + i = date.getMinutes(), + s = date.getSeconds(), + t = date.getDay(), + d = date.getDate(), + m = date.getMonth(), + y = date.getFullYear(); + if (d.toString().length < 2) + d = "0" + d; + if (h.toString().length < 2) + h = "0" + h; + if (i.toString().length < 2) + i = "0" + i; + if (s.toString().length < 2) + s = "0" + s; + // background + this.pane.fillStyle = this.data.colors.background; + this.pane.fillRect(0, 0, this.data.panel.width, this.data.panel.height); + this.pane.drawImage(this.bgCanvas, 0, 0); + // foreground dClock + this.pane.fillStyle = this.data.colors.foreground; + this.pane.font = this.data.dClock.fonts.fat; + if (n < 500) this.pane.fillText(":", this.data.dClock.positions.pulse.x, this.data.dClock.positions.pulse.y); + this.pane.font = this.data.dClock.fonts.big; + this.pane.fillText(h, this.data.dClock.positions.hour.x, this.data.dClock.positions.hour.y); + this.pane.fillText(i, this.data.dClock.positions.minute.x, this.data.dClock.positions.minute.y); + this.pane.font = this.data.dClock.fonts.small; + this.pane.fillText(s, this.data.dClock.positions.second.x, this.data.dClock.positions.second.y); + // foreground dDate + this.pane.font = this.data.dDate.font; + this.pane.fillText(this.dayNames[t] + " " + d + " " + this.monthNames[m] + " " + y, this.data.dDate.position.x, this.data.dDate.position.y); + // foreground aClock + this.pane.strokeStyle = this.data.colors.foreground; + //hour + var hour = ((h % 12) * Math.PI / 6) + (i * Math.PI / (6 * 60)) + (s * Math.PI / (360 * 60)); + renderHand(hour, this.data.aClock.radius * 0.5, this.data.aClock.radius * 0.07); + //minute + var minute = (i * Math.PI / 30) + (s * Math.PI / (30 * 60)); + renderHand(minute, this.data.aClock.radius * 0.8, this.data.aClock.radius * 0.07); + // second + var second = (s * Math.PI / 30); + renderHand(second, this.data.aClock.radius * 0.9, this.data.aClock.radius * 0.02); + // debug + //renderDebug(); + } + + var renderHand = function(pos, length, width) { + this.pane.beginPath(); + this.pane.lineWidth = width; + this.pane.lineCap = "round"; + this.pane.translate(this.data.aClock.center.x, this.data.aClock.center.y); + this.pane.moveTo(0, 0); + this.pane.rotate(pos); + this.pane.lineTo(0, -length); + this.pane.stroke(); + this.pane.rotate(-pos); + this.pane.translate(-this.data.aClock.center.x, -this.data.aClock.center.y); + this.pane.lineWidth = 1; + }.bind(this); + + var renderBG = function() { + // background dClock + this.bgPane.fillStyle = this.data.colors.shaddow; + this.bgPane.font = this.data.dClock.fonts.fat; + this.bgPane.fillText(":", this.data.dClock.positions.pulse.x, this.data.dClock.positions.pulse.y); + this.bgPane.font = this.data.dClock.fonts.big; + this.bgPane.fillText("88", this.data.dClock.positions.hour.x, this.data.dClock.positions.hour.y); + this.bgPane.fillText("88", this.data.dClock.positions.minute.x, this.data.dClock.positions.minute.y); + this.bgPane.font = this.data.dClock.fonts.small; + this.bgPane.fillText("88", this.data.dClock.positions.second.x, this.data.dClock.positions.second.y); + // background dDate + this.bgPane.font = this.data.dDate.font; + this.bgPane.fillText("00 00 000 0000", this.data.dDate.position.x, this.data.dDate.position.y); + this.bgPane.fillText("** ** *** ****", this.data.dDate.position.x, this.data.dDate.position.y); + + if (typeof this.data.aClock.bgImage == "string") { + var img = new Image(); + img.onload = function(e) { + this.data.aClock.bgImage = e.target; + this.bgPane.drawImage( + this.data.aClock.bgImage, + this.data.aClock.bounds.inner.x, + this.data.aClock.bounds.inner.y, + this.data.aClock.bounds.inner.width, + this.data.aClock.bounds.inner.height + ); + }.bind(this); + img.src = "panels/clock/"+this.data.aClock.bgImage; + } else { + this.bgPane.drawImage( + this.data.aClock.bgImage, + this.data.aClock.bounds.inner.x, + this.data.aClock.bounds.inner.y, + this.data.aClock.bounds.inner.width, + this.data.aClock.bounds.inner.height + ); + } + }.bind(this); + + var resizeDClock = function() { + var aspect = 6 / 16; + var ratio = this.data.dClock.bounds.outer.width * aspect; + if (ratio > this.data.dClock.bounds.outer.height) { + this.data.dClock.bounds.inner.width = this.data.dClock.bounds.outer.height / aspect; + this.data.dClock.bounds.inner.height = this.data.dClock.bounds.outer.height; + } else if (ratio < this.data.dClock.bounds.outer.height) { + this.data.dClock.bounds.inner.width = this.data.dClock.bounds.outer.width; + this.data.dClock.bounds.inner.height = this.data.dClock.bounds.outer.width * aspect; + } else { + this.data.dClock.bounds.inner.width = this.data.dClock.bounds.outer.width; + this.data.dClock.bounds.inner.height = this.data.dClock.bounds.outer.height; + } + this.data.dClock.bounds.inner.x = this.data.dClock.bounds.outer.x + (this.data.dClock.bounds.outer.width - this.data.dClock.bounds.inner.width) / 2; + this.data.dClock.bounds.inner.y = this.data.dClock.bounds.outer.y + (this.data.dClock.bounds.outer.height - this.data.dClock.bounds.inner.height) / 2; + this.data.dClock.positions.pulse.x = this.data.dClock.bounds.inner.x + this.data.dClock.bounds.inner.width * 0.315; + this.data.dClock.positions.pulse.y = this.data.dClock.bounds.inner.y + this.data.dClock.bounds.inner.height * 0.72; + this.data.dClock.positions.hour.x = this.data.dClock.bounds.inner.x + this.data.dClock.bounds.inner.width * 0.02; + this.data.dClock.positions.hour.y = this.data.dClock.bounds.inner.y + this.data.dClock.bounds.inner.height * 0.88; + this.data.dClock.positions.minute.x = this.data.dClock.bounds.inner.x + this.data.dClock.bounds.inner.width * 0.43; + this.data.dClock.positions.minute.y = this.data.dClock.bounds.inner.y + this.data.dClock.bounds.inner.height * 0.88; + this.data.dClock.positions.second.x = this.data.dClock.bounds.inner.x + this.data.dClock.bounds.inner.width * 0.79; + this.data.dClock.positions.second.y = this.data.dClock.bounds.inner.y + this.data.dClock.bounds.inner.height * 0.85; + var + bigFontSize = this.data.dClock.bounds.inner.height * 1.3, + smlFontSize = this.data.dClock.bounds.inner.height * 0.7; + this.data.dClock.fonts.fat = bigFontSize + "px " + this.data.fonts.fat; + this.data.dClock.fonts.big = bigFontSize + "px " + this.data.fonts.medium; + this.data.dClock.fonts.small = smlFontSize + "px " + this.data.fonts.medium; + }.bind(this); + + var resizeDDate = function() { + var aspect = 2.3 / 16; + var ratio = this.data.dDate.bounds.outer.width * aspect; + if (ratio > this.data.dDate.bounds.outer.height) { + this.data.dDate.bounds.inner.width = this.data.dDate.bounds.outer.height / aspect; + this.data.dDate.bounds.inner.height = this.data.dDate.bounds.outer.height; + } else if (ratio < this.data.dDate.bounds.outer.height) { + this.data.dDate.bounds.inner.width = this.data.dDate.bounds.outer.width; + this.data.dDate.bounds.inner.height = this.data.dDate.bounds.outer.width * aspect; + } else { + this.data.dDate.bounds.inner.width = this.data.dDate.bounds.outer.width; + this.data.dDate.bounds.inner.height = this.data.dDate.bounds.outer.height; + } + this.data.dDate.bounds.inner.x = this.data.dDate.bounds.outer.x + (this.data.dDate.bounds.outer.width - this.data.dDate.bounds.inner.width) / 2; + this.data.dDate.bounds.inner.y = this.data.dDate.bounds.outer.y + (this.data.dDate.bounds.outer.height - this.data.dDate.bounds.inner.height) / 2; + this.data.dDate.position.x = this.data.dDate.bounds.inner.x + this.data.dDate.bounds.inner.width * 0.02; + this.data.dDate.position.y = this.data.dDate.bounds.inner.y + this.data.dDate.bounds.inner.height * 0.88; + var fontSize = this.data.dDate.bounds.inner.height * 1.3; + this.data.dDate.font = fontSize + "px " + this.data.fonts.medium; + }.bind(this); + + var resizeAClock = function() { + if (this.data.aClock.bounds.outer.width > this.data.aClock.bounds.outer.height) { + this.data.aClock.bounds.inner.width = this.data.aClock.bounds.outer.height; + this.data.aClock.bounds.inner.height = this.data.aClock.bounds.outer.height; + } else if (this.data.aClock.bounds.outer.width < this.data.aClock.bounds.outer.height) { + this.data.aClock.bounds.inner.width = this.data.aClock.bounds.outer.width; + this.data.aClock.bounds.inner.height = this.data.aClock.bounds.outer.width; + } else { + this.data.aClock.bounds.inner.width = this.data.aClock.bounds.outer.width; + this.data.aClock.bounds.inner.height = this.data.aClock.bounds.outer.height; + } + this.data.aClock.bounds.inner.x = this.data.aClock.bounds.outer.x + (this.data.aClock.bounds.outer.width - this.data.aClock.bounds.inner.width) / 2; + this.data.aClock.bounds.inner.y = this.data.aClock.bounds.outer.y + (this.data.aClock.bounds.outer.height - this.data.aClock.bounds.inner.height) / 2; + this.data.aClock.center.x = this.data.aClock.bounds.inner.x + this.data.aClock.bounds.inner.width / 2; + this.data.aClock.center.y = this.data.aClock.bounds.inner.y + this.data.aClock.bounds.inner.height / 2; + this.data.aClock.radius = this.data.aClock.bounds.inner.height * 0.45; + }.bind(this); + + var renderDebug = function() { + // panel bounds + this.pane.strokeStyle = "#ff0"; + this.pane.strokeRect(this.data.bounds.inner.x, this.data.bounds.inner.y, this.data.bounds.inner.width, this.data.bounds.inner.height); + this.pane.strokeStyle = "#0ff"; + this.pane.strokeRect(this.data.bounds.outer.x, this.data.bounds.outer.y, this.data.bounds.outer.width, this.data.bounds.outer.height); + // inner bounds + this.pane.strokeStyle = "#0f0"; + this.pane.strokeRect(this.data.dClock.bounds.inner.x, this.data.dClock.bounds.inner.y, this.data.dClock.bounds.inner.width, this.data.dClock.bounds.inner.height); + this.pane.strokeRect(this.data.dDate.bounds.inner.x, this.data.dDate.bounds.inner.y, this.data.dDate.bounds.inner.width, this.data.dDate.bounds.inner.height); + this.pane.strokeRect(this.data.aClock.bounds.inner.x, this.data.aClock.bounds.inner.y, this.data.aClock.bounds.inner.width, this.data.aClock.bounds.inner.height); + // outer bounds + this.pane.strokeStyle = "#f0f"; + this.pane.strokeRect(this.data.dClock.bounds.outer.x, this.data.dClock.bounds.outer.y, this.data.dClock.bounds.outer.width, this.data.dClock.bounds.outer.height); + this.pane.strokeRect(this.data.dDate.bounds.outer.x, this.data.dDate.bounds.outer.y, this.data.dDate.bounds.outer.width, this.data.dDate.bounds.outer.height); + this.pane.strokeRect(this.data.aClock.bounds.outer.x, this.data.aClock.bounds.outer.y, this.data.aClock.bounds.outer.width, this.data.aClock.bounds.outer.height); + this.pane.strokeStyle = ""; + }.bind(this); + +} \ No newline at end of file diff --git a/js/worker/AJAX.js b/js/worker/AJAX.js new file mode 100644 index 0000000..80c62b4 --- /dev/null +++ b/js/worker/AJAX.js @@ -0,0 +1,138 @@ +AJAX = new (function AJAX() { + + function newXHR() { + return !!self.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"); + } + + function serialize(obj, prefix) { + var str = []; + for (var p in obj) { + if (obj.hasOwnProperty(p)) { + var k = prefix ? prefix + "[" + p + "]" : p, + v = obj[p]; + str.push(typeof v == "object" ? serialize(v, k) : encodeURIComponent(k) + "=" + encodeURIComponent(v)); + } + } + return str.join("&"); + } + + function decodeResponse(type, response) { + try { + switch (type) { + case "application/json": + return JSON.parse(response); + default: + return response; + } + } catch(e) { + + } + return response; + } + + function doReject(strict, result){ + return !!strict ? Promise.reject(result) : Promise.resolve(result); + } + + function doRequest(url, method, params, strict) { + return new Promise(function(resolve, reject) { + try { + if (typeof url != 'string') { + return doReject(strict, { + success: false, + response: 'url parameter must be string', + status: 0 + }).then(resolve, reject); + } + if (typeof method != 'string') { + return doReject(strict, { + success: false, + response: 'method parameter must be string', + status: 0 + }).then(resolve, reject); + } + method = method.toUpperCase(); + var xhr = newXHR(); + xhr.onload = function(e) { + if (e.target.status == 200) { + var response = decodeResponse(e.target.getResponseHeader("Content-Type"), e.target.response); + resolve({ + success: true, + response: response, + status: e.target.status + }); + } else { + var statusText = e.target.statusText; + if (!statusText.length) statusText = "unexpected error"; + doReject(strict, { + success: false, + response: statusText, + status: e.target.status + }).then(resolve, reject); + } + } + xhr.onerror = function(e) { + var statusText = e.target.statusText; + if (!statusText.length) statusText = "unexpected error"; + doReject(strict, { + success: false, + response: statusText, + status: e.target.status + }).then(resolve, reject); + } + xhr.onabort = function(e) { + doReject(strict, { + success: false, + response: 'download aborted', + status: 0 + }).then(resolve, reject); + } + params = typeof params == 'object' ? serialize(params) : ''; + if (method === 'GET') { + if (!!params.length) params = "?" + params; + xhr.open(method, url+params); + xhr.send(); + } else { + xhr.open(method, url); + xhr.send(!!params.length ? params : undefined); + } + } catch(e) { + doReject(strict, { + success: false, + response: e.message, + status: 0 + }).then(resolve, reject); + } + }); + } + + this.request = function(requests, strict) { + if (typeof strict != 'boolean') strict = true; + try { + if (typeof requests == 'string') { + return doRequest(requests, 'GET', [], strict); + } else { + if (typeof requests == 'object') { + if (Array.isArray(requests)) { + var proms = []; + for (var i = 0; i < requests.length; ++i) + proms.push(this.request(requests[i], strict)); + return Promise.all(proms); + } else { + return doRequest(requests.url, requests.method, requests.params, strict); + } + } + throw new Error('wrong type (string/array/dict expected, '+(typeof requests)+' detected)'); + } + } catch(e) { + return doReject(strict, { + success: false, + response: e.message, + status: 0 + }); + } + } + + return Object.freeze(this); + +}); \ No newline at end of file diff --git a/js/worker/AbstractWorker.js b/js/worker/AbstractWorker.js new file mode 100644 index 0000000..32db1f5 --- /dev/null +++ b/js/worker/AbstractWorker.js @@ -0,0 +1,75 @@ +class AbstractWorker { + + constructor() { + this.config = {}; + + var + ival = 1000, + timer, + cmds = [], + execRun = false; + + var update = function() { + if (!!timer) self.clearTimeout(timer); + this.tick(function(result) { + self.postMessage(result); + }); + if (ival > 0) timer = self.setTimeout(update, ival); + }.bind(this); + + var exec = function() { + if (!!cmds.length) { + execRun = true; + var cmd = cmds.shift(); + if (typeof this[cmd.cmd] == "function") { + this[cmd.cmd].apply(this,cmd.params); + } else { + exec(); + } + } else { + execRun = false; + } + }.bind(this); + + this.start = function() { + update(); + exec(); + } + + this.stop = function() { + if (!!timer) self.clearTimeout(timer); + exec(); + } + + this.loadConfig = function(name) { + AJAX.request("../../panels/departure/config/"+name+".json").then(function(data) { + this.config = this.processConfig(data.response); + exec(); + }.bind(this),function() { + exec(); + }); + } + + self.onmessage = function(e) { + cmds.push(e.data); + if (!execRun) exec(); + }.bind(this); + + this.setSpeed = function(val) { + if (isNaN(val = parseInt(val))) { + val = 0; + } + ival = val; + } + + } + + tick(callback) { + callback({}); + } + + processConfig(config) { + return config; + } + +} \ No newline at end of file diff --git a/js/worker/DepartureWorker.js b/js/worker/DepartureWorker.js new file mode 100644 index 0000000..b325b36 --- /dev/null +++ b/js/worker/DepartureWorker.js @@ -0,0 +1,164 @@ +importScripts('AJAX.js'); +importScripts('check.js'); +importScripts('AbstractWorker.js'); + +class DepartureWorker extends AbstractWorker { + + constructor() { + super(); + this.setSpeed(360000); + } + + processConfig(config) { + if (isObject(config) && isArrayNotEmpty(config['stops'])) { + config['stops_converted'] = []; + for (var i = 0; i < config['stops'].length; ++i) { + config['stops_converted'].push({url:'http://vrrf.finalrewind.org/'+config['stops'][i].split(':').join('/')+'.json',method:'GET',params:{frontend:'json'}}); + } + } + return config; + } + + tick(callback) { + var config = this.config; + if (isObject(config) && isArrayNotEmpty(config['stops_converted'])) { + AJAX.request(config['stops_converted']).then(function(results) { + if (results.length == 0) return; + var + reftime = new Date(), + result = { + vrrf_version: { + actual: '0.0.0.0', + expected: '0.0.0.0' + }, + errors: {}, + info: {}, + lines: {}, + raw: {} + }, + rawLines = {}; + reftime = calcDateValue(reftime.getFullYear(), reftime.getMonth()+1, reftime.getDate(), reftime.getHours(), reftime.getMinutes()); + for (var i = 0; i < results.length; ++i) { + if (!results[i].success) continue; + var data = results[i].response; + if (!isObject(data)) data = JSON.parse(data); + var stopName = config['stops'][i].split('/').join(' - '); + result['vrrf_version']['actual'] = data['version']; + result['vrrf_version']['expected'] = '0.0.0.0'; + result['errors'][stopName] = data['error']; + result['info'][stopName] = ''; + result['raw'][stopName] = data['raw']; + for (var j = 0; j < data['raw'].length; ++j) { + var entry = data['raw'][j]; + // filter + //if (isObjectNotEmpty(config['filter']) && !passFilter(config['filter'], entry)) continue; + // interprete + var + schedDate = entry['sched_date'].split('.'), + schedTime = entry['sched_time'].split(':'), + deptime = calcDateValue(schedDate[2], schedDate[1], schedDate[0], schedTime[0], schedTime[1]); + var delay = parseInt(entry['delay']); + if (isNaN(delay)) delay = 0; + if (((deptime + delay) - reftime) > 0) { + var ident = /*entry['lineref']['operator']+'|'+entry['lineref']['type']+'|'+*/entry['line']+'|'+entry['lineref']['identifier']+'|'+entry['key']; + if (!isObjectNotEmpty(result['lines'][ident])) { + result['lines'][ident] = { + timeValue: deptime, + line: entry['line'], + destination: entry['destination'], + type: entry['type'], + stops: [{ + timeValue: deptime, + time: entry['sched_time'], + delay: entry['delay'], + cancel: entry['is_cancelled'], + name: stopName, + info: entry['info'] + }] + }; + } else { + result['lines'][ident]['stops'].push({ + timeValue: deptime, + time: entry['sched_time'], + delay: entry['delay'], + cancel: entry['is_cancelled'], + name: stopName, + info: entry['info'] + }); + } + } + } + } + result['lines'] = sortData(Object.values(result['lines'])); + if (isNumber(config.max)) { + result['lines'] = result['lines'].slice(0, config.max); + } + callback(result); + }); + } + } + +} + +function passFilter(filter, entry) { + if (isObjectNotEmpty(filter['bl'])) { + if (isArrayNotEmpty(filter['bl']['line']) + && arrayContains(filter['bl']['line'], entry['line'])) { + return false; + } + if (isArrayNotEmpty(filter['bl']['type']) + && arrayContains(filter['bl']['type'], entry['type'])) { + return false; + } + if (isArrayNotEmpty(filter['bl']['platform']) + && arrayContains(filter['bl']['platform'], entry['platform'])) { + return false; + } + if (isArrayNotEmpty(filter['bl']['destination']) + && arrayContains(filter['bl']['destination'], entry['destination'])) { + return false; + } + } + if (isObjectNotEmpty(filter['wl'])) { + if (isArrayNotEmpty(filter['wl']['line']) + && !arrayContains(filter['wl']['line'], entry['line'])) { + return false; + } + if (isArrayNotEmpty(filter['wl']['type']) + && !arrayContains(filter['wl']['type'], entry['type'])) { + return false; + } + if (isArrayNotEmpty(filter['wl']['platform']) + && !arrayContains(filter['wl']['platform'], entry['platform'])) { + return false; + } + if (isArrayNotEmpty(filter['wl']['destination']) + && !arrayContains(filter['wl']['destination'], entry['destination'])) { + return false; + } + } + return true; +} + +function sortData(data) { + for (var i = 0; i < data.length; ++i) { + data[i]['stops'] = data[i]['stops'].sort(sortFn); + data[i]['timeValue'] = data[i]['stops'][0]['timeValue']; + } + return data.sort(sortFn); +} + +function sortFn(a,b) { + return a['timeValue'] - b['timeValue']; +} + +function calcDateValue(year, month, day, hour, minute) { + year = parseInt(year) * 12 * 31 * 24 * 60; + month = parseInt(month) * 31 * 24 * 60; + day = parseInt(day) * 24 * 60; + hour = parseInt(hour) * 60; + minute = parseInt(minute); + return year+month+day+hour+minute; +} + +new DepartureWorker; \ No newline at end of file diff --git a/js/worker/Worker.js b/js/worker/Worker.js new file mode 100644 index 0000000..2512e11 --- /dev/null +++ b/js/worker/Worker.js @@ -0,0 +1,60 @@ +self.interval = self.interval || 1000; +self.tick = self.tick || function() {}; +self.config = self.config || {}; + +(new function() { + var + me = this, + timer, + cmds = [], + execRun = false; + + function update() { + if (!!timer) self.clearTimeout(timer); + self.tick(function(result) { + self.postMessage(result); + }); + timer = self.setTimeout(update, self.interval); + } + + function exec() { + if (!!cmds.length) { + execRun = true; + var cmd = cmds.shift(); + me[cmd.cmd].apply(this,cmd.params); + } else { + execRun = false; + } + } + + this.start = function() { + update(); + exec(); + } + + this.stop = function() { + if (!!timer) self.clearTimeout(timer); + exec(); + } + + this.loadConfig = function(name) { + AJAX.request("../../panels/departure/config/"+name+".json").then(function(data) { + config = data.response; + if (isObject(config) && isArrayNotEmpty(config['stops'])) { + config['stops_converted'] = []; + for (var i = 0; i < config['stops'].length; ++i) { + config['stops_converted'].push({url:'http://vrrf.finalrewind.org/'+config['stops'][i].split(':').join('/')+'.json',method:'GET',params:{frontend:'json'}}); + } + } + exec(); + },function() { + exec(); + }); + } + + self.onmessage = function(e) { + cmds.push(e.data); + if (!execRun) exec(); + }.bind(this); + +}()); \ No newline at end of file diff --git a/js/worker/WorkerDeparture.js b/js/worker/WorkerDeparture.js new file mode 100644 index 0000000..d58c7a0 --- /dev/null +++ b/js/worker/WorkerDeparture.js @@ -0,0 +1,138 @@ +importScripts('AJAX.js'); +importScripts('check.js'); + +self.interval = 360000; + +self.tick = function(callback) { + var config = self.config; + if (isObject(config) && isArrayNotEmpty(config['stops_converted'])) { + AJAX.request(config['stops_converted']).then(function(results) { + if (results.length == 0) return; + var + result = { + vrrf_version: { + actual: '0.0.0.0', + expected: '0.0.0.0' + }, + errors: {}, + info: {}, + lines: {}, + raw: {} + }, + rawLines = {}; + for (var i = 0; i < results.length; ++i) { + if (!results[i].success) continue; + var data = JSON.parse(results[i].response); + var stopName = config['stops'][i].split(':').join(' - '); + result['vrrf_version']['actual'] = data['version']; + result['vrrf_version']['expected'] = '0.0.0.0'; + result['errors'][stopName] = data['error']; + result['info'][stopName] = ''; + result['raw'][stopName] = data['raw']; + for (var j = 0; j < data['raw'].length; ++j) { + var entry = data['raw'][j]; + // filter + if (isObjectNotEmpty(config['filter']) && !passFilter(config['filter'], entry)) continue; + // interprete + var + reftime = new Date(), + schedDate = entry['sched_date'].split('.'), + schedTime = entry['sched_time'].split(':'), + deptime = calcDateValue(schedDate[0], schedTime[0], schedTime[1]); + reftime = calcDateValue(reftime.getDate(), reftime.getHours(), reftime.getMinutes()); + if (deptime + parseInt(entry['delay']) - reftime) { + var ident = entry['lineref']['operator']+'|'+entry['lineref']['type']+'|'+entry['line']+'|'+entry['lineref']['identifier']+'|'+entry['key']; + if (!isObjectNotEmpty(result['lines'][ident])) { + result['lines'][ident] = { + timeValue: deptime, + line: entry['line'], + destination: entry['destination'], + type: entry['type'], + stops: [{ + timeValue: deptime, + time: entry['sched_time'], + delay: entry['delay'], + cancel: entry['is_cancelled'], + name: stopName, + info: entry['info'] + }] + }; + } else { + result['lines'][ident]['stops'].push({ + timeValue: deptime, + time: entry['sched_time'], + delay: entry['delay'], + cancel: entry['is_cancelled'], + name: stopName, + info: entry['info'] + }); + } + } + } + } + result['lines'] = sortData(Object.values(result['lines'])); + if (isNumber(config.max)) { + result['lines'] = result['lines'].slice(0, config.max); + } + callback(result); + }); + } +} + +function passFilter(filter, entry) { + if (isObjectNotEmpty(filter['bl'])) { + if (isArrayNotEmpty(filter['bl']['line']) + && arrayContains(filter['bl']['line'], entry['line'])) { + return false; + } + if (isArrayNotEmpty(filter['bl']['type']) + && arrayContains(filter['bl']['type'], entry['type'])) { + return false; + } + if (isArrayNotEmpty(filter['bl']['platform']) + && arrayContains(filter['bl']['platform'], entry['platform'])) { + return false; + } + if (isArrayNotEmpty(filter['bl']['destination']) + && arrayContains(filter['bl']['destination'], entry['destination'])) { + return false; + } + } + if (isObjectNotEmpty(filter['wl'])) { + if (isArrayNotEmpty(filter['wl']['line']) + && !arrayContains(filter['wl']['line'], entry['line'])) { + return false; + } + if (isArrayNotEmpty(filter['wl']['type']) + && !arrayContains(filter['wl']['type'], entry['type'])) { + return false; + } + if (isArrayNotEmpty(filter['wl']['platform']) + && !arrayContains(filter['wl']['platform'], entry['platform'])) { + return false; + } + if (isArrayNotEmpty(filter['wl']['destination']) + && !arrayContains(filter['wl']['destination'], entry['destination'])) { + return false; + } + } + return true; +} + +function sortData(data) { + for (var i = 0; i < data.length; ++i) { + data[i]['stops'] = data[i]['stops'].sort(sortFn); + data[i]['timeValue'] = data[i]['stops'][0]['timeValue']; + } + return data.sort(sortFn); +} + +function sortFn(a,b) { + return a['timeValue'] > b['timeValue']; +} + +function calcDateValue(day, hour, minute) { + return parseInt(day) * 24 * 60 + parseInt(hour) * 60 + parseInt(minute); +} + +importScripts('Worker.js'); \ No newline at end of file diff --git a/js/worker/check.js b/js/worker/check.js new file mode 100644 index 0000000..cce4070 --- /dev/null +++ b/js/worker/check.js @@ -0,0 +1,64 @@ +function isEmpty(value) { + switch (typeof value) { + case 'undefined': + return true; + break; + case 'object': + if (Array.isArray(value)) return value.length <= 0; + return value === null || Object.getOwnPropertyNames(value).length <= 0; + break; + case 'string': + return value == ""; + break; + case 'number': + return isNaN(value); + break; + default: + return false; + break; + } +} + +function isFunction(value) { + return typeof(value) == 'function'; +} + +function isObject(value) { + return typeof(value) == 'object' && !Array.isArray(value); +} + +function isObjectNotEmpty(value) { + return typeof(value) == 'object' && !Array.isArray(value) && Object.getOwnPropertyNames(value).length > 0; +} + +function isArray(value) { + return Array.isArray(value); +} + +function isArrayNotEmpty(value) { + return Array.isArray(value) && value.length > 0; +} + +function isString(value) { + return typeof(value) == 'string'; +} + +function isStringNotEmpty(value) { + return typeof(value) == 'string' && value != ""; +} + +function isNumber(value) { + return typeof(value) == 'number'; +} + +function isInteger(value) { + return Number.isSafeInteger(value); +} + +function isBoolean(value) { + return typeof(value) == 'boolean'; +} + +function arrayContains(array, value) { + return isArray(array) && !!(array.indexOf(value)+1); +} \ No newline at end of file diff --git a/panels/clock/script.js b/panels/clock/script.js index c3fd232..ff61b99 100755 --- a/panels/clock/script.js +++ b/panels/clock/script.js @@ -1,339 +1,19 @@ -var DCC; - this.loaded = function(panel, config) { - - var DigitalCanvasClock = function() { - var - me = this, - analBGFile = "panels/clock/background.png", - analBGImg = new Image(), - analogFactor = 0.9, - useBackground = true, - usePulse = true, - digiClock = panel.find("canvas[data-digital-clock]")[0], - analClock = panel.find("canvas[data-analog-clock]")[0], - digiBackground = null, - analBackground = null, - dfgc = digiClock ? digiClock.getContext("2d") : null, - dbgc = null, - afgc = analClock ? analClock.getContext("2d") : null, - abgc = null, - bgColor = null, //panel.css("background-color"), - sdColor = "#111", - icColor = "#FFF", - date = new Date(), - monthNames = ["jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"], - dayNames = ["so","mo","di","mi","do","fr","sa"], - lastSecond = -1, - seperatorOn = false, - // sizes digital (16:9) - digitalWidth = 0, - digitalHeight = 0, - clockWidth = 0, - clockHeight = 0, - clockX = 0, - clockY = 0, - // clock - clockHourX = 0, // width * 4.375% - clockSeperatorX = 0, // height * 60.185% - clockMinuteX = 0, // width * 47.083% - clockSecondX = 0, // height * 145.185% - dateX = 0, // width * 1.875% - clockTimeY = 0, // height * 58.148% - clockSeperatorY = 0, // height * 47.037% - dateY = 0, // width / 2 - // sizes analog (1:1) - analogWidth = 0, - analogHeight = 0, - analogX = 0, - analogY = 0, - analogRad = 0, - // font - fatFont = "", // width * 43.75% - bigFont = "", // width * 43.75% - smlFont = "", // width * 18.75% - fatFontPost = "time-fat", // width * 43.75% - bigFontPost = "time-medium", // width * 43.75% - smlFontPost = "time-medium"; // width * 18.75% - - inita = function() { - if (window.fontsReady) { - digiBackground = document.createElement('canvas'); - analBackground = document.createElement('canvas'); - me.resize($(panel).width(), $(panel).height()); - - loop(); - } else { - setTimeout(inita,0); - } - } - - loop = function(delta) { - me.render(); - window.requestAnimationFrame(loop); - } - - this.resize = function(width, height) { - if (height > width) { - var size = height / 2; - if (!!analClock) { - $(analClock).attr('width', width).attr('height', size); - } - if (!!digiClock) { - $(digiClock).attr('width', width).attr('height', size); - } - } else { - var size = height > width / 2 ? width / 2 : height; - if (!!analClock) { - $(analClock).attr('width', size).attr('height', height); - } - if (!!digiClock) { - $(digiClock).attr('width', width - size - 6).attr('height', height); - } - } - calc(); - } - - this.indicatorColor = function(color) { - icColor = color || icColor; - } - - this.shaddowColor = function(color) { - sdColor = color || sdColor; - renderBackground(); - } - - this.backgroundColor = function(color) { - bgColor = color || bgColor; - renderBackground(); - } - - this.enableBackground = function(value) { - if (typeof value === 'boolean') - useBackground = value; - } - - this.enablePulse = function(value) { - if (typeof value === 'boolean') - usePulse = value; - } - - calc = function() { - - if (!!digiClock) calcDigital(); - if (!!analClock) calcAnalog(); - - } - - calcDigital = function() { - // canvas size - digitalWidth = $(digiClock).width(); - digitalHeight = $(digiClock).height(); - // clock size - var ratio = digitalWidth * 9 / 16; - if (ratio > digitalHeight) { - clockWidth = digitalHeight * 16 / 9; - clockHeight = digitalHeight; - } else if (ratio < digitalHeight) { - clockWidth = digitalWidth; - clockHeight = digitalWidth * 9 / 16; - } else { - clockWidth = digitalWidth; - clockHeight = digitalHeight; - } - clockX = digitalWidth / 2 - clockWidth / 2; - clockY = digitalHeight / 2 - clockHeight / 2; - // fonts - var - bigFontSize = clockWidth * 43.75 / 100, - smlFontSize = clockWidth * 18.75 / 100; - fatFont = bigFontSize + "px " + fatFontPost; - bigFont = bigFontSize + "px " + bigFontPost; - smlFont = smlFontSize + "px " + smlFontPost; - // positions - clockHourX = clockX + clockWidth * 4.375 / 100; - clockMinuteX = clockX + clockWidth * 47.083 / 100; - clockSecondX = clockX + clockHeight * 145.185 / 100; - clockTimeY = clockY + clockHeight * 58.148 / 100; - clockSeperatorX = clockX + clockHeight * 60.185 / 100; - clockSeperatorY = clockY + clockHeight * 47.037 / 100; - dateX = clockX + clockWidth * 1.875 / 100; - dateY = clockY + clockWidth / 2; - // background - digiBackground.width = digitalWidth; - digiBackground.height = digitalHeight; - dbgc = digiBackground.getContext("2d"); - renderDigiBackground(); - } - - calcAnalog = function() { - - analogWidth = $(analClock).width(); - analogHeight = $(analClock).height(); - // clock size - var size; - if (analogWidth > analogHeight) { - size = analogHeight; - } else { - size = analogWidth; - } - analogRad = size * (analogFactor / 2); - analogX = analogWidth / 2; - analogY = analogHeight / 2; - afgc.translate(analogX, analogY); - // background - analBackground.width = analogWidth; - analBackground.height = analogHeight; - abgc = analBackground.getContext("2d"); - abgc.translate(analogX, analogY); - - renderAnalBackground(); - } - - this.render = function() { - date = new Date(); - var ms = date.getMilliseconds(); - if ((ms > 500 && seperatorOn) || (ms < 500 && !seperatorOn)) { - var - h = date.getHours(), - i = date.getMinutes(), - s = date.getSeconds(), - t = date.getDay(), - d = date.getDate(), - m = date.getMonth(), - y = date.getFullYear(); - if (d.toString().length < 2) - d = "0" + d; - if (h.toString().length < 2) - h = "0" + h; - if (i.toString().length < 2) - i = "0" + i; - if (s.toString().length < 2) - s = "0" + s; - if (!!dfgc) renderDigital(h, i, s, t, d, m, y); - if (!!afgc && s != lastSecond) renderAnalog(h, i, s); - lastSecond = s; - } - } - - renderDigital = function(h, i, s, t, d, m, y) { - if (bgColor == null) { - dfgc.clearRect(0, 0, digitalWidth, digitalHeight); - } - - dfgc.drawImage(digiBackground, 0, 0); - dfgc.fillStyle = icColor; - if (!seperatorOn) { - dfgc.font = fatFont; - dfgc.fillText(":", clockSeperatorX, clockSeperatorY); - seperatorOn = true; - } else { - seperatorOn = false; - } - dfgc.font = bigFont; - dfgc.fillText(h, clockHourX, clockTimeY); - dfgc.fillText(i, clockMinuteX, clockTimeY); - dfgc.font = smlFont; - dfgc.fillText(s, clockSecondX, clockTimeY); - dfgc.fillText(dayNames[t] + " " + d + " " + monthNames[m] + " " + y, dateX, dateY); - dfgc.fillStyle = "black"; - } - - renderAnalog = function(h, i, s) { - if (bgColor == null) { - afgc.clearRect(-analogX, -analogY, analogWidth, analogHeight); - } - //debugger; - afgc.drawImage(analBackground, -analogX, -analogY); - afgc.strokeStyle = icColor; - //drawNumbers(); - //hour - var hour=((h % 12) * Math.PI / 6) + (i * Math.PI / (6 * 60)) + (s * Math.PI / (360 * 60)); - renderHand(hour, analogRad * 0.5, analogRad * 0.07); - //minute - var minute = (i * Math.PI / 30) + (s * Math.PI / (30 * 60)); - renderHand(minute, analogRad * 0.8, analogRad * 0.07); - // second - var second = (s * Math.PI / 30); - renderHand(second, analogRad * 0.9, analogRad * 0.02); - afgc.strokeStyle = "black"; - } - - renderHand = function(pos, length, width) { - afgc.beginPath(); - afgc.lineWidth = width; - afgc.lineCap = "round"; - afgc.moveTo(0,0); - afgc.rotate(pos); - afgc.lineTo(0, -length); - afgc.stroke(); - afgc.rotate(-pos); - } - - renderDigiBackground = function() { - if (bgColor == null) { - dbgc.clearRect(0, 0, digitalWidth, digitalHeight); - } else { - dbgc.fillStyle = bgColor; - dbgc.fillRect(0, 0, digitalWidth, digitalHeight); - } - dbgc.fillStyle = sdColor; - dbgc.font = fatFont; - dbgc.fillText(":", clockSeperatorX, clockSeperatorY); - dbgc.font = bigFont; - dbgc.fillText("88", clockHourX, clockTimeY); - dbgc.fillText("88", clockMinuteX, clockTimeY); - dbgc.font = smlFont; - dbgc.fillText("88", clockSecondX, clockTimeY); - dbgc.fillText("00 00 000 0000", dateX, dateY); - dbgc.fillText("** ** *** ****", dateX, dateY); - dbgc.fillStyle = "black"; - } - - renderAnalBackground = function() { - abgc.fillStyle = bgColor; - var - bc = document.createElement('canvas'), - steps = Math.ceil(Math.log(analBGImg.width / (analogRad * 2)) / Math.log(2)) - 1, - bctx; - bc.width = analBGImg.width; - bc.height = analBGImg.height; - bctx = bc.getContext('2d'); - bctx.drawImage(analBGImg, 0, 0, bc.width, bc.height); - for (var i = 0; i < steps; ++i) { - var oc = document.createElement('canvas'); - oc.width = bc.width * 0.5; - oc.height = bc.height * 0.5; - bctx = oc.getContext('2d'); - bctx.drawImage(bc, 0, 0, oc.width, oc.height); - bc = oc; - } - - if (bgColor == null) { - abgc.clearRect(-analogX, -analogY, analogWidth, analogHeight); - } else { - abgc.fillRect(-analogX, -analogY, analogWidth, analogHeight); - } - abgc.fillStyle = "black"; - //abgc.drawImage(buffer, -analogRad, -analogRad, analogRad * 2, analogRad * 2); - abgc.drawImage(bc, -analogRad, -analogRad, analogRad * 2, analogRad * 2); - - } - analBGImg.onload = function() { - inita(); - } - analBGImg.src = analBGFile; - } - DCC = new DigitalCanvasClock(); + var clock = new Clock(panel, config); + + window.addEventListener("resize", function() { + clock.resize(panel[0].clientWidth, panel[0].clientHeight); + }.bind(this)); - r = function() { - resize(panel); + function tick() { + clock.render(); + window.requestAnimationFrame(function() { + tick(); + }, 0); } - $(window).resize(r); -} - -var resize = function(panel) { - DCC.resize($(panel).width(), $(panel).height()); -} + clock.resize(panel[0].clientWidth, panel[0].clientHeight); + tick(); + +}; \ No newline at end of file diff --git a/panels/clock/style.less b/panels/clock/style.less index 1414f31..ae1be74 100755 --- a/panels/clock/style.less +++ b/panels/clock/style.less @@ -1,11 +1,8 @@ -[data-analog-clock] { +canvas { position: relative; display: inline; left: 0px; -} - -[data-digital-clock] { - position: relative; - display: inline; - right: 0px; + top: 0px; + width: 100%; + height: 100%; } \ No newline at end of file diff --git a/panels/clock/template.html b/panels/clock/template.html index 6c4da64..bbef1f2 100755 --- a/panels/clock/template.html +++ b/panels/clock/template.html @@ -1,4 +1,2 @@ -<canvas data-analog-clock> -</canvas> -<canvas data-digital-clock> -</canvas> +<canvas> +</canvas> \ No newline at end of file diff --git a/panels/departure/cache/.gitignore b/panels/departure/cache/.gitignore deleted file mode 100755 index 72e8ffc..0000000 --- a/panels/departure/cache/.gitignore +++ /dev/null @@ -1 +0,0 @@ -* diff --git a/panels/departure/config/default.json b/panels/departure/config/default.json index 60e85c1..c147784 100755 --- a/panels/departure/config/default.json +++ b/panels/departure/config/default.json @@ -1,7 +1,7 @@ { "max":"20", "stops": [ - "Dortmund:Hbf" + "Dortmund/Hbf" ], "filter": { "bl": { diff --git a/panels/departure/config/oh14.json b/panels/departure/config/oh14.json index 437e4b1..5a2773d 100755 --- a/panels/departure/config/oh14.json +++ b/panels/departure/config/oh14.json @@ -1,9 +1,9 @@ { - "max":"20", + "max":20, "stops": [ - "Dortmund:Universität S", - "Dortmund:Joseph-von-Fraunhofer Straße", - "Dortmund:Meitnerweg" + "Dortmund/Universität S", + "Dortmund/Joseph-von-Fraunhofer Straße", + "Dortmund/Meitnerweg" ], "filter": { "bl": { @@ -11,7 +11,7 @@ "H-Bahn" ], "destination": [ - "Dortmund Otto-Hahn-Straße" + "Dortmund Otto-Hahn-Straße" ] } } diff --git a/panels/departure/departures.php b/panels/departure/departures.php deleted file mode 100755 index 97868a5..0000000 --- a/panels/departure/departures.php +++ /dev/null @@ -1,204 +0,0 @@ -<?php - error_reporting (-1); - ini_set ('display_errors', 1); - - // initialize frontend - header('Content-type: text/json'); - - // version-info - $version = "0.05"; - $vrrf_version = "0.07"; - - // options - $options = array(); - - // max entries - $max = 1000000; - - // configuration - if (isset($_GET['config'])) { - $file = "config/" . $_GET['config'] . ".json"; - if (!file_exists($file)) { - $result['error'] = 'config file "'.$file.'" not found'; - $result['config']['name'] = $file; - $result['options'] = $options; - echo json_encode($result); - exit; - } - $config = file_get_contents($file); - $buffer = json_decode($config, true); - $options['stops'] = $buffer['stops']; - $options['filter'] = $buffer['filter']; - if (is_numeric($buffer['max'])) { - $max = $buffer['max']; - } - if (count($options['stops']) == 0) { - $result['error'] = 'no stops defined'; - $result['config']['name'] = $config_name; - $result['config']['type'] = 'panel/departure'; - $result['options'] = $options; - echo json_encode($result); - exit; - } - } else { - $result['error'] = 'no config defined'; - $result['config']['name'] = $config_name; - $result['config']['type'] = 'panel/departure'; - $result['options'] = $options; - echo json_encode($result); - exit; - } - - - usort($options['stops'], function($a, $b) { - return strcmp($a, $b); - }); - - // cache - $name = json_encode($options); - $cachefile = "cache/vrr_".md5($name).".json"; - $cachetime = 60; - $cache_ablauf = 0; - $cacheused = false; - $rawdata = array(); - $alldata = array(); - - if (is_file($cachefile)) - $cache_ablauf=filemtime($cachefile)+$cachetime; - if (!isset($_GET["nocache"]) && is_file($cachefile) && (time() < filemtime($cachefile)+$cachetime)) { - $plain = file_get_contents($cachefile); - $alldata = json_decode($plain, true); - $cacheused = true; - } else { - foreach ($options['stops'] as $n => $stop) { - $stopsplit = explode(":",$stop); - - // errors? - if ($stopsplit == $stop) - echo "<div error><h1>NAME ERROR!</h1>$stop<br/>Not a propper stop name. Usage: city:stop[;city:stop]*</div>"; - - // get departures - ob_start(); - $plain = file_get_contents("http://vrrf.finalrewind.org/$stopsplit[0]/$stopsplit[1].json?frontend=json"); - $data = json_decode($plain, true); - // version - $alldata["version"] = $version; - $alldata["vrrf_version"] = $data['version']; - $alldata["used_vrrf_version"] = $vrrf_version; - // api_errors - $alldata["errors"]["$stopsplit[0] - $stopsplit[1]"] = $data['error']; - // info - $alldata["info"] = ""; // TODO generate informations - // data - $rawdata["$stopsplit[0] - $stopsplit[1]"] = $data['raw']; - } - - $reftime = date("dHi"); - $alldata['lines'] = array(); - foreach ($rawdata as $stop => $data) { - // process - foreach ($data as $i => $entry) { - - // filter - if (isset($options['filter']['bl'])) { - if (isset($options['filter']['bl']['line']) ) { - if (in_array($entry['line'], $options['filter']['bl']['line'])) { - continue; - } - } - if (isset($options['filter']['bl']['type']) ) { - if (in_array($entry['type'], $options['filter']['bl']['type'])) { - continue; - } - } - if (isset($options['filter']['bl']['platform']) ) { - if (in_array($entry['platform'], $options['filter']['bl']['platform'])) { - continue; - } - } - if (isset($options['filter']['bl']['destination']) ) { - if (in_array($entry['destination'], $options['filter']['bl']['destination'])) { - continue; - } - } - } - if (isset($options['filter']['wl'])) { - if (isset($options['filter']['wl']['line']) ) { - if (!in_array($entry['line'], $options['filter']['wl']['line'])) { - continue; - } - } - if (isset($options['filter']['wl']['type']) ) { - if (!in_array($entry['type'], $options['filter']['wl']['type'])) { - continue; - } - } - if (isset($options['filter']['wl']['platform']) ) { - if (!in_array($entry['platform'], $options['filter']['wl']['platform'])) { - continue; - } - } - if (isset($options['filter']['wl']['destination']) ) { - if (!in_array($entry['destination'], $options['filter']['wl']['destination'])) { - continue; - } - } - } - // !filter - - $scheddate = explode(".",$entry['sched_date']); - $schedtime = explode(":",$entry['sched_time']); - $deptime = $scheddate[0].$schedtime[0].$schedtime[1]; - //echo intval($deptime)." + ".intval($entry['delay'])." - ".intval($reftime)." = ".(intval($deptime) + intval($entry['delay']) - intval($reftime))."<br/>"; - if (intval($deptime) + intval($entry['delay']) - intval($reftime) > 0) { - $buf = array('date' => $entry['sched_date'], 'time' => $entry['sched_time'], 'delay' => $entry['delay'], 'cancel' => $entry['is_cancelled'], 'name' => $stop, 'info' => $entry['info']); - foreach ($alldata['lines'] as $key => $value) { - if (($entry['key'] == $value['key']) && ($entry['lineref']['identifier'] == $value['identifier']) && ($entry['line'] == $value['line'])) { - $ibuf = sizeof($alldata['lines'][$key]['stops']); - while ($buf != null) { - if ($ibuf < 1 || strcmp($buf['time'], $alldata['lines'][$key]['stops'][$ibuf - 1]['time']) > 0) { - $alldata['lines'][$key]['stops'][$ibuf] = $buf; - $buf = null; - } else { - $alldata['lines'][$key]['stops'][$ibuf] = $alldata['lines'][$key]['stops'][$ibuf - 1]; - $ibuf--; - } - } - break; - } - } - if ($buf != null) { - $dbuf = array('line' => $entry['line'], 'destination' => $entry['destination'], 'type' => $entry['type'], 'key' => $entry['key'], 'identifier' => $entry['lineref']['identifier'], 'stops' => array($buf)); - $alldata['lines'][] = $dbuf; - } - } - } - - } - - // sort - usort($alldata['lines'], function($a, $b) { - // atime - $scheddate = explode(".",$a['stops'][0]['date']); - $schedtime = explode(":",$a['stops'][0]['time']); - $atime = $scheddate[2].$scheddate[1].$scheddate[0].$schedtime[0].$schedtime[1]; - // btime - $scheddate = explode(".",$b['stops'][0]['date']); - $schedtime = explode(":",$b['stops'][0]['time']); - $btime = $scheddate[2].$scheddate[1].$scheddate[0].$schedtime[0].$schedtime[1]; - // compare - return intval($atime) - intval($btime); - }); - - // clean - foreach ($alldata['lines'] as $id => $line) { - unset($alldata['lines'][$id]['key']); - unset($alldata['lines'][$id]['identifier']); - } - - // save cache - file_put_contents($cachefile,json_encode($alldata)); - } - - echo json_encode($alldata); -?> diff --git a/panels/departure/script.js b/panels/departure/script.js index 6717c73..166f8ea 100755 --- a/panels/departure/script.js +++ b/panels/departure/script.js @@ -34,7 +34,7 @@ */ this.loaded = function(panel, config) { - console.log("Departure: register with config [" + config + "]"); + console.log("departures: register with config [" + config + "]"); // TODO load config var tplDeparture = $(panel).find('template[data-departure]').html(), @@ -46,113 +46,125 @@ this.loaded = function(panel, config) { $(panel).empty().append(fields.cont); - var u = function() { - update(config, fields); - }; - setInterval(u, 60000); + //var u = function() { + // console.log("departures: get data [" + config + "]"); + // $.get("panels/departure/departures.php?config=" + config , function(decodedData) { + // update(decodedData, fields); + // }); + //}; + //setInterval(u, 60000); var r = function() { resize(panel, config, fields.cont); }; $(window).resize(r); + + //var worker = new Worker('js/worker/WorkerDeparture.js'); + var worker = new Worker('js/worker/DepartureWorker.js'); + + worker.addEventListener('message', function(e) { + var data = e.data; + update(data, fields, config); + }, false); + + //worker.postMessage([{cmd:"loadConfig", params:[config]},{cmd:"start"}]); + worker.postMessage({cmd:"loadConfig", params:[config]}); + worker.postMessage({cmd:"start"}); - u(); + //u(); r(); } -var update = function(config, fields) { - console.log("Departure: get data [" + config + "]"); - $.get("panels/departure/departures.php?config=" + config , function(decodedData) { +var update = function(decodedData, fields, config) { - console.log("Departure: check vrrf errors [" + config + "]"); - if (!!decodedData.errors) { - var msg = ""; - for (var i in decodedData.errors) { - if (decodedData.errors[i]) { - msg += (msg.lenth > 0 ? '\r\n' : '') + i + ': ' + decodedData.errors[i] - } + console.log("departures: check vrrf errors [" + config + "]"); + if (!!decodedData.errors) { + var msg = ""; + for (var i in decodedData.errors) { + if (decodedData.errors[i]) { + msg += (msg.lenth > 0 ? '\r\n' : '') + i + ': ' + decodedData.errors[i] } - $(fields.vrrf.ttle).html('VRRF - Error'); - $(fields.vrrf.msge).html(msg); - } else { - $(fields.vrrf.ttle).html(''); - $(fields.vrrf.msge).html(''); - $(fields.vrrf.msge).css("display", "none"); - } - - console.log("Departure: check error [" + config + "]"); - if (!!decodedData.error) { - $(fields.erro.ttle).html('InfoBoard - Error'); - $(fields.erro.msge).html(decodedData.error); - } else { - $(fields.erro.ttle).html(''); - $(fields.erro.msge).html(''); - $(fields.erro.msge).css("display", "none"); - } - - console.log("Departure: check information [" + config + "]"); - if (!!decodedData.info) { - $(fields.info.ttle).html('Information'); - $(fields.info.msge).html(decodedData.info); - //$(fields.info.msge).css("display", ""); - } else { - $(fields.info.ttle).html(''); - $(fields.info.msge).html(''); - //$(fields.info.msge).css("display", "none"); } - - console.log("Departure: updating elements [" + config + "]"); - if (!!decodedData.lines) { - for (var i = 0; i < 20; ++i) { - var - actDep = fields.dprt[i], - strDep = decodedData.lines[i]; - if (!strDep) { - $(actDep.self).css("display", "none"); - $(actDep.line).html(''); - $(actDep.name).html(''); - for (var j = 0; j < 3; ++j) { - var actStn = actDep.sttn[j]; + $(fields.vrrf.ttle).html('VRRF - Error'); + $(fields.vrrf.msge).html(msg); + } else { + $(fields.vrrf.ttle).html(''); + $(fields.vrrf.msge).html(''); + $(fields.vrrf.msge).css("display", "none"); + } + + console.log("departures: check error [" + config + "]"); + if (!!decodedData.error) { + $(fields.erro.ttle).html('InfoBoard - Error'); + $(fields.erro.msge).html(decodedData.error); + } else { + $(fields.erro.ttle).html(''); + $(fields.erro.msge).html(''); + $(fields.erro.msge).css("display", "none"); + } + + console.log("departures: check information [" + config + "]"); + if (!!decodedData.info) { + $(fields.info.ttle).html('Information'); + $(fields.info.msge).html(decodedData.info); + //$(fields.info.msge).css("display", ""); + } else { + $(fields.info.ttle).html(''); + $(fields.info.msge).html(''); + //$(fields.info.msge).css("display", "none"); + } + + console.log("departures: updating elements [" + config + "]"); + if (!!decodedData.lines) { + for (var i = 0; i < 20; ++i) { + var + actDep = fields.dprt[i], + strDep = decodedData.lines[i]; + if (!strDep) { + $(actDep.self).css("display", "none"); + $(actDep.line).html(''); + $(actDep.name).html(''); + for (var j = 0; j < 3; ++j) { + var actStn = actDep.sttn[j]; + $(actStn.self).css("display", "none"); + $(actStn.time).html(''); + $(actStn.name).html(''); + //$(actStn.info.self).css("display", "none"); + //$(actStn.info.msge).html(''); + } + } else { + $(actDep.self).css("display", ""); + $(actDep.line).html(strDep.line.toUpperCase()); + $(actDep.name).html(strDep.destination.replace("Dortmund ", "")); + for (var j = 0; j < 3; ++j) { + var + actStn = actDep.sttn[j], + strStn = strDep.stops[j]; + if (!strStn) { $(actStn.self).css("display", "none"); $(actStn.time).html(''); + $(actStn.dlay).html(''); $(actStn.name).html(''); - $(actStn.info.self).css("display", "none"); - $(actStn.info.msge).html(''); - } - } else { - $(actDep.self).css("display", ""); - $(actDep.line).html(strDep.line.toUpperCase()); - $(actDep.name).html(strDep.destination.replace("Dortmund ", "")); - for (var j = 0; j < 3; ++j) { - var - actStn = actDep.sttn[j], - strStn = strDep.stops[j]; - if (!strStn) { - $(actStn.self).css("display", "none"); - $(actStn.time).html(''); - $(actStn.dlay).html(''); - $(actStn.name).html(''); + } else { + $(actStn.self).css("display", ""); + $(actStn.time).html(strStn.time); + $(actStn.name).html(strStn.name.replace("Dortmund - ", "")); + if (strStn.cancel == 1) { + $(actStn.name).css("text-decoration", "outline"); } else { - $(actStn.self).css("display", ""); - $(actStn.time).html(strStn.time); - $(actStn.name).html(strStn.name.replace("Dortmund - ", "")); - if (strStn.cancel == 1) { - $(actStn.name).css("text-decoration", "outline"); - } else { - $(actStn.name).css("text-decoration", ""); - } - - if (strStn.delay > 0) { - $(actStn.dlay).html('+' + strStn.delay); - } else { - $(actStn.dlay).html(''); - } + $(actStn.name).css("text-decoration", ""); + } + + if (strStn.delay > 0) { + $(actStn.dlay).html('+' + strStn.delay); + } else { + $(actStn.dlay).html(''); } } } } } - }); + } } var resize = function(panel, config, cont) { @@ -211,7 +223,7 @@ var getStringWidth = function(fontSize, string) { } var generate = function(config, stations, departs, tplDeparture, tplStop, tplMsg) { - console.log("Departure: generating structure [" + config + "]"); + console.log("departures: generating structure [" + config + "]"); var buffer = null, fields = { @@ -279,7 +291,7 @@ var generate = function(config, stations, departs, tplDeparture, tplStop, tplMsg } var buildDOM = function(config, fields) { - console.log("Departure: building dom [" + config + "]"); + console.log("departures: building dom [" + config + "]"); var elements = []; elements.push(fields.info.self); elements.push(fields.erro.self); -- GitLab