Add ability to filter by host
This commit is contained in:
parent
4543d255b6
commit
e5a2e7a442
2
PeerTube
2
PeerTube
|
@ -1 +1 @@
|
|||
Subproject commit cffa06fd28bbfb03980bc7d151cfd93130c3daaf
|
||||
Subproject commit 28be9d1d3ee92db7c9fd84c82e4ea20900eab0f5
|
|
@ -1,6 +1,7 @@
|
|||
export interface SearchUrl {
|
||||
search?: string
|
||||
nsfw?: string
|
||||
host?: string
|
||||
publishedDateRange?: string
|
||||
durationRange?: string
|
||||
categoryOneOf?: number[]
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
@import "_variables";
|
||||
@import "./progress";
|
||||
|
||||
$border-input-color: #C6C6C6;
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
@ -94,7 +96,7 @@ body {
|
|||
select {
|
||||
padding: 0 35px 0 12px;
|
||||
position: relative;
|
||||
border: 1px solid #C6C6C6;
|
||||
border: 1px solid $border-input-color;
|
||||
background: transparent none;
|
||||
appearance: none;
|
||||
cursor: pointer;
|
||||
|
@ -117,6 +119,15 @@ body {
|
|||
}
|
||||
}
|
||||
|
||||
.classic-input-text {
|
||||
display: block;
|
||||
min-height: 30px;
|
||||
width: 100%;
|
||||
border: 1px solid $border-input-color;
|
||||
padding: 0 35px 0 12px;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.results {
|
||||
.root-result {
|
||||
display: flex;
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import axios from 'axios'
|
||||
import { VideoPlaylistsSearchQuery } from '../../../PeerTube/shared/models'
|
||||
import { ResultList } from '../../../PeerTube/shared/models/result-list.model'
|
||||
import { ResultList, VideoPlaylistsSearchQuery } from '../../../PeerTube/shared/models'
|
||||
import { VideoChannelsSearchQuery } from '../../../PeerTube/shared/models/search/video-channels-search-query.model'
|
||||
import { VideosSearchQuery } from '../../../PeerTube/shared/models/search/videos-search-query.model'
|
||||
import { EnhancedVideoChannel } from '../../../server/types/channel.model'
|
||||
import { EnhancedVideo } from '../../../server/types/video.model'
|
||||
import { EnhancedPlaylist } from '../../../server/types/playlist.model'
|
||||
import { EnhancedVideo } from '../../../server/types/video.model'
|
||||
import { buildApiUrl } from './utils'
|
||||
|
||||
const baseVideosPath = '/api/v1/search/videos'
|
||||
|
|
|
@ -160,6 +160,12 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label v-translate for="host">Host</label>
|
||||
|
||||
<input type="text" id="host" name="host" v-model="formHost" class="classic-input-text" />
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label v-translate for="tagsAllOf">All of these tags</label>
|
||||
<button v-translate class="reset-button" v-on:click="resetField('tagsAllOf')" v-if="formTagsAllOf.length !== 0">
|
||||
|
@ -500,6 +506,7 @@
|
|||
formSort: '-match',
|
||||
|
||||
formNSFW: undefined,
|
||||
formHost: '',
|
||||
formPublishedDateRange: undefined,
|
||||
formDurationRange: undefined,
|
||||
formCategoryOneOf: undefined,
|
||||
|
@ -785,6 +792,7 @@
|
|||
search: this.formSearch,
|
||||
sort: this.formSort,
|
||||
nsfw: this.formNSFW,
|
||||
host: this.formHost,
|
||||
isLive: this.formIsLive,
|
||||
publishedDateRange: this.formPublishedDateRange,
|
||||
durationRange: this.formDurationRange,
|
||||
|
@ -835,6 +843,9 @@
|
|||
if (query.isLive) this.formIsLive = query.isLive
|
||||
else this.formIsLive = undefined
|
||||
|
||||
if (query.host) this.formHost = query.host
|
||||
else this.formHost = ''
|
||||
|
||||
if (query.page && this.currentPage !== query.page) {
|
||||
this.currentPage = parseInt(query.page + '')
|
||||
} else {
|
||||
|
@ -871,6 +882,8 @@
|
|||
|
||||
isLive: this.formIsLive !== undefined ? this.formIsLive : undefined,
|
||||
|
||||
host: this.formHost || undefined,
|
||||
|
||||
start,
|
||||
count,
|
||||
sort: this.formSort
|
||||
|
@ -887,6 +900,7 @@
|
|||
|
||||
return {
|
||||
search: this.formSearch,
|
||||
host: this.formHost || undefined,
|
||||
start,
|
||||
sort,
|
||||
count
|
||||
|
@ -903,6 +917,7 @@
|
|||
|
||||
return {
|
||||
search: this.formSearch,
|
||||
host: this.formHost || undefined,
|
||||
start,
|
||||
sort,
|
||||
count
|
||||
|
@ -1011,6 +1026,7 @@
|
|||
else if (field === 'isLive') this.formIsLive = undefined
|
||||
else if (field === 'tagsAllOf') this.formTagsAllOf = []
|
||||
else if (field === 'tagsOneOf') this.formTagsOneOf = []
|
||||
else if (field === 'host') this.formHost = ''
|
||||
},
|
||||
|
||||
simpleFormReset (searchDone = true) {
|
||||
|
@ -1022,6 +1038,7 @@
|
|||
let count = 0
|
||||
|
||||
if (this.formNSFW) count++
|
||||
if (this.formHost) count++
|
||||
if (this.formPublishedDateRange) count++
|
||||
if (this.formDurationRange) count++
|
||||
if (this.formCategoryOneOf) count++
|
||||
|
@ -1035,6 +1052,9 @@
|
|||
},
|
||||
|
||||
isChannelOrPlaylistSearchDisabled () {
|
||||
// We can search against host for playlists and channels
|
||||
if (this.formHost) return this.countActiveFilters() > 1
|
||||
|
||||
return this.countActiveFilters() > 0
|
||||
},
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as express from 'express'
|
||||
import { ResultList } from '../../PeerTube/shared/models/result-list.model'
|
||||
import { ResultList } from '../../PeerTube/shared/models/common/result-list.model'
|
||||
|
||||
function badRequest (req: express.Request, res: express.Response) {
|
||||
return res.type('json').status(400).end()
|
||||
|
|
|
@ -11,6 +11,7 @@ import { formatAvatarForAPI, formatAvatarForDB } from './shared/elastic-search-a
|
|||
async function queryChannels (search: ChannelsSearchQuery) {
|
||||
const bool: any = {}
|
||||
const mustNot: any[] = []
|
||||
const filter: any[] = []
|
||||
|
||||
if (search.search) {
|
||||
Object.assign(bool, {
|
||||
|
@ -42,6 +43,18 @@ async function queryChannels (search: ChannelsSearchQuery) {
|
|||
})
|
||||
}
|
||||
|
||||
if (search.host) {
|
||||
filter.push({
|
||||
term: {
|
||||
host: search.host
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (filter.length !== 0) {
|
||||
Object.assign(bool, { filter })
|
||||
}
|
||||
|
||||
if (mustNot.length !== 0) {
|
||||
Object.assign(bool, { must_not: mustNot })
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import { buildChannelOrAccountSummaryMapping, formatActorForDB, formatActorSumma
|
|||
async function queryPlaylists (search: PlaylistsSearchQuery) {
|
||||
const bool: any = {}
|
||||
const mustNot: any[] = []
|
||||
const filter: any[] = []
|
||||
|
||||
if (search.search) {
|
||||
Object.assign(bool, {
|
||||
|
@ -41,6 +42,18 @@ async function queryPlaylists (search: PlaylistsSearchQuery) {
|
|||
})
|
||||
}
|
||||
|
||||
if (search.host) {
|
||||
filter.push({
|
||||
term: {
|
||||
'ownerAccount.host': search.host
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (filter.length !== 0) {
|
||||
Object.assign(bool, { filter })
|
||||
}
|
||||
|
||||
if (mustNot.length !== 0) {
|
||||
Object.assign(bool, { must_not: mustNot })
|
||||
}
|
||||
|
@ -66,6 +79,7 @@ function formatPlaylistForAPI (p: DBPlaylist, fromHost?: string): EnhancedPlayli
|
|||
return {
|
||||
id: p.id,
|
||||
uuid: p.uuid,
|
||||
shortUUID: p.shortUUID,
|
||||
|
||||
score: p.score,
|
||||
|
||||
|
@ -106,6 +120,7 @@ function formatPlaylistForDB (p: IndexablePlaylist): DBPlaylist {
|
|||
return {
|
||||
id: p.id,
|
||||
uuid: p.uuid,
|
||||
shortUUID: p.shortUUID,
|
||||
|
||||
indexedAt: new Date(),
|
||||
createdAt: p.createdAt,
|
||||
|
@ -145,6 +160,9 @@ function buildPlaylistsMapping () {
|
|||
uuid: {
|
||||
type: 'keyword'
|
||||
},
|
||||
shortUUID: {
|
||||
type: 'keyword'
|
||||
},
|
||||
createdAt: {
|
||||
type: 'date',
|
||||
format: 'date_optional_time'
|
||||
|
|
|
@ -162,6 +162,14 @@ async function queryVideos (search: VideosSearchQuery) {
|
|||
})
|
||||
}
|
||||
|
||||
if (exists(search.host)) {
|
||||
filter.push({
|
||||
term: {
|
||||
'account.host': search.host
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Object.assign(bool, { filter })
|
||||
|
||||
if (mustNot.length !== 0) {
|
||||
|
@ -231,6 +239,9 @@ function buildVideosMapping () {
|
|||
uuid: {
|
||||
type: 'keyword'
|
||||
},
|
||||
shortUUID: {
|
||||
type: 'keyword'
|
||||
},
|
||||
createdAt: {
|
||||
type: 'date',
|
||||
format: 'date_optional_time'
|
||||
|
@ -366,6 +377,7 @@ function formatVideoForDB (v: IndexableVideo | IndexableVideoDetails): DBVideo |
|
|||
return {
|
||||
id: v.id,
|
||||
uuid: v.uuid,
|
||||
shortUUID: v.shortUUID,
|
||||
|
||||
indexedAt: new Date(),
|
||||
createdAt: v.createdAt,
|
||||
|
@ -418,6 +430,7 @@ function formatVideoForAPI (v: DBVideoDetails, fromHost?: string): EnhancedVideo
|
|||
return {
|
||||
id: v.id,
|
||||
uuid: v.uuid,
|
||||
shortUUID: v.shortUUID,
|
||||
|
||||
score: v.score,
|
||||
|
||||
|
|
|
@ -62,6 +62,8 @@ const commonVideosFiltersValidator = [
|
|||
const videosSearchValidator = [
|
||||
check('search').optional().not().isEmpty().withMessage('Should have a valid search'),
|
||||
|
||||
check('host').optional().not().isEmpty().withMessage('Should have a valid host'),
|
||||
|
||||
check('startDate').optional().custom(isDateValid).withMessage('Should have a valid start date'),
|
||||
check('endDate').optional().custom(isDateValid).withMessage('Should have a valid end date'),
|
||||
|
||||
|
@ -87,6 +89,7 @@ const videosSearchValidator = [
|
|||
|
||||
const videoChannelsSearchValidator = [
|
||||
check('search').not().isEmpty().withMessage('Should have a valid search'),
|
||||
check('host').optional().not().isEmpty().withMessage('Should have a valid host'),
|
||||
|
||||
(req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
logger.debug({ query: req.query, body: req.body }, 'Checking video channels search query')
|
||||
|
@ -99,6 +102,7 @@ const videoChannelsSearchValidator = [
|
|||
|
||||
const videoPlaylistsSearchValidator = [
|
||||
check('search').not().isEmpty().withMessage('Should have a valid search'),
|
||||
check('host').optional().not().isEmpty().withMessage('Should have a valid host'),
|
||||
|
||||
(req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
logger.debug({ query: req.query, body: req.body }, 'Checking video playlists search query')
|
||||
|
|
Loading…
Reference in New Issue