1
0
mirror of https://github.com/Foltik/Shimapan synced 2024-11-14 08:49:51 -05:00
shimapan/app/routes/api/stats.js

222 lines
5.6 KiB
JavaScript

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.concat(res2);
let res = {};
for (let obj of arr) {
if (res[obj._id])
res[obj._id] = mergeAggregateStats(res[obj._id], obj);
else
res[obj._id] = filterAggregateStats(obj);
}
return res;
}
const uploadProps = [
{name: 'after', type: 'date', optional: true},
{name: 'before', type: 'date', optional: true},
{name: 'limit', type: 'number', min: 1, max: 10000, optional: true}
];
router.get('/uploads', requireAuth('stats.get'), bodyVerifier(uploadProps), wrap(async (req, res) => {
let constraints = {uploader: req.username};
// Set date constraints if specified
if (req.body.after || req.body.before)
constraints.date = {};
if (req.body.after)
constraints.date.$gt = new Date(req.body.after);
if (req.body.before)
constraints.date.$lt = new Date(req.body.before);
// Create query
const query = Upload.find(constraints);
// Limit if specified
if (req.body.limit)
query.limit(req.body.limit);
// Fetch and transform results
let uploads = await query;
uploads = uploads.map(upload => {
return {
date: upload.date,
uid: upload.uid,
key: upload.uploaderKey,
file: {
originalName: upload.file.originalName,
size: upload.file.size,
mime: upload.file.mime
}
}
});
res.status(200).json(uploads);
}));
const viewProps = [
{name: 'after', type: 'date', optional: true},
{name: 'before', type: 'date', optional: true},
{name: 'limit', type: 'number', min: 1, max: 10000, optional: true}
];
router.get('/views', requireAuth('stats.get'), bodyVerifier(viewProps), wrap(async (req, res) => {
let constraints = {uploader: req.username};
// Set date constraints if specified
if (req.body.after || req.body.before)
constraints.date = {};
if (req.body.after)
constraints.date.$gt = new Date(req.body.after);
if (req.body.before)
constraints.date.$lt = new Date(req.body.before);
// Create query
const query = View.find(constraints);
// Limit if specified
if (req.body.limit)
query.limit(req.body.limit);
// Fetch and transform results
let views = await query;
views = views.map(view => {
return {
date: view.date,
uid: view.uid,
}
});
res.status(200).json(views);
}));
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 uploadStats = await (Upload.collection.aggregate([
{
$match: {
'uploader': req.username
}
},
{
$project: {
'size': '$file.size'
}
},
{
$group: {
'_id': 'total',
'count': {$sum: 1},
'size': {$sum: '$size'}
}
}
]).toArray());
const viewStats = await (View.collection.aggregate([
{
$match: {
'uploader': req.username
}
},
{
$group: {
'_id': 'total',
'views': {$sum: 1},
}
}
]).toArray());
const stats = mergeAggregations(uploadStats, viewStats);
res.status(200).json(stats);
}));
module.exports = router;