X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Fcontrollers%2Fapi%2Foverviews.ts;h=34585e557f775e9ac97ee03065a3fe9a3eb5a816;hb=bd911b54b555b11df7e9849cf92d358bccfecf6e;hp=75f3baedbd0f4c83ba71027c28c6267b16ce23bc;hpb=a15871560f80e07386c1dabb8370cd2664ecfd1f;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/controllers/api/overviews.ts b/server/controllers/api/overviews.ts index 75f3baedb..34585e557 100644 --- a/server/controllers/api/overviews.ts +++ b/server/controllers/api/overviews.ts @@ -1,17 +1,20 @@ -import * as express from 'express' +import express from 'express' +import memoizee from 'memoizee' +import { logger } from '@server/helpers/logger' +import { Hooks } from '@server/lib/plugins/hooks' +import { VideoModel } from '@server/models/video/video' +import { CategoryOverview, ChannelOverview, TagOverview, VideosOverview } from '../../../shared/models/overviews' import { buildNSFWFilter } from '../../helpers/express-utils' -import { VideoModel } from '../../models/video/video' -import { asyncMiddleware } from '../../middlewares' +import { MEMOIZE_TTL, OVERVIEWS } from '../../initializers/constants' +import { asyncMiddleware, optionalAuthenticate, videosOverviewValidator } from '../../middlewares' import { TagModel } from '../../models/video/tag' -import { VideosOverview } from '../../../shared/models/overviews' -import { MEMOIZE_TTL, OVERVIEWS, ROUTE_CACHE_LIFETIME } from '../../initializers/constants' -import { cacheRoute } from '../../middlewares/cache' -import * as memoizee from 'memoizee' +import { getServerActor } from '@server/models/application/application' const overviewsRouter = express.Router() overviewsRouter.get('/videos', - asyncMiddleware(cacheRoute()(ROUTE_CACHE_LIFETIME.OVERVIEWS.VIDEOS)), + videosOverviewValidator, + optionalAuthenticate, asyncMiddleware(getVideosOverview) ) @@ -28,17 +31,28 @@ const buildSamples = memoizee(async function () { TagModel.getRandomSamples(OVERVIEWS.VIDEOS.SAMPLE_THRESHOLD, OVERVIEWS.VIDEOS.SAMPLES_COUNT) ]) - return { categories, channels, tags } + const result = { categories, channels, tags } + + logger.debug('Building samples for overview endpoint.', { result }) + + return result }, { maxAge: MEMOIZE_TTL.OVERVIEWS_SAMPLE }) // This endpoint could be quite long, but we cache it async function getVideosOverview (req: express.Request, res: express.Response) { const attributes = await buildSamples() - const [ categories, channels, tags ] = await Promise.all([ - Promise.all(attributes.categories.map(c => getVideosByCategory(c, res))), - Promise.all(attributes.channels.map(c => getVideosByChannel(c, res))), - Promise.all(attributes.tags.map(t => getVideosByTag(t, res))) + const page = req.query.page || 1 + const index = page - 1 + + const categories: CategoryOverview[] = [] + const channels: ChannelOverview[] = [] + const tags: TagOverview[] = [] + + await Promise.all([ + getVideosByCategory(attributes.categories, index, res, categories), + getVideosByChannel(attributes.channels, index, res, channels), + getVideosByTag(attributes.tags, index, res, tags) ]) const result: VideosOverview = { @@ -47,62 +61,77 @@ async function getVideosOverview (req: express.Request, res: express.Response) { tags } - // Cleanup our object - for (const key of Object.keys(result)) { - result[key] = result[key].filter(v => v !== undefined) - } - return res.json(result) } -async function getVideosByTag (tag: string, res: express.Response) { +async function getVideosByTag (tagsSample: string[], index: number, res: express.Response, acc: TagOverview[]) { + if (tagsSample.length <= index) return + + const tag = tagsSample[index] const videos = await getVideos(res, { tagsOneOf: [ tag ] }) - if (videos.length === 0) return undefined + if (videos.length === 0) return - return { + acc.push({ tag, videos - } + }) } -async function getVideosByCategory (category: number, res: express.Response) { +async function getVideosByCategory (categoriesSample: number[], index: number, res: express.Response, acc: CategoryOverview[]) { + if (categoriesSample.length <= index) return + + const category = categoriesSample[index] const videos = await getVideos(res, { categoryOneOf: [ category ] }) - if (videos.length === 0) return undefined + if (videos.length === 0) return - return { + acc.push({ category: videos[0].category, videos - } + }) } -async function getVideosByChannel (channelId: number, res: express.Response) { +async function getVideosByChannel (channelsSample: number[], index: number, res: express.Response, acc: ChannelOverview[]) { + if (channelsSample.length <= index) return + + const channelId = channelsSample[index] const videos = await getVideos(res, { videoChannelId: channelId }) - if (videos.length === 0) return undefined + if (videos.length === 0) return - return { + acc.push({ channel: videos[0].channel, videos - } + }) } async function getVideos ( res: express.Response, where: { videoChannelId?: number, tagsOneOf?: string[], categoryOneOf?: number[] } ) { - const query = Object.assign({ + const serverActor = await getServerActor() + + const query = await Hooks.wrapObject({ start: 0, count: 12, sort: '-createdAt', - includeLocalVideos: true, + displayOnlyForFollower: { + actorId: serverActor.id, + orLocalVideos: true + }, nsfw: buildNSFWFilter(res), - withFiles: false, - countVideos: false - }, where) + user: res.locals.oauth ? res.locals.oauth.token.User : undefined, + countVideos: false, + + ...where + }, 'filter:api.overviews.videos.list.params') - const { data } = await VideoModel.listForApi(query) + const { data } = await Hooks.wrapPromiseFun( + VideoModel.listForApi, + query, + 'filter:api.overviews.videos.list.result' + ) return data.map(d => d.toFormattedJSON()) }