]>
Commit | Line | Data |
---|---|---|
2d3741d6 C |
1 | import * as express from 'express' |
2 | import { buildNSFWFilter } from '../../helpers/express-utils' | |
3 | import { VideoModel } from '../../models/video/video' | |
558187a7 | 4 | import { asyncMiddleware } from '../../middlewares' |
2d3741d6 C |
5 | import { TagModel } from '../../models/video/tag' |
6 | import { VideosOverview } from '../../../shared/models/overviews' | |
7 | import { OVERVIEWS, ROUTE_CACHE_LIFETIME } from '../../initializers' | |
8 | import { cacheRoute } from '../../middlewares/cache' | |
9 | ||
10 | const overviewsRouter = express.Router() | |
11 | ||
12 | overviewsRouter.get('/videos', | |
558187a7 | 13 | asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.OVERVIEWS.VIDEOS)), |
2d3741d6 C |
14 | asyncMiddleware(getVideosOverview) |
15 | ) | |
16 | ||
17 | // --------------------------------------------------------------------------- | |
18 | ||
19 | export { overviewsRouter } | |
20 | ||
21 | // --------------------------------------------------------------------------- | |
22 | ||
23 | // This endpoint could be quite long, but we cache it | |
24 | async function getVideosOverview (req: express.Request, res: express.Response) { | |
25 | const attributes = await buildSamples() | |
26 | const result: VideosOverview = { | |
27 | categories: await Promise.all(attributes.categories.map(c => getVideosByCategory(c, res))), | |
28 | channels: await Promise.all(attributes.channels.map(c => getVideosByChannel(c, res))), | |
29 | tags: await Promise.all(attributes.tags.map(t => getVideosByTag(t, res))) | |
30 | } | |
31 | ||
32 | // Cleanup our object | |
33 | for (const key of Object.keys(result)) { | |
34 | result[key] = result[key].filter(v => v !== undefined) | |
35 | } | |
36 | ||
37 | return res.json(result) | |
38 | } | |
39 | ||
40 | async function buildSamples () { | |
41 | const [ categories, channels, tags ] = await Promise.all([ | |
42 | VideoModel.getRandomFieldSamples('category', OVERVIEWS.VIDEOS.SAMPLE_THRESHOLD, OVERVIEWS.VIDEOS.SAMPLES_COUNT), | |
43 | VideoModel.getRandomFieldSamples('channelId', OVERVIEWS.VIDEOS.SAMPLE_THRESHOLD ,OVERVIEWS.VIDEOS.SAMPLES_COUNT), | |
44 | TagModel.getRandomSamples(OVERVIEWS.VIDEOS.SAMPLE_THRESHOLD, OVERVIEWS.VIDEOS.SAMPLES_COUNT) | |
45 | ]) | |
46 | ||
47 | return { categories, channels, tags } | |
48 | } | |
49 | ||
50 | async function getVideosByTag (tag: string, res: express.Response) { | |
51 | const videos = await getVideos(res, { tagsOneOf: [ tag ] }) | |
52 | ||
53 | if (videos.length === 0) return undefined | |
54 | ||
55 | return { | |
56 | tag, | |
57 | videos | |
58 | } | |
59 | } | |
60 | ||
61 | async function getVideosByCategory (category: number, res: express.Response) { | |
62 | const videos = await getVideos(res, { categoryOneOf: [ category ] }) | |
63 | ||
64 | if (videos.length === 0) return undefined | |
65 | ||
66 | return { | |
67 | category: videos[0].category, | |
68 | videos | |
69 | } | |
70 | } | |
71 | ||
72 | async function getVideosByChannel (channelId: number, res: express.Response) { | |
73 | const videos = await getVideos(res, { videoChannelId: channelId }) | |
74 | ||
75 | if (videos.length === 0) return undefined | |
76 | ||
77 | return { | |
78 | channel: videos[0].channel, | |
79 | videos | |
80 | } | |
81 | } | |
82 | ||
83 | async function getVideos ( | |
84 | res: express.Response, | |
85 | where: { videoChannelId?: number, tagsOneOf?: string[], categoryOneOf?: number[] } | |
86 | ) { | |
87 | const { data } = await VideoModel.listForApi(Object.assign({ | |
88 | start: 0, | |
89 | count: 10, | |
90 | sort: '-createdAt', | |
91 | includeLocalVideos: true, | |
92 | nsfw: buildNSFWFilter(res), | |
93 | withFiles: false | |
94 | }, where)) | |
95 | ||
96 | return data.map(d => d.toFormattedJSON()) | |
97 | } |