hopglass/history.js
2015-03-20 09:57:53 +01:00

170 lines
4.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

document.addEventListener('DOMContentLoaded', main)
function get(url) {
return new Promise(function(resolve, reject) {
var req = new XMLHttpRequest();
req.open('GET', url);
req.onload = function() {
if (req.status == 200) {
resolve(req.response);
}
else {
reject(Error(req.statusText));
}
};
req.onerror = function() {
reject(Error("Network Error"));
};
req.send();
});
}
function getJSON(url) {
return get(url).then(JSON.parse)
}
function main() {
getJSON('nodes.json').then(handle_data)
}
function sort(key, d) {
return d.slice().sort( function (a, b) {
return a[key] - b[key]
}).reverse()
}
function limit(key, m, d) {
return d.filter( function (d) {
return d[key].isAfter(m)
})
}
function offline(d) {
return !d.flags.online
}
function online(d) {
return d.flags.online
}
function has_location(d) {
return "location" in d.nodeinfo
}
function subtract(a, b) {
var ids = {}
b.forEach( function (d) {
ids[d.nodeinfo.node_id] = true
})
return a.filter( function (d) {
return !(d.nodeinfo.node_id in ids)
})
}
function handle_data(data) {
var nodes = Object.keys(data.nodes).map(function (key) { return data.nodes[key] })
nodes = nodes.filter( function (d) {
return "firstseen" in d && "lastseen" in d
})
nodes.forEach( function(node) {
node.firstseen = moment(node.firstseen)
node.lastseen = moment(node.lastseen)
})
var age = moment().subtract(14, 'days')
var newnodes = limit("firstseen", age, sort("firstseen", nodes).filter(online))
var lostnodes = limit("lastseen", age, sort("lastseen", nodes).filter(offline))
var onlinenodes = subtract(nodes.filter(online).filter(has_location), newnodes)
addToList(document.getElementById("newnodes"), "firstseen", newnodes)
addToList(document.getElementById("lostnodes"), "lastseen", lostnodes)
mkmap(document.getElementById("map"), newnodes, lostnodes, onlinenodes)
}
function mkmap(el, newnodes, lostnodes, onlinenodes) {
var options = { worldCopyJump: true,
zoomControl: false
}
var map = L.map(el, options)
L.control.zoom({ position: "topright" }).addTo(map)
L.tileLayer("http://otile{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.jpg", {
subdomains: "1234",
type: "osm",
attribution: "Map data Tiles &copy; <a href=\"http://www.mapquest.com/\" target=\"_blank\">MapQuest</a> <img src=\"http://developer.mapquest.com/content/osm/mq_logo.png\" />, Map data © OpenStreetMap contributors, CC-BY-SA",
maxZoom: 18
}).addTo(map)
var nodes = newnodes.concat(lostnodes).filter( function (d) {
return "location" in d.nodeinfo
})
var markers = nodes.map( function (d) {
var icon = L.MakiMarkers.icon({ color: d.flags.online ? "#0A905D" : "#E42426" })
var opt = { icon: icon }
var m = L.marker([d.nodeinfo.location.latitude, d.nodeinfo.location.longitude], opt)
m.bindPopup(d.nodeinfo.hostname)
return m
})
var onlinemarkers = onlinenodes.map( function (d) {
var opt = { color: "#0A905D",
fillColor: "#0A905D",
radius: 5
}
var m = L.circleMarker([d.nodeinfo.location.latitude, d.nodeinfo.location.longitude], opt)
m.bindPopup(d.nodeinfo.hostname)
return m
})
var group = L.featureGroup(markers).addTo(map)
var group_online = L.featureGroup(onlinemarkers).addTo(map)
map.fitBounds(group.getBounds())
}
function addToList(el, tf, list) {
list.forEach( function (d) {
var time = moment(d[tf]).fromNow()
var row = document.createElement("tr")
var td1 = document.createElement("td")
var span = document.createElement("span")
span.classList.add("hostname")
span.classList.add(d.flags.online ? "online" : "offline")
span.textContent = d.nodeinfo.hostname
td1.appendChild(span)
if ("owner" in d.nodeinfo) {
var contact = d.nodeinfo.owner.contact
td1.appendChild(document.createTextNode(" " + contact + ""))
}
var td2 = document.createElement("td")
td2.textContent = time
row.appendChild(td1)
row.appendChild(td2)
el.appendChild(row)
})
}