aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/lib
diff options
context:
space:
mode:
authorlutangar <johan.dufour@gmail.com>2021-06-29 16:02:05 +0200
committerlutangar <johan.dufour@gmail.com>2021-07-16 17:49:40 +0200
commitdc3d902234bb73fbc8cf9787e3036f2012526e6c (patch)
tree58ab2812fa5b38f4e19376f1a7cf3d718f3003fb /server/lib
parentde15b052c59cbd4b99bca835b124485ca1af399e (diff)
downloadPeerTube-dc3d902234bb73fbc8cf9787e3036f2012526e6c.tar.gz
PeerTube-dc3d902234bb73fbc8cf9787e3036f2012526e6c.tar.zst
PeerTube-dc3d902234bb73fbc8cf9787e3036f2012526e6c.zip
Introduce generic video constant manager for plugins
Allow a plugin developer to get back constants values, and reset constants deletions or additions.
Diffstat (limited to 'server/lib')
-rw-r--r--server/lib/plugins/register-helpers.ts222
-rw-r--r--server/lib/plugins/video-constant-manager-factory.ts139
2 files changed, 182 insertions, 179 deletions
diff --git a/server/lib/plugins/register-helpers.ts b/server/lib/plugins/register-helpers.ts
index 09275f9ba..af533effd 100644
--- a/server/lib/plugins/register-helpers.ts
+++ b/server/lib/plugins/register-helpers.ts
@@ -1,13 +1,7 @@
1import * as express from 'express' 1import * as express from 'express'
2import { logger } from '@server/helpers/logger' 2import { logger } from '@server/helpers/logger'
3import {
4 VIDEO_CATEGORIES,
5 VIDEO_LANGUAGES,
6 VIDEO_LICENCES,
7 VIDEO_PLAYLIST_PRIVACIES,
8 VIDEO_PRIVACIES
9} from '@server/initializers/constants'
10import { onExternalUserAuthenticated } from '@server/lib/auth/external-auth' 3import { onExternalUserAuthenticated } from '@server/lib/auth/external-auth'
4import { VideoConstantManagerFactory } from '@server/lib/plugins/video-constant-manager-factory'
11import { PluginModel } from '@server/models/server/plugin' 5import { PluginModel } from '@server/models/server/plugin'
12import { 6import {
13 RegisterServerAuthExternalOptions, 7 RegisterServerAuthExternalOptions,
@@ -18,41 +12,18 @@ import {
18} from '@server/types/plugins' 12} from '@server/types/plugins'
19import { 13import {
20 EncoderOptionsBuilder, 14 EncoderOptionsBuilder,
21 PluginPlaylistPrivacyManager,
22 PluginSettingsManager, 15 PluginSettingsManager,
23 PluginStorageManager, 16 PluginStorageManager,
24 PluginVideoCategoryManager,
25 PluginVideoLanguageManager,
26 PluginVideoLicenceManager,
27 PluginVideoPrivacyManager,
28 RegisterServerHookOptions, 17 RegisterServerHookOptions,
29 RegisterServerSettingOptions, 18 RegisterServerSettingOptions,
30 serverHookObject 19 serverHookObject,
20 VideoPlaylistPrivacy,
21 VideoPrivacy
31} from '@shared/models' 22} from '@shared/models'
32import { VideoTranscodingProfilesManager } from '../transcoding/video-transcoding-profiles' 23import { VideoTranscodingProfilesManager } from '../transcoding/video-transcoding-profiles'
33import { buildPluginHelpers } from './plugin-helpers-builder' 24import { buildPluginHelpers } from './plugin-helpers-builder'
34 25
35type AlterableVideoConstant = 'language' | 'licence' | 'category' | 'privacy' | 'playlistPrivacy'
36type VideoConstant = { [key in number | string]: string }
37
38type UpdatedVideoConstant = {
39 [name in AlterableVideoConstant]: {
40 [ npmName: string]: {
41 added: { key: number | string, label: string }[]
42 deleted: { key: number | string, label: string }[]
43 }
44 }
45}
46
47export class RegisterHelpers { 26export class RegisterHelpers {
48 private readonly updatedVideoConstants: UpdatedVideoConstant = {
49 playlistPrivacy: { },
50 privacy: { },
51 language: { },
52 licence: { },
53 category: { }
54 }
55
56 private readonly transcodingProfiles: { 27 private readonly transcodingProfiles: {
57 [ npmName: string ]: { 28 [ npmName: string ]: {
58 type: 'vod' | 'live' 29 type: 'vod' | 'live'
@@ -78,6 +49,7 @@ export class RegisterHelpers {
78 private readonly onSettingsChangeCallbacks: ((settings: any) => Promise<any>)[] = [] 49 private readonly onSettingsChangeCallbacks: ((settings: any) => Promise<any>)[] = []
79 50
80 private readonly router: express.Router 51 private readonly router: express.Router
52 private readonly videoConstantManagerFactory: VideoConstantManagerFactory
81 53
82 constructor ( 54 constructor (
83 private readonly npmName: string, 55 private readonly npmName: string,
@@ -85,6 +57,7 @@ export class RegisterHelpers {
85 private readonly onHookAdded: (options: RegisterServerHookOptions) => void 57 private readonly onHookAdded: (options: RegisterServerHookOptions) => void
86 ) { 58 ) {
87 this.router = express.Router() 59 this.router = express.Router()
60 this.videoConstantManagerFactory = new VideoConstantManagerFactory(this.npmName)
88 } 61 }
89 62
90 buildRegisterHelpers (): RegisterServerOptions { 63 buildRegisterHelpers (): RegisterServerOptions {
@@ -96,13 +69,13 @@ export class RegisterHelpers {
96 const settingsManager = this.buildSettingsManager() 69 const settingsManager = this.buildSettingsManager()
97 const storageManager = this.buildStorageManager() 70 const storageManager = this.buildStorageManager()
98 71
99 const videoLanguageManager = this.buildVideoLanguageManager() 72 const videoLanguageManager = this.videoConstantManagerFactory.createVideoConstantManager<string>('language')
100 73
101 const videoLicenceManager = this.buildVideoLicenceManager() 74 const videoLicenceManager = this.videoConstantManagerFactory.createVideoConstantManager<number>('licence')
102 const videoCategoryManager = this.buildVideoCategoryManager() 75 const videoCategoryManager = this.videoConstantManagerFactory.createVideoConstantManager<number>('category')
103 76
104 const videoPrivacyManager = this.buildVideoPrivacyManager() 77 const videoPrivacyManager = this.videoConstantManagerFactory.createVideoConstantManager<VideoPrivacy>('privacy')
105 const playlistPrivacyManager = this.buildPlaylistPrivacyManager() 78 const playlistPrivacyManager = this.videoConstantManagerFactory.createVideoConstantManager<VideoPlaylistPrivacy>('playlistPrivacy')
106 79
107 const transcodingManager = this.buildTranscodingManager() 80 const transcodingManager = this.buildTranscodingManager()
108 81
@@ -122,12 +95,38 @@ export class RegisterHelpers {
122 settingsManager, 95 settingsManager,
123 storageManager, 96 storageManager,
124 97
125 videoLanguageManager, 98 videoLanguageManager: {
126 videoCategoryManager, 99 ...videoLanguageManager,
127 videoLicenceManager, 100 /** @deprecated use `addConstant` instead **/
101 addLanguage: videoLanguageManager.addConstant,
102 /** @deprecated use `deleteConstant` instead **/
103 deleteLanguage: videoLanguageManager.deleteConstant
104 },
105 videoCategoryManager: {
106 ...videoCategoryManager,
107 /** @deprecated use `addConstant` instead **/
108 addCategory: videoCategoryManager.addConstant,
109 /** @deprecated use `deleteConstant` instead **/
110 deleteCategory: videoCategoryManager.deleteConstant
111 },
112 videoLicenceManager: {
113 ...videoLicenceManager,
114 /** @deprecated use `addConstant` instead **/
115 addLicence: videoLicenceManager.addConstant,
116 /** @deprecated use `deleteConstant` instead **/
117 deleteLicence: videoLicenceManager.deleteConstant
118 },
128 119
129 videoPrivacyManager, 120 videoPrivacyManager: {
130 playlistPrivacyManager, 121 ...videoPrivacyManager,
122 /** @deprecated use `deleteConstant` instead **/
123 deletePrivacy: videoPrivacyManager.deleteConstant
124 },
125 playlistPrivacyManager: {
126 ...playlistPrivacyManager,
127 /** @deprecated use `deleteConstant` instead **/
128 deletePlaylistPrivacy: playlistPrivacyManager.deleteConstant
129 },
131 130
132 transcodingManager, 131 transcodingManager,
133 132
@@ -141,29 +140,7 @@ export class RegisterHelpers {
141 } 140 }
142 141
143 reinitVideoConstants (npmName: string) { 142 reinitVideoConstants (npmName: string) {
144 const hash = { 143 this.videoConstantManagerFactory.resetVideoConstants(npmName)
145 language: VIDEO_LANGUAGES,
146 licence: VIDEO_LICENCES,
147 category: VIDEO_CATEGORIES,
148 privacy: VIDEO_PRIVACIES,
149 playlistPrivacy: VIDEO_PLAYLIST_PRIVACIES
150 }
151 const types: AlterableVideoConstant[] = [ 'language', 'licence', 'category', 'privacy', 'playlistPrivacy' ]
152
153 for (const type of types) {
154 const updatedConstants = this.updatedVideoConstants[type][npmName]
155 if (!updatedConstants) continue
156
157 for (const added of updatedConstants.added) {
158 delete hash[type][added.key]
159 }
160
161 for (const deleted of updatedConstants.deleted) {
162 hash[type][deleted.key] = deleted.label
163 }
164
165 delete this.updatedVideoConstants[type][npmName]
166 }
167 } 144 }
168 145
169 reinitTranscodingProfilesAndEncoders (npmName: string) { 146 reinitTranscodingProfilesAndEncoders (npmName: string) {
@@ -291,119 +268,6 @@ export class RegisterHelpers {
291 } 268 }
292 } 269 }
293 270
294 private buildVideoLanguageManager (): PluginVideoLanguageManager {
295 return {
296 addLanguage: (key: string, label: string) => {
297 return this.addConstant({ npmName: this.npmName, type: 'language', obj: VIDEO_LANGUAGES, key, label })
298 },
299
300 deleteLanguage: (key: string) => {
301 return this.deleteConstant({ npmName: this.npmName, type: 'language', obj: VIDEO_LANGUAGES, key })
302 }
303 }
304 }
305
306 private buildVideoCategoryManager (): PluginVideoCategoryManager {
307 return {
308 addCategory: (key: number, label: string) => {
309 return this.addConstant({ npmName: this.npmName, type: 'category', obj: VIDEO_CATEGORIES, key, label })
310 },
311
312 deleteCategory: (key: number) => {
313 return this.deleteConstant({ npmName: this.npmName, type: 'category', obj: VIDEO_CATEGORIES, key })
314 }
315 }
316 }
317
318 private buildVideoPrivacyManager (): PluginVideoPrivacyManager {
319 return {
320 deletePrivacy: (key: number) => {
321 return this.deleteConstant({ npmName: this.npmName, type: 'privacy', obj: VIDEO_PRIVACIES, key })
322 }
323 }
324 }
325
326 private buildPlaylistPrivacyManager (): PluginPlaylistPrivacyManager {
327 return {
328 deletePlaylistPrivacy: (key: number) => {
329 return this.deleteConstant({ npmName: this.npmName, type: 'playlistPrivacy', obj: VIDEO_PLAYLIST_PRIVACIES, key })
330 }
331 }
332 }
333
334 private buildVideoLicenceManager (): PluginVideoLicenceManager {
335 return {
336 addLicence: (key: number, label: string) => {
337 return this.addConstant({ npmName: this.npmName, type: 'licence', obj: VIDEO_LICENCES, key, label })
338 },
339
340 deleteLicence: (key: number) => {
341 return this.deleteConstant({ npmName: this.npmName, type: 'licence', obj: VIDEO_LICENCES, key })
342 }
343 }
344 }
345
346 private addConstant<T extends string | number> (parameters: {
347 npmName: string
348 type: AlterableVideoConstant
349 obj: VideoConstant
350 key: T
351 label: string
352 }) {
353 const { npmName, type, obj, key, label } = parameters
354
355 if (obj[key]) {
356 logger.warn('Cannot add %s %s by plugin %s: key already exists.', type, npmName, key)
357 return false
358 }
359
360 if (!this.updatedVideoConstants[type][npmName]) {
361 this.updatedVideoConstants[type][npmName] = {
362 added: [],
363 deleted: []
364 }
365 }
366
367 this.updatedVideoConstants[type][npmName].added.push({ key, label })
368 obj[key] = label
369
370 return true
371 }
372
373 private deleteConstant<T extends string | number> (parameters: {
374 npmName: string
375 type: AlterableVideoConstant
376 obj: VideoConstant
377 key: T
378 }) {
379 const { npmName, type, obj, key } = parameters
380
381 if (!obj[key]) {
382 logger.warn('Cannot delete %s by plugin %s: key %s does not exist.', type, npmName, key)
383 return false
384 }
385
386 if (!this.updatedVideoConstants[type][npmName]) {
387 this.updatedVideoConstants[type][npmName] = {
388 added: [],
389 deleted: []
390 }
391 }
392
393 const updatedConstants = this.updatedVideoConstants[type][npmName]
394
395 const alreadyAdded = updatedConstants.added.find(a => a.key === key)
396 if (alreadyAdded) {
397 updatedConstants.added.filter(a => a.key !== key)
398 } else if (obj[key]) {
399 updatedConstants.deleted.push({ key, label: obj[key] })
400 }
401
402 delete obj[key]
403
404 return true
405 }
406
407 private buildTranscodingManager () { 271 private buildTranscodingManager () {
408 const self = this 272 const self = this
409 273
diff --git a/server/lib/plugins/video-constant-manager-factory.ts b/server/lib/plugins/video-constant-manager-factory.ts
new file mode 100644
index 000000000..f04dde29f
--- /dev/null
+++ b/server/lib/plugins/video-constant-manager-factory.ts
@@ -0,0 +1,139 @@
1import { logger } from '@server/helpers/logger'
2import {
3 VIDEO_CATEGORIES,
4 VIDEO_LANGUAGES,
5 VIDEO_LICENCES,
6 VIDEO_PLAYLIST_PRIVACIES,
7 VIDEO_PRIVACIES
8} from '@server/initializers/constants'
9import { ConstantManager } from '@shared/models/plugins/server/plugin-constant-manager.model'
10
11type AlterableVideoConstant = 'language' | 'licence' | 'category' | 'privacy' | 'playlistPrivacy'
12type VideoConstant = Record<number | string, string>
13
14type UpdatedVideoConstant = {
15 [name in AlterableVideoConstant]: {
16 [ npmName: string]: {
17 added: VideoConstant[]
18 deleted: VideoConstant[]
19 }
20 }
21}
22
23const constantsHash: { [key in AlterableVideoConstant]: VideoConstant } = {
24 language: VIDEO_LANGUAGES,
25 licence: VIDEO_LICENCES,
26 category: VIDEO_CATEGORIES,
27 privacy: VIDEO_PRIVACIES,
28 playlistPrivacy: VIDEO_PLAYLIST_PRIVACIES
29}
30
31export class VideoConstantManagerFactory {
32 private readonly updatedVideoConstants: UpdatedVideoConstant = {
33 playlistPrivacy: { },
34 privacy: { },
35 language: { },
36 licence: { },
37 category: { }
38 }
39
40 constructor (
41 private readonly npmName: string
42 ) {}
43
44 public resetVideoConstants (npmName: string) {
45 const types: AlterableVideoConstant[] = [ 'language', 'licence', 'category', 'privacy', 'playlistPrivacy' ]
46 for (const type of types) {
47 this.resetConstants({ npmName, type })
48 }
49 }
50
51 private resetConstants (parameters: { npmName: string, type: AlterableVideoConstant }) {
52 const { npmName, type } = parameters
53 const updatedConstants = this.updatedVideoConstants[type][npmName]
54
55 if (!updatedConstants) return
56
57 for (const added of updatedConstants.added) {
58 delete constantsHash[type][added.key]
59 }
60
61 for (const deleted of updatedConstants.deleted) {
62 constantsHash[type][deleted.key] = deleted.label
63 }
64
65 delete this.updatedVideoConstants[type][npmName]
66 }
67
68 public createVideoConstantManager<K extends number | string>(type: AlterableVideoConstant): ConstantManager<K> {
69 const { npmName } = this
70 return {
71 addConstant: (key: K, label: string) => this.addConstant({ npmName, type, key, label }),
72 deleteConstant: (key: K) => this.deleteConstant({ npmName, type, key }),
73 getConstantValue: (key: K) => constantsHash[type][key],
74 getConstants: () => constantsHash[type] as Record<K, string>,
75 resetConstants: () => this.resetConstants({ npmName, type })
76 }
77 }
78
79 private addConstant<T extends string | number> (parameters: {
80 npmName: string
81 type: AlterableVideoConstant
82 key: T
83 label: string
84 }) {
85 const { npmName, type, key, label } = parameters
86 const obj = constantsHash[type]
87
88 if (obj[key]) {
89 logger.warn('Cannot add %s %s by plugin %s: key already exists.', type, npmName, key)
90 return false
91 }
92
93 if (!this.updatedVideoConstants[type][npmName]) {
94 this.updatedVideoConstants[type][npmName] = {
95 added: [],
96 deleted: []
97 }
98 }
99
100 this.updatedVideoConstants[type][npmName].added.push({ key: key, label } as VideoConstant)
101 obj[key] = label
102
103 return true
104 }
105
106 private deleteConstant<T extends string | number> (parameters: {
107 npmName: string
108 type: AlterableVideoConstant
109 key: T
110 }) {
111 const { npmName, type, key } = parameters
112 const obj = constantsHash[type]
113
114 if (!obj[key]) {
115 logger.warn('Cannot delete %s by plugin %s: key %s does not exist.', type, npmName, key)
116 return false
117 }
118
119 if (!this.updatedVideoConstants[type][npmName]) {
120 this.updatedVideoConstants[type][npmName] = {
121 added: [],
122 deleted: []
123 }
124 }
125
126 const updatedConstants = this.updatedVideoConstants[type][npmName]
127
128 const alreadyAdded = updatedConstants.added.find(a => a.key === key)
129 if (alreadyAdded) {
130 updatedConstants.added.filter(a => a.key !== key)
131 } else if (obj[key]) {
132 updatedConstants.deleted.push({ key, label: obj[key] } as VideoConstant)
133 }
134
135 delete obj[key]
136
137 return true
138 }
139}