aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/lib/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'server/lib/plugins')
-rw-r--r--server/lib/plugins/plugin-helpers.ts20
-rw-r--r--server/lib/plugins/plugin-manager.ts150
-rw-r--r--server/lib/plugins/register-helpers.ts180
3 files changed, 207 insertions, 143 deletions
diff --git a/server/lib/plugins/plugin-helpers.ts b/server/lib/plugins/plugin-helpers.ts
new file mode 100644
index 000000000..36d08d84a
--- /dev/null
+++ b/server/lib/plugins/plugin-helpers.ts
@@ -0,0 +1,20 @@
1import { PluginModel } from '@server/models/server/plugin'
2import { PeerTubeHelpers } from '@server/typings/plugins'
3
4function buildPluginHelpers (npmName: string, plugin: PluginModel): PeerTubeHelpers {
5 const logger = buildLogger(npmName)
6
7 return {
8 logger
9 }
10}
11
12export {
13 buildPluginHelpers
14}
15
16// ---------------------------------------------------------------------------
17
18function buildLogger (npmName: string) {
19 return buildLogger(npmName)
20}
diff --git a/server/lib/plugins/plugin-manager.ts b/server/lib/plugins/plugin-manager.ts
index 73f7a71ce..44530d203 100644
--- a/server/lib/plugins/plugin-manager.ts
+++ b/server/lib/plugins/plugin-manager.ts
@@ -9,12 +9,10 @@ import {
9 PluginTranslationPaths as PackagePluginTranslations 9 PluginTranslationPaths as PackagePluginTranslations
10} from '../../../shared/models/plugins/plugin-package-json.model' 10} from '../../../shared/models/plugins/plugin-package-json.model'
11import { createReadStream, createWriteStream } from 'fs' 11import { createReadStream, createWriteStream } from 'fs'
12import { PLUGIN_GLOBAL_CSS_PATH, VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES } from '../../initializers/constants' 12import { PLUGIN_GLOBAL_CSS_PATH } from '../../initializers/constants'
13import { PluginType } from '../../../shared/models/plugins/plugin.type' 13import { PluginType } from '../../../shared/models/plugins/plugin.type'
14import { installNpmPlugin, installNpmPluginFromDisk, removeNpmPlugin } from './yarn' 14import { installNpmPlugin, installNpmPluginFromDisk, removeNpmPlugin } from './yarn'
15import { outputFile, readJSON } from 'fs-extra' 15import { outputFile, readJSON } from 'fs-extra'
16import { PluginSettingsManager } from '../../../shared/models/plugins/plugin-settings-manager.model'
17import { PluginStorageManager } from '../../../shared/models/plugins/plugin-storage-manager.model'
18import { ServerHook, ServerHookName, serverHookObject } from '../../../shared/models/plugins/server-hook.model' 16import { ServerHook, ServerHookName, serverHookObject } from '../../../shared/models/plugins/server-hook.model'
19import { getHookType, internalRunHook } from '../../../shared/core-utils/plugins/hooks' 17import { getHookType, internalRunHook } from '../../../shared/core-utils/plugins/hooks'
20import { RegisterServerOptions } from '../../typings/plugins/register-server-option.model' 18import { RegisterServerOptions } from '../../typings/plugins/register-server-option.model'
@@ -22,10 +20,8 @@ import { PluginLibrary } from '../../typings/plugins'
22import { ClientHtml } from '../client-html' 20import { ClientHtml } from '../client-html'
23import { RegisterServerHookOptions } from '../../../shared/models/plugins/register-server-hook.model' 21import { RegisterServerHookOptions } from '../../../shared/models/plugins/register-server-hook.model'
24import { RegisterServerSettingOptions } from '../../../shared/models/plugins/register-server-setting.model' 22import { RegisterServerSettingOptions } from '../../../shared/models/plugins/register-server-setting.model'
25import { PluginVideoLanguageManager } from '../../../shared/models/plugins/plugin-video-language-manager.model'
26import { PluginVideoCategoryManager } from '../../../shared/models/plugins/plugin-video-category-manager.model'
27import { PluginVideoLicenceManager } from '../../../shared/models/plugins/plugin-video-licence-manager.model'
28import { PluginTranslation } from '../../../shared/models/plugins/plugin-translation.model' 23import { PluginTranslation } from '../../../shared/models/plugins/plugin-translation.model'
24import { buildRegisterHelpers, reinitVideoConstants } from './register-helpers'
29 25
30export interface RegisteredPlugin { 26export interface RegisteredPlugin {
31 npmName: string 27 npmName: string
@@ -54,17 +50,6 @@ export interface HookInformationValue {
54 priority: number 50 priority: number
55} 51}
56 52
57type AlterableVideoConstant = 'language' | 'licence' | 'category'
58type VideoConstant = { [key in number | string]: string }
59type UpdatedVideoConstant = {
60 [name in AlterableVideoConstant]: {
61 [npmName: string]: {
62 added: { key: number | string, label: string }[]
63 deleted: { key: number | string, label: string }[]
64 }
65 }
66}
67
68type PluginLocalesTranslations = { 53type PluginLocalesTranslations = {
69 [locale: string]: PluginTranslation 54 [locale: string]: PluginTranslation
70} 55}
@@ -78,12 +63,6 @@ export class PluginManager implements ServerHook {
78 private hooks: { [name: string]: HookInformationValue[] } = {} 63 private hooks: { [name: string]: HookInformationValue[] } = {}
79 private translations: PluginLocalesTranslations = {} 64 private translations: PluginLocalesTranslations = {}
80 65
81 private readonly updatedVideoConstants: UpdatedVideoConstant = {
82 language: {},
83 licence: {},
84 category: {}
85 }
86
87 private constructor () { 66 private constructor () {
88 } 67 }
89 68
@@ -197,7 +176,7 @@ export class PluginManager implements ServerHook {
197 this.hooks[key] = this.hooks[key].filter(h => h.npmName !== npmName) 176 this.hooks[key] = this.hooks[key].filter(h => h.npmName !== npmName)
198 } 177 }
199 178
200 this.reinitVideoConstants(plugin.npmName) 179 reinitVideoConstants(plugin.npmName)
201 180
202 logger.info('Regenerating registered plugin CSS to global file.') 181 logger.info('Regenerating registered plugin CSS to global file.')
203 await this.regeneratePluginGlobalCSS() 182 await this.regeneratePluginGlobalCSS()
@@ -472,127 +451,12 @@ export class PluginManager implements ServerHook {
472 this.settings[npmName].push(options) 451 this.settings[npmName].push(options)
473 } 452 }
474 453
475 const settingsManager: PluginSettingsManager = { 454 const registerHelpers = buildRegisterHelpers(npmName, plugin)
476 getSetting: (name: string) => PluginModel.getSetting(plugin.name, plugin.type, name),
477 455
478 setSetting: (name: string, value: string) => PluginModel.setSetting(plugin.name, plugin.type, name, value) 456 return Object.assign(registerHelpers, {
479 }
480
481 const storageManager: PluginStorageManager = {
482 getData: (key: string) => PluginModel.getData(plugin.name, plugin.type, key),
483
484 storeData: (key: string, data: any) => PluginModel.storeData(plugin.name, plugin.type, key, data)
485 }
486
487 const videoLanguageManager: PluginVideoLanguageManager = {
488 addLanguage: (key: string, label: string) => this.addConstant({ npmName, type: 'language', obj: VIDEO_LANGUAGES, key, label }),
489
490 deleteLanguage: (key: string) => this.deleteConstant({ npmName, type: 'language', obj: VIDEO_LANGUAGES, key })
491 }
492
493 const videoCategoryManager: PluginVideoCategoryManager = {
494 addCategory: (key: number, label: string) => this.addConstant({ npmName, type: 'category', obj: VIDEO_CATEGORIES, key, label }),
495
496 deleteCategory: (key: number) => this.deleteConstant({ npmName, type: 'category', obj: VIDEO_CATEGORIES, key })
497 }
498
499 const videoLicenceManager: PluginVideoLicenceManager = {
500 addLicence: (key: number, label: string) => this.addConstant({ npmName, type: 'licence', obj: VIDEO_LICENCES, key, label }),
501
502 deleteLicence: (key: number) => this.deleteConstant({ npmName, type: 'licence', obj: VIDEO_LICENCES, key })
503 }
504
505 const peertubeHelpers = {
506 logger
507 }
508
509 return {
510 registerHook, 457 registerHook,
511 registerSetting, 458 registerSetting
512 settingsManager, 459 })
513 storageManager,
514 videoLanguageManager,
515 videoCategoryManager,
516 videoLicenceManager,
517 peertubeHelpers
518 }
519 }
520
521 private addConstant<T extends string | number> (parameters: {
522 npmName: string
523 type: AlterableVideoConstant
524 obj: VideoConstant
525 key: T
526 label: string
527 }) {
528 const { npmName, type, obj, key, label } = parameters
529
530 if (obj[key]) {
531 logger.warn('Cannot add %s %s by plugin %s: key already exists.', type, npmName, key)
532 return false
533 }
534
535 if (!this.updatedVideoConstants[type][npmName]) {
536 this.updatedVideoConstants[type][npmName] = {
537 added: [],
538 deleted: []
539 }
540 }
541
542 this.updatedVideoConstants[type][npmName].added.push({ key, label })
543 obj[key] = label
544
545 return true
546 }
547
548 private deleteConstant<T extends string | number> (parameters: {
549 npmName: string
550 type: AlterableVideoConstant
551 obj: VideoConstant
552 key: T
553 }) {
554 const { npmName, type, obj, key } = parameters
555
556 if (!obj[key]) {
557 logger.warn('Cannot delete %s %s by plugin %s: key does not exist.', type, npmName, key)
558 return false
559 }
560
561 if (!this.updatedVideoConstants[type][npmName]) {
562 this.updatedVideoConstants[type][npmName] = {
563 added: [],
564 deleted: []
565 }
566 }
567
568 this.updatedVideoConstants[type][npmName].deleted.push({ key, label: obj[key] })
569 delete obj[key]
570
571 return true
572 }
573
574 private reinitVideoConstants (npmName: string) {
575 const hash = {
576 language: VIDEO_LANGUAGES,
577 licence: VIDEO_LICENCES,
578 category: VIDEO_CATEGORIES
579 }
580 const types: AlterableVideoConstant[] = [ 'language', 'licence', 'category' ]
581
582 for (const type of types) {
583 const updatedConstants = this.updatedVideoConstants[type][npmName]
584 if (!updatedConstants) continue
585
586 for (const added of updatedConstants.added) {
587 delete hash[type][added.key]
588 }
589
590 for (const deleted of updatedConstants.deleted) {
591 hash[type][deleted.key] = deleted.label
592 }
593
594 delete this.updatedVideoConstants[type][npmName]
595 }
596 } 460 }
597 461
598 private sanitizeAndCheckPackageJSONOrThrow (packageJSON: PluginPackageJson, pluginType: PluginType) { 462 private sanitizeAndCheckPackageJSONOrThrow (packageJSON: PluginPackageJson, pluginType: PluginType) {
diff --git a/server/lib/plugins/register-helpers.ts b/server/lib/plugins/register-helpers.ts
new file mode 100644
index 000000000..58bc96f04
--- /dev/null
+++ b/server/lib/plugins/register-helpers.ts
@@ -0,0 +1,180 @@
1import { PluginSettingsManager } from '@shared/models/plugins/plugin-settings-manager.model'
2import { PluginModel } from '@server/models/server/plugin'
3import { PluginStorageManager } from '@shared/models/plugins/plugin-storage-manager.model'
4import { PluginVideoLanguageManager } from '@shared/models/plugins/plugin-video-language-manager.model'
5import { VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES } from '@server/initializers/constants'
6import { PluginVideoLicenceManager } from '@shared/models/plugins/plugin-video-licence-manager.model'
7import { PluginVideoCategoryManager } from '@shared/models/plugins/plugin-video-category-manager.model'
8import { RegisterServerOptions } from '@server/typings/plugins'
9import { buildPluginHelpers } from './plugin-helpers'
10import { logger } from '@server/helpers/logger'
11
12type AlterableVideoConstant = 'language' | 'licence' | 'category'
13type VideoConstant = { [key in number | string]: string }
14type UpdatedVideoConstant = {
15 [name in AlterableVideoConstant]: {
16 [npmName: string]: {
17 added: { key: number | string, label: string }[]
18 deleted: { key: number | string, label: string }[]
19 }
20 }
21}
22
23const updatedVideoConstants: UpdatedVideoConstant = {
24 language: {},
25 licence: {},
26 category: {}
27}
28
29function buildRegisterHelpers (npmName: string, plugin: PluginModel): Omit<RegisterServerOptions, 'registerHook' | 'registerSetting'> {
30 const settingsManager = buildSettingsManager(plugin)
31 const storageManager = buildStorageManager(plugin)
32
33 const videoLanguageManager = buildVideoLanguageManager(npmName)
34
35 const videoCategoryManager = buildVideoCategoryManager(npmName)
36 const videoLicenceManager = buildVideoLicenceManager(npmName)
37
38 const peertubeHelpers = buildPluginHelpers(npmName, plugin)
39
40 return {
41 settingsManager,
42 storageManager,
43 videoLanguageManager,
44 videoCategoryManager,
45 videoLicenceManager,
46 peertubeHelpers
47 }
48}
49
50function reinitVideoConstants (npmName: string) {
51 const hash = {
52 language: VIDEO_LANGUAGES,
53 licence: VIDEO_LICENCES,
54 category: VIDEO_CATEGORIES
55 }
56 const types: AlterableVideoConstant[] = [ 'language', 'licence', 'category' ]
57
58 for (const type of types) {
59 const updatedConstants = updatedVideoConstants[type][npmName]
60 if (!updatedConstants) continue
61
62 for (const added of updatedConstants.added) {
63 delete hash[type][added.key]
64 }
65
66 for (const deleted of updatedConstants.deleted) {
67 hash[type][deleted.key] = deleted.label
68 }
69
70 delete updatedVideoConstants[type][npmName]
71 }
72}
73
74export {
75 buildRegisterHelpers,
76 reinitVideoConstants
77}
78
79// ---------------------------------------------------------------------------
80
81function buildSettingsManager (plugin: PluginModel): PluginSettingsManager {
82 return {
83 getSetting: (name: string) => PluginModel.getSetting(plugin.name, plugin.type, name),
84
85 setSetting: (name: string, value: string) => PluginModel.setSetting(plugin.name, plugin.type, name, value)
86 }
87}
88
89function buildStorageManager (plugin: PluginModel): PluginStorageManager {
90 return {
91 getData: (key: string) => PluginModel.getData(plugin.name, plugin.type, key),
92
93 storeData: (key: string, data: any) => PluginModel.storeData(plugin.name, plugin.type, key, data)
94 }
95}
96
97function buildVideoLanguageManager (npmName: string): PluginVideoLanguageManager {
98 return {
99 addLanguage: (key: string, label: string) => addConstant({ npmName, type: 'language', obj: VIDEO_LANGUAGES, key, label }),
100
101 deleteLanguage: (key: string) => deleteConstant({ npmName, type: 'language', obj: VIDEO_LANGUAGES, key })
102 }
103}
104
105function buildVideoCategoryManager (npmName: string): PluginVideoCategoryManager {
106 return {
107 addCategory: (key: number, label: string) => {
108 return addConstant({ npmName, type: 'category', obj: VIDEO_CATEGORIES, key, label })
109 },
110
111 deleteCategory: (key: number) => {
112 return deleteConstant({ npmName, type: 'category', obj: VIDEO_CATEGORIES, key })
113 }
114 }
115}
116
117function buildVideoLicenceManager (npmName: string): PluginVideoLicenceManager {
118 return {
119 addLicence: (key: number, label: string) => {
120 return addConstant({ npmName, type: 'licence', obj: VIDEO_LICENCES, key, label })
121 },
122
123 deleteLicence: (key: number) => {
124 return deleteConstant({ npmName, type: 'licence', obj: VIDEO_LICENCES, key })
125 }
126 }
127}
128
129function addConstant<T extends string | number> (parameters: {
130 npmName: string
131 type: AlterableVideoConstant
132 obj: VideoConstant
133 key: T
134 label: string
135}) {
136 const { npmName, type, obj, key, label } = parameters
137
138 if (obj[key]) {
139 logger.warn('Cannot add %s %s by plugin %s: key already exists.', type, npmName, key)
140 return false
141 }
142
143 if (!updatedVideoConstants[type][npmName]) {
144 updatedVideoConstants[type][npmName] = {
145 added: [],
146 deleted: []
147 }
148 }
149
150 updatedVideoConstants[type][npmName].added.push({ key, label })
151 obj[key] = label
152
153 return true
154}
155
156function deleteConstant<T extends string | number> (parameters: {
157 npmName: string
158 type: AlterableVideoConstant
159 obj: VideoConstant
160 key: T
161}) {
162 const { npmName, type, obj, key } = parameters
163
164 if (!obj[key]) {
165 logger.warn('Cannot delete %s %s by plugin %s: key does not exist.', type, npmName, key)
166 return false
167 }
168
169 if (!updatedVideoConstants[type][npmName]) {
170 updatedVideoConstants[type][npmName] = {
171 added: [],
172 deleted: []
173 }
174 }
175
176 updatedVideoConstants[type][npmName].deleted.push({ key, label: obj[key] })
177 delete obj[key]
178
179 return true
180}