cubash-archive/routes/log.js

244 lines
5.2 KiB
JavaScript

let express = require('express')
let router = express.Router()
const auth = require('../lib/auth')
let { Sequelize, Log, userWall, Thread, User, Category } = require('../models')
const Errors = require('../lib/errors')
const now = new Date()
const lastWeek = new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() - 6)
function processLogsForLineChart (logs) {
let normalizedDateLogs = logs.map(log => {
let date = new Date(log.createdAt)
date.setHours(0, 0, 0)
return { createdAt: date }
})
let pageViewsObj = normalizedDateLogs.reduce((obj, log) => {
if(!obj[log.createdAt]) {
obj[log.createdAt] = { date: log.createdAt, pageViews: 1 }
} else {
obj[log.createdAt].pageViews++
}
return obj
}, {})
for(let i = 0; i < 7; i++) {
let date = new Date(lastWeek)
date.setUTCDate(date.getUTCDate() + i)
if(!pageViewsObj[date]) {
pageViewsObj[date] = {
date,
pageViews: 0
}
}
}
let pageViewsArr = Object.keys(pageViewsObj).map(date => {
return pageViewsObj[date]
})
let pageViewsSorted = pageViewsArr.sort((a, b) => {
if(a.date < b.date) {
return -1
} else if(a.date > b.date) {
return 1
} else {
return 0
}
})
return pageViewsSorted
}
router.post('/', auth, async(req, res, next) => {
try {
let thread, user
if(req.body.route === 'thread') {
thread = await Thread.findByPk(req.body.resourceId)
if(!thread) throw Errors.sequelizeValidation(Sequelize, {
error: 'thread does not exist',
value: req.body.resourceId
})
} else if(
req.body.route === 'userPosts' ||
req.body.route === 'userThreads' ||
req.body.route === 'userMarketplace' ||
req.body.route === 'userWall'
) {
user = await User.findByPk(req.body.resourceId)
if(!user) throw Errors.sequelizeValidation(Sequelize, {
error: 'User does not exist, or feature isn\'t implemented.',
value: req.body.resourceId
})
} else if(
(req.body.route === 'settingsGeneral' ||
req.body.route === 'settingsAccount') &&
!req.userData.loggedIn
) {
throw Errors.requestNotAuthorized
}
let log = await Log.create({
route: req.body.route
})
if(thread) await log.setThread(thread)
if(user) await log.setUser(user)
if(req.userData.username) {
let sessionUser = await User.findOne({
where: { username: req.userData.username }
})
await log.setSessionUser(sessionUser)
}
res.json(log.toJSON())
} catch (e) { next(e) }
})
router.all('*', auth, async(req, res, next) => {
let user = await User.findOne({ where: {
username: req.userData.username
}})
if(!user) throw Errors.requestNotAuthorized
if(req.userData.admin && user.admin) {
next()
} else {
res.status(401)
res.json({
errors: [Errors.sessionAdminProtection]
})
}
})
router.get('/top-threads', auth, async(req, res, next) => {
try {
let logs = await Log.findAll({
where: {
createdAt: {
$gt: new Date(Date.now() - 1000*60*60*24)
},
route: 'thread'
},
include: [Thread]
})
//Sum each log for a thread
let pageViewsObj = logs.reduce((obj, log) => {
//E.g. if thread deleted
if(!log.Thread) return obj;
if(!obj[log.Thread.id]) {
obj[log.Thread.id] = { Thread: log.Thread, pageViews: 1 }
} else {
obj[log.Thread.id].pageViews++
}
return obj
}, {})
//Transform to array
let pageViewsArr = Object.keys(pageViewsObj).map(id => {
return pageViewsObj[id]
})
//Sort by number of page views descending
let sortedPageViewsArr = pageViewsArr.sort((a, b) => {
if(a.pageViews < b.pageViews) {
return 1
} else if (a.pageViews > b.pageViews) {
return -1
} else {
return 0
}
})
//Return top 3
res.json(sortedPageViewsArr.slice(0, 4))
} catch (e) { next(e) }
})
router.get('/page-views', auth, async(req, res, next) => {
try {
let logs = await Log.findAll({
where: {
createdAt: {
$gt: lastWeek
}
},
order: [['createdAt', 'ASC']]
})
res.json(processLogsForLineChart(logs))
} catch (e) { next(e) }
})
router.get('/new-users', auth, async(req, res, next) => {
try {
let users = await User.findAll({
where: {
createdAt: {
$gt: lastWeek
}
},
order: [['createdAt', 'ASC']]
})
res.json(processLogsForLineChart(users))
} catch (e) { next(e) }
})
router.get('/categories', auth, async(req, res, next) => {
try {
let categories = await Category.findAll()
let categoryThreadCount = []
await Promise.all(categories.map(async category => {
let count = await Thread.count({ where: { CategoryId: category.id } })
categoryThreadCount.push({
value: count,
label: category.name,
color: category.color
})
}))
res.json(categoryThreadCount)
} catch (e) { next(e) }
})
router.get('/new-thread', auth, async(req, res, next) => {
try {
let now = Date.now()
let threadsTodayCount = await Thread.count({
where: {
createdAt: {
$gt: new Date(now - 1000*60*60*24)
}
}
})
let threadsYesterdayCount = await Thread.count({
where: {
createdAt: {
$lt: new Date(now - 1000*60*60*24),
$gt: new Date(now - 1000*60*60*24*2)
}
}
})
res.json({
count: threadsTodayCount,
change: threadsTodayCount - threadsYesterdayCount
})
} catch (e) { next(e) }
})
module.exports = router