aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/controllers/activitypub
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2018-05-25 16:21:16 +0200
committerChocobozzz <me@florianbigard.com>2018-05-25 16:21:16 +0200
commit8fffe21a7bc96d08b229293d66ddba576e609790 (patch)
tree5ebd5f5198a59084c5338ce197d7e836b39200a4 /server/controllers/activitypub
parente251f170b00b2014ac4e823113c6ff40e3fb1471 (diff)
downloadPeerTube-8fffe21a7bc96d08b229293d66ddba576e609790.tar.gz
PeerTube-8fffe21a7bc96d08b229293d66ddba576e609790.tar.zst
PeerTube-8fffe21a7bc96d08b229293d66ddba576e609790.zip
Refractor and optimize AP collections
Only display urls in general object, and paginate video comments, shares, likes and dislikes
Diffstat (limited to 'server/controllers/activitypub')
-rw-r--r--server/controllers/activitypub/client.ts86
-rw-r--r--server/controllers/activitypub/outbox.ts24
-rw-r--r--server/controllers/activitypub/utils.ts11
3 files changed, 73 insertions, 48 deletions
diff --git a/server/controllers/activitypub/client.ts b/server/controllers/activitypub/client.ts
index 767fde5d9..1c780783c 100644
--- a/server/controllers/activitypub/client.ts
+++ b/server/controllers/activitypub/client.ts
@@ -1,9 +1,8 @@
1// Intercept ActivityPub client requests 1// Intercept ActivityPub client requests
2import * as express from 'express' 2import * as express from 'express'
3import { VideoPrivacy } from '../../../shared/models/videos' 3import { VideoPrivacy, VideoRateType } from '../../../shared/models/videos'
4import { activityPubCollectionPagination, activityPubContextify } from '../../helpers/activitypub' 4import { activityPubCollectionPagination, activityPubContextify } from '../../helpers/activitypub'
5import { pageToStartAndCount } from '../../helpers/core-utils' 5import { CONFIG, ROUTE_CACHE_LIFETIME } from '../../initializers'
6import { ACTIVITY_PUB, CONFIG, ROUTE_CACHE_LIFETIME } from '../../initializers'
7import { buildVideoAnnounce } from '../../lib/activitypub/send' 6import { buildVideoAnnounce } from '../../lib/activitypub/send'
8import { audiencify, getAudience } from '../../lib/activitypub/audience' 7import { audiencify, getAudience } from '../../lib/activitypub/audience'
9import { createActivityData } from '../../lib/activitypub/send/send-create' 8import { createActivityData } from '../../lib/activitypub/send/send-create'
@@ -18,6 +17,14 @@ import { VideoChannelModel } from '../../models/video/video-channel'
18import { VideoCommentModel } from '../../models/video/video-comment' 17import { VideoCommentModel } from '../../models/video/video-comment'
19import { VideoShareModel } from '../../models/video/video-share' 18import { VideoShareModel } from '../../models/video/video-share'
20import { cacheRoute } from '../../middlewares/cache' 19import { cacheRoute } from '../../middlewares/cache'
20import { activityPubResponse } from './utils'
21import { AccountVideoRateModel } from '../../models/account/account-video-rate'
22import {
23 getVideoCommentsActivityPubUrl,
24 getVideoDislikesActivityPubUrl,
25 getVideoLikesActivityPubUrl,
26 getVideoSharesActivityPubUrl
27} from '../../lib/activitypub'
21 28
22const activityPubClientRouter = express.Router() 29const activityPubClientRouter = express.Router()
23 30
@@ -116,10 +123,8 @@ async function accountFollowingController (req: express.Request, res: express.Re
116async function videoController (req: express.Request, res: express.Response, next: express.NextFunction) { 123async function videoController (req: express.Request, res: express.Response, next: express.NextFunction) {
117 const video: VideoModel = res.locals.video 124 const video: VideoModel = res.locals.video
118 125
119 // We need more attributes
120 const videoAll = await VideoModel.loadAndPopulateAll(video.id)
121 const audience = await getAudience(video.VideoChannel.Account.Actor, undefined, video.privacy === VideoPrivacy.PUBLIC) 126 const audience = await getAudience(video.VideoChannel.Account.Actor, undefined, video.privacy === VideoPrivacy.PUBLIC)
122 const videoObject = audiencify(videoAll.toActivityPubObject(), audience) 127 const videoObject = audiencify(video.toActivityPubObject(), audience)
123 128
124 if (req.path.endsWith('/activity')) { 129 if (req.path.endsWith('/activity')) {
125 const data = await createActivityData(video.url, video.VideoChannel.Account.Actor, videoObject, undefined, audience) 130 const data = await createActivityData(video.url, video.VideoChannel.Account.Actor, videoObject, undefined, audience)
@@ -139,41 +144,45 @@ async function videoAnnounceController (req: express.Request, res: express.Respo
139async function videoAnnouncesController (req: express.Request, res: express.Response, next: express.NextFunction) { 144async function videoAnnouncesController (req: express.Request, res: express.Response, next: express.NextFunction) {
140 const video: VideoModel = res.locals.video 145 const video: VideoModel = res.locals.video
141 146
142 // We need more attributes 147 const handler = async (start: number, count: number) => {
143 const videoAll = await VideoModel.loadAndPopulateAll(video.id) 148 const result = await VideoShareModel.listAndCountByVideoId(video.id, start, count)
144 const object = videoAll.toAnnouncesActivityPubObject() 149 return {
150 total: result.count,
151 data: result.rows.map(r => r.url)
152 }
153 }
154 const json = await activityPubCollectionPagination(getVideoSharesActivityPubUrl(video), handler, req.query.page)
145 155
146 return activityPubResponse(activityPubContextify(object), res) 156 return activityPubResponse(activityPubContextify(json), res)
147} 157}
148 158
149async function videoLikesController (req: express.Request, res: express.Response, next: express.NextFunction) { 159async function videoLikesController (req: express.Request, res: express.Response, next: express.NextFunction) {
150 const video: VideoModel = res.locals.video 160 const video: VideoModel = res.locals.video
161 const json = await videoRates(req, 'like', video, getVideoLikesActivityPubUrl(video))
151 162
152 // We need more attributes 163 return activityPubResponse(activityPubContextify(json), res)
153 const videoAll = await VideoModel.loadAndPopulateAll(video.id)
154 const { likesObject } = videoAll.toRatesActivityPubObjects()
155
156 return activityPubResponse(activityPubContextify(likesObject), res)
157} 164}
158 165
159async function videoDislikesController (req: express.Request, res: express.Response, next: express.NextFunction) { 166async function videoDislikesController (req: express.Request, res: express.Response, next: express.NextFunction) {
160 const video: VideoModel = res.locals.video 167 const video: VideoModel = res.locals.video
168 const json = await videoRates(req, 'dislike', video, getVideoDislikesActivityPubUrl(video))
161 169
162 // We need more attributes 170 return activityPubResponse(activityPubContextify(json), res)
163 const videoAll = await VideoModel.loadAndPopulateAll(video.id)
164 const { dislikesObject } = videoAll.toRatesActivityPubObjects()
165
166 return activityPubResponse(activityPubContextify(dislikesObject), res)
167} 171}
168 172
169async function videoCommentsController (req: express.Request, res: express.Response, next: express.NextFunction) { 173async function videoCommentsController (req: express.Request, res: express.Response, next: express.NextFunction) {
170 const video: VideoModel = res.locals.video 174 const video: VideoModel = res.locals.video
171 175
172 // We need more attributes 176 const handler = async (start: number, count: number) => {
173 const videoAll = await VideoModel.loadAndPopulateAll(video.id) 177 const result = await VideoCommentModel.listAndCountByVideoId(video.id, start, count)
174 const commentsObject = videoAll.toCommentsActivityPubObject() 178 return {
179 total: result.count,
180 data: result.rows.map(r => r.url)
181 }
182 }
183 const json = await activityPubCollectionPagination(getVideoCommentsActivityPubUrl(video), handler, req.query.page)
175 184
176 return activityPubResponse(activityPubContextify(commentsObject), res) 185 return activityPubResponse(activityPubContextify(json), res)
177} 186}
178 187
179async function videoChannelController (req: express.Request, res: express.Response, next: express.NextFunction) { 188async function videoChannelController (req: express.Request, res: express.Response, next: express.NextFunction) {
@@ -216,23 +225,28 @@ async function videoCommentController (req: express.Request, res: express.Respon
216// --------------------------------------------------------------------------- 225// ---------------------------------------------------------------------------
217 226
218async function actorFollowing (req: express.Request, actor: ActorModel) { 227async function actorFollowing (req: express.Request, actor: ActorModel) {
219 const page = req.query.page || 1 228 const handler = (start: number, count: number) => {
220 const { start, count } = pageToStartAndCount(page, ACTIVITY_PUB.COLLECTION_ITEMS_PER_PAGE) 229 return ActorFollowModel.listAcceptedFollowingUrlsForApi([ actor.id ], undefined, start, count)
230 }
221 231
222 const result = await ActorFollowModel.listAcceptedFollowingUrlsForApi([ actor.id ], undefined, start, count) 232 return activityPubCollectionPagination(CONFIG.WEBSERVER.URL + req.url, handler, req.query.page)
223 return activityPubCollectionPagination(CONFIG.WEBSERVER.URL + req.url, page, result)
224} 233}
225 234
226async function actorFollowers (req: express.Request, actor: ActorModel) { 235async function actorFollowers (req: express.Request, actor: ActorModel) {
227 const page = req.query.page || 1 236 const handler = (start: number, count: number) => {
228 const { start, count } = pageToStartAndCount(page, ACTIVITY_PUB.COLLECTION_ITEMS_PER_PAGE) 237 return ActorFollowModel.listAcceptedFollowerUrlsForApi([ actor.id ], undefined, start, count)
238 }
229 239
230 const result = await ActorFollowModel.listAcceptedFollowerUrlsForApi([ actor.id ], undefined, start, count) 240 return activityPubCollectionPagination(CONFIG.WEBSERVER.URL + req.url, handler, req.query.page)
231 return activityPubCollectionPagination(CONFIG.WEBSERVER.URL + req.url, page, result)
232} 241}
233 242
234function activityPubResponse (data: any, res: express.Response) { 243function videoRates (req: express.Request, rateType: VideoRateType, video: VideoModel, url: string) {
235 return res.type('application/activity+json; charset=utf-8') 244 const handler = async (start: number, count: number) => {
236 .json(data) 245 const result = await AccountVideoRateModel.listAndCountAccountUrlsByVideoId(rateType, video.id, start, count)
237 .end() 246 return {
247 total: result.count,
248 data: result.rows.map(r => r.Account.Actor.url)
249 }
250 }
251 return activityPubCollectionPagination(url, handler, req.query.page)
238} 252}
diff --git a/server/controllers/activitypub/outbox.ts b/server/controllers/activitypub/outbox.ts
index c9e087a13..97bf9b052 100644
--- a/server/controllers/activitypub/outbox.ts
+++ b/server/controllers/activitypub/outbox.ts
@@ -1,16 +1,15 @@
1import * as express from 'express' 1import * as express from 'express'
2import { Activity } from '../../../shared/models/activitypub/activity' 2import { Activity } from '../../../shared/models/activitypub/activity'
3import { VideoPrivacy } from '../../../shared/models/videos' 3import { VideoPrivacy } from '../../../shared/models/videos'
4import { activityPubCollectionPagination } from '../../helpers/activitypub' 4import { activityPubCollectionPagination, activityPubContextify } from '../../helpers/activitypub'
5import { pageToStartAndCount } from '../../helpers/core-utils'
6import { logger } from '../../helpers/logger' 5import { logger } from '../../helpers/logger'
7import { ACTIVITY_PUB } from '../../initializers/constants'
8import { announceActivityData, createActivityData } from '../../lib/activitypub/send' 6import { announceActivityData, createActivityData } from '../../lib/activitypub/send'
9import { buildAudience } from '../../lib/activitypub/audience' 7import { buildAudience } from '../../lib/activitypub/audience'
10import { asyncMiddleware, localAccountValidator } from '../../middlewares' 8import { asyncMiddleware, localAccountValidator } from '../../middlewares'
11import { AccountModel } from '../../models/account/account' 9import { AccountModel } from '../../models/account/account'
12import { ActorModel } from '../../models/activitypub/actor' 10import { ActorModel } from '../../models/activitypub/actor'
13import { VideoModel } from '../../models/video/video' 11import { VideoModel } from '../../models/video/video'
12import { activityPubResponse } from './utils'
14 13
15const outboxRouter = express.Router() 14const outboxRouter = express.Router()
16 15
@@ -30,10 +29,17 @@ export {
30async function outboxController (req: express.Request, res: express.Response, next: express.NextFunction) { 29async function outboxController (req: express.Request, res: express.Response, next: express.NextFunction) {
31 const account: AccountModel = res.locals.account 30 const account: AccountModel = res.locals.account
32 const actor = account.Actor 31 const actor = account.Actor
32 const actorOutboxUrl = account.Actor.url + '/outbox'
33
34 logger.info('Receiving outbox request for %s.', actorOutboxUrl)
33 35
34 const page = req.query.page || 1 36 const handler = (start: number, count: number) => buildActivities(actor, start, count)
35 const { start, count } = pageToStartAndCount(page, ACTIVITY_PUB.COLLECTION_ITEMS_PER_PAGE) 37 const json = await activityPubCollectionPagination(actorOutboxUrl, handler, req.query.page)
38
39 return activityPubResponse(activityPubContextify(json), res)
40}
36 41
42async function buildActivities (actor: ActorModel, start: number, count: number) {
37 const data = await VideoModel.listAllAndSharedByActorForOutbox(actor.id, start, count) 43 const data = await VideoModel.listAllAndSharedByActorForOutbox(actor.id, start, count)
38 const activities: Activity[] = [] 44 const activities: Activity[] = []
39 45
@@ -62,14 +68,8 @@ async function outboxController (req: express.Request, res: express.Response, ne
62 } 68 }
63 } 69 }
64 70
65 const newResult = { 71 return {
66 data: activities, 72 data: activities,
67 total: data.total 73 total: data.total
68 } 74 }
69 const actorOutboxUrl = account.Actor.url + '/outbox'
70 const json = activityPubCollectionPagination(actorOutboxUrl, page, newResult)
71
72 logger.info('Receiving outbox request for %s.', actorOutboxUrl)
73
74 return res.json(json).end()
75} 75}
diff --git a/server/controllers/activitypub/utils.ts b/server/controllers/activitypub/utils.ts
new file mode 100644
index 000000000..599cf48ab
--- /dev/null
+++ b/server/controllers/activitypub/utils.ts
@@ -0,0 +1,11 @@
1import * as express from 'express'
2
3function activityPubResponse (data: any, res: express.Response) {
4 return res.type('application/activity+json; charset=utf-8')
5 .json(data)
6 .end()
7}
8
9export {
10 activityPubResponse
11}