From 7006bc6378eb0d480bc5b60f2c18876f0bb2a97d Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 15 Jan 2018 09:46:46 +0100 Subject: [PATCH] Fix actor followers/following counts --- server/controllers/activitypub/client.ts | 63 +++++++++++++++++------- server/helpers/requests.ts | 6 ++- server/lib/activitypub/actor.ts | 9 ++-- server/tests/api/server/follows.ts | 2 +- 4 files changed, 54 insertions(+), 26 deletions(-) diff --git a/server/controllers/activitypub/client.ts b/server/controllers/activitypub/client.ts index ec3f72b64..ba659984f 100644 --- a/server/controllers/activitypub/client.ts +++ b/server/controllers/activitypub/client.ts @@ -10,6 +10,7 @@ import { asyncMiddleware, executeIfActivityPub, localAccountValidator } from '.. import { videoChannelsGetValidator, videosGetValidator, videosShareValidator } from '../../middlewares/validators' import { videoCommentGetValidator } from '../../middlewares/validators/video-comments' import { AccountModel } from '../../models/account/account' +import { ActorModel } from '../../models/activitypub/actor' import { ActorFollowModel } from '../../models/activitypub/actor-follow' import { VideoModel } from '../../models/video/video' import { VideoChannelModel } from '../../models/video/video-channel' @@ -22,13 +23,11 @@ activityPubClientRouter.get('/accounts?/:name', executeIfActivityPub(asyncMiddleware(localAccountValidator)), executeIfActivityPub(accountController) ) - -activityPubClientRouter.get('/accounts/:name/followers', +activityPubClientRouter.get('/accounts?/:name/followers', executeIfActivityPub(asyncMiddleware(localAccountValidator)), executeIfActivityPub(asyncMiddleware(accountFollowersController)) ) - -activityPubClientRouter.get('/accounts/:name/following', +activityPubClientRouter.get('/accounts?/:name/following', executeIfActivityPub(asyncMiddleware(localAccountValidator)), executeIfActivityPub(asyncMiddleware(accountFollowingController)) ) @@ -37,12 +36,10 @@ activityPubClientRouter.get('/videos/watch/:id', executeIfActivityPub(asyncMiddleware(videosGetValidator)), executeIfActivityPub(asyncMiddleware(videoController)) ) - activityPubClientRouter.get('/videos/watch/:id/announces/:accountId', executeIfActivityPub(asyncMiddleware(videosShareValidator)), executeIfActivityPub(asyncMiddleware(videoAnnounceController)) ) - activityPubClientRouter.get('/videos/watch/:videoId/comments/:commentId', executeIfActivityPub(asyncMiddleware(videoCommentGetValidator)), executeIfActivityPub(asyncMiddleware(videoCommentController)) @@ -52,6 +49,14 @@ activityPubClientRouter.get('/video-channels/:id', executeIfActivityPub(asyncMiddleware(videoChannelsGetValidator)), executeIfActivityPub(asyncMiddleware(videoChannelController)) ) +activityPubClientRouter.get('/video-channels/:id/followers', + executeIfActivityPub(asyncMiddleware(videoChannelsGetValidator)), + executeIfActivityPub(asyncMiddleware(videoChannelFollowersController)) +) +activityPubClientRouter.get('/video-channels/:id/following', + executeIfActivityPub(asyncMiddleware(videoChannelsGetValidator)), + executeIfActivityPub(asyncMiddleware(videoChannelFollowingController)) +) // --------------------------------------------------------------------------- @@ -70,24 +75,14 @@ function accountController (req: express.Request, res: express.Response, next: e async function accountFollowersController (req: express.Request, res: express.Response, next: express.NextFunction) { const account: AccountModel = res.locals.account - - const page = req.query.page || 1 - const { start, count } = pageToStartAndCount(page, ACTIVITY_PUB.COLLECTION_ITEMS_PER_PAGE) - - const result = await ActorFollowModel.listAcceptedFollowerUrlsForApi([ account.Actor.id ], undefined, start, count) - const activityPubResult = activityPubCollectionPagination(CONFIG.WEBSERVER.URL + req.url, page, result) + const activityPubResult = await actorFollowers(req, account.Actor) return res.json(activityPubResult) } async function accountFollowingController (req: express.Request, res: express.Response, next: express.NextFunction) { const account: AccountModel = res.locals.account - - const page = req.query.page || 1 - const { start, count } = pageToStartAndCount(page, ACTIVITY_PUB.COLLECTION_ITEMS_PER_PAGE) - - const result = await ActorFollowModel.listAcceptedFollowingUrlsForApi([ account.Actor.id ], undefined, start, count) - const activityPubResult = activityPubCollectionPagination(CONFIG.WEBSERVER.URL + req.url, page, result) + const activityPubResult = await actorFollowing(req, account.Actor) return res.json(activityPubResult) } @@ -115,9 +110,41 @@ async function videoChannelController (req: express.Request, res: express.Respon return res.json(videoChannel.toActivityPubObject()) } +async function videoChannelFollowersController (req: express.Request, res: express.Response, next: express.NextFunction) { + const videoChannel: VideoChannelModel = res.locals.videoChannel + const activityPubResult = await actorFollowers(req, videoChannel.Actor) + + return res.json(activityPubResult) +} + +async function videoChannelFollowingController (req: express.Request, res: express.Response, next: express.NextFunction) { + const videoChannel: VideoChannelModel = res.locals.videoChannel + const activityPubResult = await actorFollowing(req, videoChannel.Actor) + + return res.json(activityPubResult) +} + async function videoCommentController (req: express.Request, res: express.Response, next: express.NextFunction) { const videoComment: VideoCommentModel = res.locals.videoComment const threadParentComments = await VideoCommentModel.listThreadParentComments(videoComment, undefined) return res.json(videoComment.toActivityPubObject(threadParentComments)) } + +// --------------------------------------------------------------------------- + +async function actorFollowing (req: express.Request, actor: ActorModel) { + const page = req.query.page || 1 + const { start, count } = pageToStartAndCount(page, ACTIVITY_PUB.COLLECTION_ITEMS_PER_PAGE) + + const result = await ActorFollowModel.listAcceptedFollowingUrlsForApi([ actor.id ], undefined, start, count) + return activityPubCollectionPagination(CONFIG.WEBSERVER.URL + req.url, page, result) +} + +async function actorFollowers (req: express.Request, actor: ActorModel) { + const page = req.query.page || 1 + const { start, count } = pageToStartAndCount(page, ACTIVITY_PUB.COLLECTION_ITEMS_PER_PAGE) + + const result = await ActorFollowModel.listAcceptedFollowerUrlsForApi([ actor.id ], undefined, start, count) + return activityPubCollectionPagination(CONFIG.WEBSERVER.URL + req.url, page, result) +} diff --git a/server/helpers/requests.ts b/server/helpers/requests.ts index ce185a2c0..ac3559c58 100644 --- a/server/helpers/requests.ts +++ b/server/helpers/requests.ts @@ -1,9 +1,13 @@ import * as Promise from 'bluebird' import { createWriteStream } from 'fs' +import { RequestResponse } from 'request' import * as request from 'request' import { ACTIVITY_PUB } from '../initializers' +import Bluebird = require('bluebird') -function doRequest (requestOptions: request.CoreOptions & request.UriOptions & { activityPub?: boolean }) { +function doRequest ( + requestOptions: request.CoreOptions & request.UriOptions & { activityPub?: boolean } +): Bluebird<{ response: RequestResponse, body: any }> { if (requestOptions.activityPub === true) { if (!Array.isArray(requestOptions.headers)) requestOptions.headers = {} requestOptions.headers['accept'] = ACTIVITY_PUB.ACCEPT_HEADER diff --git a/server/lib/activitypub/actor.ts b/server/lib/activitypub/actor.ts index b3fb75421..2e0f3cfc2 100644 --- a/server/lib/activitypub/actor.ts +++ b/server/lib/activitypub/actor.ts @@ -132,15 +132,13 @@ async function fetchActorTotalItems (url: string) { activityPub: true } - let requestResult try { - requestResult = await doRequest(options) + const { body } = await doRequest(options) + return body.totalItems ? body.totalItems : 0 } catch (err) { logger.warn('Cannot fetch remote actor count %s.', url, err) - return undefined + return 0 } - - return requestResult.totalItems ? requestResult.totalItems : 0 } async function fetchAvatarIfExists (actorJSON: ActivityPubActor) { @@ -314,7 +312,6 @@ async function refreshActorIfNeeded (actor: ActorModel) { if (result === undefined) throw new Error('Cannot fetch remote actor in refresh actor.') return sequelizeTypescript.transaction(async t => { - logger.info('coucou', result.actor.toJSON()) updateInstanceWithAnother(actor, result.actor) if (result.avatarName !== undefined) { diff --git a/server/tests/api/server/follows.ts b/server/tests/api/server/follows.ts index d16e98bc1..fad58e840 100644 --- a/server/tests/api/server/follows.ts +++ b/server/tests/api/server/follows.ts @@ -256,7 +256,7 @@ describe('Test follows', function () { await expectAccountFollows(servers[1].url, 'peertube@localhost:9001', 0, 1) await expectAccountFollows(servers[1].url, 'peertube@localhost:9002', 1, 0) - await expectAccountFollows(servers[2].url, 'peertube@localhost:9001', 0, 1) + await expectAccountFollows(servers[2].url, 'peertube@localhost:9001', 0, 2) await expectAccountFollows(servers[2].url, 'peertube@localhost:9003', 1, 0) })