]>
Commit | Line | Data |
---|---|---|
0d0e8dd0 C |
1 | import { VideoChannelObject, VideoTorrentObject } from '../../../shared' |
2 | import { ActivityUpdate } from '../../../shared/models/activitypub/activity' | |
3 | import { getOrCreateAccount } from '../../helpers/activitypub' | |
4 | import { retryTransactionWrapper } from '../../helpers/database-utils' | |
5 | import { logger } from '../../helpers/logger' | |
6 | import { resetSequelizeInstance } from '../../helpers/utils' | |
7 | import { database as db } from '../../initializers' | |
8 | import { AccountInstance } from '../../models/account/account-interface' | |
9 | import { VideoInstance } from '../../models/video/video-interface' | |
10 | import { videoActivityObjectToDBAttributes, videoFileActivityUrlToDBAttributes } from './misc' | |
11 | import Bluebird = require('bluebird') | |
12 | ||
13 | async function processUpdateActivity (activity: ActivityUpdate) { | |
14 | const account = await getOrCreateAccount(activity.actor) | |
e4f97bab | 15 | |
e4f97bab | 16 | if (activity.object.type === 'Video') { |
0d0e8dd0 | 17 | return processUpdateVideo(account, activity.object) |
e4f97bab | 18 | } else if (activity.object.type === 'VideoChannel') { |
0d0e8dd0 | 19 | return processUpdateVideoChannel(account, activity.object) |
e4f97bab | 20 | } |
0d0e8dd0 C |
21 | |
22 | return undefined | |
e4f97bab C |
23 | } |
24 | ||
25 | // --------------------------------------------------------------------------- | |
26 | ||
27 | export { | |
28 | processUpdateActivity | |
29 | } | |
30 | ||
31 | // --------------------------------------------------------------------------- | |
32 | ||
0d0e8dd0 C |
33 | function processUpdateVideo (account: AccountInstance, video: VideoTorrentObject) { |
34 | const options = { | |
35 | arguments: [ account, video ], | |
36 | errorMessage: 'Cannot update the remote video with many retries' | |
37 | } | |
e4f97bab | 38 | |
0d0e8dd0 | 39 | return retryTransactionWrapper(updateRemoteVideo, options) |
e4f97bab C |
40 | } |
41 | ||
0d0e8dd0 C |
42 | async function updateRemoteVideo (account: AccountInstance, videoAttributesToUpdate: VideoTorrentObject) { |
43 | logger.debug('Updating remote video "%s".', videoAttributesToUpdate.uuid) | |
44 | let videoInstance: VideoInstance | |
45 | let videoFieldsSave: object | |
46 | ||
47 | try { | |
48 | await db.sequelize.transaction(async t => { | |
49 | const sequelizeOptions = { | |
50 | transaction: t | |
51 | } | |
52 | ||
d7d5611c | 53 | const videoInstance = await db.Video.loadByUrlAndPopulateAccount(videoAttributesToUpdate.id, t) |
0d0e8dd0 C |
54 | if (!videoInstance) throw new Error('Video ' + videoAttributesToUpdate.id + ' not found.') |
55 | ||
56 | if (videoInstance.VideoChannel.Account.id !== account.id) { | |
57 | throw new Error('Account ' + account.url + ' does not own video channel ' + videoInstance.VideoChannel.url) | |
58 | } | |
59 | ||
d7d5611c | 60 | const videoData = await videoActivityObjectToDBAttributes(videoInstance.VideoChannel, videoAttributesToUpdate) |
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) | |
66 | videoInstance.set('description', videoData.description) | |
67 | videoInstance.set('duration', videoData.duration) | |
68 | videoInstance.set('createdAt', videoData.createdAt) | |
69 | videoInstance.set('updatedAt', videoData.updatedAt) | |
70 | videoInstance.set('views', videoData.views) | |
71 | // videoInstance.set('likes', videoData.likes) | |
72 | // videoInstance.set('dislikes', videoData.dislikes) | |
0d0e8dd0 C |
73 | |
74 | await videoInstance.save(sequelizeOptions) | |
75 | ||
76 | // Remove old video files | |
77 | const videoFileDestroyTasks: Bluebird<void>[] = [] | |
78 | for (const videoFile of videoInstance.VideoFiles) { | |
79 | videoFileDestroyTasks.push(videoFile.destroy(sequelizeOptions)) | |
80 | } | |
81 | await Promise.all(videoFileDestroyTasks) | |
82 | ||
83 | const videoFileAttributes = await videoFileActivityUrlToDBAttributes(videoInstance, videoAttributesToUpdate) | |
84 | const tasks: Bluebird<any>[] = videoFileAttributes.map(f => db.VideoFile.create(f)) | |
85 | await Promise.all(tasks) | |
86 | ||
87 | const tags = videoAttributesToUpdate.tag.map(t => t.name) | |
88 | const tagInstances = await db.Tag.findOrCreateTags(tags, t) | |
89 | await videoInstance.setTags(tagInstances, sequelizeOptions) | |
90 | }) | |
91 | ||
92 | logger.info('Remote video with uuid %s updated', videoAttributesToUpdate.uuid) | |
93 | } catch (err) { | |
94 | if (videoInstance !== undefined && videoFieldsSave !== undefined) { | |
95 | resetSequelizeInstance(videoInstance, videoFieldsSave) | |
96 | } | |
97 | ||
98 | // This is just a debug because we will retry the insert | |
99 | logger.debug('Cannot update the remote video.', err) | |
100 | throw err | |
101 | } | |
102 | } | |
103 | ||
104 | async function processUpdateVideoChannel (account: AccountInstance, videoChannel: VideoChannelObject) { | |
105 | const options = { | |
106 | arguments: [ account, videoChannel ], | |
107 | errorMessage: 'Cannot update the remote video channel with many retries.' | |
108 | } | |
109 | ||
110 | await retryTransactionWrapper(updateRemoteVideoChannel, options) | |
111 | } | |
112 | ||
113 | async function updateRemoteVideoChannel (account: AccountInstance, videoChannel: VideoChannelObject) { | |
114 | logger.debug('Updating remote video channel "%s".', videoChannel.uuid) | |
115 | ||
116 | await db.sequelize.transaction(async t => { | |
117 | const sequelizeOptions = { transaction: t } | |
118 | ||
119 | const videoChannelInstance = await db.VideoChannel.loadByUrl(videoChannel.id) | |
120 | if (!videoChannelInstance) throw new Error('Video ' + videoChannel.id + ' not found.') | |
121 | ||
122 | if (videoChannelInstance.Account.id !== account.id) { | |
123 | throw new Error('Account ' + account.id + ' does not own video channel ' + videoChannelInstance.url) | |
124 | } | |
125 | ||
126 | videoChannelInstance.set('name', videoChannel.name) | |
127 | videoChannelInstance.set('description', videoChannel.content) | |
128 | videoChannelInstance.set('createdAt', videoChannel.published) | |
129 | videoChannelInstance.set('updatedAt', videoChannel.updated) | |
130 | ||
131 | await videoChannelInstance.save(sequelizeOptions) | |
132 | }) | |
e4f97bab | 133 | |
0d0e8dd0 | 134 | logger.info('Remote video channel with uuid %s updated', videoChannel.uuid) |
e4f97bab | 135 | } |