mirror of https://github.com/Chocobozzz/PeerTube
				
				
				
			
		
			
				
	
	
		
			108 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			TypeScript
		
	
	
			
		
		
	
	
			108 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			TypeScript
		
	
	
import * as express from 'express'
 | 
						|
import { buildNSFWFilter } from '../../helpers/express-utils'
 | 
						|
import { VideoModel } from '../../models/video/video'
 | 
						|
import { asyncMiddleware } 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'
 | 
						|
 | 
						|
const overviewsRouter = express.Router()
 | 
						|
 | 
						|
overviewsRouter.get('/videos',
 | 
						|
  asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.OVERVIEWS.VIDEOS)),
 | 
						|
  asyncMiddleware(getVideosOverview)
 | 
						|
)
 | 
						|
 | 
						|
// ---------------------------------------------------------------------------
 | 
						|
 | 
						|
export { overviewsRouter }
 | 
						|
 | 
						|
// ---------------------------------------------------------------------------
 | 
						|
 | 
						|
const buildSamples = memoizee(async function () {
 | 
						|
  const [ categories, channels, tags ] = await Promise.all([
 | 
						|
    VideoModel.getRandomFieldSamples('category', OVERVIEWS.VIDEOS.SAMPLE_THRESHOLD, OVERVIEWS.VIDEOS.SAMPLES_COUNT),
 | 
						|
    VideoModel.getRandomFieldSamples('channelId', OVERVIEWS.VIDEOS.SAMPLE_THRESHOLD ,OVERVIEWS.VIDEOS.SAMPLES_COUNT),
 | 
						|
    TagModel.getRandomSamples(OVERVIEWS.VIDEOS.SAMPLE_THRESHOLD, OVERVIEWS.VIDEOS.SAMPLES_COUNT)
 | 
						|
  ])
 | 
						|
 | 
						|
  return { categories, channels, tags }
 | 
						|
}, { 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 result: VideosOverview = {
 | 
						|
    categories,
 | 
						|
    channels,
 | 
						|
    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) {
 | 
						|
  const videos = await getVideos(res, { tagsOneOf: [ tag ] })
 | 
						|
 | 
						|
  if (videos.length === 0) return undefined
 | 
						|
 | 
						|
  return {
 | 
						|
    tag,
 | 
						|
    videos
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
async function getVideosByCategory (category: number, res: express.Response) {
 | 
						|
  const videos = await getVideos(res, { categoryOneOf: [ category ] })
 | 
						|
 | 
						|
  if (videos.length === 0) return undefined
 | 
						|
 | 
						|
  return {
 | 
						|
    category: videos[0].category,
 | 
						|
    videos
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
async function getVideosByChannel (channelId: number, res: express.Response) {
 | 
						|
  const videos = await getVideos(res, { videoChannelId: channelId })
 | 
						|
 | 
						|
  if (videos.length === 0) return undefined
 | 
						|
 | 
						|
  return {
 | 
						|
    channel: videos[0].channel,
 | 
						|
    videos
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
async function getVideos (
 | 
						|
  res: express.Response,
 | 
						|
  where: { videoChannelId?: number, tagsOneOf?: string[], categoryOneOf?: number[] }
 | 
						|
) {
 | 
						|
  const query = Object.assign({
 | 
						|
    start: 0,
 | 
						|
    count: 12,
 | 
						|
    sort: '-createdAt',
 | 
						|
    includeLocalVideos: true,
 | 
						|
    nsfw: buildNSFWFilter(res),
 | 
						|
    withFiles: false
 | 
						|
  }, where)
 | 
						|
 | 
						|
  const { data } = await VideoModel.listForApi(query, false)
 | 
						|
 | 
						|
  return data.map(d => d.toFormattedJSON())
 | 
						|
}
 |