1 import { BooleanBothQuery, BooleanQuery, SearchTargetType, VideosSearchQuery } from '@shared/models'
3 export class AdvancedSearch {
4 startDate: string // ISO 8601
5 endDate: string // ISO 8601
7 originallyPublishedStartDate: string // ISO 8601
8 originallyPublishedEndDate: string // ISO 8601
10 nsfw: BooleanBothQuery
21 durationMin: number // seconds
22 durationMax: number // seconds
28 searchTarget: SearchTargetType
30 // Filters we don't want to count, because they are mandatory
31 private silentFilters = new Set([ 'sort', 'searchTarget' ])
33 constructor (options?: {
36 originallyPublishedStartDate?: string
37 originallyPublishedEndDate?: string
38 nsfw?: BooleanBothQuery
39 categoryOneOf?: string
41 languageOneOf?: string
51 searchTarget?: SearchTargetType
55 this.startDate = options.startDate || undefined
56 this.endDate = options.endDate || undefined
57 this.originallyPublishedStartDate = options.originallyPublishedStartDate || undefined
58 this.originallyPublishedEndDate = options.originallyPublishedEndDate || undefined
60 this.nsfw = options.nsfw || undefined
61 this.isLive = options.isLive || undefined
63 this.categoryOneOf = options.categoryOneOf || undefined
64 this.licenceOneOf = options.licenceOneOf || undefined
65 this.languageOneOf = options.languageOneOf || undefined
66 this.tagsOneOf = this.intoArray(options.tagsOneOf)
67 this.tagsAllOf = this.intoArray(options.tagsAllOf)
68 this.durationMin = parseInt(options.durationMin, 10)
69 this.durationMax = parseInt(options.durationMax, 10)
71 this.searchTarget = options.searchTarget || undefined
73 if (isNaN(this.durationMin)) this.durationMin = undefined
74 if (isNaN(this.durationMax)) this.durationMax = undefined
76 this.sort = options.sort || '-match'
80 const obj = this.toUrlObject()
81 for (const k of Object.keys(obj)) {
82 if (this.silentFilters.has(k)) continue
84 if (this.isValidValue(obj[k])) return true
91 this.startDate = undefined
92 this.endDate = undefined
93 this.originallyPublishedStartDate = undefined
94 this.originallyPublishedEndDate = undefined
96 this.categoryOneOf = undefined
97 this.licenceOneOf = undefined
98 this.languageOneOf = undefined
99 this.tagsOneOf = undefined
100 this.tagsAllOf = undefined
101 this.durationMin = undefined
102 this.durationMax = undefined
103 this.isLive = undefined
110 startDate: this.startDate,
111 endDate: this.endDate,
112 originallyPublishedStartDate: this.originallyPublishedStartDate,
113 originallyPublishedEndDate: this.originallyPublishedEndDate,
115 categoryOneOf: this.categoryOneOf,
116 licenceOneOf: this.licenceOneOf,
117 languageOneOf: this.languageOneOf,
118 tagsOneOf: this.tagsOneOf,
119 tagsAllOf: this.tagsAllOf,
120 durationMin: this.durationMin,
121 durationMax: this.durationMax,
124 searchTarget: this.searchTarget
128 toAPIObject (): VideosSearchQuery {
130 if (this.isLive) isLive = this.isLive === 'true'
133 startDate: this.startDate,
134 endDate: this.endDate,
135 originallyPublishedStartDate: this.originallyPublishedStartDate,
136 originallyPublishedEndDate: this.originallyPublishedEndDate,
138 categoryOneOf: this.intoArray(this.categoryOneOf),
139 licenceOneOf: this.intoArray(this.licenceOneOf),
140 languageOneOf: this.intoArray(this.languageOneOf),
141 tagsOneOf: this.tagsOneOf,
142 tagsAllOf: this.tagsAllOf,
143 durationMin: this.durationMin,
144 durationMax: this.durationMax,
147 searchTarget: this.searchTarget
154 const obj = this.toUrlObject()
155 for (const k of Object.keys(obj)) {
156 if (this.silentFilters.has(k)) continue
158 if (this.isValidValue(obj[k])) acc++
164 private isValidValue (val: any) {
165 if (val === undefined) return false
166 if (val === '') return false
167 if (Array.isArray(val) && val.length === 0) return false
172 private intoArray (value: any) {
173 if (!value) return undefined
174 if (Array.isArray(value)) return value
176 if (typeof value === 'string') return value.split(',')