2021-06-24 15:18:54 +02:00
|
|
|
import { elasticSearch } from '../../helpers/elastic-search'
|
|
|
|
import { logger } from '../../helpers/logger'
|
|
|
|
import { buildUrl } from '../../helpers/utils'
|
|
|
|
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'
|
2021-11-24 13:46:03 +01:00
|
|
|
import { addUUIDFilters, buildMultiMatchBool } from './shared'
|
2021-06-24 15:18:54 +02:00
|
|
|
import { buildChannelOrAccountSummaryMapping, formatActorForDB, formatActorSummaryForAPI } from './shared/elastic-search-actor'
|
|
|
|
|
|
|
|
async function queryPlaylists (search: PlaylistsSearchQuery) {
|
|
|
|
const bool: any = {}
|
|
|
|
const mustNot: any[] = []
|
2021-07-28 11:22:42 +02:00
|
|
|
const filter: any[] = []
|
2021-06-24 15:18:54 +02:00
|
|
|
|
|
|
|
if (search.search) {
|
2021-11-24 13:46:03 +01:00
|
|
|
Object.assign(bool, buildMultiMatchBool(search.search, ELASTIC_SEARCH_QUERY.PLAYLISTS_MULTI_MATCH_FIELDS))
|
2021-06-24 15:18:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (search.blockedAccounts) {
|
|
|
|
mustNot.push({
|
|
|
|
terms: {
|
|
|
|
'ownerAccount.handle': search.blockedAccounts
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
if (search.blockedHosts) {
|
|
|
|
mustNot.push({
|
|
|
|
terms: {
|
|
|
|
host: search.blockedHosts
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-07-28 11:22:42 +02:00
|
|
|
if (search.host) {
|
|
|
|
filter.push({
|
|
|
|
term: {
|
|
|
|
'ownerAccount.host': search.host
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-07-29 10:57:33 +02:00
|
|
|
if (search.uuids) {
|
|
|
|
addUUIDFilters(filter, search.uuids)
|
|
|
|
}
|
|
|
|
|
2021-07-28 11:22:42 +02:00
|
|
|
if (filter.length !== 0) {
|
|
|
|
Object.assign(bool, { filter })
|
|
|
|
}
|
|
|
|
|
2021-06-24 15:18:54 +02:00
|
|
|
if (mustNot.length !== 0) {
|
|
|
|
Object.assign(bool, { must_not: mustNot })
|
|
|
|
}
|
|
|
|
|
|
|
|
const body = {
|
|
|
|
from: search.start,
|
|
|
|
size: search.count,
|
|
|
|
sort: buildSort(search.sort),
|
|
|
|
query: { bool }
|
|
|
|
}
|
|
|
|
|
|
|
|
logger.debug({ body }, 'Will query Elastic Search for playlists.')
|
|
|
|
|
|
|
|
const res = await elasticSearch.search({
|
|
|
|
index: CONFIG.ELASTIC_SEARCH.INDEXES.PLAYLISTS,
|
|
|
|
body
|
|
|
|
})
|
|
|
|
|
|
|
|
return extractQueryResult(res)
|
|
|
|
}
|
|
|
|
|
|
|
|
function formatPlaylistForAPI (p: DBPlaylist, fromHost?: string): EnhancedPlaylist {
|
|
|
|
return {
|
|
|
|
id: p.id,
|
|
|
|
uuid: p.uuid,
|
2021-07-28 11:22:42 +02:00
|
|
|
shortUUID: p.shortUUID,
|
2021-06-24 15:18:54 +02:00
|
|
|
|
|
|
|
score: p.score,
|
|
|
|
|
|
|
|
isLocal: fromHost === p.host,
|
|
|
|
|
|
|
|
url: p.url,
|
|
|
|
|
|
|
|
displayName: p.displayName,
|
|
|
|
description: p.description,
|
|
|
|
|
|
|
|
privacy: {
|
|
|
|
id: p.privacy.id,
|
|
|
|
label: p.privacy.label
|
|
|
|
},
|
|
|
|
|
|
|
|
videosLength: p.videosLength,
|
|
|
|
|
|
|
|
type: {
|
|
|
|
id: p.type.id,
|
|
|
|
label: p.type.label
|
|
|
|
},
|
|
|
|
|
|
|
|
thumbnailPath: p.thumbnailPath,
|
|
|
|
thumbnailUrl: buildUrl(p.host, p.thumbnailPath),
|
|
|
|
|
|
|
|
embedPath: p.embedPath,
|
|
|
|
embedUrl: buildUrl(p.host, p.embedPath),
|
|
|
|
|
|
|
|
createdAt: p.createdAt,
|
|
|
|
updatedAt: p.updatedAt,
|
|
|
|
|
|
|
|
ownerAccount: formatActorSummaryForAPI(p.ownerAccount),
|
|
|
|
videoChannel: formatActorSummaryForAPI(p.videoChannel)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function formatPlaylistForDB (p: IndexablePlaylist): DBPlaylist {
|
|
|
|
return {
|
|
|
|
id: p.id,
|
|
|
|
uuid: p.uuid,
|
2021-07-28 11:22:42 +02:00
|
|
|
shortUUID: p.shortUUID,
|
2021-06-24 15:18:54 +02:00
|
|
|
|
|
|
|
indexedAt: new Date(),
|
|
|
|
createdAt: p.createdAt,
|
|
|
|
updatedAt: p.updatedAt,
|
|
|
|
|
|
|
|
host: p.host,
|
|
|
|
url: p.url,
|
|
|
|
|
|
|
|
displayName: p.displayName,
|
|
|
|
description: p.description,
|
|
|
|
|
|
|
|
thumbnailPath: p.thumbnailPath,
|
|
|
|
embedPath: p.embedPath,
|
|
|
|
|
|
|
|
type: {
|
|
|
|
id: p.type.id,
|
|
|
|
label: p.type.label
|
|
|
|
},
|
|
|
|
privacy: {
|
|
|
|
id: p.privacy.id,
|
|
|
|
label: p.privacy.label
|
|
|
|
},
|
|
|
|
|
|
|
|
videosLength: p.videosLength,
|
|
|
|
|
|
|
|
ownerAccount: formatActorForDB(p.ownerAccount),
|
|
|
|
videoChannel: formatActorForDB(p.videoChannel)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function buildPlaylistsMapping () {
|
|
|
|
return {
|
|
|
|
id: {
|
|
|
|
type: 'long'
|
|
|
|
},
|
|
|
|
|
|
|
|
uuid: {
|
|
|
|
type: 'keyword'
|
|
|
|
},
|
2021-07-28 11:22:42 +02:00
|
|
|
shortUUID: {
|
|
|
|
type: 'keyword'
|
|
|
|
},
|
2021-06-24 15:18:54 +02:00
|
|
|
createdAt: {
|
|
|
|
type: 'date',
|
|
|
|
format: 'date_optional_time'
|
|
|
|
},
|
|
|
|
updatedAt: {
|
|
|
|
type: 'date',
|
|
|
|
format: 'date_optional_time'
|
|
|
|
},
|
|
|
|
indexedAt: {
|
|
|
|
type: 'date',
|
|
|
|
format: 'date_optional_time'
|
|
|
|
},
|
|
|
|
|
|
|
|
privacy: {
|
|
|
|
properties: {
|
|
|
|
id: {
|
|
|
|
type: 'keyword'
|
|
|
|
},
|
|
|
|
label: {
|
|
|
|
type: 'text'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
displayName: {
|
|
|
|
type: 'text'
|
|
|
|
},
|
|
|
|
|
|
|
|
description: {
|
|
|
|
type: 'text'
|
|
|
|
},
|
|
|
|
|
|
|
|
thumbnailPath: {
|
|
|
|
type: 'keyword'
|
|
|
|
},
|
|
|
|
embedPath: {
|
|
|
|
type: 'keyword'
|
|
|
|
},
|
|
|
|
|
|
|
|
url: {
|
|
|
|
type: 'keyword'
|
|
|
|
},
|
|
|
|
|
|
|
|
host: {
|
|
|
|
type: 'keyword'
|
|
|
|
},
|
|
|
|
|
|
|
|
videosLength: {
|
|
|
|
type: 'long'
|
|
|
|
},
|
|
|
|
|
|
|
|
ownerAccount: {
|
|
|
|
properties: buildChannelOrAccountSummaryMapping()
|
|
|
|
},
|
|
|
|
|
|
|
|
videoChannel: {
|
|
|
|
properties: buildChannelOrAccountSummaryMapping()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export {
|
|
|
|
formatPlaylistForAPI,
|
|
|
|
buildPlaylistsMapping,
|
|
|
|
formatPlaylistForDB,
|
|
|
|
queryPlaylists
|
|
|
|
}
|