From c1a38820974b851e19bc8682c5a04539cb6f87d3 Mon Sep 17 00:00:00 2001 From: Jack Foltz Date: Sat, 15 Sep 2018 18:25:07 -0400 Subject: [PATCH] Add stats API route --- app/public/panel/shimapan-panel.js | 2 +- app/public/services/StatSvc.js | 23 +++++++ app/routes/api/stats.js | 134 +++++++++++++++++++++++++++++++++++++ app/routes/routes.js | 2 + 4 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 app/public/services/StatSvc.js create mode 100644 app/routes/api/stats.js diff --git a/app/public/panel/shimapan-panel.js b/app/public/panel/shimapan-panel.js index 901e4da..5e13de4 100644 --- a/app/public/panel/shimapan-panel.js +++ b/app/public/panel/shimapan-panel.js @@ -1,7 +1,7 @@ var angular = require('angular'); var uirouter = require('angular-ui-router'); var chart = require('angular-chart.js'); -var app = angular.module('shimapan-panel', ['ui.router', 'AuthSvc', 'KeySvc', 'InviteSvc', 'UserSvc', 'KeyCtrl', 'InviteCtrl', 'UserCtrl', 'NavCtrl', 'DashCtrl', 'PanelRoutes']); +var app = angular.module('shimapan-panel', ['ui.router', 'AuthSvc', 'KeySvc', 'InviteSvc', 'UserSvc', 'StatSvc', 'KeyCtrl', 'InviteCtrl', 'UserCtrl', 'NavCtrl', 'DashCtrl', 'PanelRoutes']); app.run(['$rootScope', '$state', '$stateParams', function($rootScope, $state, $stateParams) { $rootScope.$state = $state; diff --git a/app/public/services/StatSvc.js b/app/public/services/StatSvc.js new file mode 100644 index 0000000..b9d7e39 --- /dev/null +++ b/app/public/services/StatSvc.js @@ -0,0 +1,23 @@ +var angular = require('angular'); + +angular.module('StatSvc', []).service('StatService', ['$http', function($http) { + this.getWeek = cb => + $http({ + method: 'GET', + url: '/api/stats/week' + }).then(res => { + cb(null, res.data) + }).catch(err => { + cb(err); + }); + + this.getAll = cb => + $http({ + method: 'GET', + url: '/api/stats/all' + }).then(res => { + cb(null, res.data[0]) + }).catch(err => { + cb(err); + }); +}]); diff --git a/app/routes/api/stats.js b/app/routes/api/stats.js new file mode 100644 index 0000000..9cdfccb --- /dev/null +++ b/app/routes/api/stats.js @@ -0,0 +1,134 @@ +const express = require('express'); +const router = express.Router(); + +const ModelPath = '../../models/'; +const Upload = require(ModelPath + 'Upload.js'); +const View = require(ModelPath + 'View.js'); + +const wrap = require('../../util/wrap'); +const bodyVerifier = require('../../util/verifyBody').bodyVerifier; +const requireAuth = require('../../util/auth').requireAuth; + +const oneDay = 1000 * 60 * 60 * 24; + +function filterAggregateStats(obj) { + if (obj._id) + delete obj._id; + + return obj; +} + +function mergeAggregateStats(obj1, obj2) { + filterAggregateStats(obj1); + filterAggregateStats(obj2); + + let res = {}; + Object.assign(res, obj1, obj2); + return res; +} + +function mergeAggregations(res1, res2) { + const arr = res1; + arr.concat(res2); + + let res = {}; + + for (let obj of arr) { + if (res[obj._id]) + mergeAggregateStats(res[obj._id], obj); + else + res[obj._id] = filterAggregateStats(obj); + } + + return res; +} + +router.get('/week', requireAuth('stats.get'), wrap(async (req, res) => { + const currentDate = new Date(); + + const uploadStats = await (Upload.collection.aggregate([ + { + $match: { + 'date': {$gt: new Date(currentDate - 7 * oneDay)}, + 'uploader': req.username + } + }, + { + $project: { + 'date': { + $concat: [ + {$substr: ['$date', 5, 2]}, + '-', + {$substr: ['$date', 8, 2]} + ] + }, + 'size': '$file.size' + } + }, + { + $group: { + '_id': '$date', + 'uploads': {$sum: 1}, + 'size': {$sum: '$size'} + } + } + ]).toArray()); + + const viewStats = await (View.collection.aggregate([ + { + $match: { + 'date': {$gt: new Date(currentDate - 7 * oneDay)}, + 'uploader': req.username + } + }, + { + $project: { + 'date': { + $concat: [ + {$substr: ['$date', 5, 2]}, + '-', + {$substr: ['$date', 8, 2]} + ] + } + } + }, + { + $group: { + '_id': '$date', + 'views': {$sum: 1}, + } + } + ]).toArray()); + + const stats = mergeAggregations(uploadStats, viewStats); + + res.status(200).json(stats); +})); + +router.get('/all', requireAuth('stats.get'), wrap(async (req, res) => { + const stats = await (Upload.collection.aggregate([ + { + $match: { + 'uploader': req.username + } + }, + { + $project: { + 'views': '$views', + 'size': '$file.size' + } + }, + { + $group: { + '_id': 'total', + 'count': {$sum: 1}, + 'views': {$sum: '$views'}, + 'size': {$sum: '$size'} + } + } + ]).toArray()); + + res.status(200).json(stats); +})); + +module.exports = router; \ No newline at end of file diff --git a/app/routes/routes.js b/app/routes/routes.js index fa59c1f..e64c53e 100644 --- a/app/routes/routes.js +++ b/app/routes/routes.js @@ -12,6 +12,7 @@ const view = require('./api/view.js'); const invites = require('./api/invites.js'); const keys = require('./api/keys.js'); const users = require('./api/users.js'); +const stats = require('./api/stats.js'); module.exports = function (app) { app.use('/', index); @@ -29,4 +30,5 @@ module.exports = function (app) { app.use('/api/invites', invites); app.use('/api/keys', keys); app.use('/api/users', users); + app.use('/api/stats', stats); }; \ No newline at end of file