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