]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/lib/activitypub/videos/shared/creator.ts
Refactor AP video create/update
[github/Chocobozzz/PeerTube.git] / server / lib / activitypub / videos / shared / creator.ts
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 }