]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - client/src/app/shared/shared-search/advanced-search.model.ts
Add ability to filter by host in search page
[github/Chocobozzz/PeerTube.git] / client / src / app / shared / shared-search / advanced-search.model.ts
1 import {
2 BooleanBothQuery,
3 BooleanQuery,
4 SearchTargetType,
5 VideoChannelsSearchQuery,
6 VideoPlaylistsSearchQuery,
7 VideosSearchQuery
8 } from '@shared/models'
9
10 export class AdvancedSearch {
11 startDate: string // ISO 8601
12 endDate: string // ISO 8601
13
14 originallyPublishedStartDate: string // ISO 8601
15 originallyPublishedEndDate: string // ISO 8601
16
17 nsfw: BooleanBothQuery
18
19 categoryOneOf: string
20
21 licenceOneOf: string
22
23 languageOneOf: string
24
25 tagsOneOf: string[]
26 tagsAllOf: string[]
27
28 durationMin: number // seconds
29 durationMax: number // seconds
30
31 isLive: BooleanQuery
32
33 host: string
34
35 sort: string
36
37 searchTarget: SearchTargetType
38
39 // Filters we don't want to count, because they are mandatory
40 private silentFilters = new Set([ 'sort', 'searchTarget' ])
41
42 constructor (options?: {
43 startDate?: string
44 endDate?: string
45 originallyPublishedStartDate?: string
46 originallyPublishedEndDate?: string
47 nsfw?: BooleanBothQuery
48 categoryOneOf?: string
49 licenceOneOf?: string
50 languageOneOf?: string
51
52 tagsOneOf?: any
53 tagsAllOf?: any
54
55 isLive?: BooleanQuery
56
57 host?: string
58
59 durationMin?: string
60 durationMax?: string
61 sort?: string
62 searchTarget?: SearchTargetType
63 }) {
64 if (!options) return
65
66 this.startDate = options.startDate || undefined
67 this.endDate = options.endDate || undefined
68 this.originallyPublishedStartDate = options.originallyPublishedStartDate || undefined
69 this.originallyPublishedEndDate = options.originallyPublishedEndDate || undefined
70
71 this.nsfw = options.nsfw || undefined
72 this.isLive = options.isLive || undefined
73
74 this.categoryOneOf = options.categoryOneOf || undefined
75 this.licenceOneOf = options.licenceOneOf || undefined
76 this.languageOneOf = options.languageOneOf || undefined
77 this.tagsOneOf = this.intoArray(options.tagsOneOf)
78 this.tagsAllOf = this.intoArray(options.tagsAllOf)
79 this.durationMin = parseInt(options.durationMin, 10)
80 this.durationMax = parseInt(options.durationMax, 10)
81
82 this.host = options.host || undefined
83
84 this.searchTarget = options.searchTarget || undefined
85
86 if (isNaN(this.durationMin)) this.durationMin = undefined
87 if (isNaN(this.durationMax)) this.durationMax = undefined
88
89 this.sort = options.sort || '-match'
90 }
91
92 containsValues () {
93 const obj = this.toUrlObject()
94 for (const k of Object.keys(obj)) {
95 if (this.silentFilters.has(k)) continue
96
97 if (this.isValidValue(obj[k])) return true
98 }
99
100 return false
101 }
102
103 reset () {
104 this.startDate = undefined
105 this.endDate = undefined
106 this.originallyPublishedStartDate = undefined
107 this.originallyPublishedEndDate = undefined
108 this.nsfw = undefined
109 this.categoryOneOf = undefined
110 this.licenceOneOf = undefined
111 this.languageOneOf = undefined
112 this.tagsOneOf = undefined
113 this.tagsAllOf = undefined
114 this.durationMin = undefined
115 this.durationMax = undefined
116 this.isLive = undefined
117 this.host = undefined
118
119 this.sort = '-match'
120 }
121
122 toUrlObject () {
123 return {
124 startDate: this.startDate,
125 endDate: this.endDate,
126 originallyPublishedStartDate: this.originallyPublishedStartDate,
127 originallyPublishedEndDate: this.originallyPublishedEndDate,
128 nsfw: this.nsfw,
129 categoryOneOf: this.categoryOneOf,
130 licenceOneOf: this.licenceOneOf,
131 languageOneOf: this.languageOneOf,
132 tagsOneOf: this.tagsOneOf,
133 tagsAllOf: this.tagsAllOf,
134 durationMin: this.durationMin,
135 durationMax: this.durationMax,
136 isLive: this.isLive,
137 host: this.host,
138 sort: this.sort,
139 searchTarget: this.searchTarget
140 }
141 }
142
143 toVideosAPIObject (): VideosSearchQuery {
144 let isLive: boolean
145 if (this.isLive) isLive = this.isLive === 'true'
146
147 return {
148 startDate: this.startDate,
149 endDate: this.endDate,
150 originallyPublishedStartDate: this.originallyPublishedStartDate,
151 originallyPublishedEndDate: this.originallyPublishedEndDate,
152 nsfw: this.nsfw,
153 categoryOneOf: this.intoArray(this.categoryOneOf),
154 licenceOneOf: this.intoArray(this.licenceOneOf),
155 languageOneOf: this.intoArray(this.languageOneOf),
156 tagsOneOf: this.tagsOneOf,
157 tagsAllOf: this.tagsAllOf,
158 durationMin: this.durationMin,
159 durationMax: this.durationMax,
160 host: this.host,
161 isLive,
162 sort: this.sort,
163 searchTarget: this.searchTarget
164 }
165 }
166
167 toPlaylistAPIObject (): VideoPlaylistsSearchQuery {
168 return {
169 host: this.host,
170 searchTarget: this.searchTarget
171 }
172 }
173
174 toChannelAPIObject (): VideoChannelsSearchQuery {
175 return {
176 host: this.host,
177 searchTarget: this.searchTarget
178 }
179 }
180
181 size () {
182 let acc = 0
183
184 const obj = this.toUrlObject()
185 for (const k of Object.keys(obj)) {
186 if (this.silentFilters.has(k)) continue
187
188 if (this.isValidValue(obj[k])) acc++
189 }
190
191 return acc
192 }
193
194 private isValidValue (val: any) {
195 if (val === undefined) return false
196 if (val === '') return false
197 if (Array.isArray(val) && val.length === 0) return false
198
199 return true
200 }
201
202 private intoArray (value: any) {
203 if (!value) return undefined
204 if (Array.isArray(value)) return value
205
206 if (typeof value === 'string') return value.split(',')
207
208 return [ value ]
209 }
210 }