From ac0eb5f3acfe12992bdb6cecdbfbc94df8e85c7e Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 29 Jul 2021 10:57:33 +0200 Subject: [PATCH] Support handles and uuids filters --- PeerTube | 2 +- server/controllers/api/search-channels.ts | 8 +++++ server/controllers/api/search-videos.ts | 1 - .../elastic-search/elastic-search-channels.ts | 8 +++++ .../elastic-search-playlists.ts | 5 +++ .../elastic-search/elastic-search-videos.ts | 7 +++- server/lib/elastic-search/shared/index.ts | 1 + .../elastic-search/shared/query-helpers.ts | 36 +++++++++++++++++++ server/middlewares/validators/search.ts | 16 +++++++-- 9 files changed, 78 insertions(+), 6 deletions(-) create mode 100644 server/lib/elastic-search/shared/query-helpers.ts diff --git a/PeerTube b/PeerTube index 28be9d1..b033851 160000 --- a/PeerTube +++ b/PeerTube @@ -1 +1 @@ -Subproject commit 28be9d1d3ee92db7c9fd84c82e4ea20900eab0f5 +Subproject commit b033851fb54241bb703f86add025229e68cc6f59 diff --git a/server/controllers/api/search-channels.ts b/server/controllers/api/search-channels.ts index 348cdb5..8f2e286 100644 --- a/server/controllers/api/search-channels.ts +++ b/server/controllers/api/search-channels.ts @@ -32,6 +32,14 @@ export { searchChannelsRouter } async function searchChannels (req: express.Request, res: express.Response) { const query = Object.assign(req.query || {}, req.body || {}) as ChannelsSearchQuery + if (query.handles && query.fromHost) { + query.handles = query.handles.map(h => { + if (h.includes('@')) return h + + return h + '@' + query.fromHost + }) + } + const searcher = new Searcher(queryChannels, formatChannelForAPI) const result = await searcher.getResult(query) diff --git a/server/controllers/api/search-videos.ts b/server/controllers/api/search-videos.ts index 2d0f66e..1b72279 100644 --- a/server/controllers/api/search-videos.ts +++ b/server/controllers/api/search-videos.ts @@ -32,7 +32,6 @@ export { searchVideosRouter } async function searchVideos (req: express.Request, res: express.Response) { const query = Object.assign(req.query || {}, req.body || {}) as VideosSearchQuery - const searcher = new Searcher(queryVideos, formatVideoForAPI) const result = await searcher.getResult(query) diff --git a/server/lib/elastic-search/elastic-search-channels.ts b/server/lib/elastic-search/elastic-search-channels.ts index 6dd09a0..3876329 100644 --- a/server/lib/elastic-search/elastic-search-channels.ts +++ b/server/lib/elastic-search/elastic-search-channels.ts @@ -51,6 +51,14 @@ async function queryChannels (search: ChannelsSearchQuery) { }) } + if (search.handles) { + filter.push({ + terms: { + handle: search.handles + } + }) + } + if (filter.length !== 0) { Object.assign(bool, { filter }) } diff --git a/server/lib/elastic-search/elastic-search-playlists.ts b/server/lib/elastic-search/elastic-search-playlists.ts index 3bba00c..d4ac42d 100644 --- a/server/lib/elastic-search/elastic-search-playlists.ts +++ b/server/lib/elastic-search/elastic-search-playlists.ts @@ -5,6 +5,7 @@ import { CONFIG, ELASTIC_SEARCH_QUERY } from '../../initializers/constants' import { DBPlaylist, EnhancedPlaylist, IndexablePlaylist } from '../../types/playlist.model' import { PlaylistsSearchQuery } from '../../types/search-query/playlist-search.model' import { buildSort, extractQueryResult } from './elastic-search-queries' +import { addUUIDFilters } from './shared' import { buildChannelOrAccountSummaryMapping, formatActorForDB, formatActorSummaryForAPI } from './shared/elastic-search-actor' async function queryPlaylists (search: PlaylistsSearchQuery) { @@ -50,6 +51,10 @@ async function queryPlaylists (search: PlaylistsSearchQuery) { }) } + if (search.uuids) { + addUUIDFilters(filter, search.uuids) + } + if (filter.length !== 0) { Object.assign(bool, { filter }) } diff --git a/server/lib/elastic-search/elastic-search-videos.ts b/server/lib/elastic-search/elastic-search-videos.ts index 920ea48..e08c958 100644 --- a/server/lib/elastic-search/elastic-search-videos.ts +++ b/server/lib/elastic-search/elastic-search-videos.ts @@ -7,6 +7,7 @@ import { CONFIG, ELASTIC_SEARCH_QUERY } from '../../initializers/constants' import { VideosSearchQuery } from '../../types/search-query/video-search.model' import { DBVideo, DBVideoDetails, EnhancedVideo, IndexableVideo, IndexableVideoDetails } from '../../types/video.model' import { buildSort, extractQueryResult } from './elastic-search-queries' +import { addUUIDFilters } from './shared' import { buildChannelOrAccountSummaryMapping, formatActorForDB, formatActorSummaryForAPI } from './shared/elastic-search-actor' async function queryVideos (search: VideosSearchQuery) { @@ -162,7 +163,7 @@ async function queryVideos (search: VideosSearchQuery) { }) } - if (exists(search.host)) { + if (search.host) { filter.push({ term: { 'account.host': search.host @@ -170,6 +171,10 @@ async function queryVideos (search: VideosSearchQuery) { }) } + if (search.uuids) { + addUUIDFilters(filter, search.uuids) + } + Object.assign(bool, { filter }) if (mustNot.length !== 0) { diff --git a/server/lib/elastic-search/shared/index.ts b/server/lib/elastic-search/shared/index.ts index 9b069bc..11842d2 100644 --- a/server/lib/elastic-search/shared/index.ts +++ b/server/lib/elastic-search/shared/index.ts @@ -1,2 +1,3 @@ export * from './elastic-search-actor' export * from './elastic-search-avatar' +export * from './query-helpers' diff --git a/server/lib/elastic-search/shared/query-helpers.ts b/server/lib/elastic-search/shared/query-helpers.ts new file mode 100644 index 0000000..ac06b17 --- /dev/null +++ b/server/lib/elastic-search/shared/query-helpers.ts @@ -0,0 +1,36 @@ +import validator from 'validator' + +function addUUIDFilters (filters: any[], uuids: string[]) { + if (!filters) return + + const result = { + shortUUIDs: [] as string[], + uuids: [] as string[] + } + + for (const uuid of uuids) { + if (validator.isUUID(uuid)) result.uuids.push(uuid) + else result.shortUUIDs.push(uuid) + } + + filters.push({ + bool: { + should: [ + { + terms: { + uuid: result.uuids + } + }, + { + terms: { + shortUUID: result.shortUUIDs + } + } + ] + } + }) +} + +export { + addUUIDFilters +} diff --git a/server/middlewares/validators/search.ts b/server/middlewares/validators/search.ts index abc11be..0e12508 100644 --- a/server/middlewares/validators/search.ts +++ b/server/middlewares/validators/search.ts @@ -1,5 +1,5 @@ -import { check } from 'express-validator' import * as express from 'express' +import { check } from 'express-validator' import { isDateValid, toArray } from '../../helpers/custom-validators/misc' import { isNSFWQueryValid, isNumberArray, isStringArray } from '../../helpers/custom-validators/search-videos' import { logger } from '../../helpers/logger' @@ -78,6 +78,10 @@ const videosSearchValidator = [ .customSanitizer(toArray) .custom(isStringArray).withMessage('Should have a valid boostLanguages array'), + check('uuids') + .optional() + .toArray(), + (req: express.Request, res: express.Response, next: express.NextFunction) => { logger.debug({ query: req.query, body: req.body }, 'Checking videos search query') @@ -88,8 +92,9 @@ const videosSearchValidator = [ ] const videoChannelsSearchValidator = [ - check('search').not().isEmpty().withMessage('Should have a valid search'), + check('search').optional().not().isEmpty().withMessage('Should have a valid search'), check('host').optional().not().isEmpty().withMessage('Should have a valid host'), + check('handles').optional().toArray(), (req: express.Request, res: express.Response, next: express.NextFunction) => { logger.debug({ query: req.query, body: req.body }, 'Checking video channels search query') @@ -101,9 +106,14 @@ const videoChannelsSearchValidator = [ ] const videoPlaylistsSearchValidator = [ - check('search').not().isEmpty().withMessage('Should have a valid search'), + check('search').optional().not().isEmpty().withMessage('Should have a valid search'), + check('host').optional().not().isEmpty().withMessage('Should have a valid host'), + check('uuids') + .optional() + .toArray(), + (req: express.Request, res: express.Response, next: express.NextFunction) => { logger.debug({ query: req.query, body: req.body }, 'Checking video playlists search query')