Optimize view endpoint
This commit is contained in:
parent
943e519390
commit
2c8776fc31
6 changed files with 46 additions and 21 deletions
|
@ -1,4 +1,3 @@
|
||||||
// Intercept ActivityPub client requests
|
|
||||||
import * as express from 'express'
|
import * as express from 'express'
|
||||||
import { VideoPrivacy, VideoRateType } from '../../../shared/models/videos'
|
import { VideoPrivacy, VideoRateType } from '../../../shared/models/videos'
|
||||||
import { activityPubCollectionPagination, activityPubContextify } from '../../helpers/activitypub'
|
import { activityPubCollectionPagination, activityPubContextify } from '../../helpers/activitypub'
|
||||||
|
@ -37,10 +36,12 @@ import { buildDislikeActivity } from '../../lib/activitypub/send/send-dislike'
|
||||||
import { videoPlaylistElementAPGetValidator, videoPlaylistsGetValidator } from '../../middlewares/validators/videos/video-playlists'
|
import { videoPlaylistElementAPGetValidator, videoPlaylistsGetValidator } from '../../middlewares/validators/videos/video-playlists'
|
||||||
import { VideoPlaylistModel } from '../../models/video/video-playlist'
|
import { VideoPlaylistModel } from '../../models/video/video-playlist'
|
||||||
import { VideoPlaylistPrivacy } from '../../../shared/models/videos/playlist/video-playlist-privacy.model'
|
import { VideoPlaylistPrivacy } from '../../../shared/models/videos/playlist/video-playlist-privacy.model'
|
||||||
import { MAccountId, MActorId, MVideo, MVideoAPWithoutCaption, MVideoId } from '@server/typings/models'
|
import { MAccountId, MActorId, MVideoAPWithoutCaption, MVideoId } from '@server/typings/models'
|
||||||
|
|
||||||
const activityPubClientRouter = express.Router()
|
const activityPubClientRouter = express.Router()
|
||||||
|
|
||||||
|
// Intercept ActivityPub client requests
|
||||||
|
|
||||||
activityPubClientRouter.get('/accounts?/:name',
|
activityPubClientRouter.get('/accounts?/:name',
|
||||||
executeIfActivityPub,
|
executeIfActivityPub,
|
||||||
asyncMiddleware(localAccountValidator),
|
asyncMiddleware(localAccountValidator),
|
||||||
|
|
|
@ -135,7 +135,7 @@ videosRouter.get('/:id',
|
||||||
asyncMiddleware(getVideo)
|
asyncMiddleware(getVideo)
|
||||||
)
|
)
|
||||||
videosRouter.post('/:id/views',
|
videosRouter.post('/:id/views',
|
||||||
asyncMiddleware(videosGetValidator),
|
asyncMiddleware(videosCustomGetValidator('only-immutable-attributes')),
|
||||||
asyncMiddleware(viewVideo)
|
asyncMiddleware(viewVideo)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -458,7 +458,7 @@ async function getVideo (req: express.Request, res: express.Response) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function viewVideo (req: express.Request, res: express.Response) {
|
async function viewVideo (req: express.Request, res: express.Response) {
|
||||||
const videoInstance = res.locals.videoAll
|
const videoInstance = res.locals.onlyImmutableVideo
|
||||||
|
|
||||||
const ip = req.ip
|
const ip = req.ip
|
||||||
const exists = await Redis.Instance.doesVideoIPViewExist(ip, videoInstance.uuid)
|
const exists = await Redis.Instance.doesVideoIPViewExist(ip, videoInstance.uuid)
|
||||||
|
|
|
@ -4,19 +4,11 @@ import { ACTIVITY_PUB } from '../../initializers/constants'
|
||||||
import { ActorModel } from '../../models/activitypub/actor'
|
import { ActorModel } from '../../models/activitypub/actor'
|
||||||
import { VideoModel } from '../../models/video/video'
|
import { VideoModel } from '../../models/video/video'
|
||||||
import { VideoShareModel } from '../../models/video/video-share'
|
import { VideoShareModel } from '../../models/video/video-share'
|
||||||
import {
|
import { MActorFollowersUrl, MActorLight, MActorUrl, MCommentOwner, MCommentOwnerVideo, MVideoId } from '../../typings/models'
|
||||||
MActorFollowersUrl,
|
|
||||||
MActorLight,
|
|
||||||
MCommentOwner,
|
|
||||||
MCommentOwnerVideo,
|
|
||||||
MVideo,
|
|
||||||
MVideoAccountLight,
|
|
||||||
MVideoId
|
|
||||||
} from '../../typings/models'
|
|
||||||
|
|
||||||
function getRemoteVideoAudience (video: MVideoAccountLight, actorsInvolvedInVideo: MActorFollowersUrl[]): ActivityAudience {
|
function getRemoteVideoAudience (accountActor: MActorUrl, actorsInvolvedInVideo: MActorFollowersUrl[]): ActivityAudience {
|
||||||
return {
|
return {
|
||||||
to: [ video.VideoChannel.Account.Actor.url ],
|
to: [ accountActor.url ],
|
||||||
cc: actorsInvolvedInVideo.map(a => a.followersUrl)
|
cc: actorsInvolvedInVideo.map(a => a.followersUrl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,9 @@ import { getVideoLikeActivityPubUrl } from '../url'
|
||||||
import { sendVideoRelatedActivity } from './utils'
|
import { sendVideoRelatedActivity } from './utils'
|
||||||
import { audiencify, getAudience } from '../audience'
|
import { audiencify, getAudience } from '../audience'
|
||||||
import { logger } from '../../../helpers/logger'
|
import { logger } from '../../../helpers/logger'
|
||||||
import { MActorAudience, MVideoAccountLight, MVideoUrl } from '@server/typings/models'
|
import { MActorAudience, MVideoImmutable, MVideoUrl } from '@server/typings/models'
|
||||||
|
|
||||||
async function sendView (byActor: ActorModel, video: MVideoAccountLight, t: Transaction) {
|
async function sendView (byActor: ActorModel, video: MVideoImmutable, t: Transaction) {
|
||||||
logger.info('Creating job to send view of %s.', video.url)
|
logger.info('Creating job to send view of %s.', video.url)
|
||||||
|
|
||||||
const activityBuilder = (audience: ActivityAudience) => {
|
const activityBuilder = (audience: ActivityAudience) => {
|
||||||
|
|
|
@ -7,12 +7,12 @@ import { JobQueue } from '../../job-queue'
|
||||||
import { getActorsInvolvedInVideo, getAudienceFromFollowersOf, getRemoteVideoAudience } from '../audience'
|
import { getActorsInvolvedInVideo, getAudienceFromFollowersOf, getRemoteVideoAudience } from '../audience'
|
||||||
import { getServerActor } from '../../../helpers/utils'
|
import { getServerActor } from '../../../helpers/utils'
|
||||||
import { afterCommitIfTransaction } from '../../../helpers/database-utils'
|
import { afterCommitIfTransaction } from '../../../helpers/database-utils'
|
||||||
import { MActorWithInboxes, MActor, MActorId, MActorLight, MVideo, MVideoAccountLight, MVideoId } from '../../../typings/models'
|
import { MActor, MActorId, MActorLight, MActorWithInboxes, MVideoAccountLight, MVideoId, MVideoImmutable } from '../../../typings/models'
|
||||||
import { ContextType } from '@server/helpers/activitypub'
|
import { ContextType } from '@server/helpers/activitypub'
|
||||||
|
|
||||||
async function sendVideoRelatedActivity (activityBuilder: (audience: ActivityAudience) => Activity, options: {
|
async function sendVideoRelatedActivity (activityBuilder: (audience: ActivityAudience) => Activity, options: {
|
||||||
byActor: MActorLight
|
byActor: MActorLight
|
||||||
video: MVideoAccountLight
|
video: MVideoImmutable | MVideoAccountLight
|
||||||
transaction?: Transaction
|
transaction?: Transaction
|
||||||
contextType?: ContextType
|
contextType?: ContextType
|
||||||
}) {
|
}) {
|
||||||
|
@ -22,11 +22,13 @@ async function sendVideoRelatedActivity (activityBuilder: (audience: ActivityAud
|
||||||
|
|
||||||
// Send to origin
|
// Send to origin
|
||||||
if (video.isOwned() === false) {
|
if (video.isOwned() === false) {
|
||||||
const audience = getRemoteVideoAudience(video, actorsInvolvedInVideo)
|
const accountActor = (video as MVideoAccountLight).VideoChannel?.Account?.Actor || await ActorModel.loadAccountActorByVideoId(video.id)
|
||||||
|
|
||||||
|
const audience = getRemoteVideoAudience(accountActor, actorsInvolvedInVideo)
|
||||||
const activity = activityBuilder(audience)
|
const activity = activityBuilder(audience)
|
||||||
|
|
||||||
return afterCommitIfTransaction(transaction, () => {
|
return afterCommitIfTransaction(transaction, () => {
|
||||||
return unicastTo(activity, byActor, video.VideoChannel.Account.Actor.getSharedInbox(), contextType)
|
return unicastTo(activity, byActor, accountActor.getSharedInbox(), contextType)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -462,6 +462,36 @@ export class ActorModel extends Model<ActorModel> {
|
||||||
}, { where, transaction })
|
}, { where, transaction })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static loadAccountActorByVideoId (videoId: number): Bluebird<MActor> {
|
||||||
|
const query = {
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
attributes: [ 'id' ],
|
||||||
|
model: AccountModel.unscoped(),
|
||||||
|
required: true,
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
attributes: [ 'id', 'accountId' ],
|
||||||
|
model: VideoChannelModel.unscoped(),
|
||||||
|
required: true,
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
attributes: [ 'id', 'channelId' ],
|
||||||
|
model: VideoModel.unscoped(),
|
||||||
|
where: {
|
||||||
|
id: videoId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
return ActorModel.unscoped().findOne(query)
|
||||||
|
}
|
||||||
|
|
||||||
getSharedInbox (this: MActorWithInboxes) {
|
getSharedInbox (this: MActorWithInboxes) {
|
||||||
return this.sharedInboxUrl || this.inboxUrl
|
return this.sharedInboxUrl || this.inboxUrl
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue