From dd364c962fd91488f2071319d44c8062163a6baf Mon Sep 17 00:00:00 2001 From: Audrius Butkevicius Date: Thu, 14 Apr 2016 22:01:25 +0100 Subject: [PATCH] Refactor javascript, always show table, add sorting --- cmd/strelaypoolsrv/auto/gui.go | 4 +- cmd/strelaypoolsrv/gui/index.html | 417 +++++++++++++++++------------- 2 files changed, 239 insertions(+), 182 deletions(-) diff --git a/cmd/strelaypoolsrv/auto/gui.go b/cmd/strelaypoolsrv/auto/gui.go index 9d7b80100..7e181b03f 100644 --- a/cmd/strelaypoolsrv/auto/gui.go +++ b/cmd/strelaypoolsrv/auto/gui.go @@ -5,12 +5,12 @@ import ( ) const ( - AssetsBuildDate = "Wed, 13 Apr 2016 20:30:55 GMT" + AssetsBuildDate = "Thu, 14 Apr 2016 21:00:33 GMT" ) func Assets() map[string][]byte { var assets = make(map[string][]byte, 1) - assets["index.html"], _ = base64.StdEncoding.DecodeString("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") + assets["index.html"], _ = base64.StdEncoding.DecodeString("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") return assets } diff --git a/cmd/strelaypoolsrv/gui/index.html b/cmd/strelaypoolsrv/gui/index.html index 77f44bb2b..1c2864ba9 100644 --- a/cmd/strelaypoolsrv/gui/index.html +++ b/cmd/strelaypoolsrv/gui/index.html @@ -19,9 +19,13 @@ display: none; } table { - font-size: 11px; + font-size: 11px !important; width: 100%; border: 1px; + + } + td { + padding: 0px !important; } tfoot td { font-weight: bold; @@ -32,57 +36,125 @@

Relay Pool Data

-
+

Please wait while we gather data

-

{{ entry.name }}... Done!

-
+

Currently {{ relays.length }} relays online ({{ totals.goMaxProcs }} cores in total).

-

The circle size represents how much bytes the relay transfered relative to other relays

+

The circle size represents how much bytes the relay transfered relative to other relays

-
- +
+
- - - - + + + + + + + - - - - - - - - - - - - + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + @@ -98,7 +170,7 @@ - +
Transfer rate in the last period (per second)
Address + + + Sessions + + + + + + Connections + + + + + + Data relayed + + + + Transfer rate in the last period + + Uptime hours + + + + + + Provided by + + + +
AddressActive SessionsConnectionsData proxied10s1m5m15m30m60mUptimeProvided by + + 10s + + + + + + 1m + + + + + + 5m + + + + + + 15m + + + + + + 30m + + + + + + 60m + + + +
{{ relay.url.split('/')[2] }}{{ status[relay.url].numActiveSessions }}{{ status[relay.url].numConnections }}{{ status[relay.url].bytesProxied | bytes }}{{ status[relay.url].kbps10s1m5m15m30m60m[0] * 128 | bytes }}/s{{ status[relay.url].kbps10s1m5m15m30m60m[1] * 128 | bytes }}/s{{ status[relay.url].kbps10s1m5m15m30m60m[2] * 128 | bytes }}/s{{ status[relay.url].kbps10s1m5m15m30m60m[3] * 128 | bytes }}/s{{ status[relay.url].kbps10s1m5m15m30m60m[4] * 128 | bytes }}/s{{ status[relay.url].kbps10s1m5m15m30m60m[5] * 128 | bytes }}/s{{ status[relay.url].uptimeSeconds/60/60 | number:0 }} hours{{ status[relay.url].options['provided-by'] || '' }}
{{ relay.address }}Looking up...{{ relay.status.numActiveSessions }}{{ relay.status.numConnections }}{{ relay.status.bytesProxied | bytes }}{{ relay.status.kbps10s1m5m15m30m60m[0] * 128 | bytes }}/s{{ relay.status.kbps10s1m5m15m30m60m[1] * 128 | bytes }}/s{{ relay.status.kbps10s1m5m15m30m60m[2] * 128 | bytes }}/s{{ relay.status.kbps10s1m5m15m30m60m[3] * 128 | bytes }}/s{{ relay.status.kbps10s1m5m15m30m60m[4] * 128 | bytes }}/s{{ relay.status.kbps10s1m5m15m30m60m[5] * 128 | bytes }}/s{{ relay.status.uptimeSeconds/60/60 | number:0 }} + {{ relay.status.options['provided-by'] || '' | limitTo:50 }} + … +
{{ totals.kbps10s1m5m15m30m60m[4] * 128 | bytes }}/s {{ totals.kbps10s1m5m15m30m60m[5] * 128 | bytes }}/s {{ totals.uptimeSeconds/60/60 | number:0 }} hours{{ relays.length }} relays
@@ -145,11 +217,6 @@ } }) .controller('relayDataController', ['$scope', '$rootScope', '$http', '$q', '$compile', '$timeout', function($scope, $rootScope, $http, $q, $compile, $timeout) { - $scope.started = false; - $scope.geoip = {}; - $scope.status = {}; - $scope.uri = {}; - $scope.progress = []; $scope.totals = { bytesProxied: 0, goMaxProcs: 0, @@ -160,176 +227,166 @@ numProxies: 0, uptimeSeconds: 0, }; + $scope.map = new google.maps.Map(document.getElementById('map'), { + zoom: 1, + mapTypeId: google.maps.MapTypeId.ROADMAP + }); + $scope.mapBounds = new google.maps.LatLngBounds(); + $scope.tooltipTemplate = $('#infoTemplate').html(); + $scope.usedLocations = {}; + $scope.sortType = 'status.numActiveSessions || 0'; + $scope.sortReverse = true; - var usedLocs = {}; - - function initProgress(name) { - $scope.progress.push({name: name, done: false}); - } - - function progressDone(name) { - angular.forEach($scope.progress, function(progress) { - if (progress.name == name) { - progress.done = true; - } - }); - } - - var map; - var template = $('#infoTemplate').html(); - - initProgress("Fetching relays"); $http.get("/endpoint").then(function(response) { - progressDone("Fetching relays"); - $scope.relays = response.data.relays; - - map = new google.maps.Map(document.getElementById('map'), { - zoom: 1, - mapTypeId: google.maps.MapTypeId.ROADMAP - }); - var promises = []; angular.forEach($scope.relays, function(relay) { - var uri = document.createElement('a'); - // HAX, otherwise doesn't work - uri.href = relay.url.replace('relay://', 'http://'); + relay.uri = constructURI(relay.url); + relay.address = relay.url.split('/')[2]; - // Convert query string to object - uri.args = {}; - angular.forEach(uri.search.replace(/^\?/, '').split('&'), function(query) { - var split = query.split('='); - uri.args[split[0]] = split[1]; - }) + addMarkerToMap(relay); - $scope.uri[relay.url] = uri; - - var resolveStatus = $q.defer(); - - initProgress("Getting relay status for " + uri.hostname); - - // Normal timeout doesn't deal with relays which accept the TCP connection - // but don't respond (some firewalls do that), so deal with it this way. - var timeoutRequest = $q.defer(); - - $http.get("http://" + uri.hostname + (uri.args.statusAddr || ":22070") + "/status", { timeout: timeoutRequest.promise }).then(function (response) { - progressDone("Getting relay status for " + uri.hostname); - $scope.status[relay.url] = response.data; - angular.forEach($scope.totals, function(value, key) { - if (typeof $scope.totals[key] == 'number') { - $scope.totals[key] += response.data[key]; - } else if (typeof $scope.totals[key] == 'object' && $scope.totals[key] instanceof Array) { - angular.forEach($scope.totals[key], function(value, index) { - $scope.totals[key][index] += response.data[key][index]; - }); - } - }); - resolveStatus.resolve(response.data); - }, function() { - progressDone("Getting relay status for " + uri.hostname); - - resolveStatus.resolve(response.data); - }); - - $timeout(function() { - timeoutRequest.resolve(); - }, 5000); - - promises.push(resolveStatus.promise); + promises.push(getRelayStatus(relay)); }); + // Can only add circles once we know the totals for transfers, which means + // we need to resolve all statuses. $q.all(promises).then(function() { - $scope.started = true; - var bounds = new google.maps.LatLngBounds(); - angular.forEach($scope.relays, function(relay) { - var scope = $rootScope.$new(true); - var loc = relay.location.latitude + "," + relay.location.longitude; - - // Deal with overlapping markers - while (loc in usedLocs) { - var locParts = loc.split(','); - locParts = [parseFloat(locParts[0]), parseFloat(locParts[1])]; - locParts[Math.round(Math.random())] += 0.5 * (Math.random() >= 0.5 ? 1 : -1); - loc = locParts.join(','); + if (relay.status) { + addCircleToMap(relay); } + }); + }); - usedLocs[loc] = true; + $scope.map.fitBounds($scope.mapBounds); + if ($scope.relays.length == 1) { + $scope.map.setZoom(13); + } + }); + function addMarkerToMap(relay) { + var loc = relay.location.latitude + "," + relay.location.longitude; + + // Deal with overlapping markers + while (loc in $scope.usedLocations) { var locParts = loc.split(','); - var position = new google.maps.LatLng(locParts[0], locParts[1]); + locParts = [parseFloat(locParts[0]), parseFloat(locParts[1])]; + locParts[Math.round(Math.random())] += 0.5 * (Math.random() >= 0.5 ? 1 : -1); + loc = locParts.join(','); + } - scope.status = $scope.status[relay.url]; - scope.relay = relay; - scope.uri = $scope.uri[relay.url]; + $scope.usedLocations[loc] = true; - var marker = new google.maps.Marker({ - position: position, - map: map, - title: relay.url, - }); + var locParts = loc.split(','); - if (scope.status) { - marker.circle = new google.maps.Circle({ - strokeColor: '#FF0000', - strokeOpacity: 0.8, - strokeWeight: 2, - fillColor: '#FF0000', - fillOpacity: 0.35, - map: map, - center: position, - radius: ((scope.status.bytesProxied * 100) / $scope.totals.bytesProxied) * 10000 + relay.marker = new google.maps.Marker({ + map: $scope.map, + position: new google.maps.LatLng(locParts[0], locParts[1]), + title: relay.url, + }); + + var scope = $rootScope.$new(true); + scope.relay = relay; + + relay.marker.info = new google.maps.InfoWindow({ + content: $compile($scope.tooltipTemplate)(scope)[0], + }); + + relay.marker.addListener('mouseover', function() { + relay.marker.info.open($scope.map, relay.marker); + }); + + relay.marker.addListener('mouseout', function() { + relay.marker.info.close(); + }); + + $scope.mapBounds.extend(relay.marker.position); + } + + function addCircleToMap(relay) { + relay.marker.circle = new google.maps.Circle({ + strokeColor: '#FF0000', + strokeOpacity: 0.8, + strokeWeight: 2, + fillColor: '#FF0000', + fillOpacity: 0.35, + map: $scope.map, + center: relay.marker.position, + radius: ((relay.status.bytesProxied * 100) / $scope.totals.bytesProxied) * 10000 + }); + } + + function getRelayStatus(relay) { + // Normal timeout doesn't deal with relays which accept the TCP connection + // but don't respond (some firewalls do that), so deal with it this way. + var timeoutRequest = $q.defer(); + var resolveStatus = $q.defer(); + + $http.get("http://" + relay.uri.hostname + (relay.uri.args.statusAddr || ":22070") + "/status", { timeout: timeoutRequest.promise }).then(function (response) { + relay.status = response.data; + resolveStatus.resolve(); + angular.forEach($scope.totals, function(value, key) { + if (typeof $scope.totals[key] == 'number') { + $scope.totals[key] += response.data[key]; + } else if (typeof $scope.totals[key] == 'object' && $scope.totals[key] instanceof Array) { + angular.forEach($scope.totals[key], function(value, index) { + $scope.totals[key][index] += response.data[key][index]; }); } - - var content = $compile(template)(scope)[0]; - - marker.info = new google.maps.InfoWindow(); - marker.info.setContent(content); - - marker.addListener('mouseover', function() { - marker.info.open(map, marker); - }); - - marker.addListener('mouseout', function() { - marker.info.close(); - }); - - bounds.extend(marker.position); }); - - map.fitBounds(bounds); - if ($scope.relays.length == 1) { - map.setZoom(13); - } - $scope.started = true; + }, function() { + relay.status = null; + resolveStatus.resolve(); }); - }); + + $timeout(function() { + timeoutRequest.resolve(); + }, 5000); + + return resolveStatus.promise; + } + + function constructURI(url) { + var uri = document.createElement('a'); + + // HAX, otherwise doesn't work + uri.href = url.replace('relay://', 'http://'); + + // Convert query string to object + uri.args = {}; + angular.forEach(uri.search.replace(/^\?/, '').split('&'), function(query) { + var split = query.split('='); + uri.args[split[0]] = split[1]; + }); + + return uri; + } }]);