Add server hooks for search endpoint
This commit is contained in:
		
							parent
							
								
									eebd9838f0
								
							
						
					
					
						commit
						74a4d53110
					
				
					 4 changed files with 121 additions and 12 deletions
				
			
		| 
						 | 
				
			
			@ -3,6 +3,7 @@ import { sanitizeUrl } from '@server/helpers/core-utils'
 | 
			
		|||
import { doJSONRequest } from '@server/helpers/requests'
 | 
			
		||||
import { CONFIG } from '@server/initializers/config'
 | 
			
		||||
import { getOrCreateVideoAndAccountAndChannel } from '@server/lib/activitypub/videos'
 | 
			
		||||
import { Hooks } from '@server/lib/plugins/hooks'
 | 
			
		||||
import { AccountBlocklistModel } from '@server/models/account/account-blocklist'
 | 
			
		||||
import { getServerActor } from '@server/models/application/application'
 | 
			
		||||
import { ServerBlocklistModel } from '@server/models/server/server-blocklist'
 | 
			
		||||
| 
						 | 
				
			
			@ -22,8 +23,8 @@ import {
 | 
			
		|||
  paginationValidator,
 | 
			
		||||
  setDefaultPagination,
 | 
			
		||||
  setDefaultSearchSort,
 | 
			
		||||
  videoChannelsSearchSortValidator,
 | 
			
		||||
  videoChannelsListSearchValidator,
 | 
			
		||||
  videoChannelsSearchSortValidator,
 | 
			
		||||
  videosSearchSortValidator,
 | 
			
		||||
  videosSearchValidator
 | 
			
		||||
} from '../../middlewares'
 | 
			
		||||
| 
						 | 
				
			
			@ -87,7 +88,7 @@ function searchVideoChannels (req: express.Request, res: express.Response) {
 | 
			
		|||
async function searchVideoChannelsIndex (query: VideoChannelsSearchQuery, res: express.Response) {
 | 
			
		||||
  const result = await buildMutedForSearchIndex(res)
 | 
			
		||||
 | 
			
		||||
  const body = Object.assign(query, result)
 | 
			
		||||
  const body = await Hooks.wrapObject(Object.assign(query, result), 'filter:api.search.video-channels.index.list.params')
 | 
			
		||||
 | 
			
		||||
  const url = sanitizeUrl(CONFIG.SEARCH.SEARCH_INDEX.URL) + '/api/v1/search/video-channels'
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -95,8 +96,9 @@ async function searchVideoChannelsIndex (query: VideoChannelsSearchQuery, res: e
 | 
			
		|||
    logger.debug('Doing video channels search index request on %s.', url, { body })
 | 
			
		||||
 | 
			
		||||
    const { body: searchIndexResult } = await doJSONRequest<ResultList<VideoChannel>>(url, { method: 'POST', json: body })
 | 
			
		||||
    const jsonResult = await Hooks.wrapObject(searchIndexResult, 'filter:api.search.video-channels.index.list.result')
 | 
			
		||||
 | 
			
		||||
    return res.json(searchIndexResult)
 | 
			
		||||
    return res.json(jsonResult)
 | 
			
		||||
  } catch (err) {
 | 
			
		||||
    logger.warn('Cannot use search index to make video channels search.', { err })
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -107,14 +109,19 @@ async function searchVideoChannelsIndex (query: VideoChannelsSearchQuery, res: e
 | 
			
		|||
async function searchVideoChannelsDB (query: VideoChannelsSearchQuery, res: express.Response) {
 | 
			
		||||
  const serverActor = await getServerActor()
 | 
			
		||||
 | 
			
		||||
  const options = {
 | 
			
		||||
  const apiOptions = await Hooks.wrapObject({
 | 
			
		||||
    actorId: serverActor.id,
 | 
			
		||||
    search: query.search,
 | 
			
		||||
    start: query.start,
 | 
			
		||||
    count: query.count,
 | 
			
		||||
    sort: query.sort
 | 
			
		||||
  }
 | 
			
		||||
  const resultList = await VideoChannelModel.searchForApi(options)
 | 
			
		||||
  }, 'filter:api.search.video-channels.local.list.params')
 | 
			
		||||
 | 
			
		||||
  const resultList = await Hooks.wrapPromiseFun(
 | 
			
		||||
    VideoChannelModel.searchForApi,
 | 
			
		||||
    apiOptions,
 | 
			
		||||
    'filter:api.search.video-channels.local.list.result'
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
  return res.json(getFormattedObjects(resultList.data, resultList.total))
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -168,7 +175,7 @@ function searchVideos (req: express.Request, res: express.Response) {
 | 
			
		|||
async function searchVideosIndex (query: VideosSearchQuery, res: express.Response) {
 | 
			
		||||
  const result = await buildMutedForSearchIndex(res)
 | 
			
		||||
 | 
			
		||||
  const body: VideosSearchQuery = Object.assign(query, result)
 | 
			
		||||
  let body: VideosSearchQuery = Object.assign(query, result)
 | 
			
		||||
 | 
			
		||||
  // Use the default instance NSFW policy if not specified
 | 
			
		||||
  if (!body.nsfw) {
 | 
			
		||||
| 
						 | 
				
			
			@ -181,14 +188,17 @@ async function searchVideosIndex (query: VideosSearchQuery, res: express.Respons
 | 
			
		|||
      : 'both'
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  body = await Hooks.wrapObject(body, 'filter:api.search.videos.index.list.params')
 | 
			
		||||
 | 
			
		||||
  const url = sanitizeUrl(CONFIG.SEARCH.SEARCH_INDEX.URL) + '/api/v1/search/videos'
 | 
			
		||||
 | 
			
		||||
  try {
 | 
			
		||||
    logger.debug('Doing videos search index request on %s.', url, { body })
 | 
			
		||||
 | 
			
		||||
    const { body: searchIndexResult } = await doJSONRequest<ResultList<Video>>(url, { method: 'POST', json: body })
 | 
			
		||||
    const jsonResult = await Hooks.wrapObject(searchIndexResult, 'filter:api.search.videos.index.list.result')
 | 
			
		||||
 | 
			
		||||
    return res.json(searchIndexResult)
 | 
			
		||||
    return res.json(jsonResult)
 | 
			
		||||
  } catch (err) {
 | 
			
		||||
    logger.warn('Cannot use search index to make video search.', { err })
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -197,13 +207,18 @@ async function searchVideosIndex (query: VideosSearchQuery, res: express.Respons
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
async function searchVideosDB (query: VideosSearchQuery, res: express.Response) {
 | 
			
		||||
  const options = Object.assign(query, {
 | 
			
		||||
  const apiOptions = await Hooks.wrapObject(Object.assign(query, {
 | 
			
		||||
    includeLocalVideos: true,
 | 
			
		||||
    nsfw: buildNSFWFilter(res, query.nsfw),
 | 
			
		||||
    filter: query.filter,
 | 
			
		||||
    user: res.locals.oauth ? res.locals.oauth.token.User : undefined
 | 
			
		||||
  })
 | 
			
		||||
  const resultList = await VideoModel.searchAndPopulateAccountAndServer(options)
 | 
			
		||||
  }), 'filter:api.search.videos.local.list.params')
 | 
			
		||||
 | 
			
		||||
  const resultList = await Hooks.wrapPromiseFun(
 | 
			
		||||
    VideoModel.searchAndPopulateAccountAndServer,
 | 
			
		||||
    apiOptions,
 | 
			
		||||
    'filter:api.search.videos.local.list.result'
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
  return res.json(getFormattedObjects(resultList.data, resultList.total))
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -230,6 +230,30 @@ async function register ({ registerHook, registerSetting, settingsManager, stora
 | 
			
		|||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    const searchHooks = [
 | 
			
		||||
      'filter:api.search.videos.local.list.params',
 | 
			
		||||
      'filter:api.search.videos.local.list.result',
 | 
			
		||||
      'filter:api.search.videos.index.list.params',
 | 
			
		||||
      'filter:api.search.videos.index.list.result',
 | 
			
		||||
      'filter:api.search.video-channels.local.list.params',
 | 
			
		||||
      'filter:api.search.video-channels.local.list.result',
 | 
			
		||||
      'filter:api.search.video-channels.index.list.params',
 | 
			
		||||
      'filter:api.search.video-channels.index.list.result',
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    for (const h of searchHooks) {
 | 
			
		||||
      registerHook({
 | 
			
		||||
        target: h,
 | 
			
		||||
        handler: (obj) => {
 | 
			
		||||
          peertubeHelpers.logger.debug('Run hook %s.', h)
 | 
			
		||||
 | 
			
		||||
          return obj
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function unregister () {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@ import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-code
 | 
			
		|||
import {
 | 
			
		||||
  addVideoCommentReply,
 | 
			
		||||
  addVideoCommentThread,
 | 
			
		||||
  advancedVideosSearch,
 | 
			
		||||
  createLive,
 | 
			
		||||
  createVideoPlaylist,
 | 
			
		||||
  doubleFollow,
 | 
			
		||||
| 
						 | 
				
			
			@ -25,6 +26,7 @@ import {
 | 
			
		|||
  installPlugin,
 | 
			
		||||
  makeRawRequest,
 | 
			
		||||
  registerUser,
 | 
			
		||||
  searchVideo,
 | 
			
		||||
  setAccessTokensToServers,
 | 
			
		||||
  setDefaultVideoChannel,
 | 
			
		||||
  updateCustomSubConfig,
 | 
			
		||||
| 
						 | 
				
			
			@ -33,7 +35,7 @@ import {
 | 
			
		|||
  uploadVideoAndGetId,
 | 
			
		||||
  waitJobs
 | 
			
		||||
} from '../../../shared/extra-utils'
 | 
			
		||||
import { cleanupTests, flushAndRunMultipleServers, ServerInfo } from '../../../shared/extra-utils/server/servers'
 | 
			
		||||
import { cleanupTests, flushAndRunMultipleServers, ServerInfo, waitUntilLog } from '../../../shared/extra-utils/server/servers'
 | 
			
		||||
import { getGoodVideoUrl, getMyVideoImports, importVideo } from '../../../shared/extra-utils/videos/video-imports'
 | 
			
		||||
import {
 | 
			
		||||
  VideoDetails,
 | 
			
		||||
| 
						 | 
				
			
			@ -44,6 +46,7 @@ import {
 | 
			
		|||
  VideoPrivacy
 | 
			
		||||
} from '../../../shared/models/videos'
 | 
			
		||||
import { VideoCommentThreadTree } from '../../../shared/models/videos/video-comment.model'
 | 
			
		||||
import { advancedVideoChannelSearch } from '@shared/extra-utils/search/video-channels'
 | 
			
		||||
 | 
			
		||||
const expect = chai.expect
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -468,6 +471,63 @@ describe('Test plugin filter hooks', function () {
 | 
			
		|||
    })
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  describe('Search filters', function () {
 | 
			
		||||
 | 
			
		||||
    before(async function () {
 | 
			
		||||
      await updateCustomSubConfig(servers[0].url, servers[0].accessToken, {
 | 
			
		||||
        search: {
 | 
			
		||||
          searchIndex: {
 | 
			
		||||
            enabled: true,
 | 
			
		||||
            isDefaultSearch: false,
 | 
			
		||||
            disableLocalSearch: false
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    it('Should run filter:api.search.videos.local.list.{params,result}', async function () {
 | 
			
		||||
      await advancedVideosSearch(servers[0].url, {
 | 
			
		||||
        search: 'Sun Quan'
 | 
			
		||||
      })
 | 
			
		||||
 | 
			
		||||
      await waitUntilLog(servers[0], 'Run hook filter:api.search.videos.local.list.params', 1)
 | 
			
		||||
      await waitUntilLog(servers[0], 'Run hook filter:api.search.videos.local.list.result', 1)
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    it('Should run filter:api.search.videos.index.list.{params,result}', async function () {
 | 
			
		||||
      await advancedVideosSearch(servers[0].url, {
 | 
			
		||||
        search: 'Sun Quan',
 | 
			
		||||
        searchTarget: 'search-index'
 | 
			
		||||
      })
 | 
			
		||||
 | 
			
		||||
      await waitUntilLog(servers[0], 'Run hook filter:api.search.videos.local.list.params', 1)
 | 
			
		||||
      await waitUntilLog(servers[0], 'Run hook filter:api.search.videos.local.list.result', 1)
 | 
			
		||||
      await waitUntilLog(servers[0], 'Run hook filter:api.search.videos.index.list.params', 1)
 | 
			
		||||
      await waitUntilLog(servers[0], 'Run hook filter:api.search.videos.index.list.result', 1)
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    it('Should run filter:api.search.video-channels.local.list.{params,result}', async function () {
 | 
			
		||||
      await advancedVideoChannelSearch(servers[0].url, {
 | 
			
		||||
        search: 'Sun Ce'
 | 
			
		||||
      })
 | 
			
		||||
 | 
			
		||||
      await waitUntilLog(servers[0], 'Run hook filter:api.search.video-channels.local.list.params', 1)
 | 
			
		||||
      await waitUntilLog(servers[0], 'Run hook filter:api.search.video-channels.local.list.result', 1)
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    it('Should run filter:api.search.video-channels.index.list.{params,result}', async function () {
 | 
			
		||||
      await advancedVideoChannelSearch(servers[0].url, {
 | 
			
		||||
        search: 'Sun Ce',
 | 
			
		||||
        searchTarget: 'search-index'
 | 
			
		||||
      })
 | 
			
		||||
 | 
			
		||||
      await waitUntilLog(servers[0], 'Run hook filter:api.search.video-channels.local.list.params', 1)
 | 
			
		||||
      await waitUntilLog(servers[0], 'Run hook filter:api.search.video-channels.local.list.result', 1)
 | 
			
		||||
      await waitUntilLog(servers[0], 'Run hook filter:api.search.video-channels.index.list.params', 1)
 | 
			
		||||
      await waitUntilLog(servers[0], 'Run hook filter:api.search.video-channels.index.list.result', 1)
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  after(async function () {
 | 
			
		||||
    await cleanupTests(servers)
 | 
			
		||||
  })
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,6 +18,16 @@ export const serverFilterHookObject = {
 | 
			
		|||
  'filter:api.user.me.videos.list.params': true,
 | 
			
		||||
  'filter:api.user.me.videos.list.result': true,
 | 
			
		||||
 | 
			
		||||
  // Filter params/results to search videos/channels in the DB or on the remote index
 | 
			
		||||
  'filter:api.search.videos.local.list.params': true,
 | 
			
		||||
  'filter:api.search.videos.local.list.result': true,
 | 
			
		||||
  'filter:api.search.videos.index.list.params': true,
 | 
			
		||||
  'filter:api.search.videos.index.list.result': true,
 | 
			
		||||
  'filter:api.search.video-channels.local.list.params': true,
 | 
			
		||||
  'filter:api.search.video-channels.local.list.result': true,
 | 
			
		||||
  'filter:api.search.video-channels.index.list.params': true,
 | 
			
		||||
  'filter:api.search.video-channels.index.list.result': true,
 | 
			
		||||
 | 
			
		||||
  // Filter the result of the get function
 | 
			
		||||
  // Used to get detailed video information (video watch page for example)
 | 
			
		||||
  'filter:api.video.get.result': true,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue