aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/lib/activitypub/process
diff options
context:
space:
mode:
Diffstat (limited to 'server/lib/activitypub/process')
-rw-r--r--server/lib/activitypub/process/process-announce.ts4
-rw-r--r--server/lib/activitypub/process/process-create.ts10
-rw-r--r--server/lib/activitypub/process/process-like.ts4
-rw-r--r--server/lib/activitypub/process/process-undo.ts6
-rw-r--r--server/lib/activitypub/process/process-update.ts99
5 files changed, 16 insertions, 107 deletions
diff --git a/server/lib/activitypub/process/process-announce.ts b/server/lib/activitypub/process/process-announce.ts
index b08156aa1..814556817 100644
--- a/server/lib/activitypub/process/process-announce.ts
+++ b/server/lib/activitypub/process/process-announce.ts
@@ -6,7 +6,7 @@ import { VideoModel } from '../../../models/video/video'
6import { VideoShareModel } from '../../../models/video/video-share' 6import { VideoShareModel } from '../../../models/video/video-share'
7import { getOrCreateActorAndServerAndModel } from '../actor' 7import { getOrCreateActorAndServerAndModel } from '../actor'
8import { forwardVideoRelatedActivity } from '../send/utils' 8import { forwardVideoRelatedActivity } from '../send/utils'
9import { getOrCreateAccountAndVideoAndChannel } from '../videos' 9import { getOrCreateVideoAndAccountAndChannel } from '../videos'
10 10
11async function processAnnounceActivity (activity: ActivityAnnounce) { 11async function processAnnounceActivity (activity: ActivityAnnounce) {
12 const actorAnnouncer = await getOrCreateActorAndServerAndModel(activity.actor) 12 const actorAnnouncer = await getOrCreateActorAndServerAndModel(activity.actor)
@@ -25,7 +25,7 @@ export {
25async function processVideoShare (actorAnnouncer: ActorModel, activity: ActivityAnnounce) { 25async function processVideoShare (actorAnnouncer: ActorModel, activity: ActivityAnnounce) {
26 const objectUri = typeof activity.object === 'string' ? activity.object : activity.object.id 26 const objectUri = typeof activity.object === 'string' ? activity.object : activity.object.id
27 27
28 const { video } = await getOrCreateAccountAndVideoAndChannel(objectUri) 28 const { video } = await getOrCreateVideoAndAccountAndChannel(objectUri)
29 29
30 return sequelizeTypescript.transaction(async t => { 30 return sequelizeTypescript.transaction(async t => {
31 // Add share entry 31 // Add share entry
diff --git a/server/lib/activitypub/process/process-create.ts b/server/lib/activitypub/process/process-create.ts
index 9655d015f..e8f5ade06 100644
--- a/server/lib/activitypub/process/process-create.ts
+++ b/server/lib/activitypub/process/process-create.ts
@@ -10,7 +10,7 @@ import { VideoAbuseModel } from '../../../models/video/video-abuse'
10import { VideoCommentModel } from '../../../models/video/video-comment' 10import { VideoCommentModel } from '../../../models/video/video-comment'
11import { getOrCreateActorAndServerAndModel } from '../actor' 11import { getOrCreateActorAndServerAndModel } from '../actor'
12import { resolveThread } from '../video-comments' 12import { resolveThread } from '../video-comments'
13import { getOrCreateAccountAndVideoAndChannel } from '../videos' 13import { getOrCreateVideoAndAccountAndChannel } from '../videos'
14import { forwardActivity, forwardVideoRelatedActivity } from '../send/utils' 14import { forwardActivity, forwardVideoRelatedActivity } from '../send/utils'
15 15
16async function processCreateActivity (activity: ActivityCreate) { 16async function processCreateActivity (activity: ActivityCreate) {
@@ -45,7 +45,7 @@ export {
45async function processCreateVideo (activity: ActivityCreate) { 45async function processCreateVideo (activity: ActivityCreate) {
46 const videoToCreateData = activity.object as VideoTorrentObject 46 const videoToCreateData = activity.object as VideoTorrentObject
47 47
48 const { video } = await getOrCreateAccountAndVideoAndChannel(videoToCreateData) 48 const { video } = await getOrCreateVideoAndAccountAndChannel(videoToCreateData)
49 49
50 return video 50 return video
51} 51}
@@ -56,7 +56,7 @@ async function processCreateDislike (byActor: ActorModel, activity: ActivityCrea
56 56
57 if (!byAccount) throw new Error('Cannot create dislike with the non account actor ' + byActor.url) 57 if (!byAccount) throw new Error('Cannot create dislike with the non account actor ' + byActor.url)
58 58
59 const { video } = await getOrCreateAccountAndVideoAndChannel(dislike.object) 59 const { video } = await getOrCreateVideoAndAccountAndChannel(dislike.object)
60 60
61 return sequelizeTypescript.transaction(async t => { 61 return sequelizeTypescript.transaction(async t => {
62 const rate = { 62 const rate = {
@@ -83,7 +83,7 @@ async function processCreateDislike (byActor: ActorModel, activity: ActivityCrea
83async function processCreateView (byActor: ActorModel, activity: ActivityCreate) { 83async function processCreateView (byActor: ActorModel, activity: ActivityCreate) {
84 const view = activity.object as ViewObject 84 const view = activity.object as ViewObject
85 85
86 const { video } = await getOrCreateAccountAndVideoAndChannel(view.object) 86 const { video } = await getOrCreateVideoAndAccountAndChannel(view.object)
87 87
88 const actor = await ActorModel.loadByUrl(view.actor) 88 const actor = await ActorModel.loadByUrl(view.actor)
89 if (!actor) throw new Error('Unknown actor ' + view.actor) 89 if (!actor) throw new Error('Unknown actor ' + view.actor)
@@ -103,7 +103,7 @@ async function processCreateVideoAbuse (actor: ActorModel, videoAbuseToCreateDat
103 const account = actor.Account 103 const account = actor.Account
104 if (!account) throw new Error('Cannot create dislike with the non account actor ' + actor.url) 104 if (!account) throw new Error('Cannot create dislike with the non account actor ' + actor.url)
105 105
106 const { video } = await getOrCreateAccountAndVideoAndChannel(videoAbuseToCreateData.object) 106 const { video } = await getOrCreateVideoAndAccountAndChannel(videoAbuseToCreateData.object)
107 107
108 return sequelizeTypescript.transaction(async t => { 108 return sequelizeTypescript.transaction(async t => {
109 const videoAbuseData = { 109 const videoAbuseData = {
diff --git a/server/lib/activitypub/process/process-like.ts b/server/lib/activitypub/process/process-like.ts
index d0865b78c..9e1664fd8 100644
--- a/server/lib/activitypub/process/process-like.ts
+++ b/server/lib/activitypub/process/process-like.ts
@@ -5,7 +5,7 @@ import { AccountVideoRateModel } from '../../../models/account/account-video-rat
5import { ActorModel } from '../../../models/activitypub/actor' 5import { ActorModel } from '../../../models/activitypub/actor'
6import { getOrCreateActorAndServerAndModel } from '../actor' 6import { getOrCreateActorAndServerAndModel } from '../actor'
7import { forwardVideoRelatedActivity } from '../send/utils' 7import { forwardVideoRelatedActivity } from '../send/utils'
8import { getOrCreateAccountAndVideoAndChannel } from '../videos' 8import { getOrCreateVideoAndAccountAndChannel } from '../videos'
9 9
10async function processLikeActivity (activity: ActivityLike) { 10async function processLikeActivity (activity: ActivityLike) {
11 const actor = await getOrCreateActorAndServerAndModel(activity.actor) 11 const actor = await getOrCreateActorAndServerAndModel(activity.actor)
@@ -27,7 +27,7 @@ async function processLikeVideo (byActor: ActorModel, activity: ActivityLike) {
27 const byAccount = byActor.Account 27 const byAccount = byActor.Account
28 if (!byAccount) throw new Error('Cannot create like with the non account actor ' + byActor.url) 28 if (!byAccount) throw new Error('Cannot create like with the non account actor ' + byActor.url)
29 29
30 const { video } = await getOrCreateAccountAndVideoAndChannel(videoUrl) 30 const { video } = await getOrCreateVideoAndAccountAndChannel(videoUrl)
31 31
32 return sequelizeTypescript.transaction(async t => { 32 return sequelizeTypescript.transaction(async t => {
33 const rate = { 33 const rate = {
diff --git a/server/lib/activitypub/process/process-undo.ts b/server/lib/activitypub/process/process-undo.ts
index b6de107ad..eab9e3d61 100644
--- a/server/lib/activitypub/process/process-undo.ts
+++ b/server/lib/activitypub/process/process-undo.ts
@@ -9,7 +9,7 @@ import { AccountVideoRateModel } from '../../../models/account/account-video-rat
9import { ActorModel } from '../../../models/activitypub/actor' 9import { ActorModel } from '../../../models/activitypub/actor'
10import { ActorFollowModel } from '../../../models/activitypub/actor-follow' 10import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
11import { forwardVideoRelatedActivity } from '../send/utils' 11import { forwardVideoRelatedActivity } from '../send/utils'
12import { getOrCreateAccountAndVideoAndChannel } from '../videos' 12import { getOrCreateVideoAndAccountAndChannel } from '../videos'
13import { VideoShareModel } from '../../../models/video/video-share' 13import { VideoShareModel } from '../../../models/video/video-share'
14 14
15async function processUndoActivity (activity: ActivityUndo) { 15async function processUndoActivity (activity: ActivityUndo) {
@@ -43,7 +43,7 @@ export {
43async function processUndoLike (actorUrl: string, activity: ActivityUndo) { 43async function processUndoLike (actorUrl: string, activity: ActivityUndo) {
44 const likeActivity = activity.object as ActivityLike 44 const likeActivity = activity.object as ActivityLike
45 45
46 const { video } = await getOrCreateAccountAndVideoAndChannel(likeActivity.object) 46 const { video } = await getOrCreateVideoAndAccountAndChannel(likeActivity.object)
47 47
48 return sequelizeTypescript.transaction(async t => { 48 return sequelizeTypescript.transaction(async t => {
49 const byAccount = await AccountModel.loadByUrl(actorUrl, t) 49 const byAccount = await AccountModel.loadByUrl(actorUrl, t)
@@ -67,7 +67,7 @@ async function processUndoLike (actorUrl: string, activity: ActivityUndo) {
67async function processUndoDislike (actorUrl: string, activity: ActivityUndo) { 67async function processUndoDislike (actorUrl: string, activity: ActivityUndo) {
68 const dislike = activity.object.object as DislikeObject 68 const dislike = activity.object.object as DislikeObject
69 69
70 const { video } = await getOrCreateAccountAndVideoAndChannel(dislike.object) 70 const { video } = await getOrCreateVideoAndAccountAndChannel(dislike.object)
71 71
72 return sequelizeTypescript.transaction(async t => { 72 return sequelizeTypescript.transaction(async t => {
73 const byAccount = await AccountModel.loadByUrl(actorUrl, t) 73 const byAccount = await AccountModel.loadByUrl(actorUrl, t)
diff --git a/server/lib/activitypub/process/process-update.ts b/server/lib/activitypub/process/process-update.ts
index 11226e275..07a5ff92f 100644
--- a/server/lib/activitypub/process/process-update.ts
+++ b/server/lib/activitypub/process/process-update.ts
@@ -1,4 +1,3 @@
1import * as Bluebird from 'bluebird'
2import { ActivityUpdate, VideoTorrentObject } from '../../../../shared/models/activitypub' 1import { ActivityUpdate, VideoTorrentObject } from '../../../../shared/models/activitypub'
3import { ActivityPubActor } from '../../../../shared/models/activitypub/activitypub-actor' 2import { ActivityPubActor } from '../../../../shared/models/activitypub/activitypub-actor'
4import { resetSequelizeInstance, retryTransactionWrapper } from '../../../helpers/database-utils' 3import { resetSequelizeInstance, retryTransactionWrapper } from '../../../helpers/database-utils'
@@ -6,19 +5,10 @@ import { logger } from '../../../helpers/logger'
6import { sequelizeTypescript } from '../../../initializers' 5import { sequelizeTypescript } from '../../../initializers'
7import { AccountModel } from '../../../models/account/account' 6import { AccountModel } from '../../../models/account/account'
8import { ActorModel } from '../../../models/activitypub/actor' 7import { ActorModel } from '../../../models/activitypub/actor'
9import { TagModel } from '../../../models/video/tag'
10import { VideoChannelModel } from '../../../models/video/video-channel' 8import { VideoChannelModel } from '../../../models/video/video-channel'
11import { VideoFileModel } from '../../../models/video/video-file'
12import { fetchAvatarIfExists, getOrCreateActorAndServerAndModel, updateActorAvatarInstance, updateActorInstance } from '../actor' 9import { fetchAvatarIfExists, getOrCreateActorAndServerAndModel, updateActorAvatarInstance, updateActorInstance } from '../actor'
13import { 10import { getOrCreateVideoAndAccountAndChannel, getOrCreateVideoChannel, updateVideoFromAP } from '../videos'
14 generateThumbnailFromUrl,
15 getOrCreateAccountAndVideoAndChannel,
16 getOrCreateVideoChannel,
17 videoActivityObjectToDBAttributes,
18 videoFileActivityUrlToDBAttributes
19} from '../videos'
20import { sanitizeAndCheckVideoTorrentObject } from '../../../helpers/custom-validators/activitypub/videos' 11import { sanitizeAndCheckVideoTorrentObject } from '../../../helpers/custom-validators/activitypub/videos'
21import { VideoCaptionModel } from '../../../models/video/video-caption'
22 12
23async function processUpdateActivity (activity: ActivityUpdate) { 13async function processUpdateActivity (activity: ActivityUpdate) {
24 const actor = await getOrCreateActorAndServerAndModel(activity.actor) 14 const actor = await getOrCreateActorAndServerAndModel(activity.actor)
@@ -49,91 +39,10 @@ async function processUpdateVideo (actor: ActorModel, activity: ActivityUpdate)
49 return undefined 39 return undefined
50 } 40 }
51 41
52 const res = await getOrCreateAccountAndVideoAndChannel(videoObject.id) 42 const { video } = await getOrCreateVideoAndAccountAndChannel(videoObject.id)
43 const channelActor = await getOrCreateVideoChannel(videoObject)
53 44
54 // Fetch video channel outside the transaction 45 return updateVideoFromAP(video, videoObject, actor, channelActor, activity.to)
55 const newVideoChannelActor = await getOrCreateVideoChannel(videoObject)
56 const newVideoChannel = newVideoChannelActor.VideoChannel
57
58 logger.debug('Updating remote video "%s".', videoObject.uuid)
59 let videoInstance = res.video
60 let videoFieldsSave: any
61
62 try {
63 await sequelizeTypescript.transaction(async t => {
64 const sequelizeOptions = {
65 transaction: t
66 }
67
68 videoFieldsSave = videoInstance.toJSON()
69
70 // Check actor has the right to update the video
71 const videoChannel = videoInstance.VideoChannel
72 if (videoChannel.Account.Actor.id !== actor.id) {
73 throw new Error('Account ' + actor.url + ' does not own video channel ' + videoChannel.Actor.url)
74 }
75
76 const videoData = await videoActivityObjectToDBAttributes(newVideoChannel, videoObject, activity.to)
77 videoInstance.set('name', videoData.name)
78 videoInstance.set('uuid', videoData.uuid)
79 videoInstance.set('url', videoData.url)
80 videoInstance.set('category', videoData.category)
81 videoInstance.set('licence', videoData.licence)
82 videoInstance.set('language', videoData.language)
83 videoInstance.set('description', videoData.description)
84 videoInstance.set('support', videoData.support)
85 videoInstance.set('nsfw', videoData.nsfw)
86 videoInstance.set('commentsEnabled', videoData.commentsEnabled)
87 videoInstance.set('waitTranscoding', videoData.waitTranscoding)
88 videoInstance.set('state', videoData.state)
89 videoInstance.set('duration', videoData.duration)
90 videoInstance.set('createdAt', videoData.createdAt)
91 videoInstance.set('updatedAt', videoData.updatedAt)
92 videoInstance.set('views', videoData.views)
93 videoInstance.set('privacy', videoData.privacy)
94 videoInstance.set('channelId', videoData.channelId)
95
96 await videoInstance.save(sequelizeOptions)
97
98 // Don't block on request
99 generateThumbnailFromUrl(videoInstance, videoObject.icon)
100 .catch(err => logger.warn('Cannot generate thumbnail of %s.', videoObject.id, { err }))
101
102 // Remove old video files
103 const videoFileDestroyTasks: Bluebird<void>[] = []
104 for (const videoFile of videoInstance.VideoFiles) {
105 videoFileDestroyTasks.push(videoFile.destroy(sequelizeOptions))
106 }
107 await Promise.all(videoFileDestroyTasks)
108
109 const videoFileAttributes = videoFileActivityUrlToDBAttributes(videoInstance, videoObject)
110 const tasks = videoFileAttributes.map(f => VideoFileModel.create(f, sequelizeOptions))
111 await Promise.all(tasks)
112
113 // Update Tags
114 const tags = videoObject.tag.map(tag => tag.name)
115 const tagInstances = await TagModel.findOrCreateTags(tags, t)
116 await videoInstance.$set('Tags', tagInstances, sequelizeOptions)
117
118 // Update captions
119 await VideoCaptionModel.deleteAllCaptionsOfRemoteVideo(videoInstance.id, t)
120
121 const videoCaptionsPromises = videoObject.subtitleLanguage.map(c => {
122 return VideoCaptionModel.insertOrReplaceLanguage(videoInstance.id, c.identifier, t)
123 })
124 await Promise.all(videoCaptionsPromises)
125 })
126
127 logger.info('Remote video with uuid %s updated', videoObject.uuid)
128 } catch (err) {
129 if (videoInstance !== undefined && videoFieldsSave !== undefined) {
130 resetSequelizeInstance(videoInstance, videoFieldsSave)
131 }
132
133 // This is just a debug because we will retry the insert
134 logger.debug('Cannot update the remote video.', { err })
135 throw err
136 }
137} 46}
138 47
139async function processUpdateActor (actor: ActorModel, activity: ActivityUpdate) { 48async function processUpdateActor (actor: ActorModel, activity: ActivityUpdate) {