]>
Commit | Line | Data |
---|---|---|
54141398 | 1 | import { Transaction } from 'sequelize' |
3fd3ab2d | 2 | import { ActivityAudience, ActivityCreate } from '../../../../shared/models/activitypub' |
50d6de9c | 3 | import { VideoPrivacy } from '../../../../shared/models/videos' |
50d6de9c | 4 | import { ActorModel } from '../../../models/activitypub/actor' |
3fd3ab2d C |
5 | import { VideoModel } from '../../../models/video/video' |
6 | import { VideoAbuseModel } from '../../../models/video/video-abuse' | |
ea44f375 | 7 | import { VideoCommentModel } from '../../../models/video/video-comment' |
0032ebe9 | 8 | import { getVideoAbuseActivityPubUrl, getVideoDislikeActivityPubUrl, getVideoViewActivityPubUrl } from '../url' |
a2377d15 C |
9 | import { broadcastToActors, broadcastToFollowers, sendVideoRelatedActivity, unicastTo } from './utils' |
10 | import { audiencify, getActorsInvolvedInVideo, getAudience, getAudienceFromFollowersOf, getVideoCommentAudience } from '../audience' | |
8e0fd45e | 11 | import { logger } from '../../../helpers/logger' |
c48e82b5 | 12 | import { VideoRedundancyModel } from '../../../models/redundancy/video-redundancy' |
54141398 | 13 | |
50d6de9c | 14 | async function sendCreateVideo (video: VideoModel, t: Transaction) { |
54b38063 | 15 | if (video.privacy === VideoPrivacy.PRIVATE) return undefined |
54141398 | 16 | |
8e0fd45e C |
17 | logger.info('Creating job to send video creation of %s.', video.url) |
18 | ||
e12a0092 | 19 | const byActor = video.VideoChannel.Account.Actor |
50d6de9c | 20 | const videoObject = video.toActivityPubObject() |
e12a0092 | 21 | |
2186386c | 22 | const audience = getAudience(byActor, video.privacy === VideoPrivacy.PUBLIC) |
c48e82b5 | 23 | const createActivity = buildCreateActivity(video.url, byActor, videoObject, audience) |
54141398 | 24 | |
c48e82b5 | 25 | return broadcastToFollowers(createActivity, byActor, [ byActor ], t) |
54141398 C |
26 | } |
27 | ||
c48e82b5 | 28 | async function sendVideoAbuse (byActor: ActorModel, videoAbuse: VideoAbuseModel, video: VideoModel) { |
06a05d5f C |
29 | if (!video.VideoChannel.Account.Actor.serverId) return // Local |
30 | ||
54141398 | 31 | const url = getVideoAbuseActivityPubUrl(videoAbuse) |
40ff5707 | 32 | |
8e0fd45e C |
33 | logger.info('Creating job to send video abuse %s.', url) |
34 | ||
a2377d15 | 35 | // Custom audience, we only send the abuse to the origin instance |
50d6de9c | 36 | const audience = { to: [ video.VideoChannel.Account.Actor.url ], cc: [] } |
c48e82b5 | 37 | const createActivity = buildCreateActivity(url, byActor, videoAbuse.toActivityPubObject(), audience) |
40ff5707 | 38 | |
c48e82b5 C |
39 | return unicastTo(createActivity, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl) |
40 | } | |
41 | ||
42 | async function sendCreateCacheFile (byActor: ActorModel, fileRedundancy: VideoRedundancyModel) { | |
43 | logger.info('Creating job to send file cache of %s.', fileRedundancy.url) | |
44 | ||
c48e82b5 | 45 | const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(fileRedundancy.VideoFile.Video.id) |
a2377d15 | 46 | const redundancyObject = fileRedundancy.toActivityPubObject() |
c48e82b5 | 47 | |
a2377d15 C |
48 | return sendVideoRelatedCreateActivity({ |
49 | byActor, | |
50 | video, | |
51 | url: fileRedundancy.url, | |
52 | object: redundancyObject | |
53 | }) | |
40ff5707 C |
54 | } |
55 | ||
07197db4 | 56 | async function sendCreateVideoComment (comment: VideoCommentModel, t: Transaction) { |
8e0fd45e C |
57 | logger.info('Creating job to send comment %s.', comment.url) |
58 | ||
07197db4 C |
59 | const isOrigin = comment.Video.isOwned() |
60 | ||
ea44f375 | 61 | const byActor = comment.Account.Actor |
d7e70384 C |
62 | const threadParentComments = await VideoCommentModel.listThreadParentComments(comment, t) |
63 | const commentObject = comment.toActivityPubObject(threadParentComments) | |
ea44f375 | 64 | |
93ef8a9d | 65 | const actorsInvolvedInComment = await getActorsInvolvedInVideo(comment.Video, t) |
a2377d15 | 66 | // Add the actor that commented too |
93ef8a9d | 67 | actorsInvolvedInComment.push(byActor) |
93ef8a9d | 68 | |
07197db4 | 69 | const parentsCommentActors = threadParentComments.map(c => c.Account.Actor) |
ea44f375 | 70 | |
07197db4 C |
71 | let audience: ActivityAudience |
72 | if (isOrigin) { | |
73 | audience = getVideoCommentAudience(comment, threadParentComments, actorsInvolvedInComment, isOrigin) | |
74 | } else { | |
a2377d15 | 75 | audience = getAudienceFromFollowersOf(actorsInvolvedInComment.concat(parentsCommentActors)) |
07197db4 | 76 | } |
93ef8a9d | 77 | |
c48e82b5 | 78 | const createActivity = buildCreateActivity(comment.url, byActor, commentObject, audience) |
ea44f375 | 79 | |
93ef8a9d C |
80 | // This was a reply, send it to the parent actors |
81 | const actorsException = [ byActor ] | |
c48e82b5 | 82 | await broadcastToActors(createActivity, byActor, parentsCommentActors, actorsException) |
93ef8a9d C |
83 | |
84 | // Broadcast to our followers | |
c48e82b5 | 85 | await broadcastToFollowers(createActivity, byActor, [ byActor ], t) |
93ef8a9d C |
86 | |
87 | // Send to actors involved in the comment | |
c48e82b5 | 88 | if (isOrigin) return broadcastToFollowers(createActivity, byActor, actorsInvolvedInComment, t, actorsException) |
07197db4 C |
89 | |
90 | // Send to origin | |
c48e82b5 | 91 | return unicastTo(createActivity, byActor, comment.Video.VideoChannel.Account.Actor.sharedInboxUrl) |
ea44f375 C |
92 | } |
93 | ||
07197db4 | 94 | async function sendCreateView (byActor: ActorModel, video: VideoModel, t: Transaction) { |
8e0fd45e C |
95 | logger.info('Creating job to send view of %s.', video.url) |
96 | ||
50d6de9c | 97 | const url = getVideoViewActivityPubUrl(byActor, video) |
5c6d985f | 98 | const viewActivity = buildViewActivity(url, byActor, video) |
40ff5707 | 99 | |
a2377d15 C |
100 | return sendVideoRelatedCreateActivity({ |
101 | // Use the server actor to send the view | |
102 | byActor, | |
103 | video, | |
104 | url, | |
105 | object: viewActivity, | |
106 | transaction: t | |
107 | }) | |
0032ebe9 C |
108 | } |
109 | ||
07197db4 | 110 | async function sendCreateDislike (byActor: ActorModel, video: VideoModel, t: Transaction) { |
8e0fd45e C |
111 | logger.info('Creating job to dislike %s.', video.url) |
112 | ||
50d6de9c | 113 | const url = getVideoDislikeActivityPubUrl(byActor, video) |
5c6d985f | 114 | const dislikeActivity = buildDislikeActivity(url, byActor, video) |
0032ebe9 | 115 | |
a2377d15 C |
116 | return sendVideoRelatedCreateActivity({ |
117 | byActor, | |
118 | video, | |
119 | url, | |
120 | object: dislikeActivity, | |
121 | transaction: t | |
122 | }) | |
40ff5707 C |
123 | } |
124 | ||
c48e82b5 | 125 | function buildCreateActivity (url: string, byActor: ActorModel, object: any, audience?: ActivityAudience): ActivityCreate { |
2186386c C |
126 | if (!audience) audience = getAudience(byActor) |
127 | ||
128 | return audiencify( | |
129 | { | |
130 | type: 'Create' as 'Create', | |
131 | id: url + '/activity', | |
132 | actor: byActor.url, | |
133 | object: audiencify(object, audience) | |
134 | }, | |
135 | audience | |
136 | ) | |
54141398 C |
137 | } |
138 | ||
5c6d985f | 139 | function buildDislikeActivity (url: string, byActor: ActorModel, video: VideoModel) { |
3fd3ab2d | 140 | return { |
5c6d985f | 141 | id: url, |
0032ebe9 | 142 | type: 'Dislike', |
50d6de9c | 143 | actor: byActor.url, |
0032ebe9 C |
144 | object: video.url |
145 | } | |
0032ebe9 C |
146 | } |
147 | ||
5c6d985f | 148 | function buildViewActivity (url: string, byActor: ActorModel, video: VideoModel) { |
ea44f375 | 149 | return { |
5c6d985f | 150 | id: url, |
ea44f375 C |
151 | type: 'View', |
152 | actor: byActor.url, | |
153 | object: video.url | |
154 | } | |
155 | } | |
156 | ||
54141398 C |
157 | // --------------------------------------------------------------------------- |
158 | ||
159 | export { | |
50d6de9c | 160 | sendCreateVideo, |
54141398 | 161 | sendVideoAbuse, |
c48e82b5 | 162 | buildCreateActivity, |
07197db4 C |
163 | sendCreateView, |
164 | sendCreateDislike, | |
c48e82b5 C |
165 | buildDislikeActivity, |
166 | sendCreateVideoComment, | |
167 | sendCreateCacheFile | |
54141398 | 168 | } |
a2377d15 C |
169 | |
170 | // --------------------------------------------------------------------------- | |
171 | ||
172 | async function sendVideoRelatedCreateActivity (options: { | |
173 | byActor: ActorModel, | |
174 | video: VideoModel, | |
175 | url: string, | |
176 | object: any, | |
177 | transaction?: Transaction | |
178 | }) { | |
179 | const activityBuilder = (audience: ActivityAudience) => { | |
180 | return buildCreateActivity(options.url, options.byActor, options.object, audience) | |
181 | } | |
182 | ||
183 | return sendVideoRelatedActivity(activityBuilder, options) | |
184 | } |