]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - shared/server-commands/server/config-command.ts
9a6e413f2b4ecdcd70a23c1bf34850aa7ec3519a
[github/Chocobozzz/PeerTube.git] / shared / server-commands / server / config-command.ts
1 import { merge } from 'lodash'
2 import { About, CustomConfig, HttpStatusCode, ServerConfig } from '@shared/models'
3 import { DeepPartial } from '@shared/typescript-utils'
4 import { AbstractCommand, OverrideCommandOptions } from '../shared/abstract-command'
5
6 export class ConfigCommand extends AbstractCommand {
7
8 static getCustomConfigResolutions (enabled: boolean, with0p = false) {
9 return {
10 '0p': enabled && with0p,
11 '144p': enabled,
12 '240p': enabled,
13 '360p': enabled,
14 '480p': enabled,
15 '720p': enabled,
16 '1080p': enabled,
17 '1440p': enabled,
18 '2160p': enabled
19 }
20 }
21
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
35 enableSignup (requiresApproval: boolean, limit = -1) {
36 return this.updateExistingSubConfig({
37 newConfig: {
38 signup: {
39 enabled: true,
40 requiresApproval,
41 limit
42 }
43 }
44 })
45 }
46
47 // ---------------------------------------------------------------------------
48
49 disableImports () {
50 return this.setImportsEnabled(false)
51 }
52
53 enableImports () {
54 return this.setImportsEnabled(true)
55 }
56
57 private setImportsEnabled (enabled: boolean) {
58 return this.updateExistingSubConfig({
59 newConfig: {
60 import: {
61 videos: {
62 http: {
63 enabled
64 },
65
66 torrent: {
67 enabled
68 }
69 }
70 }
71 }
72 })
73 }
74
75 // ---------------------------------------------------------------------------
76
77 enableChannelSync () {
78 return this.setChannelSyncEnabled(true)
79 }
80
81 disableChannelSync () {
82 return this.setChannelSyncEnabled(false)
83 }
84
85 private setChannelSyncEnabled (enabled: boolean) {
86 return this.updateExistingSubConfig({
87 newConfig: {
88 import: {
89 videoChannelSynchronization: {
90 enabled
91 }
92 }
93 }
94 })
95 }
96
97 // ---------------------------------------------------------------------------
98
99 enableLive (options: {
100 allowReplay?: boolean
101 transcoding?: boolean
102 resolutions?: 'min' | 'max' // Default max
103 } = {}) {
104 const { allowReplay, transcoding, resolutions = 'max' } = options
105
106 return this.updateExistingSubConfig({
107 newConfig: {
108 live: {
109 enabled: true,
110 allowReplay: allowReplay ?? true,
111 transcoding: {
112 enabled: transcoding ?? true,
113 resolutions: ConfigCommand.getCustomConfigResolutions(resolutions === 'max')
114 }
115 }
116 }
117 })
118 }
119
120 disableTranscoding () {
121 return this.updateExistingSubConfig({
122 newConfig: {
123 transcoding: {
124 enabled: false
125 },
126 videoStudio: {
127 enabled: false
128 }
129 }
130 })
131 }
132
133 // TODO: convert args to object
134 enableTranscoding (webtorrent = true, hls = true, with0p = false) {
135 return this.updateExistingSubConfig({
136 newConfig: {
137 transcoding: {
138 enabled: true,
139
140 allowAudioFiles: true,
141 allowAdditionalExtensions: true,
142
143 resolutions: ConfigCommand.getCustomConfigResolutions(true, with0p),
144
145 webtorrent: {
146 enabled: webtorrent
147 },
148 hls: {
149 enabled: hls
150 }
151 }
152 }
153 })
154 }
155
156 // TODO: convert args to object
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
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
198 // ---------------------------------------------------------------------------
199
200 enableStudio () {
201 return this.updateExistingSubConfig({
202 newConfig: {
203 videoStudio: {
204 enabled: true
205 }
206 }
207 })
208 }
209
210 // ---------------------------------------------------------------------------
211
212 getConfig (options: OverrideCommandOptions = {}) {
213 const path = '/api/v1/config'
214
215 return this.getRequestBody<ServerConfig>({
216 ...options,
217
218 path,
219 implicitToken: false,
220 defaultExpectedStatus: HttpStatusCode.OK_200
221 })
222 }
223
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
239 getAbout (options: OverrideCommandOptions = {}) {
240 const path = '/api/v1/config/about'
241
242 return this.getRequestBody<About>({
243 ...options,
244
245 path,
246 implicitToken: false,
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,
258 implicitToken: true,
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,
273 implicitToken: true,
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,
285 implicitToken: true,
286 defaultExpectedStatus: HttpStatusCode.OK_200
287 })
288 }
289
290 async updateExistingSubConfig (options: OverrideCommandOptions & {
291 newConfig: DeepPartial<CustomConfig>
292 }) {
293 const existing = await this.getCustomConfig({ ...options, expectedStatus: HttpStatusCode.OK_200 })
294
295 return this.updateCustomConfig({ ...options, newCustomConfig: merge({}, existing, options.newConfig) })
296 }
297
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 },
338 client: {
339 videos: {
340 miniature: {
341 preferAuthorDisplayName: false
342 }
343 },
344 menu: {
345 login: {
346 redirectOnSingleExternalAuth: false
347 }
348 }
349 },
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,
364 requiresApproval: true,
365 requiresEmailVerification: false,
366 minimumAge: 16
367 },
368 admin: {
369 email: 'superadmin1@example.com'
370 },
371 contactForm: {
372 enabled: true
373 },
374 user: {
375 history: {
376 videos: {
377 enabled: true
378 }
379 },
380 videoQuota: 5242881,
381 videoQuotaDaily: 318742
382 },
383 videoChannels: {
384 maxPerUser: 20
385 },
386 transcoding: {
387 enabled: true,
388 remoteRunners: {
389 enabled: false
390 },
391 allowAdditionalExtensions: true,
392 allowAudioFiles: true,
393 threads: 1,
394 concurrency: 3,
395 profile: 'default',
396 resolutions: {
397 '0p': false,
398 '144p': false,
399 '240p': false,
400 '360p': true,
401 '480p': true,
402 '720p': false,
403 '1080p': false,
404 '1440p': false,
405 '2160p': false
406 },
407 alwaysTranscodeOriginalResolution: true,
408 webtorrent: {
409 enabled: true
410 },
411 hls: {
412 enabled: false
413 }
414 },
415 live: {
416 enabled: true,
417 allowReplay: false,
418 latencySetting: {
419 enabled: false
420 },
421 maxDuration: -1,
422 maxInstanceLives: -1,
423 maxUserLives: 50,
424 transcoding: {
425 enabled: true,
426 remoteRunners: {
427 enabled: false
428 },
429 threads: 4,
430 profile: 'default',
431 resolutions: {
432 '144p': true,
433 '240p': true,
434 '360p': true,
435 '480p': true,
436 '720p': true,
437 '1080p': true,
438 '1440p': true,
439 '2160p': true
440 },
441 alwaysTranscodeOriginalResolution: true
442 }
443 },
444 videoStudio: {
445 enabled: false
446 },
447 import: {
448 videos: {
449 concurrency: 3,
450 http: {
451 enabled: false
452 },
453 torrent: {
454 enabled: false
455 }
456 },
457 videoChannelSynchronization: {
458 enabled: false,
459 maxPerUser: 10
460 }
461 },
462 trending: {
463 videos: {
464 algorithms: {
465 enabled: [ 'hot', 'most-viewed', 'most-liked' ],
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 }