]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - shared/server-commands/server/config-command.ts
Add runner server tests
[github/Chocobozzz/PeerTube.git] / shared / server-commands / server / config-command.ts
CommitLineData
65e6e260 1import { merge } from 'lodash'
c55e3d72 2import { About, CustomConfig, HttpStatusCode, ServerConfig } from '@shared/models'
6b5f72be 3import { DeepPartial } from '@shared/typescript-utils'
c55e3d72 4import { AbstractCommand, OverrideCommandOptions } from '../shared/abstract-command'
65e6e260
C
5
6export class ConfigCommand extends AbstractCommand {
7
d102de1b 8 static getCustomConfigResolutions (enabled: boolean, with0p = false) {
65e6e260 9 return {
d102de1b 10 '0p': enabled && with0p,
8dd754c7 11 '144p': enabled,
65e6e260
C
12 '240p': enabled,
13 '360p': enabled,
14 '480p': enabled,
15 '720p': enabled,
16 '1080p': enabled,
17 '1440p': enabled,
18 '2160p': enabled
19 }
20 }
21
b379759f
C
22 // ---------------------------------------------------------------------------
23
24 static getEmailOverrideConfig (emailPort: number) {
25 return {
26 smtp: {
27 hostname: '127.0.0.1',
28 port: emailPort
29 }
30 }
31 }
32
33 // ---------------------------------------------------------------------------
34
9436936c 35 enableSignup (requiresApproval: boolean, limit = -1) {
b379759f
C
36 return this.updateExistingSubConfig({
37 newConfig: {
38 signup: {
39 enabled: true,
40 requiresApproval,
9436936c 41 limit
b379759f
C
42 }
43 }
44 })
45 }
46
47 // ---------------------------------------------------------------------------
48
2a491182
F
49 disableImports () {
50 return this.setImportsEnabled(false)
51 }
52
0305db28 53 enableImports () {
2a491182
F
54 return this.setImportsEnabled(true)
55 }
56
57 private setImportsEnabled (enabled: boolean) {
0305db28
JB
58 return this.updateExistingSubConfig({
59 newConfig: {
60 import: {
61 videos: {
62 http: {
2a491182 63 enabled
0305db28
JB
64 },
65
66 torrent: {
2a491182 67 enabled
0305db28
JB
68 }
69 }
70 }
71 }
72 })
73 }
74
b379759f
C
75 // ---------------------------------------------------------------------------
76
77 enableChannelSync () {
78 return this.setChannelSyncEnabled(true)
79 }
80
81 disableChannelSync () {
82 return this.setChannelSyncEnabled(false)
83 }
84
2a491182
F
85 private setChannelSyncEnabled (enabled: boolean) {
86 return this.updateExistingSubConfig({
87 newConfig: {
88 import: {
89 videoChannelSynchronization: {
90 enabled
91 }
92 }
93 }
94 })
95 }
96
b379759f 97 // ---------------------------------------------------------------------------
2a491182 98
0305db28
JB
99 enableLive (options: {
100 allowReplay?: boolean
101 transcoding?: boolean
53023be3 102 resolutions?: 'min' | 'max' // Default max
0305db28 103 } = {}) {
53023be3
C
104 const { allowReplay, transcoding, resolutions = 'max' } = options
105
0305db28
JB
106 return this.updateExistingSubConfig({
107 newConfig: {
108 live: {
109 enabled: true,
53023be3 110 allowReplay: allowReplay ?? true,
0305db28 111 transcoding: {
53023be3
C
112 enabled: transcoding ?? true,
113 resolutions: ConfigCommand.getCustomConfigResolutions(resolutions === 'max')
0305db28
JB
114 }
115 }
116 }
117 })
118 }
119
120 disableTranscoding () {
121 return this.updateExistingSubConfig({
122 newConfig: {
123 transcoding: {
124 enabled: false
c729caf6 125 },
92e66e04 126 videoStudio: {
c729caf6 127 enabled: false
0305db28
JB
128 }
129 }
130 })
131 }
132
d102de1b
C
133 // TODO: convert args to object
134 enableTranscoding (webtorrent = true, hls = true, with0p = false) {
0305db28
JB
135 return this.updateExistingSubConfig({
136 newConfig: {
137 transcoding: {
138 enabled: true,
c729caf6
C
139
140 allowAudioFiles: true,
141 allowAdditionalExtensions: true,
142
d102de1b 143 resolutions: ConfigCommand.getCustomConfigResolutions(true, with0p),
0305db28
JB
144
145 webtorrent: {
146 enabled: webtorrent
147 },
148 hls: {
149 enabled: hls
150 }
151 }
152 }
153 })
154 }
155
d102de1b 156 // TODO: convert args to object
c729caf6
C
157 enableMinimumTranscoding (webtorrent = true, hls = true) {
158 return this.updateExistingSubConfig({
159 newConfig: {
160 transcoding: {
161 enabled: true,
162 resolutions: {
163 ...ConfigCommand.getCustomConfigResolutions(false),
164
165 '240p': true
166 },
167
168 webtorrent: {
169 enabled: webtorrent
170 },
171 hls: {
172 enabled: hls
173 }
174 }
175 }
176 })
177 }
178
d102de1b
C
179 enableRemoteTranscoding () {
180 return this.updateExistingSubConfig({
181 newConfig: {
182 transcoding: {
183 remoteRunners: {
184 enabled: true
185 }
186 },
187 live: {
188 transcoding: {
189 remoteRunners: {
190 enabled: true
191 }
192 }
193 }
194 }
195 })
196 }
197
b379759f
C
198 // ---------------------------------------------------------------------------
199
92e66e04 200 enableStudio () {
1808a1f8
C
201 return this.updateExistingSubConfig({
202 newConfig: {
92e66e04 203 videoStudio: {
1808a1f8
C
204 enabled: true
205 }
206 }
207 })
208 }
209
b379759f
C
210 // ---------------------------------------------------------------------------
211
65e6e260
C
212 getConfig (options: OverrideCommandOptions = {}) {
213 const path = '/api/v1/config'
214
215 return this.getRequestBody<ServerConfig>({
216 ...options,
217
65e6e260 218 path,
a1637fa1 219 implicitToken: false,
65e6e260
C
220 defaultExpectedStatus: HttpStatusCode.OK_200
221 })
222 }
223
2769876f
C
224 async getIndexHTMLConfig (options: OverrideCommandOptions = {}) {
225 const text = await this.getRequestText({
226 ...options,
227
228 path: '/',
229 implicitToken: false,
230 defaultExpectedStatus: HttpStatusCode.OK_200
231 })
232
233 const match = text.match('<script type="application/javascript">window.PeerTubeServerConfig = (".+?")</script>')
234
235 // We parse the string twice, first to extract the string and then to extract the JSON
236 return JSON.parse(JSON.parse(match[1])) as ServerConfig
237 }
238
65e6e260
C
239 getAbout (options: OverrideCommandOptions = {}) {
240 const path = '/api/v1/config/about'
241
242 return this.getRequestBody<About>({
243 ...options,
244
65e6e260 245 path,
a1637fa1 246 implicitToken: false,
65e6e260
C
247 defaultExpectedStatus: HttpStatusCode.OK_200
248 })
249 }
250
251 getCustomConfig (options: OverrideCommandOptions = {}) {
252 const path = '/api/v1/config/custom'
253
254 return this.getRequestBody<CustomConfig>({
255 ...options,
256
257 path,
a1637fa1 258 implicitToken: true,
65e6e260
C
259 defaultExpectedStatus: HttpStatusCode.OK_200
260 })
261 }
262
263 updateCustomConfig (options: OverrideCommandOptions & {
264 newCustomConfig: CustomConfig
265 }) {
266 const path = '/api/v1/config/custom'
267
268 return this.putBodyRequest({
269 ...options,
270
271 path,
272 fields: options.newCustomConfig,
a1637fa1 273 implicitToken: true,
65e6e260
C
274 defaultExpectedStatus: HttpStatusCode.OK_200
275 })
276 }
277
278 deleteCustomConfig (options: OverrideCommandOptions = {}) {
279 const path = '/api/v1/config/custom'
280
281 return this.deleteRequest({
282 ...options,
283
284 path,
a1637fa1 285 implicitToken: true,
65e6e260
C
286 defaultExpectedStatus: HttpStatusCode.OK_200
287 })
288 }
289
0305db28
JB
290 async updateExistingSubConfig (options: OverrideCommandOptions & {
291 newConfig: DeepPartial<CustomConfig>
292 }) {
c729caf6 293 const existing = await this.getCustomConfig({ ...options, expectedStatus: HttpStatusCode.OK_200 })
0305db28
JB
294
295 return this.updateCustomConfig({ ...options, newCustomConfig: merge({}, existing, options.newConfig) })
296 }
297
65e6e260
C
298 updateCustomSubConfig (options: OverrideCommandOptions & {
299 newConfig: DeepPartial<CustomConfig>
300 }) {
301 const newCustomConfig: CustomConfig = {
302 instance: {
303 name: 'PeerTube updated',
304 shortDescription: 'my short description',
305 description: 'my super description',
306 terms: 'my super terms',
307 codeOfConduct: 'my super coc',
308
309 creationReason: 'my super creation reason',
310 moderationInformation: 'my super moderation information',
311 administrator: 'Kuja',
312 maintenanceLifetime: 'forever',
313 businessModel: 'my super business model',
314 hardwareInformation: '2vCore 3GB RAM',
315
316 languages: [ 'en', 'es' ],
317 categories: [ 1, 2 ],
318
319 isNSFW: true,
320 defaultNSFWPolicy: 'blur',
321
322 defaultClientRoute: '/videos/recently-added',
323
324 customizations: {
325 javascript: 'alert("coucou")',
326 css: 'body { background-color: red; }'
327 }
328 },
329 theme: {
330 default: 'default'
331 },
332 services: {
333 twitter: {
334 username: '@MySuperUsername',
335 whitelisted: true
336 }
337 },
0bc53e20
C
338 client: {
339 videos: {
340 miniature: {
341 preferAuthorDisplayName: false
342 }
343 },
344 menu: {
345 login: {
346 redirectOnSingleExternalAuth: false
347 }
348 }
349 },
65e6e260
C
350 cache: {
351 previews: {
352 size: 2
353 },
354 captions: {
355 size: 3
356 },
357 torrents: {
358 size: 4
359 }
360 },
361 signup: {
362 enabled: false,
363 limit: 5,
b379759f 364 requiresApproval: true,
65e6e260
C
365 requiresEmailVerification: false,
366 minimumAge: 16
367 },
368 admin: {
369 email: 'superadmin1@example.com'
370 },
371 contactForm: {
372 enabled: true
373 },
374 user: {
b302c80d
W
375 history: {
376 videos: {
377 enabled: true
378 }
379 },
65e6e260
C
380 videoQuota: 5242881,
381 videoQuotaDaily: 318742
382 },
754b6f5f
FC
383 videoChannels: {
384 maxPerUser: 20
385 },
65e6e260
C
386 transcoding: {
387 enabled: true,
d102de1b
C
388 remoteRunners: {
389 enabled: false
390 },
65e6e260
C
391 allowAdditionalExtensions: true,
392 allowAudioFiles: true,
393 threads: 1,
394 concurrency: 3,
395 profile: 'default',
396 resolutions: {
397 '0p': false,
8dd754c7 398 '144p': false,
65e6e260
C
399 '240p': false,
400 '360p': true,
401 '480p': true,
402 '720p': false,
403 '1080p': false,
404 '1440p': false,
405 '2160p': false
406 },
84cae54e 407 alwaysTranscodeOriginalResolution: true,
65e6e260
C
408 webtorrent: {
409 enabled: true
410 },
411 hls: {
412 enabled: false
413 }
414 },
415 live: {
416 enabled: true,
417 allowReplay: false,
f443a746
C
418 latencySetting: {
419 enabled: false
420 },
65e6e260
C
421 maxDuration: -1,
422 maxInstanceLives: -1,
423 maxUserLives: 50,
424 transcoding: {
425 enabled: true,
d102de1b
C
426 remoteRunners: {
427 enabled: false
428 },
65e6e260
C
429 threads: 4,
430 profile: 'default',
431 resolutions: {
8dd754c7 432 '144p': true,
65e6e260
C
433 '240p': true,
434 '360p': true,
435 '480p': true,
436 '720p': true,
437 '1080p': true,
438 '1440p': true,
439 '2160p': true
84cae54e
C
440 },
441 alwaysTranscodeOriginalResolution: true
65e6e260
C
442 }
443 },
92e66e04 444 videoStudio: {
c729caf6
C
445 enabled: false
446 },
65e6e260
C
447 import: {
448 videos: {
449 concurrency: 3,
450 http: {
451 enabled: false
452 },
453 torrent: {
454 enabled: false
455 }
2a491182
F
456 },
457 videoChannelSynchronization: {
458 enabled: false,
459 maxPerUser: 10
65e6e260
C
460 }
461 },
462 trending: {
463 videos: {
464 algorithms: {
010382b6 465 enabled: [ 'hot', 'most-viewed', 'most-liked' ],
65e6e260
C
466 default: 'hot'
467 }
468 }
469 },
470 autoBlacklist: {
471 videos: {
472 ofUsers: {
473 enabled: false
474 }
475 }
476 },
477 followers: {
478 instance: {
479 enabled: true,
480 manualApproval: false
481 }
482 },
483 followings: {
484 instance: {
485 autoFollowBack: {
486 enabled: false
487 },
488 autoFollowIndex: {
489 indexUrl: 'https://instances.joinpeertube.org/api/v1/instances/hosts',
490 enabled: false
491 }
492 }
493 },
494 broadcastMessage: {
495 enabled: true,
496 level: 'warning',
497 message: 'hello',
498 dismissable: true
499 },
500 search: {
501 remoteUri: {
502 users: true,
503 anonymous: true
504 },
505 searchIndex: {
506 enabled: true,
507 url: 'https://search.joinpeertube.org',
508 disableLocalSearch: true,
509 isDefaultSearch: true
510 }
511 }
512 }
513
514 merge(newCustomConfig, options.newConfig)
515
516 return this.updateCustomConfig({ ...options, newCustomConfig })
517 }
518}