diff options
Diffstat (limited to 'web/nms-public.gathering.org/js/nms.js')
-rw-r--r-- | web/nms-public.gathering.org/js/nms.js | 692 |
1 files changed, 0 insertions, 692 deletions
diff --git a/web/nms-public.gathering.org/js/nms.js b/web/nms-public.gathering.org/js/nms.js deleted file mode 100644 index 8783844..0000000 --- a/web/nms-public.gathering.org/js/nms.js +++ /dev/null @@ -1,692 +0,0 @@ -"use strict"; -var nms = { - stats:{}, // Various internal stats - get nightMode() { return this._nightMode; }, - set nightMode(val) { if (val != this._nightMode) { this._nightMode = val; setNightMode(val); } }, - /* - * FIXME: This should be slightly smarter. - */ - _now: false, - get now() { return this._now }, - set now(v) { this._now = v; nmsData.now = v; }, - /* - * Various setInterval() handlers. See nmsTimer() for how they are - * used. - * - * FIXME: Should just stop using these. - */ - timers: { - playback:false - }, - - menuShowing:true, - /* - * This is a list of nms[x] variables that we store in our - * settings-cookie when altered and restore on load. - */ - settingsList:[ - 'nightMode', - 'menuShowing' - ], - keyBindings:{ - '-':toggleMenu, - 'n':toggleNightMode, - '1':setMapModeFromN, - '2':setMapModeFromN, - '3':setMapModeFromN, - '4':setMapModeFromN, - '5':setMapModeFromN, - '6':setMapModeFromN, - '7':setMapModeFromN, - '8':setMapModeFromN, - '9':setMapModeFromN, - 'c':toggleConnect, - 'h':moveTimeFromKey, - 'j':moveTimeFromKey, - 'k':moveTimeFromKey, - 'l':moveTimeFromKey, - 'p':moveTimeFromKey, - 'r':moveTimeFromKey, - 'Escape':hideWindow, - '?':toggleHelp - }, - /* - * Playback controllers and variables - */ - playback:{ - startTime: false, - stopTime: false, - playing: false, - replayTime: 0, - replayIncrement: 60 * 60 - } -}; - -/* - * Returns a handler object. - * - * This might seem a bit much for 'setInterval()' etc, but it's really more - * about self-documentation and predictable ways of configuring timers. - */ -function nmsTimer(handler, interval, name, description) { - this.handler = handler; - this.handle = false; - this.interval = parseInt(interval); - this.name = name; - this.description = description; - this.start = function() { - if (this.handle) { - this.stop(); - } - this.handle = setInterval(this.handler,this.interval); - }; - this.stop = function() { - if (this.handle) - clearInterval(this.handle); - this.handle = false; - }; - - this.setInterval = function(interval) { - var started = this.handle != false; - this.stop(); - this.interval = parseInt(interval); - if (started) - this.start(); - }; -} - - -/* - * Convenience function that doesn't support huge numbers, and it's easier - * to comment than to fix. But not really, but I'm not fixing it anyway. - */ -function byteCount(bytes,precision) { - if (precision ==undefined) - precision = 1; - var units = ['', 'K', 'M', 'G', 'T', 'P']; - var i = 0; - while (bytes > 1024) { - bytes = bytes / 1024; - i++; - } - return bytes.toFixed(precision) + units[i]; -} - -/* - * Definitely not a way to toggle night mode. Does something COMPLETELY - * DIFFERENT. - */ -function toggleNightMode() -{ - nms.nightMode = !nms.nightMode; - saveSettings(); -} - -/* - * Parse 'now' from user-input. - * - * Should probably just use stringToEpoch() instead, but alas, not yet. - */ -function parseNow(now) -{ - if (Date.parse(now)) { - // Adjust for timezone when converting from epoch (UTC) to string (local) - var d = new Date(now); - var timezoneOffset = d.getTimezoneOffset() * -60000; - var d = new Date(Date.parse(now) - timezoneOffset); - var str = d.getFullYear() + "-" + ("00" + (parseInt(d.getMonth())+1)).slice(-2) + "-" + ("00" + d.getDate()).slice(-2) + "T"; - str += ("00" + d.getHours()).slice(-2) + ":" + ("00" + d.getMinutes()).slice(-2) + ":" + ("00" + d.getSeconds()).slice(-2); - return str; - - } - if (now == "") - return ""; - return false; -} - -/* - * Convert back and forth between epoch. - * - * There's no particular reason why I use seconds instead of javascript - * microseconds, except to leave the mark of a C coder on this javascript - * project. - */ -function stringToEpoch(t) -{ - var foo = t.toString(); -// foo = foo.replace('T',' '); - var ret = new Date(Date.parse(foo)); - return parseInt(parseInt(ret.valueOf()) / 1000); -} - -/* - * Have to pad with zeroes to avoid "17:5:0" instead of the conventional - * and more readable "17:05:00". I'm sure there's a better way, but this - * works just fine. - */ -function epochToString(t) -{ - // Adjust for timezone when converting from epoch (UTC) to string (local) - var date = new Date(parseInt(t) * parseInt(1000)); - var timezoneOffset = date.getTimezoneOffset() * -60; - t = t - timezoneOffset; - - date = new Date(parseInt(t) * parseInt(1000)); - var str = date.getFullYear() + "-"; - if (parseInt(date.getMonth()) < 9) - str += "0"; - str += (parseInt(date.getMonth())+1) + "-"; - if (date.getDate() < 10) - str += "0"; - str += date.getDate() + "T"; - if (date.getHours() < 10) - str += "0"; - str += date.getHours() + ":"; - if (date.getMinutes() < 10) - str += "0"; - str += date.getMinutes() + ":"; - if (date.getSeconds() < 10) - str += "0"; - str += date.getSeconds(); - - return str; -} - -function localEpochToString(t) { - var d = new Date(parseInt(t) * parseInt(1000)); - var timezoneOffset = d.getTimezoneOffset() * -60; - t = t + timezoneOffset; - - return epochToString(t); -} - -/* - * Start replaying historical data. - */ -nms.playback.startReplay = function(startTime,stopTime) { - if(!startTime || !stopTime) - return false; - - nms.playback.pause(); - nms.playback.startTime = stringToEpoch(startTime); - nms.playback.stopTime = stringToEpoch(stopTime); - nms.now = epochToString(nms.playback.startTime); - nms.playback.play(); -}; - -/* - * Pause playback - */ -nms.playback.pause = function() { - nms.timers.playback.stop(); - nms.playback.playing = false; -}; - -/* - * Start playback - */ -nms.playback.play = function() { - nms.playback.tick(); - nms.timers.playback.start(); - nms.playback.playing = true; -}; - -/* - * Toggle playback - */ -nms.playback.toggle = function() { - if(nms.playback.playing) { - nms.playback.pause(); - } else { - nms.playback.play(); - } -}; - -/* - * Jump to place in time - */ -nms.playback.setNow = function(now) { - nms.now = parseNow(now); - - nms.playback.stopTime = false; - nms.playback.startTime = false; - nms.playback.tick(); -}; - -/* - * Step forwards or backwards in timer - */ -nms.playback.stepTime = function(n) -{ - var now = getNowEpoch(); - var newtime = parseInt(now) + parseInt(n); - nms.now = epochToString(parseInt(newtime)); - - if(!nms.playback.playing) - nms.playback.tick(); -}; - -/* - * Ticker to trigger updates, and advance time if replaying - * - * This is run on a timer (nms.timers.tick) every second while unpaused - */ -nms.playback.tick = function() -{ - nms.playback.replayTime = getNowEpoch(); - - // If outside start-/stopTime, remove limits and pause playback - if (nms.playback.stopTime && (nms.playback.replayTime >= nms.playback.stopTime || nms.playback.replayTime < nms.playback.startTime)) { - nms.playback.stopTime = false; - nms.playback.startTime = false; - nms.playback.pause(); - return; - } - - // If past actual datetime, go live - if (nms.playback.replayTime > parseInt(Date.now() / 1000)) { - nms.now = false; - } - - // If we are still replaying, advance time - if(nms.now !== false && nms.playback.playing) { - nms.playback.stepTime(nms.playback.replayIncrement); - } -}; - -/* - * Helper function for safely getting a valid now-epoch - */ -function getNowEpoch() { - if (nms.now && nms.now != 0) - return stringToEpoch(nms.now); - else - return parseInt(Date.now() / 1000); -} - -/* - * There are 4 legend-bars. This is a helper-function to set the color and - * description/name for each one. Used from handler init-functions. - * - * FIXME: Should be smarter, possibly use a canvas-writer so we can get - * proper text (e.g.: not black text on dark blue). - */ -function setLegend(x,color,name) -{ - var el = document.getElementById("legend-" + x); - el.style.background = color; - el.title = name; - el.textContent = name; -} - -/* - * Change map handler (e.g., change from uplink map to ping map) - */ -function setUpdater(fo) -{ - nmsMap.reset(); - nmsData.unregisterHandlerWildcard("mapHandler"); - try { - fo.init(); - } catch (e) { - /* - * This can happen typically on initial load where the data - * hasn't been retrieved yet. Instead of breaking the - * entire init-process, just bail out here. - */ - console.log("Possibly broken handler: " + fo.name); - console.log(e); - } - var foo = document.getElementById("updater_name"); - foo.innerHTML = fo.name + " "; - document.location.hash = fo.tag; -} - -function toggleLayer(layer) { - var l = document.getElementById(layer); - if (l.style.display == 'none') - l.style.display = ''; - else - l.style.display = 'none'; -} - -function toggleConnect() { - toggleLayer("linkCanvas"); -} - -function commentInactive(id) -{ - commentChange(id,"inactive"); -} - -function commentPersist(id) -{ - commentChange(id,"persist"); -} - -function commentDelete(id) -{ - var r = confirm("Really delete comment? (Delted comments are still stored in the database, but never displayed)"); - if (r == true) { - commentChange(id,"delete"); - } -} - -/* - * FIXME: Neither of these two handle failures in any way, shape or form. - * Nor do they really give user-feedback. They work, but only by magic. - */ -function commentChange(id,state) -{ - var myData = { - comment:id, - state:state - }; - myData = JSON.stringify(myData); - $.ajax({ - type: "POST", - url: "/api/write/comment-change", - dataType: "text", - data:myData, - success: function (data, textStatus, jqXHR) { - nmsData.invalidate("comments"); - } - }); -} - -function addComment(sw,comment) -{ - var myData = { - switch:sw, - comment:comment - }; - myData = JSON.stringify(myData); - $.ajax({ - type: "POST", - url: "/api/write/comment-add", - dataType: "text", - data:myData, - success: function (data, textStatus, jqXHR) { - nmsData.invalidate("comments"); - } - }); -} - - - -/* - * Returns true if the coordinates (x,y) is inside the box defined by - * box.{x,y,w.h} (e.g.: placement of a switch). - */ -function isIn(box, x, y) -{ - return ((x >= box.x) && (x <= (box.x + box.width)) && (y >= box.y) && (y <= (box.y + box.height))); -} - -/* - * Return the name of the switch found at coordinates (x,y), or 'undefined' - * if none is found. - */ -function findSwitch(x,y) { - x = parseInt(parseInt(x) / nmsMap.scale); - y = parseInt(parseInt(y) / nmsMap.scale); - - for (var v in nmsData.switches.switches) { - if(isIn(nmsData.switches.switches[v]['placement'],x,y)) { - return v; - } - } - return undefined; -} - -/* - * Set night mode to whatever 'toggle' is. - * - * Changes background and nav-bar, then leaves the rest to nmsMap. - */ -function setNightMode(toggle) { - nms.nightMode = toggle; - var body = document.getElementById("body"); - body.style.background = toggle ? "black" : "white"; - var nav = document.getElementsByTagName("nav")[0]; - if (toggle) { - nav.classList.add('navbar-inverse'); - } else { - nav.classList.remove('navbar-inverse'); - } - nmsMap.setNightMode(toggle); -} - -/* - * Boot up "fully fledged" NMS. - * - * This can be re-written to provide different looks and feels but using - * the same framework. Or rather: that's the goal. We're not quite there - * yet. - */ -function initNMS() { - nms.timers.playback = new nmsTimer(nms.playback.tick, 1000, "Playback ticker", "Handler used to advance time"); - - // Public - nmsData.registerSource("ping", "/api/public/ping"); - nmsData.registerSource("switches","/api/public/switches"); - nmsData.registerSource("switchstate","/api/public/switch-state"); - nmsData.registerSource("dhcpsummary","/api/public/dhcp-summary"); - nmsData.registerSource("dhcp","/api/public/dhcp"); - - // This is a magic dummy-source, it's purpose is to give a unified - // way to get ticks every second. It is mainly meant to allow map - // handlers to register for ticks so they will execute without data - // (and thus notice stale data instead of showing a green ping-map - // despite no pings) - nmsData.registerSource("ticker","bananabananbanana"); - - restoreSettings(); - nmsMap.init(); - detectHandler(); - nms.playback.play(); - setupKeyhandler(); - setupSearchKeyHandler(); -} - -function detectHandler() { - for (var i in handlers) { - if (('#' + handlers[i].tag) == document.location.hash) { - setUpdater(handlers[i]); - return; - } - } - setUpdater(handler_ping); -} - -function setMenu() -{ - var nav = document.getElementsByTagName("nav")[0]; - nav.style.display = nms.menuShowing ? '' : 'none'; -} - -function toggleMenu() -{ - nms.menuShowing = ! nms.menuShowing; - setMenu(); - saveSettings(); -} -function hideWindow(e,key) -{ - nmsInfoBox.hide(); -} -function toggleHelp(e,key) { - toggleLayer('aboutKeybindings'); -} - -function setMapModeFromN(e,key) -{ - switch(key) { - case '1': - setUpdater(handler_ping); - break; - case '2': - setUpdater(handler_uplinks); - break; - case '3': - setUpdater(handler_dhcp); - break; - case '4': - setUpdater(handler_comment); - break; - case '5': - setUpdater(handler_temp); - break; - case '6': - setUpdater(handler_traffic); - break; - case '7': - setUpdater(handler_traffic_tot); - break; - case '8': - setUpdater(handler_snmp); - break; - case '9': - setUpdater(handler_disco); - break; - } - return true; -} - -function moveTimeFromKey(e,key) -{ - switch(key) { - case 'h': - nms.playback.stepTime(-3600); - break; - case 'j': - nms.playback.stepTime(-300); - break; - case 'k': - nms.playback.stepTime(300); - break; - case 'l': - nms.playback.stepTime(3600); - break; - case 'p': - nms.playback.toggle(); - break; - case 'r': - nms.playback.setNow(); - nms.playback.play(); - break; - } - return true; -} - -function keyPressed(e) -{ - if (e.target.nodeName == "INPUT") { - return false; - } - if(e.key) { - var key = e.key; - } else { - var key = e.keyCode; - switch(key) { - case 187: - key = '?'; - break; - case 189: - key = '-'; - break; - case 27: - key = 'Escape'; - break; - default: - key = String.fromCharCode(key); - key = key.toLowerCase(); - break; - } - } - if (nms.keyBindings[key]) - return nms.keyBindings[key](e,key); - if (nms.keyBindings['default']) - return nms.keyBindings['default'](e,key); - return false; -} - -function setupKeyhandler() -{ - var b = document.getElementsByTagName("body")[0]; - $( "body" ).keyup(function(e) { - keyPressed(e); - }); -} - -function setupSearchKeyHandler() -{ - $("#searchbox").keyup(function(e) { - nmsInfoBox._searchKeyListener(e); - }); -} - - -function getCookie(cname) { - var name = cname + "="; - var ca = document.cookie.split(';'); - for(var i=0; i<ca.length; i++) { - var c = ca[i]; - while (c.charAt(0)==' ') - c = c.substring(1); - if (c.indexOf(name) == 0) - return c.substring(name.length,c.length); - } - return ""; -} - -function saveSettings() -{ - var foo={}; - for ( var v in nms.settingsList ) { - foo[ nms.settingsList[v] ] = nms[ nms.settingsList[v] ]; - } - document.cookie = 'nms='+btoa(JSON.stringify(foo)); -} - -function restoreSettings() -{ - try { - var retrieve = JSON.parse(atob(getCookie("nms"))); - } catch(e) { - console.log("nothing saved"); - } - - for (var v in retrieve) { - nms[v] = retrieve[v]; - } - setMenu(); -} - -/* - * Time travel gui - */ -function startNowPicker(now) { - $.datetimepicker.setLocale('no'); - $('#nowPicker').datetimepicker('destroy'); - if(!now && nms.now) - now = nms.now; - var datepicker = $('#nowPicker').datetimepicker({ - value: now, - mask:false, - inline:true, - todayButton: false, - validateOnBlur:false, - dayOfWeekStart:1, - maxDate:'+1970/01/01', - onSelectDate: function(ct,$i){ - document.getElementById('nowPicker').dataset.iso = localEpochToString(ct.valueOf()/1000); - }, - onSelectTime: function(ct,$i){ - document.getElementById('nowPicker').dataset.iso = localEpochToString(ct.valueOf()/1000); - }, - onGenerate: function(ct,$i){ - document.getElementById('nowPicker').dataset.iso = localEpochToString(ct.valueOf()/1000); - } - }); -} |