X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Fmodels%2Fvideo%2Fvideo-channel.ts;h=67fccab68c11527b5a045f09503bd1d8e39d8874;hb=3b504f6ed4e890bebb46d0481aba15b43050323a;hp=410fd6d3f777c4e15c2bb0f509eb2012eb0210de;hpb=7b51ede977c299a74728171d8c124bcc4cbba6ea;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/models/video/video-channel.ts b/server/models/video/video-channel.ts index 410fd6d3f..67fccab68 100644 --- a/server/models/video/video-channel.ts +++ b/server/models/video/video-channel.ts @@ -19,7 +19,7 @@ import { } from 'sequelize-typescript' import { CONFIG } from '@server/initializers/config' import { MAccountActor } from '@server/types/models' -import { pick } from '@shared/core-utils' +import { forceNumber, pick } from '@shared/core-utils' import { AttributesOnly } from '@shared/typescript-utils' import { ActivityPubActor } from '../../../shared/models/activitypub' import { VideoChannel, VideoChannelSummary } from '../../../shared/models/videos' @@ -43,8 +43,14 @@ import { ActorModel, unusedActorAttributesForAPI } from '../actor/actor' import { ActorFollowModel } from '../actor/actor-follow' import { ActorImageModel } from '../actor/actor-image' import { ServerModel } from '../server/server' -import { setAsUpdated } from '../shared' -import { buildServerIdsFollowedBy, buildTrigramSearchIndex, createSimilarityAttribute, getSort, throwIfNotValid } from '../utils' +import { + buildServerIdsFollowedBy, + buildTrigramSearchIndex, + createSimilarityAttribute, + getSort, + setAsUpdated, + throwIfNotValid +} from '../shared' import { VideoModel } from './video' import { VideoPlaylistModel } from './video-playlist' @@ -143,28 +149,28 @@ export type SummaryOptions = { }) } - const channelInclude: Includeable[] = [] - const accountInclude: Includeable[] = [] + const channelActorInclude: Includeable[] = [] + const accountActorInclude: Includeable[] = [] if (options.forCount !== true) { - accountInclude.push({ + accountActorInclude.push({ model: ServerModel, required: false }) - accountInclude.push({ + accountActorInclude.push({ model: ActorImageModel, as: 'Avatars', required: false }) - channelInclude.push({ + channelActorInclude.push({ model: ActorImageModel, as: 'Avatars', required: false }) - channelInclude.push({ + channelActorInclude.push({ model: ActorImageModel, as: 'Banners', required: false @@ -172,7 +178,7 @@ export type SummaryOptions = { } if (options.forCount !== true || serverRequired) { - channelInclude.push({ + channelActorInclude.push({ model: ServerModel, duplicating: false, required: serverRequired, @@ -190,7 +196,7 @@ export type SummaryOptions = { where: { [Op.and]: whereActorAnd }, - include: channelInclude + include: channelActorInclude }, { model: AccountModel.unscoped(), @@ -202,7 +208,7 @@ export type SummaryOptions = { }, model: ActorModel.unscoped(), required: true, - include: accountInclude + include: accountActorInclude } ] } @@ -280,7 +286,7 @@ export type SummaryOptions = { ] }, [ScopeNames.WITH_STATS]: (options: AvailableWithStatsOptions = { daysPrior: 30 }) => { - const daysPrior = parseInt(options.daysPrior + '', 10) + const daysPrior = forceNumber(options.daysPrior) return { attributes: { @@ -311,6 +317,16 @@ export type SummaryOptions = { ')' ), 'viewsPerDay' + ], + [ + literal( + '(' + + 'SELECT COALESCE(SUM("video".views), 0) AS totalViews ' + + 'FROM "video" ' + + 'WHERE "video"."channelId" = "VideoChannelModel"."id"' + + ')' + ), + 'totalViews' ] ] } @@ -419,47 +435,46 @@ export class VideoChannelModel extends Model Now() - interval '${days}d')` + : '' + 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"` + SELECT COUNT(DISTINCT("VideoChannelModel"."id")) AS "count" + FROM "videoChannel" AS "VideoChannelModel" + ${videoJoin} + 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` 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) + const totalLocalVideoChannels = await getLocalVideoChannelStats() + const totalLocalDailyActiveVideoChannels = await getLocalVideoChannelStats(1) + const totalLocalWeeklyActiveVideoChannels = await getLocalVideoChannelStats(7) + const totalLocalMonthlyActiveVideoChannels = await getLocalVideoChannelStats(30) + const totalLocalHalfYearActiveVideoChannels = await getLocalVideoChannelStats(180) return { totalLocalVideoChannels, totalLocalDailyActiveVideoChannels, totalLocalWeeklyActiveVideoChannels, totalLocalMonthlyActiveVideoChannels, - totalHalfYearActiveVideoChannels + totalLocalHalfYearActiveVideoChannels } } @@ -605,17 +620,17 @@ ON "Account->Actor"."serverId" = "Account->Actor->Server"."id"` } } - const scopes: string | ScopeOptions | (string | ScopeOptions)[] = [ ScopeNames.WITH_ACTOR_BANNER ] + const findScopes: string | ScopeOptions | (string | ScopeOptions)[] = [ ScopeNames.WITH_ACTOR_BANNER ] if (options.withStats === true) { - scopes.push({ + findScopes.push({ method: [ ScopeNames.WITH_STATS, { daysPrior: 30 } as AvailableWithStatsOptions ] }) } return Promise.all([ - VideoChannelModel.scope(scopes).count(getQuery(true)), - VideoChannelModel.scope(scopes).findAll(getQuery(false)) + VideoChannelModel.unscoped().count(getQuery(true)), + VideoChannelModel.scope(findScopes).findAll(getQuery(false)) ]).then(([ total, data ]) => ({ total, data })) } @@ -766,6 +781,8 @@ ON "Account->Actor"."serverId" = "Account->Actor->Server"."id"` }) } + const totalViews = this.get('totalViews') as number + const actor = this.Actor.toFormattedJSON() const videoChannel = { id: this.id, @@ -779,6 +796,7 @@ ON "Account->Actor"."serverId" = "Account->Actor->Server"."id"` videosCount, viewsPerDay, + totalViews, avatars: actor.avatars, @@ -791,8 +809,8 @@ ON "Account->Actor"."serverId" = "Account->Actor->Server"."id"` return Object.assign(actor, videoChannel) } - toActivityPubObject (this: MChannelAP): ActivityPubActor { - const obj = this.Actor.toActivityPubObject(this.name) + async toActivityPubObject (this: MChannelAP): Promise { + const obj = await this.Actor.toActivityPubObject(this.name) return Object.assign(obj, { summary: this.description, @@ -819,6 +837,6 @@ ON "Account->Actor"."serverId" = "Account->Actor->Server"."id"` } setAsUpdated (transaction?: Transaction) { - return setAsUpdated('videoChannel', this.id, transaction) + return setAsUpdated({ sequelize: this.sequelize, table: 'videoChannel', id: this.id, transaction }) } }