From 49eb4ac007f55ea744c0d2a3029468247146c0b3 Mon Sep 17 00:00:00 2001 From: Christof Schulze Date: Tue, 26 Apr 2016 21:33:29 +0200 Subject: [PATCH] remove statuspage --- package/gluon-status-page/Makefile | 67 ---- .../gluon-status-page/iconfont-config.json | 100 ------ package/gluon-status-page/src/build.js | 10 - .../gluon-status-page/src/css/animation.css | 85 ------ package/gluon-status-page/src/css/font.css | 53 ---- package/gluon-status-page/src/css/main.css | 171 ----------- package/gluon-status-page/src/css/menu.css | 60 ---- package/gluon-status-page/src/css/reset.css | 86 ------ package/gluon-status-page/src/index.html.m4 | 17 -- package/gluon-status-page/src/js/lib/gui.js | 157 ---------- .../gluon-status-page/src/js/lib/gui/menu.js | 39 --- .../src/js/lib/gui/neighbours.js | 282 ----------------- .../src/js/lib/gui/nodeinfo.js | 54 ---- .../src/js/lib/gui/signal.js | 48 --- .../src/js/lib/gui/signalgraph.js | 137 --------- .../src/js/lib/gui/statistics.js | 285 ------------------ .../gluon-status-page/src/js/lib/helper.js | 92 ------ .../src/js/lib/neighbourstream.js | 132 -------- .../gluon-status-page/src/js/lib/streams.js | 66 ---- package/gluon-status-page/src/js/main.js | 108 ------- 20 files changed, 2049 deletions(-) delete mode 100644 package/gluon-status-page/Makefile delete mode 100644 package/gluon-status-page/iconfont-config.json delete mode 100644 package/gluon-status-page/src/build.js delete mode 100644 package/gluon-status-page/src/css/animation.css delete mode 100644 package/gluon-status-page/src/css/font.css delete mode 100644 package/gluon-status-page/src/css/main.css delete mode 100644 package/gluon-status-page/src/css/menu.css delete mode 100644 package/gluon-status-page/src/css/reset.css delete mode 100644 package/gluon-status-page/src/index.html.m4 delete mode 100644 package/gluon-status-page/src/js/lib/gui.js delete mode 100644 package/gluon-status-page/src/js/lib/gui/menu.js delete mode 100644 package/gluon-status-page/src/js/lib/gui/neighbours.js delete mode 100644 package/gluon-status-page/src/js/lib/gui/nodeinfo.js delete mode 100644 package/gluon-status-page/src/js/lib/gui/signal.js delete mode 100644 package/gluon-status-page/src/js/lib/gui/signalgraph.js delete mode 100644 package/gluon-status-page/src/js/lib/gui/statistics.js delete mode 100644 package/gluon-status-page/src/js/lib/helper.js delete mode 100644 package/gluon-status-page/src/js/lib/neighbourstream.js delete mode 100644 package/gluon-status-page/src/js/lib/streams.js delete mode 100644 package/gluon-status-page/src/js/main.js diff --git a/package/gluon-status-page/Makefile b/package/gluon-status-page/Makefile deleted file mode 100644 index 460764d0..00000000 --- a/package/gluon-status-page/Makefile +++ /dev/null @@ -1,67 +0,0 @@ -include $(TOPDIR)/rules.mk - -PKG_NAME:=gluon-status-page -PKG_VERSION:=2 -PKG_RELEASE:=1 - -PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) -PKG_BUILD_DEPENDS:=node/host - -include $(INCLUDE_DIR)/package.mk - -define Download/rjs - FILE:=r.js - URL:=http://requirejs.org/docs/release/2.1.10 - MD5SUM:=270154b3f5d417c3a42f1e58d03e6607 -endef - -define Download/Bacon - FILE:=Bacon.js - URL:=http://cdnjs.cloudflare.com/ajax/libs/bacon.js/0.7.71 - MD5SUM:=4600a60e1d7ffdb2259dfcce97c860ed -endef - -define Download/almond - FILE:=almond.js - URL:=https://raw.githubusercontent.com/jrburke/almond/0.3.1 - MD5SUM:=aa66c0c0cb55a4627bb706df73f3aff5 -endef - -$(eval $(call Download,rjs)) -$(eval $(call Download,Bacon)) -$(eval $(call Download,almond)) - -define Package/gluon-status-page - SECTION:=gluon - CATEGORY:=Gluon - TITLE:=Adds a status page showing information about the node. - DEPENDS:=+gluon-status-page-api -endef - -define Package/gluon-status-page/description - Adds a status page showing information about the node. - Especially useful in combination with the next-node feature. -endef - -define Build/Prepare - mkdir -p $(PKG_BUILD_DIR) - $(CP) -t $(PKG_BUILD_DIR) $(DL_DIR)/r.js $(DL_DIR)/Bacon.js $(DL_DIR)/almond.js -endef - -define Build/Configure - $(CP) ./src/* $(PKG_BUILD_DIR)/ -endef - -define Build/Compile - cd $(PKG_BUILD_DIR) && \ - node r.js -o build.js && \ - node r.js -o cssIn=css/main.css out=style.css && \ - $(M4) index.html.m4 > index.html -endef - -define Package/gluon-status-page/install - $(INSTALL_DIR) $(1)/lib/gluon/status-page/www/ - $(INSTALL_DATA) $(PKG_BUILD_DIR)/index.html $(1)/lib/gluon/status-page/www/ -endef - -$(eval $(call BuildPackage,gluon-status-page)) diff --git a/package/gluon-status-page/iconfont-config.json b/package/gluon-status-page/iconfont-config.json deleted file mode 100644 index af8718cc..00000000 --- a/package/gluon-status-page/iconfont-config.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "name": "statuspage", - "css_prefix_text": "icon-", - "css_use_suffix": false, - "hinting": true, - "units_per_em": 1000, - "ascent": 850, - "glyphs": [ - { - "uid": "12f4ece88e46abd864e40b35e05b11cd", - "css": "ok", - "code": 59397, - "src": "fontawesome" - }, - { - "uid": "5211af474d3a9848f67f945e2ccaf143", - "css": "cancel", - "code": 59399, - "src": "fontawesome" - }, - { - "uid": "e15f0d620a7897e2035c18c80142f6d9", - "css": "link-ext", - "code": 59407, - "src": "fontawesome" - }, - { - "uid": "c76b7947c957c9b78b11741173c8349b", - "css": "attention", - "code": 59403, - "src": "fontawesome" - }, - { - "uid": "559647a6f430b3aeadbecd67194451dd", - "css": "menu", - "code": 59392, - "src": "fontawesome" - }, - { - "uid": "2d6150442079cbda7df64522dc24f482", - "css": "down-dir", - "code": 59393, - "src": "fontawesome" - }, - { - "uid": "80cd1022bd9ea151d554bec1fa05f2de", - "css": "up-dir", - "code": 59394, - "src": "fontawesome" - }, - { - "uid": "9dc654095085167524602c9acc0c5570", - "css": "left-dir", - "code": 59395, - "src": "fontawesome" - }, - { - "uid": "fb1c799ffe5bf8fb7f8bcb647c8fe9e6", - "css": "right-dir", - "code": 59396, - "src": "fontawesome" - }, - { - "uid": "a73c5deb486c8d66249811642e5d719a", - "css": "arrows-cw", - "code": 59400, - "src": "fontawesome" - }, - { - "uid": "750058837a91edae64b03d60fc7e81a7", - "css": "ellipsis-vert", - "code": 59401, - "src": "fontawesome" - }, - { - "uid": "56a21935a5d4d79b2e91ec00f760b369", - "css": "sort", - "code": 59404, - "src": "fontawesome" - }, - { - "uid": "94103e1b3f1e8cf514178ec5912b4469", - "css": "sort-down", - "code": 59405, - "src": "fontawesome" - }, - { - "uid": "65b3ce930627cabfb6ac81ac60ec5ae4", - "css": "sort-up", - "code": 59406, - "src": "fontawesome" - }, - { - "uid": "cda0cdcfd38f5f1d9255e722dad42012", - "css": "spinner", - "code": 59402, - "src": "fontawesome" - } - ] -} \ No newline at end of file diff --git a/package/gluon-status-page/src/build.js b/package/gluon-status-page/src/build.js deleted file mode 100644 index a1b1d703..00000000 --- a/package/gluon-status-page/src/build.js +++ /dev/null @@ -1,10 +0,0 @@ -({ - paths: { - "bacon": "../Bacon" - }, - baseUrl: "js/", - name: "../almond", - include: "main", - optimize: "uglify2", - out: "app.js", -}) diff --git a/package/gluon-status-page/src/css/animation.css b/package/gluon-status-page/src/css/animation.css deleted file mode 100644 index ac5a9562..00000000 --- a/package/gluon-status-page/src/css/animation.css +++ /dev/null @@ -1,85 +0,0 @@ -/* - Animation example, for spinners -*/ -.animate-spin { - -moz-animation: spin 2s infinite linear; - -o-animation: spin 2s infinite linear; - -webkit-animation: spin 2s infinite linear; - animation: spin 2s infinite linear; - display: inline-block; -} -@-moz-keyframes spin { - 0% { - -moz-transform: rotate(0deg); - -o-transform: rotate(0deg); - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - - 100% { - -moz-transform: rotate(359deg); - -o-transform: rotate(359deg); - -webkit-transform: rotate(359deg); - transform: rotate(359deg); - } -} -@-webkit-keyframes spin { - 0% { - -moz-transform: rotate(0deg); - -o-transform: rotate(0deg); - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - - 100% { - -moz-transform: rotate(359deg); - -o-transform: rotate(359deg); - -webkit-transform: rotate(359deg); - transform: rotate(359deg); - } -} -@-o-keyframes spin { - 0% { - -moz-transform: rotate(0deg); - -o-transform: rotate(0deg); - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - - 100% { - -moz-transform: rotate(359deg); - -o-transform: rotate(359deg); - -webkit-transform: rotate(359deg); - transform: rotate(359deg); - } -} -@-ms-keyframes spin { - 0% { - -moz-transform: rotate(0deg); - -o-transform: rotate(0deg); - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - - 100% { - -moz-transform: rotate(359deg); - -o-transform: rotate(359deg); - -webkit-transform: rotate(359deg); - transform: rotate(359deg); - } -} -@keyframes spin { - 0% { - -moz-transform: rotate(0deg); - -o-transform: rotate(0deg); - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - - 100% { - -moz-transform: rotate(359deg); - -o-transform: rotate(359deg); - -webkit-transform: rotate(359deg); - transform: rotate(359deg); - } -} diff --git a/package/gluon-status-page/src/css/font.css b/package/gluon-status-page/src/css/font.css deleted file mode 100644 index c26ee355..00000000 --- a/package/gluon-status-page/src/css/font.css +++ /dev/null @@ -1,53 +0,0 @@ -@font-face { - font-family: 'statuspage'; - src: url(data:application/font-woff;charset=utf-8;base64,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) format('woff'); - font-weight: normal; - font-style: normal; -} - -[class^="icon-"]:before, [class*=" icon-"]:before { - font-family: "statuspage"; - font-style: normal; - font-weight: normal; - speak: none; - - display: inline-block; - text-decoration: inherit; - width: 1em; - margin-right: .2em; - text-align: center; - /* opacity: .8; */ - - /* For safety - reset parent styles, that can break glyph codes*/ - font-variant: normal; - text-transform: none; - - /* fix buttons height, for twitter bootstrap */ - line-height: 1em; - - /* Animation center compensation - margins should be symmetric */ - /* remove if not needed */ - margin-left: .2em; - - /* you can be more comfortable with increased icons size */ - /* font-size: 120%; */ - - /* Uncomment for 3D effect */ - /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */ -} - -.icon-menu:before { content: '\e800'; } /* '' */ -.icon-down-dir:before { content: '\e801'; } /* '' */ -.icon-up-dir:before { content: '\e802'; } /* '' */ -.icon-left-dir:before { content: '\e803'; } /* '' */ -.icon-right-dir:before { content: '\e804'; } /* '' */ -.icon-ok:before { content: '\e805'; } /* '' */ -.icon-cancel:before { content: '\e807'; } /* '' */ -.icon-arrows-cw:before { content: '\e808'; } /* '' */ -.icon-ellipsis-vert:before { content: '\e809'; } /* '' */ -.icon-spinner:before { content: '\e80a'; } /* '' */ -.icon-attention:before { content: '\e80b'; } /* '' */ -.icon-sort:before { content: '\e80c'; } /* '' */ -.icon-sort-down:before { content: '\e80d'; } /* '' */ -.icon-sort-up:before { content: '\e80e'; } /* '' */ -.icon-link-ext:before { content: '\e80f'; } /* '' */ diff --git a/package/gluon-status-page/src/css/main.css b/package/gluon-status-page/src/css/main.css deleted file mode 100644 index 0604802e..00000000 --- a/package/gluon-status-page/src/css/main.css +++ /dev/null @@ -1,171 +0,0 @@ -@import "reset.css"; -@import "font.css"; -@import "menu.css"; -@import "animation.css"; - -body { - background: rgba(0, 0, 0, 0.12); - font-family: Roboto, Lucida Grande, sans, Arial; - color: rgba(0, 0, 0, 0.87); - font-size: 14px; -} - - -a { - color: rgba(220, 0, 103, 0.87); - text-decoration: none; -} - -a:hover { - text-decoration: underline; -} - -header { - display: flex; - padding: 0 14px; - background: #dc0067; - color: rgba(255, 255, 255, 0.98); - position: absolute; - top: 0; - width: 100%; - box-sizing: border-box; - height: 20vh; - z-index: -1; - box-shadow: 0px 5px 6px rgba(0, 0, 0, 0.16), 0px 1.5px 3px rgba(0, 0, 0, 0.23); - white-space: nowrap; -} - -header h1, header .icons { - font-size: 24px; - margin: 10px 0; - padding: 6px 0; -} - -header h1 { - text-overflow: ellipsis; - overflow: hidden; - flex: 1; -} - -header h1:hover { - text-decoration: underline; - cursor: pointer; -} - -h1 { - font-weight: bold; -} - -h2, h3 { - font-size: 16px; - color: rgba(0, 0, 0, 0.54); -} - -h2 { - padding: 16px 16px; -} - -h3 { - padding: 16px 16px 8px; -} - -.container { - max-width: 90vw; - margin: 64px auto 24px auto; - background: rgb(253, 253, 253); - box-shadow: 0px 5px 20px rgba(0, 0, 0, 0.19), 0px 3px 6px rgba(0, 0, 0, 0.23); -} - -.container .frame { - box-sizing: border-box; -} - -.vertical-split { - display: flex; -} - -.vertical-split > .frame { - flex: 1; - border-style: solid; - border-color: rgba(0, 0, 0, 0.12); -} - -.vertical-split > .frame + .frame { - border-width: 0 0 0 1px; -} - -dl, pre { - padding: 0 16px 16px; -} - -table { - margin: 0 16px; -} - -dt, th { - font-weight: bold; - color: rgba(0, 0, 0, 0.87); -} - -dt { - margin-bottom: 4px; -} - -th { - text-align: left; - padding: 4px 16px 4px 0; -} - -dd, td { - font-weight: normal; - font-size: 0.9em; - color: rgba(0, 0, 0, 0.54); -} - -dd { - padding-bottom: 16px; -} - -table.datatable { - width: calc(100% - 32px); -} - -table.datatable td { - font-size: 1em; - padding: 4px 0; -} - -table.datatable tr.inactive { - opacity: 0.33; -} - -table.datatable tr.highlight { - background: rgba(255, 180, 0, 0.25); -} - -div.signalgraph { - margin: 16px; -} - -@media only screen and (max-width: 1250px) { - .container { - max-width: none; - margin: 56px 0 0; - } - - header { - height: 56px; - z-index: 1; - position: fixed; - } -} - -@media only screen and (max-width: 700px) { - .vertical-split { - display: block; - } - - .vertical-split > .frame + .frame { - border-width: 1px 0 0 0; - } -} diff --git a/package/gluon-status-page/src/css/menu.css b/package/gluon-status-page/src/css/menu.css deleted file mode 100644 index c865c648..00000000 --- a/package/gluon-status-page/src/css/menu.css +++ /dev/null @@ -1,60 +0,0 @@ -.noscroll { - overflow: hidden; -} - -.menu-background { - position: fixed; - top: 0; - left: 0; - width: 100vw; - height: 100vh; - z-index: 10; -} - -.menu { - background: rgba(255, 255, 255, 1); - position: fixed; - z-index: 11; - padding: 8px 0; - box-shadow: 0 1px 6px rgba(0, 0, 0, 0.12), 0 1px 4px rgba(0, 0, 0, 0.24); - overflow-y: auto; - max-height: 80vh; - - transform-origin: top left; - -webkit-animation: new-menu-animation .08s ease-out forwards; - -moz-animation: new-menu-animation .08s ease-out forwards; -} - -@-webkit-keyframes new-menu-animation { - from { - transform: scaleY(0); - } - to { - transform: scaleY(1); - } -} - -@-moz-keyframes new-menu-animation { - from { - transform: scaleY(0); - } - to { - transform: scaleY(1); - } -} - -.menu li { - cursor: pointer; - display: block; - font-size: 16px; - padding: 16px 32px 16px 16px; - color: rgba(0, 0, 0, 0.87); -} - -.menu li:hover { - background: rgba(0, 0, 0, 0.07); -} - -.menu li:active { - background: rgba(0, 0, 0, 0.07); -} diff --git a/package/gluon-status-page/src/css/reset.css b/package/gluon-status-page/src/css/reset.css deleted file mode 100644 index f6ca1484..00000000 --- a/package/gluon-status-page/src/css/reset.css +++ /dev/null @@ -1,86 +0,0 @@ -/* -html5doctor.com Reset Stylesheet v1.6.1 -Last Updated: 2010-09-17 -Author: Richard Clark - http://richclarkdesign.com -*/ -html, body, div, span, object, iframe, -h1, h2, h3, h4, h5, h6, p, blockquote, pre, -abbr, address, cite, code, -del, dfn, em, img, ins, kbd, q, samp, -small, strong, sub, sup, var, -b, i, -dl, dt, dd, ol, ul, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td, -article, aside, canvas, details, figcaption, figure, -footer, header, hgroup, menu, nav, section, summary, -time, mark, audio, video { - margin:0; - padding:0; - border:0; - outline:0; - font-size:100%; - vertical-align:baseline; - background:transparent; -} -body { - line-height:1; -} -article,aside,details,figcaption,figure, -footer,header,hgroup,menu,nav,section { - display:block; -} -nav ul { - list-style:none; -} -blockquote, q { - quotes:none; -} -blockquote:before, blockquote:after, -q:before, q:after { - content:''; - content:none; -} -a { - margin:0; - padding:0; - font-size:100%; - vertical-align:baseline; - background:transparent; -} -/* change colours to suit your needs */ -ins { - background-color:#ff9; - color:#000; - text-decoration:none; -} -/* change colours to suit your needs */ -mark { - background-color:#ff9; - color:#000; - font-style:italic; - font-weight:bold; -} -del { - text-decoration: line-through; -} -abbr[title], dfn[title] { - border-bottom:1px dotted; - cursor:help; -} -table { - border-collapse:collapse; - border-spacing:0; -} -/* change border colour to suit your needs */ -hr { - display:block; - height:1px; - border:0; - border-top:1px solid #cccccc; - margin:1em 0; - padding:0; -} -input, select { - vertical-align:middle; -} diff --git a/package/gluon-status-page/src/index.html.m4 b/package/gluon-status-page/src/index.html.m4 deleted file mode 100644 index 489c1cf0..00000000 --- a/package/gluon-status-page/src/index.html.m4 +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - diff --git a/package/gluon-status-page/src/js/lib/gui.js b/package/gluon-status-page/src/js/lib/gui.js deleted file mode 100644 index 3d771005..00000000 --- a/package/gluon-status-page/src/js/lib/gui.js +++ /dev/null @@ -1,157 +0,0 @@ -"use strict" -define([ "lib/gui/nodeinfo" - , "lib/gui/statistics" - , "lib/gui/neighbours" - , "lib/gui/menu" - , "lib/streams" - , "lib/neighbourstream" - ], function ( NodeInfo - , Statistics - , Neighbours - , Menu - , Streams - , NeighbourStream - ) { - - function VerticalSplit(parent) { - var el = document.createElement("div") - el.className = "vertical-split" - parent.appendChild(el) - - el.push = function (child) { - var header = document.createElement("h2") - header.appendChild(child.title) - - var div = document.createElement("div") - div.className = "frame" - div.node = child - div.appendChild(header) - - el.appendChild(div) - - child.render(div) - - return function () { - div.node.destroy() - el.removeChild(div) - } - } - - el.clear = function () { - while (el.firstChild) { - el.firstChild.node.destroy() - el.removeChild(el.firstChild) - } - } - - return el - } - - var h1 - - return function (mgmtBus, nodesBus) { - function setTitle(node, state) { - var title = node ? node.hostname : "(not connected)" - - document.title = title - h1.textContent = title - - var icon = document.createElement("i") - icon.className = "icon-down-dir" - - h1.appendChild(icon) - - switch (state) { - case "connect": - stateIcon.className = "icon-arrows-cw animate-spin" - break - case "fail": - stateIcon.className = "icon-attention" - break - default: - stateIcon.className = "" - break - } - } - - var nodes = [] - - function nodeMenu() { - var myNodes = nodes.slice() - - myNodes.sort(function (a, b) { - a = a.hostname - b = b.hostname - return (a < b) ? -1 : (a > b) - }) - - var menu = myNodes.map(function (d) { - return [d.hostname, function () { - mgmtBus.pushEvent("goto", d) - }] - }) - - new Menu(menu).apply(this) - } - - var header = document.createElement("header") - h1 = document.createElement("h1") - header.appendChild(h1) - - h1.onclick = nodeMenu - - var icons = document.createElement("p") - icons.className = "icons" - header.appendChild(icons) - - var stateIcon = document.createElement("i") - icons.appendChild(stateIcon) - - document.body.appendChild(header) - - var container = document.createElement("div") - container.className = "container" - - document.body.appendChild(container) - - setTitle() - - var content = new VerticalSplit(container) - - function nodeChanged(nodeInfo) { - setTitle(nodeInfo, "connect") - - content.clear() - content.push(new NodeInfo(nodeInfo)) - } - - function nodeNotArrived(nodeInfo) { - setTitle(nodeInfo, "fail") - } - - function nodeArrived(nodeInfo, ip) { - setTitle(nodeInfo) - - var neighbourStream = new NeighbourStream(mgmtBus, nodesBus, ip) - var statisticsStream = new Streams.Statistics(ip) - - content.push(new Statistics(statisticsStream)) - content.push(new Neighbours(nodeInfo, neighbourStream, mgmtBus)) - } - - function newNodes(d) { - nodes = [] - for (var nodeId in d) - nodes.push(d[nodeId]) - } - - mgmtBus.onEvent({ "goto": nodeChanged - , "arrived": nodeArrived - , "gotoFailed": nodeNotArrived - }) - - nodesBus.map(".nodes").onValue(newNodes) - - return this - } -}) diff --git a/package/gluon-status-page/src/js/lib/gui/menu.js b/package/gluon-status-page/src/js/lib/gui/menu.js deleted file mode 100644 index 712f2d0f..00000000 --- a/package/gluon-status-page/src/js/lib/gui/menu.js +++ /dev/null @@ -1,39 +0,0 @@ -"use strict" -define(function () { - return function (menu) { - return function () { - var background = document.createElement("div") - background.className = "menu-background" - document.body.appendChild(background) - document.body.classList.add("noscroll") - - var offset = this.getBoundingClientRect() - var container = document.createElement("ul") - container.className = "menu" - container.style.top = offset.top + "px" - container.style.left = offset.left + "px" - - background.onclick = destroy - - menu.forEach(function (item) { - var li = document.createElement("li") - li.textContent = item[0] - li.action = item[1] - li.onclick = function () { - destroy() - this.action() - } - - container.appendChild(li) - }) - - document.body.appendChild(container) - - function destroy() { - document.body.classList.remove("noscroll") - document.body.removeChild(background) - document.body.removeChild(container) - } - } - } -}) diff --git a/package/gluon-status-page/src/js/lib/gui/neighbours.js b/package/gluon-status-page/src/js/lib/gui/neighbours.js deleted file mode 100644 index ff782506..00000000 --- a/package/gluon-status-page/src/js/lib/gui/neighbours.js +++ /dev/null @@ -1,282 +0,0 @@ -"use strict" -define([ "lib/helper", "lib/gui/signalgraph", "lib/gui/signal"], -function (Helper, SignalGraph, Signal) { - - var graphColors = ["#396AB1", "#DA7C30", "#3E9651", "#CC2529", "#535154", "#6B4C9A", "#922428", "#948B3D"] - //graphColors = ["#7293CB", "#E1974C", "#84BA5B", "#D35E60", "#808585", "#9067A7", "#AB6857", "#CCC210"]; - - var inactiveTime = 200 - - function SignalEntry(graph, color, stream) { - var signal = new Signal(color) - var remove = graph.add(signal) - - var unsubscribe = stream.onValue(update) - - this.destroy = function () { - unsubscribe() - remove() - } - - this.getSignal = function () { - return signal - } - - return this - - function update(d) { - if ("wifi" in d) - signal.set(d.wifi.inactive > inactiveTime ? null : d.wifi.signal) - } - } - - function TableEntry(parent, nodeInfo, color, stream, mgmtBus, signal) { - var el = document.createElement("tr") - parent.appendChild(el) - - var tdHostname = document.createElement("td") - var tdTQ = document.createElement("td") - var tdSignal = document.createElement("td") - var tdDistance = document.createElement("td") - var tdInactive = document.createElement("td") - - el.appendChild(tdHostname) - el.appendChild(tdTQ) - el.appendChild(tdSignal) - el.appendChild(tdDistance) - el.appendChild(tdInactive) - - var marker = document.createElement("span") - marker.textContent = "⬤ " - marker.style.color = color - tdHostname.appendChild(marker) - - var hostname = document.createElement("span") - tdHostname.appendChild(hostname) - - var infoSet = false - var unsubscribe = stream.onValue(update) - - el.onmouseenter = function () { - el.classList.add("highlight") - signal.setHighlight(true) - } - - el.onmouseleave = function () { - el.classList.remove("highlight") - signal.setHighlight(false) - } - - el.destroy = function () { - unsubscribe() - parent.removeChild(el) - } - - return el - - function update(d) { - if ("wifi" in d) { - var signal = d.wifi.signal - var inactive = d.wifi.inactive - - el.classList.toggle("inactive", inactive > inactiveTime) - - tdSignal.textContent = signal - tdInactive.textContent = Math.round(inactive / 1000) + " s" - } - - if ("batadv" in d) - tdTQ.textContent = Math.round(d.batadv.tq / 2.55) + " %" - else - tdTQ.textContent = "‒" - - if (infoSet) - return - - if ("nodeInfo" in d) { - infoSet = true - - var link = document.createElement("a") - link.textContent = d.nodeInfo.hostname - link.href = "#" - link.nodeInfo = d.nodeInfo - link.onclick = function () { - mgmtBus.pushEvent("goto", this.nodeInfo) - return false - } - - while (hostname.firstChild) - hostname.removeChild(hostname.firstChild) - - hostname.appendChild(link) - - try { - var distance = Helper.haversine(nodeInfo.location.latitude, nodeInfo.location.longitude, - d.nodeInfo.location.latitude, d.nodeInfo.location.longitude) - - tdDistance.textContent = Math.round(distance * 1000) + " m" - } catch (e) { - tdDistance.textContent = "‒" - } - } else - hostname.textContent = d.id - } - } - - function Interface(parent, nodeInfo, iface, stream, mgmtBus) { - var colors = graphColors.slice(0) - - var el = document.createElement("div") - el.ifname = iface - parent.appendChild(el) - - var h = document.createElement("h3") - h.textContent = iface - el.appendChild(h) - - var table = document.createElement("table") - var tr = document.createElement("tr") - table.appendChild(tr) - table.classList.add("datatable") - - var th = document.createElement("th") - th.textContent = "Knoten" - tr.appendChild(th) - - th = document.createElement("th") - th.textContent = "TQ" - tr.appendChild(th) - - th = document.createElement("th") - th.textContent = "dBm" - tr.appendChild(th) - - th = document.createElement("th") - th.textContent = "Entfernung" - tr.appendChild(th) - - th = document.createElement("th") - th.textContent = "Inaktiv" - tr.appendChild(th) - - el.appendChild(table) - - var wrapper = document.createElement("div") - wrapper.className = "signalgraph" - el.appendChild(wrapper) - - var canvas = document.createElement("canvas") - canvas.className = "signal-history" - canvas.height = 200 - wrapper.appendChild(canvas) - - var graph = new SignalGraph(canvas, -100, 0, true) - - var stopStream = stream.skipDuplicates(sameKeys).onValue(update) - - var managedNeighbours = {} - - function update(d) { - var notUpdated = new Set() - var id - - for (id in managedNeighbours) - notUpdated.add(id) - - for (id in d) { - if (!(id in managedNeighbours)) { - var neighbourStream = stream.map("." + id).filter( function (d) { return d !== undefined }) - var color = colors.shift() - var signal = new SignalEntry(graph, color, neighbourStream) - managedNeighbours[id] = { views: [ signal, - new TableEntry(table, nodeInfo, color, neighbourStream, mgmtBus, signal.getSignal()) - ], - color: color - } - } - - notUpdated.delete(id) - } - - notUpdated.forEach(function (id) { - managedNeighbours[id].views.forEach( function (d) { d.destroy() }) - colors.push(managedNeighbours[id].color) - delete managedNeighbours[id] - }) - } - - - el.destroy = function () { - stopStream() - - for (var id in managedNeighbours) - managedNeighbours[id].views.forEach( function (d) { d.destroy() }) - - el.removeChild(h) - el.removeChild(wrapper) - el.removeChild(table) - } - } - - function sameKeys(a, b) { - a = Object.keys(a).sort() - b = Object.keys(b).sort() - - return !(a < b || a > b) - } - - function getter(k) { - return function(obj) { - return obj[k] - } - } - - return function (nodeInfo, stream, mgmtBus) { - var stopStream, div - - function render(el) { - div = document.createElement("div") - el.appendChild(div) - - stopStream = stream.skipDuplicates(sameKeys).onValue(update) - - function update(d) { - var have = {} - var remove = [] - if (div.hasChildNodes()) { - var children = div.childNodes - for (var i = 0; i < children.length; i++) { - var a = children[i] - if (a.ifname in d) - have[a.ifname] = true - else { - a.destroy() - remove.push(a) - } - } - } - - remove.forEach(function (d) { div.removeChild(d) }) - - for (var k in d) { - if (!(k in have)) - new Interface(div, nodeInfo, k, stream.map(getter(k)), mgmtBus) - } - } - } - - function destroy() { - stopStream() - - while (div.firstChild) { - div.firstChild.destroy() - div.removeChild(div.firstChild) - } - } - - return { title: document.createTextNode("Nachbarknoten") - , render: render - , destroy: destroy - } - } -}) diff --git a/package/gluon-status-page/src/js/lib/gui/nodeinfo.js b/package/gluon-status-page/src/js/lib/gui/nodeinfo.js deleted file mode 100644 index 75910aae..00000000 --- a/package/gluon-status-page/src/js/lib/gui/nodeinfo.js +++ /dev/null @@ -1,54 +0,0 @@ -"use strict" -define(["lib/helper"], function (Helper) { - return function (nodeInfo) { - var el = document.createElement("div") - - update(nodeInfo) - - function dlEntry(dl, dict, key, prettyName) { - var v = Helper.dictGet(dict, key.split(".")) - - if (v === null) - return - - var dt = document.createElement("dt") - var dd = document.createElement("dd") - - dt.textContent = prettyName - if (v instanceof Array) { - var tn = v.map(function (d) { return document.createTextNode(d) }) - tn.forEach(function (node) { - if (dd.hasChildNodes()) - dd.appendChild(document.createElement("br")) - - dd.appendChild(node) - }) - } else - dd.textContent = v - - dl.appendChild(dt) - dl.appendChild(dd) - } - - function update(nodeInfo) { - var list = document.createElement("dl") - - dlEntry(list, nodeInfo, "hostname", "Knotenname") - dlEntry(list, nodeInfo, "owner.contact", "Kontakt") - dlEntry(list, nodeInfo, "hardware.model", "Modell") - dlEntry(list, nodeInfo, "network.mac", "Primäre MAC") - dlEntry(list, nodeInfo, "network.addresses", "IP-Adresse") - dlEntry(list, nodeInfo, "software.firmware.release", "Firmware") - dlEntry(list, nodeInfo, "software.fastd.enabled", "Mesh-VPN") - dlEntry(list, nodeInfo, "software.autoupdater.enabled", "Automatische Updates") - dlEntry(list, nodeInfo, "software.autoupdater.branch", "Branch") - - el.appendChild(list) - } - - return { title: document.createTextNode("Übersicht") - , render: function (d) { d.appendChild(el) } - , destroy: function () {} - } - } -}) diff --git a/package/gluon-status-page/src/js/lib/gui/signal.js b/package/gluon-status-page/src/js/lib/gui/signal.js deleted file mode 100644 index d91c63fb..00000000 --- a/package/gluon-status-page/src/js/lib/gui/signal.js +++ /dev/null @@ -1,48 +0,0 @@ -"use strict" -define(function () { - return function (color) { - var canvas = document.createElement("canvas") - var ctx = canvas.getContext("2d") - var v = null - var radius = 1.2 - var highlight = false - - function drawPixel(x, y) { - ctx.beginPath() - ctx.fillStyle = color - ctx.arc(x, y, radius, 0, Math.PI * 2, false) - ctx.closePath() - ctx.fill() - } - - this.resize = function (w, h) { - canvas.width = w - canvas.height = h - } - - this.draw = function (x, scale) { - var y = scale(v) - - ctx.clearRect(x, 0, 5, canvas.height) - - if (y) - drawPixel(x, y) - } - - this.canvas = canvas - - this.set = function (d) { - v = d - } - - this.setHighlight = function (d) { - highlight = d - } - - this.getHighlight = function () { - return highlight - } - - return this - } -}) diff --git a/package/gluon-status-page/src/js/lib/gui/signalgraph.js b/package/gluon-status-page/src/js/lib/gui/signalgraph.js deleted file mode 100644 index 231ce628..00000000 --- a/package/gluon-status-page/src/js/lib/gui/signalgraph.js +++ /dev/null @@ -1,137 +0,0 @@ -"use strict" -define(function () { - return function (canvas, min, max) { - var i = 0 - var graphWidth - var last = 0 - - var signals = [] - - var ctx = canvas.getContext("2d") - - resize() - - window.addEventListener("resize", resize, false) - window.requestAnimationFrame(step) - - function step(timestamp) { - var delta = timestamp - last - - if (delta > 40) { - draw() - last = timestamp - } - - window.requestAnimationFrame(step) - } - - function drawGrid() { - var gridctx = ctx - var nLines = Math.floor(canvas.height / 40) - gridctx.save() - gridctx.lineWidth = 0.5 - gridctx.strokeStyle = "rgba(0, 0, 0, 0.25)" - gridctx.fillStyle = "rgba(0, 0, 0, 0.5)" - gridctx.textAlign = "end" - gridctx.textBaseline = "bottom" - - gridctx.beginPath() - - for (var i = 0; i < nLines; i++) { - var y = canvas.height - i * 40 - gridctx.moveTo(0, y - 0.5) - gridctx.lineTo(canvas.width, y - 0.5) - var dBm = Math.round(scaleInverse(y, min, max, canvas.height)) + " dBm" - - gridctx.save() - gridctx.strokeStyle = "rgba(255, 255, 255, 0.9)" - gridctx.lineWidth = 4 - gridctx.miterLimit = 2 - gridctx.strokeText(dBm, canvas.width - 5, y - 2.5) - gridctx.fillText(dBm, canvas.width - 5, y - 2.5) - gridctx.restore() - } - - gridctx.stroke() - - gridctx.strokeStyle = "rgba(0, 0, 0, 0.83)" - gridctx.lineWidth = 1.5 - gridctx.strokeRect(0.5, 0.5, canvas.width - 1, canvas.height - 1) - - gridctx.restore() - } - - function draw() { - var anyHighlight = signals.some( function (d) { return d.getHighlight() }) - - signals.forEach( function (d) { - d.draw(i, function (v) { - return scale(v, min, max, canvas.height) - }) - }) - - ctx.clearRect(0, 0, canvas.width, canvas.height) - - ctx.save() - - signals.forEach( function (d) { - if (anyHighlight) - ctx.globalAlpha = 0.1 - - if (d.getHighlight()) - ctx.globalAlpha = 1 - - ctx.drawImage(d.canvas, 0, 0) - }) - - ctx.restore() - - ctx.save() - ctx.beginPath() - ctx.strokeStyle = "rgba(255, 180, 0, 0.15)" - ctx.lineWidth = 5 - ctx.moveTo(i + 2.5, 0) - ctx.lineTo(i + 2.5, canvas.height) - ctx.stroke() - - drawGrid() - - i = (i + 1) % graphWidth - } - - function scaleInverse(n, min, max, height) { - return (min * n + max * height - max * n) / height - } - - function scale(n, min, max, height) { - return (1 - (n - min) / (max - min)) * height - } - - function resize() { - var newWidth = canvas.parentNode.clientWidth - - if (newWidth === 0 || newWidth === canvas.width) - return - - var lastImage = ctx.getImageData(0, 0, newWidth, canvas.height) - canvas.width = newWidth - graphWidth = canvas.width - ctx.putImageData(lastImage, 0, 0) - - signals.forEach( function (d) { - d.resize(canvas.width, canvas.height) - }) - } - - this.add = function (d) { - signals.push(d) - d.resize(canvas.width, canvas.height) - - return function () { - signals = signals.filter( function (e) { return e !== d } ) - } - } - - return this - } -}) diff --git a/package/gluon-status-page/src/js/lib/gui/statistics.js b/package/gluon-status-page/src/js/lib/gui/statistics.js deleted file mode 100644 index 59a7c560..00000000 --- a/package/gluon-status-page/src/js/lib/gui/statistics.js +++ /dev/null @@ -1,285 +0,0 @@ -"use strict" -define(["lib/helper"], function (Helper) { - function streamElement(type, stream) { - var el = document.createElement(type) - el.destroy = stream.onValue(update) - - function update(d) { - el.textContent = d - } - - return el - } - - function streamNode(stream) { - var el = document.createTextNode("") - el.destroy = stream.onValue(update) - - function update(d) { - el.textContent = d - } - - return el - } - - function mkRow(table, label, stream, sorted) { - - var i = -1 - - if (sorted) { - for (i = 0; i < table.rows.length; i++) { - if (label < table.rows[i].firstChild.textContent) - break - } - } - - var tr = table.insertRow(i) - var th = document.createElement("th") - var td = streamElement("td", stream) - th.textContent = label - tr.appendChild(th) - tr.appendChild(td) - - tr.destroy = function () { - td.destroy() - table.tBodies[0].removeChild(tr) - } - - return tr - } - - function mkTrafficRow(table, children, label, stream, selector) { - var tr = document.createElement("tr") - var th = document.createElement("th") - var td = document.createElement("td") - th.textContent = label - - var traffic = stream.slidingWindow(2, 2) - var pkts = streamNode(traffic.map(deltaUptime(selector + ".packets")).map(prettyPackets)) - var bw = streamNode(traffic.map(deltaUptime(selector + ".bytes")).map(prettyBits)) - var bytes = streamNode(stream.map(selector).map(".bytes").map(prettyBytes)) - - td.appendChild(pkts) - td.appendChild(document.createElement("br")) - td.appendChild(bw) - td.appendChild(document.createElement("br")) - td.appendChild(bytes) - - tr.appendChild(th) - tr.appendChild(td) - table.appendChild(tr) - - children.push(pkts) - children.push(bw) - children.push(bytes) - } - - function mkMeshVPN(el, stream) { - var children = {} - var init = false - var h = document.createElement("h3") - h.textContent = "Mesh-VPN" - - var table = document.createElement("table") - - var unsubscribe = stream.onValue( function (d) { - function addPeer(peer, path) { - return { peer: peer, path: path } - } - - function addPeers(d, path) { - if (!("peers" in d)) - return [] - - var peers = [] - - for (var peer in d.peers) - peers.push(addPeer(peer, path + ".peers." + peer)) - - return peers - } - - function addGroup(d, path) { - var peers = [] - - peers = peers.concat(addPeers(d, path)) - - if ("groups" in d) - for (var group in d.groups) - peers = peers.concat(addGroup(d.groups[group], path + ".groups." + group)) - - return peers - } - - if (d === undefined) - clear() - - else { - if (!init) { - init = true - el.appendChild(h) - el.appendChild(table) - } - - var peers = addGroup(d, "") - var paths = new Set(peers.map(function (d) { return d.path } )) - - for (var path in children) - if (!paths.has(path)) { - children[path].destroy() - delete children[path] - } - - peers.forEach( function (peer) { - if (!(peer.path in children)) - children[peer.path] = mkRow(table, peer.peer, - stream.startWith(d) - .map(peer.path) - .filter(function (d) { return d !== undefined }) - .map(prettyPeer), true) - }) - } - }) - - function clear() { - if (init) { - init = false - el.removeChild(h) - el.removeChild(table) - } - - for (var peer in children) - children[peer].destroy() - - children = {} - } - - function destroy() { - unsubscribe() - clear() - } - - return { destroy: destroy } - } - - function deltaUptime(selector) { - return function (d) { - var deltaTime = d[1].uptime - d[0].uptime - var d0 = Helper.dictGet(d[0], selector.split(".").splice(1)) - var d1 = Helper.dictGet(d[1], selector.split(".").splice(1)) - - return (d1 - d0) / deltaTime - } - } - - function prettyPeer(d) { - if (d === null) - return "nicht verbunden" - else - return "verbunden (" + prettyUptime(d.established) + ")" - } - - function prettyPackets(d) { - var v = Helper.formatNumberFixed(d, 0) - return v + " Pakete/s" - } - - function prettyPrefix(prefixes, step, d) { - var prefix = 0 - - while (d > step && prefix < prefixes.length - 1) { - d /= step - prefix++ - } - - d = Helper.formatNumber(d, 3) - return d + " " + prefixes[prefix] - } - - function prettySize(d) { - return prettyPrefix([ "", "k", "M", "G", "T" ], 1024, d) - } - - function prettyBits(d) { - return prettySize(d * 8) + "bps" - } - - function prettyBytes(d) { - return prettySize(d) + "B" - } - - function prettyUptime(seconds) { - var minutes = Math.round(seconds / 60) - - var days = Math.floor(minutes / 1440) - var hours = Math.floor((minutes % 1440) / 60) - minutes = Math.floor(minutes % 60) - - var out = "" - - if (days === 1) - out += "1 Tag, " - else if (days > 1) - out += days + " Tage, " - - out += hours + ":" - - if (minutes < 10) - out += "0" - - out += minutes - - return out - } - - function prettyNVRAM(usage) { - return Helper.formatNumber(usage * 100, 3) + "% belegt" - } - - function prettyLoad(load) { - return Helper.formatNumberFixed(load, 2) - } - - function prettyRAM(memory) { - var usage = 1 - (memory.free + memory.buffers + memory.cached) / memory.total - return prettyNVRAM(usage) - } - - return function (stream) { - var children = [] - var el = document.createElement("div") - var table = document.createElement("table") - - children.push(mkRow(table, "Laufzeit", stream.map(".uptime").map(prettyUptime))) - children.push(mkRow(table, "Systemlast", stream.map(".loadavg").map(prettyLoad))) - children.push(mkRow(table, "RAM", stream.map(".memory").map(prettyRAM))) - children.push(mkRow(table, "NVRAM", stream.map(".rootfs_usage").map(prettyNVRAM))) - children.push(mkRow(table, "Gateway", stream.map(".gateway"))) - children.push(mkRow(table, "Clients", stream.map(".clients.total"))) - - el.appendChild(table) - - var h = document.createElement("h3") - h.textContent = "Traffic" - el.appendChild(h) - - table = document.createElement("table") - - mkTrafficRow(table, children, "Gesendet", stream, ".traffic.tx") - mkTrafficRow(table, children, "Empfangen", stream, ".traffic.rx") - mkTrafficRow(table, children, "Weitergeleitet", stream, ".traffic.forward") - - el.appendChild(table) - - children.push(mkMeshVPN(el, stream.map(".mesh_vpn"))) - - function destroy() { - children.forEach(function (d) {d.destroy()}) - } - - return { title: document.createTextNode("Statistik") - , render: function (d) { d.appendChild(el) } - , destroy: destroy - } - } -}) diff --git a/package/gluon-status-page/src/js/lib/helper.js b/package/gluon-status-page/src/js/lib/helper.js deleted file mode 100644 index c0c0ce2f..00000000 --- a/package/gluon-status-page/src/js/lib/helper.js +++ /dev/null @@ -1,92 +0,0 @@ -"use strict" -define([ "bacon" ], function (Bacon) { - function get(url) { - return Bacon.fromBinder(function(sink) { - var req = new XMLHttpRequest() - req.open("GET", url) - - req.onload = function() { - if (req.status === 200) - sink(new Bacon.Next(req.response)) - else - sink(new Bacon.Error(req.statusText)) - sink(new Bacon.End()) - } - - req.onerror = function() { - sink(new Bacon.Error("network error")) - sink(new Bacon.End()) - } - - req.send() - - return function () {} - }) - } - - function getJSON(url) { - return get(url).map(JSON.parse) - } - - function buildUrl(ip, object, param) { - var url = "http://[" + ip + "]/cgi-bin/" + object - if (param) url += "?" + param - - return url - } - - function request(ip, object, param) { - return getJSON(buildUrl(ip, object, param)) - } - - function dictGet(dict, key) { - var k = key.shift() - - if (!(k in dict)) - return null - - if (key.length === 0) - return dict[k] - - return dictGet(dict[k], key) - } - - function localizeNumber(d) { - var sep = ',' - return d.replace('.', sep) - } - - function formatNumberFixed(d, digits) { - return localizeNumber(d.toFixed(digits)) - } - - function formatNumber(d, digits) { - digits-- - - for (var v = d; v >= 10 && digits > 0; v /= 10) - digits-- - - // avoid toPrecision as it might produce strings in exponential notation - return formatNumberFixed(d, digits) - } - - function haversine() { - var radians = Array.prototype.map.call(arguments, function(deg) { return deg / 180.0 * Math.PI }) - var lat1 = radians[0], lon1 = radians[1], lat2 = radians[2], lon2 = radians[3] - var R = 6372.8 // km - var dLat = lat2 - lat1 - var dLon = lon2 - lon1 - var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2) - var c = 2 * Math.asin(Math.sqrt(a)) - return R * c - } - - return { buildUrl: buildUrl - , request: request - , getJSON: getJSON - , dictGet: dictGet - , formatNumber: formatNumber - , formatNumberFixed: formatNumberFixed - , haversine: haversine - } -}) diff --git a/package/gluon-status-page/src/js/lib/neighbourstream.js b/package/gluon-status-page/src/js/lib/neighbourstream.js deleted file mode 100644 index dbe42a34..00000000 --- a/package/gluon-status-page/src/js/lib/neighbourstream.js +++ /dev/null @@ -1,132 +0,0 @@ -"use strict" -define([ "bacon" - , "lib/helper" - , "lib/streams" - ], function(Bacon, Helper, Streams) { - - return function (mgmtBus, nodesBus, ip) { - function nodeQuerier() { - var asked = {} - var timeout = 6000 - - return function (ifname) { - var now = new Date().getTime() - - if (ifname in asked && now - asked[ifname] < timeout) - return Bacon.never() - - asked[ifname] = now - return Streams.nodeInfo(ip, ifname).map(function (d) { - return { "ifname": ifname - , "nodeInfo": d - } - }) - } - } - - var querierAsk = new Bacon.Bus() - var querier = querierAsk.flatMap(nodeQuerier()) - querier.map(".nodeInfo").onValue(mgmtBus, "pushEvent", "nodeinfo") - - function wrapIfname(ifname, d) { - return [ifname, d] - } - - function extractIfname(d) { - var r = {} - - for (var station in d) { - var ifname = d[station].ifname - delete d[station].ifname - - if (!(ifname in r)) - r[ifname] = {} - - r[ifname][station] = d[station] - } - - return r - } - - function stationsStream(ifname) { - return new Streams.Stations(ip, ifname).map(wrapIfname, ifname) - } - - function magic(interfaces) { - var ifnames = Object.keys(interfaces) - ifnames.forEach(querierAsk.push) - - var wifiStream = Bacon.fromArray(ifnames) - .flatMap(stationsStream) - .scan({}, function (a, b) { - a[b[0]] = b[1] - return a - }) - - var batadvStream = new Streams.Batadv(ip).toProperty({}) - - return Bacon.combineWith(combine, wifiStream - , batadvStream.map(extractIfname) - , nodesBus.map(".macs") - ) - } - - function combine(wifi, batadv, macs) { - var interfaces = combineWithIfnames(wifi, batadv) - - for (var ifname in interfaces) { - var stations = interfaces[ifname] - for (var station in stations) { - stations[station].id = station - - if (station in macs) - stations[station].nodeInfo = macs[station] - else - querierAsk.push(ifname) - } - } - - return interfaces - } - - function combineWithIfnames(wifi, batadv) { - var ifnames = Object.keys(wifi).concat(Object.keys(batadv)) - - // remove duplicates - ifnames.filter(function(e, i) { - return ifnames.indexOf(e) === i - }) - - var out = {} - - ifnames.forEach(function (ifname) { - out[ifname] = combineWifiBatadv(wifi[ifname], batadv[ifname]) - }) - - return out - } - - function combineWifiBatadv(wifi, batadv) { - var station - var out = {} - - for (station in batadv) { - if (!(station in out)) - out[station] = {} - - out[station].batadv = batadv[station] - } - - for (station in wifi) { - if (!(station in out)) - out[station] = {} - - out[station].wifi = wifi[station] - } - - return out - } - - return Helper.request(ip, "interfaces").flatMap(magic) - } -}) diff --git a/package/gluon-status-page/src/js/lib/streams.js b/package/gluon-status-page/src/js/lib/streams.js deleted file mode 100644 index 68667cb2..00000000 --- a/package/gluon-status-page/src/js/lib/streams.js +++ /dev/null @@ -1,66 +0,0 @@ -"use strict" -define(["bacon", "lib/helper"], function(Bacon, Helper) { - function nodeInfo(ip, ifname) { - return Bacon.fromBinder(function (sink) { - var url = Helper.buildUrl(ip, "dyn/neighbours-nodeinfo", ifname) - var evtSource = new EventSource(url) - - evtSource.addEventListener("neighbour", function(e) { - var r = sink(new Bacon.Next(JSON.parse(e.data))) - - if (r === Bacon.noMore) - tearDown() - }, false) - - evtSource.addEventListener("eot", function() { - evtSource.close() - sink(new Bacon.End()) - }, false) - - function tearDown() { - evtSource.close() - } - - return tearDown - }) - } - - function simpleStream(url) { - return Bacon.fromBinder(function (sink) { - var evtSource = new EventSource(url) - - evtSource.onmessage = function (e) { - var r = sink(new Bacon.Next(JSON.parse(e.data))) - if (r === Bacon.noMore) - tearDown() - } - - function tearDown() { - evtSource.close() - } - - return tearDown - }) - } - - function batadv(ip) { - var url = Helper.buildUrl(ip, "dyn/neighbours-batadv") - return simpleStream(url) - } - - function stations(ip, ifname) { - var url = Helper.buildUrl(ip, "dyn/stations", ifname) - return simpleStream(url) - } - - function statistics(ip) { - var url = Helper.buildUrl(ip, "dyn/statistics") - return simpleStream(url).skipDuplicates(function (a, b) {return (a.uptime === b.uptime)}) - } - - return { nodeInfo: nodeInfo - , Batadv: batadv - , Stations: stations - , Statistics: statistics - } -}) diff --git a/package/gluon-status-page/src/js/main.js b/package/gluon-status-page/src/js/main.js deleted file mode 100644 index 3bdbe2a0..00000000 --- a/package/gluon-status-page/src/js/main.js +++ /dev/null @@ -1,108 +0,0 @@ -"use strict" -require([ "bacon" - , "lib/helper" - , "lib/streams" - , "lib/gui" - ], function(Bacon, Helper, Streams, GUI) { - - var mgmtBus = new Bacon.Bus() - - mgmtBus.pushEvent = function (key, a) { - var v = [key].concat(a) - return this.push(v) - } - - mgmtBus.onEvent = function (events) { - return this.onValue(function (e) { - var d = e.slice() // shallow copy so calling shift doesn't change it - var ev = d.shift() - if (ev in events) - events[ev].apply(this, d) - }) - } - - var nodesBusIn = new Bacon.Bus() - - var nodesBus = nodesBusIn.scan({ "nodes": {} - , "macs": {} - }, scanNodeInfo) - - new GUI(mgmtBus, nodesBus) - - mgmtBus.onEvent({ "goto": gotoNode - , "nodeinfo": function (d) { nodesBusIn.push(d) } - }) - - function tryIp(ip) { - return Helper.request(ip, "nodeinfo").map(function () { return ip }) - } - - var gotoEpoch = 0 - - function onEpoch(epoch, f) { - return function (d) { - if (epoch === gotoEpoch) - return f(d) - } - } - - function gotoNode(nodeInfo) { - gotoEpoch++ - - var addresses = nodeInfo.network.addresses.filter(function (d) { return !/^fe80:/.test(d) }) - var race = Bacon.fromArray(addresses).flatMap(tryIp).withStateMachine([], function (acc, ev) { - if (ev.isError()) - return [acc.concat(ev.error), []] - else if (ev.isEnd() && acc.length > 0) - return [undefined, [new Bacon.Error(acc), ev]] - else if (ev.hasValue()) - return [[], [ev, new Bacon.End()]] - }) - - race.onValue(onEpoch(gotoEpoch, function (d) { - mgmtBus.pushEvent("arrived", [nodeInfo, d]) - })) - - race.onError(onEpoch(gotoEpoch, function () { - mgmtBus.pushEvent("gotoFailed", nodeInfo) - })) - } - - function scanNodeInfo(a, nodeInfo) { - a.nodes[nodeInfo.node_id] = nodeInfo - - var mesh = Helper.dictGet(nodeInfo, ["network", "mesh"]) - - if (mesh) - for (var m in mesh) - for (var ifname in mesh[m].interfaces) - mesh[m].interfaces[ifname].forEach( function (d) { - a.macs[d] = nodeInfo - }) - - return a - } - - if (localStorage.nodes) - JSON.parse(localStorage.nodes).forEach(nodesBusIn.push) - - nodesBus.map(".nodes").onValue(function (nodes) { - var out = [] - - for (var k in nodes) - out.push(nodes[k]) - - localStorage.nodes = JSON.stringify(out) - }) - - var bootstrap = Helper.getJSON(bootstrapUrl) - - bootstrap.onError(function () { - console.log("FIXME bootstrapping failed") - }) - - bootstrap.onValue(function (d) { - mgmtBus.pushEvent("nodeinfo", d) - mgmtBus.pushEvent("goto", d) - }) -})