X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Flib%2Factivitypub%2Fvideos%2Fshared%2Fabstract-builder.ts;h=f299ba4fd736b6530893feae9d9b6cb49cf45958;hb=7e98a7df7d04e19ba67163a86c7b876d78d76839;hp=953710f6c8e94f733d724656d1be95a8c35c7053;hpb=463206948d6a9d46e7e68d55c7b763e601ecc870;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/lib/activitypub/videos/shared/abstract-builder.ts b/server/lib/activitypub/videos/shared/abstract-builder.ts index 953710f6c..f299ba4fd 100644 --- a/server/lib/activitypub/videos/shared/abstract-builder.ts +++ b/server/lib/activitypub/videos/shared/abstract-builder.ts @@ -1,8 +1,7 @@ import { Transaction } from 'sequelize/types' -import { checkUrlsSameHost } from '@server/helpers/activitypub' -import { deleteNonExistingModels } from '@server/helpers/database-utils' +import { deleteAllModels, filterNonExistingModels } from '@server/helpers/database-utils' import { logger, LoggerTagsFn } from '@server/helpers/logger' -import { createPlaceholderThumbnail, createVideoMiniatureFromUrl } from '@server/lib/thumbnail' +import { updatePlaceholderThumbnail, updateVideoMiniatureFromUrl } from '@server/lib/thumbnail' import { setVideoTags } from '@server/lib/video' import { VideoCaptionModel } from '@server/models/video/video-caption' import { VideoFileModel } from '@server/models/video/video-file' @@ -10,7 +9,8 @@ import { VideoLiveModel } from '@server/models/video/video-live' import { VideoStreamingPlaylistModel } from '@server/models/video/video-streaming-playlist' import { MStreamingPlaylistFilesVideo, MThumbnail, MVideoCaption, MVideoFile, MVideoFullLight, MVideoThumbnail } from '@server/types/models' import { ActivityTagObject, ThumbnailType, VideoObject, VideoStreamingPlaylistType } from '@shared/models' -import { getOrCreateActorAndServerAndModel } from '../../actor' +import { getOrCreateAPActor } from '../../actors' +import { checkUrlsSameHost } from '../../url' import { getCaptionAttributesFromObject, getFileAttributesFromUrl, @@ -34,27 +34,27 @@ export abstract class APVideoAbstractBuilder { throw new Error(`Video channel url ${channel.id} does not have the same host than video object id ${this.videoObject.id}`) } - return getOrCreateActorAndServerAndModel(channel.id, 'all') + return getOrCreateAPActor(channel.id, 'all') } protected tryToGenerateThumbnail (video: MVideoThumbnail): Promise { - return createVideoMiniatureFromUrl({ + return updateVideoMiniatureFromUrl({ downloadUrl: getThumbnailFromIcons(this.videoObject).url, video, type: ThumbnailType.MINIATURE }).catch(err => { - logger.warn('Cannot generate thumbnail of %s.', this.videoObject.id, { err, ...this.lTags(video.uuid) }) + logger.warn('Cannot generate thumbnail of %s.', this.videoObject.id, { err, ...this.lTags() }) return undefined }) } - protected async setPreview (video: MVideoFullLight, t: Transaction) { + protected async setPreview (video: MVideoFullLight, t?: Transaction) { // Don't fetch the preview that could be big, create a placeholder instead const previewIcon = getPreviewFromIcons(this.videoObject) if (!previewIcon) return - const previewModel = createPlaceholderThumbnail({ + const previewModel = updatePlaceholderThumbnail({ fileUrl: previewIcon.url, video, type: ThumbnailType.PREVIEW, @@ -75,11 +75,28 @@ export abstract class APVideoAbstractBuilder { } protected async insertOrReplaceCaptions (video: MVideoFullLight, t: Transaction) { - const videoCaptionsPromises = getCaptionAttributesFromObject(video, this.videoObject) - .map(a => new VideoCaptionModel(a) as MVideoCaption) - .map(c => VideoCaptionModel.insertOrReplaceLanguage(c, t)) + const existingCaptions = await VideoCaptionModel.listVideoCaptions(video.id, t) - await Promise.all(videoCaptionsPromises) + let captionsToCreate = getCaptionAttributesFromObject(video, this.videoObject) + .map(a => new VideoCaptionModel(a) as MVideoCaption) + + for (const existingCaption of existingCaptions) { + // Only keep captions that do not already exist + const filtered = captionsToCreate.filter(c => !c.isEqual(existingCaption)) + + // This caption already exists, we don't need to destroy and create it + if (filtered.length !== captionsToCreate.length) { + captionsToCreate = filtered + continue + } + + // Destroy this caption that does not exist anymore + await existingCaption.destroy({ transaction: t }) + } + + for (const captionToCreate of captionsToCreate) { + await captionToCreate.save({ transaction: t }) + } } protected async insertOrReplaceLive (video: MVideoFullLight, transaction: Transaction) { @@ -94,8 +111,7 @@ export abstract class APVideoAbstractBuilder { const newVideoFiles = videoFileAttributes.map(a => new VideoFileModel(a)) // Remove video files that do not exist anymore - const destroyTasks = deleteNonExistingModels(video.VideoFiles || [], newVideoFiles, t) - await Promise.all(destroyTasks) + await deleteAllModels(filterNonExistingModels(video.VideoFiles || [], newVideoFiles), t) // Update or add other one const upsertTasks = newVideoFiles.map(f => VideoFileModel.customUpsert(f, 'video', t)) @@ -103,17 +119,15 @@ export abstract class APVideoAbstractBuilder { } protected async setStreamingPlaylists (video: MVideoFullLight, t: Transaction) { - const streamingPlaylistAttributes = getStreamingPlaylistAttributesFromObject(video, this.videoObject, video.VideoFiles || []) + const streamingPlaylistAttributes = getStreamingPlaylistAttributesFromObject(video, this.videoObject) const newStreamingPlaylists = streamingPlaylistAttributes.map(a => new VideoStreamingPlaylistModel(a)) // Remove video playlists that do not exist anymore - const destroyTasks = deleteNonExistingModels(video.VideoStreamingPlaylists || [], newStreamingPlaylists, t) - await Promise.all(destroyTasks) + await deleteAllModels(filterNonExistingModels(video.VideoStreamingPlaylists || [], newStreamingPlaylists), t) video.VideoStreamingPlaylists = [] for (const playlistAttributes of streamingPlaylistAttributes) { - const streamingPlaylistModel = await this.insertOrReplaceStreamingPlaylist(playlistAttributes, t) streamingPlaylistModel.Video = video @@ -146,8 +160,7 @@ export abstract class APVideoAbstractBuilder { const newVideoFiles: MVideoFile[] = getFileAttributesFromUrl(playlistModel, tagObjects).map(a => new VideoFileModel(a)) - const destroyTasks = deleteNonExistingModels(oldStreamingPlaylistFiles, newVideoFiles, t) - await Promise.all(destroyTasks) + await deleteAllModels(filterNonExistingModels(oldStreamingPlaylistFiles, newVideoFiles), t) // Update or add other one const upsertTasks = newVideoFiles.map(f => VideoFileModel.customUpsert(f, 'streaming-playlist', t))