Add ability to search by UUID

pull/2324/head
Chocobozzz 2019-12-09 15:32:53 +01:00
parent 1aa7543403
commit 3cf53828db
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
2 changed files with 40 additions and 20 deletions

View File

@ -59,8 +59,6 @@ import {
ACTIVITY_PUB,
API_VERSION,
CONSTRAINTS_FIELDS,
HLS_REDUNDANCY_DIRECTORY,
HLS_STREAMING_PLAYLIST_DIRECTORY,
LAZY_STATIC_PATHS,
REMOTE_SCHEME,
STATIC_DOWNLOAD_PATHS,
@ -143,7 +141,8 @@ import {
import { MVideoFile, MVideoFileStreamingPlaylistVideo } from '../../typings/models/video/video-file'
import { MThumbnail } from '../../typings/models/video/thumbnail'
import { VideoFile } from '@shared/models/videos/video-file.model'
import { getTorrentFileName, getTorrentFilePath, getVideoFilename, getVideoFilePath, getHLSDirectory } from '@server/lib/video-paths'
import { getHLSDirectory, getTorrentFileName, getTorrentFilePath, getVideoFilename, getVideoFilePath } from '@server/lib/video-paths'
import * as validator from 'validator'
// FIXME: Define indexes here because there is an issue with TS and Sequelize.literal when called directly in the annotation
const indexes: (ModelIndexesOptions & { where?: WhereOptions })[] = [
@ -1352,24 +1351,35 @@ export class VideoModel extends Model<VideoModel> {
const escapedSearch = VideoModel.sequelize.escape(options.search)
const escapedLikeSearch = VideoModel.sequelize.escape('%' + options.search + '%')
if (options.search) {
whereAnd.push(
{
id: {
[ Op.in ]: Sequelize.literal(
'(' +
'SELECT "video"."id" FROM "video" ' +
'WHERE ' +
'lower(immutable_unaccent("video"."name")) % lower(immutable_unaccent(' + escapedSearch + ')) OR ' +
'lower(immutable_unaccent("video"."name")) LIKE lower(immutable_unaccent(' + escapedLikeSearch + '))' +
'UNION ALL ' +
'SELECT "video"."id" FROM "video" LEFT JOIN "videoTag" ON "videoTag"."videoId" = "video"."id" ' +
'INNER JOIN "tag" ON "tag"."id" = "videoTag"."tagId" ' +
'WHERE "tag"."name" = ' + escapedSearch +
')'
)
}
const trigramSearch = {
id: {
[ Op.in ]: Sequelize.literal(
'(' +
'SELECT "video"."id" FROM "video" ' +
'WHERE ' +
'lower(immutable_unaccent("video"."name")) % lower(immutable_unaccent(' + escapedSearch + ')) OR ' +
'lower(immutable_unaccent("video"."name")) LIKE lower(immutable_unaccent(' + escapedLikeSearch + '))' +
'UNION ALL ' +
'SELECT "video"."id" FROM "video" LEFT JOIN "videoTag" ON "videoTag"."videoId" = "video"."id" ' +
'INNER JOIN "tag" ON "tag"."id" = "videoTag"."tagId" ' +
'WHERE "tag"."name" = ' + escapedSearch +
')'
)
}
)
}
if (validator.isUUID(options.search)) {
whereAnd.push({
[Op.or]: [
trigramSearch,
{
uuid: options.search
}
]
})
} else {
whereAnd.push(trigramSearch)
}
attributesInclude.push(createSimilarityAttribute('VideoModel.name', options.search))
}

View File

@ -20,6 +20,7 @@ const expect = chai.expect
describe('Test videos search', function () {
let server: ServerInfo = null
let startDate: string
let videoUUID: string
before(async function () {
this.timeout(30000)
@ -46,6 +47,7 @@ describe('Test videos search', function () {
const attributes3 = immutableAssign(attributes1, { name: attributes1.name + ' - 3', language: undefined })
const res = await uploadVideo(server.url, server.accessToken, attributes3)
const videoId = res.body.video.id
videoUUID = res.body.video.uuid
await createVideoCaption({
url: server.url,
@ -439,6 +441,14 @@ describe('Test videos search', function () {
}
})
it('Should search by UUID', async function () {
const search = videoUUID
const res = await advancedVideosSearch(server.url, { search })
expect(res.body.total).to.equal(1)
expect(res.body.data[0].name).to.equal('1111 2222 3333 - 3')
})
after(async function () {
await cleanupTests([ server ])
})