diff options
author | Chocobozzz <florian.bigard@gmail.com> | 2017-11-27 14:44:51 +0100 |
---|---|---|
committer | Chocobozzz <florian.bigard@gmail.com> | 2017-11-27 19:40:53 +0100 |
commit | 4e50b6a1c9a3eb261e04ede73241648e6edf21d6 (patch) | |
tree | e1c6c121d561ffc1cf2996daec03a1e7f27f0a25 /server/lib/activitypub | |
parent | 74bb2cb8348d6794ed3a0e2ec94c8c9abdde82cf (diff) | |
download | PeerTube-4e50b6a1c9a3eb261e04ede73241648e6edf21d6.tar.gz PeerTube-4e50b6a1c9a3eb261e04ede73241648e6edf21d6.tar.zst PeerTube-4e50b6a1c9a3eb261e04ede73241648e6edf21d6.zip |
Add shares forward and collection on videos/video channels
Diffstat (limited to 'server/lib/activitypub')
-rw-r--r-- | server/lib/activitypub/process/misc.ts | 57 | ||||
-rw-r--r-- | server/lib/activitypub/process/process-add.ts | 16 | ||||
-rw-r--r-- | server/lib/activitypub/process/process-announce.ts | 100 | ||||
-rw-r--r-- | server/lib/activitypub/process/process-create.ts | 12 | ||||
-rw-r--r-- | server/lib/activitypub/send/misc.ts | 27 | ||||
-rw-r--r-- | server/lib/activitypub/send/send-announce.ts | 86 | ||||
-rw-r--r-- | server/lib/activitypub/send/send-create.ts | 6 | ||||
-rw-r--r-- | server/lib/activitypub/send/send-like.ts | 4 | ||||
-rw-r--r-- | server/lib/activitypub/send/send-undo.ts | 4 | ||||
-rw-r--r-- | server/lib/activitypub/share.ts | 6 | ||||
-rw-r--r-- | server/lib/activitypub/url.ts | 14 |
11 files changed, 270 insertions, 62 deletions
diff --git a/server/lib/activitypub/process/misc.ts b/server/lib/activitypub/process/misc.ts index eefbe2884..f20e588ab 100644 --- a/server/lib/activitypub/process/misc.ts +++ b/server/lib/activitypub/process/misc.ts | |||
@@ -1,13 +1,16 @@ | |||
1 | import * as magnetUtil from 'magnet-uri' | 1 | import * as magnetUtil from 'magnet-uri' |
2 | import { VideoTorrentObject } from '../../../../shared' | 2 | import { VideoTorrentObject } from '../../../../shared' |
3 | import { VideoChannelObject } from '../../../../shared/models/activitypub/objects/video-channel-object' | 3 | import { VideoChannelObject } from '../../../../shared/models/activitypub/objects/video-channel-object' |
4 | import { VideoPrivacy } from '../../../../shared/models/videos/video-privacy.enum' | ||
4 | import { isVideoFileInfoHashValid } from '../../../helpers/custom-validators/videos' | 5 | import { isVideoFileInfoHashValid } from '../../../helpers/custom-validators/videos' |
6 | import { doRequest } from '../../../helpers/requests' | ||
7 | import { database as db } from '../../../initializers' | ||
5 | import { ACTIVITY_PUB, VIDEO_MIMETYPE_EXT } from '../../../initializers/constants' | 8 | import { ACTIVITY_PUB, VIDEO_MIMETYPE_EXT } from '../../../initializers/constants' |
6 | import { AccountInstance } from '../../../models/account/account-interface' | 9 | import { AccountInstance } from '../../../models/account/account-interface' |
7 | import { VideoChannelInstance } from '../../../models/video/video-channel-interface' | 10 | import { VideoChannelInstance } from '../../../models/video/video-channel-interface' |
8 | import { VideoFileAttributes } from '../../../models/video/video-file-interface' | 11 | import { VideoFileAttributes } from '../../../models/video/video-file-interface' |
9 | import { VideoAttributes, VideoInstance } from '../../../models/video/video-interface' | 12 | import { VideoAttributes, VideoInstance } from '../../../models/video/video-interface' |
10 | import { VideoPrivacy } from '../../../../shared/models/videos/video-privacy.enum' | 13 | import { getOrCreateAccountAndServer } from '../account' |
11 | 14 | ||
12 | function videoChannelActivityObjectToDBAttributes (videoChannelObject: VideoChannelObject, account: AccountInstance) { | 15 | function videoChannelActivityObjectToDBAttributes (videoChannelObject: VideoChannelObject, account: AccountInstance) { |
13 | return { | 16 | return { |
@@ -97,10 +100,60 @@ function videoFileActivityUrlToDBAttributes (videoCreated: VideoInstance, videoO | |||
97 | return attributes | 100 | return attributes |
98 | } | 101 | } |
99 | 102 | ||
103 | async function addVideoShares (instance: VideoInstance, shares: string[]) { | ||
104 | for (const share of shares) { | ||
105 | // Fetch url | ||
106 | const json = await doRequest({ | ||
107 | uri: share, | ||
108 | json: true | ||
109 | }) | ||
110 | const actor = json['actor'] | ||
111 | if (!actor) continue | ||
112 | |||
113 | const account = await getOrCreateAccountAndServer(actor) | ||
114 | |||
115 | const entry = { | ||
116 | accountId: account.id, | ||
117 | videoId: instance.id | ||
118 | } | ||
119 | |||
120 | await db.VideoShare.findOrCreate({ | ||
121 | where: entry, | ||
122 | defaults: entry | ||
123 | }) | ||
124 | } | ||
125 | } | ||
126 | |||
127 | async function addVideoChannelShares (instance: VideoChannelInstance, shares: string[]) { | ||
128 | for (const share of shares) { | ||
129 | // Fetch url | ||
130 | const json = await doRequest({ | ||
131 | uri: share, | ||
132 | json: true | ||
133 | }) | ||
134 | const actor = json['actor'] | ||
135 | if (!actor) continue | ||
136 | |||
137 | const account = await getOrCreateAccountAndServer(actor) | ||
138 | |||
139 | const entry = { | ||
140 | accountId: account.id, | ||
141 | videoChannelId: instance.id | ||
142 | } | ||
143 | |||
144 | await db.VideoChannelShare.findOrCreate({ | ||
145 | where: entry, | ||
146 | defaults: entry | ||
147 | }) | ||
148 | } | ||
149 | } | ||
150 | |||
100 | // --------------------------------------------------------------------------- | 151 | // --------------------------------------------------------------------------- |
101 | 152 | ||
102 | export { | 153 | export { |
103 | videoFileActivityUrlToDBAttributes, | 154 | videoFileActivityUrlToDBAttributes, |
104 | videoActivityObjectToDBAttributes, | 155 | videoActivityObjectToDBAttributes, |
105 | videoChannelActivityObjectToDBAttributes | 156 | videoChannelActivityObjectToDBAttributes, |
157 | addVideoChannelShares, | ||
158 | addVideoShares | ||
106 | } | 159 | } |
diff --git a/server/lib/activitypub/process/process-add.ts b/server/lib/activitypub/process/process-add.ts index 98280b9f0..e6bf63eb2 100644 --- a/server/lib/activitypub/process/process-add.ts +++ b/server/lib/activitypub/process/process-add.ts | |||
@@ -11,7 +11,7 @@ import { VideoInstance } from '../../../models/video/video-interface' | |||
11 | import { getOrCreateAccountAndServer } from '../account' | 11 | import { getOrCreateAccountAndServer } from '../account' |
12 | import { getOrCreateVideoChannel } from '../video-channels' | 12 | import { getOrCreateVideoChannel } from '../video-channels' |
13 | import { generateThumbnailFromUrl } from '../videos' | 13 | import { generateThumbnailFromUrl } from '../videos' |
14 | import { videoActivityObjectToDBAttributes, videoFileActivityUrlToDBAttributes } from './misc' | 14 | import { addVideoShares, videoActivityObjectToDBAttributes, videoFileActivityUrlToDBAttributes } from './misc' |
15 | 15 | ||
16 | async function processAddActivity (activity: ActivityAdd) { | 16 | async function processAddActivity (activity: ActivityAdd) { |
17 | const activityObject = activity.object | 17 | const activityObject = activity.object |
@@ -37,12 +37,10 @@ export { | |||
37 | 37 | ||
38 | // --------------------------------------------------------------------------- | 38 | // --------------------------------------------------------------------------- |
39 | 39 | ||
40 | async function processAddVideo ( | 40 | async function processAddVideo (account: AccountInstance, |
41 | account: AccountInstance, | 41 | activity: ActivityAdd, |
42 | activity: ActivityAdd, | 42 | videoChannel: VideoChannelInstance, |
43 | videoChannel: VideoChannelInstance, | 43 | videoToCreateData: VideoTorrentObject) { |
44 | videoToCreateData: VideoTorrentObject | ||
45 | ) { | ||
46 | const options = { | 44 | const options = { |
47 | arguments: [ account, activity, videoChannel, videoToCreateData ], | 45 | arguments: [ account, activity, videoChannel, videoToCreateData ], |
48 | errorMessage: 'Cannot insert the remote video with many retries.' | 46 | errorMessage: 'Cannot insert the remote video with many retries.' |
@@ -59,6 +57,10 @@ async function processAddVideo ( | |||
59 | await createRates(videoToCreateData.dislikes.orderedItems, video, 'dislike') | 57 | await createRates(videoToCreateData.dislikes.orderedItems, video, 'dislike') |
60 | } | 58 | } |
61 | 59 | ||
60 | if (videoToCreateData.shares && Array.isArray(videoToCreateData.shares.orderedItems)) { | ||
61 | await addVideoShares(video, videoToCreateData.shares.orderedItems) | ||
62 | } | ||
63 | |||
62 | return video | 64 | return video |
63 | } | 65 | } |
64 | 66 | ||
diff --git a/server/lib/activitypub/process/process-announce.ts b/server/lib/activitypub/process/process-announce.ts index d8532d3a1..2aa9ad5c7 100644 --- a/server/lib/activitypub/process/process-announce.ts +++ b/server/lib/activitypub/process/process-announce.ts | |||
@@ -1,34 +1,23 @@ | |||
1 | import { ActivityAnnounce } from '../../../../shared/models/activitypub/activity' | 1 | import { ActivityAdd, ActivityAnnounce, ActivityCreate } from '../../../../shared/models/activitypub/activity' |
2 | import { retryTransactionWrapper } from '../../../helpers/database-utils' | ||
2 | import { logger } from '../../../helpers/logger' | 3 | import { logger } from '../../../helpers/logger' |
3 | import { database as db } from '../../../initializers/index' | 4 | import { database as db } from '../../../initializers/index' |
5 | import { AccountInstance } from '../../../models/account/account-interface' | ||
4 | import { VideoInstance } from '../../../models/index' | 6 | import { VideoInstance } from '../../../models/index' |
5 | import { VideoChannelInstance } from '../../../models/video/video-channel-interface' | 7 | import { VideoChannelInstance } from '../../../models/video/video-channel-interface' |
8 | import { getOrCreateAccountAndServer } from '../account' | ||
9 | import { forwardActivity } from '../send/misc' | ||
6 | import { processAddActivity } from './process-add' | 10 | import { processAddActivity } from './process-add' |
7 | import { processCreateActivity } from './process-create' | 11 | import { processCreateActivity } from './process-create' |
8 | import { getOrCreateAccountAndServer } from '../account' | ||
9 | 12 | ||
10 | async function processAnnounceActivity (activity: ActivityAnnounce) { | 13 | async function processAnnounceActivity (activity: ActivityAnnounce) { |
11 | const announcedActivity = activity.object | 14 | const announcedActivity = activity.object |
12 | const accountAnnouncer = await getOrCreateAccountAndServer(activity.actor) | 15 | const accountAnnouncer = await getOrCreateAccountAndServer(activity.actor) |
13 | 16 | ||
14 | if (announcedActivity.type === 'Create' && announcedActivity.object.type === 'VideoChannel') { | 17 | if (announcedActivity.type === 'Create' && announcedActivity.object.type === 'VideoChannel') { |
15 | // Add share entry | 18 | return processVideoChannelShare(accountAnnouncer, activity) |
16 | const videoChannel: VideoChannelInstance = await processCreateActivity(announcedActivity) | ||
17 | await db.VideoChannelShare.create({ | ||
18 | accountId: accountAnnouncer.id, | ||
19 | videoChannelId: videoChannel.id | ||
20 | }) | ||
21 | |||
22 | return undefined | ||
23 | } else if (announcedActivity.type === 'Add' && announcedActivity.object.type === 'Video') { | 19 | } else if (announcedActivity.type === 'Add' && announcedActivity.object.type === 'Video') { |
24 | // Add share entry | 20 | return processVideoShare(accountAnnouncer, activity) |
25 | const video: VideoInstance = await processAddActivity(announcedActivity) | ||
26 | await db.VideoShare.create({ | ||
27 | accountId: accountAnnouncer.id, | ||
28 | videoId: video.id | ||
29 | }) | ||
30 | |||
31 | return undefined | ||
32 | } | 21 | } |
33 | 22 | ||
34 | logger.warn( | 23 | logger.warn( |
@@ -44,3 +33,78 @@ async function processAnnounceActivity (activity: ActivityAnnounce) { | |||
44 | export { | 33 | export { |
45 | processAnnounceActivity | 34 | processAnnounceActivity |
46 | } | 35 | } |
36 | |||
37 | // --------------------------------------------------------------------------- | ||
38 | |||
39 | function processVideoChannelShare (accountAnnouncer: AccountInstance, activity: ActivityAnnounce) { | ||
40 | const options = { | ||
41 | arguments: [ accountAnnouncer, activity ], | ||
42 | errorMessage: 'Cannot share the video channel with many retries.' | ||
43 | } | ||
44 | |||
45 | return retryTransactionWrapper(shareVideoChannel, options) | ||
46 | } | ||
47 | |||
48 | async function shareVideoChannel (accountAnnouncer: AccountInstance, activity: ActivityAnnounce) { | ||
49 | const announcedActivity = activity.object as ActivityCreate | ||
50 | |||
51 | return db.sequelize.transaction(async t => { | ||
52 | // Add share entry | ||
53 | const videoChannel: VideoChannelInstance = await processCreateActivity(announcedActivity) | ||
54 | const share = { | ||
55 | accountId: accountAnnouncer.id, | ||
56 | videoChannelId: videoChannel.id | ||
57 | } | ||
58 | |||
59 | const [ , created ] = await db.VideoChannelShare.findOrCreate({ | ||
60 | where: share, | ||
61 | defaults: share, | ||
62 | transaction: t | ||
63 | }) | ||
64 | |||
65 | if (videoChannel.isOwned() && created === true) { | ||
66 | // Don't resend the activity to the sender | ||
67 | const exceptions = [ accountAnnouncer ] | ||
68 | await forwardActivity(activity, t, exceptions) | ||
69 | } | ||
70 | |||
71 | return undefined | ||
72 | }) | ||
73 | } | ||
74 | |||
75 | function processVideoShare (accountAnnouncer: AccountInstance, activity: ActivityAnnounce) { | ||
76 | const options = { | ||
77 | arguments: [ accountAnnouncer, activity ], | ||
78 | errorMessage: 'Cannot share the video with many retries.' | ||
79 | } | ||
80 | |||
81 | return retryTransactionWrapper(shareVideo, options) | ||
82 | } | ||
83 | |||
84 | function shareVideo (accountAnnouncer: AccountInstance, activity: ActivityAnnounce) { | ||
85 | const announcedActivity = activity.object as ActivityAdd | ||
86 | |||
87 | return db.sequelize.transaction(async t => { | ||
88 | // Add share entry | ||
89 | const video: VideoInstance = await processAddActivity(announcedActivity) | ||
90 | |||
91 | const share = { | ||
92 | accountId: accountAnnouncer.id, | ||
93 | videoId: video.id | ||
94 | } | ||
95 | |||
96 | const [ , created ] = await db.VideoShare.findOrCreate({ | ||
97 | where: share, | ||
98 | defaults: share, | ||
99 | transaction: t | ||
100 | }) | ||
101 | |||
102 | if (video.isOwned() && created === true) { | ||
103 | // Don't resend the activity to the sender | ||
104 | const exceptions = [ accountAnnouncer ] | ||
105 | await forwardActivity(activity, t, exceptions) | ||
106 | } | ||
107 | |||
108 | return undefined | ||
109 | }) | ||
110 | } | ||
diff --git a/server/lib/activitypub/process/process-create.ts b/server/lib/activitypub/process/process-create.ts index 1f982598b..c88082bbf 100644 --- a/server/lib/activitypub/process/process-create.ts +++ b/server/lib/activitypub/process/process-create.ts | |||
@@ -8,7 +8,7 @@ import { AccountInstance } from '../../../models/account/account-interface' | |||
8 | import { getOrCreateAccountAndServer } from '../account' | 8 | import { getOrCreateAccountAndServer } from '../account' |
9 | import { forwardActivity } from '../send/misc' | 9 | import { forwardActivity } from '../send/misc' |
10 | import { getVideoChannelActivityPubUrl } from '../url' | 10 | import { getVideoChannelActivityPubUrl } from '../url' |
11 | import { videoChannelActivityObjectToDBAttributes } from './misc' | 11 | import { addVideoChannelShares, videoChannelActivityObjectToDBAttributes } from './misc' |
12 | 12 | ||
13 | async function processCreateActivity (activity: ActivityCreate) { | 13 | async function processCreateActivity (activity: ActivityCreate) { |
14 | const activityObject = activity.object | 14 | const activityObject = activity.object |
@@ -92,13 +92,19 @@ async function processCreateView (byAccount: AccountInstance, activity: Activity | |||
92 | } | 92 | } |
93 | } | 93 | } |
94 | 94 | ||
95 | function processCreateVideoChannel (account: AccountInstance, videoChannelToCreateData: VideoChannelObject) { | 95 | async function processCreateVideoChannel (account: AccountInstance, videoChannelToCreateData: VideoChannelObject) { |
96 | const options = { | 96 | const options = { |
97 | arguments: [ account, videoChannelToCreateData ], | 97 | arguments: [ account, videoChannelToCreateData ], |
98 | errorMessage: 'Cannot insert the remote video channel with many retries.' | 98 | errorMessage: 'Cannot insert the remote video channel with many retries.' |
99 | } | 99 | } |
100 | 100 | ||
101 | return retryTransactionWrapper(addRemoteVideoChannel, options) | 101 | const videoChannel = await retryTransactionWrapper(addRemoteVideoChannel, options) |
102 | |||
103 | if (videoChannelToCreateData.shares && Array.isArray(videoChannelToCreateData.shares.orderedItems)) { | ||
104 | await addVideoChannelShares(videoChannel, videoChannelToCreateData.shares.orderedItems) | ||
105 | } | ||
106 | |||
107 | return videoChannel | ||
102 | } | 108 | } |
103 | 109 | ||
104 | function addRemoteVideoChannel (account: AccountInstance, videoChannelToCreateData: VideoChannelObject) { | 110 | function addRemoteVideoChannel (account: AccountInstance, videoChannelToCreateData: VideoChannelObject) { |
diff --git a/server/lib/activitypub/send/misc.ts b/server/lib/activitypub/send/misc.ts index 444c1cbd6..fd1add68e 100644 --- a/server/lib/activitypub/send/misc.ts +++ b/server/lib/activitypub/send/misc.ts | |||
@@ -1,13 +1,14 @@ | |||
1 | import { Transaction } from 'sequelize' | 1 | import { Transaction } from 'sequelize' |
2 | import { Activity } from '../../../../shared/models/activitypub/activity' | ||
2 | import { logger } from '../../../helpers/logger' | 3 | import { logger } from '../../../helpers/logger' |
3 | import { ACTIVITY_PUB, database as db } from '../../../initializers' | 4 | import { ACTIVITY_PUB, database as db } from '../../../initializers' |
4 | import { AccountInstance } from '../../../models/account/account-interface' | 5 | import { AccountInstance } from '../../../models/account/account-interface' |
6 | import { VideoChannelInstance } from '../../../models/index' | ||
7 | import { VideoInstance } from '../../../models/video/video-interface' | ||
5 | import { | 8 | import { |
6 | activitypubHttpJobScheduler, | 9 | activitypubHttpJobScheduler, |
7 | ActivityPubHttpPayload | 10 | ActivityPubHttpPayload |
8 | } from '../../jobs/activitypub-http-job-scheduler/activitypub-http-job-scheduler' | 11 | } from '../../jobs/activitypub-http-job-scheduler/activitypub-http-job-scheduler' |
9 | import { VideoInstance } from '../../../models/video/video-interface' | ||
10 | import { Activity } from '../../../../shared/models/activitypub/activity' | ||
11 | 12 | ||
12 | async function forwardActivity ( | 13 | async function forwardActivity ( |
13 | activity: Activity, | 14 | activity: Activity, |
@@ -85,9 +86,16 @@ function getOriginVideoAudience (video: VideoInstance, accountsInvolvedInVideo: | |||
85 | } | 86 | } |
86 | } | 87 | } |
87 | 88 | ||
88 | function getVideoFollowersAudience (accountsInvolvedInVideo: AccountInstance[]) { | 89 | function getOriginVideoChannelAudience (videoChannel: VideoChannelInstance, accountsInvolved: AccountInstance[]) { |
90 | return { | ||
91 | to: [ videoChannel.Account.url ], | ||
92 | cc: accountsInvolved.map(a => a.followersUrl) | ||
93 | } | ||
94 | } | ||
95 | |||
96 | function getObjectFollowersAudience (accountsInvolvedInObject: AccountInstance[]) { | ||
89 | return { | 97 | return { |
90 | to: accountsInvolvedInVideo.map(a => a.followersUrl), | 98 | to: accountsInvolvedInObject.map(a => a.followersUrl), |
91 | cc: [] | 99 | cc: [] |
92 | } | 100 | } |
93 | } | 101 | } |
@@ -99,6 +107,13 @@ async function getAccountsInvolvedInVideo (video: VideoInstance) { | |||
99 | return accountsToForwardView | 107 | return accountsToForwardView |
100 | } | 108 | } |
101 | 109 | ||
110 | async function getAccountsInvolvedInVideoChannel (videoChannel: VideoChannelInstance) { | ||
111 | const accountsToForwardView = await db.VideoChannelShare.loadAccountsByShare(videoChannel.id) | ||
112 | accountsToForwardView.push(videoChannel.Account) | ||
113 | |||
114 | return accountsToForwardView | ||
115 | } | ||
116 | |||
102 | async function getAudience (accountSender: AccountInstance, isPublic = true) { | 117 | async function getAudience (accountSender: AccountInstance, isPublic = true) { |
103 | const followerInboxUrls = await accountSender.getFollowerSharedInboxUrls() | 118 | const followerInboxUrls = await accountSender.getFollowerSharedInboxUrls() |
104 | 119 | ||
@@ -131,10 +146,12 @@ async function computeFollowerUris (toAccountFollower: AccountInstance[], follow | |||
131 | 146 | ||
132 | export { | 147 | export { |
133 | broadcastToFollowers, | 148 | broadcastToFollowers, |
149 | getOriginVideoChannelAudience, | ||
134 | unicastTo, | 150 | unicastTo, |
135 | getAudience, | 151 | getAudience, |
136 | getOriginVideoAudience, | 152 | getOriginVideoAudience, |
137 | getAccountsInvolvedInVideo, | 153 | getAccountsInvolvedInVideo, |
138 | getVideoFollowersAudience, | 154 | getAccountsInvolvedInVideoChannel, |
155 | getObjectFollowersAudience, | ||
139 | forwardActivity | 156 | forwardActivity |
140 | } | 157 | } |
diff --git a/server/lib/activitypub/send/send-announce.ts b/server/lib/activitypub/send/send-announce.ts index b8ea51bc0..efc23af46 100644 --- a/server/lib/activitypub/send/send-announce.ts +++ b/server/lib/activitypub/send/send-announce.ts | |||
@@ -1,34 +1,96 @@ | |||
1 | import { Transaction } from 'sequelize' | 1 | import { Transaction } from 'sequelize' |
2 | import { ActivityAdd } from '../../../../shared/index' | 2 | import { ActivityAdd } from '../../../../shared/index' |
3 | import { ActivityAnnounce, ActivityCreate } from '../../../../shared/models/activitypub/activity' | 3 | import { ActivityAnnounce, ActivityAudience, ActivityCreate } from '../../../../shared/models/activitypub/activity' |
4 | import { AccountInstance, VideoInstance } from '../../../models' | 4 | import { AccountInstance, VideoInstance } from '../../../models' |
5 | import { VideoChannelInstance } from '../../../models/video/video-channel-interface' | 5 | import { VideoChannelInstance } from '../../../models/video/video-channel-interface' |
6 | import { getAnnounceActivityPubUrl } from '../url' | 6 | import { getAnnounceActivityPubUrl } from '../url' |
7 | import { broadcastToFollowers } from './misc' | 7 | import { |
8 | broadcastToFollowers, | ||
9 | getAccountsInvolvedInVideo, | ||
10 | getAccountsInvolvedInVideoChannel, | ||
11 | getAudience, | ||
12 | getObjectFollowersAudience, | ||
13 | getOriginVideoAudience, | ||
14 | getOriginVideoChannelAudience, | ||
15 | unicastTo | ||
16 | } from './misc' | ||
8 | import { addActivityData } from './send-add' | 17 | import { addActivityData } from './send-add' |
9 | import { createActivityData } from './send-create' | 18 | import { createActivityData } from './send-create' |
10 | 19 | ||
11 | async function sendVideoAnnounce (byAccount: AccountInstance, video: VideoInstance, t: Transaction) { | 20 | async function buildVideoAnnounceToFollowers (byAccount: AccountInstance, video: VideoInstance, t: Transaction) { |
12 | const url = getAnnounceActivityPubUrl(video.url, byAccount) | 21 | const url = getAnnounceActivityPubUrl(video.url, byAccount) |
13 | 22 | ||
14 | const videoChannel = video.VideoChannel | 23 | const videoChannel = video.VideoChannel |
15 | const announcedActivity = await addActivityData(url, videoChannel.Account, video, videoChannel.url, video.toActivityPubObject()) | 24 | const announcedActivity = await addActivityData(url, videoChannel.Account, video, videoChannel.url, video.toActivityPubObject()) |
16 | 25 | ||
17 | const data = await announceActivityData(url, byAccount, announcedActivity) | 26 | const accountsToForwardView = await getAccountsInvolvedInVideo(video) |
27 | const audience = getObjectFollowersAudience(accountsToForwardView) | ||
28 | const data = await announceActivityData(url, byAccount, announcedActivity, audience) | ||
29 | |||
30 | return data | ||
31 | } | ||
32 | |||
33 | async function sendVideoAnnounceToFollowers (byAccount: AccountInstance, video: VideoInstance, t: Transaction) { | ||
34 | const data = await buildVideoAnnounceToFollowers(byAccount, video, t) | ||
35 | |||
18 | return broadcastToFollowers(data, byAccount, [ byAccount ], t) | 36 | return broadcastToFollowers(data, byAccount, [ byAccount ], t) |
19 | } | 37 | } |
20 | 38 | ||
21 | async function sendVideoChannelAnnounce (byAccount: AccountInstance, videoChannel: VideoChannelInstance, t: Transaction) { | 39 | async function sendVideoAnnounceToOrigin (byAccount: AccountInstance, video: VideoInstance, t: Transaction) { |
40 | const url = getAnnounceActivityPubUrl(video.url, byAccount) | ||
41 | |||
42 | const videoChannel = video.VideoChannel | ||
43 | const announcedActivity = await addActivityData(url, videoChannel.Account, video, videoChannel.url, video.toActivityPubObject()) | ||
44 | |||
45 | const accountsInvolvedInVideo = await getAccountsInvolvedInVideo(video) | ||
46 | const audience = getOriginVideoAudience(video, accountsInvolvedInVideo) | ||
47 | const data = await createActivityData(url, byAccount, announcedActivity, audience) | ||
48 | |||
49 | return unicastTo(data, byAccount, videoChannel.Account.sharedInboxUrl, t) | ||
50 | } | ||
51 | |||
52 | async function buildVideoChannelAnnounceToFollowers (byAccount: AccountInstance, videoChannel: VideoChannelInstance, t: Transaction) { | ||
22 | const url = getAnnounceActivityPubUrl(videoChannel.url, byAccount) | 53 | const url = getAnnounceActivityPubUrl(videoChannel.url, byAccount) |
23 | const announcedActivity = await createActivityData(url, videoChannel.Account, videoChannel.toActivityPubObject()) | 54 | const announcedActivity = await createActivityData(url, videoChannel.Account, videoChannel.toActivityPubObject()) |
24 | 55 | ||
25 | const data = await announceActivityData(url, byAccount, announcedActivity) | 56 | const accountsToForwardView = await getAccountsInvolvedInVideoChannel(videoChannel) |
57 | const audience = getObjectFollowersAudience(accountsToForwardView) | ||
58 | const data = await announceActivityData(url, byAccount, announcedActivity, audience) | ||
59 | |||
60 | return data | ||
61 | } | ||
62 | |||
63 | async function sendVideoChannelAnnounceToFollowers (byAccount: AccountInstance, videoChannel: VideoChannelInstance, t: Transaction) { | ||
64 | const data = await buildVideoChannelAnnounceToFollowers(byAccount, videoChannel, t) | ||
65 | |||
26 | return broadcastToFollowers(data, byAccount, [ byAccount ], t) | 66 | return broadcastToFollowers(data, byAccount, [ byAccount ], t) |
27 | } | 67 | } |
28 | 68 | ||
29 | async function announceActivityData (url: string, byAccount: AccountInstance, object: ActivityCreate | ActivityAdd) { | 69 | async function sendVideoChannelAnnounceToOrigin (byAccount: AccountInstance, videoChannel: VideoChannelInstance, t: Transaction) { |
70 | const url = getAnnounceActivityPubUrl(videoChannel.url, byAccount) | ||
71 | const announcedActivity = await createActivityData(url, videoChannel.Account, videoChannel.toActivityPubObject()) | ||
72 | |||
73 | const accountsInvolvedInVideo = await getAccountsInvolvedInVideoChannel(videoChannel) | ||
74 | const audience = getOriginVideoChannelAudience(videoChannel, accountsInvolvedInVideo) | ||
75 | const data = await createActivityData(url, byAccount, announcedActivity, audience) | ||
76 | |||
77 | return unicastTo(data, byAccount, videoChannel.Account.sharedInboxUrl, t) | ||
78 | } | ||
79 | |||
80 | async function announceActivityData ( | ||
81 | url: string, | ||
82 | byAccount: AccountInstance, | ||
83 | object: ActivityCreate | ActivityAdd, | ||
84 | audience?: ActivityAudience | ||
85 | ) { | ||
86 | if (!audience) { | ||
87 | audience = await getAudience(byAccount) | ||
88 | } | ||
89 | |||
30 | const activity: ActivityAnnounce = { | 90 | const activity: ActivityAnnounce = { |
31 | type: 'Announce', | 91 | type: 'Announce', |
92 | to: audience.to, | ||
93 | cc: audience.cc, | ||
32 | id: url, | 94 | id: url, |
33 | actor: byAccount.url, | 95 | actor: byAccount.url, |
34 | object | 96 | object |
@@ -40,7 +102,11 @@ async function announceActivityData (url: string, byAccount: AccountInstance, ob | |||
40 | // --------------------------------------------------------------------------- | 102 | // --------------------------------------------------------------------------- |
41 | 103 | ||
42 | export { | 104 | export { |
43 | sendVideoAnnounce, | 105 | sendVideoAnnounceToFollowers, |
44 | sendVideoChannelAnnounce, | 106 | sendVideoChannelAnnounceToFollowers, |
45 | announceActivityData | 107 | sendVideoAnnounceToOrigin, |
108 | sendVideoChannelAnnounceToOrigin, | ||
109 | announceActivityData, | ||
110 | buildVideoAnnounceToFollowers, | ||
111 | buildVideoChannelAnnounceToFollowers | ||
46 | } | 112 | } |
diff --git a/server/lib/activitypub/send/send-create.ts b/server/lib/activitypub/send/send-create.ts index 113d89233..bf66606c1 100644 --- a/server/lib/activitypub/send/send-create.ts +++ b/server/lib/activitypub/send/send-create.ts | |||
@@ -9,7 +9,7 @@ import { | |||
9 | getAccountsInvolvedInVideo, | 9 | getAccountsInvolvedInVideo, |
10 | getAudience, | 10 | getAudience, |
11 | getOriginVideoAudience, | 11 | getOriginVideoAudience, |
12 | getVideoFollowersAudience, | 12 | getObjectFollowersAudience, |
13 | unicastTo | 13 | unicastTo |
14 | } from './misc' | 14 | } from './misc' |
15 | 15 | ||
@@ -47,7 +47,7 @@ async function sendCreateViewToVideoFollowers (byAccount: AccountInstance, video | |||
47 | const viewActivity = createViewActivityData(byAccount, video) | 47 | const viewActivity = createViewActivityData(byAccount, video) |
48 | 48 | ||
49 | const accountsToForwardView = await getAccountsInvolvedInVideo(video) | 49 | const accountsToForwardView = await getAccountsInvolvedInVideo(video) |
50 | const audience = getVideoFollowersAudience(accountsToForwardView) | 50 | const audience = getObjectFollowersAudience(accountsToForwardView) |
51 | const data = await createActivityData(url, byAccount, viewActivity, audience) | 51 | const data = await createActivityData(url, byAccount, viewActivity, audience) |
52 | 52 | ||
53 | // Use the server account to send the view, because it could be an unregistered account | 53 | // Use the server account to send the view, because it could be an unregistered account |
@@ -72,7 +72,7 @@ async function sendCreateDislikeToVideoFollowers (byAccount: AccountInstance, vi | |||
72 | const dislikeActivity = createDislikeActivityData(byAccount, video) | 72 | const dislikeActivity = createDislikeActivityData(byAccount, video) |
73 | 73 | ||
74 | const accountsToForwardView = await getAccountsInvolvedInVideo(video) | 74 | const accountsToForwardView = await getAccountsInvolvedInVideo(video) |
75 | const audience = getVideoFollowersAudience(accountsToForwardView) | 75 | const audience = getObjectFollowersAudience(accountsToForwardView) |
76 | const data = await createActivityData(url, byAccount, dislikeActivity, audience) | 76 | const data = await createActivityData(url, byAccount, dislikeActivity, audience) |
77 | 77 | ||
78 | const followersException = [ byAccount ] | 78 | const followersException = [ byAccount ] |
diff --git a/server/lib/activitypub/send/send-like.ts b/server/lib/activitypub/send/send-like.ts index 8ca775bf3..41b879b8a 100644 --- a/server/lib/activitypub/send/send-like.ts +++ b/server/lib/activitypub/send/send-like.ts | |||
@@ -7,7 +7,7 @@ import { | |||
7 | getAccountsInvolvedInVideo, | 7 | getAccountsInvolvedInVideo, |
8 | getAudience, | 8 | getAudience, |
9 | getOriginVideoAudience, | 9 | getOriginVideoAudience, |
10 | getVideoFollowersAudience, | 10 | getObjectFollowersAudience, |
11 | unicastTo | 11 | unicastTo |
12 | } from './misc' | 12 | } from './misc' |
13 | 13 | ||
@@ -25,7 +25,7 @@ async function sendLikeToVideoFollowers (byAccount: AccountInstance, video: Vide | |||
25 | const url = getVideoLikeActivityPubUrl(byAccount, video) | 25 | const url = getVideoLikeActivityPubUrl(byAccount, video) |
26 | 26 | ||
27 | const accountsInvolvedInVideo = await getAccountsInvolvedInVideo(video) | 27 | const accountsInvolvedInVideo = await getAccountsInvolvedInVideo(video) |
28 | const audience = getVideoFollowersAudience(accountsInvolvedInVideo) | 28 | const audience = getObjectFollowersAudience(accountsInvolvedInVideo) |
29 | const data = await likeActivityData(url, byAccount, video, audience) | 29 | const data = await likeActivityData(url, byAccount, video, audience) |
30 | 30 | ||
31 | const toAccountsFollowers = await getAccountsInvolvedInVideo(video) | 31 | const toAccountsFollowers = await getAccountsInvolvedInVideo(video) |
diff --git a/server/lib/activitypub/send/send-undo.ts b/server/lib/activitypub/send/send-undo.ts index 79fc113f0..9b732df40 100644 --- a/server/lib/activitypub/send/send-undo.ts +++ b/server/lib/activitypub/send/send-undo.ts | |||
@@ -10,7 +10,7 @@ import { AccountInstance } from '../../../models' | |||
10 | import { AccountFollowInstance } from '../../../models/account/account-follow-interface' | 10 | import { AccountFollowInstance } from '../../../models/account/account-follow-interface' |
11 | import { VideoInstance } from '../../../models/video/video-interface' | 11 | import { VideoInstance } from '../../../models/video/video-interface' |
12 | import { getAccountFollowActivityPubUrl, getUndoActivityPubUrl, getVideoDislikeActivityPubUrl, getVideoLikeActivityPubUrl } from '../url' | 12 | import { getAccountFollowActivityPubUrl, getUndoActivityPubUrl, getVideoDislikeActivityPubUrl, getVideoLikeActivityPubUrl } from '../url' |
13 | import { broadcastToFollowers, getAccountsInvolvedInVideo, getAudience, getVideoFollowersAudience, unicastTo } from './misc' | 13 | import { broadcastToFollowers, getAccountsInvolvedInVideo, getAudience, getObjectFollowersAudience, unicastTo } from './misc' |
14 | import { createActivityData, createDislikeActivityData } from './send-create' | 14 | import { createActivityData, createDislikeActivityData } from './send-create' |
15 | import { followActivityData } from './send-follow' | 15 | import { followActivityData } from './send-follow' |
16 | import { likeActivityData } from './send-like' | 16 | import { likeActivityData } from './send-like' |
@@ -43,7 +43,7 @@ async function sendUndoLikeToVideoFollowers (byAccount: AccountInstance, video: | |||
43 | const undoUrl = getUndoActivityPubUrl(likeUrl) | 43 | const undoUrl = getUndoActivityPubUrl(likeUrl) |
44 | 44 | ||
45 | const toAccountsFollowers = await getAccountsInvolvedInVideo(video) | 45 | const toAccountsFollowers = await getAccountsInvolvedInVideo(video) |
46 | const audience = getVideoFollowersAudience(toAccountsFollowers) | 46 | const audience = getObjectFollowersAudience(toAccountsFollowers) |
47 | const object = await likeActivityData(likeUrl, byAccount, video) | 47 | const object = await likeActivityData(likeUrl, byAccount, video) |
48 | const data = await undoActivityData(undoUrl, byAccount, object, audience) | 48 | const data = await undoActivityData(undoUrl, byAccount, object, audience) |
49 | 49 | ||
diff --git a/server/lib/activitypub/share.ts b/server/lib/activitypub/share.ts index 689e200a6..e14b0f50c 100644 --- a/server/lib/activitypub/share.ts +++ b/server/lib/activitypub/share.ts | |||
@@ -3,7 +3,7 @@ import { getServerAccount } from '../../helpers/utils' | |||
3 | import { database as db } from '../../initializers' | 3 | import { database as db } from '../../initializers' |
4 | import { VideoChannelInstance } from '../../models/index' | 4 | import { VideoChannelInstance } from '../../models/index' |
5 | import { VideoInstance } from '../../models/video/video-interface' | 5 | import { VideoInstance } from '../../models/video/video-interface' |
6 | import { sendVideoAnnounce, sendVideoChannelAnnounce } from './send/send-announce' | 6 | import { sendVideoAnnounceToFollowers, sendVideoChannelAnnounceToFollowers } from './send/send-announce' |
7 | 7 | ||
8 | async function shareVideoChannelByServer (videoChannel: VideoChannelInstance, t: Transaction) { | 8 | async function shareVideoChannelByServer (videoChannel: VideoChannelInstance, t: Transaction) { |
9 | const serverAccount = await getServerAccount() | 9 | const serverAccount = await getServerAccount() |
@@ -13,7 +13,7 @@ async function shareVideoChannelByServer (videoChannel: VideoChannelInstance, t: | |||
13 | videoChannelId: videoChannel.id | 13 | videoChannelId: videoChannel.id |
14 | }, { transaction: t }) | 14 | }, { transaction: t }) |
15 | 15 | ||
16 | return sendVideoChannelAnnounce(serverAccount, videoChannel, t) | 16 | return sendVideoChannelAnnounceToFollowers(serverAccount, videoChannel, t) |
17 | } | 17 | } |
18 | 18 | ||
19 | async function shareVideoByServer (video: VideoInstance, t: Transaction) { | 19 | async function shareVideoByServer (video: VideoInstance, t: Transaction) { |
@@ -24,7 +24,7 @@ async function shareVideoByServer (video: VideoInstance, t: Transaction) { | |||
24 | videoId: video.id | 24 | videoId: video.id |
25 | }, { transaction: t }) | 25 | }, { transaction: t }) |
26 | 26 | ||
27 | return sendVideoAnnounce(serverAccount, video, t) | 27 | return sendVideoAnnounceToFollowers(serverAccount, video, t) |
28 | } | 28 | } |
29 | 29 | ||
30 | export { | 30 | export { |
diff --git a/server/lib/activitypub/url.ts b/server/lib/activitypub/url.ts index 17395a99b..6475c4218 100644 --- a/server/lib/activitypub/url.ts +++ b/server/lib/activitypub/url.ts | |||
@@ -22,37 +22,37 @@ function getVideoAbuseActivityPubUrl (videoAbuse: VideoAbuseInstance) { | |||
22 | } | 22 | } |
23 | 23 | ||
24 | function getVideoViewActivityPubUrl (byAccount: AccountInstance, video: VideoInstance) { | 24 | function getVideoViewActivityPubUrl (byAccount: AccountInstance, video: VideoInstance) { |
25 | return video.url + '#views/' + byAccount.uuid + '/' + new Date().toISOString() | 25 | return video.url + '/views/' + byAccount.uuid + '/' + new Date().toISOString() |
26 | } | 26 | } |
27 | 27 | ||
28 | function getVideoLikeActivityPubUrl (byAccount: AccountInstance, video: VideoInstance) { | 28 | function getVideoLikeActivityPubUrl (byAccount: AccountInstance, video: VideoInstance) { |
29 | return byAccount.url + '#likes/' + video.id | 29 | return byAccount.url + '/likes/' + video.id |
30 | } | 30 | } |
31 | 31 | ||
32 | function getVideoDislikeActivityPubUrl (byAccount: AccountInstance, video: VideoInstance) { | 32 | function getVideoDislikeActivityPubUrl (byAccount: AccountInstance, video: VideoInstance) { |
33 | return byAccount.url + '#dislikes/' + video.id | 33 | return byAccount.url + '/dislikes/' + video.id |
34 | } | 34 | } |
35 | 35 | ||
36 | function getAccountFollowActivityPubUrl (accountFollow: AccountFollowInstance) { | 36 | function getAccountFollowActivityPubUrl (accountFollow: AccountFollowInstance) { |
37 | const me = accountFollow.AccountFollower | 37 | const me = accountFollow.AccountFollower |
38 | const following = accountFollow.AccountFollowing | 38 | const following = accountFollow.AccountFollowing |
39 | 39 | ||
40 | return me.url + '#follows/' + following.id | 40 | return me.url + '/follows/' + following.id |
41 | } | 41 | } |
42 | 42 | ||
43 | function getAccountFollowAcceptActivityPubUrl (accountFollow: AccountFollowInstance) { | 43 | function getAccountFollowAcceptActivityPubUrl (accountFollow: AccountFollowInstance) { |
44 | const follower = accountFollow.AccountFollower | 44 | const follower = accountFollow.AccountFollower |
45 | const me = accountFollow.AccountFollowing | 45 | const me = accountFollow.AccountFollowing |
46 | 46 | ||
47 | return follower.url + '#accepts/follows/' + me.id | 47 | return follower.url + '/accepts/follows/' + me.id |
48 | } | 48 | } |
49 | 49 | ||
50 | function getAnnounceActivityPubUrl (originalUrl: string, byAccount: AccountInstance) { | 50 | function getAnnounceActivityPubUrl (originalUrl: string, byAccount: AccountInstance) { |
51 | return originalUrl + '#announces/' + byAccount.id | 51 | return originalUrl + '/announces/' + byAccount.id |
52 | } | 52 | } |
53 | 53 | ||
54 | function getUpdateActivityPubUrl (originalUrl: string, updatedAt: string) { | 54 | function getUpdateActivityPubUrl (originalUrl: string, updatedAt: string) { |
55 | return originalUrl + '#updates/' + updatedAt | 55 | return originalUrl + '/updates/' + updatedAt |
56 | } | 56 | } |
57 | 57 | ||
58 | function getUndoActivityPubUrl (originalUrl: string) { | 58 | function getUndoActivityPubUrl (originalUrl: string) { |