]>
Commit | Line | Data |
---|---|---|
54141398 | 1 | import { Transaction } from 'sequelize' |
57e4e1c1 C |
2 | import { getServerActor } from '@server/models/application/application' |
3 | import { ActivityAudience, ActivityCreate, ContextType, VideoPlaylistPrivacy, VideoPrivacy } from '@shared/models' | |
452b3bea | 4 | import { logger, loggerTagsFactory } from '../../../helpers/logger' |
57e4e1c1 | 5 | import { VideoCommentModel } from '../../../models/video/video-comment' |
453e83ea C |
6 | import { |
7 | MActorLight, | |
8 | MCommentOwnerVideo, | |
b2111066 | 9 | MLocalVideoViewerWithWatchSections, |
453e83ea C |
10 | MVideoAccountLight, |
11 | MVideoAP, | |
12 | MVideoPlaylistFull, | |
13 | MVideoRedundancyFileVideo, | |
14 | MVideoRedundancyStreamingPlaylistVideo | |
26d6bf65 | 15 | } from '../../../types/models' |
57e4e1c1 C |
16 | import { audiencify, getAudience } from '../audience' |
17 | import { | |
18 | broadcastToActors, | |
19 | broadcastToFollowers, | |
20 | getActorsInvolvedInVideo, | |
21 | getAudienceFromFollowersOf, | |
22 | getVideoCommentAudience, | |
b2111066 | 23 | sendVideoActivityToOrigin, |
57e4e1c1 C |
24 | sendVideoRelatedActivity, |
25 | unicastTo | |
26 | } from './shared' | |
453e83ea | 27 | |
452b3bea C |
28 | const lTags = loggerTagsFactory('ap', 'create') |
29 | ||
a219c910 | 30 | async function sendCreateVideo (video: MVideoAP, transaction: Transaction) { |
22a73cb8 | 31 | if (!video.hasPrivacyForFederation()) return undefined |
54141398 | 32 | |
452b3bea | 33 | logger.info('Creating job to send video creation of %s.', video.url, lTags(video.uuid)) |
8e0fd45e | 34 | |
e12a0092 | 35 | const byActor = video.VideoChannel.Account.Actor |
866b5d3f | 36 | const videoObject = await video.toActivityPubObject() |
e12a0092 | 37 | |
2186386c | 38 | const audience = getAudience(byActor, video.privacy === VideoPrivacy.PUBLIC) |
c48e82b5 | 39 | const createActivity = buildCreateActivity(video.url, byActor, videoObject, audience) |
54141398 | 40 | |
a219c910 C |
41 | return broadcastToFollowers({ |
42 | data: createActivity, | |
43 | byActor, | |
44 | toFollowersOf: [ byActor ], | |
45 | transaction, | |
46 | contextType: 'Video' | |
47 | }) | |
54141398 C |
48 | } |
49 | ||
453e83ea C |
50 | async function sendCreateCacheFile ( |
51 | byActor: MActorLight, | |
52 | video: MVideoAccountLight, | |
53 | fileRedundancy: MVideoRedundancyStreamingPlaylistVideo | MVideoRedundancyFileVideo | |
54 | ) { | |
452b3bea | 55 | logger.info('Creating job to send file cache of %s.', fileRedundancy.url, lTags(video.uuid)) |
c48e82b5 | 56 | |
a2377d15 C |
57 | return sendVideoRelatedCreateActivity({ |
58 | byActor, | |
59 | video, | |
60 | url: fileRedundancy.url, | |
084a2cd0 C |
61 | object: fileRedundancy.toActivityPubObject(), |
62 | contextType: 'CacheFile' | |
a2377d15 | 63 | }) |
40ff5707 C |
64 | } |
65 | ||
b2111066 C |
66 | async function sendCreateWatchAction (stats: MLocalVideoViewerWithWatchSections, transaction: Transaction) { |
67 | logger.info('Creating job to send create watch action %s.', stats.url, lTags(stats.uuid)) | |
68 | ||
69 | const byActor = await getServerActor() | |
70 | ||
71 | const activityBuilder = (audience: ActivityAudience) => { | |
72 | return buildCreateActivity(stats.url, byActor, stats.toActivityPubObject(), audience) | |
73 | } | |
74 | ||
75 | return sendVideoActivityToOrigin(activityBuilder, { byActor, video: stats.Video, transaction, contextType: 'WatchAction' }) | |
76 | } | |
77 | ||
a219c910 | 78 | async function sendCreateVideoPlaylist (playlist: MVideoPlaylistFull, transaction: Transaction) { |
418d092a C |
79 | if (playlist.privacy === VideoPlaylistPrivacy.PRIVATE) return undefined |
80 | ||
452b3bea | 81 | logger.info('Creating job to send create video playlist of %s.', playlist.url, lTags(playlist.uuid)) |
418d092a C |
82 | |
83 | const byActor = playlist.OwnerAccount.Actor | |
84 | const audience = getAudience(byActor, playlist.privacy === VideoPlaylistPrivacy.PUBLIC) | |
85 | ||
a219c910 | 86 | const object = await playlist.toActivityPubObject(null, transaction) |
418d092a C |
87 | const createActivity = buildCreateActivity(playlist.url, byActor, object, audience) |
88 | ||
89 | const serverActor = await getServerActor() | |
90 | const toFollowersOf = [ byActor, serverActor ] | |
91 | ||
92 | if (playlist.VideoChannel) toFollowersOf.push(playlist.VideoChannel.Actor) | |
93 | ||
a219c910 C |
94 | return broadcastToFollowers({ |
95 | data: createActivity, | |
96 | byActor, | |
97 | toFollowersOf, | |
98 | transaction, | |
99 | contextType: 'Playlist' | |
100 | }) | |
418d092a C |
101 | } |
102 | ||
a219c910 | 103 | async function sendCreateVideoComment (comment: MCommentOwnerVideo, transaction: Transaction) { |
8e0fd45e C |
104 | logger.info('Creating job to send comment %s.', comment.url) |
105 | ||
07197db4 C |
106 | const isOrigin = comment.Video.isOwned() |
107 | ||
ea44f375 | 108 | const byActor = comment.Account.Actor |
a219c910 | 109 | const threadParentComments = await VideoCommentModel.listThreadParentComments(comment, transaction) |
d7e70384 | 110 | const commentObject = comment.toActivityPubObject(threadParentComments) |
ea44f375 | 111 | |
a219c910 | 112 | const actorsInvolvedInComment = await getActorsInvolvedInVideo(comment.Video, transaction) |
a2377d15 | 113 | // Add the actor that commented too |
93ef8a9d | 114 | actorsInvolvedInComment.push(byActor) |
93ef8a9d | 115 | |
6cb55644 C |
116 | const parentsCommentActors = threadParentComments.filter(c => !c.isDeleted()) |
117 | .map(c => c.Account.Actor) | |
ea44f375 | 118 | |
07197db4 C |
119 | let audience: ActivityAudience |
120 | if (isOrigin) { | |
121 | audience = getVideoCommentAudience(comment, threadParentComments, actorsInvolvedInComment, isOrigin) | |
122 | } else { | |
a2377d15 | 123 | audience = getAudienceFromFollowersOf(actorsInvolvedInComment.concat(parentsCommentActors)) |
07197db4 | 124 | } |
93ef8a9d | 125 | |
c48e82b5 | 126 | const createActivity = buildCreateActivity(comment.url, byActor, commentObject, audience) |
ea44f375 | 127 | |
93ef8a9d C |
128 | // This was a reply, send it to the parent actors |
129 | const actorsException = [ byActor ] | |
a219c910 C |
130 | await broadcastToActors({ |
131 | data: createActivity, | |
132 | byActor, | |
133 | toActors: parentsCommentActors, | |
134 | transaction, | |
135 | actorsException, | |
136 | contextType: 'Comment' | |
137 | }) | |
93ef8a9d C |
138 | |
139 | // Broadcast to our followers | |
a219c910 C |
140 | await broadcastToFollowers({ |
141 | data: createActivity, | |
142 | byActor, | |
143 | toFollowersOf: [ byActor ], | |
144 | transaction, | |
145 | contextType: 'Comment' | |
146 | }) | |
93ef8a9d C |
147 | |
148 | // Send to actors involved in the comment | |
a219c910 C |
149 | if (isOrigin) { |
150 | return broadcastToFollowers({ | |
151 | data: createActivity, | |
152 | byActor, | |
153 | toFollowersOf: actorsInvolvedInComment, | |
154 | transaction, | |
155 | actorsException, | |
156 | contextType: 'Comment' | |
157 | }) | |
158 | } | |
07197db4 C |
159 | |
160 | // Send to origin | |
a219c910 C |
161 | return transaction.afterCommit(() => { |
162 | return unicastTo({ | |
163 | data: createActivity, | |
164 | byActor, | |
165 | toActorUrl: comment.Video.VideoChannel.Account.Actor.getSharedInbox(), | |
166 | contextType: 'Comment' | |
167 | }) | |
168 | }) | |
ea44f375 C |
169 | } |
170 | ||
453e83ea | 171 | function buildCreateActivity (url: string, byActor: MActorLight, object: any, audience?: ActivityAudience): ActivityCreate { |
2186386c C |
172 | if (!audience) audience = getAudience(byActor) |
173 | ||
174 | return audiencify( | |
175 | { | |
176 | type: 'Create' as 'Create', | |
177 | id: url + '/activity', | |
178 | actor: byActor.url, | |
ab18fadf | 179 | object: audiencify(object, audience) |
2186386c C |
180 | }, |
181 | audience | |
182 | ) | |
54141398 C |
183 | } |
184 | ||
185 | // --------------------------------------------------------------------------- | |
186 | ||
187 | export { | |
50d6de9c | 188 | sendCreateVideo, |
c48e82b5 | 189 | buildCreateActivity, |
c48e82b5 | 190 | sendCreateVideoComment, |
418d092a | 191 | sendCreateVideoPlaylist, |
b2111066 C |
192 | sendCreateCacheFile, |
193 | sendCreateWatchAction | |
54141398 | 194 | } |
a2377d15 C |
195 | |
196 | // --------------------------------------------------------------------------- | |
197 | ||
198 | async function sendVideoRelatedCreateActivity (options: { | |
a1587156 C |
199 | byActor: MActorLight |
200 | video: MVideoAccountLight | |
201 | url: string | |
202 | object: any | |
a219c910 | 203 | contextType: ContextType |
a2377d15 C |
204 | transaction?: Transaction |
205 | }) { | |
206 | const activityBuilder = (audience: ActivityAudience) => { | |
207 | return buildCreateActivity(options.url, options.byActor, options.object, audience) | |
208 | } | |
209 | ||
210 | return sendVideoRelatedActivity(activityBuilder, options) | |
211 | } |