From 443358ccce168d2ee67f8f3a47bd4b12b01ff2de Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 31 Oct 2023 10:02:19 +0100 Subject: [PATCH] Reduce video comment sql query size --- .../video-static-file-privacy.ts | 11 ++++++++--- server/core/controllers/activitypub/inbox.ts | 2 +- .../core/lib/activitypub/send/send-create.ts | 5 ++++- .../core/lib/activitypub/send/send-delete.ts | 8 ++++++-- .../activitypub/send/shared/audience-utils.ts | 6 +++--- server/core/lib/activitypub/video-comments.ts | 2 ++ server/core/models/video/video-comment.ts | 18 ++++++++++++++++-- .../core/types/models/video/video-channel.ts | 7 +++++++ .../core/types/models/video/video-comment.ts | 6 +++--- server/core/types/models/video/video.ts | 5 +++++ 10 files changed, 55 insertions(+), 15 deletions(-) diff --git a/packages/tests/src/api/object-storage/video-static-file-privacy.ts b/packages/tests/src/api/object-storage/video-static-file-privacy.ts index cf6e9b4b9..7a22de926 100644 --- a/packages/tests/src/api/object-storage/video-static-file-privacy.ts +++ b/packages/tests/src/api/object-storage/video-static-file-privacy.ts @@ -352,13 +352,18 @@ describe('Object storage for video static file privacy', function () { await makeRawRequest({ url, token: server.accessToken, expectedStatus: HttpStatusCode.OK_200 }) await makeRawRequest({ url, query: { videoFileToken: fileToken }, expectedStatus: HttpStatusCode.OK_200 }) - if (videoPassword) { - await makeRawRequest({ url, headers: { 'x-peertube-video-password': videoPassword }, expectedStatus: HttpStatusCode.OK_200 }) - } + await makeRawRequest({ url, token: userToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) await makeRawRequest({ url, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) await makeRawRequest({ url, query: { videoFileToken: unrelatedFileToken }, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) + if (videoPassword) { + await makeRawRequest({ + url, + headers: { 'x-peertube-video-password': videoPassword }, + expectedStatus: HttpStatusCode.OK_200 + }) + await makeRawRequest({ url, headers: { 'x-peertube-video-password': 'incorrectPassword' }, diff --git a/server/core/controllers/activitypub/inbox.ts b/server/core/controllers/activitypub/inbox.ts index 6473cea06..945d22547 100644 --- a/server/core/controllers/activitypub/inbox.ts +++ b/server/core/controllers/activitypub/inbox.ts @@ -64,7 +64,7 @@ function inboxController (req: express.Request, res: express.Response) { } // Only keep activities we are able to process - logger.debug('Filtering %d activities...', activities.length) + logger.debug('Filtering %d activities...', activities.length, { activities }) activities = activities.filter(a => isActivityValid(a)) logger.debug('We keep %d activities.', activities.length, { activities }) diff --git a/server/core/lib/activitypub/send/send-create.ts b/server/core/lib/activitypub/send/send-create.ts index 7f9721be3..7ab567d03 100644 --- a/server/core/lib/activitypub/send/send-create.ts +++ b/server/core/lib/activitypub/send/send-create.ts @@ -32,6 +32,7 @@ import { sendVideoRelatedActivity, unicastTo } from './shared/index.js' +import { AccountModel } from '@server/models/account/account.js' const lTags = loggerTagsFactory('ap', 'create') @@ -114,6 +115,8 @@ async function sendCreateVideoComment (comment: MCommentOwnerVideo, transaction: const isOrigin = comment.Video.isOwned() const byActor = comment.Account.Actor + const videoAccount = await AccountModel.load(comment.Video.VideoChannel.Account.id, transaction) + const threadParentComments = await VideoCommentModel.listThreadParentComments(comment, transaction) const commentObject = comment.toActivityPubObject(threadParentComments) as VideoCommentObject @@ -170,7 +173,7 @@ async function sendCreateVideoComment (comment: MCommentOwnerVideo, transaction: return unicastTo({ data: createActivity, byActor, - toActorUrl: comment.Video.VideoChannel.Account.Actor.getSharedInbox(), + toActorUrl: videoAccount.Actor.getSharedInbox(), contextType: 'Comment' }) }) diff --git a/server/core/lib/activitypub/send/send-delete.ts b/server/core/lib/activitypub/send/send-delete.ts index 2f83da15d..3bf5ae75a 100644 --- a/server/core/lib/activitypub/send/send-delete.ts +++ b/server/core/lib/activitypub/send/send-delete.ts @@ -11,6 +11,7 @@ import { audiencify } from '../audience.js' import { getDeleteActivityPubUrl } from '../url.js' import { getActorsInvolvedInVideo, getVideoCommentAudience } from './shared/index.js' import { broadcastToActors, broadcastToFollowers, sendVideoRelatedActivity, unicastTo } from './shared/send-utils.js' +import { AccountModel } from '@server/models/account/account.js' async function sendDeleteVideo (video: MVideoAccountLight, transaction: Transaction) { logger.info('Creating job to broadcast delete of video %s.', video.url) @@ -55,9 +56,12 @@ async function sendDeleteVideoComment (videoComment: MCommentOwnerVideo, transac const isVideoOrigin = videoComment.Video.isOwned() const url = getDeleteActivityPubUrl(videoComment.url) + + const videoAccount = await AccountModel.load(videoComment.Video.VideoChannel.Account.id, transaction) + const byActor = videoComment.isOwned() ? videoComment.Account.Actor - : videoComment.Video.VideoChannel.Account.Actor + : videoAccount.Actor const threadParentComments = await VideoCommentModel.listThreadParentComments(videoComment, transaction) const threadParentCommentsFiltered = threadParentComments.filter(c => !c.isDeleted()) @@ -105,7 +109,7 @@ async function sendDeleteVideoComment (videoComment: MCommentOwnerVideo, transac return unicastTo({ data: activity, byActor, - toActorUrl: videoComment.Video.VideoChannel.Account.Actor.getSharedInbox(), + toActorUrl: videoAccount.Actor.getSharedInbox(), contextType: 'Delete' }) }) diff --git a/server/core/lib/activitypub/send/shared/audience-utils.ts b/server/core/lib/activitypub/send/shared/audience-utils.ts index ac88c4567..4d06df148 100644 --- a/server/core/lib/activitypub/send/shared/audience-utils.ts +++ b/server/core/lib/activitypub/send/shared/audience-utils.ts @@ -53,10 +53,10 @@ function getAudienceFromFollowersOf (actorsInvolvedInObject: MActorFollowersUrl[ async function getActorsInvolvedInVideo (video: MVideoId, t: Transaction) { const actors = await VideoShareModel.listActorIdsAndFollowerUrlsByShare(video.id, t) - const videoAll = video as VideoModel + const alreadyLoadedActor = (video as VideoModel).VideoChannel?.Account?.Actor - const videoActor = videoAll.VideoChannel?.Account - ? videoAll.VideoChannel.Account.Actor + const videoActor = alreadyLoadedActor?.url && alreadyLoadedActor?.followersUrl + ? alreadyLoadedActor : await ActorModel.loadAccountActorFollowerUrlByVideoId(video.id, t) actors.push(videoActor) diff --git a/server/core/lib/activitypub/video-comments.ts b/server/core/lib/activitypub/video-comments.ts index 9da89ef0c..f3072988a 100644 --- a/server/core/lib/activitypub/video-comments.ts +++ b/server/core/lib/activitypub/video-comments.ts @@ -173,6 +173,8 @@ async function resolveRemoteParentComment (params: ResolveThreadParams) { }) as MCommentOwner comment.Account = actor ? actor.Account : null + logger.debug('Created remote comment %s', comment.url, { comment }) + return resolveThread({ url: body.inReplyTo, comments: comments.concat([ comment ]), diff --git a/server/core/models/video/video-comment.ts b/server/core/models/video/video-comment.ts index 001ef85bb..052c53a3d 100644 --- a/server/core/models/video/video-comment.ts +++ b/server/core/models/video/video-comment.ts @@ -71,12 +71,26 @@ export enum ScopeNames { required: true, include: [ { - model: VideoChannelModel, + model: VideoChannelModel.unscoped(), + attributes: [ 'id', 'accountId' ], required: true, include: [ { - model: AccountModel, + attributes: [ 'id', 'url' ], + model: ActorModel.unscoped(), required: true + }, + { + attributes: [ 'id' ], + model: AccountModel.unscoped(), + required: true, + include: [ + { + attributes: [ 'id', 'url' ], + model: ActorModel.unscoped(), + required: true + } + ] } ] } diff --git a/server/core/types/models/video/video-channel.ts b/server/core/types/models/video/video-channel.ts index e8cb9cb26..b3a74aa53 100644 --- a/server/core/types/models/video/video-channel.ts +++ b/server/core/types/models/video/video-channel.ts @@ -5,6 +5,7 @@ import { MAccountAPI, MAccountDefault, MAccountFormattable, + MAccountId, MAccountLight, MAccountSummaryBlocks, MAccountSummaryFormattable, @@ -22,6 +23,7 @@ import { MActorFormattable, MActorHost, MActorHostOnly, + MActorId, MActorLight, MActorSummary, MActorSummaryFormattable, @@ -49,6 +51,11 @@ export type MChannelUserId = Pick & Use<'Account', MAccountUserId> +export type MChannelAccountIdUrl = + Pick & + Use<'Actor', MActorUrl & MActorId> & + Use<'Account', MAccountId & MAccountUrl> + export type MChannelActor = MChannel & Use<'Actor', MActor> diff --git a/server/core/types/models/video/video-comment.ts b/server/core/types/models/video/video-comment.ts index d4fd34f7c..a7247911c 100644 --- a/server/core/types/models/video/video-comment.ts +++ b/server/core/types/models/video/video-comment.ts @@ -1,7 +1,7 @@ import { PickWith, PickWithOpt } from '@peertube/peertube-typescript-utils' import { VideoCommentModel } from '../../../models/video/video-comment.js' import { MAccountDefault, MAccountFormattable, MAccountUrl } from '../account/index.js' -import { MVideo, MVideoAccountLight, MVideoFeed, MVideoIdUrl, MVideoUrl } from './video.js' +import { MVideo, MVideoAccountIdUrl, MVideoAccountLight, MVideoFeed, MVideoIdUrl, MVideoUrl } from './video.js' type Use = PickWith @@ -29,12 +29,12 @@ export type MCommentReply = export type MCommentOwnerVideo = MComment & Use<'Account', MAccountDefault> & - Use<'Video', MVideoAccountLight> + Use<'Video', MVideoAccountIdUrl> export type MCommentOwnerVideoReply = MComment & Use<'Account', MAccountDefault> & - Use<'Video', MVideoAccountLight> & + Use<'Video', MVideoAccountIdUrl> & Use<'InReplyToVideoComment', MComment> export type MCommentOwnerReplyVideoLight = diff --git a/server/core/types/models/video/video.ts b/server/core/types/models/video/video.ts index f9141681b..d6f62648a 100644 --- a/server/core/types/models/video/video.ts +++ b/server/core/types/models/video/video.ts @@ -10,6 +10,7 @@ import { MVideoBlacklist, MVideoBlacklistLight, MVideoBlacklistUnfederated } fro import { MVideoCaptionLanguage, MVideoCaptionLanguageUrl } from './video-caption.js' import { MChannelAccountDefault, + MChannelAccountIdUrl, MChannelAccountLight, MChannelAccountSummaryFormattable, MChannelActor, @@ -136,6 +137,10 @@ export type MVideoAccountDefault = MVideo & Use<'VideoChannel', MChannelAccountDefault> +export type MVideoAccountIdUrl = + MVideo & + Use<'VideoChannel', MChannelAccountIdUrl> + export type MVideoThumbnailAccountDefault = MVideo & Use<'Thumbnails', MThumbnail[]> &