Fix tests
[oweals/peertube.git] / server / controllers / api / search.ts
1 import * as express from 'express'
2 import { buildNSFWFilter } from '../../helpers/express-utils'
3 import { getFormattedObjects } from '../../helpers/utils'
4 import { VideoModel } from '../../models/video/video'
5 import {
6   asyncMiddleware,
7   commonVideosFiltersValidator,
8   optionalAuthenticate,
9   paginationValidator,
10   searchValidator,
11   setDefaultPagination,
12   setDefaultSearchSort,
13   videosSearchSortValidator
14 } from '../../middlewares'
15 import { VideosSearchQuery } from '../../../shared/models/search'
16 import { getOrCreateVideoAndAccountAndChannel } from '../../lib/activitypub'
17 import { logger } from '../../helpers/logger'
18 import { User } from '../../../shared/models/users'
19 import { CONFIG } from '../../initializers/constants'
20
21 const searchRouter = express.Router()
22
23 searchRouter.get('/videos',
24   paginationValidator,
25   setDefaultPagination,
26   videosSearchSortValidator,
27   setDefaultSearchSort,
28   optionalAuthenticate,
29   commonVideosFiltersValidator,
30   searchValidator,
31   asyncMiddleware(searchVideos)
32 )
33
34 // ---------------------------------------------------------------------------
35
36 export { searchRouter }
37
38 // ---------------------------------------------------------------------------
39
40 function searchVideos (req: express.Request, res: express.Response) {
41   const query: VideosSearchQuery = req.query
42   const search = query.search
43   if (search && (search.startsWith('http://') || search.startsWith('https://'))) {
44     return searchVideoUrl(search, res)
45   }
46
47   return searchVideosDB(query, res)
48 }
49
50 async function searchVideosDB (query: VideosSearchQuery, res: express.Response) {
51   const options = Object.assign(query, {
52     includeLocalVideos: true,
53     nsfw: buildNSFWFilter(res, query.nsfw)
54   })
55   const resultList = await VideoModel.searchAndPopulateAccountAndServer(options)
56
57   return res.json(getFormattedObjects(resultList.data, resultList.total))
58 }
59
60 async function searchVideoUrl (url: string, res: express.Response) {
61   let video: VideoModel
62   const user: User = res.locals.oauth ? res.locals.oauth.token.User : undefined
63
64   // Check if we can fetch a remote video with the URL
65   if (
66     CONFIG.SEARCH.REMOTE_URI.ANONYMOUS === true ||
67     (CONFIG.SEARCH.REMOTE_URI.USERS === true && user !== undefined)
68   ) {
69     try {
70       const syncParam = {
71         likes: false,
72         dislikes: false,
73         shares: false,
74         comments: false,
75         thumbnail: true,
76         refreshVideo: false
77       }
78
79       const res = await getOrCreateVideoAndAccountAndChannel(url, syncParam)
80       video = res ? res.video : undefined
81     } catch (err) {
82       logger.info('Cannot search remote video %s.', url)
83     }
84   } else {
85     video = await VideoModel.loadByUrlAndPopulateAccount(url)
86   }
87
88   return res.json({
89     total: video ? 1 : 0,
90     data: video ? [ video.toFormattedJSON() ] : []
91   })
92 }