]>
Commit | Line | Data |
---|---|---|
1 | import { Transaction } from 'sequelize' | |
2 | import { | |
3 | ActivityAnnounce, | |
4 | ActivityAudience, | |
5 | ActivityCreate, | |
6 | ActivityDislike, | |
7 | ActivityFollow, | |
8 | ActivityLike, | |
9 | ActivityUndo, | |
10 | ContextType | |
11 | } from '@shared/models' | |
12 | import { logger } from '../../../helpers/logger' | |
13 | import { VideoModel } from '../../../models/video/video' | |
14 | import { | |
15 | MActor, | |
16 | MActorAudience, | |
17 | MActorFollowActors, | |
18 | MActorLight, | |
19 | MVideo, | |
20 | MVideoAccountLight, | |
21 | MVideoRedundancyVideo, | |
22 | MVideoShare | |
23 | } from '../../../types/models' | |
24 | import { audiencify, getAudience } from '../audience' | |
25 | import { getUndoActivityPubUrl, getVideoDislikeActivityPubUrlByLocalActor, getVideoLikeActivityPubUrlByLocalActor } from '../url' | |
26 | import { buildAnnounceWithVideoAudience } from './send-announce' | |
27 | import { buildCreateActivity } from './send-create' | |
28 | import { buildDislikeActivity } from './send-dislike' | |
29 | import { buildFollowActivity } from './send-follow' | |
30 | import { buildLikeActivity } from './send-like' | |
31 | import { broadcastToFollowers, sendVideoActivityToOrigin, sendVideoRelatedActivity, unicastTo } from './shared/send-utils' | |
32 | ||
33 | function sendUndoFollow (actorFollow: MActorFollowActors, t: Transaction) { | |
34 | const me = actorFollow.ActorFollower | |
35 | const following = actorFollow.ActorFollowing | |
36 | ||
37 | // Same server as ours | |
38 | if (!following.serverId) return | |
39 | ||
40 | logger.info('Creating job to send an unfollow request to %s.', following.url) | |
41 | ||
42 | const undoUrl = getUndoActivityPubUrl(actorFollow.url) | |
43 | ||
44 | const followActivity = buildFollowActivity(actorFollow.url, me, following) | |
45 | const undoActivity = undoActivityData(undoUrl, me, followActivity) | |
46 | ||
47 | t.afterCommit(() => { | |
48 | return unicastTo({ | |
49 | data: undoActivity, | |
50 | byActor: me, | |
51 | toActorUrl: following.inboxUrl, | |
52 | contextType: 'Follow' | |
53 | }) | |
54 | }) | |
55 | } | |
56 | ||
57 | // --------------------------------------------------------------------------- | |
58 | ||
59 | async function sendUndoAnnounce (byActor: MActorLight, videoShare: MVideoShare, video: MVideo, transaction: Transaction) { | |
60 | logger.info('Creating job to undo announce %s.', videoShare.url) | |
61 | ||
62 | const undoUrl = getUndoActivityPubUrl(videoShare.url) | |
63 | ||
64 | const { activity: announce, actorsInvolvedInVideo } = await buildAnnounceWithVideoAudience(byActor, videoShare, video, transaction) | |
65 | const undoActivity = undoActivityData(undoUrl, byActor, announce) | |
66 | ||
67 | return broadcastToFollowers({ | |
68 | data: undoActivity, | |
69 | byActor, | |
70 | toFollowersOf: actorsInvolvedInVideo, | |
71 | transaction, | |
72 | actorsException: [ byActor ], | |
73 | contextType: 'Announce' | |
74 | }) | |
75 | } | |
76 | ||
77 | async function sendUndoCacheFile (byActor: MActor, redundancyModel: MVideoRedundancyVideo, transaction: Transaction) { | |
78 | logger.info('Creating job to undo cache file %s.', redundancyModel.url) | |
79 | ||
80 | const associatedVideo = redundancyModel.getVideo() | |
81 | if (!associatedVideo) { | |
82 | logger.warn('Cannot send undo activity for redundancy %s: no video files associated.', redundancyModel.url) | |
83 | return | |
84 | } | |
85 | ||
86 | const video = await VideoModel.loadFull(associatedVideo.id) | |
87 | const createActivity = buildCreateActivity(redundancyModel.url, byActor, redundancyModel.toActivityPubObject()) | |
88 | ||
89 | return sendUndoVideoRelatedActivity({ | |
90 | byActor, | |
91 | video, | |
92 | url: redundancyModel.url, | |
93 | activity: createActivity, | |
94 | contextType: 'CacheFile', | |
95 | transaction | |
96 | }) | |
97 | } | |
98 | ||
99 | // --------------------------------------------------------------------------- | |
100 | ||
101 | async function sendUndoLike (byActor: MActor, video: MVideoAccountLight, t: Transaction) { | |
102 | logger.info('Creating job to undo a like of video %s.', video.url) | |
103 | ||
104 | const likeUrl = getVideoLikeActivityPubUrlByLocalActor(byActor, video) | |
105 | const likeActivity = buildLikeActivity(likeUrl, byActor, video) | |
106 | ||
107 | return sendUndoVideoRateToOriginActivity({ byActor, video, url: likeUrl, activity: likeActivity, transaction: t }) | |
108 | } | |
109 | ||
110 | async function sendUndoDislike (byActor: MActor, video: MVideoAccountLight, t: Transaction) { | |
111 | logger.info('Creating job to undo a dislike of video %s.', video.url) | |
112 | ||
113 | const dislikeUrl = getVideoDislikeActivityPubUrlByLocalActor(byActor, video) | |
114 | const dislikeActivity = buildDislikeActivity(dislikeUrl, byActor, video) | |
115 | ||
116 | return sendUndoVideoRateToOriginActivity({ byActor, video, url: dislikeUrl, activity: dislikeActivity, transaction: t }) | |
117 | } | |
118 | ||
119 | // --------------------------------------------------------------------------- | |
120 | ||
121 | export { | |
122 | sendUndoFollow, | |
123 | sendUndoLike, | |
124 | sendUndoDislike, | |
125 | sendUndoAnnounce, | |
126 | sendUndoCacheFile | |
127 | } | |
128 | ||
129 | // --------------------------------------------------------------------------- | |
130 | ||
131 | function undoActivityData ( | |
132 | url: string, | |
133 | byActor: MActorAudience, | |
134 | object: ActivityFollow | ActivityLike | ActivityDislike | ActivityCreate | ActivityAnnounce, | |
135 | audience?: ActivityAudience | |
136 | ): ActivityUndo { | |
137 | if (!audience) audience = getAudience(byActor) | |
138 | ||
139 | return audiencify( | |
140 | { | |
141 | type: 'Undo' as 'Undo', | |
142 | id: url, | |
143 | actor: byActor.url, | |
144 | object | |
145 | }, | |
146 | audience | |
147 | ) | |
148 | } | |
149 | ||
150 | async function sendUndoVideoRelatedActivity (options: { | |
151 | byActor: MActor | |
152 | video: MVideoAccountLight | |
153 | url: string | |
154 | activity: ActivityFollow | ActivityCreate | ActivityAnnounce | |
155 | contextType: ContextType | |
156 | transaction: Transaction | |
157 | }) { | |
158 | const activityBuilder = (audience: ActivityAudience) => { | |
159 | const undoUrl = getUndoActivityPubUrl(options.url) | |
160 | ||
161 | return undoActivityData(undoUrl, options.byActor, options.activity, audience) | |
162 | } | |
163 | ||
164 | return sendVideoRelatedActivity(activityBuilder, options) | |
165 | } | |
166 | ||
167 | async function sendUndoVideoRateToOriginActivity (options: { | |
168 | byActor: MActor | |
169 | video: MVideoAccountLight | |
170 | url: string | |
171 | activity: ActivityLike | ActivityDislike | |
172 | transaction: Transaction | |
173 | }) { | |
174 | const activityBuilder = (audience: ActivityAudience) => { | |
175 | const undoUrl = getUndoActivityPubUrl(options.url) | |
176 | ||
177 | return undoActivityData(undoUrl, options.byActor, options.activity, audience) | |
178 | } | |
179 | ||
180 | return sendVideoActivityToOrigin(activityBuilder, { ...options, contextType: 'Rate' }) | |
181 | } |