]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - shared/server-commands/server/config-command.ts
Support studio transcoding in peertube runner
[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
5e47f6ab
C
198 enableRemoteStudio () {
199 return this.updateExistingSubConfig({
200 newConfig: {
201 videoStudio: {
202 remoteRunners: {
203 enabled: true
204 }
205 }
206 }
207 })
208 }
209
b379759f
C
210 // ---------------------------------------------------------------------------
211
92e66e04 212 enableStudio () {
1808a1f8
C
213 return this.updateExistingSubConfig({
214 newConfig: {
92e66e04 215 videoStudio: {
1808a1f8
C
216 enabled: true
217 }
218 }
219 })
220 }
221
b379759f
C
222 // ---------------------------------------------------------------------------
223
65e6e260
C
224 getConfig (options: OverrideCommandOptions = {}) {
225 const path = '/api/v1/config'
226
227 return this.getRequestBody<ServerConfig>({
228 ...options,
229
65e6e260 230 path,
a1637fa1 231 implicitToken: false,
65e6e260
C
232 defaultExpectedStatus: HttpStatusCode.OK_200
233 })
234 }
235
2769876f
C
236 async getIndexHTMLConfig (options: OverrideCommandOptions = {}) {
237 const text = await this.getRequestText({
238 ...options,
239
240 path: '/',
241 implicitToken: false,
242 defaultExpectedStatus: HttpStatusCode.OK_200
243 })
244
245 const match = text.match('<script type="application/javascript">window.PeerTubeServerConfig = (".+?")</script>')
246
247 // We parse the string twice, first to extract the string and then to extract the JSON
248 return JSON.parse(JSON.parse(match[1])) as ServerConfig
249 }
250
65e6e260
C
251 getAbout (options: OverrideCommandOptions = {}) {
252 const path = '/api/v1/config/about'
253
254 return this.getRequestBody<About>({
255 ...options,
256
65e6e260 257 path,
a1637fa1 258 implicitToken: false,
65e6e260
C
259 defaultExpectedStatus: HttpStatusCode.OK_200
260 })
261 }
262
263 getCustomConfig (options: OverrideCommandOptions = {}) {
264 const path = '/api/v1/config/custom'
265
266 return this.getRequestBody<CustomConfig>({
267 ...options,
268
269 path,
a1637fa1 270 implicitToken: true,
65e6e260
C
271 defaultExpectedStatus: HttpStatusCode.OK_200
272 })
273 }
274
275 updateCustomConfig (options: OverrideCommandOptions & {
276 newCustomConfig: CustomConfig
277 }) {
278 const path = '/api/v1/config/custom'
279
280 return this.putBodyRequest({
281 ...options,
282
283 path,
284 fields: options.newCustomConfig,
a1637fa1 285 implicitToken: true,
65e6e260
C
286 defaultExpectedStatus: HttpStatusCode.OK_200
287 })
288 }
289
290 deleteCustomConfig (options: OverrideCommandOptions = {}) {
291 const path = '/api/v1/config/custom'
292
293 return this.deleteRequest({
294 ...options,
295
296 path,
a1637fa1 297 implicitToken: true,
65e6e260
C
298 defaultExpectedStatus: HttpStatusCode.OK_200
299 })
300 }
301
0305db28
JB
302 async updateExistingSubConfig (options: OverrideCommandOptions & {
303 newConfig: DeepPartial<CustomConfig>
304 }) {
c729caf6 305 const existing = await this.getCustomConfig({ ...options, expectedStatus: HttpStatusCode.OK_200 })
0305db28
JB
306
307 return this.updateCustomConfig({ ...options, newCustomConfig: merge({}, existing, options.newConfig) })
308 }
309
65e6e260
C
310 updateCustomSubConfig (options: OverrideCommandOptions & {
311 newConfig: DeepPartial<CustomConfig>
312 }) {
313 const newCustomConfig: CustomConfig = {
314 instance: {
315 name: 'PeerTube updated',
316 shortDescription: 'my short description',
317 description: 'my super description',
318 terms: 'my super terms',
319 codeOfConduct: 'my super coc',
320
321 creationReason: 'my super creation reason',
322 moderationInformation: 'my super moderation information',
323 administrator: 'Kuja',
324 maintenanceLifetime: 'forever',
325 businessModel: 'my super business model',
326 hardwareInformation: '2vCore 3GB RAM',
327
328 languages: [ 'en', 'es' ],
329 categories: [ 1, 2 ],
330
331 isNSFW: true,
332 defaultNSFWPolicy: 'blur',
333
334 defaultClientRoute: '/videos/recently-added',
335
336 customizations: {
337 javascript: 'alert("coucou")',
338 css: 'body { background-color: red; }'
339 }
340 },
341 theme: {
342 default: 'default'
343 },
344 services: {
345 twitter: {
346 username: '@MySuperUsername',
347 whitelisted: true
348 }
349 },
0bc53e20
C
350 client: {
351 videos: {
352 miniature: {
353 preferAuthorDisplayName: false
354 }
355 },
356 menu: {
357 login: {
358 redirectOnSingleExternalAuth: false
359 }
360 }
361 },
65e6e260
C
362 cache: {
363 previews: {
364 size: 2
365 },
366 captions: {
367 size: 3
368 },
369 torrents: {
370 size: 4
371 }
372 },
373 signup: {
374 enabled: false,
375 limit: 5,
b379759f 376 requiresApproval: true,
65e6e260
C
377 requiresEmailVerification: false,
378 minimumAge: 16
379 },
380 admin: {
381 email: 'superadmin1@example.com'
382 },
383 contactForm: {
384 enabled: true
385 },
386 user: {
b302c80d
W
387 history: {
388 videos: {
389 enabled: true
390 }
391 },
65e6e260
C
392 videoQuota: 5242881,
393 videoQuotaDaily: 318742
394 },
754b6f5f
FC
395 videoChannels: {
396 maxPerUser: 20
397 },
65e6e260
C
398 transcoding: {
399 enabled: true,
d102de1b
C
400 remoteRunners: {
401 enabled: false
402 },
65e6e260
C
403 allowAdditionalExtensions: true,
404 allowAudioFiles: true,
405 threads: 1,
406 concurrency: 3,
407 profile: 'default',
408 resolutions: {
409 '0p': false,
8dd754c7 410 '144p': false,
65e6e260
C
411 '240p': false,
412 '360p': true,
413 '480p': true,
414 '720p': false,
415 '1080p': false,
416 '1440p': false,
417 '2160p': false
418 },
84cae54e 419 alwaysTranscodeOriginalResolution: true,
65e6e260
C
420 webtorrent: {
421 enabled: true
422 },
423 hls: {
424 enabled: false
425 }
426 },
427 live: {
428 enabled: true,
429 allowReplay: false,
f443a746
C
430 latencySetting: {
431 enabled: false
432 },
65e6e260
C
433 maxDuration: -1,
434 maxInstanceLives: -1,
435 maxUserLives: 50,
436 transcoding: {
437 enabled: true,
d102de1b
C
438 remoteRunners: {
439 enabled: false
440 },
65e6e260
C
441 threads: 4,
442 profile: 'default',
443 resolutions: {
8dd754c7 444 '144p': true,
65e6e260
C
445 '240p': true,
446 '360p': true,
447 '480p': true,
448 '720p': true,
449 '1080p': true,
450 '1440p': true,
451 '2160p': true
84cae54e
C
452 },
453 alwaysTranscodeOriginalResolution: true
65e6e260
C
454 }
455 },
92e66e04 456 videoStudio: {
5e47f6ab
C
457 enabled: false,
458 remoteRunners: {
459 enabled: false
460 }
c729caf6 461 },
65e6e260
C
462 import: {
463 videos: {
464 concurrency: 3,
465 http: {
466 enabled: false
467 },
468 torrent: {
469 enabled: false
470 }
2a491182
F
471 },
472 videoChannelSynchronization: {
473 enabled: false,
474 maxPerUser: 10
65e6e260
C
475 }
476 },
477 trending: {
478 videos: {
479 algorithms: {
010382b6 480 enabled: [ 'hot', 'most-viewed', 'most-liked' ],
65e6e260
C
481 default: 'hot'
482 }
483 }
484 },
485 autoBlacklist: {
486 videos: {
487 ofUsers: {
488 enabled: false
489 }
490 }
491 },
492 followers: {
493 instance: {
494 enabled: true,
495 manualApproval: false
496 }
497 },
498 followings: {
499 instance: {
500 autoFollowBack: {
501 enabled: false
502 },
503 autoFollowIndex: {
504 indexUrl: 'https://instances.joinpeertube.org/api/v1/instances/hosts',
505 enabled: false
506 }
507 }
508 },
509 broadcastMessage: {
510 enabled: true,
511 level: 'warning',
512 message: 'hello',
513 dismissable: true
514 },
515 search: {
516 remoteUri: {
517 users: true,
518 anonymous: true
519 },
520 searchIndex: {
521 enabled: true,
522 url: 'https://search.joinpeertube.org',
523 disableLocalSearch: true,
524 isDefaultSearch: true
525 }
526 }
527 }
528
529 merge(newCustomConfig, options.newConfig)
530
531 return this.updateCustomConfig({ ...options, newCustomConfig })
532 }
533}