]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/lib/activitypub/process/process-update.ts
Begin moving video channel to actor
[github/Chocobozzz/PeerTube.git] / server / lib / activitypub / process / process-update.ts
CommitLineData
25ed141c 1import * as Bluebird from 'bluebird'
3fd3ab2d
C
2import { ActivityUpdate } from '../../../../shared/models/activitypub'
3import { logger, resetSequelizeInstance, retryTransactionWrapper } from '../../../helpers'
4import { sequelizeTypescript } from '../../../initializers'
50d6de9c 5import { ActorModel } from '../../../models/activitypub/actor'
3fd3ab2d
C
6import { TagModel } from '../../../models/video/tag'
7import { VideoModel } from '../../../models/video/video'
3fd3ab2d 8import { VideoFileModel } from '../../../models/video/video-file'
50d6de9c 9import { getOrCreateActorAndServerAndModel } from '../actor'
25ed141c 10import { videoActivityObjectToDBAttributes, videoFileActivityUrlToDBAttributes } from './misc'
0d0e8dd0
C
11
12async function processUpdateActivity (activity: ActivityUpdate) {
50d6de9c 13 const actor = await getOrCreateActorAndServerAndModel(activity.actor)
e4f97bab 14
e4f97bab 15 if (activity.object.type === 'Video') {
50d6de9c 16 return processUpdateVideo(actor, activity)
e4f97bab 17 }
0d0e8dd0 18
b1cbc0dd 19 return
e4f97bab
C
20}
21
22// ---------------------------------------------------------------------------
23
24export {
25 processUpdateActivity
26}
27
28// ---------------------------------------------------------------------------
29
50d6de9c 30function processUpdateVideo (actor: ActorModel, activity: ActivityUpdate) {
0d0e8dd0 31 const options = {
50d6de9c 32 arguments: [ actor, activity ],
0d0e8dd0
C
33 errorMessage: 'Cannot update the remote video with many retries'
34 }
e4f97bab 35
0d0e8dd0 36 return retryTransactionWrapper(updateRemoteVideo, options)
e4f97bab
C
37}
38
50d6de9c
C
39async function updateRemoteVideo (actor: ActorModel, activity: ActivityUpdate) {
40 const videoAttributesToUpdate = activity.object
41
0d0e8dd0 42 logger.debug('Updating remote video "%s".', videoAttributesToUpdate.uuid)
3fd3ab2d 43 let videoInstance: VideoModel
0d0e8dd0
C
44 let videoFieldsSave: object
45
46 try {
3fd3ab2d 47 await sequelizeTypescript.transaction(async t => {
0d0e8dd0
C
48 const sequelizeOptions = {
49 transaction: t
50 }
51
3fd3ab2d 52 const videoInstance = await VideoModel.loadByUrlAndPopulateAccount(videoAttributesToUpdate.id, t)
0d0e8dd0
C
53 if (!videoInstance) throw new Error('Video ' + videoAttributesToUpdate.id + ' not found.')
54
50d6de9c
C
55 const videoChannel = videoInstance.VideoChannel
56 if (videoChannel.Account.Actor.id !== actor.id) {
57 throw new Error('Account ' + actor.url + ' does not own video channel ' + videoChannel.Actor.url)
0d0e8dd0
C
58 }
59
50d6de9c 60 const videoData = await videoActivityObjectToDBAttributes(videoChannel, videoAttributesToUpdate, activity.to, activity.cc)
0d0e8dd0
C
61 videoInstance.set('name', videoData.name)
62 videoInstance.set('category', videoData.category)
63 videoInstance.set('licence', videoData.licence)
64 videoInstance.set('language', videoData.language)
65 videoInstance.set('nsfw', videoData.nsfw)
50d6de9c 66 videoInstance.set('privacy', videoData.privacy)
0d0e8dd0
C
67 videoInstance.set('description', videoData.description)
68 videoInstance.set('duration', videoData.duration)
69 videoInstance.set('createdAt', videoData.createdAt)
70 videoInstance.set('updatedAt', videoData.updatedAt)
71 videoInstance.set('views', videoData.views)
0d0e8dd0
C
72
73 await videoInstance.save(sequelizeOptions)
74
75 // Remove old video files
76 const videoFileDestroyTasks: Bluebird<void>[] = []
77 for (const videoFile of videoInstance.VideoFiles) {
78 videoFileDestroyTasks.push(videoFile.destroy(sequelizeOptions))
79 }
80 await Promise.all(videoFileDestroyTasks)
81
79d5caf9 82 const videoFileAttributes = videoFileActivityUrlToDBAttributes(videoInstance, videoAttributesToUpdate)
3fd3ab2d 83 const tasks: Bluebird<any>[] = videoFileAttributes.map(f => VideoFileModel.create(f))
0d0e8dd0
C
84 await Promise.all(tasks)
85
86 const tags = videoAttributesToUpdate.tag.map(t => t.name)
3fd3ab2d
C
87 const tagInstances = await TagModel.findOrCreateTags(tags, t)
88 await videoInstance.$set('Tags', tagInstances, sequelizeOptions)
0d0e8dd0
C
89 })
90
91 logger.info('Remote video with uuid %s updated', videoAttributesToUpdate.uuid)
92 } catch (err) {
93 if (videoInstance !== undefined && videoFieldsSave !== undefined) {
94 resetSequelizeInstance(videoInstance, videoFieldsSave)
95 }
96
97 // This is just a debug because we will retry the insert
98 logger.debug('Cannot update the remote video.', err)
99 throw err
100 }
101}