diff options
Diffstat (limited to 'server/lib/activitypub/videos/shared/creator.ts')
-rw-r--r-- | server/lib/activitypub/videos/shared/creator.ts | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/server/lib/activitypub/videos/shared/creator.ts b/server/lib/activitypub/videos/shared/creator.ts new file mode 100644 index 000000000..4f2d79374 --- /dev/null +++ b/server/lib/activitypub/videos/shared/creator.ts | |||
@@ -0,0 +1,90 @@ | |||
1 | |||
2 | import { logger } from '@server/helpers/logger' | ||
3 | import { sequelizeTypescript } from '@server/initializers/database' | ||
4 | import { autoBlacklistVideoIfNeeded } from '@server/lib/video-blacklist' | ||
5 | import { VideoModel } from '@server/models/video/video' | ||
6 | import { MChannelAccountLight, MThumbnail, MVideoFullLight, MVideoThumbnail } from '@server/types/models' | ||
7 | import { VideoObject } from '@shared/models' | ||
8 | import { APVideoAbstractBuilder } from './abstract-builder' | ||
9 | import { getVideoAttributesFromObject } from './object-to-model-attributes' | ||
10 | |||
11 | export class APVideoCreator extends APVideoAbstractBuilder { | ||
12 | protected readonly videoObject: VideoObject | ||
13 | private readonly channel: MChannelAccountLight | ||
14 | |||
15 | constructor (options: { | ||
16 | videoObject: VideoObject | ||
17 | channel: MChannelAccountLight | ||
18 | }) { | ||
19 | super() | ||
20 | |||
21 | this.videoObject = options.videoObject | ||
22 | this.channel = options.channel | ||
23 | } | ||
24 | |||
25 | async create (waitThumbnail = false) { | ||
26 | logger.debug('Adding remote video %s.', this.videoObject.id) | ||
27 | |||
28 | const videoData = await getVideoAttributesFromObject(this.channel, this.videoObject, this.videoObject.to) | ||
29 | const video = VideoModel.build(videoData) as MVideoThumbnail | ||
30 | |||
31 | const promiseThumbnail = this.tryToGenerateThumbnail(video) | ||
32 | |||
33 | let thumbnailModel: MThumbnail | ||
34 | if (waitThumbnail === true) { | ||
35 | thumbnailModel = await promiseThumbnail | ||
36 | } | ||
37 | |||
38 | const { autoBlacklisted, videoCreated } = await sequelizeTypescript.transaction(async t => { | ||
39 | try { | ||
40 | const videoCreated = await video.save({ transaction: t }) as MVideoFullLight | ||
41 | videoCreated.VideoChannel = this.channel | ||
42 | |||
43 | if (thumbnailModel) await videoCreated.addAndSaveThumbnail(thumbnailModel, t) | ||
44 | |||
45 | await this.setPreview(videoCreated, t) | ||
46 | await this.setWebTorrentFiles(videoCreated, t) | ||
47 | await this.setStreamingPlaylists(videoCreated, t) | ||
48 | await this.setTags(videoCreated, t) | ||
49 | await this.setTrackers(videoCreated, t) | ||
50 | await this.insertOrReplaceCaptions(videoCreated, t) | ||
51 | await this.insertOrReplaceLive(videoCreated, t) | ||
52 | |||
53 | // We added a video in this channel, set it as updated | ||
54 | await this.channel.setAsUpdated(t) | ||
55 | |||
56 | const autoBlacklisted = await autoBlacklistVideoIfNeeded({ | ||
57 | video: videoCreated, | ||
58 | user: undefined, | ||
59 | isRemote: true, | ||
60 | isNew: true, | ||
61 | transaction: t | ||
62 | }) | ||
63 | |||
64 | logger.info('Remote video with uuid %s inserted.', this.videoObject.uuid) | ||
65 | |||
66 | return { autoBlacklisted, videoCreated } | ||
67 | } catch (err) { | ||
68 | // FIXME: Use rollback hook when https://github.com/sequelize/sequelize/pull/13038 is released | ||
69 | // Remove thumbnail | ||
70 | if (thumbnailModel) await thumbnailModel.removeThumbnail() | ||
71 | |||
72 | throw err | ||
73 | } | ||
74 | }) | ||
75 | |||
76 | if (waitThumbnail === false) { | ||
77 | // Error is already caught above | ||
78 | // eslint-disable-next-line @typescript-eslint/no-floating-promises | ||
79 | promiseThumbnail.then(thumbnailModel => { | ||
80 | if (!thumbnailModel) return | ||
81 | |||
82 | thumbnailModel = videoCreated.id | ||
83 | |||
84 | return thumbnailModel.save() | ||
85 | }) | ||
86 | } | ||
87 | |||
88 | return { autoBlacklisted, videoCreated } | ||
89 | } | ||
90 | } | ||