diff options
Diffstat (limited to 'server/lib/plugins')
-rw-r--r-- | server/lib/plugins/register-helpers.ts | 222 | ||||
-rw-r--r-- | server/lib/plugins/video-constant-manager-factory.ts | 139 |
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 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import { logger } from '@server/helpers/logger' | 2 | import { logger } from '@server/helpers/logger' |
3 | import { | ||
4 | VIDEO_CATEGORIES, | ||
5 | VIDEO_LANGUAGES, | ||
6 | VIDEO_LICENCES, | ||
7 | VIDEO_PLAYLIST_PRIVACIES, | ||
8 | VIDEO_PRIVACIES | ||
9 | } from '@server/initializers/constants' | ||
10 | import { onExternalUserAuthenticated } from '@server/lib/auth/external-auth' | 3 | import { onExternalUserAuthenticated } from '@server/lib/auth/external-auth' |
4 | import { VideoConstantManagerFactory } from '@server/lib/plugins/video-constant-manager-factory' | ||
11 | import { PluginModel } from '@server/models/server/plugin' | 5 | import { PluginModel } from '@server/models/server/plugin' |
12 | import { | 6 | import { |
13 | RegisterServerAuthExternalOptions, | 7 | RegisterServerAuthExternalOptions, |
@@ -18,41 +12,18 @@ import { | |||
18 | } from '@server/types/plugins' | 12 | } from '@server/types/plugins' |
19 | import { | 13 | import { |
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' |
32 | import { VideoTranscodingProfilesManager } from '../transcoding/video-transcoding-profiles' | 23 | import { VideoTranscodingProfilesManager } from '../transcoding/video-transcoding-profiles' |
33 | import { buildPluginHelpers } from './plugin-helpers-builder' | 24 | import { buildPluginHelpers } from './plugin-helpers-builder' |
34 | 25 | ||
35 | type AlterableVideoConstant = 'language' | 'licence' | 'category' | 'privacy' | 'playlistPrivacy' | ||
36 | type VideoConstant = { [key in number | string]: string } | ||
37 | |||
38 | type 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 | |||
47 | export class RegisterHelpers { | 26 | export 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 @@ | |||
1 | import { logger } from '@server/helpers/logger' | ||
2 | import { | ||
3 | VIDEO_CATEGORIES, | ||
4 | VIDEO_LANGUAGES, | ||
5 | VIDEO_LICENCES, | ||
6 | VIDEO_PLAYLIST_PRIVACIES, | ||
7 | VIDEO_PRIVACIES | ||
8 | } from '@server/initializers/constants' | ||
9 | import { ConstantManager } from '@shared/models/plugins/server/plugin-constant-manager.model' | ||
10 | |||
11 | type AlterableVideoConstant = 'language' | 'licence' | 'category' | 'privacy' | 'playlistPrivacy' | ||
12 | type VideoConstant = Record<number | string, string> | ||
13 | |||
14 | type UpdatedVideoConstant = { | ||
15 | [name in AlterableVideoConstant]: { | ||
16 | [ npmName: string]: { | ||
17 | added: VideoConstant[] | ||
18 | deleted: VideoConstant[] | ||
19 | } | ||
20 | } | ||
21 | } | ||
22 | |||
23 | const 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 | |||
31 | export 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 | } | ||