diff options
Diffstat (limited to 'server/lib/activitypub')
-rw-r--r-- | server/lib/activitypub/videos/shared/abstract-builder.ts | 25 | ||||
-rw-r--r-- | server/lib/activitypub/videos/shared/creator.ts | 81 | ||||
-rw-r--r-- | server/lib/activitypub/videos/updater.ts | 11 |
3 files changed, 50 insertions, 67 deletions
diff --git a/server/lib/activitypub/videos/shared/abstract-builder.ts b/server/lib/activitypub/videos/shared/abstract-builder.ts index e50bf29dc..4f74316d3 100644 --- a/server/lib/activitypub/videos/shared/abstract-builder.ts +++ b/server/lib/activitypub/videos/shared/abstract-builder.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { CreationAttributes, Transaction } from 'sequelize/types' | 1 | import { CreationAttributes, Transaction } from 'sequelize/types' |
2 | import { deleteAllModels, filterNonExistingModels } from '@server/helpers/database-utils' | 2 | import { deleteAllModels, filterNonExistingModels } from '@server/helpers/database-utils' |
3 | import { logger, LoggerTagsFn } from '@server/helpers/logger' | 3 | import { logger, LoggerTagsFn } from '@server/helpers/logger' |
4 | import { updateRemoteThumbnail, updateVideoMiniatureFromUrl } from '@server/lib/thumbnail' | 4 | import { updateRemoteThumbnail } from '@server/lib/thumbnail' |
5 | import { setVideoTags } from '@server/lib/video' | 5 | import { setVideoTags } from '@server/lib/video' |
6 | import { StoryboardModel } from '@server/models/video/storyboard' | 6 | import { StoryboardModel } from '@server/models/video/storyboard' |
7 | import { VideoCaptionModel } from '@server/models/video/video-caption' | 7 | import { VideoCaptionModel } from '@server/models/video/video-caption' |
@@ -11,7 +11,6 @@ import { VideoStreamingPlaylistModel } from '@server/models/video/video-streamin | |||
11 | import { | 11 | import { |
12 | MStreamingPlaylistFiles, | 12 | MStreamingPlaylistFiles, |
13 | MStreamingPlaylistFilesVideo, | 13 | MStreamingPlaylistFilesVideo, |
14 | MThumbnail, | ||
15 | MVideoCaption, | 14 | MVideoCaption, |
16 | MVideoFile, | 15 | MVideoFile, |
17 | MVideoFullLight, | 16 | MVideoFullLight, |
@@ -42,16 +41,22 @@ export abstract class APVideoAbstractBuilder { | |||
42 | return getOrCreateAPActor(channel.id, 'all') | 41 | return getOrCreateAPActor(channel.id, 'all') |
43 | } | 42 | } |
44 | 43 | ||
45 | protected tryToGenerateThumbnail (video: MVideoThumbnail): Promise<MThumbnail> { | 44 | protected async setThumbnail (video: MVideoThumbnail, t?: Transaction) { |
46 | return updateVideoMiniatureFromUrl({ | 45 | const miniatureIcon = getThumbnailFromIcons(this.videoObject) |
47 | downloadUrl: getThumbnailFromIcons(this.videoObject).url, | 46 | if (!miniatureIcon) { |
48 | video, | 47 | logger.warn('Cannot find thumbnail in video object', { object: this.videoObject }) |
49 | type: ThumbnailType.MINIATURE | ||
50 | }).catch(err => { | ||
51 | logger.warn('Cannot generate thumbnail of %s.', this.videoObject.id, { err, ...this.lTags() }) | ||
52 | |||
53 | return undefined | 48 | return undefined |
49 | } | ||
50 | |||
51 | const miniatureModel = updateRemoteThumbnail({ | ||
52 | fileUrl: miniatureIcon.url, | ||
53 | video, | ||
54 | type: ThumbnailType.MINIATURE, | ||
55 | size: miniatureIcon, | ||
56 | onDisk: false // Lazy download remote thumbnails | ||
54 | }) | 57 | }) |
58 | |||
59 | await video.addAndSaveThumbnail(miniatureModel, t) | ||
55 | } | 60 | } |
56 | 61 | ||
57 | protected async setPreview (video: MVideoFullLight, t?: Transaction) { | 62 | protected async setPreview (video: MVideoFullLight, t?: Transaction) { |
diff --git a/server/lib/activitypub/videos/shared/creator.ts b/server/lib/activitypub/videos/shared/creator.ts index e6d7bc23c..3d646ef66 100644 --- a/server/lib/activitypub/videos/shared/creator.ts +++ b/server/lib/activitypub/videos/shared/creator.ts | |||
@@ -4,7 +4,7 @@ import { sequelizeTypescript } from '@server/initializers/database' | |||
4 | import { Hooks } from '@server/lib/plugins/hooks' | 4 | import { Hooks } from '@server/lib/plugins/hooks' |
5 | import { autoBlacklistVideoIfNeeded } from '@server/lib/video-blacklist' | 5 | import { autoBlacklistVideoIfNeeded } from '@server/lib/video-blacklist' |
6 | import { VideoModel } from '@server/models/video/video' | 6 | import { VideoModel } from '@server/models/video/video' |
7 | import { MThumbnail, MVideoFullLight, MVideoThumbnail } from '@server/types/models' | 7 | import { MVideoFullLight, MVideoThumbnail } from '@server/types/models' |
8 | import { VideoObject } from '@shared/models' | 8 | import { VideoObject } from '@shared/models' |
9 | import { APVideoAbstractBuilder } from './abstract-builder' | 9 | import { APVideoAbstractBuilder } from './abstract-builder' |
10 | import { getVideoAttributesFromObject } from './object-to-model-attributes' | 10 | import { getVideoAttributesFromObject } from './object-to-model-attributes' |
@@ -27,65 +27,38 @@ export class APVideoCreator extends APVideoAbstractBuilder { | |||
27 | const videoData = getVideoAttributesFromObject(channel, this.videoObject, this.videoObject.to) | 27 | const videoData = getVideoAttributesFromObject(channel, this.videoObject, this.videoObject.to) |
28 | const video = VideoModel.build({ ...videoData, likes: 0, dislikes: 0 }) as MVideoThumbnail | 28 | const video = VideoModel.build({ ...videoData, likes: 0, dislikes: 0 }) as MVideoThumbnail |
29 | 29 | ||
30 | const promiseThumbnail = this.tryToGenerateThumbnail(video) | ||
31 | |||
32 | let thumbnailModel: MThumbnail | ||
33 | if (waitThumbnail === true) { | ||
34 | thumbnailModel = await promiseThumbnail | ||
35 | } | ||
36 | |||
37 | const { autoBlacklisted, videoCreated } = await sequelizeTypescript.transaction(async t => { | 30 | const { autoBlacklisted, videoCreated } = await sequelizeTypescript.transaction(async t => { |
38 | try { | 31 | const videoCreated = await video.save({ transaction: t }) as MVideoFullLight |
39 | const videoCreated = await video.save({ transaction: t }) as MVideoFullLight | 32 | videoCreated.VideoChannel = channel |
40 | videoCreated.VideoChannel = channel | 33 | |
41 | 34 | await this.setThumbnail(videoCreated, t) | |
42 | if (thumbnailModel) await videoCreated.addAndSaveThumbnail(thumbnailModel, t) | 35 | await this.setPreview(videoCreated, t) |
43 | 36 | await this.setWebTorrentFiles(videoCreated, t) | |
44 | await this.setPreview(videoCreated, t) | 37 | await this.setStreamingPlaylists(videoCreated, t) |
45 | await this.setWebTorrentFiles(videoCreated, t) | 38 | await this.setTags(videoCreated, t) |
46 | await this.setStreamingPlaylists(videoCreated, t) | 39 | await this.setTrackers(videoCreated, t) |
47 | await this.setTags(videoCreated, t) | 40 | await this.insertOrReplaceCaptions(videoCreated, t) |
48 | await this.setTrackers(videoCreated, t) | 41 | await this.insertOrReplaceLive(videoCreated, t) |
49 | await this.insertOrReplaceCaptions(videoCreated, t) | 42 | await this.insertOrReplaceStoryboard(videoCreated, t) |
50 | await this.insertOrReplaceLive(videoCreated, t) | 43 | |
51 | await this.insertOrReplaceStoryboard(videoCreated, t) | 44 | // We added a video in this channel, set it as updated |
52 | 45 | await channel.setAsUpdated(t) | |
53 | // We added a video in this channel, set it as updated | 46 | |
54 | await channel.setAsUpdated(t) | 47 | const autoBlacklisted = await autoBlacklistVideoIfNeeded({ |
55 | 48 | video: videoCreated, | |
56 | const autoBlacklisted = await autoBlacklistVideoIfNeeded({ | 49 | user: undefined, |
57 | video: videoCreated, | 50 | isRemote: true, |
58 | user: undefined, | 51 | isNew: true, |
59 | isRemote: true, | 52 | transaction: t |
60 | isNew: true, | 53 | }) |
61 | transaction: t | ||
62 | }) | ||
63 | |||
64 | logger.info('Remote video with uuid %s inserted.', this.videoObject.uuid, this.lTags()) | ||
65 | 54 | ||
66 | Hooks.runAction('action:activity-pub.remote-video.created', { video: videoCreated, videoAPObject: this.videoObject }) | 55 | logger.info('Remote video with uuid %s inserted.', this.videoObject.uuid, this.lTags()) |
67 | 56 | ||
68 | return { autoBlacklisted, videoCreated } | 57 | Hooks.runAction('action:activity-pub.remote-video.created', { video: videoCreated, videoAPObject: this.videoObject }) |
69 | } catch (err) { | ||
70 | // FIXME: Use rollback hook when https://github.com/sequelize/sequelize/pull/13038 is released | ||
71 | if (thumbnailModel) await thumbnailModel.removeThumbnail() | ||
72 | 58 | ||
73 | throw err | 59 | return { autoBlacklisted, videoCreated } |
74 | } | ||
75 | }) | 60 | }) |
76 | 61 | ||
77 | if (waitThumbnail === false) { | ||
78 | // Error is already caught above | ||
79 | // eslint-disable-next-line @typescript-eslint/no-floating-promises | ||
80 | promiseThumbnail.then(thumbnailModel => { | ||
81 | if (!thumbnailModel) return | ||
82 | |||
83 | thumbnailModel = videoCreated.id | ||
84 | |||
85 | return thumbnailModel.save() | ||
86 | }) | ||
87 | } | ||
88 | |||
89 | return { autoBlacklisted, videoCreated } | 62 | return { autoBlacklisted, videoCreated } |
90 | } | 63 | } |
91 | } | 64 | } |
diff --git a/server/lib/activitypub/videos/updater.ts b/server/lib/activitypub/videos/updater.ts index 3a0886523..c98bce662 100644 --- a/server/lib/activitypub/videos/updater.ts +++ b/server/lib/activitypub/videos/updater.ts | |||
@@ -41,7 +41,7 @@ export class APVideoUpdater extends APVideoAbstractBuilder { | |||
41 | try { | 41 | try { |
42 | const channelActor = await this.getOrCreateVideoChannelFromVideoObject() | 42 | const channelActor = await this.getOrCreateVideoChannelFromVideoObject() |
43 | 43 | ||
44 | const thumbnailModel = await this.tryToGenerateThumbnail(this.video) | 44 | const thumbnailModel = await this.setThumbnail(this.video) |
45 | 45 | ||
46 | this.checkChannelUpdateOrThrow(channelActor) | 46 | this.checkChannelUpdateOrThrow(channelActor) |
47 | 47 | ||
@@ -58,8 +58,13 @@ export class APVideoUpdater extends APVideoAbstractBuilder { | |||
58 | runInReadCommittedTransaction(t => this.setTags(videoUpdated, t)), | 58 | runInReadCommittedTransaction(t => this.setTags(videoUpdated, t)), |
59 | runInReadCommittedTransaction(t => this.setTrackers(videoUpdated, t)), | 59 | runInReadCommittedTransaction(t => this.setTrackers(videoUpdated, t)), |
60 | runInReadCommittedTransaction(t => this.setStoryboard(videoUpdated, t)), | 60 | runInReadCommittedTransaction(t => this.setStoryboard(videoUpdated, t)), |
61 | this.setOrDeleteLive(videoUpdated), | 61 | runInReadCommittedTransaction(t => { |
62 | this.setPreview(videoUpdated) | 62 | return Promise.all([ |
63 | this.setPreview(videoUpdated, t), | ||
64 | this.setThumbnail(videoUpdated, t) | ||
65 | ]) | ||
66 | }), | ||
67 | this.setOrDeleteLive(videoUpdated) | ||
63 | ]) | 68 | ]) |
64 | 69 | ||
65 | await runInReadCommittedTransaction(t => this.setCaptions(videoUpdated, t)) | 70 | await runInReadCommittedTransaction(t => this.setCaptions(videoUpdated, t)) |