Optimize views per day in video channels

pull/2871/head
Chocobozzz 2020-06-12 16:01:42 +02:00
parent e74bda21d1
commit 5a61ffbb7c
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
3 changed files with 22 additions and 22 deletions

View File

@ -1,20 +1,20 @@
import * as express from 'express' import * as express from 'express'
import { body, param, query } from 'express-validator' import { body, param, query } from 'express-validator'
import { VIDEO_CHANNELS } from '@server/initializers/constants'
import { MChannelAccountDefault, MUser } from '@server/typings/models'
import { UserRight } from '../../../../shared' import { UserRight } from '../../../../shared'
import { isActorPreferredUsernameValid } from '../../../helpers/custom-validators/activitypub/actor'
import { isBooleanValid, toBooleanOrNull } from '../../../helpers/custom-validators/misc'
import { import {
isVideoChannelDescriptionValid, isVideoChannelDescriptionValid,
isVideoChannelNameValid, isVideoChannelNameValid,
isVideoChannelSupportValid isVideoChannelSupportValid
} from '../../../helpers/custom-validators/video-channels' } from '../../../helpers/custom-validators/video-channels'
import { logger } from '../../../helpers/logger' import { logger } from '../../../helpers/logger'
import { doesLocalVideoChannelNameExist, doesVideoChannelNameWithHostExist } from '../../../helpers/middlewares'
import { ActorModel } from '../../../models/activitypub/actor'
import { VideoChannelModel } from '../../../models/video/video-channel' import { VideoChannelModel } from '../../../models/video/video-channel'
import { areValidationErrors } from '../utils' import { areValidationErrors } from '../utils'
import { isActorPreferredUsernameValid } from '../../../helpers/custom-validators/activitypub/actor'
import { ActorModel } from '../../../models/activitypub/actor'
import { isBooleanValid } from '../../../helpers/custom-validators/misc'
import { doesLocalVideoChannelNameExist, doesVideoChannelNameWithHostExist } from '../../../helpers/middlewares'
import { MChannelAccountDefault, MUser } from '@server/typings/models'
import { VIDEO_CHANNELS } from '@server/initializers/constants'
const videoChannelsAddValidator = [ const videoChannelsAddValidator = [
body('name').custom(isActorPreferredUsernameValid).withMessage('Should have a valid channel name'), body('name').custom(isActorPreferredUsernameValid).withMessage('Should have a valid channel name'),
@ -129,7 +129,10 @@ const localVideoChannelValidator = [
] ]
const videoChannelStatsValidator = [ const videoChannelStatsValidator = [
query('withStats').optional().isBoolean().withMessage('Should have a valid stats flag'), query('withStats')
.optional()
.customSanitizer(toBooleanOrNull)
.custom(isBooleanValid).withMessage('Should have a valid stats flag'),
(req: express.Request, res: express.Response, next: express.NextFunction) => { (req: express.Request, res: express.Response, next: express.NextFunction) => {
if (areValidationErrors(req, res)) return if (areValidationErrors(req, res)) return

View File

@ -181,20 +181,16 @@ export type SummaryOptions = {
'days AS ( ' + 'days AS ( ' +
`SELECT generate_series(date_trunc('day', now()) - '${daysPrior} day'::interval, ` + `SELECT generate_series(date_trunc('day', now()) - '${daysPrior} day'::interval, ` +
`date_trunc('day', now()), '1 day'::interval) AS day ` + `date_trunc('day', now()), '1 day'::interval) AS day ` +
'), ' +
'views AS ( ' +
'SELECT v.* ' +
'FROM "videoView" AS v ' +
'INNER JOIN "video" ON "video"."id" = v."videoId" ' +
'WHERE "video"."channelId" = "VideoChannelModel"."id" ' +
') ' + ') ' +
'SELECT days.day AS day, ' + 'SELECT days.day AS day, COALESCE(SUM("videoView".views), 0) AS views ' +
'COALESCE(SUM(views.views), 0) AS views ' + 'FROM days ' +
'FROM days ' + 'LEFT JOIN (' +
`LEFT JOIN views ON date_trunc('day', "views"."startDate") = date_trunc('day', days.day) ` + '"videoView" INNER JOIN "video" ON "videoView"."videoId" = "video"."id" ' +
'GROUP BY day ' + 'AND "video"."channelId" = "VideoChannelModel"."id"' +
'ORDER BY day ' + `) ON date_trunc('day', "videoView"."startDate") = date_trunc('day', days.day) ` +
') t' + 'GROUP BY day ' +
'ORDER BY day ' +
') t' +
')' ')'
), ),
'viewsPerDay' 'viewsPerDay'
@ -413,7 +409,7 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
const scopes: string | ScopeOptions | (string | ScopeOptions)[] = [ ScopeNames.WITH_ACTOR ] const scopes: string | ScopeOptions | (string | ScopeOptions)[] = [ ScopeNames.WITH_ACTOR ]
if (options.withStats) { if (options.withStats === true) {
scopes.push({ scopes.push({
method: [ ScopeNames.WITH_STATS, { daysPrior: 30 } as AvailableWithStatsOptions ] method: [ ScopeNames.WITH_STATS, { daysPrior: 30 } as AvailableWithStatsOptions ]
}) })
@ -560,7 +556,7 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
createdAt: this.createdAt, createdAt: this.createdAt,
updatedAt: this.updatedAt, updatedAt: this.updatedAt,
ownerAccount: undefined, ownerAccount: undefined,
viewsPerDay: viewsPerDay !== undefined viewsPerDay: viewsPerDay
? viewsPerDay.split(',').map(v => { ? viewsPerDay.split(',').map(v => {
const o = v.split('|') const o = v.split('|')
return { return {

View File

@ -366,6 +366,7 @@ describe('Test video channels', function () {
}) })
it('Should report correct channel statistics', async function () { it('Should report correct channel statistics', async function () {
this.timeout(10000)
{ {
const res = await getAccountVideoChannelsList({ const res = await getAccountVideoChannelsList({