add channel and playlist stats to server stats endpoint (#3747)

* add channel and playlist stats to nodeinfo

* add tests for active video channels stats

* fix tests for active channel stats
This commit is contained in:
Rigel Kent
2021-04-12 11:19:07 +02:00
committed by GitHub
parent a472cf0330
commit fe19f600da
5 changed files with 193 additions and 24 deletions

View File

@@ -1,4 +1,4 @@
import { FindOptions, Includeable, literal, Op, ScopeOptions } from 'sequelize'
import { FindOptions, Includeable, literal, Op, QueryTypes, ScopeOptions } from 'sequelize'
import {
AllowNull,
BeforeDestroy,
@@ -338,6 +338,47 @@ export class VideoChannelModel extends Model {
return VideoChannelModel.count(query)
}
static async getStats () {
function getActiveVideoChannels (days: number) {
const options = {
type: QueryTypes.SELECT as QueryTypes.SELECT,
raw: true
}
const query = `
SELECT COUNT(DISTINCT("VideoChannelModel"."id")) AS "count"
FROM "videoChannel" AS "VideoChannelModel"
INNER JOIN "video" AS "Videos"
ON "VideoChannelModel"."id" = "Videos"."channelId"
AND ("Videos"."publishedAt" > Now() - interval '${days}d')
INNER JOIN "account" AS "Account"
ON "VideoChannelModel"."accountId" = "Account"."id"
INNER JOIN "actor" AS "Account->Actor"
ON "Account"."actorId" = "Account->Actor"."id"
AND "Account->Actor"."serverId" IS NULL
LEFT OUTER JOIN "server" AS "Account->Actor->Server"
ON "Account->Actor"."serverId" = "Account->Actor->Server"."id"`
return VideoChannelModel.sequelize.query<{ count: string }>(query, options)
.then(r => parseInt(r[0].count, 10))
}
const totalLocalVideoChannels = await VideoChannelModel.count()
const totalLocalDailyActiveVideoChannels = await getActiveVideoChannels(1)
const totalLocalWeeklyActiveVideoChannels = await getActiveVideoChannels(7)
const totalLocalMonthlyActiveVideoChannels = await getActiveVideoChannels(30)
const totalHalfYearActiveVideoChannels = await getActiveVideoChannels(180)
return {
totalLocalVideoChannels,
totalLocalDailyActiveVideoChannels,
totalLocalWeeklyActiveVideoChannels,
totalLocalMonthlyActiveVideoChannels,
totalHalfYearActiveVideoChannels
}
}
static listForApi (parameters: {
actorId: number
start: number

View File

@@ -54,6 +54,7 @@ import { buildServerIdsFollowedBy, buildWhereIdOrUUID, getPlaylistSort, isOutdat
import { ThumbnailModel } from './thumbnail'
import { ScopeNames as VideoChannelScopeNames, VideoChannelModel } from './video-channel'
import { VideoPlaylistElementModel } from './video-playlist-element'
import { ActorModel } from '../activitypub/actor'
enum ScopeNames {
AVAILABLE_FOR_LIST = 'AVAILABLE_FOR_LIST',
@@ -65,7 +66,7 @@ enum ScopeNames {
}
type AvailableForListOptions = {
followerActorId: number
followerActorId?: number
type?: VideoPlaylistType
accountId?: number
videoChannelId?: number
@@ -134,20 +135,26 @@ type AvailableForListOptions = {
privacy: VideoPlaylistPrivacy.PUBLIC
})
// Only list local playlists OR playlists that are on an instance followed by actorId
const inQueryInstanceFollow = buildServerIdsFollowedBy(options.followerActorId)
// Only list local playlists
const whereActorOr: WhereOptions[] = [
{
serverId: null
}
]
// … OR playlists that are on an instance followed by actorId
if (options.followerActorId) {
const inQueryInstanceFollow = buildServerIdsFollowedBy(options.followerActorId)
whereActorOr.push({
serverId: {
[Op.in]: literal(inQueryInstanceFollow)
}
})
}
whereActor = {
[Op.or]: [
{
serverId: null
},
{
serverId: {
[Op.in]: literal(inQueryInstanceFollow)
}
}
]
[Op.or]: whereActorOr
}
}
@@ -495,6 +502,33 @@ export class VideoPlaylistModel extends Model {
return '/video-playlists/embed/' + this.uuid
}
static async getStats () {
const totalLocalPlaylists = await VideoPlaylistModel.count({
include: [
{
model: AccountModel,
required: true,
include: [
{
model: ActorModel,
required: true,
where: {
serverId: null
}
}
]
}
],
where: {
privacy: VideoPlaylistPrivacy.PUBLIC
}
})
return {
totalLocalPlaylists
}
}
setAsRefreshed () {
this.changed('updatedAt', true)