From 3c80be4d00d601f154a5142b5f5fe19355ae649b Mon Sep 17 00:00:00 2001 From: baldo Date: Tue, 19 Jul 2016 13:24:43 +0200 Subject: [PATCH] Added Statistics See: https://github.com/freifunkhamburg/ffffng/issues/24 --- admin/index.html | 1 + admin/js/main.js | 23 +++++++ admin/js/views/dashboardStats.js | 22 +++++++ admin/views/dashboardStats.html | 88 ++++++++++++++++++++++++++ server/main.js | 1 + server/resources/statisticsResource.js | 26 ++++++++ server/router.js | 3 + server/services/nodeService.js | 39 ++++++++++++ 8 files changed, 203 insertions(+) create mode 100644 admin/js/views/dashboardStats.js create mode 100644 admin/views/dashboardStats.html create mode 100644 server/resources/statisticsResource.js diff --git a/admin/index.html b/admin/index.html index 9caa5c3..cf20b2b 100644 --- a/admin/index.html +++ b/admin/index.html @@ -75,6 +75,7 @@ + diff --git a/admin/js/main.js b/admin/js/main.js index f70f4b3..8c9ef61 100644 --- a/admin/js/main.js +++ b/admin/js/main.js @@ -337,6 +337,14 @@ angular.module('ffffngAdmin').config(function(NgAdminConfigurationProvider, Rest admin.menu( nga.menu() + .addChild(nga + .menu() + .template( + '' + + ' Dashboard / Statistics' + + '' + ) + ) .addChild(nga .menu(nodes) .icon('') @@ -363,5 +371,20 @@ angular.module('ffffngAdmin').config(function(NgAdminConfigurationProvider, Rest ) ); + admin.dashboard(nga.dashboard() + .template( + '
' + + '' + + + '
' + + '
' + + '
' + + '' + + '
' + + '
' + + '
' + ) + ); + nga.configure(admin); }); diff --git a/admin/js/views/dashboardStats.js b/admin/js/views/dashboardStats.js new file mode 100644 index 0000000..475f227 --- /dev/null +++ b/admin/js/views/dashboardStats.js @@ -0,0 +1,22 @@ +'use strict'; + +angular.module('ffffngAdmin') +.directive('faDashboardStats', function ($http, $state, notification) { + var link = function (scope) { + scope.stats = {}; + $http.get('/internal/api/statistics') + .then(function (result) { scope.stats = result.data; }) + .catch(function (e) { + notification.log('Error: ' + e.data, { addnCls: 'humane-flatty-error' }); + console.error(e); + }); + }; + + return { + 'link': link, + 'restrict': 'E', + 'scope': {}, + + 'templateUrl': 'views/dashboardStats.html' + }; +}); diff --git a/admin/views/dashboardStats.html b/admin/views/dashboardStats.html new file mode 100644 index 0000000..ffaaa17 --- /dev/null +++ b/admin/views/dashboardStats.html @@ -0,0 +1,88 @@ + + +

Nodes

+ +
+
+
+
+
+
+ +
+
+
{{ stats.nodes.registered }}
+
Total Registered
+
+
+
+
+
+
+
+
+
+
+ +
+
+
{{ stats.nodes.withVPN }}
+
With VPN-Key
+
+
+
+
+
+
+
+
+
+
+ +
+
+
{{ stats.nodes.withCoords }}
+
With Coordinates
+
+
+
+
+
+
+ +

Monitoring

+ +
+
+
+
+
+
+ +
+
+
{{ stats.nodes.monitoring.active }}
+
Active
+
+
+
+
+
+
+
+
+
+
+ +
+
+
{{ stats.nodes.monitoring.pending }}
+
Pending
+
+
+
+
+
+
diff --git a/server/main.js b/server/main.js index 7c59750..f2025f5 100755 --- a/server/main.js +++ b/server/main.js @@ -29,6 +29,7 @@ require('./utils/strings'); require('./utils/urlBuilder'); require('./resources/versionResource'); +require('./resources/statisticsResource'); require('./resources/frontendResource'); require('./resources/taskResource'); require('./resources/mailResource'); diff --git a/server/resources/statisticsResource.js b/server/resources/statisticsResource.js new file mode 100644 index 0000000..e3cc43a --- /dev/null +++ b/server/resources/statisticsResource.js @@ -0,0 +1,26 @@ +'use strict'; + +angular.module('ffffng').factory('StatisticsResource', function ( + Logger, + NodeService, + Resources, + ErrorTypes +) { + return { + get: function (req, res) { + NodeService.getNodeStatistics(function (err, nodeStatistics) { + if (err) { + Logger.tag('statistics').error('Error getting statistics:', err); + return Resources.error(res, {data: 'Internal error.', type: ErrorTypes.internalError}); + } + + return Resources.success( + res, + { + nodes: nodeStatistics + } + ); + }); + } + }; +}); diff --git a/server/router.js b/server/router.js index 095c930..42c635f 100644 --- a/server/router.js +++ b/server/router.js @@ -3,6 +3,7 @@ angular.module('ffffng').factory('Router', function ( app, VersionResource, + StatisticsResource, FrontendResource, NodeResource, MonitoringResource, @@ -23,6 +24,8 @@ angular.module('ffffng').factory('Router', function ( app.put('/api/monitoring/confirm/:token', MonitoringResource.confirm); app.put('/api/monitoring/disable/:token', MonitoringResource.disable); + app.get('/internal/api/statistics', StatisticsResource.get); + app.get('/internal/api/tasks', TaskResource.getAll); app.put('/internal/api/tasks/run/:id', TaskResource.run); app.put('/internal/api/tasks/enable/:id', TaskResource.enable); diff --git a/server/services/nodeService.js b/server/services/nodeService.js index 3d8a21e..de8e95e 100644 --- a/server/services/nodeService.js +++ b/server/services/nodeService.js @@ -490,6 +490,45 @@ angular.module('ffffng') callback ); }); + }, + + getNodeStatistics: function (callback) { + this.getAllNodes(function (err, nodes) { + if (err) { + return callback(err); + } + + var nodeStatistics = { + registered: _.size(nodes), + withVPN: 0, + withCoords: 0, + monitoring: { + active: 0, + pending: 0 + } + }; + + _.each(nodes, function (node) { + if (node.key) { + nodeStatistics.withVPN += 1; + } + + if (node.coords) { + nodeStatistics.withCoords += 1; + } + + switch (node.monitoringState) { + case 'active': + nodeStatistics.monitoring.active += 1; + break; + case 'pending': + nodeStatistics.monitoring.pending += 1; + break; + } + }); + + callback(null, nodeStatistics); + }) } }; });