aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--server/models/video/video.ts50
-rw-r--r--server/tests/api/search/search-videos.ts10
2 files changed, 40 insertions, 20 deletions
diff --git a/server/models/video/video.ts b/server/models/video/video.ts
index 7e3512fe1..73e0d2345 100644
--- a/server/models/video/video.ts
+++ b/server/models/video/video.ts
@@ -59,8 +59,6 @@ import {
59 ACTIVITY_PUB, 59 ACTIVITY_PUB,
60 API_VERSION, 60 API_VERSION,
61 CONSTRAINTS_FIELDS, 61 CONSTRAINTS_FIELDS,
62 HLS_REDUNDANCY_DIRECTORY,
63 HLS_STREAMING_PLAYLIST_DIRECTORY,
64 LAZY_STATIC_PATHS, 62 LAZY_STATIC_PATHS,
65 REMOTE_SCHEME, 63 REMOTE_SCHEME,
66 STATIC_DOWNLOAD_PATHS, 64 STATIC_DOWNLOAD_PATHS,
@@ -143,7 +141,8 @@ import {
143import { MVideoFile, MVideoFileStreamingPlaylistVideo } from '../../typings/models/video/video-file' 141import { MVideoFile, MVideoFileStreamingPlaylistVideo } from '../../typings/models/video/video-file'
144import { MThumbnail } from '../../typings/models/video/thumbnail' 142import { MThumbnail } from '../../typings/models/video/thumbnail'
145import { VideoFile } from '@shared/models/videos/video-file.model' 143import { VideoFile } from '@shared/models/videos/video-file.model'
146import { getTorrentFileName, getTorrentFilePath, getVideoFilename, getVideoFilePath, getHLSDirectory } from '@server/lib/video-paths' 144import { getHLSDirectory, getTorrentFileName, getTorrentFilePath, getVideoFilename, getVideoFilePath } from '@server/lib/video-paths'
145import * as validator from 'validator'
147 146
148// FIXME: Define indexes here because there is an issue with TS and Sequelize.literal when called directly in the annotation 147// FIXME: Define indexes here because there is an issue with TS and Sequelize.literal when called directly in the annotation
149const indexes: (ModelIndexesOptions & { where?: WhereOptions })[] = [ 148const indexes: (ModelIndexesOptions & { where?: WhereOptions })[] = [
@@ -1352,24 +1351,35 @@ export class VideoModel extends Model<VideoModel> {
1352 const escapedSearch = VideoModel.sequelize.escape(options.search) 1351 const escapedSearch = VideoModel.sequelize.escape(options.search)
1353 const escapedLikeSearch = VideoModel.sequelize.escape('%' + options.search + '%') 1352 const escapedLikeSearch = VideoModel.sequelize.escape('%' + options.search + '%')
1354 if (options.search) { 1353 if (options.search) {
1355 whereAnd.push( 1354 const trigramSearch = {
1356 { 1355 id: {
1357 id: { 1356 [ Op.in ]: Sequelize.literal(
1358 [ Op.in ]: Sequelize.literal( 1357 '(' +
1359 '(' + 1358 'SELECT "video"."id" FROM "video" ' +
1360 'SELECT "video"."id" FROM "video" ' + 1359 'WHERE ' +
1361 'WHERE ' + 1360 'lower(immutable_unaccent("video"."name")) % lower(immutable_unaccent(' + escapedSearch + ')) OR ' +
1362 'lower(immutable_unaccent("video"."name")) % lower(immutable_unaccent(' + escapedSearch + ')) OR ' + 1361 'lower(immutable_unaccent("video"."name")) LIKE lower(immutable_unaccent(' + escapedLikeSearch + '))' +
1363 'lower(immutable_unaccent("video"."name")) LIKE lower(immutable_unaccent(' + escapedLikeSearch + '))' + 1362 'UNION ALL ' +
1364 'UNION ALL ' + 1363 'SELECT "video"."id" FROM "video" LEFT JOIN "videoTag" ON "videoTag"."videoId" = "video"."id" ' +
1365 'SELECT "video"."id" FROM "video" LEFT JOIN "videoTag" ON "videoTag"."videoId" = "video"."id" ' + 1364 'INNER JOIN "tag" ON "tag"."id" = "videoTag"."tagId" ' +
1366 'INNER JOIN "tag" ON "tag"."id" = "videoTag"."tagId" ' + 1365 'WHERE "tag"."name" = ' + escapedSearch +
1367 'WHERE "tag"."name" = ' + escapedSearch + 1366 ')'
1368 ')' 1367 )
1369 )
1370 }
1371 } 1368 }
1372 ) 1369 }
1370
1371 if (validator.isUUID(options.search)) {
1372 whereAnd.push({
1373 [Op.or]: [
1374 trigramSearch,
1375 {
1376 uuid: options.search
1377 }
1378 ]
1379 })
1380 } else {
1381 whereAnd.push(trigramSearch)
1382 }
1373 1383
1374 attributesInclude.push(createSimilarityAttribute('VideoModel.name', options.search)) 1384 attributesInclude.push(createSimilarityAttribute('VideoModel.name', options.search))
1375 } 1385 }
diff --git a/server/tests/api/search/search-videos.ts b/server/tests/api/search/search-videos.ts
index a3e05156b..7882d9373 100644
--- a/server/tests/api/search/search-videos.ts
+++ b/server/tests/api/search/search-videos.ts
@@ -20,6 +20,7 @@ const expect = chai.expect
20describe('Test videos search', function () { 20describe('Test videos search', function () {
21 let server: ServerInfo = null 21 let server: ServerInfo = null
22 let startDate: string 22 let startDate: string
23 let videoUUID: string
23 24
24 before(async function () { 25 before(async function () {
25 this.timeout(30000) 26 this.timeout(30000)
@@ -46,6 +47,7 @@ describe('Test videos search', function () {
46 const attributes3 = immutableAssign(attributes1, { name: attributes1.name + ' - 3', language: undefined }) 47 const attributes3 = immutableAssign(attributes1, { name: attributes1.name + ' - 3', language: undefined })
47 const res = await uploadVideo(server.url, server.accessToken, attributes3) 48 const res = await uploadVideo(server.url, server.accessToken, attributes3)
48 const videoId = res.body.video.id 49 const videoId = res.body.video.id
50 videoUUID = res.body.video.uuid
49 51
50 await createVideoCaption({ 52 await createVideoCaption({
51 url: server.url, 53 url: server.url,
@@ -439,6 +441,14 @@ describe('Test videos search', function () {
439 } 441 }
440 }) 442 })
441 443
444 it('Should search by UUID', async function () {
445 const search = videoUUID
446 const res = await advancedVideosSearch(server.url, { search })
447
448 expect(res.body.total).to.equal(1)
449 expect(res.body.data[0].name).to.equal('1111 2222 3333 - 3')
450 })
451
442 after(async function () { 452 after(async function () {
443 await cleanupTests([ server ]) 453 await cleanupTests([ server ])
444 }) 454 })