aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models/video
diff options
context:
space:
mode:
authorRigel Kent <sendmemail@rigelk.eu>2021-04-12 11:19:07 +0200
committerGitHub <noreply@github.com>2021-04-12 11:19:07 +0200
commitfe19f600dab0f6b00a7aa146ba4bd4bb96536155 (patch)
treebe388f89a41cbc257fc9a642a9205b4910b7a6b7 /server/models/video
parenta472cf033003cf96b69a80808b2dce1fe382e09b (diff)
downloadPeerTube-fe19f600dab0f6b00a7aa146ba4bd4bb96536155.tar.gz
PeerTube-fe19f600dab0f6b00a7aa146ba4bd4bb96536155.tar.zst
PeerTube-fe19f600dab0f6b00a7aa146ba4bd4bb96536155.zip
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
Diffstat (limited to 'server/models/video')
-rw-r--r--server/models/video/video-channel.ts43
-rw-r--r--server/models/video/video-playlist.ts60
2 files changed, 89 insertions, 14 deletions
diff --git a/server/models/video/video-channel.ts b/server/models/video/video-channel.ts
index d2a055f5b..b7ffbd3b1 100644
--- a/server/models/video/video-channel.ts
+++ b/server/models/video/video-channel.ts
@@ -1,4 +1,4 @@
1import { FindOptions, Includeable, literal, Op, ScopeOptions } from 'sequelize' 1import { FindOptions, Includeable, literal, Op, QueryTypes, ScopeOptions } from 'sequelize'
2import { 2import {
3 AllowNull, 3 AllowNull,
4 BeforeDestroy, 4 BeforeDestroy,
@@ -338,6 +338,47 @@ export class VideoChannelModel extends Model {
338 return VideoChannelModel.count(query) 338 return VideoChannelModel.count(query)
339 } 339 }
340 340
341 static async getStats () {
342
343 function getActiveVideoChannels (days: number) {
344 const options = {
345 type: QueryTypes.SELECT as QueryTypes.SELECT,
346 raw: true
347 }
348
349 const query = `
350SELECT COUNT(DISTINCT("VideoChannelModel"."id")) AS "count"
351FROM "videoChannel" AS "VideoChannelModel"
352INNER JOIN "video" AS "Videos"
353ON "VideoChannelModel"."id" = "Videos"."channelId"
354AND ("Videos"."publishedAt" > Now() - interval '${days}d')
355INNER JOIN "account" AS "Account"
356ON "VideoChannelModel"."accountId" = "Account"."id"
357INNER JOIN "actor" AS "Account->Actor"
358ON "Account"."actorId" = "Account->Actor"."id"
359AND "Account->Actor"."serverId" IS NULL
360LEFT OUTER JOIN "server" AS "Account->Actor->Server"
361ON "Account->Actor"."serverId" = "Account->Actor->Server"."id"`
362
363 return VideoChannelModel.sequelize.query<{ count: string }>(query, options)
364 .then(r => parseInt(r[0].count, 10))
365 }
366
367 const totalLocalVideoChannels = await VideoChannelModel.count()
368 const totalLocalDailyActiveVideoChannels = await getActiveVideoChannels(1)
369 const totalLocalWeeklyActiveVideoChannels = await getActiveVideoChannels(7)
370 const totalLocalMonthlyActiveVideoChannels = await getActiveVideoChannels(30)
371 const totalHalfYearActiveVideoChannels = await getActiveVideoChannels(180)
372
373 return {
374 totalLocalVideoChannels,
375 totalLocalDailyActiveVideoChannels,
376 totalLocalWeeklyActiveVideoChannels,
377 totalLocalMonthlyActiveVideoChannels,
378 totalHalfYearActiveVideoChannels
379 }
380 }
381
341 static listForApi (parameters: { 382 static listForApi (parameters: {
342 actorId: number 383 actorId: number
343 start: number 384 start: number
diff --git a/server/models/video/video-playlist.ts b/server/models/video/video-playlist.ts
index 49a406608..efe5be36d 100644
--- a/server/models/video/video-playlist.ts
+++ b/server/models/video/video-playlist.ts
@@ -54,6 +54,7 @@ import { buildServerIdsFollowedBy, buildWhereIdOrUUID, getPlaylistSort, isOutdat
54import { ThumbnailModel } from './thumbnail' 54import { ThumbnailModel } from './thumbnail'
55import { ScopeNames as VideoChannelScopeNames, VideoChannelModel } from './video-channel' 55import { ScopeNames as VideoChannelScopeNames, VideoChannelModel } from './video-channel'
56import { VideoPlaylistElementModel } from './video-playlist-element' 56import { VideoPlaylistElementModel } from './video-playlist-element'
57import { ActorModel } from '../activitypub/actor'
57 58
58enum ScopeNames { 59enum ScopeNames {
59 AVAILABLE_FOR_LIST = 'AVAILABLE_FOR_LIST', 60 AVAILABLE_FOR_LIST = 'AVAILABLE_FOR_LIST',
@@ -65,7 +66,7 @@ enum ScopeNames {
65} 66}
66 67
67type AvailableForListOptions = { 68type AvailableForListOptions = {
68 followerActorId: number 69 followerActorId?: number
69 type?: VideoPlaylistType 70 type?: VideoPlaylistType
70 accountId?: number 71 accountId?: number
71 videoChannelId?: number 72 videoChannelId?: number
@@ -134,20 +135,26 @@ type AvailableForListOptions = {
134 privacy: VideoPlaylistPrivacy.PUBLIC 135 privacy: VideoPlaylistPrivacy.PUBLIC
135 }) 136 })
136 137
137 // Only list local playlists OR playlists that are on an instance followed by actorId 138 // Only list local playlists
138 const inQueryInstanceFollow = buildServerIdsFollowedBy(options.followerActorId) 139 const whereActorOr: WhereOptions[] = [
140 {
141 serverId: null
142 }
143 ]
139 144
140 whereActor = { 145 // … OR playlists that are on an instance followed by actorId
141 [Op.or]: [ 146 if (options.followerActorId) {
142 { 147 const inQueryInstanceFollow = buildServerIdsFollowedBy(options.followerActorId)
143 serverId: null 148
144 }, 149 whereActorOr.push({
145 { 150 serverId: {
146 serverId: { 151 [Op.in]: literal(inQueryInstanceFollow)
147 [Op.in]: literal(inQueryInstanceFollow)
148 }
149 } 152 }
150 ] 153 })
154 }
155
156 whereActor = {
157 [Op.or]: whereActorOr
151 } 158 }
152 } 159 }
153 160
@@ -495,6 +502,33 @@ export class VideoPlaylistModel extends Model {
495 return '/video-playlists/embed/' + this.uuid 502 return '/video-playlists/embed/' + this.uuid
496 } 503 }
497 504
505 static async getStats () {
506 const totalLocalPlaylists = await VideoPlaylistModel.count({
507 include: [
508 {
509 model: AccountModel,
510 required: true,
511 include: [
512 {
513 model: ActorModel,
514 required: true,
515 where: {
516 serverId: null
517 }
518 }
519 ]
520 }
521 ],
522 where: {
523 privacy: VideoPlaylistPrivacy.PUBLIC
524 }
525 })
526
527 return {
528 totalLocalPlaylists
529 }
530 }
531
498 setAsRefreshed () { 532 setAsRefreshed () {
499 this.changed('updatedAt', true) 533 this.changed('updatedAt', true)
500 534